David Mort
/
SPI_flex
CLASS for software SPI master class instantiated on any general IO pin. Slow but flexible.
SPI_flex.h@0:9e3e70548ec3, 2014-03-22 (annotated)
- Committer:
- dtmort
- Date:
- Sat Mar 22 18:53:40 2014 +0000
- Revision:
- 0:9e3e70548ec3
Initial commit 2014.03.22
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dtmort | 0:9e3e70548ec3 | 1 | /* Class SPI_flex, Copyright 2014, David T. Mort (http://mbed.org/users/dtmort/) |
dtmort | 0:9e3e70548ec3 | 2 | |
dtmort | 0:9e3e70548ec3 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); |
dtmort | 0:9e3e70548ec3 | 4 | you may not use this file except in compliance with the License. |
dtmort | 0:9e3e70548ec3 | 5 | You may obtain a copy of the License at |
dtmort | 0:9e3e70548ec3 | 6 | |
dtmort | 0:9e3e70548ec3 | 7 | http://www.apache.org/licenses/LICENSE-2.0 |
dtmort | 0:9e3e70548ec3 | 8 | |
dtmort | 0:9e3e70548ec3 | 9 | Unless required by applicable law or agreed to in writing, software |
dtmort | 0:9e3e70548ec3 | 10 | distributed under the License is distributed on an "AS IS" BASIS, |
dtmort | 0:9e3e70548ec3 | 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
dtmort | 0:9e3e70548ec3 | 12 | See the License for the specific language governing permissions and |
dtmort | 0:9e3e70548ec3 | 13 | limitations under the License. |
dtmort | 0:9e3e70548ec3 | 14 | */ |
dtmort | 0:9e3e70548ec3 | 15 | #ifndef MBED_SPI_FLEX_H |
dtmort | 0:9e3e70548ec3 | 16 | #define MBED_SPI_FLEX_H |
dtmort | 0:9e3e70548ec3 | 17 | |
dtmort | 0:9e3e70548ec3 | 18 | #include "mbed.h" |
dtmort | 0:9e3e70548ec3 | 19 | |
dtmort | 0:9e3e70548ec3 | 20 | /**A software Master SPI (Serial Peripheral Interface) class |
dtmort | 0:9e3e70548ec3 | 21 | * that can be instantiated on any mbed LPC1768 general IO pins (p5...p30). |
dtmort | 0:9e3e70548ec3 | 22 | * |
dtmort | 0:9e3e70548ec3 | 23 | * Primarily optimized for driving daisy-chained serial display hardware, |
dtmort | 0:9e3e70548ec3 | 24 | * it provides flexibility beyond on-board SPI hardware capabilities and some automation |
dtmort | 0:9e3e70548ec3 | 25 | * at the expense of speed. Currently runs full clock speed at about 395kHz. |
dtmort | 0:9e3e70548ec3 | 26 | * Comment-out code lines testing/setting the automatic chip select for higher speed |
dtmort | 0:9e3e70548ec3 | 27 | * performance if the chip select feature is not required. |
dtmort | 0:9e3e70548ec3 | 28 | * - flexible bit-lengths from 0 .. 4,294,967,295. Not possible with mbed hardware. |
dtmort | 0:9e3e70548ec3 | 29 | * - automation of the chip select line which enables |
dtmort | 0:9e3e70548ec3 | 30 | * all external chips to be loaded with information before latching data in. |
dtmort | 0:9e3e70548ec3 | 31 | * - selectable clock polarity and edge trigger (Mode 0 through Mode 3). |
dtmort | 0:9e3e70548ec3 | 32 | * - selectable chip select polarity (active-low or active-high). |
dtmort | 0:9e3e70548ec3 | 33 | * - latching data in while clock is still active on last bit, |
dtmort | 0:9e3e70548ec3 | 34 | * **such as required by the Maxim MAX6952. This is not possible with the mbed API, |
dtmort | 0:9e3e70548ec3 | 35 | * onboard SPI or SSP hardware. |
dtmort | 0:9e3e70548ec3 | 36 | * - allows one-shot loading of all daisy-chained hardware registers before latching. |
dtmort | 0:9e3e70548ec3 | 37 | * Prevents display ghosting effect. |
dtmort | 0:9e3e70548ec3 | 38 | * |
dtmort | 0:9e3e70548ec3 | 39 | * The MAX6952 chip requires the following sequence: |
dtmort | 0:9e3e70548ec3 | 40 | * |
dtmort | 0:9e3e70548ec3 | 41 | * [[http://datasheets.maxim-ic.com/en/ds/MAX6952.pdf]] |
dtmort | 0:9e3e70548ec3 | 42 | * -# Take CLK low. |
dtmort | 0:9e3e70548ec3 | 43 | * -# Take CS low. This enables the internal 16-bit shift register. |
dtmort | 0:9e3e70548ec3 | 44 | * -# 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. |
dtmort | 0:9e3e70548ec3 | 45 | * -# Take CS high **(while CLK is still high after clocking in the last data bit). |
dtmort | 0:9e3e70548ec3 | 46 | * -# Take CLK low. |
dtmort | 0:9e3e70548ec3 | 47 | * |
dtmort | 0:9e3e70548ec3 | 48 | * Example: |
dtmort | 0:9e3e70548ec3 | 49 | * @code |
dtmort | 0:9e3e70548ec3 | 50 | * // Send a byte to a SPI slave, and record the response |
dtmort | 0:9e3e70548ec3 | 51 | * |
dtmort | 0:9e3e70548ec3 | 52 | * // Chip select is automatic |
dtmort | 0:9e3e70548ec3 | 53 | * |
dtmort | 0:9e3e70548ec3 | 54 | * #include "mbed.h" |
dtmort | 0:9e3e70548ec3 | 55 | * #include "SPI_flex.h" |
dtmort | 0:9e3e70548ec3 | 56 | * |
dtmort | 0:9e3e70548ec3 | 57 | * SPI device(p5, p6, p7, p8); // mosi, miso, sclk, cs |
dtmort | 0:9e3e70548ec3 | 58 | * |
dtmort | 0:9e3e70548ec3 | 59 | * int main() { |
dtmort | 0:9e3e70548ec3 | 60 | * device.frequency(300000); //to slow clock speed if necessary |
dtmort | 0:9e3e70548ec3 | 61 | * int response = device.writebyte(0xFF); |
dtmort | 0:9e3e70548ec3 | 62 | * } |
dtmort | 0:9e3e70548ec3 | 63 | * @endcode |
dtmort | 0:9e3e70548ec3 | 64 | */ |
dtmort | 0:9e3e70548ec3 | 65 | class SPI_flex { |
dtmort | 0:9e3e70548ec3 | 66 | |
dtmort | 0:9e3e70548ec3 | 67 | public: |
dtmort | 0:9e3e70548ec3 | 68 | /**Create a software Master SPI bus instance |
dtmort | 0:9e3e70548ec3 | 69 | * |
dtmort | 0:9e3e70548ec3 | 70 | * @param mosi Master Out Slave In pin |
dtmort | 0:9e3e70548ec3 | 71 | * @param miso Master In Slave Out pin |
dtmort | 0:9e3e70548ec3 | 72 | * @param sclk Serial Clock out pin |
dtmort | 0:9e3e70548ec3 | 73 | * @param cs Chip Select out pin |
dtmort | 0:9e3e70548ec3 | 74 | */ |
dtmort | 0:9e3e70548ec3 | 75 | SPI_flex(PinName mosi, PinName miso, PinName sclk, PinName cs); |
dtmort | 0:9e3e70548ec3 | 76 | |
dtmort | 0:9e3e70548ec3 | 77 | /** Configure the SPI bus data transmission format |
dtmort | 0:9e3e70548ec3 | 78 | * |
dtmort | 0:9e3e70548ec3 | 79 | * Constructor calls by default. Call only if change needed. |
dtmort | 0:9e3e70548ec3 | 80 | * |
dtmort | 0:9e3e70548ec3 | 81 | * Automatically controls chip select output pin. Default is 16 bit. |
dtmort | 0:9e3e70548ec3 | 82 | * |
dtmort | 0:9e3e70548ec3 | 83 | * @param bits Bits per SPI hardware string frame (0 .. 4,294,967,295) |
dtmort | 0:9e3e70548ec3 | 84 | * |
dtmort | 0:9e3e70548ec3 | 85 | * @param mode Clock polarity and phase. Default is Mode 0. |
dtmort | 0:9e3e70548ec3 | 86 | * |
dtmort | 0:9e3e70548ec3 | 87 | @code |
dtmort | 0:9e3e70548ec3 | 88 | Mode | POL | PHA |
dtmort | 0:9e3e70548ec3 | 89 | -----|-----|---- |
dtmort | 0:9e3e70548ec3 | 90 | 0 | 0 | 0 |
dtmort | 0:9e3e70548ec3 | 91 | 1 | 0 | 1 |
dtmort | 0:9e3e70548ec3 | 92 | 2 | 1 | 0 |
dtmort | 0:9e3e70548ec3 | 93 | 3 | 1 | 1 |
dtmort | 0:9e3e70548ec3 | 94 | @endcode |
dtmort | 0:9e3e70548ec3 | 95 | */ |
dtmort | 0:9e3e70548ec3 | 96 | void format(unsigned int bits=16, int mode=0); |
dtmort | 0:9e3e70548ec3 | 97 | |
dtmort | 0:9e3e70548ec3 | 98 | /** Set active state of the SPI bus chip select pin |
dtmort | 0:9e3e70548ec3 | 99 | * |
dtmort | 0:9e3e70548ec3 | 100 | * Constructor calls by default. Call only if change needed. |
dtmort | 0:9e3e70548ec3 | 101 | * |
dtmort | 0:9e3e70548ec3 | 102 | * @param cs 0 (default) for active-low, 1 for active-high |
dtmort | 0:9e3e70548ec3 | 103 | */ |
dtmort | 0:9e3e70548ec3 | 104 | void csactive(bool cs=0); |
dtmort | 0:9e3e70548ec3 | 105 | |
dtmort | 0:9e3e70548ec3 | 106 | /** Set the SPI bus clock frequency. |
dtmort | 0:9e3e70548ec3 | 107 | * Is maximum by default. Call only if change needed. |
dtmort | 0:9e3e70548ec3 | 108 | * |
dtmort | 0:9e3e70548ec3 | 109 | * Result will not be exact and may jump in 5Khz increments |
dtmort | 0:9e3e70548ec3 | 110 | * due to integer rounding. |
dtmort | 0:9e3e70548ec3 | 111 | * |
dtmort | 0:9e3e70548ec3 | 112 | * @param Hz Hertz 395,000 is approximate maximum (and default speed) |
dtmort | 0:9e3e70548ec3 | 113 | */ |
dtmort | 0:9e3e70548ec3 | 114 | void frequency(int Hz=400000); |
dtmort | 0:9e3e70548ec3 | 115 | |
dtmort | 0:9e3e70548ec3 | 116 | |
dtmort | 0:9e3e70548ec3 | 117 | /** Send a single bit on the SPI bus MOSI pin and read response on MISO pin |
dtmort | 0:9e3e70548ec3 | 118 | * |
dtmort | 0:9e3e70548ec3 | 119 | * @param bit Boolean one or zero, TRUE or FALSE |
dtmort | 0:9e3e70548ec3 | 120 | * @returns Boolean one or zero read from MISO from external hardware |
dtmort | 0:9e3e70548ec3 | 121 | */ |
dtmort | 0:9e3e70548ec3 | 122 | bool writebit(bool bit); |
dtmort | 0:9e3e70548ec3 | 123 | |
dtmort | 0:9e3e70548ec3 | 124 | /** Send a byte on the SPI bus MOSI pin and read response on MISO pin |
dtmort | 0:9e3e70548ec3 | 125 | * |
dtmort | 0:9e3e70548ec3 | 126 | * MSB first out, LSB last out (7:0) |
dtmort | 0:9e3e70548ec3 | 127 | * |
dtmort | 0:9e3e70548ec3 | 128 | * @param byte An 8-bit value |
dtmort | 0:9e3e70548ec3 | 129 | * @returns 8-bit value read from MISO from external hardware |
dtmort | 0:9e3e70548ec3 | 130 | */ |
dtmort | 0:9e3e70548ec3 | 131 | uint8_t writebyte(uint8_t byte); |
dtmort | 0:9e3e70548ec3 | 132 | |
dtmort | 0:9e3e70548ec3 | 133 | /** Send a word on the SPI bus MOSI pin and read response on MISO pin |
dtmort | 0:9e3e70548ec3 | 134 | * |
dtmort | 0:9e3e70548ec3 | 135 | * MSB first out, LSB last out (15:0) |
dtmort | 0:9e3e70548ec3 | 136 | * |
dtmort | 0:9e3e70548ec3 | 137 | * @param word A 16-bit value |
dtmort | 0:9e3e70548ec3 | 138 | * @returns 16-bit value read from MISO from external hardware |
dtmort | 0:9e3e70548ec3 | 139 | */ |
dtmort | 0:9e3e70548ec3 | 140 | uint16_t writeword(uint16_t word); |
dtmort | 0:9e3e70548ec3 | 141 | |
dtmort | 0:9e3e70548ec3 | 142 | |
dtmort | 0:9e3e70548ec3 | 143 | |
dtmort | 0:9e3e70548ec3 | 144 | //protected: |
dtmort | 0:9e3e70548ec3 | 145 | |
dtmort | 0:9e3e70548ec3 | 146 | private: |
dtmort | 0:9e3e70548ec3 | 147 | |
dtmort | 0:9e3e70548ec3 | 148 | void select(void); //activates chip select sequence, called by writebit() function |
dtmort | 0:9e3e70548ec3 | 149 | void deSelect(void); //deactivates chip select, called by writebit() function |
dtmort | 0:9e3e70548ec3 | 150 | DigitalOut _mosi; //master out slave in, pin |
dtmort | 0:9e3e70548ec3 | 151 | DigitalIn _miso; //master in slave out, pin |
dtmort | 0:9e3e70548ec3 | 152 | DigitalOut _sclk; //serial clock, pin |
dtmort | 0:9e3e70548ec3 | 153 | DigitalOut _cs; //chip select, pin |
dtmort | 0:9e3e70548ec3 | 154 | bool __cs; //chip select active state, operating setup |
dtmort | 0:9e3e70548ec3 | 155 | bool _cpol; //clock polarity, operating setup |
dtmort | 0:9e3e70548ec3 | 156 | bool _cpha; //clock phase, operating setup |
dtmort | 0:9e3e70548ec3 | 157 | int _mode; //mode 0,1,2 or 3, operating setup |
dtmort | 0:9e3e70548ec3 | 158 | unsigned int _deAssert; //counts-up bits sent for chip select, placeholder |
dtmort | 0:9e3e70548ec3 | 159 | unsigned int BitString; //# serialized bits sent to hardware string, controls chip select activation |
dtmort | 0:9e3e70548ec3 | 160 | unsigned int BitStream; //# bits to hardware from source data, not used yet |
dtmort | 0:9e3e70548ec3 | 161 | bool bit_read; //bit value read from miso pin |
dtmort | 0:9e3e70548ec3 | 162 | uint8_t byte_read; //byte value read from miso pin |
dtmort | 0:9e3e70548ec3 | 163 | uint16_t word_read; //word value read from miso pin |
dtmort | 0:9e3e70548ec3 | 164 | int Dcpwi; //Delay clock pulse width inactive, for freqency adjustments |
dtmort | 0:9e3e70548ec3 | 165 | int Dcpwa; //Delay clock pulse width active, for freqency adjustments |
dtmort | 0:9e3e70548ec3 | 166 | |
dtmort | 0:9e3e70548ec3 | 167 | }; |
dtmort | 0:9e3e70548ec3 | 168 | #endif |