diff options
Diffstat (limited to 'os')
| -rw-r--r-- | os/hal/platforms/STM32/USARTv1/uart_lld.c | 179 | ||||
| -rw-r--r-- | os/hal/platforms/STM32/USARTv1/uart_lld.h | 163 | 
2 files changed, 338 insertions, 4 deletions
diff --git a/os/hal/platforms/STM32/USARTv1/uart_lld.c b/os/hal/platforms/STM32/USARTv1/uart_lld.c index c1e624918..b965655aa 100644 --- a/os/hal/platforms/STM32/USARTv1/uart_lld.c +++ b/os/hal/platforms/STM32/USARTv1/uart_lld.c @@ -55,6 +55,22 @@    STM32_DMA_GETCHANNEL(STM32_UART_USART3_TX_DMA_STREAM,                     \
                         STM32_USART3_TX_DMA_CHN)
 +#define UART4_RX_DMA_CHANNEL                                                \
 +  STM32_DMA_GETCHANNEL(STM32_UART_UART4_RX_DMA_STREAM,                      \
 +                       STM32_UART4_RX_DMA_CHN)
 +
 +#define USART4_TX_DMA_CHANNEL                                               \
 +  STM32_DMA_GETCHANNEL(STM32_UART_USART4_TX_DMA_STREAM,                     \
 +                       STM32_UART4_TX_DMA_CHN)
 +
 +#define UART5_RX_DMA_CHANNEL                                                \
 +  STM32_DMA_GETCHANNEL(STM32_UART_UART5_RX_DMA_STREAM,                      \
 +                       STM32_UART5_RX_DMA_CHN)
 +
 +#define USART5_TX_DMA_CHANNEL                                               \
 +  STM32_DMA_GETCHANNEL(STM32_UART_USART5_TX_DMA_STREAM,                     \
 +                       STM32_UART5_TX_DMA_CHN)
 +
  #define USART6_RX_DMA_CHANNEL                                               \
    STM32_DMA_GETCHANNEL(STM32_UART_USART6_RX_DMA_STREAM,                     \
                         STM32_USART6_RX_DMA_CHN)
 @@ -63,6 +79,14 @@    STM32_DMA_GETCHANNEL(STM32_UART_USART6_TX_DMA_STREAM,                     \
                         STM32_USART6_TX_DMA_CHN)
 +#if (STM32_UART_USE_UART4 || STM32_UART_USE_UART5)
 +  #define STM32_UART45_CR2_CHECK_MASK (USART_CR2_STOP_0 | USART_CR2_CLKEN | \
 +                        USART_CR2_CPOL | USART_CR2_CPHA | USART_CR2_LBCL)
 +
 +  #define STM32_UART45_CR3_CHECK_MASK (USART_CR3_CTSIE | USART_CR3_CTSE |   \
 +                       USART_CR3_RTSE | USART_CR3_SCEN | USART_CR3_NACK)
 +#endif
 +
  /*===========================================================================*/
  /* Driver exported variables.                                                */
  /*===========================================================================*/
 @@ -82,6 +106,15 @@ UARTDriver UARTD2;  UARTDriver UARTD3;
  #endif
 +/** @brief UART4 UART driver identifier.*/
 +#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
 +UARTDriver UARTD4;
 +#endif
 +
 +/** @brief UART5 UART driver identifier.*/
 +#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
 +UARTDriver UARTD5;
 +#endif
  /** @brief USART6 UART driver identifier.*/
  #if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
 @@ -358,6 +391,44 @@ CH_IRQ_HANDLER(STM32_USART3_HANDLER) {  }
  #endif /* STM32_UART_USE_USART3 */
 +#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
 +#if !defined(STM32_UART4_HANDLER)
 +#error "STM32_USART4_HANDLER not defined"
 +#endif
 +/**
 + * @brief   UART4 IRQ handler.
 + *
 + * @isr
 + */
 +CH_IRQ_HANDLER(STM32_UART4_HANDLER) {
 +
 +  CH_IRQ_PROLOGUE();
 +
 +  serve_usart_irq(&UARTD4);
 +
 +  CH_IRQ_EPILOGUE();
 +}
 +#endif /* STM32_UART_USE_UART4 */
 +
 +#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
 +#if !defined(STM32_UART5_HANDLER)
 +#error "STM32_USART5_HANDLER not defined"
 +#endif
 +/**
 + * @brief   UART5 IRQ handler.
 + *
 + * @isr
 + */
 +CH_IRQ_HANDLER(STM32_UART5_HANDLER) {
 +
 +  CH_IRQ_PROLOGUE();
 +
 +  serve_usart_irq(&UARTD5);
 +
 +  CH_IRQ_EPILOGUE();
 +}
 +#endif /* STM32_UART_USE_UART5 */
 +
  #if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
  #if !defined(STM32_USART6_HANDLER)
  #error "STM32_USART6_HANDLER not defined"
 @@ -412,6 +483,22 @@ void uart_lld_init(void) {    UARTD3.dmatx   = STM32_DMA_STREAM(STM32_UART_USART3_TX_DMA_STREAM);
  #endif
 +#if STM32_UART_USE_UART4
 +  uartObjectInit(&UARTD4);
 +  UARTD4.usart   = UART4;
 +  UARTD4.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
 +  UARTD4.dmarx   = STM32_DMA_STREAM(STM32_UART_UART4_RX_DMA_STREAM);
 +  UARTD4.dmatx   = STM32_DMA_STREAM(STM32_UART_UART4_TX_DMA_STREAM);
 +#endif
 +
 +#if STM32_UART_USE_UART5
 +  uartObjectInit(&UARTD5);
 +  UARTD5.usart   = UART5;
 +  UARTD5.dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
 +  UARTD5.dmarx   = STM32_DMA_STREAM(STM32_UART_UART5_RX_DMA_STREAM);
 +  UARTD5.dmatx   = STM32_DMA_STREAM(STM32_UART_UART5_TX_DMA_STREAM);
 +#endif
 +
  #if STM32_UART_USE_USART6
    uartObjectInit(&UARTD6);
    UARTD6.usart   = USART6;
 @@ -421,6 +508,28 @@ void uart_lld_init(void) {  }
  /**
 + * @brief   Check CR2 and CR3 values for compatibility with UART4, UART5.
 + *
 + * @param[in] uartp     pointer to the @p UARTDriver object
 + *
 + * @notapi
 + */
 +#if (STM32_UART_USE_UART4 || STM32_UART_USE_UART5)
 +static void uart_check_config(const UARTDriver *uartp) {
 +
 +  uint16_t cr;
 +
 +  cr = uartp->config->cr2;
 +  chDbgCheck((cr & STM32_UART45_CR2_CHECK_MASK) == 0,
 +      "Some flags from CR2 unavailable for this UART");
 +
 +  cr = uartp->config->cr3;
 +  chDbgCheck((cr & STM32_UART45_CR3_CHECK_MASK) == 0,
 +      "Some flags from CR3 unavailable for this UART");
 +}
 +#endif /* (STM32_UART_USE_USART4 || STM32_UART_USE_USART5) */
 +
 +/**
   * @brief   Configures and activates the UART peripheral.
   *
   * @param[in] uartp     pointer to the @p UARTDriver object
 @@ -429,6 +538,14 @@ void uart_lld_init(void) {   */
  void uart_lld_start(UARTDriver *uartp) {
 +#if STM32_UART_USE_UART4
 +  if (uartp == &UARTD4)
 +    uart_check_config(uartp);
 +#elif STM32_UART_USE_UART5
 +  else if (uartp == &UARTD5)
 +    uart_check_config(uartp);
 +#endif
 +
    if (uartp->state == UART_STOP) {
  #if STM32_UART_USE_USART1
      if (&UARTD1 == uartp) {
 @@ -493,6 +610,48 @@ void uart_lld_start(UARTDriver *uartp) {      }
  #endif
 +#if STM32_UART_USE_UART4
 +    if (&UARTD4 == uartp) {
 +      bool_t b;
 +      b = dmaStreamAllocate(uartp->dmarx,
 +                            STM32_UART_UART4_IRQ_PRIORITY,
 +                            (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
 +                            (void *)uartp);
 +      chDbgAssert(!b, "uart_lld_start(), #7", "stream already allocated");
 +      b = dmaStreamAllocate(uartp->dmatx,
 +                            STM32_UART_UART4_IRQ_PRIORITY,
 +                            (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
 +                            (void *)uartp);
 +      chDbgAssert(!b, "uart_lld_start(), #8", "stream already allocated");
 +      rccEnableUART4(FALSE);
 +      nvicEnableVector(STM32_UART4_NUMBER,
 +                       CORTEX_PRIORITY_MASK(STM32_UART_UART4_IRQ_PRIORITY));
 +      uartp->dmamode |= STM32_DMA_CR_CHSEL(UART4_RX_DMA_CHANNEL) |
 +                        STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
 +    }
 +#endif
 +
 +#if STM32_UART_USE_UART5
 +    if (&UARTD5 == uartp) {
 +      bool_t b;
 +      b = dmaStreamAllocate(uartp->dmarx,
 +                            STM32_UART_UART5_IRQ_PRIORITY,
 +                            (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
 +                            (void *)uartp);
 +      chDbgAssert(!b, "uart_lld_start(), #9", "stream already allocated");
 +      b = dmaStreamAllocate(uartp->dmatx,
 +                            STM32_UART_UART5_IRQ_PRIORITY,
 +                            (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
 +                            (void *)uartp);
 +      chDbgAssert(!b, "uart_lld_start(), #10", "stream already allocated");
 +      rccEnableUART5(FALSE);
 +      nvicEnableVector(STM32_UART5_NUMBER,
 +                       CORTEX_PRIORITY_MASK(STM32_UART_UART5_IRQ_PRIORITY));
 +      uartp->dmamode |= STM32_DMA_CR_CHSEL(UART5_RX_DMA_CHANNEL) |
 +                        STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
 +    }
 +#endif
 +
  #if STM32_UART_USE_USART6
      if (&UARTD6 == uartp) {
        bool_t b;
 @@ -500,12 +659,12 @@ void uart_lld_start(UARTDriver *uartp) {                              STM32_UART_USART6_IRQ_PRIORITY,
                              (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
                              (void *)uartp);
 -      chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated");
 +      chDbgAssert(!b, "uart_lld_start(), #11", "stream already allocated");
        b = dmaStreamAllocate(uartp->dmatx,
                              STM32_UART_USART6_IRQ_PRIORITY,
                              (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
                              (void *)uartp);
 -      chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated");
 +      chDbgAssert(!b, "uart_lld_start(), #12", "stream already allocated");
        rccEnableUSART6(FALSE);
        nvicEnableVector(STM32_USART6_NUMBER,
                         CORTEX_PRIORITY_MASK(STM32_UART_USART6_IRQ_PRIORITY));
 @@ -566,6 +725,22 @@ void uart_lld_stop(UARTDriver *uartp) {      }
  #endif
 +#if STM32_UART_USE_UART4
 +    if (&UARTD4 == uartp) {
 +      nvicDisableVector(STM32_UART4_NUMBER);
 +      rccDisableUART4(FALSE);
 +      return;
 +    }
 +#endif
 +
 +#if STM32_UART_USE_UART5
 +    if (&UARTD5 == uartp) {
 +      nvicDisableVector(STM32_UART5_NUMBER);
 +      rccDisableUART5(FALSE);
 +      return;
 +    }
 +#endif
 +
  #if STM32_UART_USE_USART6
      if (&UARTD6 == uartp) {
        nvicDisableVector(STM32_USART6_NUMBER);
 diff --git a/os/hal/platforms/STM32/USARTv1/uart_lld.h b/os/hal/platforms/STM32/USARTv1/uart_lld.h index ffaed007e..ba8f00f1e 100644 --- a/os/hal/platforms/STM32/USARTv1/uart_lld.h +++ b/os/hal/platforms/STM32/USARTv1/uart_lld.h @@ -67,6 +67,24 @@  #endif
  /**
 + * @brief   UART driver on UART4 enable switch.
 + * @details If set to @p TRUE the support for UART4 is included.
 + * @note    The default is @p FALSE.
 + */
 +#if !defined(STM32_UART_USE_UART4) || defined(__DOXYGEN__)
 +#define STM32_UART_USE_UART4                FALSE
 +#endif
 +
 +/**
 + * @brief   UART driver on UART5 enable switch.
 + * @details If set to @p TRUE the support for UART5 is included.
 + * @note    The default is @p FALSE.
 + */
 +#if !defined(STM32_UART_USE_UART4) || defined(__DOXYGEN__)
 +#define STM32_UART_USE_UART5                FALSE
 +#endif
 +
 +/**
   * @brief   UART driver on USART6 enable switch.
   * @details If set to @p TRUE the support for USART6 is included.
   * @note    The default is @p FALSE.
 @@ -97,6 +115,20 @@  #endif
  /**
 + * @brief   UART4 interrupt priority level setting.
 + */
 +#if !defined(STM32_UART_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__)
 +#define STM32_UART_UART4_IRQ_PRIORITY       12
 +#endif
 +
 +/**
 + * @brief   UART5 interrupt priority level setting.
 + */
 +#if !defined(STM32_UART_UART5_IRQ_PRIORITY) || defined(__DOXYGEN__)
 +#define STM32_UART_UART5_IRQ_PRIORITY       12
 +#endif
 +
 +/**
   * @brief   USART6 interrupt priority level setting.
   */
  #if !defined(STM32_UART_USART6_IRQ_PRIORITY) || defined(__DOXYGEN__)
 @@ -134,6 +166,26 @@  #endif
  /**
 + * @brief   UART4 DMA priority (0..3|lowest..highest).
 + * @note    The priority level is used for both the TX and RX DMA channels but
 + *          because of the channels ordering the RX channel has always priority
 + *          over the TX channel.
 + */
 +#if !defined(STM32_UART_UART4_DMA_PRIORITY) || defined(__DOXYGEN__)
 +#define STM32_UART_UART4_DMA_PRIORITY       0
 +#endif
 +
 +/**
 + * @brief   UART5 DMA priority (0..3|lowest..highest).
 + * @note    The priority level is used for both the TX and RX DMA channels but
 + *          because of the channels ordering the RX channel has always priority
 + *          over the TX channel.
 + */
 +#if !defined(STM32_UART_UART5_DMA_PRIORITY) || defined(__DOXYGEN__)
 +#define STM32_UART_UART5_DMA_PRIORITY       0
 +#endif
 +
 +/**
   * @brief   USART6 DMA priority (0..3|lowest..highest).
   * @note    The priority level is used for both the TX and RX DMA channels but
   *          because of the channels ordering the RX channel has always priority
 @@ -144,7 +196,7 @@  #endif
  /**
 - * @brief   USART1 DMA error hook.
 + * @brief   USART DMA error hook.
   * @note    The default action for DMA errors is a system halt because DMA
   *          error can only happen because programming errors.
   */
 @@ -203,6 +255,38 @@  #endif
  /**
 + * @brief   DMA stream used for UART4 RX operations.
 + * @note    This option is only available on platforms with enhanced DMA.
 + */
 +#if !defined(STM32_UART_UART4_RX_DMA_STREAM) || defined(__DOXYGEN__)
 +#define STM32_UART_UART4_RX_DMA_STREAM     STM32_DMA_STREAM_ID(1, 2)
 +#endif
 +
 +/**
 + * @brief   DMA stream used for UART4 TX operations.
 + * @note    This option is only available on platforms with enhanced DMA.
 + */
 +#if !defined(STM32_UART_UART4_TX_DMA_STREAM) || defined(__DOXYGEN__)
 +#define STM32_UART_UART4_TX_DMA_STREAM     STM32_DMA_STREAM_ID(1, 4)
 +#endif
 +
 +/**
 + * @brief   DMA stream used for UART5 RX operations.
 + * @note    This option is only available on platforms with enhanced DMA.
 + */
 +#if !defined(STM32_UART_UART5_RX_DMA_STREAM) || defined(__DOXYGEN__)
 +#define STM32_UART_UART5_RX_DMA_STREAM     STM32_DMA_STREAM_ID(1, 0)
 +#endif
 +
 +/**
 + * @brief   DMA stream used for UART5 TX operations.
 + * @note    This option is only available on platforms with enhanced DMA.
 + */
 +#if !defined(STM32_UART_UART5_TX_DMA_STREAM) || defined(__DOXYGEN__)
 +#define STM32_UART_UART5_TX_DMA_STREAM     STM32_DMA_STREAM_ID(1, 7)
 +#endif
 +
 +/**
   * @brief   DMA stream used for USART6 RX operations.
   * @note    This option is only available on platforms with enhanced DMA.
   */
 @@ -228,6 +312,8 @@  #define STM32_UART_USART2_TX_DMA_STREAM     STM32_DMA_STREAM_ID(1, 7)
  #define STM32_UART_USART3_RX_DMA_STREAM     STM32_DMA_STREAM_ID(1, 3)
  #define STM32_UART_USART3_TX_DMA_STREAM     STM32_DMA_STREAM_ID(1, 2)
 +#define STM32_UART_UART4_RX_DMA_STREAM      STM32_DMA_STREAM_ID(2, 3)
 +#define STM32_UART_UART4_TX_DMA_STREAM      STM32_DMA_STREAM_ID(2, 5)
  #endif /* !STM32_ADVANCED_DMA*/
  /** @} */
 @@ -248,12 +334,33 @@  #error "USART3 not present in the selected device"
  #endif
 +#if STM32_UART_USE_UART4 
 +  #if !STM32_HAS_UART4
 +  #error "UART4 not present in the selected device"
 +  #endif
 +
 +  #if !defined(STM32F4XX) || !defined(STM32F4XX)
 +  #error "UART4 DMA access not supported in this platform"
 +  #endif
 +#endif
 +
 +#if STM32_UART_USE_UART5
 +  #if !STM32_HAS_UART5
 +  #error "UART5 not present in the selected device"
 +  #endif
 +
 +  #if !defined(STM32F4XX) || !defined(STM32F4XX)
 +  #error "UART5 DMA access not supported in this platform"
 +  #endif
 +#endif
 +
  #if STM32_UART_USE_USART6 && !STM32_HAS_USART6
  #error "USART6 not present in the selected device"
  #endif
  #if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 &&                     \
 -    !STM32_UART_USE_USART3 && !STM32_UART_USE_USART6
 +    !STM32_UART_USE_USART3 && !STM32_UART_USE_UART4 &&                      \
 +    !STM32_UART_USE_UART5  && !STM32_UART_USE_USART6
  #error "UART driver activated but no USART/UART peripheral assigned"
  #endif
 @@ -272,6 +379,16 @@  #error "Invalid IRQ priority assigned to USART3"
  #endif
 +#if STM32_UART_USE_UART4 &&                                                 \
 +    !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_UART_UART4_IRQ_PRIORITY)
 +#error "Invalid IRQ priority assigned to UART4"
 +#endif
 +
 +#if STM32_UART_USE_UART5 &&                                                 \
 +    !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_UART_UART5_IRQ_PRIORITY)
 +#error "Invalid IRQ priority assigned to UART5"
 +#endif
 +
  #if STM32_UART_USE_USART6 &&                                                \
      !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_UART_USART6_IRQ_PRIORITY)
  #error "Invalid IRQ priority assigned to USART6"
 @@ -292,6 +409,16 @@  #error "Invalid DMA priority assigned to USART3"
  #endif
 +#if STM32_UART_USE_UART4 &&                                                 \
 +    !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART4_DMA_PRIORITY)
 +#error "Invalid DMA priority assigned to UART4"
 +#endif
 +
 +#if STM32_UART_USE_UART5 &&                                                 \
 +    !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART5_DMA_PRIORITY)
 +#error "Invalid DMA priority assigned to UART5"
 +#endif
 +
  #if STM32_UART_USE_USART6 &&                                                \
      !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART6_DMA_PRIORITY)
  #error "Invalid DMA priority assigned to USART6"
 @@ -333,6 +460,30 @@  #error "invalid DMA stream associated to USART3 TX"
  #endif
 +#if STM32_UART_USE_UART4 &&                                                 \
 +    !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_RX_DMA_STREAM,                  \
 +                           STM32_UART4_RX_DMA_MSK)
 +#error "invalid DMA stream associated to UART4 RX"
 +#endif
 +
 +#if STM32_UART_USE_UART4 &&                                                 \
 +    !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_TX_DMA_STREAM,                  \
 +                           STM32_UART4_TX_DMA_MSK)
 +#error "invalid DMA stream associated to UART4 TX"
 +#endif
 +
 +#if STM32_UART_USE_UART5 &&                                                 \
 +    !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_RX_DMA_STREAM,                  \
 +                           STM32_UART5_RX_DMA_MSK)
 +#error "invalid DMA stream associated to UART5 RX"
 +#endif
 +
 +#if STM32_UART_USE_UART5 &&                                                 \
 +    !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_TX_DMA_STREAM,                  \
 +                           STM32_UART5_TX_DMA_MSK)
 +#error "invalid DMA stream associated to UART5 TX"
 +#endif
 +
  #if STM32_UART_USE_USART6 &&                                                \
      !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_RX_DMA_STREAM,                 \
                             STM32_USART6_RX_DMA_MSK)
 @@ -496,6 +647,14 @@ extern UARTDriver UARTD2;  extern UARTDriver UARTD3;
  #endif
 +#if STM32_UART_USE_UART4 && !defined(__DOXYGEN__)
 +extern UARTDriver UARTD4;
 +#endif
 +
 +#if STM32_UART_USE_UART5 && !defined(__DOXYGEN__)
 +extern UARTDriver UARTD5;
 +#endif
 +
  #if STM32_UART_USE_USART6 && !defined(__DOXYGEN__)
  extern UARTDriver UARTD6;
  #endif
  | 
