mbed library sources

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Thu Jul 24 12:00:06 2014 +0100
Parent:
265:9632ea190e16
Child:
267:8673334f2cbe
Commit message:
Synchronized with git revision 928b206625931afb76627d6d4dd92aacaa8cf7e4

Full URL: https://github.com/mbedmicro/mbed/commit/928b206625931afb76627d6d4dd92aacaa8cf7e4/

Fixed three issues with the SPI driver for the LPC1549 platform:

Changed in this revision

targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c	Wed Jul 23 21:15:06 2014 +0100
+++ b/targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c	Thu Jul 24 12:00:06 2014 +0100
@@ -43,13 +43,69 @@
 
 // bit flags for used SPIs
 static unsigned char spi_used = 0;
-static int get_available_spi(void)
+static int get_available_spi(PinName mosi, PinName miso, PinName sclk, PinName ssel)
 {
-    int i;
-    for (i=0; i<2; i++) {
-        if ((spi_used & (1 << i)) == 0)
-            return i;
+    if (spi_used == 0) {
+        return 0; // The first user
     }
+
+    const SWM_Map *swm;
+    uint32_t regVal;
+
+    // Investigate if same pins as the used SPI0/1 - to be able to reuse it
+    for (int spi_n = 0; spi_n < 2; spi_n++) {
+        if (spi_used & (1<<spi_n)) {
+            if (sclk != NC) {
+                swm = &SWM_SPI_SCLK[spi_n];
+                regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset);
+                if (regVal != (sclk << swm->offset)) {
+                    // Existing pin is not the same as the one we want
+                    continue;
+                }
+            }
+
+            if (mosi != NC) {
+                swm = &SWM_SPI_MOSI[spi_n];
+                regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset);
+                if (regVal != (mosi << swm->offset)) {
+                    // Existing pin is not the same as the one we want
+                    continue;
+                }
+            }
+
+            if (miso != NC) {
+                swm = &SWM_SPI_MISO[spi_n];
+                regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset);
+                if (regVal != (miso << swm->offset)) {
+                    // Existing pin is not the same as the one we want
+                    continue;
+                }
+            }
+
+            if (ssel != NC) {
+                swm = &SWM_SPI_SSEL[spi_n];
+                regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset);
+                if (regVal != (ssel << swm->offset)) {
+                    // Existing pin is not the same as the one we want
+                    continue;
+                }
+            }
+
+            // The pins for the currently used SPIx are the same as the
+            // ones we want so we will reuse it
+            return spi_n;
+        }
+    }
+
+    // None of the existing SPIx pin setups match the pins we want
+    // so the last hope is to select one unused SPIx
+    if ((spi_used & 1) == 0) {
+        return 0;
+    } else if ((spi_used & 2) == 0) {
+        return 1;
+    }
+
+    // No matching setup and no free SPIx
     return -1;
 }
 
@@ -58,7 +114,7 @@
 
 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
 {
-    int spi_n = get_available_spi();
+    int spi_n = get_available_spi(mosi, miso, sclk, ssel);
     if (spi_n == -1) {
         error("No available SPI");
     }
@@ -138,10 +194,10 @@
     obj->spi->CFG = tmp;
 
     // select frame length
-    tmp = obj->spi->TXDATCTL;
+    tmp = obj->spi->TXCTL;
     tmp &= ~(0xf << 24);
     tmp |= (LEN << 24);
-    obj->spi->TXDATCTL = tmp;
+    obj->spi->TXCTL = tmp;
 
     spi_enable(obj);
 }
@@ -181,14 +237,14 @@
 {
     while (!spi_writeable(obj));
     // end of transfer
-    obj->spi->TXDATCTL |= (1 << 20);
-    obj->spi->TXDAT = value;
+    obj->spi->TXCTL |= (1 << 20);
+    obj->spi->TXDAT = (value & 0xffff);
 }
 
 static inline int spi_read(spi_t *obj)
 {
     while (!spi_readable(obj));
-    return obj->spi->RXDAT;
+    return obj->spi->RXDAT & 0xffff; // Only the lower 16 bits contain data
 }
 
 int spi_busy(spi_t *obj)
@@ -210,7 +266,7 @@
 
 int spi_slave_read(spi_t *obj)
 {
-    return obj->spi->RXDAT;
+    return obj->spi->RXDAT & 0xffff; // Only the lower 16 bits contain data
 }
 
 void spi_slave_write(spi_t *obj, int value)