XHAL SPI ready for testing.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16295 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2023-06-19 17:26:17 +00:00
parent eb6e882637
commit dcb1f9fc76
8 changed files with 263 additions and 172 deletions

View File

@ -407,6 +407,10 @@ do {
<brief>Type of SIO event flags.</brief> <brief>Type of SIO event flags.</brief>
<basetype ctype="chnflags_t" /> <basetype ctype="chnflags_t" />
</typedef> </typedef>
<typedef name="hal_sio_driver_c">
<brief>Type of structure representing a SIO driver.</brief>
<basetype ctype="struct hal_sio_driver" />
</typedef>
<typedef name="hal_sio_config_t"> <typedef name="hal_sio_config_t">
<brief>Type of structure representing a SIO configuration.</brief> <brief>Type of structure representing a SIO configuration.</brief>
<basetype ctype="struct hal_sio_config" /> <basetype ctype="struct hal_sio_config" />

View File

@ -64,6 +64,10 @@
</macro> </macro>
</macros> </macros>
<types> <types>
<typedef name="hal_spi_driver_c">
<brief>Type of structure representing a SPI driver.</brief>
<basetype ctype="struct hal_spi_driver" />
</typedef>
<typedef name="hal_spi_config_t"> <typedef name="hal_spi_config_t">
<brief>Type of structure representing a SPI configuration.</brief> <brief>Type of structure representing a SPI configuration.</brief>
<basetype ctype="struct hal_spi_config" /> <basetype ctype="struct hal_spi_config" />

View File

@ -34,7 +34,7 @@ HALSRC = $(CHIBIOS)/os/xhal/src/hal.c \
$(CHIBIOS)/os/xhal/src/hal_st.c \ $(CHIBIOS)/os/xhal/src/hal_st.c \
$(CHIBIOS)/os/xhal/src/hal_queues.c \ $(CHIBIOS)/os/xhal/src/hal_queues.c \
$(CHIBIOS)/os/xhal/src/hal_pal.c \ $(CHIBIOS)/os/xhal/src/hal_pal.c \
$(CHIBIOS)/os/xhal/src/hal_sio.c $(CHIBIOS)/os/xhal/src/hal_sio.c \
$(CHIBIOS)/os/xhal/src/hal_spi.c $(CHIBIOS)/os/xhal/src/hal_spi.c
endif endif

View File

@ -477,6 +477,11 @@
*/ */
typedef chnflags_t sioevents_t; typedef chnflags_t sioevents_t;
/**
* @brief Type of structure representing a SIO driver.
*/
typedef struct hal_sio_driver hal_sio_driver_c;
/** /**
* @brief Type of structure representing a SIO configuration. * @brief Type of structure representing a SIO configuration.
*/ */

View File

@ -140,6 +140,11 @@
/* Module data structures and types. */ /* Module data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Type of structure representing a SPI driver.
*/
typedef struct hal_spi_driver hal_spi_driver_c;
/** /**
* @brief Type of structure representing a SPI configuration. * @brief Type of structure representing a SPI configuration.
*/ */

View File

@ -116,6 +116,25 @@ SPIDriver SPID6;
/* Driver local variables and types. */ /* Driver local variables and types. */
/*===========================================================================*/ /*===========================================================================*/
/*
* Default SPI configuration.
*/
static const hal_spi_config_t spi_default_config = {
.circular = false,
.slave = false,
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined (__DOXYGEN__)
.ssline = PAL_LINE(STM32_SPI_DEFAULT_PORT, STM32_SPI_DEFAULT_PAD);
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PORT
.ssport = STM32_SPI_DEFAULT_PORT,
.ssport = PAL_PORT_BIT(STM32_SPI_DEFAULT_PAD),
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PAD
.ssport = STM32_SPI_DEFAULT_PORT,
.sspad = STM32_SPI_DEFAULT_PAD,
#endif
.cr1 = STM32_SPI_DEFAULT_CR1,
.cr2 = STM32_SPI_DEFAULT_CR2
};
/*===========================================================================*/ /*===========================================================================*/
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
@ -454,138 +473,224 @@ void spi_lld_init(void) {
* @notapi * @notapi
*/ */
msg_t spi_lld_start(SPIDriver *spip) { msg_t spi_lld_start(SPIDriver *spip) {
uint32_t ds;
msg_t msg; msg_t msg;
/* Resetting TX pattern source.*/ /* Resetting TX pattern source.*/
spip->txsource = (uint32_t)STM32_SPI_FILLER_PATTERN; spip->txsource = (uint32_t)STM32_SPI_FILLER_PATTERN;
/* If in stopped state then enables the SPI and DMA clocks.*/ /* Activating SPI unit.*/
if (spip->state == DRV_STATE_STOP) { if (false) {
if (false) { }
}
#if STM32_SPI_USE_SPI1 #if STM32_SPI_USE_SPI1
else if (&SPID1 == spip) { else if (&SPID1 == spip) {
msg = spi_lld_get_dma(spip, msg = spi_lld_get_dma(spip,
STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI_SPI1_RX_DMA_STREAM,
STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI_SPI1_TX_DMA_STREAM,
STM32_SPI_SPI1_IRQ_PRIORITY); STM32_SPI_SPI1_IRQ_PRIORITY);
if (msg != HAL_RET_SUCCESS) { if (msg != HAL_RET_SUCCESS) {
return msg; 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
} }
rccEnableSPI1(true);
rccResetSPI1();
#if STM32_DMA_SUPPORTS_DMAMUX
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI1_RX);
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI1_TX);
#endif
}
#endif #endif
#if STM32_SPI_USE_SPI2 #if STM32_SPI_USE_SPI2
else if (&SPID2 == spip) { else if (&SPID2 == spip) {
msg = spi_lld_get_dma(spip, msg = spi_lld_get_dma(spip,
STM32_SPI_SPI2_RX_DMA_STREAM, STM32_SPI_SPI2_RX_DMA_STREAM,
STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI_SPI2_TX_DMA_STREAM,
STM32_SPI_SPI2_IRQ_PRIORITY); STM32_SPI_SPI2_IRQ_PRIORITY);
if (msg != HAL_RET_SUCCESS) { if (msg != HAL_RET_SUCCESS) {
return msg; 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
} }
rccEnableSPI2(true);
rccResetSPI2();
#if STM32_DMA_SUPPORTS_DMAMUX
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI2_RX);
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI2_TX);
#endif
}
#endif #endif
#if STM32_SPI_USE_SPI3 #if STM32_SPI_USE_SPI3
else if (&SPID3 == spip) { else if (&SPID3 == spip) {
msg = spi_lld_get_dma(spip, msg = spi_lld_get_dma(spip,
STM32_SPI_SPI3_RX_DMA_STREAM, STM32_SPI_SPI3_RX_DMA_STREAM,
STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI_SPI3_TX_DMA_STREAM,
STM32_SPI_SPI3_IRQ_PRIORITY); STM32_SPI_SPI3_IRQ_PRIORITY);
if (msg != HAL_RET_SUCCESS) { if (msg != HAL_RET_SUCCESS) {
return msg; 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
} }
rccEnableSPI3(true);
rccResetSPI3();
#if STM32_DMA_SUPPORTS_DMAMUX
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI3_RX);
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI3_TX);
#endif
}
#endif #endif
#if STM32_SPI_USE_SPI4 #if STM32_SPI_USE_SPI4
else if (&SPID4 == spip) { else if (&SPID4 == spip) {
msg = spi_lld_get_dma(spip, msg = spi_lld_get_dma(spip,
STM32_SPI_SPI4_RX_DMA_STREAM, STM32_SPI_SPI4_RX_DMA_STREAM,
STM32_SPI_SPI4_TX_DMA_STREAM, STM32_SPI_SPI4_TX_DMA_STREAM,
STM32_SPI_SPI4_IRQ_PRIORITY); STM32_SPI_SPI4_IRQ_PRIORITY);
if (msg != HAL_RET_SUCCESS) { if (msg != HAL_RET_SUCCESS) {
return msg; 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
} }
rccEnableSPI4(true);
rccResetSPI4();
#if STM32_DMA_SUPPORTS_DMAMUX
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI4_RX);
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI4_TX);
#endif
}
#endif #endif
#if STM32_SPI_USE_SPI5 #if STM32_SPI_USE_SPI5
else if (&SPID5 == spip) { else if (&SPID5 == spip) {
msg = spi_lld_get_dma(spip, msg = spi_lld_get_dma(spip,
STM32_SPI_SPI5_RX_DMA_STREAM, STM32_SPI_SPI5_RX_DMA_STREAM,
STM32_SPI_SPI5_TX_DMA_STREAM, STM32_SPI_SPI5_TX_DMA_STREAM,
STM32_SPI_SPI5_IRQ_PRIORITY); STM32_SPI_SPI5_IRQ_PRIORITY);
if (msg != HAL_RET_SUCCESS) { if (msg != HAL_RET_SUCCESS) {
return msg; 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
} }
rccEnableSPI5(true);
rccResetSPI5();
#if STM32_DMA_SUPPORTS_DMAMUX
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI5_RX);
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI5_TX);
#endif
}
#endif #endif
#if STM32_SPI_USE_SPI6 #if STM32_SPI_USE_SPI6
else if (&SPID6 == spip) { else if (&SPID6 == spip) {
msg = spi_lld_get_dma(spip, msg = spi_lld_get_dma(spip,
STM32_SPI_SPI6_RX_DMA_STREAM, STM32_SPI_SPI6_RX_DMA_STREAM,
STM32_SPI_SPI6_TX_DMA_STREAM, STM32_SPI_SPI6_TX_DMA_STREAM,
STM32_SPI_SPI6_IRQ_PRIORITY); STM32_SPI_SPI6_IRQ_PRIORITY);
if (msg != HAL_RET_SUCCESS) { if (msg != HAL_RET_SUCCESS) {
return msg; return msg;
} }
rccEnableSPI6(true); rccEnableSPI6(true);
rccResetSPI6(); 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);
#endif #endif
}
#endif
else {
osalDbgAssert(false, "invalid SPI instance");
}
/* DMA setup.*/
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
} }
#endif
else { else {
/* De-activation before re-configuration.*/ osalDbgAssert(false, "invalid SPI instance");
spi_lld_disable(spip);
} }
/* DMA setup.*/
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
/* Configures the peripheral.*/
spi_lld_configure(spip, &spi_default_config);
return HAL_RET_SUCCESS;
}
/**
* @brief Deactivates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_stop(SPIDriver *spip) {
/* Just in case this has been called uncleanly.*/
spi_lld_disable(spip);
/* SPI cleanup.*/
spip->spi->CR1 = 0;
spip->spi->CR2 = 0;
/* DMA channels release.*/
dmaStreamFreeI(spip->dmatx);
dmaStreamFreeI(spip->dmarx);
spip->dmarx = NULL;
spip->dmatx = NULL;
/* Clock shutdown.*/
if (false) {
}
#if STM32_SPI_USE_SPI1
else if (&SPID1 == spip) {
rccDisableSPI1();
}
#endif
#if STM32_SPI_USE_SPI2
else if (&SPID2 == spip) {
rccDisableSPI2();
}
#endif
#if STM32_SPI_USE_SPI3
else if (&SPID3 == spip) {
rccDisableSPI3();
}
#endif
#if STM32_SPI_USE_SPI4
else if (&SPID4 == spip) {
rccDisableSPI4();
}
#endif
#if STM32_SPI_USE_SPI5
else if (&SPID5 == spip) {
rccDisableSPI5();
}
#endif
#if STM32_SPI_USE_SPI6
else if (&SPID6 == spip) {
rccDisableSPI6();
}
#endif
else {
osalDbgAssert(false, "invalid SPI instance");
}
}
/**
* @brief SPI configuration.
*
* @param[in] spip pointer to the @p hal_spi_driver_c object
* @param[in] config pointer to the @p hal_spi_config_t structure
* @return A pointer to the current configuration structure.
*
* @notapi
*/
const hal_spi_config_t *spi_lld_configure(hal_spi_driver_c *spip,
const hal_spi_config_t *config) {
uint32_t ds;
if (config == NULL) {
config = &spi_default_config;
}
/* De-activation before re-configuration.*/
spi_lld_disable(spip);
/* Configuration-specific DMA setup.*/ /* Configuration-specific DMA setup.*/
ds = __spi_getfield(spip, cr2) & SPI_CR2_DS; ds = __spi_getfield(spip, cr2) & SPI_CR2_DS;
if (!ds || (ds <= (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0))) { if (!ds || (ds <= (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0))) {
@ -615,78 +720,7 @@ msg_t spi_lld_start(SPIDriver *spip) {
/* SPI setup.*/ /* SPI setup.*/
spi_lld_enable(spip); spi_lld_enable(spip);
return HAL_RET_SUCCESS; return config;
}
/**
* @brief Deactivates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*
* @notapi
*/
void spi_lld_stop(SPIDriver *spip) {
/* If in ready state then disables the SPI clock.*/
if (spip->state == SPI_READY) {
/* Just in case this has been called uncleanly.*/
spi_lld_disable(spip);
/* SPI cleanup.*/
spip->spi->CR1 = 0;
spip->spi->CR2 = 0;
/* DMA channels release.*/
dmaStreamFreeI(spip->dmatx);
dmaStreamFreeI(spip->dmarx);
spip->dmarx = NULL;
spip->dmatx = NULL;
/* Clock shutdown.*/
if (false) {
}
#if STM32_SPI_USE_SPI1
else if (&SPID1 == spip) {
rccDisableSPI1();
}
#endif
#if STM32_SPI_USE_SPI2
else if (&SPID2 == spip) {
rccDisableSPI2();
}
#endif
#if STM32_SPI_USE_SPI3
else if (&SPID3 == spip) {
rccDisableSPI3();
}
#endif
#if STM32_SPI_USE_SPI4
else if (&SPID4 == spip) {
rccDisableSPI4();
}
#endif
#if STM32_SPI_USE_SPI5
else if (&SPID5 == spip) {
rccDisableSPI5();
}
#endif
#if STM32_SPI_USE_SPI6
else if (&SPID6 == spip) {
rccDisableSPI6();
}
#endif
else {
osalDbgAssert(false, "invalid SPI instance");
}
}
} }
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) #if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)

View File

@ -218,6 +218,34 @@
#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) #if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
#endif #endif
/**
* @brief Default PAL port for Chip Select line.
*/
#if !defined(STM32_SPI_DEFAULT_PORT) || defined(__DOXYGEN__)
#define STM32_SPI_DEFAULT_PORT GPIOA
#endif
/**
* @brief Default PAL pad for Chip Select line.
*/
#if !defined(STM32_SPI_DEFAULT_PAD) || defined(__DOXYGEN__)
#define STM32_SPI_DEFAULT_PAD 0U
#endif
/**
* @brief CR1 setting for default SPI configuration.
*/
#if !defined(STM32_SPI_DEFAULT_CR1) || defined(__DOXYGEN__)
#define STM32_SPI_DEFAULT_CR1 (SPI_CR1_BR_2 | SPI_CR1_BR_1)
#endif
/**
* @brief CR2 setting for default SPI configuration.
*/
#if !defined(STM32_SPI_DEFAULT_CR2) || defined(__DOXYGEN__)
#define STM32_SPI_DEFAULT_CR2 (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0)
#endif
/** @} */ /** @} */
/*===========================================================================*/ /*===========================================================================*/
@ -549,6 +577,8 @@ extern "C" {
void spi_lld_init(void); void spi_lld_init(void);
msg_t spi_lld_start(SPIDriver *spip); msg_t spi_lld_start(SPIDriver *spip);
void spi_lld_stop(SPIDriver *spip); void spi_lld_stop(SPIDriver *spip);
const hal_spi_config_t *spi_lld_configure(hal_spi_driver_c *spip,
const hal_spi_config_t *config);
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) #if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
void spi_lld_select(SPIDriver *spip); void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip); void spi_lld_unselect(SPIDriver *spip);

View File

@ -460,6 +460,15 @@ void sio_lld_stop(SIODriver *siop) {
} }
} }
/**
* @brief SIO configuration.
*
* @param[in] siop pointer to the @p SIODriver object
* @param[in] config pointer to the @p SIOConfig structure
* @return A pointer to the current configuration structure.
*
* @notapi
*/
const SIOConfig *sio_lld_configure(SIODriver *siop, const SIOConfig *config) { const SIOConfig *sio_lld_configure(SIODriver *siop, const SIOConfig *config) {
USART_TypeDef *u = siop->usart; USART_TypeDef *u = siop->usart;
uint32_t presc, brr, clock; uint32_t presc, brr, clock;