diff options
author | Daniel Garcia <danielgarcia@gmail.com> | 2014-03-11 04:27:55 +0400 |
---|---|---|
committer | Daniel Garcia <danielgarcia@gmail.com> | 2014-03-11 04:27:55 +0400 |
commit | 0bb025ef288e09173a06e74f4e647f479e555d9d (patch) | |
tree | 8e69c0265a523dfaf75d9bdd6a194aea98ae1823 | |
parent | c81fb6b935d4adbd7d11fcabcccea5e940056648 (diff) |
Due hardware SPI, FTW\!
-rw-r--r-- | examples/Cylon/Cylon.ino | 2 | ||||
-rw-r--r-- | fastspi_arm_sam.h | 55 |
2 files changed, 23 insertions, 34 deletions
diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino index 3f066425..94cb7541 100644 --- a/examples/Cylon/Cylon.ino +++ b/examples/Cylon/Cylon.ino @@ -13,7 +13,7 @@ CRGB leds[NUM_LEDS]; void setup() { - FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); + FastLED.addLeds<LPD8806>(leds, NUM_LEDS); } void loop() { diff --git a/fastspi_arm_sam.h b/fastspi_arm_sam.h index e9d822c1..5b205e0f 100644 --- a/fastspi_arm_sam.h +++ b/fastspi_arm_sam.h @@ -13,20 +13,20 @@ class SAMHardwareSPIOutput { void enableConfig() { m_SPI->SPI_WPMR &= ~SPI_WPMR_WPEN; } void disableConfig() { m_SPI->SPI_WPMR |= SPI_WPMR_WPEN; } - void enableSPI() { m_SPI->SPI_CR |= SPI_CR_SPIEN; } - void disableSPI() { m_SPI->SPI_CR &= ~SPI_CR_SPIEN; } + void enableSPI() { m_SPI->SPI_CR = SPI_CR_SPIEN; } + void disableSPI() { m_SPI->SPI_CR = SPI_CR_SPIDIS; } + void resetSPI() { m_SPI->SPI_CR = SPI_CR_SWRST; } - void readyTransferBits(register byte bits) { + static inline void readyTransferBits(register byte bits) { bits -= 8; // don't change the number of transfer bits while data is still being transferred from TDR to the shift register waitForEmpty(); - m_SPI->SPI_CSR[0] = (bits << SPI_CSR_BITS_Pos) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER); + m_SPI->SPI_CSR[0] = SPI_CSR_NCPHA | SPI_CSR_CSAAT | (bits << SPI_CSR_BITS_Pos) | SPI_CSR_DLYBCT(1) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER); } template<int BITS> static inline void writeBits(uint16_t w) { - waitForEmpty(); - m_SPI->SPI_CSR[0] = (BITS << SPI_CSR_BITS_Pos) | SPI_CSR_SCBR(_SPI_CLOCK_DIVIDER); - m_SPI->SPI_TDR = w; + readyTransferBits(BITS); + m_SPI->SPI_TDR = (uint32_t)w | SPI_PCS(0); } public: @@ -40,38 +40,28 @@ public: void init() { // m_SPI = SPI0; - // set the output pins - FastPin<_DATA_PIN>::setOutput(); - FastPin<_CLOCK_PIN>::setOutput(); + // set the output pins master out, master in, clock. Note doing this here because I still don't + // know how I want to expose this type of functionality in FastPin. + PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_DATA_PIN>::mask(), PIO_DEFAULT); + PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_DATA_PIN-1>::mask(), PIO_DEFAULT); + PIO_Configure(PIOA, PIO_PERIPH_A, FastPin<_CLOCK_PIN>::mask(), PIO_DEFAULT); + release(); // Configure the SPI clock, divider between 1-255 // SCBR = _SPI_CLOCK_DIVIDER + pmc_enable_periph_clk(ID_SPI0); + disableSPI(); - // Enable writes - enableConfig(); + // reset twice (what the sam code does, not sure why?) + resetSPI(); + resetSPI(); // Configure SPI as master, enable - enableSPI(); - - // Only bit in MR we want on is master, everything is left to 0, see commented out psuedocode - m_SPI->SPI_MR = SPI_MR_MSTR; - // SPI_MR.MSTR = 1; set master - // SPI_MR.PS = 0 fixed peripheral select - // SPI_MR.PCSDEC = 0 direct connect CS decode - // SPI_MR.PCS = 0 device 0 - // SPI_MR.DLYBCS = 0; 0 delay between chip selects - - // set inter-transfer delay to 0 - // DLYBCT = 0; - // DLYBS = 0; - - // CSR items - // SPI_CSR0 = 0; - // SPI_CSR0.BITS = 0 (8bit), 1 (9bit), 8 (16bit) - // SPI_CSR0.SCBR = _SPI_CLOCK_DIVIDER - // SPI_CSR0.DLYBS = 0, SPI_CSR0.DLYBCT = 0 + // Bits we want in MR: master, disable mode fault detection, variable peripheral select + m_SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS; + enableSPI(); } // latch the CS select @@ -145,8 +135,7 @@ public: while(data != end) { if(FLAGS & FLAG_START_BIT) { - writeBit<0>(1); - writeByte(D::adjust(pixels.loadAndScale0())); + writeBits<9>((1<<8) | D::adjust(pixels.loadAndScale0())); writeByte(D::adjust(pixels.loadAndScale1())); writeByte(D::adjust(pixels.loadAndScale2())); } else { |