Experimental SPI v2 code, not finished.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14915 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
a0982b7301
commit
e5098d67e4
|
@ -63,6 +63,13 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Inserts an assertion on function errors before returning.
|
||||
*/
|
||||
#if !defined(SPI_USE_ASSERT_ON_ERROR) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_ASSERT_ON_ERROR TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables circular transfers APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
|
@ -358,13 +365,13 @@ do { \
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _spi_wakeup_isr(spip) { \
|
||||
#define __spi_wakeup_isr(spip) { \
|
||||
osalSysLockFromISR(); \
|
||||
osalThreadResumeI(&(spip)->sync_transfer, MSG_OK); \
|
||||
osalSysUnlockFromISR(); \
|
||||
}
|
||||
#else /* !SPI_USE_SYNCHRONIZATION */
|
||||
#define _spi_wakeup_isr(spip)
|
||||
#define __spi_wakeup_isr(spip)
|
||||
#endif /* !SPI_USE_SYNCHRONIZATION */
|
||||
|
||||
/**
|
||||
|
@ -381,7 +388,7 @@ do { \
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _spi_isr_code(spip) { \
|
||||
#define __spi_isr_code(spip) { \
|
||||
if ((spip)->config->end_cb) { \
|
||||
(spip)->state = SPI_COMPLETE; \
|
||||
(spip)->config->end_cb(spip); \
|
||||
|
@ -390,7 +397,7 @@ do { \
|
|||
} \
|
||||
else \
|
||||
(spip)->state = SPI_READY; \
|
||||
_spi_wakeup_isr(spip); \
|
||||
__spi_wakeup_isr(spip); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -405,7 +412,7 @@ do { \
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _spi_isr_half_code(spip) { \
|
||||
#define __spi_isr_half_code(spip) { \
|
||||
if ((spip)->config->end_cb) { \
|
||||
(spip)->config->end_cb(spip); \
|
||||
} \
|
||||
|
@ -424,7 +431,7 @@ do { \
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _spi_isr_full_code(spip) { \
|
||||
#define __spi_isr_full_code(spip) { \
|
||||
if ((spip)->config->end_cb) { \
|
||||
(spip)->state = SPI_COMPLETE; \
|
||||
(spip)->config->end_cb(spip); \
|
||||
|
@ -447,25 +454,25 @@ extern "C" {
|
|||
void spiStop(SPIDriver *spip);
|
||||
void spiSelect(SPIDriver *spip);
|
||||
void spiUnselect(SPIDriver *spip);
|
||||
bool spiStartIgnoreI(SPIDriver *spip, size_t n);
|
||||
bool spiStartIgnore(SPIDriver *spip, size_t n);
|
||||
bool spiStartExchangeI(SPIDriver *spip, size_t n,
|
||||
msg_t spiStartIgnoreI(SPIDriver *spip, size_t n);
|
||||
msg_t spiStartIgnore(SPIDriver *spip, size_t n);
|
||||
msg_t spiStartExchangeI(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf);
|
||||
msg_t spiStartExchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf);
|
||||
bool spiStartExchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf);
|
||||
bool spiStartSendI(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
bool spiStartSend(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
bool spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
bool spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
size_t spiStopTransferI(SPIDriver *spip);
|
||||
size_t spiStopTransfer(SPIDriver *spip);
|
||||
msg_t spiStartSendI(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
msg_t spiStartSend(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
msg_t spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
msg_t spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
msg_t spiStopTransferI(SPIDriver *spip, size_t *sizep);
|
||||
msg_t spiStopTransfer(SPIDriver *spip, size_t *sizep);
|
||||
#if SPI_USE_SYNCHRONIZATION == TRUE
|
||||
msg_t spiSynchronizeS(SPIDriver *spip, sysinterval_t timeout);
|
||||
msg_t spiSynchronize(SPIDriver *spip, sysinterval_t timeout);
|
||||
void spiIgnore(SPIDriver *spip, size_t n);
|
||||
void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf);
|
||||
void spiSend(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
void spiReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
msg_t spiIgnore(SPIDriver *spip, size_t n);
|
||||
msg_t spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf);
|
||||
msg_t spiSend(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
msg_t spiReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
#endif
|
||||
#if SPI_USE_MUTUAL_EXCLUSION == TRUE
|
||||
void spiAcquireBus(SPIDriver *spip);
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_I2S TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
|
||||
endif
|
||||
ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_spi_v2_lld.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
|
||||
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_spi_v2_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2
|
|
@ -143,11 +143,11 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
|
|||
if (spip->config->circular) {
|
||||
if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
|
||||
/* Half buffer interrupt.*/
|
||||
_spi_isr_half_code(spip);
|
||||
__spi_isr_half_code(spip);
|
||||
}
|
||||
if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
|
||||
/* End buffer interrupt.*/
|
||||
_spi_isr_full_code(spip);
|
||||
__spi_isr_full_code(spip);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -157,7 +157,7 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
|
|||
|
||||
/* Portable SPI ISR code defined in the high level driver, note, it is
|
||||
a macro.*/
|
||||
_spi_isr_code(spip);
|
||||
__spi_isr_code(spip);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,6 +181,36 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static msg_t spi_lld_get_dma(SPIDriver *spip, uint32_t rxstream,
|
||||
uint32_t txstream, uint32_t priority){
|
||||
|
||||
spip->dmarx = dmaStreamAllocI(rxstream, priority,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
if (spip->dmarx == NULL) {
|
||||
return HAL_RET_NO_RESOURCE;
|
||||
}
|
||||
|
||||
spip->dmatx = dmaStreamAllocI(txstream, priority,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
if (spip->dmatx == NULL) {
|
||||
dmaStreamFreeI(spip->dmarx);
|
||||
return HAL_RET_NO_RESOURCE;
|
||||
}
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static msg_t spi_lld_wait_not_busy(SPIDriver *spip) {
|
||||
|
||||
while ((spip->spi->SR & SPI_SR_BSY) != 0U) {
|
||||
}
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
@ -309,122 +339,120 @@ void spi_lld_init(void) {
|
|||
* @brief Configures and activates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @return The operation status.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_start(SPIDriver *spip) {
|
||||
msg_t spi_lld_start(SPIDriver *spip) {
|
||||
uint32_t ds;
|
||||
msg_t msg;
|
||||
|
||||
/* If in stopped state then enables the SPI and DMA clocks.*/
|
||||
if (spip->state == SPI_STOP) {
|
||||
if (false) {
|
||||
}
|
||||
|
||||
#if STM32_SPI_USE_SPI1
|
||||
if (&SPID1 == spip) {
|
||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI1_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI1_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI1_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI1_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
||||
else if (&SPID1 == spip) {
|
||||
msg = spi_lld_get_dma(spip,
|
||||
STM32_SPI_SPI1_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI1_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI1_IRQ_PRIORITY);
|
||||
if (msg != HAL_RET_SUCCESS) {
|
||||
return msg;
|
||||
}
|
||||
rccEnableSPI1(true);
|
||||
rccResetSPI1();
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI1_RX);
|
||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI1_TX);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2
|
||||
if (&SPID2 == spip) {
|
||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI2_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI2_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI2_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI2_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
||||
msg = spi_lld_get_dma(spip,
|
||||
STM32_SPI_SPI2_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI2_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI2_IRQ_PRIORITY);
|
||||
if (msg != HAL_RET_SUCCESS) {
|
||||
return msg;
|
||||
}
|
||||
rccEnableSPI2(true);
|
||||
rccResetSPI2();
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI2_RX);
|
||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI2_TX);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3
|
||||
if (&SPID3 == spip) {
|
||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI3_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI3_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI3_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI3_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
||||
else if (&SPID3 == spip) {
|
||||
msg = spi_lld_get_dma(spip,
|
||||
STM32_SPI_SPI3_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI3_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI3_IRQ_PRIORITY);
|
||||
if (msg != HAL_RET_SUCCESS) {
|
||||
return msg;
|
||||
}
|
||||
rccEnableSPI3(true);
|
||||
rccResetSPI3();
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI3_RX);
|
||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI3_TX);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4
|
||||
if (&SPID4 == spip) {
|
||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI4_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI4_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI4_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI4_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
||||
else if (&SPID4 == spip) {
|
||||
msg = spi_lld_get_dma(spip,
|
||||
STM32_SPI_SPI4_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI4_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI4_IRQ_PRIORITY);
|
||||
if (msg != HAL_RET_SUCCESS) {
|
||||
return msg;
|
||||
}
|
||||
rccEnableSPI4(true);
|
||||
rccResetSPI4();
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI4_RX);
|
||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI4_TX);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5
|
||||
if (&SPID5 == spip) {
|
||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI5_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI5_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI5_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI5_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
||||
else if (&SPID5 == spip) {
|
||||
msg = spi_lld_get_dma(spip,
|
||||
STM32_SPI_SPI5_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI5_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI5_IRQ_PRIORITY);
|
||||
if (msg != HAL_RET_SUCCESS) {
|
||||
return msg;
|
||||
}
|
||||
rccEnableSPI5(true);
|
||||
rccResetSPI5();
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI5_RX);
|
||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI5_TX);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6
|
||||
if (&SPID6 == spip) {
|
||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI6_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI6_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI6_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI6_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
||||
(void *)spip);
|
||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
||||
msg = spi_lld_get_dma(spip,
|
||||
STM32_SPI_SPI6_RX_DMA_STREAM,
|
||||
STM32_SPI_SPI6_TX_DMA_STREAM,
|
||||
STM32_SPI_SPI6_IRQ_PRIORITY);
|
||||
if (msg != HAL_RET_SUCCESS) {
|
||||
return msg;
|
||||
}
|
||||
rccEnableSPI6(true);
|
||||
rccResetSPI6();
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI6_RX);
|
||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI6_TX);
|
||||
|
@ -432,6 +460,10 @@ void spi_lld_start(SPIDriver *spip) {
|
|||
}
|
||||
#endif
|
||||
|
||||
else {
|
||||
osalDbgAssert(false, "invalid SPI instance");
|
||||
}
|
||||
|
||||
/* DMA setup.*/
|
||||
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
|
||||
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
|
||||
|
@ -469,6 +501,8 @@ void spi_lld_start(SPIDriver *spip) {
|
|||
spip->spi->CR2 = spip->config->cr2 | SPI_CR2_FRXTH | SPI_CR2_SSOE |
|
||||
SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
|
||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -555,10 +589,11 @@ void spi_lld_unselect(SPIDriver *spip) {
|
|||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be ignored
|
||||
* @return The operation status.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
bool spi_lld_ignore(SPIDriver *spip, size_t n) {
|
||||
msg_t spi_lld_ignore(SPIDriver *spip, size_t n) {
|
||||
|
||||
osalDbgAssert(n < 65536, "unsupported DMA transfer size");
|
||||
|
||||
|
@ -573,7 +608,7 @@ bool spi_lld_ignore(SPIDriver *spip, size_t n) {
|
|||
dmaStreamEnable(spip->dmarx);
|
||||
dmaStreamEnable(spip->dmatx);
|
||||
|
||||
return false;
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -588,11 +623,12 @@ bool spi_lld_ignore(SPIDriver *spip, size_t n) {
|
|||
* @param[in] n number of words to be exchanged
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
* @return The operation status.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
bool spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
msg_t spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
|
||||
osalDbgAssert(n < 65536, "unsupported DMA transfer size");
|
||||
|
||||
|
@ -607,7 +643,7 @@ bool spi_lld_exchange(SPIDriver *spip, size_t n,
|
|||
dmaStreamEnable(spip->dmarx);
|
||||
dmaStreamEnable(spip->dmatx);
|
||||
|
||||
return false;
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -620,10 +656,11 @@ bool spi_lld_exchange(SPIDriver *spip, size_t n,
|
|||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @return The operation status.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
msg_t spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
|
||||
osalDbgAssert(n < 65536, "unsupported DMA transfer size");
|
||||
|
||||
|
@ -637,6 +674,8 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
|||
|
||||
dmaStreamEnable(spip->dmarx);
|
||||
dmaStreamEnable(spip->dmatx);
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -649,10 +688,11 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
|||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to receive
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
* @return The operation status.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
|
||||
osalDbgAssert(n < 65536, "unsupported DMA transfer size");
|
||||
|
||||
|
@ -666,23 +706,38 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
|||
|
||||
dmaStreamEnable(spip->dmarx);
|
||||
dmaStreamEnable(spip->dmatx);
|
||||
|
||||
return HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Aborts the ongoing SPI operation, if any.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[out sizep pointer to the counter of frames not yet transferred
|
||||
* or @p NULL
|
||||
* @return The operation status.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_abort(SPIDriver *spip) {
|
||||
msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep) {
|
||||
msg_t msg;
|
||||
|
||||
/* Stopping DMAs.*/
|
||||
/* Stopping TX DMA.*/
|
||||
dmaStreamDisable(spip->dmatx);
|
||||
|
||||
/* Waiting for the SPI to become not busy.*/
|
||||
msg = spi_lld_wait_not_busy(spip);
|
||||
|
||||
/* Stopping RX DMA.*/
|
||||
dmaStreamDisable(spip->dmarx);
|
||||
|
||||
if (sizep != NULL) {
|
||||
*sizep = dmaStreamGetTransactionSize(spip->dmatx);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */
|
||||
|
||||
/**
|
||||
* @brief Exchanges one frame using a polled wait.
|
||||
|
|
|
@ -0,0 +1,554 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file SPIv2/hal_spi_lld.h
|
||||
* @brief STM32 SPI subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup SPI
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_SPI_LLD_H
|
||||
#define HAL_SPI_LLD_H
|
||||
|
||||
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Circular mode support flag.
|
||||
*/
|
||||
#define SPI_SUPPORTS_CIRCULAR TRUE
|
||||
|
||||
/**
|
||||
* @brief Slave mode support flag.
|
||||
*/
|
||||
#define SPI_SUPPORTS_SLAVE_MODE FALSE
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief SPI1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for SPI1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_USE_SPI1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for SPI2 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_USE_SPI2 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI3 driver enable switch.
|
||||
* @details If set to @p TRUE the support for SPI3 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_USE_SPI3 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI4 driver enable switch.
|
||||
* @details If set to @p TRUE the support for SPI4 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_USE_SPI4 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI5 driver enable switch.
|
||||
* @details If set to @p TRUE the support for SPI5 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_USE_SPI5 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI6 driver enable switch.
|
||||
* @details If set to @p TRUE the support for SPI6 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_USE_SPI6 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI2 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI3 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI4 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI4_IRQ_PRIORITY 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI5 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI5_IRQ_PRIORITY 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI6 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI6_IRQ_PRIORITY 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI1 DMA priority (0..3|lowest..highest).
|
||||
* @note The priority level is used for both the TX and RX DMA streams but
|
||||
* because of the streams ordering the RX stream has always priority
|
||||
* over the TX stream.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI1_DMA_PRIORITY 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI2 DMA priority (0..3|lowest..highest).
|
||||
* @note The priority level is used for both the TX and RX DMA streams but
|
||||
* because of the streams ordering the RX stream has always priority
|
||||
* over the TX stream.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI2_DMA_PRIORITY 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI3 DMA priority (0..3|lowest..highest).
|
||||
* @note The priority level is used for both the TX and RX DMA streams but
|
||||
* because of the streams ordering the RX stream has always priority
|
||||
* over the TX stream.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI3_DMA_PRIORITY 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI4 DMA priority (0..3|lowest..highest).
|
||||
* @note The priority level is used for both the TX and RX DMA streams but
|
||||
* because of the streams ordering the RX stream has always priority
|
||||
* over the TX stream.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI4_DMA_PRIORITY 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI5 DMA priority (0..3|lowest..highest).
|
||||
* @note The priority level is used for both the TX and RX DMA streams but
|
||||
* because of the streams ordering the RX stream has always priority
|
||||
* over the TX stream.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI5_DMA_PRIORITY 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI6 DMA priority (0..3|lowest..highest).
|
||||
* @note The priority level is used for both the TX and RX DMA streams but
|
||||
* because of the streams ordering the RX stream has always priority
|
||||
* over the TX stream.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI6_DMA_PRIORITY 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI DMA error hook.
|
||||
*/
|
||||
#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1
|
||||
#error "SPI1 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2
|
||||
#error "SPI2 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3
|
||||
#error "SPI3 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4
|
||||
#error "SPI4 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5
|
||||
#error "SPI5 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6
|
||||
#error "SPI6 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \
|
||||
!STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6
|
||||
#error "SPI driver activated but no SPI peripheral assigned"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI1 && \
|
||||
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI1_IRQ_PRIORITY)
|
||||
#error "Invalid IRQ priority assigned to SPI1"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && \
|
||||
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI2_IRQ_PRIORITY)
|
||||
#error "Invalid IRQ priority assigned to SPI2"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && \
|
||||
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI3_IRQ_PRIORITY)
|
||||
#error "Invalid IRQ priority assigned to SPI3"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && \
|
||||
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY)
|
||||
#error "Invalid IRQ priority assigned to SPI4"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && \
|
||||
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY)
|
||||
#error "Invalid IRQ priority assigned to SPI5"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && \
|
||||
!OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY)
|
||||
#error "Invalid IRQ priority assigned to SPI6"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI1 && \
|
||||
!STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
|
||||
#error "Invalid DMA priority assigned to SPI1"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && \
|
||||
!STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY)
|
||||
#error "Invalid DMA priority assigned to SPI2"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && \
|
||||
!STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY)
|
||||
#error "Invalid DMA priority assigned to SPI3"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && \
|
||||
!STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
|
||||
#error "Invalid DMA priority assigned to SPI4"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && \
|
||||
!STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
|
||||
#error "Invalid DMA priority assigned to SPI5"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && \
|
||||
!STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
|
||||
#error "Invalid DMA priority assigned to SPI6"
|
||||
#endif
|
||||
|
||||
/* Check on the presence of the DMA streams settings in mcuconf.h.*/
|
||||
#if STM32_SPI_USE_SPI1 && (!defined(STM32_SPI_SPI1_RX_DMA_STREAM) || \
|
||||
!defined(STM32_SPI_SPI1_TX_DMA_STREAM))
|
||||
#error "SPI1 DMA streams not defined"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && (!defined(STM32_SPI_SPI2_RX_DMA_STREAM) || \
|
||||
!defined(STM32_SPI_SPI2_TX_DMA_STREAM))
|
||||
#error "SPI2 DMA streams not defined"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && (!defined(STM32_SPI_SPI3_RX_DMA_STREAM) || \
|
||||
!defined(STM32_SPI_SPI3_TX_DMA_STREAM))
|
||||
#error "SPI3 DMA streams not defined"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \
|
||||
!defined(STM32_SPI_SPI4_TX_DMA_STREAM))
|
||||
#error "SPI4 DMA streams not defined"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \
|
||||
!defined(STM32_SPI_SPI5_TX_DMA_STREAM))
|
||||
#error "SPI5 DMA streams not defined"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_DMA_STREAM) || \
|
||||
!defined(STM32_SPI_SPI6_TX_DMA_STREAM))
|
||||
#error "SPI6 DMA streams not defined"
|
||||
#endif
|
||||
|
||||
/* Check on the validity of the assigned DMA channels.*/
|
||||
#if STM32_SPI_USE_SPI1 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI1 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_RX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI2 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_TX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI2 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_RX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI3 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_TX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI3 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_RX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI4 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_TX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI4 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_RX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI5 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_TX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI5 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI6_RX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI6 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && \
|
||||
!STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI6_TX_DMA_STREAM)
|
||||
#error "Invalid DMA channel assigned to SPI6 TX"
|
||||
#endif
|
||||
|
||||
/* Devices without DMAMUX require an additional check.*/
|
||||
#if STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX
|
||||
|
||||
/* Check on the validity of the assigned DMA channels.*/
|
||||
#if STM32_SPI_USE_SPI1 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI1 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI1 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI1 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI2 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI2 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI3 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI3 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_RX_DMA_STREAM, STM32_SPI4_RX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI4 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_TX_DMA_STREAM, STM32_SPI4_TX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI4 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_RX_DMA_STREAM, STM32_SPI5_RX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI5 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_TX_DMA_STREAM, STM32_SPI5_TX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI5 TX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_RX_DMA_STREAM, STM32_SPI6_RX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI6 RX"
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_TX_DMA_STREAM, STM32_SPI6_TX_DMA_MSK)
|
||||
#error "invalid DMA stream associated to SPI6 TX"
|
||||
#endif
|
||||
|
||||
#endif /* STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX */
|
||||
|
||||
#if !defined(STM32_DMA_REQUIRED)
|
||||
#define STM32_DMA_REQUIRED
|
||||
#endif
|
||||
|
||||
#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
|
||||
#error "SPI_SELECT_MODE_LLD not supported by this driver"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the SPI driver structure.
|
||||
*/
|
||||
#define spi_lld_driver_fields \
|
||||
/* Pointer to the SPIx registers block.*/ \
|
||||
SPI_TypeDef *spi; \
|
||||
/* Receive DMA stream.*/ \
|
||||
const stm32_dma_stream_t *dmarx; \
|
||||
/* Transmit DMA stream.*/ \
|
||||
const stm32_dma_stream_t *dmatx; \
|
||||
/* RX DMA mode bit mask.*/ \
|
||||
uint32_t rxdmamode; \
|
||||
/* TX DMA mode bit mask.*/ \
|
||||
uint32_t txdmamode
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the SPI configuration structure.
|
||||
*/
|
||||
#define spi_lld_config_fields \
|
||||
/* SPI CR1 register initialization data.*/ \
|
||||
uint16_t cr1; \
|
||||
/* SPI CR2 register initialization data.*/ \
|
||||
uint16_t cr2
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID1;
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID2;
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID3;
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID4;
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID5;
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID6;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void spi_lld_init(void);
|
||||
msg_t spi_lld_start(SPIDriver *spip);
|
||||
void spi_lld_stop(SPIDriver *spip);
|
||||
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
|
||||
void spi_lld_select(SPIDriver *spip);
|
||||
void spi_lld_unselect(SPIDriver *spip);
|
||||
#endif
|
||||
msg_t spi_lld_ignore(SPIDriver *spip, size_t n);
|
||||
msg_t spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf);
|
||||
msg_t spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SPI */
|
||||
|
||||
#endif /* HAL_SPI_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -98,13 +98,8 @@ msg_t spiStart(SPIDriver *spip, const SPIConfig *config) {
|
|||
|
||||
spip->config = config;
|
||||
|
||||
#if defined(SPI_LLD_ENHANCED_API)
|
||||
msg = spi_lld_start(spip);
|
||||
#else
|
||||
spi_lld_start(spip);
|
||||
msg = HAL_START_SUCCESS;
|
||||
#endif
|
||||
if (msg == HAL_START_SUCCESS) {
|
||||
if (msg == HAL_RET_SUCCESS) {
|
||||
spip->state = SPI_READY;
|
||||
}
|
||||
else {
|
||||
|
@ -113,6 +108,10 @@ msg_t spiStart(SPIDriver *spip, const SPIConfig *config) {
|
|||
|
||||
osalSysUnlock();
|
||||
|
||||
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
||||
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
||||
#endif
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
@ -185,12 +184,13 @@ void spiUnselect(SPIDriver *spip) {
|
|||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be ignored
|
||||
* @return The operation status.
|
||||
* @retval false if the operation started correctly.
|
||||
* @retval true if the operation did not start.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
bool spiStartIgnoreI(SPIDriver *spip, size_t n) {
|
||||
msg_t spiStartIgnoreI(SPIDriver *spip, size_t n) {
|
||||
msg_t msg;
|
||||
|
||||
osalDbgCheckClassI();
|
||||
|
||||
osalDbgCheck((spip != NULL) && (n > 0U));
|
||||
#if SPI_SUPPORTS_CIRCULAR
|
||||
|
@ -200,7 +200,13 @@ bool spiStartIgnoreI(SPIDriver *spip, size_t n) {
|
|||
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
||||
|
||||
spip->state = SPI_ACTIVE;
|
||||
return spi_lld_ignore(spip, n);
|
||||
msg = spi_lld_ignore(spip, n);
|
||||
|
||||
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
||||
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
||||
#endif
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -214,19 +220,17 @@ bool spiStartIgnoreI(SPIDriver *spip, size_t n) {
|
|||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be ignored
|
||||
* @return The operation status.
|
||||
* @retval false if the operation started correctly.
|
||||
* @retval true if the operation did not start.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool spiStartIgnore(SPIDriver *spip, size_t n) {
|
||||
bool ret;
|
||||
msg_t spiStartIgnore(SPIDriver *spip, size_t n) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
ret = spiStartIgnoreI(spip, n);
|
||||
msg = spiStartIgnoreI(spip, n);
|
||||
osalSysUnlock();
|
||||
|
||||
return ret;
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -244,13 +248,14 @@ bool spiStartIgnore(SPIDriver *spip, size_t n) {
|
|||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
* @return The operation status.
|
||||
* @retval false if the operation started correctly.
|
||||
* @retval true if the operation did not start.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
bool spiStartExchangeI(SPIDriver *spip, size_t n,
|
||||
msg_t spiStartExchangeI(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
msg_t msg;
|
||||
|
||||
osalDbgCheckClassI();
|
||||
|
||||
osalDbgCheck((spip != NULL) && (n > 0U) &&
|
||||
(rxbuf != NULL) && (txbuf != NULL));
|
||||
|
@ -261,7 +266,13 @@ bool spiStartExchangeI(SPIDriver *spip, size_t n,
|
|||
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
||||
|
||||
spip->state = SPI_ACTIVE;
|
||||
return spi_lld_exchange(spip, n, txbuf, rxbuf);
|
||||
msg = spi_lld_exchange(spip, n, txbuf, rxbuf);
|
||||
|
||||
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
||||
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
||||
#endif
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,20 +290,18 @@ bool spiStartExchangeI(SPIDriver *spip, size_t n,
|
|||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
* @return The operation status.
|
||||
* @retval false if the operation started correctly.
|
||||
* @retval true if the operation did not start.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool spiStartExchange(SPIDriver *spip, size_t n,
|
||||
msg_t spiStartExchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
bool ret;
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
ret = spiStartExchangeI(spip, n, txbuf, rxbuf);
|
||||
msg = spiStartExchangeI(spip, n, txbuf, rxbuf);
|
||||
osalSysUnlock();
|
||||
|
||||
return ret;
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -308,12 +317,13 @@ bool spiStartExchange(SPIDriver *spip, size_t n,
|
|||
* @param[in] n number of words to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @return The operation status.
|
||||
* @retval false if the operation started correctly.
|
||||
* @retval true if the operation did not start.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
bool spiStartSendI(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
msg_t spiStartSendI(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
msg_t msg;
|
||||
|
||||
osalDbgCheckClassI();
|
||||
|
||||
osalDbgCheck((spip != NULL) && (n > 0U) && (txbuf != NULL));
|
||||
#if SPI_SUPPORTS_CIRCULAR
|
||||
|
@ -323,7 +333,13 @@ bool spiStartSendI(SPIDriver *spip, size_t n, const void *txbuf) {
|
|||
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
||||
|
||||
spip->state = SPI_ACTIVE;
|
||||
return spi_lld_send(spip, n, txbuf);
|
||||
msg = spi_lld_send(spip, n, txbuf);
|
||||
|
||||
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
||||
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
||||
#endif
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -339,19 +355,17 @@ bool spiStartSendI(SPIDriver *spip, size_t n, const void *txbuf) {
|
|||
* @param[in] n number of words to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @return The operation status.
|
||||
* @retval false if the operation started correctly.
|
||||
* @retval true if the operation did not start.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
bool ret;
|
||||
msg_t spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
ret = spiStartSendI(spip, n, txbuf);
|
||||
msg = spiStartSendI(spip, n, txbuf);
|
||||
osalSysUnlock();
|
||||
|
||||
return ret;
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -367,12 +381,13 @@ bool spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) {
|
|||
* @param[in] n number of words to receive
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
* @return The operation status.
|
||||
* @retval false if the operation started correctly.
|
||||
* @retval true if the operation did not start.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
bool spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
msg_t spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
msg_t msg;
|
||||
|
||||
osalDbgCheckClassI();
|
||||
|
||||
osalDbgCheck((spip != NULL) && (n > 0U) && (rxbuf != NULL));
|
||||
#if SPI_SUPPORTS_CIRCULAR
|
||||
|
@ -382,7 +397,13 @@ bool spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf) {
|
|||
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
||||
|
||||
spip->state = SPI_ACTIVE;
|
||||
return spi_lld_receive(spip, n, rxbuf);
|
||||
msg = spi_lld_receive(spip, n, rxbuf);
|
||||
|
||||
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
||||
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
||||
#endif
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -398,19 +419,79 @@ bool spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf) {
|
|||
* @param[in] n number of words to receive
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
* @return The operation status.
|
||||
* @retval false if the operation started correctly.
|
||||
* @retval true if the operation did not start.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
bool ret;
|
||||
msg_t spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
ret = spiStartReceiveI(spip, n, rxbuf);
|
||||
msg = spiStartReceiveI(spip, n, rxbuf);
|
||||
osalSysUnlock();
|
||||
|
||||
return ret;
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the ongoing SPI operation.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[out sizep pointer to the counter of frames not yet transferred
|
||||
* or @p NULL
|
||||
* @return The operation status.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
msg_t spiStopTranferI(SPIDriver *spip, size_t *sizep) {
|
||||
msg_t msg;
|
||||
|
||||
osalDbgCheckClassI();
|
||||
|
||||
osalDbgCheck(spip != NULL);
|
||||
|
||||
osalDbgAssert((spip->state == SPI_READY) ||
|
||||
(spip->state == SPI_ACTIVE) ||
|
||||
(spip->state == SPI_COMPLETE),
|
||||
"invalid state");
|
||||
|
||||
if ((spip->state == SPI_ACTIVE) || (spip->state == SPI_COMPLETE)) {
|
||||
|
||||
/* Stopping transfer at low level.*/
|
||||
msg = spi_lld_stop_transfer(spip, sizep);
|
||||
spip->state = SPI_READY;
|
||||
|
||||
#if SPI_USE_SYNCHRONIZATION == TRUE
|
||||
osalThreadResumeI(&spip->sync_transfer, MSG_OK);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
msg = HAL_RET_SUCCESS;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the ongoing SPI operation, if any.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[out sizep pointer to the counter of frames not yet transferred
|
||||
* or @p NULL
|
||||
* @return The operation status.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t spiStopTranfer(SPIDriver *spip, size_t *sizep) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
|
||||
msg = spiStopTranferI(spip, sizep);
|
||||
osalOsRescheduleS();
|
||||
|
||||
osalSysUnlock();
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
#if (SPI_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||
|
@ -474,16 +555,23 @@ msg_t spiSynchronize(SPIDriver *spip, sysinterval_t timeout) {
|
|||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be ignored
|
||||
* @return The operation status.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void spiIgnore(SPIDriver *spip, size_t n) {
|
||||
bool ret;
|
||||
msg_t spiIgnore(SPIDriver *spip, size_t n) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
spiStartIgnoreI(spip, n);
|
||||
(void) spiSynchronizeS(spip, TIME_INFINITE);
|
||||
|
||||
msg = spiStartIgnoreI(spip, n);
|
||||
if (msg != MSG_OK) {
|
||||
msg = spiSynchronizeS(spip, TIME_INFINITE);
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -499,16 +587,24 @@ void spiIgnore(SPIDriver *spip, size_t n) {
|
|||
* @param[in] n number of words to be exchanged
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
* @return The operation status.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void spiExchange(SPIDriver *spip, size_t n,
|
||||
msg_t spiExchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
spiStartExchangeI(spip, n, txbuf, rxbuf);
|
||||
(void) spiSynchronizeS(spip, TIME_INFINITE);
|
||||
|
||||
msg = spiStartExchangeI(spip, n, txbuf, rxbuf);
|
||||
if (msg != MSG_OK) {
|
||||
msg = spiSynchronizeS(spip, TIME_INFINITE);
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -522,15 +618,23 @@ void spiExchange(SPIDriver *spip, size_t n,
|
|||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @return The operation status.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
msg_t spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
spiStartSendI(spip, n, txbuf);
|
||||
(void) spiSynchronizeS(spip, TIME_INFINITE);
|
||||
|
||||
msg = spiStartSendI(spip, n, txbuf);
|
||||
if (msg != MSG_OK) {
|
||||
msg = spiSynchronizeS(spip, TIME_INFINITE);
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -544,15 +648,23 @@ void spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
|
|||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to receive
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
* @return The operation status.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
msg_t spiReceive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
spiStartReceiveI(spip, n, rxbuf);
|
||||
(void) spiSynchronizeS(spip, TIME_INFINITE);
|
||||
|
||||
msg = spiStartReceiveI(spip, n, rxbuf);
|
||||
if (msg != MSG_OK) {
|
||||
msg = spiSynchronizeS(spip, TIME_INFINITE);
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endif /* SPI_USE_SYNCHRONIZATION == TRUE */
|
||||
|
||||
|
|
Loading…
Reference in New Issue