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. */
|
/* 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.
|
* @brief Configures and enables a SPI.
|
||||||
* @note This is done nicely or by brutally resetting it depending on
|
|
||||||
* the mode and settings.
|
|
||||||
*
|
*
|
||||||
* @param[in] spip pointer to the @p SPIDriver object
|
* @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) {
|
if (!spip->config->slave) {
|
||||||
/* Master mode, stopping gracefully.*/
|
/* 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.*/
|
/* Waiting for current frame completion then stop SPI.*/
|
||||||
while ((spip->spi->SR & SPI_SR_BSY) != 0U) {
|
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.*/
|
/* Now it is idle, stopping RX DMA channel.*/
|
||||||
dmaStreamDisable(spip->dmarx);
|
dmaStreamDisable(spip->dmarx);
|
||||||
|
@ -209,12 +222,7 @@ static msg_t spi_lld_stop_abort(SPIDriver *spip) {
|
||||||
else {
|
else {
|
||||||
osalDbgAssert(false, "invalid SPI instance");
|
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.*/
|
/* Hook first, if defined.*/
|
||||||
STM32_SPI_DMA_ERROR_HOOK(spip);
|
STM32_SPI_DMA_ERROR_HOOK(spip);
|
||||||
#endif
|
#endif
|
||||||
|
/* Stopping DMAs.*/
|
||||||
/* Aborting the transfer.*/
|
dmaStreamDisable(spip->dmatx);
|
||||||
(void) spi_lld_stop_abort(spip);
|
dmaStreamDisable(spip->dmarx);
|
||||||
|
|
||||||
/* Reporting the failure.*/
|
/* Reporting the failure.*/
|
||||||
__spi_isr_error_code(spip, HAL_RET_HW_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 {
|
else {
|
||||||
/* Stopping the transfer.*/
|
/* Stopping DMAs.*/
|
||||||
(void) spi_lld_stop_abort(spip);
|
dmaStreamDisable(spip->dmatx);
|
||||||
|
dmaStreamDisable(spip->dmarx);
|
||||||
|
|
||||||
/* Operation finished interrupt.*/
|
/* Operation finished interrupt.*/
|
||||||
__spi_isr_complete_code(spip);
|
__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);
|
STM32_SPI_DMA_ERROR_HOOK(spip);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Aborting the transfer.*/
|
/* Stopping DMAs.*/
|
||||||
(void) spi_lld_stop_abort(spip);
|
dmaStreamDisable(spip->dmatx);
|
||||||
|
dmaStreamDisable(spip->dmarx);
|
||||||
|
|
||||||
/* Reporting the failure.*/
|
/* Reporting the failure.*/
|
||||||
__spi_isr_error_code(spip, HAL_RET_HW_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->dmarx, &spip->spi->DR);
|
||||||
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
|
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* De-activation before re-configuration.*/
|
||||||
|
spi_lld_disable(spip);
|
||||||
|
}
|
||||||
|
|
||||||
/* Configuration-specific DMA setup.*/
|
/* Configuration-specific DMA setup.*/
|
||||||
ds = spip->config->cr2 & SPI_CR2_DS;
|
ds = spip->config->cr2 & SPI_CR2_DS;
|
||||||
|
@ -598,7 +612,7 @@ msg_t spi_lld_start(SPIDriver *spip) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SPI setup.*/
|
/* SPI setup.*/
|
||||||
spi_lld_configure(spip);
|
spi_lld_enable(spip);
|
||||||
|
|
||||||
return HAL_RET_SUCCESS;
|
return HAL_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -616,7 +630,7 @@ void spi_lld_stop(SPIDriver *spip) {
|
||||||
if (spip->state == SPI_READY) {
|
if (spip->state == SPI_READY) {
|
||||||
|
|
||||||
/* Just in case this has been called uncleanly.*/
|
/* Just in case this has been called uncleanly.*/
|
||||||
(void) spi_lld_stop_abort(spip);
|
spi_lld_disable(spip);
|
||||||
|
|
||||||
/* SPI cleanup.*/
|
/* SPI cleanup.*/
|
||||||
spip->spi->CR1 = 0;
|
spip->spi->CR1 = 0;
|
||||||
|
@ -729,8 +743,6 @@ msg_t spi_lld_ignore(SPIDriver *spip, size_t n) {
|
||||||
dmaStreamEnable(spip->dmarx);
|
dmaStreamEnable(spip->dmarx);
|
||||||
dmaStreamEnable(spip->dmatx);
|
dmaStreamEnable(spip->dmatx);
|
||||||
|
|
||||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
|
||||||
|
|
||||||
return HAL_RET_SUCCESS;
|
return HAL_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,8 +778,6 @@ msg_t spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||||
dmaStreamEnable(spip->dmarx);
|
dmaStreamEnable(spip->dmarx);
|
||||||
dmaStreamEnable(spip->dmatx);
|
dmaStreamEnable(spip->dmatx);
|
||||||
|
|
||||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
|
||||||
|
|
||||||
return HAL_RET_SUCCESS;
|
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->dmarx);
|
||||||
dmaStreamEnable(spip->dmatx);
|
dmaStreamEnable(spip->dmatx);
|
||||||
|
|
||||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
|
||||||
|
|
||||||
return HAL_RET_SUCCESS;
|
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->dmarx);
|
||||||
dmaStreamEnable(spip->dmatx);
|
dmaStreamEnable(spip->dmatx);
|
||||||
|
|
||||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
|
||||||
|
|
||||||
return HAL_RET_SUCCESS;
|
return HAL_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,16 +856,24 @@ msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep) {
|
msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep) {
|
||||||
msg_t msg;
|
|
||||||
|
|
||||||
/* Stopping everything.*/
|
/* Stopping TX DMA.*/
|
||||||
msg = spi_lld_stop_abort(spip);
|
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) {
|
if (sizep != NULL) {
|
||||||
*sizep = dmaStreamGetTransactionSize(spip->dmarx);
|
*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) {
|
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.
|
* Data register must be accessed with the appropriate data size.
|
||||||
* Byte size access (uint8_t *) for transactions that are <= 8-bit.
|
* 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;
|
frame = (uint16_t)*dr16p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disabling SPI and done.*/
|
|
||||||
spip->spi->CR1 &= ~SPI_CR1_SPE;
|
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,9 +114,9 @@ void portab_setup(void) {
|
||||||
*/
|
*/
|
||||||
palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) |
|
palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) |
|
||||||
PAL_STM32_OSPEED_HIGHEST); /* SPI2 SCK. */
|
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. */
|
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. */
|
PAL_STM32_OSPEED_HIGHEST); /* SPI2 MOSI. */
|
||||||
palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL |
|
palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL |
|
||||||
PAL_STM32_OSPEED_HIGHEST); /* SPI2 CS. */
|
PAL_STM32_OSPEED_HIGHEST); /* SPI2 CS. */
|
||||||
|
|
Loading…
Reference in New Issue