mbed library sources
Dependents: frdm_kl05z_gpio_test
Fork of mbed-src by
Diff: targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c
- Revision:
- 266:69e8a32876bd
- Parent:
- 261:ee1cf08b7bc7
- Child:
- 285:31249416b6f9
diff -r 9632ea190e16 -r 69e8a32876bd targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c --- 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)