From da3c7c5e60ee36795e711f8d2dfe8e92287433fa Mon Sep 17 00:00:00 2001 From: Sissors Date: Sun, 18 May 2014 09:40:39 +0200 Subject: [PATCH] K20D5(0)M SPI code Other pinouts still need to be done. PTC6 as MOSI possibly has issues. There are also some changes which technically aren't required, but were made in the search to why on earth it wasn't doing anything. --- .../TARGET_Freescale/TARGET_K20D5M/spi_api.c | 52 ++++++++----------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/spi_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/spi_api.c index 3075a33a49..2bc6691dfa 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/spi_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/spi_api.c @@ -54,7 +54,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel 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 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel 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 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel // 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 @@ void spi_free(spi_t *obj) { // [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 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) { 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_writeable(spi_t *obj) { } 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));