Improved the SPI driver for ADuCM36x introducing a cell reset on spi_lld_start and fixing a mismanagement of the TX buffer in the the ISR.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13140 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Rocco Marco Guglielmi 2019-10-23 09:26:58 +00:00
parent 5c08575971
commit be28a47f11
1 changed files with 47 additions and 11 deletions

View File

@ -81,23 +81,41 @@ static void spi_lld_serve_interrupt(SPIDriver *spip) {
dummy_rx = spip->spi->SPIRX; dummy_rx = spip->spi->SPIRX;
} }
/* Pushing the new TX: this will start a new transfert. */ /* Pushing the new TX: this will start a new transfer. */
if(spip->txbuf != NULL) { if((spip->txbuf != NULL) && (spip->size > 0)) {
spip->spi->SPITX = *(spip->txbuf);
(spip->txbuf)++; (spip->txbuf)++;
spip->spi->SPITX = *(spip->txbuf);
} }
else { else {
spip->spi->SPITX = dummy_tx; spip->spi->SPITX = dummy_tx;
} }
if(spip->size == 0) {
/* Portable SPI ISR code defined in the high level driver, note, it is
a macro.*/
_spi_isr_code(spip);
}
(void)dummy_rx; (void)dummy_rx;
} }
}
if(spip->size == 0) { /**
/* Portable SPI ISR code defined in the high level driver, note, it is * @brief Utility function useful to clean-up the SPI cell.
a macro.*/ *
_spi_isr_code(spip); * @param[in] spip pointer to the @p SPIDriver object
} */
static void spi_lld_reset_spi_cell(SPIDriver* spip) {
uint32_t sta;
/* Disabling the SPI. And flushing RX and TX buffers. */
spip->spi->SPICON = ADUCM_SPI_CON_RFLUSH | ADUCM_SPI_CON_TFLUSH;
spip->spi->SPICON = 0;
/* Cleaning IRQs. */
sta = spip->spi->SPISTA;
(void) sta;
} }
/*===========================================================================*/ /*===========================================================================*/
@ -185,6 +203,9 @@ void spi_lld_start(SPIDriver *spip) {
if (&SPID0 == spip) { if (&SPID0 == spip) {
/* Enabling peripheral clock branch. */ /* Enabling peripheral clock branch. */
ccEnableSPI0(); ccEnableSPI0();
/* Resetting the SPI cell. */
spi_lld_reset_spi_cell(spip);
/* Enabling peripheral interrupt. */ /* Enabling peripheral interrupt. */
nvicEnableVector(ADUCM_SPI0_NUMBER, ADUCM_SPI_SPI0_IRQ_PRIORITY); nvicEnableVector(ADUCM_SPI0_NUMBER, ADUCM_SPI_SPI0_IRQ_PRIORITY);
@ -195,6 +216,9 @@ void spi_lld_start(SPIDriver *spip) {
/* Enabling peripheral clock branch. */ /* Enabling peripheral clock branch. */
ccEnableSPI1(); ccEnableSPI1();
/* Resetting the SPI cell. */
spi_lld_reset_spi_cell(spip);
/* Enabling peripheral interrupt. */ /* Enabling peripheral interrupt. */
nvicEnableVector(ADUCM_SPI1_NUMBER, ADUCM_SPI_SPI1_IRQ_PRIORITY); nvicEnableVector(ADUCM_SPI1_NUMBER, ADUCM_SPI_SPI1_IRQ_PRIORITY);
} }
@ -225,20 +249,32 @@ void spi_lld_stop(SPIDriver *spip) {
if (spip->state == SPI_READY) { if (spip->state == SPI_READY) {
/* SPI disable.*/ /* SPI disable.*/
spip->spi->SPICON &= ~ADUCM_SPI_CON_ENABLE;
spip->spi->SPICON = 0; spip->spi->SPICON = 0;
spip->spi->SPIDIV = 0; spip->spi->SPIDIV = 0;
spip->rxbuf = NULL; spip->rxbuf = NULL;
spip->txbuf = NULL; spip->txbuf = NULL;
spip->size = 0; spip->size = 0;
/* Resetting the SPI cell. */
spi_lld_reset_spi_cell(spip);
#if ADUCM_SPI_USE_SPI0 #if ADUCM_SPI_USE_SPI0
if (&SPID0 == spip) if (&SPID0 == spip) {
/* Disabling peripheral clock branch. */
ccDisableSPI0(); ccDisableSPI0();
/* Disabling peripheral interrupt. */
nvicDisableVector(ADUCM_SPI0_NUMBER);
}
#endif #endif
#if ADUCM_SPI_USE_SPI1 #if ADUCM_SPI_USE_SPI1
if (&SPID1 == spip) if (&SPID1 == spip) {
/* Disabling peripheral clock branch. */
ccDisableSPI1(); ccDisableSPI1();
/* Disabling peripheral interrupt. */
nvicDisableVector(ADUCM_SPI1_NUMBER);
}
#endif #endif
} }
} }