diff options
Diffstat (limited to 'os')
-rw-r--r-- | os/common/ext/CMSIS/KINETIS/k20xx.h | 2 | ||||
-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 | 6 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h | 6 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sram.c | 5 |
8 files changed, 87 insertions, 22 deletions
diff --git a/os/common/ext/CMSIS/KINETIS/k20xx.h b/os/common/ext/CMSIS/KINETIS/k20xx.h index 38855aa..8218b3c 100644 --- a/os/common/ext/CMSIS/KINETIS/k20xx.h +++ b/os/common/ext/CMSIS/KINETIS/k20xx.h @@ -2242,7 +2242,7 @@ typedef struct /******** Bits definition for USBx_CTL register *****************/ #define USBx_CTL_JSTATE ((uint8_t)0x80) /*!< Live USB differential receiver JSTATE signal */ #define USBx_CTL_SE0 ((uint8_t)0x40) /*!< Live USB single ended zero signal */ -#define USBx_CTL_TXSUSPENDTOKENBUS ((uint8_t)0x20) /*!< */ +#define USBx_CTL_TXSUSPENDTOKENBUSY ((uint8_t)0x20) /*!< */ #define USBx_CTL_RESET ((uint8_t)0x10) /*!< Generates an USB reset signal (host mode) */ #define USBx_CTL_HOSTMODEEN ((uint8_t)0x08) /*!< Operate in Host mode */ #define USBx_CTL_RESUME ((uint8_t)0x04) /*!< Executes resume signaling */ 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 51b9428..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(STM32F7)) + 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 ac83477..6d727c8 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c +++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.c @@ -28,7 +28,11 @@ #include "hal.h" #if (defined(STM32F427xx) || defined(STM32F437xx) || \ - defined(STM32F429xx) || defined(STM32F439xx)) + defined(STM32F429xx) || defined(STM32F439xx) || \ + 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 b419168..c9f9de0 100644 --- a/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h +++ b/os/hal/ports/STM32/LLD/FSMCv1/hal_fsmc_sdram.h @@ -29,7 +29,11 @@ #define HAL_FMC_SDRAM_H_ #if (defined(STM32F427xx) || defined(STM32F437xx) || \ - defined(STM32F429xx) || defined(STM32F439xx)) + defined(STM32F429xx) || defined(STM32F439xx) || \ + 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; |