Class to be able to send SPI data with almost no overhead, useful at very high speeds.

Dependents:   MakerBotServer epaper_mbed_130411_KL25Z epaper_mbed_test epaper_mbed_test_copy1 ... more

General

BurstSPI sends SPI data without reading it back, allowing higher speeds than the regular SPI library. This is mainly useful at high frequencies and large payloads. With a small number of bytes the setting up and finishing time will remove any advantage.

The three new functions compared to regular SPI are: fastWrite, setFormat and clearRX.

fastWrite is the function to quickly write data. setFormat is only required if the SPI format might have changed, or the first time you fastWrite something and you haven't used a regular SPI write before. clearRX is required if you also want to be able read from the SPI peripheral later on.

//Send 1000 SPI packets as fast as possible
spi.setFormat();
for (int i = 0; i<1000; i++)
    spi.fastWrite(data[i]);
spi.clearRX();

Supported targets

  • KL25Z, KL46Z
  • LPC1768, LPC11u24, LPC1114, LPC1549, LPC1347
  • STML152RE

If a target is not supported the library will issue a warning, and use regular writes. This means if you for example use this library to speed up writing to an LCD display, your LCD display library will work on all targets, and if possible BurstSPI will speed up the process.

Committer:
Sissors
Date:
Thu Jul 04 19:03:58 2013 +0000
Revision:
3:7d9b64d67b22
Parent:
2:a8e55f7cbfee
Refactored code, added version 1 of KL25Z support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:600eecd89a78 1 #ifndef BURSTSPI_H
Sissors 0:600eecd89a78 2 #define BURSTSPI_H
Sissors 0:600eecd89a78 3
Sissors 0:600eecd89a78 4 #include "mbed.h"
Sissors 0:600eecd89a78 5
Sissors 0:600eecd89a78 6
Sissors 0:600eecd89a78 7 /** An SPI Master, used for communicating with SPI slave devices at very high speeds
Sissors 0:600eecd89a78 8 *
frankvnk 2:a8e55f7cbfee 9 * The default mbed SPI class allows for communication via the SPI bus at high clock frequencies,
frankvnk 2:a8e55f7cbfee 10 * however at these frequencies there is alot of overhead from the mbed code.
frankvnk 2:a8e55f7cbfee 11 * While this code makes sure your code is alot more robust, it is also relative slow.
frankvnk 2:a8e55f7cbfee 12 * This library adds to your default SPI commands some extra commands to transmit data rapidly with
frankvnk 2:a8e55f7cbfee 13 * very little overhead. Downsides are that currently it is TX only (all RX packets are discarded),
frankvnk 2:a8e55f7cbfee 14 * and it requires some extra commands.
Sissors 0:600eecd89a78 15 *
Sissors 0:600eecd89a78 16 * Example:
Sissors 0:600eecd89a78 17 * @code
Sissors 0:600eecd89a78 18 * //Send 1000 SPI packets as fast as possible
Sissors 0:600eecd89a78 19 * spi.setFormat();
Sissors 0:600eecd89a78 20 * for (int i = 0; i<1000; i++)
Sissors 0:600eecd89a78 21 * spi.fastWrite(data[i]);
Sissors 0:600eecd89a78 22 * spi.clearRX();
Sissors 0:600eecd89a78 23 * @endcode
Sissors 0:600eecd89a78 24 *
frankvnk 2:a8e55f7cbfee 25 * As an example, writing 76,800 16-bit data packets to an LCD screen at 48MHz requires 111ms with
frankvnk 2:a8e55f7cbfee 26 * the normal mbed library. With this library it takes 25ms, which is also the theoretical
Sissors 0:600eecd89a78 27 * amount of time it should take. If you are running at 1MHz this will do alot less.
Sissors 0:600eecd89a78 28 */
Sissors 3:7d9b64d67b22 29 class BurstSPI : public SPI
Sissors 3:7d9b64d67b22 30 {
Sissors 0:600eecd89a78 31 public:
Sissors 0:600eecd89a78 32 /** Create a SPI master connected to the specified pins
Sissors 0:600eecd89a78 33 *
Sissors 0:600eecd89a78 34 * Pin Options:
Sissors 0:600eecd89a78 35 * (5, 6, 7) or (11, 12, 13)
Sissors 0:600eecd89a78 36 *
Sissors 0:600eecd89a78 37 * mosi or miso can be specfied as NC if not used
Sissors 0:600eecd89a78 38 *
Sissors 0:600eecd89a78 39 * @param mosi SPI Master Out, Slave In pin
Sissors 0:600eecd89a78 40 * @param miso SPI Master In, Slave Out pin
Sissors 0:600eecd89a78 41 * @param sclk SPI Clock pin
Sissors 0:600eecd89a78 42 */
Sissors 3:7d9b64d67b22 43 BurstSPI(PinName mosi, PinName miso, PinName sclk) : SPI(mosi, miso, sclk) {};
Sissors 0:600eecd89a78 44
Sissors 0:600eecd89a78 45 /** Put data packet in the SPI TX FIFO buffer
Sissors 0:600eecd89a78 46 *
frankvnk 2:a8e55f7cbfee 47 * If there is no space in the FIFO buffer it will block until there is space.
frankvnk 2:a8e55f7cbfee 48 * The FIFO buffer will automatically send the packets. There is no receiving here, only transmitting.
Sissors 0:600eecd89a78 49 *
Sissors 0:600eecd89a78 50 * @param data Data to be sent to the SPI slave
Sissors 0:600eecd89a78 51 */
Sissors 0:600eecd89a78 52 void fastWrite(int data);
Sissors 3:7d9b64d67b22 53
Sissors 0:600eecd89a78 54 /** Use this function before fastWrite to set the correct settings
Sissors 3:7d9b64d67b22 55 *
frankvnk 2:a8e55f7cbfee 56 * It is not needed to use this if the last SPI commands were either normal SPI transmissions,
frankvnk 2:a8e55f7cbfee 57 * or setting different format/frequency for this object. It is required to call this
frankvnk 2:a8e55f7cbfee 58 * function when several SPI objects use the same peripheral, and your last transmission was
frankvnk 2:a8e55f7cbfee 59 * from a different object with different settings. Not sure if you should use it?
Sissors 0:600eecd89a78 60 * Use it, it takes very little time to execute, so can't hurt.
Sissors 0:600eecd89a78 61 */
Sissors 3:7d9b64d67b22 62 void setFormat( void ) {
Sissors 3:7d9b64d67b22 63 format(_bits, _mode);
Sissors 3:7d9b64d67b22 64 frequency(_hz);
Sissors 3:7d9b64d67b22 65 }
Sissors 3:7d9b64d67b22 66
Sissors 0:600eecd89a78 67 /** After you are done with fastWrite, call this function
Sissors 0:600eecd89a78 68 *
frankvnk 2:a8e55f7cbfee 69 * FastWrite simply fills the SPI's (SSP's actually) TX FIFO buffer as fast as it can,
frankvnk 2:a8e55f7cbfee 70 * and that is the only thing it does. It doesn't do anything with received packages (currently, may change),
frankvnk 2:a8e55f7cbfee 71 * so the the RX buffer is full with unneeded packets. This function waits until transmission is finished,
frankvnk 2:a8e55f7cbfee 72 * and clears the RX buffer. You always have to call this before you want to receive
Sissors 0:600eecd89a78 73 * SPI data after using fastWrite.
Sissors 3:7d9b64d67b22 74 */
Sissors 0:600eecd89a78 75 void clearRX( void );
Sissors 3:7d9b64d67b22 76
Sissors 3:7d9b64d67b22 77
Sissors 0:600eecd89a78 78 //Just for documentation:
Sissors 3:7d9b64d67b22 79 #if 0
Sissors 0:600eecd89a78 80 /** Configure the data transmission format
Sissors 0:600eecd89a78 81 *
Sissors 0:600eecd89a78 82 * @param bits Number of bits per SPI frame (4 - 16)
Sissors 0:600eecd89a78 83 * @param mode Clock polarity and phase mode (0 - 3)
Sissors 0:600eecd89a78 84 *
Sissors 0:600eecd89a78 85 * @code
Sissors 3:7d9b64d67b22 86 * mode | POL PHA
Sissors 3:7d9b64d67b22 87 * -----+--------
Sissors 3:7d9b64d67b22 88 * 0 | 0 0
Sissors 0:600eecd89a78 89 * 1 | 0 1
Sissors 3:7d9b64d67b22 90 * 2 | 1 0
Sissors 0:600eecd89a78 91 * 3 | 1 1
Sissors 0:600eecd89a78 92 * @endcode
Sissors 0:600eecd89a78 93 */
Sissors 0:600eecd89a78 94 void format(int bits, int mode = 0);
Sissors 3:7d9b64d67b22 95
Sissors 0:600eecd89a78 96 /** Set the spi bus clock frequency
Sissors 0:600eecd89a78 97 *
Sissors 0:600eecd89a78 98 * @param hz SCLK frequency in hz (default = 1MHz)
Sissors 0:600eecd89a78 99 */
Sissors 0:600eecd89a78 100 void frequency(int hz = 1000000);
Sissors 3:7d9b64d67b22 101
Sissors 0:600eecd89a78 102 /** Write to the SPI Slave and return the response
Sissors 0:600eecd89a78 103 *
Sissors 0:600eecd89a78 104 * @param value Data to be sent to the SPI slave
Sissors 0:600eecd89a78 105 *
Sissors 0:600eecd89a78 106 * @returns
Sissors 0:600eecd89a78 107 * Response from the SPI slave
Sissors 0:600eecd89a78 108 */
Sissors 0:600eecd89a78 109 virtual int write(int value);
Sissors 3:7d9b64d67b22 110 #endif
Sissors 0:600eecd89a78 111
Sissors 0:600eecd89a78 112 };
Sissors 0:600eecd89a78 113
Sissors 0:600eecd89a78 114 #endif