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>
<basetype ctype="chnflags_t" />
</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">
<brief>Type of structure representing a SIO configuration.</brief>
<basetype ctype="struct hal_sio_config" />

View File

@ -64,6 +64,10 @@
</macro>
</macros>
<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">
<brief>Type of structure representing a SPI configuration.</brief>
<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_queues.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
endif

View File

@ -477,6 +477,11 @@
*/
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.
*/

View File

@ -140,6 +140,11 @@
/* 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.
*/

View File

@ -116,6 +116,25 @@ SPIDriver SPID6;
/* 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. */
/*===========================================================================*/
@ -454,138 +473,224 @@ void spi_lld_init(void) {
* @notapi
*/
msg_t spi_lld_start(SPIDriver *spip) {
uint32_t ds;
msg_t msg;
/* Resetting TX pattern source.*/
spip->txsource = (uint32_t)STM32_SPI_FILLER_PATTERN;
/* If in stopped state then enables the SPI and DMA clocks.*/
if (spip->state == DRV_STATE_STOP) {
if (false) {
}
/* Activating SPI unit.*/
if (false) {
}
#if STM32_SPI_USE_SPI1
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
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
else if (&SPID2 == spip) {
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
else if (&SPID2 == spip) {
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
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
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
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
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
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
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
else if (&SPID6 == spip) {
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();
else if (&SPID6 == spip) {
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);
dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI6_RX);
dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI6_TX);
#endif
}
#endif
else {
osalDbgAssert(false, "invalid SPI instance");
}
/* DMA setup.*/
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
}
#endif
else {
/* De-activation before re-configuration.*/
spi_lld_disable(spip);
osalDbgAssert(false, "invalid SPI instance");
}
/* 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.*/
ds = __spi_getfield(spip, cr2) & SPI_CR2_DS;
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_lld_enable(spip);
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) {
/* 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");
}
}
return config;
}
#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__)
#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
#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);
msg_t spi_lld_start(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__)
void spi_lld_select(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) {
USART_TypeDef *u = siop->usart;
uint32_t presc, brr, clock;