diff options
Diffstat (limited to 'os/hal')
| -rw-r--r-- | os/hal/ports/KINETIS/LLD/hal_serial_lld.c | 251 | ||||
| -rw-r--r-- | os/hal/ports/KINETIS/LLD/hal_serial_lld.h | 69 | ||||
| -rw-r--r-- | os/hal/ports/KINETIS/LLD/hal_usb_lld.c | 57 | ||||
| -rw-r--r-- | os/hal/ports/KINETIS/LLD/hal_usb_lld.h | 23 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c | 5 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h | 5 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c | 5 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h | 5 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c | 5 | 
9 files changed, 332 insertions, 93 deletions
diff --git a/os/hal/ports/KINETIS/LLD/hal_serial_lld.c b/os/hal/ports/KINETIS/LLD/hal_serial_lld.c index c80cf22..c92fa5c 100644 --- a/os/hal/ports/KINETIS/LLD/hal_serial_lld.c +++ b/os/hal/ports/KINETIS/LLD/hal_serial_lld.c @@ -1,5 +1,6 @@  /*
      ChibiOS - Copyright (C) 2013-2015 Fabio Utzig
 +              Copyright (C) 2017 Wim Lewis
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
 @@ -50,6 +51,18 @@ SerialDriver SD2;  SerialDriver SD3;
  #endif
 +#if KINETIS_SERIAL_USE_UART3 || defined(__DOXYGEN__)
 +SerialDriver SD4;
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART4 || defined(__DOXYGEN__)
 +SerialDriver SD5;
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART5 || defined(__DOXYGEN__)
 +SerialDriver SD6;
 +#endif
 +
  /*===========================================================================*/
  /* Driver local variables and types.                                         */
  /*===========================================================================*/
 @@ -95,33 +108,37 @@ static void serve_error_interrupt(SerialDriver *sdp) {    UART_w_TypeDef *u = &(sdp->uart);
    uint8_t s1 = *(u->s1_p);
 -  /* S1 bits are write-1-to-clear for UART0 on KL2x. */
 -  /* Clearing on K20x and KL2x/UART>0 is done by reading S1 and
 +  /* Clearing on K20x, K60x, and KL2x/UART>0 is done by reading S1 and
     * then reading D.*/
 -#if defined(KL2x) && KINETIS_SERIAL_USE_UART0
 -  if(sdp == &SD1) {
 -    if(s1 & UARTx_S1_IDLE) {
 -      *(u->s1_p) |= UARTx_S1_IDLE;
 -    }
 +  if(s1 & UARTx_S1_IDLE) {
 +    (void)*(u->d_p);
 +  }
 -    if(s1 & (UARTx_S1_OR | UARTx_S1_NF | UARTx_S1_FE | UARTx_S1_PF)) {
 -      set_error(sdp, s1);
 -      *(u->s1_p) |= UARTx_S1_OR | UARTx_S1_NF | UARTx_S1_FE | UARTx_S1_PF;
 -    }
 -    return;
 +  if(s1 & (UARTx_S1_OR | UARTx_S1_NF | UARTx_S1_FE | UARTx_S1_PF)) {
 +    set_error(sdp, s1);
 +    (void)*(u->d_p);
    }
 -#endif /* KL2x && KINETIS_SERIAL_USE_UART0 */
 +}
 +
 +#if defined(KL2x) && KINETIS_SERIAL_USE_UART0
 +static void serve_error_interrupt_uart0(void) {
 +  SerialDriver *sdp = &SD1;
 +  UART_w_TypeDef *u = &(sdp->uart);
 +  uint8_t s1 = *(u->s1_p);
 +
 +  /* S1 bits are write-1-to-clear for UART0 on KL2x. */
    if(s1 & UARTx_S1_IDLE) {
 -    (void)*(u->d_p);
 +    *(u->s1_p) |= UARTx_S1_IDLE;
    }
    if(s1 & (UARTx_S1_OR | UARTx_S1_NF | UARTx_S1_FE | UARTx_S1_PF)) {
      set_error(sdp, s1);
 -    (void)*(u->d_p);
 +    *(u->s1_p) |= UARTx_S1_OR | UARTx_S1_NF | UARTx_S1_FE | UARTx_S1_PF;
    }
  }
 +#endif /* KL2x && KINETIS_SERIAL_USE_UART0 */
  /**
   * @brief   Common IRQ handler.
 @@ -161,6 +178,12 @@ static void serve_interrupt(SerialDriver *sdp) {      }
    }
 +#if defined(KL2x) && KINETIS_SERIAL_USE_UART0
 +  if (sdp == &SD1) {
 +    serve_error_interrupt_uart0();
 +    return;
 +  }
 +#endif
    serve_error_interrupt(sdp);
  }
 @@ -184,29 +207,28 @@ static void preload(SerialDriver *sdp) {  /**
   * @brief   Driver output notification.
   */
 -#if KINETIS_SERIAL_USE_UART0 || defined(__DOXYGEN__)
 -static void notify1(io_queue_t *qp)
 +static void notify(io_queue_t *qp)
  {
 -  (void)qp;
 -  preload(&SD1);
 +  preload(qp->q_link);
  }
 -#endif
 -#if KINETIS_SERIAL_USE_UART1 || defined(__DOXYGEN__)
 -static void notify2(io_queue_t *qp)
 -{
 -  (void)qp;
 -  preload(&SD2);
 -}
 -#endif
 -
 -#if KINETIS_SERIAL_USE_UART2 || defined(__DOXYGEN__)
 -static void notify3(io_queue_t *qp)
 -{
 -  (void)qp;
 -  preload(&SD3);
 +/**
 + * @brief   Common driver initialization, except LP.
 + */
 +static void sd_lld_init_driver(SerialDriver *SDn, UART_TypeDef *UARTn) {
 +  /* Driver initialization.*/
 +  sdObjectInit(SDn, NULL, notify);
 +  SDn->uart.bdh_p = &(UARTn->BDH);
 +  SDn->uart.bdl_p = &(UARTn->BDL);
 +  SDn->uart.c1_p =  &(UARTn->C1);
 +  SDn->uart.c2_p =  &(UARTn->C2);
 +  SDn->uart.c3_p =  &(UARTn->C3);
 +  SDn->uart.c4_p =  &(UARTn->C4);
 +  SDn->uart.s1_p =  (volatile uint8_t *)&(UARTn->S1);
 +  SDn->uart.s2_p =  &(UARTn->S2);
 +  SDn->uart.d_p =   &(UARTn->D);
 +  SDn->uart.uart_p = UARTn;
  }
 -#endif
  /**
   * @brief   Common UART configuration.
 @@ -240,9 +262,9 @@ static void configure_uart(SerialDriver *sdp, const SerialConfig *config) {    }
  #endif /* KINETIS_SERIAL_USE_UART0 */
 -#elif defined(K20x) /* KL2x */
 +#elif defined(K20x) || defined(K60x) /* KL2x */
 -  /* UARTs 0 and 1 are clocked from SYSCLK, others from BUSCLK on K20x. */
 +  /* UARTs 0 and 1 are clocked from SYSCLK, others from BUSCLK on K20x and K60x. */
  #if KINETIS_SERIAL_USE_UART0
    if(sdp == &SD1)
      divisor = KINETIS_SYSCLK_FREQUENCY;
 @@ -260,9 +282,9 @@ static void configure_uart(SerialDriver *sdp, const SerialConfig *config) {    *(uart->bdh_p) = UARTx_BDH_SBR(divisor >> 13) | (*(uart->bdh_p) & ~UARTx_BDH_SBR_MASK);
    *(uart->bdl_p) = UARTx_BDL_SBR(divisor >> 5);
 -#if defined(K20x)
 +#if defined(K20x) || defined(K60x)
    *(uart->c4_p) = UARTx_C4_BRFA(divisor) | (*(uart->c4_p) & ~UARTx_C4_BRFA_MASK);
 -#endif /* K20x */
 +#endif /* K20x, K60x */
    /* Line settings. */
    *(uart->c1_p) = 0;
 @@ -300,12 +322,40 @@ OSAL_IRQ_HANDLER(KINETIS_SERIAL2_IRQ_VECTOR) {  }
  #endif
 +#if KINETIS_SERIAL_USE_UART3 || defined(__DOXYGEN__)
 +OSAL_IRQ_HANDLER(KINETIS_SERIAL3_IRQ_VECTOR) {
 +  OSAL_IRQ_PROLOGUE();
 +  serve_interrupt(&SD4);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART4 || defined(__DOXYGEN__)
 +OSAL_IRQ_HANDLER(KINETIS_SERIAL4_IRQ_VECTOR) {
 +  OSAL_IRQ_PROLOGUE();
 +  serve_interrupt(&SD5);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART5 || defined(__DOXYGEN__)
 +OSAL_IRQ_HANDLER(KINETIS_SERIAL5_IRQ_VECTOR) {
 +  OSAL_IRQ_PROLOGUE();
 +  serve_interrupt(&SD6);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif
 +
  #if KINETIS_HAS_SERIAL_ERROR_IRQ
  #if KINETIS_SERIAL_USE_UART0 || defined(__DOXYGEN__)
  OSAL_IRQ_HANDLER(KINETIS_SERIAL0_ERROR_IRQ_VECTOR) {
    OSAL_IRQ_PROLOGUE();
 +#if defined(KL2x)
 +  serve_error_interrupt_uart0();
 +#else
    serve_error_interrupt(&SD1);
 +#endif
    OSAL_IRQ_EPILOGUE();
  }
  #endif
 @@ -326,6 +376,30 @@ OSAL_IRQ_HANDLER(KINETIS_SERIAL2_ERROR_IRQ_VECTOR) {  }
  #endif
 +#if KINETIS_SERIAL_USE_UART3 || defined(__DOXYGEN__)
 +OSAL_IRQ_HANDLER(KINETIS_SERIAL3_ERROR_IRQ_VECTOR) {
 +  OSAL_IRQ_PROLOGUE();
 +  serve_error_interrupt(&SD4);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART4 || defined(__DOXYGEN__)
 +OSAL_IRQ_HANDLER(KINETIS_SERIAL4_ERROR_IRQ_VECTOR) {
 +  OSAL_IRQ_PROLOGUE();
 +  serve_error_interrupt(&SD5);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART5 || defined(__DOXYGEN__)
 +OSAL_IRQ_HANDLER(KINETIS_SERIAL5_ERROR_IRQ_VECTOR) {
 +  OSAL_IRQ_PROLOGUE();
 +  serve_error_interrupt(&SD6);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif
 +
  #endif /* KINETIS_HAS_SERIAL_ERROR_IRQ */
  /*===========================================================================*/
 @@ -341,19 +415,11 @@ void sd_lld_init(void) {  #if KINETIS_SERIAL_USE_UART0
    /* Driver initialization.*/
 -  sdObjectInit(&SD1, NULL, notify1);
  #if ! KINETIS_SERIAL0_IS_LPUART
 -  SD1.uart.bdh_p = &(UART0->BDH);
 -  SD1.uart.bdl_p = &(UART0->BDL);
 -  SD1.uart.c1_p =  &(UART0->C1);
 -  SD1.uart.c2_p =  &(UART0->C2);
 -  SD1.uart.c3_p =  &(UART0->C3);
 -  SD1.uart.c4_p =  &(UART0->C4);
 -  SD1.uart.s1_p =  (volatile uint8_t *)&(UART0->S1);
 -  SD1.uart.s2_p =  &(UART0->S2);
 -  SD1.uart.d_p =   &(UART0->D);
 +  sd_lld_init_driver(&SD1, UART0);
  #else /* ! KINETIS_SERIAL0_IS_LPUART */
    /* little endian! */
 +  sdObjectInit(&SD1, NULL, notify);
    SD1.uart.bdh_p = ((uint8_t *)&(LPUART0->BAUD)) + 1; /* BDH: BAUD, byte 3 */
    SD1.uart.bdl_p = ((uint8_t *)&(LPUART0->BAUD)) + 0; /* BDL: BAUD, byte 4 */
    SD1.uart.c1_p =  ((uint8_t *)&(LPUART0->CTRL)) + 0; /* C1: CTRL, byte 4 */
 @@ -377,20 +443,11 @@ void sd_lld_init(void) {  #if KINETIS_SERIAL_USE_UART1
    /* Driver initialization.*/
 -  sdObjectInit(&SD2, NULL, notify2);
  #if ! KINETIS_SERIAL1_IS_LPUART
 -  SD2.uart.bdh_p = &(UART1->BDH);
 -  SD2.uart.bdl_p = &(UART1->BDL);
 -  SD2.uart.c1_p =  &(UART1->C1);
 -  SD2.uart.c2_p =  &(UART1->C2);
 -  SD2.uart.c3_p =  &(UART1->C3);
 -  SD2.uart.c4_p =  &(UART1->C4);
 -  SD2.uart.s1_p =  (volatile uint8_t *)&(UART1->S1);
 -  SD2.uart.s2_p =  &(UART1->S2);
 -  SD2.uart.d_p =   &(UART1->D);
 -  SD2.uart.uart_p = UART1;
 +  sd_lld_init_driver(&SD2, UART1);
  #else /* ! KINETIS_SERIAL1_IS_LPUART */
    /* little endian! */
 +  sdObjectInit(&SD2, NULL, notify);
    SD2.uart.bdh_p = ((uint8_t *)&(LPUART1->BAUD)) + 1; /* BDH: BAUD, byte 3 */
    SD2.uart.bdl_p = ((uint8_t *)&(LPUART1->BAUD)) + 0; /* BDL: BAUD, byte 4 */
    SD2.uart.c1_p =  ((uint8_t *)&(LPUART1->CTRL)) + 0; /* C1: CTRL, byte 4 */
 @@ -406,19 +463,20 @@ void sd_lld_init(void) {  #endif /* KINETIS_SERIAL_USE_UART1 */
  #if KINETIS_SERIAL_USE_UART2
 -  /* Driver initialization.*/
 -  sdObjectInit(&SD3, NULL, notify3);
 -  SD3.uart.bdh_p = &(UART2->BDH);
 -  SD3.uart.bdl_p = &(UART2->BDL);
 -  SD3.uart.c1_p =  &(UART2->C1);
 -  SD3.uart.c2_p =  &(UART2->C2);
 -  SD3.uart.c3_p =  &(UART2->C3);
 -  SD3.uart.c4_p =  &(UART2->C4);
 -  SD3.uart.s1_p =  (volatile uint8_t *)&(UART2->S1);
 -  SD3.uart.s2_p =  &(UART2->S2);
 -  SD3.uart.d_p =   &(UART2->D);
 -  SD3.uart.uart_p = UART2;
 +  sd_lld_init_driver(&SD3, UART2);
  #endif /* KINETIS_SERIAL_USE_UART2 */
 +
 +#if KINETIS_SERIAL_USE_UART3
 +  sd_lld_init_driver(&SD4, UART3);
 +#endif /* KINETIS_SERIAL_USE_UART3 */
 +
 +#if KINETIS_SERIAL_USE_UART4
 +  sd_lld_init_driver(&SD5, UART4);
 +#endif /* KINETIS_SERIAL_USE_UART4 */
 +
 +#if KINETIS_SERIAL_USE_UART5
 +  sd_lld_init_driver(&SD6, UART5);
 +#endif /* KINETIS_SERIAL_USE_UART5 */
  }
  /**
 @@ -505,6 +563,33 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {      }
  #endif /* KINETIS_SERIAL_USE_UART2 */
 +#if KINETIS_SERIAL_USE_UART3
 +    if (sdp == &SD4) {
 +      SIM->SCGC4 |= SIM_SCGC4_UART3;
 +      configure_uart(sdp, config);
 +      nvicEnableVector(UART3Status_IRQn, KINETIS_SERIAL_UART3_PRIORITY);
 +      nvicEnableVector(UART3Error_IRQn, KINETIS_SERIAL_UART3_PRIORITY);
 +    }
 +#endif /* KINETIS_SERIAL_USE_UART3 */
 +
 +#if KINETIS_SERIAL_USE_UART4
 +    if (sdp == &SD5) {
 +      SIM->SCGC1 |= SIM_SCGC1_UART4;
 +      configure_uart(sdp, config);
 +      nvicEnableVector(UART4Status_IRQn, KINETIS_SERIAL_UART4_PRIORITY);
 +      nvicEnableVector(UART4Error_IRQn, KINETIS_SERIAL_UART4_PRIORITY);
 +    }
 +#endif /* KINETIS_SERIAL_USE_UART4 */
 +
 +#if KINETIS_SERIAL_USE_UART5
 +    if (sdp == &SD6) {
 +      SIM->SCGC1 |= SIM_SCGC1_UART5;
 +      configure_uart(sdp, config);
 +      nvicEnableVector(UART5Status_IRQn, KINETIS_SERIAL_UART5_PRIORITY);
 +      nvicEnableVector(UART5Error_IRQn, KINETIS_SERIAL_UART5_PRIORITY);
 +    }
 +#endif /* KINETIS_SERIAL_USE_UART5 */
 +
    }
    /* Configures the peripheral.*/
 @@ -575,6 +660,30 @@ void sd_lld_stop(SerialDriver *sdp) {        SIM->SCGC4 &= ~SIM_SCGC4_UART2;
      }
  #endif
 +
 +#if KINETIS_SERIAL_USE_UART3
 +    if (sdp == &SD4) {
 +      nvicDisableVector(UART3Status_IRQn);
 +      nvicDisableVector(UART3Error_IRQn);
 +      SIM->SCGC4 &= ~SIM_SCGC4_UART3;
 +    }
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART4
 +    if (sdp == &SD5) {
 +      nvicDisableVector(UART4Status_IRQn);
 +      nvicDisableVector(UART4Error_IRQn);
 +      SIM->SCGC1 &= ~SIM_SCGC1_UART4;
 +    }
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART5
 +    if (sdp == &SD6) {
 +      nvicDisableVector(UART5Status_IRQn);
 +      nvicDisableVector(UART5Error_IRQn);
 +      SIM->SCGC1 &= ~SIM_SCGC1_UART5;
 +    }
 +#endif
    }
  }
 diff --git a/os/hal/ports/KINETIS/LLD/hal_serial_lld.h b/os/hal/ports/KINETIS/LLD/hal_serial_lld.h index f11c063..3cb6d2b 100644 --- a/os/hal/ports/KINETIS/LLD/hal_serial_lld.h +++ b/os/hal/ports/KINETIS/LLD/hal_serial_lld.h @@ -60,6 +60,27 @@  #if !defined(KINETIS_SERIAL_USE_UART2) || defined(__DOXYGEN__)
  #define KINETIS_SERIAL_USE_UART2             FALSE
  #endif
 +/**
 + * @brief   SD4 driver enable switch.
 + * @details If set to @p TRUE the support for SD4 is included.
 + */
 +#if !defined(KINETIS_SERIAL_USE_UART3) || defined(__DOXYGEN__)
 +#define KINETIS_SERIAL_USE_UART3             FALSE
 +#endif
 +/**
 + * @brief   SD5 driver enable switch.
 + * @details If set to @p TRUE the support for SD5 is included.
 + */
 +#if !defined(KINETIS_SERIAL_USE_UART4) || defined(__DOXYGEN__)
 +#define KINETIS_SERIAL_USE_UART4             FALSE
 +#endif
 +/**
 + * @brief   SD6 driver enable switch.
 + * @details If set to @p TRUE the support for SD6 is included.
 + */
 +#if !defined(KINETIS_SERIAL_USE_UART5) || defined(__DOXYGEN__)
 +#define KINETIS_SERIAL_USE_UART5             FALSE
 +#endif
  /**
   * @brief   UART0 interrupt priority level setting.
 @@ -83,6 +104,27 @@  #endif
  /**
 + * @brief   UART3 interrupt priority level setting.
 + */
 +#if !defined(KINETIS_SERIAL_UART3_PRIORITY) || defined(__DOXYGEN__)
 +#define KINETIS_SERIAL_UART3_PRIORITY        12
 +#endif
 +
 +/**
 + * @brief   UART4 interrupt priority level setting.
 + */
 +#if !defined(KINETIS_SERIAL_UART4_PRIORITY) || defined(__DOXYGEN__)
 +#define KINETIS_SERIAL_UART4_PRIORITY        12
 +#endif
 +
 +/**
 + * @brief   UART5 interrupt priority level setting.
 + */
 +#if !defined(KINETIS_SERIAL_UART5_PRIORITY) || defined(__DOXYGEN__)
 +#define KINETIS_SERIAL_UART5_PRIORITY        12
 +#endif
 +
 +/**
   * @brief   UART0 clock source.
   */
  #if !defined(KINETIS_UART0_CLOCK_SRC) || defined(__DOXYGEN__)
 @@ -115,8 +157,21 @@  #error "UART2 not present in the selected device"
  #endif
 +#if KINETIS_SERIAL_USE_UART3 && !KINETIS_HAS_SERIAL3
 +#error "UART3 not present in the selected device"
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART4 && !KINETIS_HAS_SERIAL4
 +#error "UART4 not present in the selected device"
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART5 && !KINETIS_HAS_SERIAL5
 +#error "UART5 not present in the selected device"
 +#endif
 +
  #if !(KINETIS_SERIAL_USE_UART0 || KINETIS_SERIAL_USE_UART1 || \
 -      KINETIS_SERIAL_USE_UART2)
 +      KINETIS_SERIAL_USE_UART2 || KINETIS_SERIAL_USE_UART3 || \
 +      KINETIS_SERIAL_USE_UART4 || KINETIS_SERIAL_USE_UART5)
  #error "Serial driver activated but no UART peripheral assigned"
  #endif
 @@ -203,6 +258,18 @@ extern SerialDriver SD2;  extern SerialDriver SD3;
  #endif
 +#if KINETIS_SERIAL_USE_UART3 && !defined(__DOXYGEN__)
 +extern SerialDriver SD4;
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART4 && !defined(__DOXYGEN__)
 +extern SerialDriver SD5;
 +#endif
 +
 +#if KINETIS_SERIAL_USE_UART5 && !defined(__DOXYGEN__)
 +extern SerialDriver SD6;
 +#endif
 +
  #ifdef __cplusplus
  extern "C" {
  #endif
 diff --git a/os/hal/ports/KINETIS/LLD/hal_usb_lld.c b/os/hal/ports/KINETIS/LLD/hal_usb_lld.c index e8d9778..ba91d24 100644 --- a/os/hal/ports/KINETIS/LLD/hal_usb_lld.c +++ b/os/hal/ports/KINETIS/LLD/hal_usb_lld.c @@ -158,7 +158,7 @@ void usb_packet_transmit(USBDriver *usbp, usbep_t ep, size_t n)    USBInEndpointState *isp = epc->in_state;
    bd_t *bd = (bd_t *)&_bdt[BDT_INDEX(ep, TX, isp->odd_even)];
 -  
 +
    if (n > (size_t)epc->in_maxsize)
      n = (size_t)epc->in_maxsize;
 @@ -244,19 +244,16 @@ OSAL_IRQ_HANDLER(KINETIS_USB_IRQ_VECTOR) {      {
        case BDT_PID_SETUP:                                              // SETUP
        {
 -        /* Clear any pending IN stuff */
 -        _bdt[BDT_INDEX(ep, TX, EVEN)].desc = 0;
 -        _bdt[BDT_INDEX(ep, TX,  ODD)].desc = 0;
 -        /* Also in the chibios state machine */
 +        /* Clear receiving in the chibios state machine */
          (usbp)->receiving &= ~1;
 -        /* After a SETUP, IN is always DATA1 */
 -        usbp->epc[ep]->in_state->data_bank = DATA1;
 -
 -        /* Call SETUP function (ChibiOS core), which sends back stuff */
 +        /* Call SETUP function (ChibiOS core), which prepares
 +         * for send or receive and releases the buffer
 +         */
          _usb_isr_invoke_setup_cb(usbp, ep);
 -        /* Buffer is released by the above callback. */
 -        /* from Paul: "unfreeze the USB, now that we're ready" */
 -        USB0->CTL = USBx_CTL_USBENSOFEN;
 +        /* When a setup packet is received, tx is suspended,
 +         * so it needs to be resumed here.
 +         */
 +        USB0->CTL &= ~USBx_CTL_TXSUSPENDTOKENBUSY;
        } break;
        case BDT_PID_IN:                                                 // IN
        {
 @@ -728,9 +725,23 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {    }
    /* Release the buffer
     * Setup packet is always DATA0
 -   * Initialize buffers so current expects DATA0 & opposite DATA1 */
 +   * Release the current DATA0 buffer
 +   */
    bd->desc = BDT_DESC(usbp->epc[ep]->out_maxsize,DATA0);
 -  _bdt[BDT_INDEX(ep, RX, os->odd_even^ODD)].desc = BDT_DESC(usbp->epc[ep]->out_maxsize,DATA1);
 +  /* If DATA1 was expected, then the states are out of sync.
 +   * So reset the other buffer too, and set it as DATA1.
 +   * This should not happen in normal cases, but is possible in
 +   * error situations. NOTE: it's possible that this is too late
 +   * and the next packet has already been received and dropped, but
 +   * there's nothing that we can do about that anymore at this point.
 +   */
 +  if (os->data_bank == DATA1)
 +  {
 +    bd_t *bd_next = (bd_t*)&_bdt[BDT_INDEX(ep, RX, os->odd_even^ODD)];
 +    bd_next->desc = BDT_DESC(usbp->epc[ep]->out_maxsize,DATA1);
 +  }
 +  /* After a SETUP, both in and out are always DATA1 */
 +  usbp->epc[ep]->in_state->data_bank = DATA1;
    os->data_bank = DATA1;
  }
 @@ -762,8 +773,22 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {   * @notapi
   */
  void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
 -  (void)usbp;
 -  (void)ep;
 +  if (ep == 0 && usbp->ep0state == USB_EP0_IN_SENDING_STS) {
 +    /* When a status packet is about to be sent on endpoint 0 the
 +     * next packet will be a setup packet, which means that the
 +     * buffer we expect after this should be DATA0, and the following
 +     * DATA1. Since no out packets should be in flight at this time
 +     * it's safe to initialize the buffers according to the expectations
 +     * here.
 +     */
 +    const USBEndpointConfig* epc = usbp->epc[ep];
 +    bd_t * bd = (bd_t*)&_bdt[BDT_INDEX(ep, RX, epc->out_state->odd_even)];
 +    bd_t *bd_next = (bd_t*)&_bdt[BDT_INDEX(ep, RX, epc->out_state->odd_even^ODD)];
 +
 +    bd->desc = BDT_DESC(usbp->epc[ep]->out_maxsize,DATA1);
 +    bd_next->desc = BDT_DESC(usbp->epc[ep]->out_maxsize,DATA0);
 +    epc->out_state->data_bank = DATA0;
 +  }
    usb_packet_transmit(usbp,ep,usbp->epc[ep]->in_state->txsize);
  }
 diff --git a/os/hal/ports/KINETIS/LLD/hal_usb_lld.h b/os/hal/ports/KINETIS/LLD/hal_usb_lld.h index 961490e..bd4eb39 100644 --- a/os/hal/ports/KINETIS/LLD/hal_usb_lld.h +++ b/os/hal/ports/KINETIS/LLD/hal_usb_lld.h @@ -76,6 +76,13 @@    #define KINETIS_USB_ENDPOINTS USB_MAX_ENDPOINTS+1
  #endif
 +/**
 + * @brief   Host wake-up procedure duration.
 + */
 +#if !defined(USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
 +#define USB_HOST_WAKEUP_DURATION            2
 +#endif
 +
  /*===========================================================================*/
  /* Derived constants and error checks.                                       */
  /*===========================================================================*/
 @@ -97,6 +104,10 @@  #error "KINETIS_USB_IRQ_VECTOR not defined"
  #endif
 +#if (USB_HOST_WAKEUP_DURATION < 2) || (USB_HOST_WAKEUP_DURATION > 15)
 +#error "invalid USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15"
 +#endif
 +
  /*===========================================================================*/
  /* Driver data structures and types.                                         */
  /*===========================================================================*/
 @@ -394,6 +405,18 @@ struct USBDriver {  #endif /* KINETIS_USB0_IS_USBOTG */
  #endif
 +/**
 + * @brief   Start of host wake-up procedure.
 + *
 + * @notapi
 + */
 +#define usb_lld_wakeup_host(usbp)                                     \
 +  do{                                                                 \
 +    USB0->CTL |= USBx_CTL_RESUME;                                     \
 +    osalThreadSleepMilliseconds(USB_HOST_WAKEUP_DURATION);            \
 +    USB0->CTL &= ~USBx_CTL_RESUME;                                    \
 +  } while (false)
 +
  /*===========================================================================*/
  /* External declarations.                                                    */
  /*===========================================================================*/
 diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c index b4c2938..500b2e7 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.c @@ -97,7 +97,10 @@ void fsmc_init(void) {  #if (defined(STM32F427xx) || defined(STM32F437xx) || \       defined(STM32F429xx) || defined(STM32F439xx) || \ -     defined(STM32F7)) +     defined(STM32F745xx) || defined(STM32F746xx) || \ +     defined(STM32F756xx) || defined(STM32F767xx) || \ +     defined(STM32F769xx) || defined(STM32F777xx) || \ +     defined(STM32F779xx))    #if STM32_USE_FSMC_SDRAM      FSMCD1.sdram = (FSMC_SDRAM_TypeDef *)FSMC_Bank5_6_R_BASE;    #endif diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h index 2bc267f..80c5d26 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc.h @@ -36,7 +36,10 @@   */  #if (defined(STM32F427xx) || defined(STM32F437xx) || \       defined(STM32F429xx) || defined(STM32F439xx) || \ -     defined(STM32F769xx)) +     defined(STM32F745xx) || defined(STM32F746xx) || \ +     defined(STM32F756xx) || defined(STM32F767xx) || \ +     defined(STM32F769xx) || defined(STM32F777xx) || \ +     defined(STM32F779xx))    #if !defined(FSMC_Bank1_R_BASE)    #define FSMC_Bank1_R_BASE               (FMC_R_BASE + 0x0000)    #endif diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c index ea1be4c..6d727c8 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c @@ -29,7 +29,10 @@  #if (defined(STM32F427xx) || defined(STM32F437xx) || \       defined(STM32F429xx) || defined(STM32F439xx) || \ -     defined(STM32F769xx)) +     defined(STM32F745xx) || defined(STM32F746xx) || \ +     defined(STM32F756xx) || defined(STM32F767xx) || \ +     defined(STM32F769xx) || defined(STM32F777xx) || \ +     defined(STM32F779xx))  #if (STM32_USE_FSMC_SDRAM == TRUE) || defined(__DOXYGEN__) diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h index fdf3268..c9f9de0 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h @@ -30,7 +30,10 @@  #if (defined(STM32F427xx) || defined(STM32F437xx) || \       defined(STM32F429xx) || defined(STM32F439xx) || \ -     defined(STM32F769xx)) +     defined(STM32F745xx) || defined(STM32F746xx) || \ +     defined(STM32F756xx) || defined(STM32F767xx) || \ +     defined(STM32F769xx) || defined(STM32F777xx) || \ +     defined(STM32F779xx))  #include "hal_fsmc.h" diff --git a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c index fbd6f56..da13ca5 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c @@ -148,7 +148,10 @@ void fsmcSramStop(SRAMDriver *sramp) {      uint32_t mask = FSMC_BCR_MBKEN;  #if (defined(STM32F427xx) || defined(STM32F437xx) || \       defined(STM32F429xx) || defined(STM32F439xx) || \ -     defined(STM32F7)) +     defined(STM32F745xx) || defined(STM32F746xx) || \ +     defined(STM32F756xx) || defined(STM32F767xx) || \ +     defined(STM32F769xx) || defined(STM32F777xx) || \ +     defined(STM32F779xx))      mask |= FSMC_BCR_CCLKEN;  #endif      sramp->sram->BCR &= ~mask;  | 
