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
|
||||||
#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.
|
* @brief Enables circular transfers APIs.
|
||||||
* @note Disabling this option saves both code and data space.
|
* @note Disabling this option saves both code and data space.
|
||||||
|
@ -358,13 +365,13 @@ do { \
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
#define _spi_wakeup_isr(spip) { \
|
#define __spi_wakeup_isr(spip) { \
|
||||||
osalSysLockFromISR(); \
|
osalSysLockFromISR(); \
|
||||||
osalThreadResumeI(&(spip)->sync_transfer, MSG_OK); \
|
osalThreadResumeI(&(spip)->sync_transfer, MSG_OK); \
|
||||||
osalSysUnlockFromISR(); \
|
osalSysUnlockFromISR(); \
|
||||||
}
|
}
|
||||||
#else /* !SPI_USE_SYNCHRONIZATION */
|
#else /* !SPI_USE_SYNCHRONIZATION */
|
||||||
#define _spi_wakeup_isr(spip)
|
#define __spi_wakeup_isr(spip)
|
||||||
#endif /* !SPI_USE_SYNCHRONIZATION */
|
#endif /* !SPI_USE_SYNCHRONIZATION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -381,7 +388,7 @@ do { \
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
#define _spi_isr_code(spip) { \
|
#define __spi_isr_code(spip) { \
|
||||||
if ((spip)->config->end_cb) { \
|
if ((spip)->config->end_cb) { \
|
||||||
(spip)->state = SPI_COMPLETE; \
|
(spip)->state = SPI_COMPLETE; \
|
||||||
(spip)->config->end_cb(spip); \
|
(spip)->config->end_cb(spip); \
|
||||||
|
@ -390,7 +397,7 @@ do { \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
(spip)->state = SPI_READY; \
|
(spip)->state = SPI_READY; \
|
||||||
_spi_wakeup_isr(spip); \
|
__spi_wakeup_isr(spip); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -405,7 +412,7 @@ do { \
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
#define _spi_isr_half_code(spip) { \
|
#define __spi_isr_half_code(spip) { \
|
||||||
if ((spip)->config->end_cb) { \
|
if ((spip)->config->end_cb) { \
|
||||||
(spip)->config->end_cb(spip); \
|
(spip)->config->end_cb(spip); \
|
||||||
} \
|
} \
|
||||||
|
@ -424,7 +431,7 @@ do { \
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
#define _spi_isr_full_code(spip) { \
|
#define __spi_isr_full_code(spip) { \
|
||||||
if ((spip)->config->end_cb) { \
|
if ((spip)->config->end_cb) { \
|
||||||
(spip)->state = SPI_COMPLETE; \
|
(spip)->state = SPI_COMPLETE; \
|
||||||
(spip)->config->end_cb(spip); \
|
(spip)->config->end_cb(spip); \
|
||||||
|
@ -447,25 +454,25 @@ extern "C" {
|
||||||
void spiStop(SPIDriver *spip);
|
void spiStop(SPIDriver *spip);
|
||||||
void spiSelect(SPIDriver *spip);
|
void spiSelect(SPIDriver *spip);
|
||||||
void spiUnselect(SPIDriver *spip);
|
void spiUnselect(SPIDriver *spip);
|
||||||
bool spiStartIgnoreI(SPIDriver *spip, size_t n);
|
msg_t spiStartIgnoreI(SPIDriver *spip, size_t n);
|
||||||
bool spiStartIgnore(SPIDriver *spip, size_t n);
|
msg_t spiStartIgnore(SPIDriver *spip, size_t n);
|
||||||
bool spiStartExchangeI(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);
|
const void *txbuf, void *rxbuf);
|
||||||
bool spiStartExchange(SPIDriver *spip, size_t n,
|
msg_t spiStartSendI(SPIDriver *spip, size_t n, const void *txbuf);
|
||||||
const void *txbuf, void *rxbuf);
|
msg_t spiStartSend(SPIDriver *spip, size_t n, const void *txbuf);
|
||||||
bool spiStartSendI(SPIDriver *spip, size_t n, const void *txbuf);
|
msg_t spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf);
|
||||||
bool spiStartSend(SPIDriver *spip, size_t n, const void *txbuf);
|
msg_t spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||||
bool spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf);
|
msg_t spiStopTransferI(SPIDriver *spip, size_t *sizep);
|
||||||
bool spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
msg_t spiStopTransfer(SPIDriver *spip, size_t *sizep);
|
||||||
size_t spiStopTransferI(SPIDriver *spip);
|
|
||||||
size_t spiStopTransfer(SPIDriver *spip);
|
|
||||||
#if SPI_USE_SYNCHRONIZATION == TRUE
|
#if SPI_USE_SYNCHRONIZATION == TRUE
|
||||||
msg_t spiSynchronizeS(SPIDriver *spip, sysinterval_t timeout);
|
msg_t spiSynchronizeS(SPIDriver *spip, sysinterval_t timeout);
|
||||||
msg_t spiSynchronize(SPIDriver *spip, sysinterval_t timeout);
|
msg_t spiSynchronize(SPIDriver *spip, sysinterval_t timeout);
|
||||||
void spiIgnore(SPIDriver *spip, size_t n);
|
msg_t spiIgnore(SPIDriver *spip, size_t n);
|
||||||
void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf);
|
msg_t spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf);
|
||||||
void spiSend(SPIDriver *spip, size_t n, const void *txbuf);
|
msg_t spiSend(SPIDriver *spip, size_t n, const void *txbuf);
|
||||||
void spiReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
msg_t spiReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||||
#endif
|
#endif
|
||||||
#if SPI_USE_MUTUAL_EXCLUSION == TRUE
|
#if SPI_USE_MUTUAL_EXCLUSION == TRUE
|
||||||
void spiAcquireBus(SPIDriver *spip);
|
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 (spip->config->circular) {
|
||||||
if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
|
if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
|
||||||
/* Half buffer interrupt.*/
|
/* Half buffer interrupt.*/
|
||||||
_spi_isr_half_code(spip);
|
__spi_isr_half_code(spip);
|
||||||
}
|
}
|
||||||
if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
|
if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
|
||||||
/* End buffer interrupt.*/
|
/* End buffer interrupt.*/
|
||||||
_spi_isr_full_code(spip);
|
__spi_isr_full_code(spip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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
|
/* Portable SPI ISR code defined in the high level driver, note, it is
|
||||||
a macro.*/
|
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
|
#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. */
|
/* Driver interrupt handlers. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -309,122 +339,120 @@ void spi_lld_init(void) {
|
||||||
* @brief Configures and activates the SPI peripheral.
|
* @brief Configures and activates the SPI peripheral.
|
||||||
*
|
*
|
||||||
* @param[in] spip pointer to the @p SPIDriver object
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
void spi_lld_start(SPIDriver *spip) {
|
msg_t spi_lld_start(SPIDriver *spip) {
|
||||||
uint32_t ds;
|
uint32_t ds;
|
||||||
|
msg_t msg;
|
||||||
|
|
||||||
/* If in stopped state then enables the SPI and DMA clocks.*/
|
/* If in stopped state then enables the SPI and DMA clocks.*/
|
||||||
if (spip->state == SPI_STOP) {
|
if (spip->state == SPI_STOP) {
|
||||||
|
if (false) {
|
||||||
|
}
|
||||||
|
|
||||||
#if STM32_SPI_USE_SPI1
|
#if STM32_SPI_USE_SPI1
|
||||||
if (&SPID1 == spip) {
|
else if (&SPID1 == spip) {
|
||||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI1_RX_DMA_STREAM,
|
msg = spi_lld_get_dma(spip,
|
||||||
STM32_SPI_SPI1_IRQ_PRIORITY,
|
STM32_SPI_SPI1_RX_DMA_STREAM,
|
||||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
STM32_SPI_SPI1_TX_DMA_STREAM,
|
||||||
(void *)spip);
|
STM32_SPI_SPI1_IRQ_PRIORITY);
|
||||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
if (msg != HAL_RET_SUCCESS) {
|
||||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI1_TX_DMA_STREAM,
|
return msg;
|
||||||
STM32_SPI_SPI1_IRQ_PRIORITY,
|
}
|
||||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
|
||||||
(void *)spip);
|
|
||||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
|
||||||
rccEnableSPI1(true);
|
rccEnableSPI1(true);
|
||||||
|
rccResetSPI1();
|
||||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI1_RX);
|
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI1_RX);
|
||||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI1_TX);
|
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI1_TX);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if STM32_SPI_USE_SPI2
|
#if STM32_SPI_USE_SPI2
|
||||||
if (&SPID2 == spip) {
|
if (&SPID2 == spip) {
|
||||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI2_RX_DMA_STREAM,
|
msg = spi_lld_get_dma(spip,
|
||||||
STM32_SPI_SPI2_IRQ_PRIORITY,
|
STM32_SPI_SPI2_RX_DMA_STREAM,
|
||||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
STM32_SPI_SPI2_TX_DMA_STREAM,
|
||||||
(void *)spip);
|
STM32_SPI_SPI2_IRQ_PRIORITY);
|
||||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
if (msg != HAL_RET_SUCCESS) {
|
||||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI2_TX_DMA_STREAM,
|
return msg;
|
||||||
STM32_SPI_SPI2_IRQ_PRIORITY,
|
}
|
||||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
|
||||||
(void *)spip);
|
|
||||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
|
||||||
rccEnableSPI2(true);
|
rccEnableSPI2(true);
|
||||||
|
rccResetSPI2();
|
||||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI2_RX);
|
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI2_RX);
|
||||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI2_TX);
|
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI2_TX);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if STM32_SPI_USE_SPI3
|
#if STM32_SPI_USE_SPI3
|
||||||
if (&SPID3 == spip) {
|
else if (&SPID3 == spip) {
|
||||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI3_RX_DMA_STREAM,
|
msg = spi_lld_get_dma(spip,
|
||||||
STM32_SPI_SPI3_IRQ_PRIORITY,
|
STM32_SPI_SPI3_RX_DMA_STREAM,
|
||||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
STM32_SPI_SPI3_TX_DMA_STREAM,
|
||||||
(void *)spip);
|
STM32_SPI_SPI3_IRQ_PRIORITY);
|
||||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
if (msg != HAL_RET_SUCCESS) {
|
||||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI3_TX_DMA_STREAM,
|
return msg;
|
||||||
STM32_SPI_SPI3_IRQ_PRIORITY,
|
}
|
||||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
|
||||||
(void *)spip);
|
|
||||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
|
||||||
rccEnableSPI3(true);
|
rccEnableSPI3(true);
|
||||||
|
rccResetSPI3();
|
||||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI3_RX);
|
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI3_RX);
|
||||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI3_TX);
|
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI3_TX);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if STM32_SPI_USE_SPI4
|
#if STM32_SPI_USE_SPI4
|
||||||
if (&SPID4 == spip) {
|
else if (&SPID4 == spip) {
|
||||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI4_RX_DMA_STREAM,
|
msg = spi_lld_get_dma(spip,
|
||||||
STM32_SPI_SPI4_IRQ_PRIORITY,
|
STM32_SPI_SPI4_RX_DMA_STREAM,
|
||||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
STM32_SPI_SPI4_TX_DMA_STREAM,
|
||||||
(void *)spip);
|
STM32_SPI_SPI4_IRQ_PRIORITY);
|
||||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
if (msg != HAL_RET_SUCCESS) {
|
||||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI4_TX_DMA_STREAM,
|
return msg;
|
||||||
STM32_SPI_SPI4_IRQ_PRIORITY,
|
}
|
||||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
|
||||||
(void *)spip);
|
|
||||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
|
||||||
rccEnableSPI4(true);
|
rccEnableSPI4(true);
|
||||||
|
rccResetSPI4();
|
||||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI4_RX);
|
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI4_RX);
|
||||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI4_TX);
|
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI4_TX);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if STM32_SPI_USE_SPI5
|
#if STM32_SPI_USE_SPI5
|
||||||
if (&SPID5 == spip) {
|
else if (&SPID5 == spip) {
|
||||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI5_RX_DMA_STREAM,
|
msg = spi_lld_get_dma(spip,
|
||||||
STM32_SPI_SPI5_IRQ_PRIORITY,
|
STM32_SPI_SPI5_RX_DMA_STREAM,
|
||||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
STM32_SPI_SPI5_TX_DMA_STREAM,
|
||||||
(void *)spip);
|
STM32_SPI_SPI5_IRQ_PRIORITY);
|
||||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
if (msg != HAL_RET_SUCCESS) {
|
||||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI5_TX_DMA_STREAM,
|
return msg;
|
||||||
STM32_SPI_SPI5_IRQ_PRIORITY,
|
}
|
||||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
|
||||||
(void *)spip);
|
|
||||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
|
||||||
rccEnableSPI5(true);
|
rccEnableSPI5(true);
|
||||||
|
rccResetSPI5();
|
||||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI5_RX);
|
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI5_RX);
|
||||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI5_TX);
|
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI5_TX);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if STM32_SPI_USE_SPI6
|
#if STM32_SPI_USE_SPI6
|
||||||
if (&SPID6 == spip) {
|
if (&SPID6 == spip) {
|
||||||
spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI6_RX_DMA_STREAM,
|
msg = spi_lld_get_dma(spip,
|
||||||
STM32_SPI_SPI6_IRQ_PRIORITY,
|
STM32_SPI_SPI6_RX_DMA_STREAM,
|
||||||
(stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
|
STM32_SPI_SPI6_TX_DMA_STREAM,
|
||||||
(void *)spip);
|
STM32_SPI_SPI6_IRQ_PRIORITY);
|
||||||
osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
|
if (msg != HAL_RET_SUCCESS) {
|
||||||
spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI6_TX_DMA_STREAM,
|
return msg;
|
||||||
STM32_SPI_SPI6_IRQ_PRIORITY,
|
}
|
||||||
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
|
|
||||||
(void *)spip);
|
|
||||||
osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
|
|
||||||
rccEnableSPI6(true);
|
rccEnableSPI6(true);
|
||||||
|
rccResetSPI6();
|
||||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||||
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI6_RX);
|
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI6_RX);
|
||||||
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI6_TX);
|
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI6_TX);
|
||||||
|
@ -432,6 +460,10 @@ void spi_lld_start(SPIDriver *spip) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
else {
|
||||||
|
osalDbgAssert(false, "invalid SPI instance");
|
||||||
|
}
|
||||||
|
|
||||||
/* DMA setup.*/
|
/* DMA setup.*/
|
||||||
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
|
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
|
||||||
dmaStreamSetPeripheral(spip->dmatx, &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 |
|
spip->spi->CR2 = spip->config->cr2 | SPI_CR2_FRXTH | SPI_CR2_SSOE |
|
||||||
SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
|
SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
|
||||||
spip->spi->CR1 |= SPI_CR1_SPE;
|
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] spip pointer to the @p SPIDriver object
|
||||||
* @param[in] n number of words to be ignored
|
* @param[in] n number of words to be ignored
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @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");
|
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->dmarx);
|
||||||
dmaStreamEnable(spip->dmatx);
|
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] n number of words to be exchanged
|
||||||
* @param[in] txbuf the pointer to the transmit buffer
|
* @param[in] txbuf the pointer to the transmit buffer
|
||||||
* @param[out] rxbuf the pointer to the receive buffer
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
bool spi_lld_exchange(SPIDriver *spip, size_t n,
|
msg_t spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||||
const void *txbuf, void *rxbuf) {
|
const void *txbuf, void *rxbuf) {
|
||||||
|
|
||||||
osalDbgAssert(n < 65536, "unsupported DMA transfer size");
|
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->dmarx);
|
||||||
dmaStreamEnable(spip->dmatx);
|
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] spip pointer to the @p SPIDriver object
|
||||||
* @param[in] n number of words to send
|
* @param[in] n number of words to send
|
||||||
* @param[in] txbuf the pointer to the transmit buffer
|
* @param[in] txbuf the pointer to the transmit buffer
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @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");
|
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->dmarx);
|
||||||
dmaStreamEnable(spip->dmatx);
|
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] spip pointer to the @p SPIDriver object
|
||||||
* @param[in] n number of words to receive
|
* @param[in] n number of words to receive
|
||||||
* @param[out] rxbuf the pointer to the receive buffer
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @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");
|
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->dmarx);
|
||||||
dmaStreamEnable(spip->dmatx);
|
dmaStreamEnable(spip->dmatx);
|
||||||
|
|
||||||
|
return HAL_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
/**
|
||||||
* @brief Aborts the ongoing SPI operation, if any.
|
* @brief Aborts the ongoing SPI operation, if any.
|
||||||
*
|
*
|
||||||
* @param[in] spip pointer to the @p SPIDriver object
|
* @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
|
* @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);
|
dmaStreamDisable(spip->dmatx);
|
||||||
|
|
||||||
|
/* Waiting for the SPI to become not busy.*/
|
||||||
|
msg = spi_lld_wait_not_busy(spip);
|
||||||
|
|
||||||
|
/* Stopping RX DMA.*/
|
||||||
dmaStreamDisable(spip->dmarx);
|
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.
|
* @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;
|
spip->config = config;
|
||||||
|
|
||||||
#if defined(SPI_LLD_ENHANCED_API)
|
|
||||||
msg = spi_lld_start(spip);
|
msg = spi_lld_start(spip);
|
||||||
#else
|
if (msg == HAL_RET_SUCCESS) {
|
||||||
spi_lld_start(spip);
|
|
||||||
msg = HAL_START_SUCCESS;
|
|
||||||
#endif
|
|
||||||
if (msg == HAL_START_SUCCESS) {
|
|
||||||
spip->state = SPI_READY;
|
spip->state = SPI_READY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -113,6 +108,10 @@ msg_t spiStart(SPIDriver *spip, const SPIConfig *config) {
|
||||||
|
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
|
||||||
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
||||||
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,12 +184,13 @@ void spiUnselect(SPIDriver *spip) {
|
||||||
* @param[in] spip pointer to the @p SPIDriver object
|
* @param[in] spip pointer to the @p SPIDriver object
|
||||||
* @param[in] n number of words to be ignored
|
* @param[in] n number of words to be ignored
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval false if the operation started correctly.
|
|
||||||
* @retval true if the operation did not start.
|
|
||||||
*
|
*
|
||||||
* @iclass
|
* @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));
|
osalDbgCheck((spip != NULL) && (n > 0U));
|
||||||
#if SPI_SUPPORTS_CIRCULAR
|
#if SPI_SUPPORTS_CIRCULAR
|
||||||
|
@ -200,7 +200,13 @@ bool spiStartIgnoreI(SPIDriver *spip, size_t n) {
|
||||||
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
||||||
|
|
||||||
spip->state = SPI_ACTIVE;
|
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] spip pointer to the @p SPIDriver object
|
||||||
* @param[in] n number of words to be ignored
|
* @param[in] n number of words to be ignored
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval false if the operation started correctly.
|
|
||||||
* @retval true if the operation did not start.
|
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool spiStartIgnore(SPIDriver *spip, size_t n) {
|
msg_t spiStartIgnore(SPIDriver *spip, size_t n) {
|
||||||
bool ret;
|
msg_t msg;
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
ret = spiStartIgnoreI(spip, n);
|
msg = spiStartIgnoreI(spip, n);
|
||||||
osalSysUnlock();
|
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[in] txbuf the pointer to the transmit buffer
|
||||||
* @param[out] rxbuf the pointer to the receive buffer
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval false if the operation started correctly.
|
|
||||||
* @retval true if the operation did not start.
|
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
bool spiStartExchangeI(SPIDriver *spip, size_t n,
|
msg_t spiStartExchangeI(SPIDriver *spip, size_t n,
|
||||||
const void *txbuf, void *rxbuf) {
|
const void *txbuf, void *rxbuf) {
|
||||||
|
msg_t msg;
|
||||||
|
|
||||||
|
osalDbgCheckClassI();
|
||||||
|
|
||||||
osalDbgCheck((spip != NULL) && (n > 0U) &&
|
osalDbgCheck((spip != NULL) && (n > 0U) &&
|
||||||
(rxbuf != NULL) && (txbuf != NULL));
|
(rxbuf != NULL) && (txbuf != NULL));
|
||||||
|
@ -261,7 +266,13 @@ bool spiStartExchangeI(SPIDriver *spip, size_t n,
|
||||||
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
||||||
|
|
||||||
spip->state = SPI_ACTIVE;
|
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[in] txbuf the pointer to the transmit buffer
|
||||||
* @param[out] rxbuf the pointer to the receive buffer
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval false if the operation started correctly.
|
|
||||||
* @retval true if the operation did not start.
|
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool spiStartExchange(SPIDriver *spip, size_t n,
|
msg_t spiStartExchange(SPIDriver *spip, size_t n,
|
||||||
const void *txbuf, void *rxbuf) {
|
const void *txbuf, void *rxbuf) {
|
||||||
bool ret;
|
msg_t msg;
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
ret = spiStartExchangeI(spip, n, txbuf, rxbuf);
|
msg = spiStartExchangeI(spip, n, txbuf, rxbuf);
|
||||||
osalSysUnlock();
|
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] n number of words to send
|
||||||
* @param[in] txbuf the pointer to the transmit buffer
|
* @param[in] txbuf the pointer to the transmit buffer
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval false if the operation started correctly.
|
|
||||||
* @retval true if the operation did not start.
|
|
||||||
*
|
*
|
||||||
* @iclass
|
* @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));
|
osalDbgCheck((spip != NULL) && (n > 0U) && (txbuf != NULL));
|
||||||
#if SPI_SUPPORTS_CIRCULAR
|
#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");
|
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
||||||
|
|
||||||
spip->state = SPI_ACTIVE;
|
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] n number of words to send
|
||||||
* @param[in] txbuf the pointer to the transmit buffer
|
* @param[in] txbuf the pointer to the transmit buffer
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval false if the operation started correctly.
|
|
||||||
* @retval true if the operation did not start.
|
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) {
|
msg_t spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||||
bool ret;
|
msg_t msg;
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
ret = spiStartSendI(spip, n, txbuf);
|
msg = spiStartSendI(spip, n, txbuf);
|
||||||
osalSysUnlock();
|
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[in] n number of words to receive
|
||||||
* @param[out] rxbuf the pointer to the receive buffer
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval false if the operation started correctly.
|
|
||||||
* @retval true if the operation did not start.
|
|
||||||
*
|
*
|
||||||
* @iclass
|
* @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));
|
osalDbgCheck((spip != NULL) && (n > 0U) && (rxbuf != NULL));
|
||||||
#if SPI_SUPPORTS_CIRCULAR
|
#if SPI_SUPPORTS_CIRCULAR
|
||||||
|
@ -382,7 +397,13 @@ bool spiStartReceiveI(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||||
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
osalDbgAssert(spip->state == SPI_READY, "not ready");
|
||||||
|
|
||||||
spip->state = SPI_ACTIVE;
|
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[in] n number of words to receive
|
||||||
* @param[out] rxbuf the pointer to the receive buffer
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval false if the operation started correctly.
|
|
||||||
* @retval true if the operation did not start.
|
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
|
msg_t spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||||
bool ret;
|
msg_t msg;
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
ret = spiStartReceiveI(spip, n, rxbuf);
|
msg = spiStartReceiveI(spip, n, rxbuf);
|
||||||
osalSysUnlock();
|
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__)
|
#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] spip pointer to the @p SPIDriver object
|
||||||
* @param[in] n number of words to be ignored
|
* @param[in] n number of words to be ignored
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void spiIgnore(SPIDriver *spip, size_t n) {
|
msg_t spiIgnore(SPIDriver *spip, size_t n) {
|
||||||
bool ret;
|
msg_t msg;
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
spiStartIgnoreI(spip, n);
|
|
||||||
(void) spiSynchronizeS(spip, TIME_INFINITE);
|
msg = spiStartIgnoreI(spip, n);
|
||||||
|
if (msg != MSG_OK) {
|
||||||
|
msg = spiSynchronizeS(spip, TIME_INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
osalSysUnlock();
|
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] n number of words to be exchanged
|
||||||
* @param[in] txbuf the pointer to the transmit buffer
|
* @param[in] txbuf the pointer to the transmit buffer
|
||||||
* @param[out] rxbuf the pointer to the receive buffer
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void spiExchange(SPIDriver *spip, size_t n,
|
msg_t spiExchange(SPIDriver *spip, size_t n,
|
||||||
const void *txbuf, void *rxbuf) {
|
const void *txbuf, void *rxbuf) {
|
||||||
|
msg_t msg;
|
||||||
|
|
||||||
osalSysLock();
|
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();
|
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] spip pointer to the @p SPIDriver object
|
||||||
* @param[in] n number of words to send
|
* @param[in] n number of words to send
|
||||||
* @param[in] txbuf the pointer to the transmit buffer
|
* @param[in] txbuf the pointer to the transmit buffer
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @api
|
* @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();
|
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();
|
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] spip pointer to the @p SPIDriver object
|
||||||
* @param[in] n number of words to receive
|
* @param[in] n number of words to receive
|
||||||
* @param[out] rxbuf the pointer to the receive buffer
|
* @param[out] rxbuf the pointer to the receive buffer
|
||||||
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) {
|
msg_t spiReceive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||||
|
msg_t msg;
|
||||||
|
|
||||||
osalSysLock();
|
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();
|
osalSysUnlock();
|
||||||
|
|
||||||
|
return msg;
|
||||||
}
|
}
|
||||||
#endif /* SPI_USE_SYNCHRONIZATION == TRUE */
|
#endif /* SPI_USE_SYNCHRONIZATION == TRUE */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue