CLASS for software SPI master class instantiated on any general IO pin. Slow but flexible.

Dependencies:   mbed

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?

UserRevisionLine numberNew 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