From 7423bd3d7b9463c0f0fcd34a0150ae73031ce57b Mon Sep 17 00:00:00 2001 From: Sissors Date: Sun, 6 Sep 2015 20:34:46 +0200 Subject: [PATCH] [HAL][K20XX] Fixed (possibly) glitches when changing SPI mode on K20 MCUs Made register access bit nicer (not first clearing bit and then setting it again if thats not required), and additionally when clock idle level is changed, it writes out a dummy byte. Problem is only after a write the idle level is changed, resulting in a clock glitch at the start --- .../TARGET_Freescale/TARGET_K20XX/spi_api.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/spi_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/spi_api.c index 5f1313b131..789150f3e1 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/spi_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/spi_api.c @@ -68,16 +68,27 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) { MBED_ASSERT((bits > 4) || (bits < 16)); MBED_ASSERT((mode >= 0) && (mode <= 3)); - uint32_t polarity = (mode & 0x2) ? 1 : 0; - uint32_t phase = (mode & 0x1) ? 1 : 0; + uint8_t polarity = (mode & 0x2) ? 1 : 0; + uint8_t phase = (mode & 0x1) ? 1 : 0; + uint8_t old_polarity = (obj->spi->CTAR[0] & SPI_CTAR_CPOL_MASK) != 0; // set master/slave - obj->spi->MCR &= ~SPI_MCR_MSTR_MASK; - obj->spi->MCR |= ((!slave) << SPI_MCR_MSTR_SHIFT); + if (slave) { + obj->spi->MCR &= ~SPI_MCR_MSTR_MASK; + } else { + obj->spi->MCR |= (1UL << SPI_MCR_MSTR_SHIFT); + } // CTAR0 is used 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); + + //If clk idle state was changed, start a dummy transmission + //This is a 'feature' in DSPI: https://community.freescale.com/thread/105526 + if ((old_polarity != polarity) && (slave == 0)) { + //Start transfer (CS should be high, so shouldn't matter) + spi_master_write(obj, 0xFFFF); + } } static const uint8_t baudrate_prescaler[] = {2,3,5,7};