Fork of RTOS_SPI that removes SimpleDMA from direct include to correct linker issues when using SimpleDMA twice Note that this library is still required!
Fork of RTOS_SPI by
Revision 0:004e5e86de4e, committed 2013-12-26
- Comitter:
- Sissors
- Date:
- Thu Dec 26 14:14:44 2013 +0000
- Child:
- 1:d021fb155bff
- Commit message:
- v1.0 for KL25
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RTOS_SPI.cpp Thu Dec 26 14:14:44 2013 +0000 @@ -0,0 +1,37 @@ +#include "RTOS_SPI.h" + +RTOS_SPI::RTOS_SPI(PinName mosi, PinName miso, PinName sclk, PinName _unused) : SPI(mosi, miso, sclk) { + if (_spi.spi == SPI0) { + read_dma.trigger(Trigger_SPI0_RX); + write_dma.trigger(Trigger_SPI0_TX); + } else { + read_dma.trigger(Trigger_SPI1_RX); + write_dma.trigger(Trigger_SPI1_TX); + } + + read_dma.source(&_spi.spi->D, false); + write_dma.destination(&_spi.spi->D, false); +}; + +void RTOS_SPI::bulkInternal(uint8_t *read_data, uint8_t *write_data, int length, bool read_inc, bool write_inc) { + aquire(); + _spi.spi->C2 |= SPI_C2_TXDMAE_MASK | SPI_C2_RXDMAE_MASK; + + read_dma.destination(read_data, read_inc); + if (write_inc) + write_dma.source(write_data+1, write_inc); + else + write_dma.source(write_data, write_inc); + + //simply start the read_dma + read_dma.start(length); + + //Write the first byte manually, since this is recommended method (and the normal method sends the first byte twice) + while((_spi.spi->S & SPI_S_SPTEF_MASK) == 0); + _spi.spi->D = write_data[0]; + + write_dma.wait(length-1); + while(read_dma.isBusy()); + + _spi.spi->C2 &= ~(SPI_C2_TXDMAE_MASK | SPI_C2_RXDMAE_MASK); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RTOS_SPI.h Thu Dec 26 14:14:44 2013 +0000 @@ -0,0 +1,66 @@ +#ifndef RTOS_SPI_H +#define RTOS_SPI_H + +#include "mbed.h" +#include "rtos.h" +#include "SimpleDMA.h" + +/** +* RTOS_SPI uses SimpleDMA to control SPI using DMA. +* +* As the name says it is intended to be used with RTOS. +* The current Thread is paused until it is done, meanwhile +* other Threads will continue to run. Once finished the +* Thread will continue. +* +* This is a child class of SPI, so all regular SPI functions +* are available + two for DMA control. +*/ +class RTOS_SPI: public SPI { + public: + /** Create a SPI master connected to the specified pins + * + * mosi or miso can be specfied as NC if not used + * + * @param mosi - SPI Master Out, Slave In pin + * @param miso - SPI Master In, Slave Out pin + * @param sclk - SPI Clock pin + */ + RTOS_SPI(PinName mosi, PinName miso, PinName sclk, PinName _unused=NC); + + /** + * Write a block of data via SPI + * + * This throws away all read data + * + * @param *write_data - uint8_t pointer to data to write + * @param length - number of bytes to write + * @param array - true if write_data is an array, false if it is a single constant value + */ + void bulkWrite(uint8_t *write_data, int length, bool array = true) { + uint8_t dummy; + bulkInternal(&dummy, write_data, length, false, array); + } + + /** + * Write a block of data via SPI, read returning value + * + * @param *read_data - uint8_t pointer to array where received data should be stored + * @param *write_data - uint8_t pointer to data to write + * @param length - number of bytes to write + * @param array - true if write_data is an array, false if it is a single constant value + */ + void bulkReadWrite(uint8_t *read_data, uint8_t *write_data, int length, bool array = true) { + bulkInternal(read_data, write_data, length, true, array); + } + + private: + void bulkInternal(uint8_t *read_data, uint8_t *write_data, int length, bool read_inc, bool write_inc); + + SimpleDMA read_dma; + SimpleDMA write_dma; + +}; + + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SimpleDMA.lib Thu Dec 26 14:14:44 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Sissors/code/SimpleDMA/#34f5bf8adfa0