Tentative fix for STM32 SPIv2.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15646 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
1f3c1037a6
commit
89adc08744
|
@ -120,29 +120,39 @@ SPIDriver SPID6;
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static void spi_lld_configure(SPIDriver *spip) {
|
||||
|
||||
/* SPI setup.*/
|
||||
if (spip->config->slave) {
|
||||
spip->spi->CR1 = spip->config->cr1 & ~(SPI_CR1_MSTR | SPI_CR1_SPE);
|
||||
spip->spi->CR2 = spip->config->cr2 | SPI_CR2_FRXTH |
|
||||
SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
|
||||
}
|
||||
else {
|
||||
spip->spi->CR1 = (spip->config->cr1 | SPI_CR1_MSTR) & ~SPI_CR1_SPE;
|
||||
spip->spi->CR2 = spip->config->cr2 | SPI_CR2_FRXTH | SPI_CR2_SSOE |
|
||||
SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stopping the SPI transaction.
|
||||
* @note This is done nicely or by brutally resetting it depending on
|
||||
* the mode and settings.
|
||||
* @brief Configures and enables a SPI.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
static msg_t spi_lld_stop_abort(SPIDriver *spip) {
|
||||
static void spi_lld_enable(SPIDriver *spip) {
|
||||
uint32_t cr1, cr2;
|
||||
|
||||
/* SPI setup.*/
|
||||
if (spip->config->slave) {
|
||||
cr1 = spip->config->cr1 & ~(SPI_CR1_MSTR | SPI_CR1_SPE);
|
||||
cr2 = spip->config->cr2 | SPI_CR2_FRXTH | SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
|
||||
}
|
||||
else {
|
||||
cr1 = (spip->config->cr1 | SPI_CR1_MSTR) & ~SPI_CR1_SPE;
|
||||
cr2 = spip->config->cr2 | SPI_CR2_FRXTH | SPI_CR2_SSOE | SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
|
||||
}
|
||||
|
||||
spip->spi->CR1 = cr1;
|
||||
spip->spi->CR2 = cr2;
|
||||
spip->spi->CR1 = cr1 | SPI_CR1_SPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a SPI.
|
||||
* @note This is done nicely or by brutally resetting it depending on
|
||||
* the mode and settings.
|
||||
* @note DMAs are also disabled because this is required by the correct
|
||||
* disable procedure.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
static void spi_lld_disable(SPIDriver *spip) {
|
||||
|
||||
if (!spip->config->slave) {
|
||||
/* Master mode, stopping gracefully.*/
|
||||
|
@ -153,7 +163,10 @@ static msg_t spi_lld_stop_abort(SPIDriver *spip) {
|
|||
/* Waiting for current frame completion then stop SPI.*/
|
||||
while ((spip->spi->SR & SPI_SR_BSY) != 0U) {
|
||||
}
|
||||
spip->spi->CR1 &= ~SPI_CR1_SPE;
|
||||
|
||||
/* Clearing SPE and the rest.*/
|
||||
spip->spi->CR1 = 0U;
|
||||
spip->spi->CR2 = 0U;
|
||||
|
||||
/* Now it is idle, stopping RX DMA channel.*/
|
||||
dmaStreamDisable(spip->dmarx);
|
||||
|
@ -209,12 +222,7 @@ static msg_t spi_lld_stop_abort(SPIDriver *spip) {
|
|||
else {
|
||||
osalDbgAssert(false, "invalid SPI instance");
|
||||
}
|
||||
|
||||
/* Reconfiguring SPI.*/
|
||||
spi_lld_configure(spip);
|
||||
}
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -231,9 +239,9 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
|
|||
/* Hook first, if defined.*/
|
||||
STM32_SPI_DMA_ERROR_HOOK(spip);
|
||||
#endif
|
||||
|
||||
/* Aborting the transfer.*/
|
||||
(void) spi_lld_stop_abort(spip);
|
||||
/* Stopping DMAs.*/
|
||||
dmaStreamDisable(spip->dmatx);
|
||||
dmaStreamDisable(spip->dmarx);
|
||||
|
||||
/* Reporting the failure.*/
|
||||
__spi_isr_error_code(spip, HAL_RET_HW_FAILURE);
|
||||
|
@ -249,8 +257,9 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* Stopping the transfer.*/
|
||||
(void) spi_lld_stop_abort(spip);
|
||||
/* Stopping DMAs.*/
|
||||
dmaStreamDisable(spip->dmatx);
|
||||
dmaStreamDisable(spip->dmarx);
|
||||
|
||||
/* Operation finished interrupt.*/
|
||||
__spi_isr_complete_code(spip);
|
||||
|
@ -272,8 +281,9 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
|
|||
STM32_SPI_DMA_ERROR_HOOK(spip);
|
||||
#endif
|
||||
|
||||
/* Aborting the transfer.*/
|
||||
(void) spi_lld_stop_abort(spip);
|
||||
/* Stopping DMAs.*/
|
||||
dmaStreamDisable(spip->dmatx);
|
||||
dmaStreamDisable(spip->dmarx);
|
||||
|
||||
/* Reporting the failure.*/
|
||||
__spi_isr_error_code(spip, HAL_RET_HW_FAILURE);
|
||||
|
@ -570,6 +580,10 @@ msg_t spi_lld_start(SPIDriver *spip) {
|
|||
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
|
||||
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
|
||||
}
|
||||
else {
|
||||
/* De-activation before re-configuration.*/
|
||||
spi_lld_disable(spip);
|
||||
}
|
||||
|
||||
/* Configuration-specific DMA setup.*/
|
||||
ds = spip->config->cr2 & SPI_CR2_DS;
|
||||
|
@ -598,7 +612,7 @@ msg_t spi_lld_start(SPIDriver *spip) {
|
|||
}
|
||||
|
||||
/* SPI setup.*/
|
||||
spi_lld_configure(spip);
|
||||
spi_lld_enable(spip);
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
@ -616,7 +630,7 @@ void spi_lld_stop(SPIDriver *spip) {
|
|||
if (spip->state == SPI_READY) {
|
||||
|
||||
/* Just in case this has been called uncleanly.*/
|
||||
(void) spi_lld_stop_abort(spip);
|
||||
spi_lld_disable(spip);
|
||||
|
||||
/* SPI cleanup.*/
|
||||
spip->spi->CR1 = 0;
|
||||
|
@ -729,8 +743,6 @@ msg_t spi_lld_ignore(SPIDriver *spip, size_t n) {
|
|||
dmaStreamEnable(spip->dmarx);
|
||||
dmaStreamEnable(spip->dmatx);
|
||||
|
||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -766,8 +778,6 @@ msg_t spi_lld_exchange(SPIDriver *spip, size_t n,
|
|||
dmaStreamEnable(spip->dmarx);
|
||||
dmaStreamEnable(spip->dmatx);
|
||||
|
||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -800,8 +810,6 @@ msg_t spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
|||
dmaStreamEnable(spip->dmarx);
|
||||
dmaStreamEnable(spip->dmatx);
|
||||
|
||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -834,8 +842,6 @@ msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
|||
dmaStreamEnable(spip->dmarx);
|
||||
dmaStreamEnable(spip->dmatx);
|
||||
|
||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -850,16 +856,24 @@ msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
|||
* @notapi
|
||||
*/
|
||||
msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep) {
|
||||
msg_t msg;
|
||||
|
||||
/* Stopping everything.*/
|
||||
msg = spi_lld_stop_abort(spip);
|
||||
/* Stopping TX DMA.*/
|
||||
dmaStreamDisable(spip->dmatx);
|
||||
|
||||
/* Waiting for current frame completion then stop SPI.*/
|
||||
while ((spip->spi->SR & SPI_SR_BSY) != 0U) {
|
||||
/* Still busy.*/
|
||||
}
|
||||
|
||||
/* Size of unprocessed data.*/
|
||||
if (sizep != NULL) {
|
||||
*sizep = dmaStreamGetTransactionSize(spip->dmarx);
|
||||
}
|
||||
|
||||
return msg;
|
||||
/* Stopping RX DMA.*/
|
||||
dmaStreamDisable(spip->dmarx);
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -876,9 +890,6 @@ msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep) {
|
|||
*/
|
||||
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
|
||||
|
||||
/* Enabling SPI for the exchange.*/
|
||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
||||
|
||||
/*
|
||||
* Data register must be accessed with the appropriate data size.
|
||||
* Byte size access (uint8_t *) for transactions that are <= 8-bit.
|
||||
|
@ -903,9 +914,6 @@ uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
|
|||
frame = (uint16_t)*dr16p;
|
||||
}
|
||||
|
||||
/* Disabling SPI and done.*/
|
||||
spip->spi->CR1 &= ~SPI_CR1_SPE;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,9 +114,9 @@ void portab_setup(void) {
|
|||
*/
|
||||
palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) |
|
||||
PAL_STM32_OSPEED_HIGHEST); /* SPI2 SCK. */
|
||||
palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(5) |
|
||||
palSetPadMode(GPIOC, 2, PAL_MODE_ALTERNATE(5) |
|
||||
PAL_STM32_OSPEED_HIGHEST); /* SPI2 MISO. */
|
||||
palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(5) |
|
||||
palSetPadMode(GPIOC, 3, PAL_MODE_ALTERNATE(5) |
|
||||
PAL_STM32_OSPEED_HIGHEST); /* SPI2 MOSI. */
|
||||
palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL |
|
||||
PAL_STM32_OSPEED_HIGHEST); /* SPI2 CS. */
|
||||
|
|
Loading…
Reference in New Issue