From 4658591470f6776a18edf15625b31dbaef14a1b9 Mon Sep 17 00:00:00 2001 From: Theodore Ateba Date: Fri, 1 Sep 2017 22:42:58 +0000 Subject: Fixed SPI interruption enable, driver restart with different configuration. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10522 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.c | 111 ++++++++------------------ os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.h | 89 ++++++++++++--------- 2 files changed, 83 insertions(+), 117 deletions(-) (limited to 'os/hal') diff --git a/os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.c b/os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.c index a9bb13228..69480cfcd 100644 --- a/os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.c +++ b/os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.c @@ -15,7 +15,7 @@ */ /** - * @file hal_spi_lld.c + * @file AVR/hal_spi_lld.c * @brief AVR SPI subsystem low level driver source. * * @addtogroup SPI @@ -111,8 +111,6 @@ void spi_lld_start(SPIDriver *spip) { uint8_t dummy; - /* Configures the peripheral.*/ - if (spip->state == SPI_STOP) { /* Enables the peripheral.*/ #if AVR_SPI_USE_SPI1 @@ -123,75 +121,29 @@ void spi_lld_start(SPIDriver *spip) { #elif defined(PRR) PRR &= ~(1 << PRSPI); #endif - - /* SPI enable, SPI interrupt enable */ - SPCR |= ((1 << SPE) | (1 << SPIE)); - - SPCR |= (1 << MSTR); - DDR_SPI1 |= ((1 << SPI1_MOSI) | (1 << SPI1_SCK)); - DDR_SPI1 &= ~(1 << SPI1_MISO); - spip->config->ssport->dir |= (1 << spip->config->sspad); - - switch (spip->config->bitorder) { - case SPI_LSB_FIRST: - SPCR |= (1 << DORD); - break; - case SPI_MSB_FIRST: /* fallthrough */ - default: - SPCR &= ~(1 << DORD); - break; - } - - SPCR &= ~((1 << CPOL) | (1 << CPHA)); - switch (spip->config->mode) { - case SPI_MODE_1: - SPCR |= (1 << CPHA); - break; - case SPI_MODE_2: - SPCR |= (1 << CPOL); - break; - case SPI_MODE_3: - SPCR |= ((1 << CPOL) | (1 << CPHA)); - break; - case SPI_MODE_0: /* fallthrough */ - default: break; - } - - SPCR &= ~((1 << SPR1) | (1 << SPR0)); - SPSR &= ~(1 << SPI2X); - switch (spip->config->clockrate) { - case SPI_SCK_FOSC_2: - SPSR |= (1 << SPI2X); - break; - case SPI_SCK_FOSC_8: - SPSR |= (1 << SPI2X); - SPCR |= (1 << SPR0); - break; - case SPI_SCK_FOSC_16: - SPCR |= (1 << SPR0); - break; - case SPI_SCK_FOSC_32: - SPSR |= (1 << SPI2X); - SPCR |= (1 << SPR1); - break; - case SPI_SCK_FOSC_64: - SPCR |= (1 << SPR1); - break; - case SPI_SCK_FOSC_128: - SPCR |= ((1 << SPR1) | (1 << SPR0)); - break; - case SPI_SCK_FOSC_4: /* fallthrough */ - default: break; - } - - /* dummy reads before enabling interrupt */ - dummy = SPSR; - dummy = SPDR; - (void) dummy; /* suppress warning about unused variable */ - SPCR |= (1 << SPIE); +#endif } -#endif /* AVR_SPI_USE_SPI1 */ } + +#if AVR_SPI_USE_SPI1 + if (&SPID1 == spip) { + /* Configures the peripheral.*/ + /* Note that some bits are forced: + SPI interrupt disabled, + SPI enabled, + SPI master enabled */ + SPCR = (spip->config->spcr & ~(SPI_CR_SPIE)) | SPI_CR_MSTR | SPI_CR_SPE; + SPSR = spip->config->spsr; + + /* dummy reads before enabling interrupt */ + dummy = SPSR; + dummy = SPDR; + (void) dummy; /* suppress warning about unused variable */ + + /* Enable SPI interrupts */ + SPCR |= SPI_CR_SPIE; + } +#endif /* AVR_SPI_USE_SPI1 */ } /** @@ -209,8 +161,7 @@ void spi_lld_stop(SPIDriver *spip) { /* Disables the peripheral.*/ #if AVR_SPI_USE_SPI1 if (&SPID1 == spip) { - SPCR &= ((1 << SPIE) | (1 << SPE)); - spip->config->ssport->dir &= ~(1 << spip->config->sspad); + SPCR &= (SPI_CR_SPIE | SPI_CR_SPE); } /* Disable SPI clock using Power Reduction Register */ #if defined(PRR0) @@ -298,22 +249,23 @@ uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { uint16_t spdr = 0; uint8_t dummy; + (void)spip; /* disable interrupt */ - SPCR &= ~(1 << SPIE); + SPCR &= ~(SPI_CR_SPIE); SPDR = frame >> 8; - while (!(SPSR & (1 << SPIF))) ; + while (!(SPSR & SPI_SR_SPIF)) ; spdr = SPDR << 8; SPDR = frame & 0xFF; - while (!(SPSR & (1 << SPIF))) ; + while (!(SPSR & SPI_SR_SPIF)) ; spdr |= SPDR; dummy = SPSR; dummy = SPDR; (void) dummy; /* suppress warning about unused variable */ - SPCR |= (1 << SPIE); + SPCR |= SPI_CR_SPIE; return spdr; } @@ -322,18 +274,19 @@ uint8_t spi_lld_polled_exchange(SPIDriver *spip, uint8_t frame) { uint8_t spdr = 0; uint8_t dummy; + (void)spip; /* disable interrupt */ - SPCR &= ~(1 << SPIE); + SPCR &= ~(SPI_CR_SPIE); SPDR = frame; - while (!(SPSR & (1 << SPIF))) ; + while (!(SPSR & SPI_SR_SPIF)) ; spdr = SPDR; dummy = SPSR; dummy = SPDR; (void) dummy; /* suppress warning about unused variable */ - SPCR |= (1 << SPIE); + SPCR |= SPI_CR_SPIE; return spdr; } diff --git a/os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.h b/os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.h index 73d8ff856..23f13fbaf 100644 --- a/os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.h +++ b/os/hal/ports/AVR/MEGA/LLD/SPIv1/hal_spi_lld.h @@ -15,7 +15,7 @@ */ /** - * @file hal_spi_lld.h + * @file AVR/hal_spi_lld.h * @brief AVR SPI subsystem low level driver header. * * @addtogroup SPI @@ -31,29 +31,46 @@ /* Driver constants. */ /*===========================================================================*/ -/** @brief SPI Mode (Polarity/Phase) */ -#define SPI_CPOL0_CPHA0 0 -#define SPI_CPOL0_CPHA1 1 -#define SPI_CPOL1_CPHA0 2 -#define SPI_CPOL1_CPHA1 3 - -#define SPI_MODE_0 SPI_CPOL0_CPHA0 -#define SPI_MODE_1 SPI_CPOL0_CPHA1 -#define SPI_MODE_2 SPI_CPOL1_CPHA0 -#define SPI_MODE_3 SPI_CPOL1_CPHA1 - -/** @brief Bit order */ -#define SPI_LSB_FIRST 0 -#define SPI_MSB_FIRST 1 - -/** @brief SPI clock rate FOSC/x */ -#define SPI_SCK_FOSC_2 0 -#define SPI_SCK_FOSC_4 1 -#define SPI_SCK_FOSC_8 2 -#define SPI_SCK_FOSC_16 3 -#define SPI_SCK_FOSC_32 4 -#define SPI_SCK_FOSC_64 5 -#define SPI_SCK_FOSC_128 6 +/** + * @name SPI Configuration Register + * @{ + */ +#define SPI_CR_SPIE (1 << SPIE) + +#define SPI_CR_SPE (1 << SPE) + +#define SPI_CR_DORD_MSB_FIRST (0 << DORD) +#define SPI_CR_DORD_LSB_FIRST (1 << DORD) + +#define SPI_CR_MSTR (1 << MSTR) + +#define SPI_CR_CPOL_CPHA_MODE(n) ((n) << CPHA) + +#define SPI_CR_SCK_FOSC_2 (0 << SPR0) +#define SPI_CR_SCK_FOSC_4 (0 << SPR0) +#define SPI_CR_SCK_FOSC_8 (1 << SPR0) +#define SPI_CR_SCK_FOSC_16 (1 << SPR0) +#define SPI_CR_SCK_FOSC_32 (2 << SPR0) +#define SPI_CR_SCK_FOSC_64 (2 << SPR0) +#define SPI_CR_SCK_FOSC_128 (3 << SPR0) +/** @} */ + +/** + * @name SPI Status Register + * { + */ +#define SPI_SR_SPIF (1 << SPIF) + +#define SPI_SR_WCOL (1 << WCOL) + +#define SPI_SR_SCK_FOSC_2 (1 << SPI2X) +#define SPI_SR_SCK_FOSC_4 (0 << SPI2X) +#define SPI_SR_SCK_FOSC_8 (1 << SPI2X) +#define SPI_SR_SCK_FOSC_16 (0 << SPI2X) +#define SPI_SR_SCK_FOSC_32 (1 << SPI2X) +#define SPI_SR_SCK_FOSC_64 (0 << SPI2X) +#define SPI_SR_SCK_FOSC_128 (0 << SPI2X) +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -68,7 +85,7 @@ * @details If set to @p TRUE the support for SPI1 is included. */ #if !defined(AVR_SPI_USE_SPI1) || defined(__DOXYGEN__) -#define AVR_SPI_USE_SPI1 FALSE +#define AVR_SPI_USE_SPI1 FALSE #endif /** @} */ @@ -99,6 +116,11 @@ typedef void (*spicallback_t)(SPIDriver *spip); * architecture dependent, fields. */ typedef struct { + /** + * @brief Operation complete callback. + */ + spicallback_t end_cb; + /* End of the mandatory fields.*/ /** * @brief Port used of Slave Select */ @@ -108,22 +130,13 @@ typedef struct { */ uint8_t sspad; /** - * @brief Polarity/Phase mode + * @brief SPI Control Register initialization data. */ - uint8_t mode; + uint8_t spcr; /** - * @brief Use MSB/LSB first? + * @brief SPI Status Register initialization data. */ - uint8_t bitorder; - /** - * @brief Clock rate of the subsystem - */ - uint8_t clockrate; - /** - * @brief Operation complete callback. - */ - spicallback_t end_cb; - /* End of the mandatory fields.*/ + uint8_t spsr; } SPIConfig; /** -- cgit v1.2.3