git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2094 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2010-07-27 10:31:19 +00:00
parent b91f48eb10
commit 79b97b0f60
8 changed files with 219 additions and 144 deletions

View File

@ -59,25 +59,6 @@
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Generic UART notification callback type.
*/
typedef void (*uartcb_t)(void);
/**
* @brief Character received UART notification callback type.
*
* @param[in] c received character
*/
typedef void (*uartccb_t)(uint16_t c);
/**
* @brief Receive error UART notification callback type.
*
* @param[in] e receive error mask
*/
typedef void (*uartecb_t)(uint16_t e);
/**
* @brief Driver state machine possible states.
*/

View File

@ -20,6 +20,7 @@
/**
* @file STM32/adc_lld.c
* @brief STM32 ADC subsystem low level driver source.
*
* @addtogroup STM32_ADC
* @{
*/

View File

@ -20,6 +20,7 @@
/**
* @file STM32/adc_lld.h
* @brief STM32 ADC subsystem low level driver header.
*
* @addtogroup STM32_ADC
* @{
*/
@ -111,6 +112,7 @@ typedef uint16_t adc_channels_num_t;
/**
* @brief ADC notification callback type.
*
* @param[in] buffer pointer to the most recent samples data
* @param[in] n number of buffer rows available starting from @p buffer
*/
@ -171,13 +173,6 @@ typedef struct {
* @note It could be empty on some architectures.
*/
typedef struct {
/* * <----------
* @brief ADC prescaler setting.
* @note This field can assume one of the following values:
* @p RCC_CFGR_ADCPRE_DIV2, @p RCC_CFGR_ADCPRE_DIV4,
* @p RCC_CFGR_ADCPRE_DIV6, @p RCC_CFGR_ADCPRE_DIV8.
*/
/* uint32_t ac_prescaler;*/
} ADCConfig;
/**

View File

@ -20,6 +20,7 @@
/**
* @file STM32/can_lld.h
* @brief STM32 CAN subsystem low level driver header.
*
* @addtogroup STM32_CAN
* @{
*/

View File

@ -20,6 +20,7 @@
/**
* @file STM32/pwm_lld.h
* @brief STM32 PWM subsystem low level driver header.
*
* @addtogroup STM32_PWM
* @{
*/
@ -139,7 +140,7 @@ typedef struct {
pwmmode_t pcc_mode;
/**
* @brief Channel callback pointer.
* @details This callback is invoked on the channel compare event. If set to
* @note This callback is invoked on the channel compare event. If set to
* @p NULL then the callback is disabled.
*/
pwmcallback_t pcc_callback;
@ -153,7 +154,7 @@ typedef struct {
typedef struct {
/**
* @brief Periodic callback pointer.
* @details This callback is invoked on PWM counter reset. If set to
* @note This callback is invoked on PWM counter reset. If set to
* @p NULL then the callback is disabled.
*/
pwmcallback_t pc_callback;

View File

@ -132,6 +132,12 @@ typedef struct {
* data register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
* @param[in] cntdr value to be written in the CNDTR register
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*/
#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \
stm32_dma_channel_t *dmachp = &dmap->channels[ch]; \
@ -142,11 +148,28 @@ typedef struct {
/**
* @brief DMA channel disable.
* @note Channel's pending interrupts are cleared.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*/
#define dmaDisableChannel(dmap, ch) { \
(dmap)->channels[ch].CCR = 0; \
(dmap)->IFCR = 0xF << (ch); \
}
/**
* @brief DMA channel interrupt sources clear.
* @details Sets the appropriate CGIF bit into the IFCR register in order to
* withdraw all the pending interrupt bits from the ISR register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*/
#define dmaClearChannel(dmap, ch){ \
(dmap)->IFCR = 1 << (ch); \
}
/*===========================================================================*/

View File

@ -47,6 +47,39 @@ UARTDriver UARTD1;
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Puts the receiver in the UART_RX_IDLE state.
*
* @param[in] uartp pointer to the @p UARTDriver object
*/
static void set_rx_idle(UARTDriver *uartp) {
uint32_t ccr;
dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmarx);
dmaClearChannel(uartp->ud_dmap, uartp->ud_dmarx);
uartp->ud_rxstate = UART_RX_IDLE;
/* RX DMA channel preparation, circular 1 frame transfers, an interrupt is
generated for each received character if the callback is defined.*/
ccr = DMA_CCR1_TEIE | DMA_CCR1_CIRC | DMA_CCR1_EN;
if (uartp->ud_config->uc_rxchar != NULL)
ccr |= DMA_CCR1_TCIE;
dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmarx, 1,
&uartp->ud_rxbuf, uartp->ud_dmaccr | ccr);
}
/**
* @brief Puts the transmitter in the UART_TX_IDLE state.
*
* @param[in] uartp pointer to the @p UARTDriver object
*/
static void set_tx_idle(UARTDriver *uartp) {
dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmatx);
dmaClearChannel(uartp->ud_dmap, uartp->ud_dmatx);
uartp->ud_txstate = UART_TX_IDLE;
}
/**
* @brief USART initialization.
* @details This function must be invoked with interrupts disabled.
@ -73,26 +106,23 @@ static void usart_start(UARTDriver *uartp) {
(void)u->SR; /* SR reset step 1.*/
(void)u->DR; /* SR reset step 2.*/
/* RX DMA channel preparation, circular 1 frame transfers, an interrupt is
generated for each received character.*/
dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmarx, 1, &uartp->ud_rxbuf,
DMA_CCR1_TCIE | DMA_CCR1_TEIE | DMA_CCR1_CIRC | DMA_CCR1_EN);
/* TX DMA channel preparation, simply disabled.*/
dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmatx);
set_rx_idle(uartp);
set_tx_idle(uartp);
}
/**
* @brief USART de-initialization.
* @details This function must be invoked with interrupts disabled.
*
* @param[in] u pointer to an USART I/O block
* @param[in] uartp pointer to the @p UARTDriver object
*/
static void usart_stop(UARTDriver *uartp) {
/* Stops RX and TX DMA channels.*/
dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmarx);
dmaDisableChannel(uartp->ud_dmap, uartp->ud_dmatx);
dmaClearChannel(uartp->ud_dmap, uartp->ud_dmarx);
dmaClearChannel(uartp->ud_dmap, uartp->ud_dmatx);
/* Stops USART operations.*/
uartp->ud_usart->CR1 = 0;
@ -109,11 +139,30 @@ static void usart_stop(UARTDriver *uartp) {
* @brief USART1 RX DMA interrupt handler (channel 4).
*/
CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
UARTDriver *uartp;
CH_IRQ_PROLOGUE();
DMA1->IFCR |= DMA_IFCR_CGIF4 | DMA_IFCR_CTCIF4 |
DMA_IFCR_CHTIF4 | DMA_IFCR_CTEIF4;
dmaClearChannel(&DMA1, STM32_DMA_CHANNEL_4);
uartp = &UARTD1;
if (uartp->ud_rxstate == UART_RX_IDLE) {
/* Receiver in idle state, a callback is generated, if enabled, for each
received character.*/
if (uartp->ud_config->uc_rxchar != NULL)
uartp->ud_config->uc_rxchar(uartp->ud_rxbuf);
}
else {
/* Receiver in active state, a callback is generated, if enabled, after
a completed transfer.*/
uartp->ud_rxstate = UART_RX_COMPLETE;
if (uartp->ud_config->uc_rxend != NULL)
uartp->ud_config->uc_rxend();
/* If the callback didn't restart a receive operation then the receiver
returns to the idle state.*/
if (uartp->ud_rxstate == UART_RX_COMPLETE)
set_rx_idle(uartp);
}
CH_IRQ_EPILOGUE();
}
@ -125,17 +174,24 @@ CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
CH_IRQ_PROLOGUE();
DMA1->IFCR |= DMA_IFCR_CGIF5 | DMA_IFCR_CTCIF5 |
DMA_IFCR_CHTIF5 | DMA_IFCR_CTEIF5;
dmaClearChannel(&DMA1, STM32_DMA_CHANNEL_5);
/* A callback is generated, if enabled, after a completed transfer.*/
uartp->ud_txstate = UART_TX_COMPLETE;
if (UARTD1.ud_config->uc_txend1 != NULL)
UARTD1.ud_config->uc_txend1();
/* If the callback didn't restart a transmit operation then the transmitter
returns to the idle state.*/
if (uartp->ud_txstate == UART_TX_COMPLETE)
set_tx_idle(uartp);
CH_IRQ_EPILOGUE();
}
CH_IRQ_HANDLER(USART2_IRQHandler) {
CH_IRQ_HANDLER(USART1_IRQHandler) {
CH_IRQ_PROLOGUE();
serve_interrupt(&SD2);
CH_IRQ_EPILOGUE();
}
@ -190,8 +246,6 @@ void uart_lld_start(UARTDriver *uartp) {
uartp->ud_dmap->channels[uartp->ud_dmarx].CPAR = (uint32_t)&uartp->ud_usart->DR;
uartp->ud_dmap->channels[uartp->ud_dmatx].CPAR = (uint32_t)&uartp->ud_usart->DR;
}
uartp->ud_txstate = UART_TX_IDLE;
uartp->ud_rxstate = UART_RX_IDLE;
usart_start(uartp);
}

View File

@ -77,6 +77,25 @@
*/
typedef uint32_t uartflags_t;
/**
* @brief Generic UART notification callback type.
*/
typedef void (*uartcb_t)(void);
/**
* @brief Character received UART notification callback type.
*
* @param[in] c received character
*/
typedef void (*uartccb_t)(uint16_t c);
/**
* @brief Receive error UART notification callback type.
*
* @param[in] e receive error mask
*/
typedef void (*uartecb_t)(uartflags_t e);
/**
* @brief Driver configuration structure.
* @note It could be empty on some architectures.
@ -89,9 +108,9 @@ typedef struct {
/** @brief Receive buffer filled callback.*/
uartcb_t uc_rxend;
/** @brief Character received while out if the @p UART_RECEIVE state.*/
uartcb_t uc_rxchar;
uartccb_t uc_rxchar;
/** @brief Receive error callback.*/
uartcb_t uc_rxerr;
uartecb_t uc_rxerr;
/* End of the mandatory fields.*/
/** @brief Bit rate.*/
uint32_t uc_speed;