Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
Diff: targets/hal/TARGET_Freescale/TARGET_K20D5M/spi_api.c
- Revision:
- 195:442092318da6
- Parent:
- 73:299c67215126
- Child:
- 227:7bd0639b8911
--- a/targets/hal/TARGET_Freescale/TARGET_K20D5M/spi_api.c Fri May 16 16:15:06 2014 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_K20D5M/spi_api.c Mon May 19 08:15:19 2014 +0100
@@ -54,7 +54,7 @@
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
-
+
obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl);
if ((int)obj->spi == NC) {
error("SPI pinout mapping failed");
@@ -63,9 +63,8 @@
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK;
SIM->SCGC6 |= SIM_SCGC6_SPI0_MASK;
- // halted state
- obj->spi->MCR &= ~SPI_MCR_MDIS_MASK;
- obj->spi->MCR |= SPI_MCR_HALT_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK;
+ obj->spi->MCR &= ~(SPI_MCR_MDIS_MASK | SPI_MCR_HALT_MASK);
+ //obj->spi->MCR |= SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK;
// set default format and frequency
if (ssel == NC) {
@@ -77,8 +76,6 @@
// not halt in the debug mode
obj->spi->SR |= SPI_SR_EOQF_MASK;
- // enable SPI
- obj->spi->MCR &= (~SPI_MCR_HALT_MASK);
// pin out the spi pins
pinmap_pinout(mosi, PinMap_SPI_MOSI);
@@ -93,9 +90,9 @@
// [TODO]
}
void spi_format(spi_t *obj, int bits, int mode, int slave) {
- if ((bits != 8) && (bits != 16)) {
- error("Only 8/16 bits SPI supported");
- }
+ if ((bits < 4) || (bits > 16))
+ error("SPI: Only frames between 4 and 16-bit supported");
+
if ((mode < 0) || (mode > 3)) {
error("SPI mode unsupported");
@@ -109,48 +106,45 @@
obj->spi->MCR |= ((!slave) << SPI_MCR_MSTR_SHIFT);
// CTAR0 is used
- obj->spi->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK);
- obj->spi->CTAR[0] |= (polarity << SPI_CTAR_CPOL_SHIFT) | (phase << SPI_CTAR_CPHA_SHIFT);
+ obj->spi->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_FMSZ_MASK);
+ obj->spi->CTAR[0] |= (polarity << SPI_CTAR_CPOL_SHIFT) | (phase << SPI_CTAR_CPHA_SHIFT) | ((bits - 1) << SPI_CTAR_FMSZ_SHIFT);
}
static const uint8_t baudrate_prescaler[] = {2,3,5,7};
-static const uint32_t baudrate_scaler[] = {2, 4, 6, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
-static const uint8_t delay_prescaler[] = {1, 3, 5, 7};
+static const uint16_t baudrate_scaler[] = {2,4,6,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
void spi_frequency(spi_t *obj, int hz) {
- uint32_t error = 0;
+ uint32_t f_error = 0;
uint32_t p_error = 0xffffffff;
uint32_t ref = 0;
uint32_t br = 0;
uint32_t ref_spr = 0;
uint32_t ref_prescaler = 0;
+ uint32_t ref_dr = 0;
// bus clk
uint32_t PCLK = bus_frequency();
- uint32_t divisor = 2;
- uint32_t prescaler;
- /* TODO */
for (uint32_t i = 0; i < 4; i++) {
- prescaler = baudrate_prescaler[i];
- divisor = 2;
- for (br = 0; br <= 15; br++, divisor *= 2) {
+ for (br = 0; br <= 15; br++) {
for (uint32_t dr = 0; dr < 2; dr++) {
- ref = (PCLK / prescaler) * ((1U + dr) / divisor);
+ ref = (PCLK * (1U + dr) / baudrate_prescaler[i]) / baudrate_scaler[br];
if (ref > (uint32_t)hz)
continue;
- error = hz - ref;
- if (error < p_error) {
+ f_error = hz - ref;
+ if (f_error < p_error) {
ref_spr = br;
ref_prescaler = i;
- p_error = error;
+ ref_dr = dr;
+ p_error = f_error;
}
}
}
}
// set PBR and BR
- obj->spi->CTAR[0] = ((ref_prescaler & 0x3) << SPI_CTAR_PBR_SHIFT) | (ref_spr & 0xf);
+ obj->spi->CTAR[0] &= ~(SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK | SPI_CTAR_DBR_MASK);
+ obj->spi->CTAR[0] |= (ref_prescaler << SPI_CTAR_PBR_SHIFT) | (ref_spr << SPI_CTAR_BR_SHIFT) | (ref_dr << SPI_CTAR_DBR_SHIFT);
}
static inline int spi_writeable(spi_t *obj) {
@@ -158,15 +152,15 @@
}
static inline int spi_readable(spi_t *obj) {
- return (obj->spi->SR & SPI_SR_RFDF_MASK) ? 0 : 1;
+ return (obj->spi->SR & SPI_SR_RFDF_MASK) ? 1 : 0;
}
int spi_master_write(spi_t *obj, int value) {
+ //clear RX buffer flag
+ obj->spi->SR |= SPI_SR_RFDF_MASK;
// wait tx buffer empty
while(!spi_writeable(obj));
- obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xff) /*| SPI_PUSHR_EOQ_MASK*/;
-
- while (!obj->spi->SR & SPI_SR_TCF_MASK); // wait for transfer to be complete
+ obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xffff) /*| SPI_PUSHR_EOQ_MASK*/;
// wait rx buffer full
while (!spi_readable(obj));
