David Mort
/
SPI_flex
CLASS for software SPI master class instantiated on any general IO pin. Slow but flexible.
SPI_flex.h
- Committer:
- dtmort
- Date:
- 2014-03-22
- Revision:
- 0:9e3e70548ec3
File content as of revision 0:9e3e70548ec3:
/* Class SPI_flex, 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_SPI_FLEX_H #define MBED_SPI_FLEX_H #include "mbed.h" /**A software Master SPI (Serial Peripheral Interface) class * that can be instantiated on any mbed LPC1768 general IO pins (p5...p30). * * Primarily optimized for driving daisy-chained serial display hardware, * it provides flexibility beyond on-board SPI hardware capabilities and some automation * at the expense of speed. Currently runs full clock speed at about 395kHz. * Comment-out code lines testing/setting the automatic chip select for higher speed * performance if the chip select feature is not required. * - flexible bit-lengths from 0 .. 4,294,967,295. Not possible with mbed hardware. * - automation of the chip select line which enables * all external chips to be loaded with information before latching data in. * - selectable clock polarity and edge trigger (Mode 0 through Mode 3). * - 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. * - allows one-shot loading of all daisy-chained hardware registers before latching. * Prevents display ghosting effect. * * 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 byte to a SPI slave, and record the response * * // Chip select is automatic * * #include "mbed.h" * #include "SPI_flex.h" * * SPI device(p5, p6, p7, p8); // mosi, miso, sclk, cs * * int main() { * device.frequency(300000); //to slow clock speed if necessary * int response = device.writebyte(0xFF); * } * @endcode */ class SPI_flex { public: /**Create a software Master SPI bus instance * * @param mosi Master Out Slave In pin * @param miso Master In Slave Out pin * @param sclk Serial Clock out pin * @param cs Chip Select out pin */ SPI_flex(PinName mosi, PinName miso, PinName sclk, PinName cs); /** Configure the SPI bus data transmission format * * Constructor calls by default. Call only if change needed. * * Automatically controls chip select output pin. Default is 16 bit. * * @param bits Bits per SPI hardware string frame (0 .. 4,294,967,295) * * @param mode Clock polarity and phase. Default is Mode 0. * @code Mode | POL | PHA -----|-----|---- 0 | 0 | 0 1 | 0 | 1 2 | 1 | 0 3 | 1 | 1 @endcode */ void format(unsigned int bits=16, int mode=0); /** Set active state of the SPI bus chip select pin * * Constructor calls by default. Call only if change needed. * * @param cs 0 (default) for active-low, 1 for active-high */ void csactive(bool cs=0); /** Set the SPI bus clock frequency. * Is maximum by default. Call only if change needed. * * Result will not be exact and may jump in 5Khz increments * due to integer rounding. * * @param Hz Hertz 395,000 is approximate maximum (and default speed) */ void frequency(int Hz=400000); /** Send a single bit on the SPI bus MOSI pin and read response on MISO pin * * @param bit Boolean one or zero, TRUE or FALSE * @returns Boolean one or zero read from MISO from external hardware */ bool writebit(bool bit); /** Send a byte on the SPI bus MOSI pin and read response on MISO pin * * MSB first out, LSB last out (7:0) * * @param byte An 8-bit value * @returns 8-bit value read from MISO from external hardware */ uint8_t writebyte(uint8_t byte); /** Send a word on the SPI bus MOSI pin and read response on MISO pin * * MSB first out, LSB last out (15:0) * * @param word A 16-bit value * @returns 16-bit value read from MISO from external hardware */ uint16_t writeword(uint16_t word); //protected: private: void select(void); //activates chip select sequence, called by writebit() function void deSelect(void); //deactivates chip select, called by writebit() function DigitalOut _mosi; //master out slave in, pin DigitalIn _miso; //master in slave out, pin DigitalOut _sclk; //serial clock, pin DigitalOut _cs; //chip select, pin bool __cs; //chip select active state, operating setup bool _cpol; //clock polarity, operating setup bool _cpha; //clock phase, operating setup int _mode; //mode 0,1,2 or 3, operating setup unsigned int _deAssert; //counts-up bits sent for chip select, placeholder unsigned int BitString; //# serialized bits sent to hardware string, controls chip select activation unsigned int BitStream; //# bits to hardware from source data, not used yet bool bit_read; //bit value read from miso pin uint8_t byte_read; //byte value read from miso pin uint16_t word_read; //word value read from miso pin int Dcpwi; //Delay clock pulse width inactive, for freqency adjustments int Dcpwa; //Delay clock pulse width active, for freqency adjustments }; #endif