From 8ca210a4af9fd039e290cfcc309adde543999c1f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 9 Aug 2013 08:24:22 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6108 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USBv1/stm32_usb.h | 243 --------- os/hal/platforms/STM32/USBv1/usb_lld.c | 830 ------------------------------- os/hal/platforms/STM32/USBv1/usb_lld.h | 437 ---------------- 3 files changed, 1510 deletions(-) delete mode 100644 os/hal/platforms/STM32/USBv1/stm32_usb.h delete mode 100644 os/hal/platforms/STM32/USBv1/usb_lld.c delete mode 100644 os/hal/platforms/STM32/USBv1/usb_lld.h (limited to 'os/hal/platforms/STM32/USBv1') diff --git a/os/hal/platforms/STM32/USBv1/stm32_usb.h b/os/hal/platforms/STM32/USBv1/stm32_usb.h deleted file mode 100644 index 83f349e42..000000000 --- a/os/hal/platforms/STM32/USBv1/stm32_usb.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file stm32_usb.h - * @brief STM32 USB registers layout header. - * @note This file requires definitions from the ST STM32 header files - * stm32f10x.h or stm32l1xx.h. - * - * @addtogroup USB - * @{ - */ - -#ifndef _STM32_USB_H_ -#define _STM32_USB_H_ - -/** - * @brief Number of the available endpoints. - * @details This value does not include the endpoint 0 which is always present. - */ -#define USB_ENDOPOINTS_NUMBER 7 - -/** - * @brief USB registers block. - */ -typedef struct { - /** - * @brief Endpoint registers. - */ - volatile uint32_t EPR[USB_ENDOPOINTS_NUMBER + 1]; - /* - * @brief Reserved space. - */ - volatile uint32_t _r20[8]; - /* - * @brief Control Register. - */ - volatile uint32_t CNTR; - /* - * @brief Interrupt Status Register. - */ - volatile uint32_t ISTR; - /* - * @brief Frame Number Register. - */ - volatile uint32_t FNR; - /* - * @brief Device Address Register. - */ - volatile uint32_t DADDR; - /* - * @brief Buffer Table Address. - */ - volatile uint32_t BTABLE; -} stm32_usb_t; - -/** - * @brief USB descriptor registers block. - */ -typedef struct { - /** - * @brief TX buffer offset register. - */ - volatile uint32_t TXADDR0; - /** - * @brief TX counter register 0. - */ - volatile uint16_t TXCOUNT0; - /** - * @brief TX counter register 1. - */ - volatile uint16_t TXCOUNT1; - /** - * @brief RX buffer offset register. - */ - volatile uint32_t RXADDR0; - /** - * @brief RX counter register 0. - */ - volatile uint16_t RXCOUNT0; - /** - * @brief RX counter register 1. - */ - volatile uint16_t RXCOUNT1; -} stm32_usb_descriptor_t; - -/** - * @name Register aliases - * @{ - */ -#define RXADDR1 TXADDR0 -#define TXADDR1 RXADDR0 -/** @} */ - -/** - * @brief USB registers block numeric address. - */ -#define STM32_USB_BASE (APB1PERIPH_BASE + 0x5C00) - -/** - * @brief USB RAM numeric address. - */ -#define STM32_USBRAM_BASE (APB1PERIPH_BASE + 0x6000) - -/** - * @brief Pointer to the USB registers block. - */ -#define STM32_USB ((stm32_usb_t *)STM32_USB_BASE) - -/** - * @brief Pointer to the USB RAM. - */ -#define STM32_USBRAM ((uint32_t *)STM32_USBRAM_BASE) - -/** - * @brief Size of the dedicated packet memory. - */ -#define USB_PMA_SIZE 512 - -/** - * @brief Mask of all the toggling bits in the EPR register. - */ -#define EPR_TOGGLE_MASK (EPR_STAT_TX_MASK | EPR_DTOG_TX | \ - EPR_STAT_RX_MASK | EPR_DTOG_RX | \ - EPR_SETUP) - -#define EPR_EA_MASK 0x000F -#define EPR_STAT_TX_MASK 0x0030 -#define EPR_STAT_TX_DIS 0x0000 -#define EPR_STAT_TX_STALL 0x0010 -#define EPR_STAT_TX_NAK 0x0020 -#define EPR_STAT_TX_VALID 0x0030 -#define EPR_DTOG_TX 0x0040 -#define EPR_SWBUF_RX EPR_DTOG_TX -#define EPR_CTR_TX 0x0080 -#define EPR_EP_KIND 0x0100 -#define EPR_EP_DBL_BUF EPR_EP_KIND -#define EPR_EP_STATUS_OUT EPR_EP_KIND -#define EPR_EP_TYPE_MASK 0x0600 -#define EPR_EP_TYPE_BULK 0x0000 -#define EPR_EP_TYPE_CONTROL 0x0200 -#define EPR_EP_TYPE_ISO 0x0400 -#define EPR_EP_TYPE_INTERRUPT 0x0600 -#define EPR_SETUP 0x0800 -#define EPR_STAT_RX_MASK 0x3000 -#define EPR_STAT_RX_DIS 0x0000 -#define EPR_STAT_RX_STALL 0x1000 -#define EPR_STAT_RX_NAK 0x2000 -#define EPR_STAT_RX_VALID 0x3000 -#define EPR_DTOG_RX 0x4000 -#define EPR_SWBUF_TX EPR_DTOG_RX -#define EPR_CTR_RX 0x8000 - -#define CNTR_FRES 0x0001 -#define CNTR_PDWN 0x0002 -#define CNTR_LP_MODE 0x0004 -#define CNTR_FSUSP 0x0008 -#define CNTR_RESUME 0x0010 -#define CNTR_ESOFM 0x0100 -#define CNTR_SOFM 0x0200 -#define CNTR_RESETM 0x0400 -#define CNTR_SUSPM 0x0800 -#define CNTR_WKUPM 0x1000 -#define CNTR_ERRM 0x2000 -#define CNTR_PMAOVRM 0x4000 -#define CNTR_CTRM 0x8000 - -#define ISTR_EP_ID_MASK 0x000F -#define ISTR_DIR 0x0010 -#define ISTR_ESOF 0x0100 -#define ISTR_SOF 0x0200 -#define ISTR_RESET 0x0400 -#define ISTR_SUSP 0x0800 -#define ISTR_WKUP 0x1000 -#define ISTR_ERR 0x2000 -#define ISTR_PMAOVR 0x4000 -#define ISTR_CTR 0x8000 - -#define FNR_FN_MASK 0x07FF -#define FNR_LSOF 0x1800 -#define FNR_LCK 0x2000 -#define FNR_RXDM 0x4000 -#define FNR_RXDP 0x8000 - -#define DADDR_ADD_MASK 0x007F -#define DADDR_EF 0x0080 - -#define RXCOUNT_COUNT_MASK 0x03FF -#define TXCOUNT_COUNT_MASK 0x03FF - -#define EPR_SET(ep, epr) \ - STM32_USB->EPR[ep] = (epr) & ~EPR_TOGGLE_MASK - -#define EPR_TOGGLE(ep, epr) \ - STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] ^ ((epr) & EPR_TOGGLE_MASK)) - -#define EPR_SET_STAT_RX(ep, epr) \ - STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] & \ - ~(EPR_TOGGLE_MASK & ~EPR_STAT_RX_MASK)) ^ \ - (epr) - -#define EPR_SET_STAT_TX(ep, epr) \ - STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] & \ - ~(EPR_TOGGLE_MASK & ~EPR_STAT_TX_MASK)) ^ \ - (epr) - -#define EPR_CLEAR_CTR_RX(ep) \ - STM32_USB->EPR[ep] &= ~EPR_CTR_RX & ~EPR_TOGGLE_MASK - -#define EPR_CLEAR_CTR_TX(ep) \ - STM32_USB->EPR[ep] &= ~EPR_CTR_TX & ~EPR_TOGGLE_MASK - -/** - * @brief Returns an endpoint descriptor pointer. - */ -#define USB_GET_DESCRIPTOR(ep) \ - ((stm32_usb_descriptor_t *)((uint32_t)STM32_USBRAM_BASE + \ - (uint32_t)STM32_USB->BTABLE * 2 + \ - (uint32_t)(ep) * \ - sizeof(stm32_usb_descriptor_t))) - -/** - * @brief Converts from a PMA address to a physical address. - */ -#define USB_ADDR2PTR(addr) \ - ((uint32_t *)((addr) * 2 + STM32_USBRAM_BASE)) - -#endif /* _STM32_USB_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c deleted file mode 100644 index 22af59866..000000000 --- a/os/hal/platforms/STM32/USBv1/usb_lld.c +++ /dev/null @@ -1,830 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file STM32/USBv1/usb_lld.c - * @brief STM32 USB subsystem low level driver source. - * - * @addtogroup USB - * @{ - */ - -#include - -#include "ch.h" -#include "hal.h" - -#if HAL_USE_USB || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define BTABLE_ADDR 0x0000 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief USB1 driver identifier.*/ -#if STM32_USB_USE_USB1 || defined(__DOXYGEN__) -USBDriver USBD1; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief EP0 state. - * @note It is an union because IN and OUT endpoints are never used at the - * same time for EP0. - */ -static union { - /** - * @brief IN EP0 state. - */ - USBInEndpointState in; - /** - * @brief OUT EP0 state. - */ - USBOutEndpointState out; -} ep0_state; - -/** - * @brief Buffer for the EP0 setup packets. - */ -static uint8_t ep0setup_buffer[8]; - -/** - * @brief EP0 initialization structure. - */ -static const USBEndpointConfig ep0config = { - USB_EP_MODE_TYPE_CTRL, - _usb_ep0setup, - _usb_ep0in, - _usb_ep0out, - 0x40, - 0x40, - &ep0_state.in, - &ep0_state.out, - 1, - ep0setup_buffer -}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Resets the packet memory allocator. - * - * @param[in] usbp pointer to the @p USBDriver object - */ -static void usb_pm_reset(USBDriver *usbp) { - - /* The first 64 bytes are reserved for the descriptors table. The effective - available RAM for endpoint buffers is just 448 bytes.*/ - usbp->pmnext = 64; -} - -/** - * @brief Resets the packet memory allocator. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] size size of the packet buffer to allocate - */ -static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) { - uint32_t next; - - next = usbp->pmnext; - usbp->pmnext += size; - chDbgAssert(usbp->pmnext <= USB_PMA_SIZE, "usb_pm_alloc(), #1", "PMA overflow"); - return next; -} - -/** - * @brief Reads from a dedicated packet buffer. - * - * @param[in] udp pointer to a @p stm32_usb_descriptor_t - * @param[out] buf buffer where to copy the packet data - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. - * - * @notapi - */ -static void usb_packet_read_to_buffer(stm32_usb_descriptor_t *udp, - uint8_t *buf, size_t n) { - uint32_t *pmap= USB_ADDR2PTR(udp->RXADDR0); - - n = (n + 1) / 2; - while (n > 0) { - /* Note, this line relies on the Cortex-M3/M4 ability to perform - unaligned word accesses.*/ - *(uint16_t *)buf = (uint16_t)*pmap++; - buf += 2; - n--; - } -} - -/** - * @brief Reads from a dedicated packet buffer. - * - * @param[in] udp pointer to a @p stm32_usb_descriptor_t - * @param[in] iqp pointer to an @p InputQueue object - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. - * - * @notapi - */ -static void usb_packet_read_to_queue(stm32_usb_descriptor_t *udp, - InputQueue *iqp, size_t n) { - size_t nhw; - uint32_t *pmap= USB_ADDR2PTR(udp->RXADDR0); - - nhw = n / 2; - while (nhw > 0) { - uint32_t w; - - w = *pmap++; - *iqp->q_wrptr++ = (uint8_t)w; - if (iqp->q_wrptr >= iqp->q_top) - iqp->q_wrptr = iqp->q_buffer; - *iqp->q_wrptr++ = (uint8_t)(w >> 8); - if (iqp->q_wrptr >= iqp->q_top) - iqp->q_wrptr = iqp->q_buffer; - nhw--; - } - /* Last byte for odd numbers.*/ - if ((n & 1) != 0) { - *iqp->q_wrptr++ = (uint8_t)*pmap; - if (iqp->q_wrptr >= iqp->q_top) - iqp->q_wrptr = iqp->q_buffer; - } - - /* Updating queue.*/ - chSysLockFromIsr(); - iqp->q_counter += n; - while (notempty(&iqp->q_waiting)) - chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; - chSysUnlockFromIsr(); -} - -/** - * @brief Writes to a dedicated packet buffer. - * - * @param[in] udp pointer to a @p stm32_usb_descriptor_t - * @param[in] buf buffer where to fetch the packet data - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. - * - * @notapi - */ -static void usb_packet_write_from_buffer(stm32_usb_descriptor_t *udp, - const uint8_t *buf, - size_t n) { - uint32_t *pmap = USB_ADDR2PTR(udp->TXADDR0); - - udp->TXCOUNT0 = (uint16_t)n; - n = (n + 1) / 2; - while (n > 0) { - /* Note, this line relies on the Cortex-M3/M4 ability to perform - unaligned word accesses.*/ - *pmap++ = *(uint16_t *)buf; - buf += 2; - n--; - } -} - -/** - * @brief Writes to a dedicated packet buffer. - * - * @param[in] udp pointer to a @p stm32_usb_descriptor_t - * @param[in] buf buffer where to fetch the packet data - * @param[in] n maximum number of bytes to copy. This value must - * not exceed the maximum packet size for this endpoint. - * - * @notapi - */ -static void usb_packet_write_from_queue(stm32_usb_descriptor_t *udp, - OutputQueue *oqp, size_t n) { - size_t nhw; - uint32_t *pmap = USB_ADDR2PTR(udp->TXADDR0); - - udp->TXCOUNT0 = (uint16_t)n; - nhw = n / 2; - while (nhw > 0) { - uint32_t w; - - w = (uint32_t)*oqp->q_rdptr++; - if (oqp->q_rdptr >= oqp->q_top) - oqp->q_rdptr = oqp->q_buffer; - w |= (uint32_t)*oqp->q_rdptr++ << 8; - if (oqp->q_rdptr >= oqp->q_top) - oqp->q_rdptr = oqp->q_buffer; - *pmap++ = w; - nhw--; - } - - /* Last byte for odd numbers.*/ - if ((n & 1) != 0) { - *pmap = (uint32_t)*oqp->q_rdptr++; - if (oqp->q_rdptr >= oqp->q_top) - oqp->q_rdptr = oqp->q_buffer; - } - - /* Updating queue. Note, the lock is done in this unusual way because this - function can be called from both ISR and thread context so the kind - of lock function to be invoked cannot be decided beforehand.*/ - port_lock(); - dbg_enter_lock(); - - oqp->q_counter += n; - while (notempty(&oqp->q_waiting)) - chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK; - - dbg_leave_lock(); - port_unlock(); -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if STM32_USB_USE_USB1 || defined(__DOXYGEN__) -#if !defined(STM32_USB1_HP_HANDLER) -#error "STM32_USB1_HP_HANDLER not defined" -#endif -/** - * @brief USB high priority interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(STM32_USB1_HP_HANDLER) { - - CH_IRQ_PROLOGUE(); - - CH_IRQ_EPILOGUE(); -} - -#if !defined(STM32_USB1_LP_HANDLER) -#error "STM32_USB1_LP_HANDLER not defined" -#endif -/** - * @brief USB low priority interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(STM32_USB1_LP_HANDLER) { - uint32_t istr; - USBDriver *usbp = &USBD1; - - CH_IRQ_PROLOGUE(); - - istr = STM32_USB->ISTR; - - /* USB bus reset condition handling.*/ - if (istr & ISTR_RESET) { - _usb_reset(usbp); - _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET); - STM32_USB->ISTR = ~ISTR_RESET; - } - - /* USB bus SUSPEND condition handling.*/ - if (istr & ISTR_SUSP) { - STM32_USB->CNTR |= CNTR_FSUSP; - _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND); -#if STM32_USB_LOW_POWER_ON_SUSPEND - STM32_USB->CNTR |= CNTR_LP_MODE; -#endif - STM32_USB->ISTR = ~ISTR_SUSP; - } - - /* USB bus WAKEUP condition handling.*/ - if (istr & ISTR_WKUP) { - uint32_t fnr = STM32_USB->FNR; - if (!(fnr & FNR_RXDP)) { - STM32_USB->CNTR &= ~CNTR_FSUSP; - _usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP); - } -#if STM32_USB_LOW_POWER_ON_SUSPEND - else { - /* Just noise, going back in SUSPEND mode, reference manual 22.4.5, - table 169.*/ - STM32_USB->CNTR |= CNTR_LP_MODE; - } -#endif - STM32_USB->ISTR = ~ISTR_WKUP; - } - - /* SOF handling.*/ - if (istr & ISTR_SOF) { - _usb_isr_invoke_sof_cb(usbp); - STM32_USB->ISTR = ~ISTR_SOF; - } - - /* Endpoint events handling.*/ - while (istr & ISTR_CTR) { - size_t n; - uint32_t ep; - uint32_t epr = STM32_USB->EPR[ep = istr & ISTR_EP_ID_MASK]; - const USBEndpointConfig *epcp = usbp->epc[ep]; - - if (epr & EPR_CTR_TX) { - size_t transmitted; - /* IN endpoint, transmission.*/ - EPR_CLEAR_CTR_TX(ep); - - transmitted = (size_t)USB_GET_DESCRIPTOR(ep)->TXCOUNT0; - epcp->in_state->txcnt += transmitted; - n = epcp->in_state->txsize - epcp->in_state->txcnt; - if (n > 0) { - /* Transfer not completed, there are more packets to send.*/ - if (n > epcp->in_maxsize) - n = epcp->in_maxsize; - - if (epcp->in_state->txqueued) - usb_packet_write_from_queue(USB_GET_DESCRIPTOR(ep), - epcp->in_state->mode.queue.txqueue, - n); - else { - epcp->in_state->mode.linear.txbuf += transmitted; - usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep), - epcp->in_state->mode.linear.txbuf, - n); - } - chSysLockFromIsr(); - usb_lld_start_in(usbp, ep); - chSysUnlockFromIsr(); - } - else { - /* Transfer completed, invokes the callback.*/ - _usb_isr_invoke_in_cb(usbp, ep); - } - } - if (epr & EPR_CTR_RX) { - EPR_CLEAR_CTR_RX(ep); - /* OUT endpoint, receive.*/ - if (epr & EPR_SETUP) { - /* Setup packets handling, setup packets are handled using a - specific callback.*/ - _usb_isr_invoke_setup_cb(usbp, ep); - } - else { - stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep); - n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK; - - /* Reads the packet into the defined buffer.*/ - if (epcp->out_state->rxqueued) - usb_packet_read_to_queue(udp, - epcp->out_state->mode.queue.rxqueue, - n); - else { - usb_packet_read_to_buffer(udp, - epcp->out_state->mode.linear.rxbuf, - n); - epcp->out_state->mode.linear.rxbuf += n; - } - /* Transaction data updated.*/ - epcp->out_state->rxcnt += n; - epcp->out_state->rxsize -= n; - epcp->out_state->rxpkts -= 1; - - /* The transaction is completed if the specified number of packets - has been received or the current packet is a short packet.*/ - if ((n < epcp->out_maxsize) || (epcp->out_state->rxpkts == 0)) { - /* Transfer complete, invokes the callback.*/ - _usb_isr_invoke_out_cb(usbp, ep); - } - else { - /* Transfer not complete, there are more packets to receive.*/ - EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID); - } - } - } - istr = STM32_USB->ISTR; - } - - CH_IRQ_EPILOGUE(); -} -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level USB driver initialization. - * - * @notapi - */ -void usb_lld_init(void) { - - /* Driver initialization.*/ - usbObjectInit(&USBD1); -} - -/** - * @brief Configures and activates the USB peripheral. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_start(USBDriver *usbp) { - - if (usbp->state == USB_STOP) { - /* Clock activation.*/ -#if STM32_USB_USE_USB1 - if (&USBD1 == usbp) { - /* USB clock enabled.*/ - rccEnableUSB(FALSE); - /* Powers up the transceiver while holding the USB in reset state.*/ - STM32_USB->CNTR = CNTR_FRES; - /* Enabling the USB IRQ vectors, this also gives enough time to allow - the transceiver power up (1uS).*/ - nvicEnableVector(STM32_USB1_HP_NUMBER, - CORTEX_PRIORITY_MASK(STM32_USB_USB1_HP_IRQ_PRIORITY)); - nvicEnableVector(STM32_USB1_LP_NUMBER, - CORTEX_PRIORITY_MASK(STM32_USB_USB1_LP_IRQ_PRIORITY)); - /* Releases the USB reset.*/ - STM32_USB->CNTR = 0; - } -#endif - /* Reset procedure enforced on driver start.*/ - _usb_reset(usbp); - } - /* Configuration.*/ -} - -/** - * @brief Deactivates the USB peripheral. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_stop(USBDriver *usbp) { - - /* If in ready state then disables the USB clock.*/ - if (usbp->state == USB_STOP) { -#if STM32_USB_USE_USB1 - if (&USBD1 == usbp) { - nvicDisableVector(STM32_USB1_HP_NUMBER); - nvicDisableVector(STM32_USB1_LP_NUMBER); - STM32_USB->CNTR = CNTR_PDWN | CNTR_FRES; - rccDisableUSB(FALSE); - } -#endif - } -} - -/** - * @brief USB low level reset routine. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_reset(USBDriver *usbp) { - uint32_t cntr; - - /* Post reset initialization.*/ - STM32_USB->BTABLE = 0; - STM32_USB->ISTR = 0; - STM32_USB->DADDR = DADDR_EF; - cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM | - CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM; - /* The SOF interrupt is only enabled if a callback is defined for - this service because it is an high rate source.*/ - if (usbp->config->sof_cb != NULL) - cntr |= CNTR_SOFM; - STM32_USB->CNTR = cntr; - - /* Resets the packet memory allocator.*/ - usb_pm_reset(usbp); - - /* EP0 initialization.*/ - usbp->epc[0] = &ep0config; - usb_lld_init_endpoint(usbp, 0); -} - -/** - * @brief Sets the USB address. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_set_address(USBDriver *usbp) { - - STM32_USB->DADDR = (uint32_t)(usbp->address) | DADDR_EF; -} - -/** - * @brief Enables an endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { - uint16_t nblocks, epr; - stm32_usb_descriptor_t *dp; - const USBEndpointConfig *epcp = usbp->epc[ep]; - - /* Setting the endpoint type.*/ - switch (epcp->ep_mode & USB_EP_MODE_TYPE) { - case USB_EP_MODE_TYPE_ISOC: - epr = EPR_EP_TYPE_ISO; - break; - case USB_EP_MODE_TYPE_BULK: - epr = EPR_EP_TYPE_BULK; - break; - case USB_EP_MODE_TYPE_INTR: - epr = EPR_EP_TYPE_INTERRUPT; - break; - default: - epr = EPR_EP_TYPE_CONTROL; - } - - /* IN endpoint initially in NAK mode.*/ - if (epcp->in_cb != NULL) - epr |= EPR_STAT_TX_NAK; - - /* OUT endpoint initially in NAK mode.*/ - if (epcp->out_cb != NULL) - epr |= EPR_STAT_RX_NAK; - - /* EPxR register setup.*/ - EPR_SET(ep, epr | ep); - EPR_TOGGLE(ep, epr); - - /* Endpoint size and address initialization.*/ - if (epcp->out_maxsize > 62) - nblocks = (((((epcp->out_maxsize - 1) | 0x1f) + 1) / 32) << 10) | - 0x8000; - else - nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10; - dp = USB_GET_DESCRIPTOR(ep); - dp->TXCOUNT0 = 0; - dp->RXCOUNT0 = nblocks; - dp->TXADDR0 = usb_pm_alloc(usbp, epcp->in_maxsize); - dp->RXADDR0 = usb_pm_alloc(usbp, epcp->out_maxsize); -} - -/** - * @brief Disables all the active endpoints except the endpoint zero. - * - * @param[in] usbp pointer to the @p USBDriver object - * - * @notapi - */ -void usb_lld_disable_endpoints(USBDriver *usbp) { - unsigned i; - - /* Resets the packet memory allocator.*/ - usb_pm_reset(usbp); - - /* Disabling all endpoints.*/ - for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) { - EPR_TOGGLE(i, 0); - EPR_SET(i, 0); - } -} - -/** - * @brief Returns the status of an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return The endpoint status. - * @retval EP_STATUS_DISABLED The endpoint is not active. - * @retval EP_STATUS_STALLED The endpoint is stalled. - * @retval EP_STATUS_ACTIVE The endpoint is active. - * - * @notapi - */ -usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) { - case EPR_STAT_RX_DIS: - return EP_STATUS_DISABLED; - case EPR_STAT_RX_STALL: - return EP_STATUS_STALLED; - default: - return EP_STATUS_ACTIVE; - } -} - -/** - * @brief Returns the status of an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return The endpoint status. - * @retval EP_STATUS_DISABLED The endpoint is not active. - * @retval EP_STATUS_STALLED The endpoint is stalled. - * @retval EP_STATUS_ACTIVE The endpoint is active. - * - * @notapi - */ -usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) { - case EPR_STAT_TX_DIS: - return EP_STATUS_DISABLED; - case EPR_STAT_TX_STALL: - return EP_STATUS_STALLED; - default: - return EP_STATUS_ACTIVE; - } -} - -/** - * @brief Reads a setup packet from the dedicated packet buffer. - * @details This function must be invoked in the context of the @p setup_cb - * callback in order to read the received setup packet. - * @pre In order to use this function the endpoint must have been - * initialized as a control endpoint. - * @post The endpoint is ready to accept another packet. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @param[out] buf buffer where to copy the packet data - * - * @notapi - */ -void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { - uint32_t *pmap; - stm32_usb_descriptor_t *udp; - uint32_t n; - - (void)usbp; - udp = USB_GET_DESCRIPTOR(ep); - pmap = USB_ADDR2PTR(udp->RXADDR0); - for (n = 0; n < 4; n++) { - *(uint16_t *)buf = (uint16_t)*pmap++; - buf += 2; - } -} - -/** - * @brief Prepares for a receive operation. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep) { - USBOutEndpointState *osp = usbp->epc[ep]->out_state; - - /* Transfer initialization.*/ - if (osp->rxsize == 0) /* Special case for zero sized packets.*/ - osp->rxpkts = 1; - else - osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) / - usbp->epc[ep]->out_maxsize); -} - -/** - * @brief Prepares for a transmit operation. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) { - size_t n; - USBInEndpointState *isp = usbp->epc[ep]->in_state; - - /* Transfer initialization.*/ - n = isp->txsize; - if (n > (size_t)usbp->epc[ep]->in_maxsize) - n = (size_t)usbp->epc[ep]->in_maxsize; - - if (isp->txqueued) - usb_packet_write_from_queue(USB_GET_DESCRIPTOR(ep), - isp->mode.queue.txqueue, n); - else - usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep), - isp->mode.linear.txbuf, n); -} - -/** - * @brief Starts a receive operation on an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID); -} - -/** - * @brief Starts a transmit operation on an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID); -} - -/** - * @brief Brings an OUT endpoint in the stalled state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL); -} - -/** - * @brief Brings an IN endpoint in the stalled state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL); -} - -/** - * @brief Brings an OUT endpoint in the active state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - /* Makes sure to not put to NAK an endpoint that is already - transferring.*/ - if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID) - EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK); -} - -/** - * @brief Brings an IN endpoint in the active state. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) { - - (void)usbp; - - /* Makes sure to not put to NAK an endpoint that is already - transferring.*/ - if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID) - EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK); -} - -#endif /* HAL_USE_USB */ - -/** @} */ diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.h b/os/hal/platforms/STM32/USBv1/usb_lld.h deleted file mode 100644 index a0092a334..000000000 --- a/os/hal/platforms/STM32/USBv1/usb_lld.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file STM32/USBv1/usb_lld.h - * @brief STM32 USB subsystem low level driver header. - * - * @addtogroup USB - * @{ - */ - -#ifndef _USB_LLD_H_ -#define _USB_LLD_H_ - -#if HAL_USE_USB || defined(__DOXYGEN__) - -#include "stm32_usb.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Maximum endpoint address. - */ -#define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER - -/** - * @brief This device requires the address change after the status packet. - */ -#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @brief USB1 driver enable switch. - * @details If set to @p TRUE the support for USB1 is included. - * @note The default is @p TRUE. - */ -#if !defined(STM32_USB_USE_USB1) || defined(__DOXYGEN__) -#define STM32_USB_USE_USB1 FALSE -#endif - -/** - * @brief Enables the USB device low power mode on suspend. - */ -#if !defined(STM32_USB_LOW_POWER_ON_SUSPEND) || defined(__DOXYGEN__) -#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE -#endif - -/** - * @brief USB1 interrupt priority level setting. - */ -#if !defined(STM32_USB_USB1_HP_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_USB_USB1_HP_IRQ_PRIORITY 13 -#endif - -/** - * @brief USB1 interrupt priority level setting. - */ -#if !defined(STM32_USB_USB1_LP_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_USB_USB1_LP_IRQ_PRIORITY 14 -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if STM32_USB_USE_USB1 && !STM32_HAS_USB -#error "USB not present in the selected device" -#endif - -#if !STM32_USB_USE_USB1 -#error "USB driver activated but no USB peripheral assigned" -#endif - -#if STM32_USB_USE_USB1 && \ - !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_USB_USB1_HP_IRQ_PRIORITY) -#error "Invalid IRQ priority assigned to USB HP" -#endif - -#if STM32_USB_USE_USB1 && \ - !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_USB_USB1_LP_IRQ_PRIORITY) -#error "Invalid IRQ priority assigned to USB LP" -#endif - -#if STM32_USBCLK != 48000000 -#error "the USB driver requires a 48MHz clock" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of an IN endpoint state structure. - */ -typedef struct { - /** - * @brief Buffer mode, queue or linear. - */ - bool_t txqueued; - /** - * @brief Requested transmit transfer size. - */ - size_t txsize; - /** - * @brief Transmitted bytes so far. - */ - size_t txcnt; - union { - struct { - /** - * @brief Pointer to the transmission linear buffer. - */ - const uint8_t *txbuf; - } linear; - struct { - /** - * @brief Pointer to the output queue. - */ - OutputQueue *txqueue; - } queue; - /* End of the mandatory fields.*/ - } mode; -} USBInEndpointState; - -/** - * @brief Type of an OUT endpoint state structure. - */ -typedef struct { - /** - * @brief Buffer mode, queue or linear. - */ - bool_t rxqueued; - /** - * @brief Requested receive transfer size. - */ - size_t rxsize; - /** - * @brief Received bytes so far. - */ - size_t rxcnt; - union { - struct { - /** - * @brief Pointer to the receive linear buffer. - */ - uint8_t *rxbuf; - } linear; - struct { - /** - * @brief Pointer to the input queue. - */ - InputQueue *rxqueue; - } queue; - } mode; - /* End of the mandatory fields.*/ - /** - * @brief Number of packets to receive. - */ - uint16_t rxpkts; -} USBOutEndpointState; - -/** - * @brief Type of an USB endpoint configuration structure. - * @note Platform specific restrictions may apply to endpoints. - */ -typedef struct { - /** - * @brief Type and mode of the endpoint. - */ - uint32_t ep_mode; - /** - * @brief Setup packet notification callback. - * @details This callback is invoked when a setup packet has been - * received. - * @post The application must immediately call @p usbReadPacket() in - * order to access the received packet. - * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL - * endpoints, it should be set to @p NULL for other endpoint - * types. - */ - usbepcallback_t setup_cb; - /** - * @brief IN endpoint notification callback. - * @details This field must be set to @p NULL if the IN endpoint is not - * used. - */ - usbepcallback_t in_cb; - /** - * @brief OUT endpoint notification callback. - * @details This field must be set to @p NULL if the OUT endpoint is not - * used. - */ - usbepcallback_t out_cb; - /** - * @brief IN endpoint maximum packet size. - * @details This field must be set to zero if the IN endpoint is not - * used. - */ - uint16_t in_maxsize; - /** - * @brief OUT endpoint maximum packet size. - * @details This field must be set to zero if the OUT endpoint is not - * used. - */ - uint16_t out_maxsize; - /** - * @brief @p USBEndpointState associated to the IN endpoint. - * @details This structure maintains the state of the IN endpoint. - */ - USBInEndpointState *in_state; - /** - * @brief @p USBEndpointState associated to the OUT endpoint. - * @details This structure maintains the state of the OUT endpoint. - */ - USBOutEndpointState *out_state; - /* End of the mandatory fields.*/ - /** - * @brief Reserved field, not currently used. - * @note Initialize this field to 1 in order to be forward compatible. - */ - uint16_t ep_buffers; - /** - * @brief Pointer to a buffer for setup packets. - * @details Setup packets require a dedicated 8-bytes buffer, set this - * field to @p NULL for non-control endpoints. - */ - uint8_t *setup_buf; -} USBEndpointConfig; - -/** - * @brief Type of an USB driver configuration structure. - */ -typedef struct { - /** - * @brief USB events callback. - * @details This callback is invoked when an USB driver event is registered. - */ - usbeventcb_t event_cb; - /** - * @brief Device GET_DESCRIPTOR request callback. - * @note This callback is mandatory and cannot be set to @p NULL. - */ - usbgetdescriptor_t get_descriptor_cb; - /** - * @brief Requests hook callback. - * @details This hook allows to be notified of standard requests or to - * handle non standard requests. - */ - usbreqhandler_t requests_hook_cb; - /** - * @brief Start Of Frame callback. - */ - usbcallback_t sof_cb; - /* End of the mandatory fields.*/ -} USBConfig; - -/** - * @brief Structure representing an USB driver. - */ -struct USBDriver { - /** - * @brief Driver state. - */ - usbstate_t state; - /** - * @brief Current configuration data. - */ - const USBConfig *config; - /** - * @brief Bit map of the transmitting IN endpoints. - */ - uint16_t transmitting; - /** - * @brief Bit map of the receiving OUT endpoints. - */ - uint16_t receiving; - /** - * @brief Active endpoints configurations. - */ - const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1]; - /** - * @brief Fields available to user, it can be used to associate an - * application-defined handler to an IN endpoint. - * @note The base index is one, the endpoint zero does not have a - * reserved element in this array. - */ - void *in_params[USB_MAX_ENDPOINTS]; - /** - * @brief Fields available to user, it can be used to associate an - * application-defined handler to an OUT endpoint. - * @note The base index is one, the endpoint zero does not have a - * reserved element in this array. - */ - void *out_params[USB_MAX_ENDPOINTS]; - /** - * @brief Endpoint 0 state. - */ - usbep0state_t ep0state; - /** - * @brief Next position in the buffer to be transferred through endpoint 0. - */ - uint8_t *ep0next; - /** - * @brief Number of bytes yet to be transferred through endpoint 0. - */ - size_t ep0n; - /** - * @brief Endpoint 0 end transaction callback. - */ - usbcallback_t ep0endcb; - /** - * @brief Setup packet buffer. - */ - uint8_t setup[8]; - /** - * @brief Current USB device status. - */ - uint16_t status; - /** - * @brief Assigned USB address. - */ - uint8_t address; - /** - * @brief Current USB device configuration. - */ - uint8_t configuration; -#if defined(USB_DRIVER_EXT_FIELDS) - USB_DRIVER_EXT_FIELDS -#endif - /* End of the mandatory fields.*/ - /** - * @brief Pointer to the next address in the packet memory. - */ - uint32_t pmnext; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Returns the current frame number. - * - * @param[in] usbp pointer to the @p USBDriver object - * @return The current frame number. - * - * @notapi - */ -#define usb_lld_get_frame_number(usbp) (STM32_USB->FNR & FNR_FN_MASK) - -/** - * @brief Returns the exact size of a receive transaction. - * @details The received size can be different from the size specified in - * @p usbStartReceiveI() because the last packet could have a size - * different from the expected one. - * @pre The OUT endpoint must have been configured in transaction mode - * in order to use this function. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return Received data size. - * - * @notapi - */ -#define usb_lld_get_transaction_size(usbp, ep) \ - ((usbp)->epc[ep]->out_state->rxcnt) - -/** - * @brief Returns the exact size of a received packet. - * @pre The OUT endpoint must have been configured in packet mode - * in order to use this function. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * @return Received data size. - * - * @notapi - */ -#define usb_lld_get_packet_size(usbp, ep) \ - ((size_t)USB_GET_DESCRIPTOR(ep)->RXCOUNT & RXCOUNT_COUNT_MASK) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if STM32_USB_USE_USB1 && !defined(__DOXYGEN__) -extern USBDriver USBD1; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void usb_lld_init(void); - void usb_lld_start(USBDriver *usbp); - void usb_lld_stop(USBDriver *usbp); - void usb_lld_reset(USBDriver *usbp); - void usb_lld_set_address(USBDriver *usbp); - void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep); - void usb_lld_disable_endpoints(USBDriver *usbp); - usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep); - usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep); - void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf); - void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep); - void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep); - void usb_lld_start_out(USBDriver *usbp, usbep_t ep); - void usb_lld_start_in(USBDriver *usbp, usbep_t ep); - void usb_lld_stall_out(USBDriver *usbp, usbep_t ep); - void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); - void usb_lld_clear_out(USBDriver *usbp, usbep_t ep); - void usb_lld_clear_in(USBDriver *usbp, usbep_t ep); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_USB */ - -#endif /* _USB_LLD_H_ */ - -/** @} */ -- cgit v1.2.3