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

Dependencies:   mbed

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