CLASS for automated serial 'chip select' implimentation utilizing mbed LPC1768 Timer2 hardware and it's inturrupt features.
Revision 0:9fa30f3069ae, committed 2014-03-22
- Comitter:
- dtmort
- Date:
- Sat Mar 22 18:57:17 2014 +0000
- Commit message:
- Initial commit 2014.03.22
Changed in this revision
SSEL_spi.cpp | Show annotated file Show diff for this revision Revisions of this file |
SSEL_spi.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SSEL_spi.cpp Sat Mar 22 18:57:17 2014 +0000 @@ -0,0 +1,52 @@ +/* Class SSEL_spi, Copyright 2014, David T. Mort (http://mbed.org/users/dtmort/) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +#include "SSEL_spi.h" +#include "mbed.h" + +SSEL_spi::SSEL_spi(uint32_t frame, int mode){ + //hardwire SPI sclk to p30 so Counter2 can trigger p8 SSEL from serial clock counts + //Setup Timer/Counter2 ******************************************************************************** + LPC_SC->PCONP |= 0x00400000; //Timer/COUNTER2 turn power on bit 22, Table 46 + LPC_PINCON->PINSEL0 |= 0x00003300; //Timer/COUNTER2: (9:8)CAP2.0 on p30, (13:12)MAT2.0 on p8(SSEL), Table 79 + switch (mode){ + case 1: + case 2: + LPC_TIM2->CTCR= 2; //increment on falling edge of CAP2.0 input, Table 428 + break; + case 0: + case 3: + LPC_TIM2->CTCR= 1; //increment on rising edge of CAP2.0 input, Table 428 + } + LPC_TIM2->MCR = 3; //reset TC on match to MR0 (bit 1) & interrupt (bit 0), Table 429 + LPC_TIM2->EMR = 48; //set bits 5:4 for toggle function, clear bit 0 MAT2.0(SSEL), Table 431/432 + + NVIC_EnableIRQ(TIMER2_IRQn); //this method enables timer2 interrupt at run time + + LPC_TIM2->TCR = 3UL; //1:0 reset TC/PC & enable counter, clear bit 1 to begin counting, Table 427 + LPC_TIM2->MR0 = frame; //clock bit counter load, see 21.6.7 + LPC_TIM2->TCR &= ~2UL; //clear bit 1 to enable counting +} + +void SSEL_spi::active(bool cs){ + LPC_TIM2->EMR = 48+cs; //set or clear bit 0 of MAT2.0(SSEL) pin 8 output, Table 431/432 +} + + // ISR routine **************************************************************************************** +extern "C" void TIMER2_IRQHandler (void){ + if((LPC_TIM2->IR & 0x01)==0x01){ //if MR0 interrupt, proceed, Table 426 + LPC_TIM2->IR = 1UL; //clear MR0 interrupt flag by writing 1, writing 0 has no effect + LPC_TIM2->EMR ^= 1UL; //toggle bit:0 to reset SSEL back to active state, Table 431 + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SSEL_spi.h Sat Mar 22 18:57:17 2014 +0000 @@ -0,0 +1,107 @@ +/* Class SSEL_spi, Copyright 2014, David T. Mort (http://mbed.org/users/dtmort/) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +#ifndef MBED_SSEL_SPI_H +#define MBED_SSEL_SPI_H + + +#include "mbed.h" +extern "C" void TIMER2_IRQHandler (void); //this method Linker loads ISR vector at compile time + +/**A hardware implimentation of a Serial (chip) SElect line output designed primarily for SPI (Serial Peripheral Interface) + * devices by utilizing mbed LPC1768 Timer 2 hardware and it's inturrupt features. + * + * Use of this class does require hardwiring p30 to the serial clock output (usually p7 or p13). + * + * p8 is the SSEL serial select output pin (chip select) and is not relocatable. + * + * Some SPI peripherals require data latching while the serial clock is still active on + * the last bit clocked-in, such as the Maxim MAX6952. Using the mbed SPI and DigitalOut API's + * (for chip select) this timing is not possible. This SSEL_spi class takes advantage of + * the speed achievable with the mbed SPI API, and leaves the chip select output handling + * entirely in the capable hands of the Timer 2 hardware with fully automated frame lengths + * making code simpler to write and read. + * + * - Flexible serial frame lengths from 0 .. 4,294,967,295 bits (usually a multiple of SPI bit length) + * - Un-attended automation of the chip select line. + * - Selectable mode for proper clock polarity and edge trigger (make same as SPI mode). + * - Selectable chip select polarity (active-low or active-high). + * - Latching data in while clock is still active on last bit, + * **such as required by the Maxim MAX6952. This is not possible with the mbed API, + * onboard SPI or SSP hardware alone. SPI speed is limited up to 3Mhz for this feature. + * Higher SPI speeds are permissable although due to the limitations of the hardware the chip + * select will latch AFTER sclk returns to the inactive state, tolerated by some serial peripherals. + * - Allows one-shot loading of all serial daisy-chained hardware registers before latching. + * Prevents display ghosting effect. For example + * a daisy-chain of seven serial chips each requiring 16 bits each would set up a frame + * length of 7 x 16 = 112 bit frame length. + * + * The MAX6952 chip requires the following sequence: + * + * [[http://datasheets.maxim-ic.com/en/ds/MAX6952.pdf]] + * -# Take CLK low. + * -# Take CS low. This enables the internal 16-bit shift register. + * -# Clock 16 bits of data into DIN, D15 first to D0 last, observing the setup and hold times. Bit D15 is low, indicating a write command. + * -# Take CS high **(while CLK is still high after clocking in the last data bit). + * -# Take CLK low. + * + * Example: + * @code + * // Send a 16 bit word to a SPI slave + * // NOTE: You must hardwire sclk output pin (usually p7 or p13) + * // to p30 which is the CAP2.0 sensing pin used by Timer2. + * + * // Chip select is automatic and will always be p8 + * + * #include "mbed.h" + * #include "SSEL_spi.h" + * + * SPI spi(p5,p6,p7); //mosi, miso, sclk + * SSEL_spi cs(16,0); //16 bits per frame, mode 0 (mode optional, 0 is default) + * + * int main(){ + * cs.active(1); //optionally will establish active-high (1) chip select + * spi.format(16,0); + * spi.frequency(1000000); + * + * while(1) spi.write(0x5555); + * + * } + * @endcode + */ +class SSEL_spi { + +public: +/**Create automatated SSEL chip select output for an SPI interface on p8 utilizing Timer2. Must hardwire SPI sclk output pin to p30. + * + * @param frame Bit Length of the SSEL chip select frame. Usually a multiple of the SPI bit length transmission. + * @param mode Set up proper triggering from SPI sclk output. Default mode = 0. Set mode same as SPI mode. + * + */ + SSEL_spi(uint32_t frame, int mode=0); + +/** Set active state of the chip select pin 8 + * + * Is active-low (0) by default. Call only if change needed. + * + * Can also be called to force an output high or low condition. + * @param cs 0 (default) for active-low, 1 for active-high + */ + void active(bool cs); +protected: + +private: + +}; +#endif