aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms/STM32
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2010-10-11 11:48:03 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2010-10-11 11:48:03 +0000
commit7c2a8e13d969029fb675e67c57349c1deaa09284 (patch)
treeb5ac48d0272cccf258c22f658f9589bcf0f6cc1c /os/hal/platforms/STM32
parent8cbeb405b96f12df958a75bcbc1af072ceb0e26e (diff)
downloadChibiOS-7c2a8e13d969029fb675e67c57349c1deaa09284.tar.gz
ChibiOS-7c2a8e13d969029fb675e67c57349c1deaa09284.tar.bz2
ChibiOS-7c2a8e13d969029fb675e67c57349c1deaa09284.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2246 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/platforms/STM32')
-rw-r--r--os/hal/platforms/STM32/spi_lld.c83
-rw-r--r--os/hal/platforms/STM32/spi_lld.h77
-rw-r--r--os/hal/platforms/STM32/uart_lld.h84
3 files changed, 172 insertions, 72 deletions
diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c
index c12b410c8..bb69f8c5f 100644
--- a/os/hal/platforms/STM32/spi_lld.c
+++ b/os/hal/platforms/STM32/spi_lld.c
@@ -57,30 +57,43 @@ SPIDriver SPID3;
/* Driver local functions. */
/*===========================================================================*/
-static void spi_stop(SPIDriver *spip) {
-
- /* Stops RX and TX DMA channels.*/
- dmaChannelDisable(spip->spd_dmarx);
- dmaChannelDisable(spip->spd_dmatx);
+/**
+ * @brief Stops the SPI DMA channels.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ */
+#define dma_stop(spip) { \
+ dmaChannelDisable(spip->spd_dmatx); \
+ dmaChannelDisable(spip->spd_dmarx); \
+}
- chSysLockFromIsr();
- chSchReadyI(spip->spd_thread);
- chSysUnlockFromIsr();
+/**
+ * @brief Starts the SPI DMA channels.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ */
+#define dma_start(spip) { \
+ dmaChannelEnable((spip)->spd_dmarx); \
+ dmaChannelEnable((spip)->spd_dmatx); \
}
-static void spi_start_wait(SPIDriver *spip) {
+/**
+ * @brief Shared end-of-transfer service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ */
+static void serve_interrupt(SPIDriver *spip) {
- chSysLock();
+ /* Stops everything.*/
+ dma_stop(spip);
- /* DMAs start.*/
- dmaChannelEnable(spip->spd_dmarx);
- dmaChannelEnable(spip->spd_dmatx);
+ /* If a callback is defined then invokes it.*/
+ if (spip->spd_config->spc_endcb)
+ spip->spd_config->spc_endcb(spip);
- /* Wait for completion event.*/
- spip->spd_thread = currp;
- chSchGoSleepS(THD_STATE_SUSPENDED);
- spip->spd_thread = NULL;
- chSysUnlock();
+ /* Wakeup the waiting thread if any, note that the following macro is
+ empty if the SPI_USE_WAIT option is disabled.*/
+ _spi_wakeup(spip);
}
/*===========================================================================*/
@@ -97,10 +110,10 @@ CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
CH_IRQ_PROLOGUE();
- spi_stop(&SPID1);
if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
STM32_SPI_SPI1_DMA_ERROR_HOOK();
}
+ serve_interrupt(&SPID1);
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
CH_IRQ_EPILOGUE();
@@ -132,10 +145,10 @@ CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
CH_IRQ_PROLOGUE();
- spi_stop(&SPID2);
if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
STM32_SPI_SPI2_DMA_ERROR_HOOK();
}
+ serve_interrupt(&SPID2);
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
CH_IRQ_EPILOGUE();
@@ -167,10 +180,10 @@ CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
CH_IRQ_PROLOGUE();
- spi_stop(&SPID3);
if ((STM32_DMA2->ISR & DMA_ISR_TEIF1) != 0) {
STM32_SPI_SPI3_DMA_ERROR_HOOK();
}
+ serve_interrupt(&SPID3);
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
CH_IRQ_EPILOGUE();
@@ -365,9 +378,9 @@ void spi_lld_unselect(SPIDriver *spip) {
/**
* @brief Ignores data on the SPI bus.
- * @details This function transmits a series of idle words on the SPI bus and
- * ignores the received data. This function can be invoked even
- * when a slave select signal has not been yet asserted.
+ * @details This asynchronous function starts the transmission of a series of
+ * idle words on the SPI bus and ignores the received data.
+ * @post At the end of the operation the configured callback is invoked.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
@@ -382,14 +395,16 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) {
spip->spd_dmaccr | DMA_CCR1_TCIE);
dmaChannelSetup(spip->spd_dmatx, n, &dummytx,
spip->spd_dmaccr | DMA_CCR1_DIR);
- spi_start_wait(spip);
+ dma_start(spip);
}
/**
* @brief Exchanges data on the SPI bus.
- * @details This function performs a simultaneous transmit/receive operation.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
+ * @details This asynchronous function starts a simultaneous transmit/receive
+ * operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be exchanged
@@ -405,11 +420,13 @@ void spi_lld_exchange(SPIDriver *spip, size_t n,
spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC);
dmaChannelSetup(spip->spd_dmatx, n, txbuf,
spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC);
- spi_start_wait(spip);
+ dma_start(spip);
}
/**
- * @brief Sends data ever the SPI bus.
+ * @brief Sends data over the SPI bus.
+ * @details This asynchronous function starts a transmit operation.
+ * @post At the end of the operation the configured callback is invoked.
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -426,11 +443,13 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
spip->spd_dmaccr | DMA_CCR1_TCIE);
dmaChannelSetup(spip->spd_dmatx, n, txbuf,
spip->spd_dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC);
- spi_start_wait(spip);
+ dma_start(spip);
}
/**
* @brief Receives data from the SPI bus.
+ * @details This asynchronous function starts a receive operation.
+ * @post At the end of the operation the configured callback is invoked.
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -447,7 +466,7 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
spip->spd_dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC);
dmaChannelSetup(spip->spd_dmatx, n, &dummytx,
spip->spd_dmaccr | DMA_CCR1_DIR);
- spi_start_wait(spip);
+ dma_start(spip);
}
#endif /* CH_HAL_USE_SPI */
diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h
index 4989712a9..fcca37c27 100644
--- a/os/hal/platforms/STM32/spi_lld.h
+++ b/os/hal/platforms/STM32/spi_lld.h
@@ -161,45 +161,90 @@
/*===========================================================================*/
/**
- * @brief Driver configuration structure.
+ * @brief Type of a structure representing an SPI driver.
+ */
+typedef struct SPIDriver SPIDriver;
+
+/**
+ * @brief SPI notification callback type.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object triggering the
+ * callback
+ */
+typedef void (*spicallback_t)(SPIDriver *spip);
+
+/**
+ * @brief Driver configuration structure.
*/
typedef struct {
- /** @brief The chip select line port.*/
+ /**
+ * @brief Operation complete callback.
+ */
+ spicallback_t spc_endcb;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief The chip select line port.
+ */
ioportid_t spc_ssport;
- /** @brief The chip select line pad number.*/
+ /**
+ * @brief The chip select line pad number.
+ */
uint16_t spc_sspad;
- /** @brief SPI initialization data.*/
+ /**
+ * @brief SPI initialization data.
+ */
uint16_t spc_cr1;
} SPIConfig;
/**
- * @brief Structure representing a SPI driver.
+ * @brief Structure representing a SPI driver.
*/
-typedef struct {
- /** @brief Driver state.*/
+struct SPIDriver{
+ /**
+ * @brief Driver state.
+ */
spistate_t spd_state;
+#if SPI_USE_WAIT || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ Thread *spd_thread;
+#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
- /** @brief Mutex protecting the bus.*/
+ /**
+ * @brief Mutex protecting the bus.
+ */
Mutex spd_mutex;
#elif CH_USE_SEMAPHORES
Semaphore spd_semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
- /** @brief Current configuration data.*/
+ /**
+ * @brief Current configuration data.
+ */
const SPIConfig *spd_config;
+#if defined(SPI_DRIVER_EXT_FIELDS)
+ SPI_DRIVER_EXT_FIELDS
+#endif
/* End of the mandatory fields.*/
- /** @brief Thread waiting for I/O completion.*/
- Thread *spd_thread;
- /** @brief Pointer to the SPIx registers block.*/
+ /**
+ * @brief Pointer to the SPIx registers block.
+ */
SPI_TypeDef *spd_spi;
- /** @brief Pointer to the receive DMA channel registers block.*/
+ /**
+ * @brief Pointer to the receive DMA channel registers block.
+ */
stm32_dma_channel_t *spd_dmarx;
- /** @brief Pointer to the transmit DMA channel registers block.*/
+ /**
+ * @brief Pointer to the transmit DMA channel registers block.
+ */
stm32_dma_channel_t *spd_dmatx;
- /** @brief DMA priority bit mask.*/
+ /**
+ * @brief DMA priority bit mask.\
+ */
uint32_t spd_dmaccr;
-} SPIDriver;
+};
/*===========================================================================*/
/* Driver macros. */
diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h
index 7cac040ce..7af1cc32c 100644
--- a/os/hal/platforms/STM32/uart_lld.h
+++ b/os/hal/platforms/STM32/uart_lld.h
@@ -198,24 +198,42 @@ typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
* @note It could be empty on some architectures.
*/
typedef struct {
- /** @brief End of transmission buffer callback.*/
+ /**
+ * @brief End of transmission buffer callback.
+ */
uartcb_t uc_txend1;
- /** @brief Physical end of transmission callback.*/
+ /**
+ * @brief Physical end of transmission callback.
+ */
uartcb_t uc_txend2;
- /** @brief Receive buffer filled callback.*/
+ /**
+ * @brief Receive buffer filled callback.
+ */
uartcb_t uc_rxend;
- /** @brief Character received while out if the @p UART_RECEIVE state.*/
- uartccb_t uc_rxchar;
- /** @brief Receive error callback.*/
- uartecb_t uc_rxerr;
+ /**
+ * @brief Character received while out if the @p UART_RECEIVE state.
+ */
+ uartcb_t uc_rxchar;
+ /**
+ * @brief Receive error callback.
+ */
+ uartcb_t uc_rxerr;
/* End of the mandatory fields.*/
- /** @brief Bit rate.*/
+ /**
+ * @brief Bit rate.
+ */
uint32_t uc_speed;
- /** @brief Initialization value for the CR1 register.*/
+ /**
+ * @brief Initialization value for the CR1 register.
+ */
uint16_t uc_cr1;
- /** @brief Initialization value for the CR2 register.*/
+ /**
+ * @brief Initialization value for the CR2 register.
+ */
uint16_t uc_cr2;
- /** @brief Initialization value for the CR3 register.*/
+ /**
+ * @brief Initialization value for the CR3 register.
+ */
uint16_t uc_cr3;
} UARTConfig;
@@ -223,31 +241,49 @@ typedef struct {
* @brief Structure representing an UART driver.
*/
struct UARTDriver {
- /** @brief Driver state.*/
+ /**
+ * @brief Driver state.
+ */
uartstate_t ud_state;
- /** @brief Current configuration data.*/
- const UARTConfig *ud_config;
- /** @brief Transmitter state.*/
+ /**
+ * @brief Transmitter state.
+ */
uarttxstate_t ud_txstate;
- /** @brief Receiver state.*/
+ /**
+ * @brief Receiver state.
+ */
uartrxstate_t ud_rxstate;
- /** @brief UART driver status flags.*/
- uartflags_t ud_flags;
+ /**
+ * @brief Current configuration data.
+ */
+ const UARTConfig *ud_config;
#if defined(UART_DRIVER_EXT_FIELDS)
UART_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
- /** @brief Pointer to the USART registers block.*/
+ /**
+ * @brief Pointer to the USART registers block.
+ */
USART_TypeDef *ud_usart;
- /** @brief Pointer to the DMA registers block.*/
+ /**
+ * @brief Pointer to the DMA registers block.
+ */
stm32_dma_t *ud_dmap;
- /** @brief DMA priority bit mask.*/
+ /**
+ * @brief DMA priority bit mask.
+ */
uint32_t ud_dmaccr;
- /** @brief Receive DMA channel.*/
+ /**
+ * @brief Receive DMA channel.
+ */
uint8_t ud_dmarx;
- /** @brief Transmit DMA channel.*/
+ /**
+ * @brief Transmit DMA channel.
+ */
uint8_t ud_dmatx;
- /** @brief Default receive buffer while into @p UART_RX_IDLE state.*/
+ /**
+ * @brief Default receive buffer while into @p UART_RX_IDLE state.
+ */
volatile uint16_t ud_rxbuf;
};