From 79b97b0f60aa6d99667a6bb4d402c420cb6d856e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 27 Jul 2010 10:31:19 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2094 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/uart.h | 19 --------- os/hal/platforms/STM32/adc_lld.c | 17 ++++---- os/hal/platforms/STM32/adc_lld.h | 55 +++++++++++------------- os/hal/platforms/STM32/can_lld.h | 79 +++++++++++++++++----------------- os/hal/platforms/STM32/pwm_lld.h | 55 ++++++++++++------------ os/hal/platforms/STM32/stm32_dma.h | 29 +++++++++++-- os/hal/platforms/STM32/uart_lld.c | 86 +++++++++++++++++++++++++++++++------- os/hal/platforms/STM32/uart_lld.h | 23 +++++++++- 8 files changed, 219 insertions(+), 144 deletions(-) (limited to 'os') diff --git a/os/hal/include/uart.h b/os/hal/include/uart.h index 245bd1939..c0ee4c9ef 100644 --- a/os/hal/include/uart.h +++ b/os/hal/include/uart.h @@ -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. */ diff --git a/os/hal/platforms/STM32/adc_lld.c b/os/hal/platforms/STM32/adc_lld.c index 82b70bd12..203eff7d4 100644 --- a/os/hal/platforms/STM32/adc_lld.c +++ b/os/hal/platforms/STM32/adc_lld.c @@ -18,8 +18,9 @@ */ /** - * @file STM32/adc_lld.c - * @brief STM32 ADC subsystem low level driver source. + * @file STM32/adc_lld.c + * @brief STM32 ADC subsystem low level driver source. + * * @addtogroup STM32_ADC * @{ */ @@ -52,7 +53,7 @@ ADCDriver ADCD1; #if USE_STM32_ADC1 || defined(__DOXYGEN__) /** - * @brief ADC1 DMA interrupt handler (channel 1). + * @brief ADC1 DMA interrupt handler (channel 1). */ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { uint32_t isr; @@ -107,7 +108,7 @@ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { /*===========================================================================*/ /** - * @brief Low level ADC driver initialization. + * @brief Low level ADC driver initialization. */ void adc_lld_init(void) { @@ -144,7 +145,7 @@ void adc_lld_init(void) { } /** - * @brief Configures and activates the ADC peripheral. + * @brief Configures and activates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object */ @@ -170,7 +171,7 @@ void adc_lld_start(ADCDriver *adcp) { } /** - * @brief Deactivates the ADC peripheral. + * @brief Deactivates the ADC peripheral. * * @param[in] adcp pointer to the @p ADCDriver object */ @@ -191,7 +192,7 @@ void adc_lld_stop(ADCDriver *adcp) { } /** - * @brief Starts an ADC conversion. + * @brief Starts an ADC conversion. * * @param[in] adcp pointer to the @p ADCDriver object */ @@ -230,7 +231,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { } /** - * @brief Stops an ongoing conversion. + * @brief Stops an ongoing conversion. * * @param[in] adcp pointer to the @p ADCDriver object */ diff --git a/os/hal/platforms/STM32/adc_lld.h b/os/hal/platforms/STM32/adc_lld.h index 2b9ac2dd7..599acf69c 100644 --- a/os/hal/platforms/STM32/adc_lld.h +++ b/os/hal/platforms/STM32/adc_lld.h @@ -18,8 +18,9 @@ */ /** - * @file STM32/adc_lld.h - * @brief STM32 ADC subsystem low level driver header. + * @file STM32/adc_lld.h + * @brief STM32 ADC subsystem low level driver header. + * * @addtogroup STM32_ADC * @{ */ @@ -60,32 +61,32 @@ /*===========================================================================*/ /** - * @brief ADC1 driver enable switch. + * @brief ADC1 driver enable switch. * @details If set to @p TRUE the support for ADC1 is included. - * @note The default is @p TRUE. + * @note The default is @p TRUE. */ #if !defined(USE_STM32_ADC1) || defined(__DOXYGEN__) #define USE_STM32_ADC1 TRUE #endif /** - * @brief ADC1 DMA priority (0..3|lowest..highest). + * @brief ADC1 DMA priority (0..3|lowest..highest). */ #if !defined(STM32_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__) #define STM32_ADC1_DMA_PRIORITY 3 #endif /** - * @brief ADC1 interrupt priority level setting. + * @brief ADC1 interrupt priority level setting. */ #if !defined(STM32_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_ADC1_IRQ_PRIORITY 5 #endif /** - * @brief ADC1 DMA error hook. - * @note The default action for DMA errors is a system halt because DMA error - * can only happen because programming errors. + * @brief ADC1 DMA error hook. + * @note The default action for DMA errors is a system halt because DMA error + * can only happen because programming errors. */ #if !defined(STM32_ADC1_DMA_ERROR_HOOK) || defined(__DOXYGEN__) #define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt() @@ -100,24 +101,25 @@ /*===========================================================================*/ /** - * @brief ADC sample data type. + * @brief ADC sample data type. */ typedef uint16_t adcsample_t; /** - * @brief Channels number in a conversion group. + * @brief Channels number in a conversion group. */ 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 + * @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 */ typedef void (*adccallback_t)(adcsample_t *buffer, size_t n); /** - * @brief Conversion group configuration structure. + * @brief Conversion group configuration structure. * @details This implementation-dependent structure describes a conversion * operation. */ @@ -133,15 +135,15 @@ typedef struct { /* End of the mandatory fields.*/ /** * @brief ADC CR1 register initialization data. - * @note All the required bits must be defined into this field except - * @p ADC_CR1_SCAN that is enforced inside the driver. + * @note All the required bits must be defined into this field except + * @p ADC_CR1_SCAN that is enforced inside the driver. */ uint32_t acg_cr1; /** * @brief ADC CR2 register initialization data. - * @note All the required bits must be defined into this field except - * @p ADC_CR2_DMA and @p ADC_CR2_ADON that are enforced inside the - * driver. + * @note All the required bits must be defined into this field except + * @p ADC_CR2_DMA and @p ADC_CR2_ADON that are enforced inside the + * driver. */ uint32_t acg_cr2; /** @@ -167,21 +169,14 @@ typedef struct { } ADCConversionGroup; /** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. + * @brief Driver configuration structure. + * @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; /** - * @brief Structure representing an ADC driver. + * @brief Structure representing an ADC driver. */ typedef struct { /** diff --git a/os/hal/platforms/STM32/can_lld.h b/os/hal/platforms/STM32/can_lld.h index 85d86b0cb..fd4784fc7 100644 --- a/os/hal/platforms/STM32/can_lld.h +++ b/os/hal/platforms/STM32/can_lld.h @@ -18,8 +18,9 @@ */ /** - * @file STM32/can_lld.h - * @brief STM32 CAN subsystem low level driver header. + * @file STM32/can_lld.h + * @brief STM32 CAN subsystem low level driver header. + * * @addtogroup STM32_CAN * @{ */ @@ -43,13 +44,13 @@ #undef CAN_BTR_SJW /** - * @brief This switch defines whether the driver implementation supports - * a low power switch mode with automatic an wakeup feature. + * @brief This switch defines whether the driver implementation supports + * a low power switch mode with automatic an wakeup feature. */ #define CAN_SUPPORTS_SLEEP TRUE /** - * @brief Minimum number of CAN filters. + * @brief Minimum number of CAN filters. */ #if defined(STM32F10X_CL) || defined(__DOXYGEN__) #define CAN_MAX_FILTERS 28 @@ -73,16 +74,16 @@ /*===========================================================================*/ /** - * @brief CAN1 driver enable switch. + * @brief CAN1 driver enable switch. * @details If set to @p TRUE the support for ADC1 is included. - * @note The default is @p TRUE. + * @note The default is @p TRUE. */ #if !defined(USE_STM32_CAN1) || defined(__DOXYGEN__) #define USE_STM32_CAN1 TRUE #endif /** - * @brief CAN1 interrupt priority level setting. + * @brief CAN1 interrupt priority level setting. */ #if !defined(STM32_CAN1_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_CAN1_IRQ_PRIORITY 11 @@ -101,14 +102,14 @@ /*===========================================================================*/ /** - * @brief CAN status flags. + * @brief CAN status flags. */ typedef uint32_t canstatus_t; /** - * @brief CAN transmission frame. - * @note Accessing the frame data as word16 or word32 is not portable because - * machine data endianness, it can be still useful for a quick filling. + * @brief CAN transmission frame. + * @note Accessing the frame data as word16 or word32 is not portable because + * machine data endianness, it can be still useful for a quick filling. */ typedef struct { struct { @@ -132,9 +133,9 @@ typedef struct { } CANTxFrame; /** - * @brief CAN received frame. - * @note Accessing the frame data as word16 or word32 is not portable because - * machine data endianness, it can be still useful for a quick filling. + * @brief CAN received frame. + * @note Accessing the frame data as word16 or word32 is not portable because + * machine data endianness, it can be still useful for a quick filling. */ typedef struct { struct { @@ -162,26 +163,26 @@ typedef struct { } CANRxFrame; /** - * @brief CAN filter. - * @note Refer to the STM32 reference manual for info about filters. + * @brief CAN filter. + * @note Refer to the STM32 reference manual for info about filters. */ typedef struct { /** * @brief Filter mode. - * @note This bit represent the CAN_FM1R register bit associated to this - * filter (0=mask mode, 1=list mode). + * @note This bit represent the CAN_FM1R register bit associated to this + * filter (0=mask mode, 1=list mode). */ uint32_t cf_mode:1; /** * @brief Filter sclae. - * @note This bit represent the CAN_FS1R register bit associated to this - * filter (0=16 bits mode, 1=32 bits mode). + * @note This bit represent the CAN_FS1R register bit associated to this + * filter (0=16 bits mode, 1=32 bits mode). */ uint32_t cf_scale:1; /** * @brief Filter mode. - * @note This bit represent the CAN_FFA1R register bit associated to this - * filter, must be set to zero in this version of the driver. + * @note This bit represent the CAN_FFA1R register bit associated to this + * filter, must be set to zero in this version of the driver. */ uint32_t cf_assignment:1; /** @@ -195,37 +196,37 @@ typedef struct { } CANFilter; /** - * @brief Driver configuration structure. + * @brief Driver configuration structure. */ typedef struct { /** * @brief CAN MCR register initialization data. - * @note Some bits in this register are enforced by the driver regardless - * their status in this field. + * @note Some bits in this register are enforced by the driver regardless + * their status in this field. */ uint32_t cc_mcr; /** * @brief CAN BTR register initialization data. - * @note Some bits in this register are enforced by the driver regardless - * their status in this field. + * @note Some bits in this register are enforced by the driver regardless + * their status in this field. */ uint32_t cc_btr; /** * @brief Number of elements into the filters array. - * @note By setting this field to zero a default filter is enabled that - * allows all frames, this should be adequate for simple applications. + * @note By setting this field to zero a default filter is enabled that + * allows all frames, this should be adequate for simple applications. */ uint32_t cc_num; /** * @brief Pointer to an array of @p CANFilter structures. - * @note This field can be set to @p NULL if the field @p cc_num is set to - * zero. + * @note This field can be set to @p NULL if the field @p cc_num is set to + * zero. */ const CANFilter *cc_filters; } CANConfig; /** - * @brief Structure representing an CAN driver. + * @brief Structure representing an CAN driver. */ typedef struct { /** @@ -246,12 +247,12 @@ typedef struct { Semaphore cd_rxsem; /** * @brief One or more frames become available. - * @note After broadcasting this event it will not be broadcasted again - * until the received frames queue has been completely emptied. It - * is not broadcasted for each received frame. It is - * responsibility of the application to empty the queue by repeatedly - * invoking @p chReceive() when listening to this event. This behavior - * minimizes the interrupt served by the system because CAN traffic. + * @note After broadcasting this event it will not be broadcasted again + * until the received frames queue has been completely emptied. It + * is not broadcasted for each received frame. It is + * responsibility of the application to empty the queue by repeatedly + * invoking @p chReceive() when listening to this event. This behavior + * minimizes the interrupt served by the system because CAN traffic. */ EventSource cd_rxfull_event; /** diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h index 4249a8514..8605bb314 100644 --- a/os/hal/platforms/STM32/pwm_lld.h +++ b/os/hal/platforms/STM32/pwm_lld.h @@ -18,8 +18,9 @@ */ /** - * @file STM32/pwm_lld.h - * @brief STM32 PWM subsystem low level driver header. + * @file STM32/pwm_lld.h + * @brief STM32 PWM subsystem low level driver header. + * * @addtogroup STM32_PWM * @{ */ @@ -34,7 +35,7 @@ /*===========================================================================*/ /** - * @brief Number of PWM channels per PWM driver. + * @brief Number of PWM channels per PWM driver. */ #define PWM_CHANNELS 4 @@ -43,64 +44,64 @@ /*===========================================================================*/ /** - * @brief PWM1 driver enable switch. + * @brief PWM1 driver enable switch. * @details If set to @p TRUE the support for PWM1 is included. - * @note The default is @p TRUE. + * @note The default is @p TRUE. */ #if !defined(USE_STM32_PWM1) || defined(__DOXYGEN__) #define USE_STM32_PWM1 TRUE #endif /** - * @brief PWM2 driver enable switch. + * @brief PWM2 driver enable switch. * @details If set to @p TRUE the support for PWM2 is included. - * @note The default is @p TRUE. + * @note The default is @p TRUE. */ #if !defined(USE_STM32_PWM2) || defined(__DOXYGEN__) #define USE_STM32_PWM2 TRUE #endif /** - * @brief PWM3 driver enable switch. + * @brief PWM3 driver enable switch. * @details If set to @p TRUE the support for PWM3 is included. - * @note The default is @p TRUE. + * @note The default is @p TRUE. */ #if !defined(USE_STM32_PWM3) || defined(__DOXYGEN__) #define USE_STM32_PWM3 TRUE #endif /** - * @brief PWM4 driver enable switch. + * @brief PWM4 driver enable switch. * @details If set to @p TRUE the support for PWM4 is included. - * @note The default is @p TRUE. + * @note The default is @p TRUE. */ #if !defined(USE_STM32_PWM4) || defined(__DOXYGEN__) #define USE_STM32_PWM4 TRUE #endif /** - * @brief PWM1 interrupt priority level setting. + * @brief PWM1 interrupt priority level setting. */ #if !defined(STM32_PWM1_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_PWM1_IRQ_PRIORITY 7 #endif /** - * @brief PWM2 interrupt priority level setting. + * @brief PWM2 interrupt priority level setting. */ #if !defined(STM32_PWM2_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_PWM2_IRQ_PRIORITY 7 #endif /** - * @brief PWM3 interrupt priority level setting. + * @brief PWM3 interrupt priority level setting. */ #if !defined(STM32_PWM3_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_PWM3_IRQ_PRIORITY 7 #endif /** - * @brief PWM4 interrupt priority level setting. + * @brief PWM4 interrupt priority level setting. */ #if !defined(STM32_PWM4_IRQ_PRIORITY) || defined(__DOXYGEN__) #define STM32_PWM4_IRQ_PRIORITY 7 @@ -119,18 +120,18 @@ /*===========================================================================*/ /** - * @brief PWM channel type. + * @brief PWM channel type. */ typedef uint8_t pwmchannel_t; /** - * @brief PWM counter type. + * @brief PWM counter type. */ typedef uint16_t pwmcnt_t; /** - * @brief PWM driver channel configuration structure. - * @note It could be empty on some architectures. + * @brief PWM driver channel configuration structure. + * @note It could be empty on some architectures. */ typedef struct { /** @@ -139,22 +140,22 @@ typedef struct { pwmmode_t pcc_mode; /** * @brief Channel callback pointer. - * @details This callback is invoked on the channel compare event. If set to - * @p NULL then the callback is disabled. + * @note This callback is invoked on the channel compare event. If set to + * @p NULL then the callback is disabled. */ pwmcallback_t pcc_callback; /* End of the mandatory fields.*/ } PWMChannelConfig; /** - * @brief PWM driver configuration structure. - * @note It could be empty on some architectures. + * @brief PWM driver configuration structure. + * @note It could be empty on some architectures. */ typedef struct { /** * @brief Periodic callback pointer. - * @details This callback is invoked on PWM counter reset. If set to - * @p NULL then the callback is disabled. + * @note This callback is invoked on PWM counter reset. If set to + * @p NULL then the callback is disabled. */ pwmcallback_t pc_callback; /** @@ -172,13 +173,13 @@ typedef struct { uint16_t pc_arr; /** * @brief TIM CR2 register initialization data. - * @note The value of this field should normally be equal to zero. + * @note The value of this field should normally be equal to zero. */ uint16_t pc_cr2; } PWMConfig; /** - * @brief Structure representing a PWM driver. + * @brief Structure representing a PWM driver. */ typedef struct { /** diff --git a/os/hal/platforms/STM32/stm32_dma.h b/os/hal/platforms/STM32/stm32_dma.h index dba85711e..94e863d31 100644 --- a/os/hal/platforms/STM32/stm32_dma.h +++ b/os/hal/platforms/STM32/stm32_dma.h @@ -131,7 +131,13 @@ typedef struct { * value does not change frequently, it usually points to a peripheral * data register. * @note Channels are numbered from 0 to 6, use the appropriate macro - * as parameter. + * 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); \ } /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c index 73088a454..56930a686 100644 --- a/os/hal/platforms/STM32/uart_lld.c +++ b/os/hal/platforms/STM32/uart_lld.c @@ -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); } diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h index 29cdda1ed..2977e15c5 100644 --- a/os/hal/platforms/STM32/uart_lld.h +++ b/os/hal/platforms/STM32/uart_lld.h @@ -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; -- cgit v1.2.3