Uses DMA to read/write SPI blocks, while putting the current thread in Wait state.

Dependencies:   SimpleDMA

Dependents:   SDFileSystem-RTOS

Files at this revision

API Documentation at this revision

Comitter:
Tomo2k
Date:
Fri Jun 27 10:12:42 2014 +0000
Parent:
1:d021fb155bff
Child:
3:2ef44ef2094b
Commit message:
Added support for KL46

Changed in this revision

RTOS_SPI.h Show annotated file Show diff for this revision Revisions of this file
RTOS_SPI_KL25.cpp Show annotated file Show diff for this revision Revisions of this file
RTOS_SPI_KL46.cpp Show annotated file Show diff for this revision Revisions of this file
RTOS_SPI_LPC1768.cpp Show annotated file Show diff for this revision Revisions of this file
SimpleDMA.lib Show annotated file Show diff for this revision Revisions of this file
--- a/RTOS_SPI.h	Sun Jan 05 10:20:17 2014 +0000
+++ b/RTOS_SPI.h	Fri Jun 27 10:12:42 2014 +0000
@@ -15,6 +15,8 @@
 *
 * This is a child class of SPI, so all regular SPI functions
 * are available + two for DMA control.
+*
+* @note Only supports 8-bit SPI. The 16-bit SPI mode of the KL46Z is not supported.
 */
 class RTOS_SPI: public SPI {
     public:
@@ -37,7 +39,7 @@
     * @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) {
+    void bulkWrite(const uint8_t *write_data, int length, bool array = true) {
         uint8_t dummy;
         bulkInternal(&dummy, write_data, length, false, array);
     }
@@ -50,12 +52,12 @@
     * @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) {
+    void bulkReadWrite(uint8_t *read_data, const 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);
+    void bulkInternal(uint8_t *read_data, const uint8_t *write_data, int length, bool read_inc, bool write_inc);
     
     SimpleDMA read_dma;
     SimpleDMA write_dma;
--- a/RTOS_SPI_KL25.cpp	Sun Jan 05 10:20:17 2014 +0000
+++ b/RTOS_SPI_KL25.cpp	Fri Jun 27 10:12:42 2014 +0000
@@ -14,7 +14,7 @@
     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) {
+void RTOS_SPI::bulkInternal(uint8_t *read_data, const uint8_t *write_data, int length, bool read_inc, bool write_inc) {
     aquire();
     _spi.spi->C2 |= SPI_C2_TXDMAE_MASK | SPI_C2_RXDMAE_MASK;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RTOS_SPI_KL46.cpp	Fri Jun 27 10:12:42 2014 +0000
@@ -0,0 +1,39 @@
+#ifdef TARGET_KL46Z
+#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->DL, false);          // 8-bit SPI only uses the LSB
+    write_dma.destination(&_spi.spi->DL, false);    // 8-bit SPI only uses the LSB
+};
+
+void RTOS_SPI::bulkInternal(uint8_t *read_data, const 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->DL = write_data[0];                   // 8-bit SPI only uses the LSB
+    
+    write_dma.wait(length-1);
+    while(read_dma.isBusy());
+
+    _spi.spi->C2 &= ~(SPI_C2_TXDMAE_MASK | SPI_C2_RXDMAE_MASK);
+}
+#endif
--- a/RTOS_SPI_LPC1768.cpp	Sun Jan 05 10:20:17 2014 +0000
+++ b/RTOS_SPI_LPC1768.cpp	Fri Jun 27 10:12:42 2014 +0000
@@ -14,7 +14,7 @@
     write_dma.destination(&_spi.spi->DR, false, 8);
 };
 
-void RTOS_SPI::bulkInternal(uint8_t *read_data, uint8_t *write_data, int length, bool read_inc, bool write_inc) {
+void RTOS_SPI::bulkInternal(uint8_t *read_data, const uint8_t *write_data, int length, bool read_inc, bool write_inc) {
     aquire();
     _spi.spi->DMACR = 3;
 
--- a/SimpleDMA.lib	Sun Jan 05 10:20:17 2014 +0000
+++ b/SimpleDMA.lib	Fri Jun 27 10:12:42 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/Sissors/code/SimpleDMA/#d9f46ef80e20
+http://mbed.org/users/Sissors/code/SimpleDMA/#d3be727fa9d2