diff --git a/os/hal/ports/RP/LLD/USBDv1/driver.mk b/os/hal/ports/RP/LLD/USBDv1/driver.mk new file mode 100644 index 00000000..909db629 --- /dev/null +++ b/os/hal/ports/RP/LLD/USBDv1/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.c +endif +else +PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.c +endif + +PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/RP/LLD/USBDv1 diff --git a/os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.c b/os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.c new file mode 100644 index 00000000..4e8f6a02 --- /dev/null +++ b/os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.c @@ -0,0 +1,939 @@ +/* + ChibiOS - Copyright (C) 2006..2018 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 hal_usb_lld.c + * @brief PLATFORM USB subsystem low level driver source. + * + * @addtogroup USB + * @{ + */ + +#include + +#include "hal.h" + +#include "hal_usb_lld.h" + +#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__) + +#include "mcuconf.h" + +#ifdef USB_DEBUG + +#include "rp_fifo.h" + +#define CMD_RESET 0x00 +#define CMD_SETUP 0x01 +#define CMD_READ_SETUP 0x02 +#define CMD_SET_ADDR 0x03 +#define CMD_START_IN 0x04 +#define CMD_START_OUT 0x05 +#define CMD_BUFF_STATUS 0x06 +#define CMD_EP_DONE 0x07 +#define CMD_DATA_ERROR 0x09 + +void cmd_send(uint8_t cmd, uint8_t length) { + uint32_t data = (cmd << 24) | (length << 16); + fifoBlockingWrite(data); +} + +void data_send(uint32_t data) { + fifoBlockingWrite(data); +} +#endif // USB_DEBUG + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Get endpoint control register. + */ +#define EP_CTRL(ep) (USB_DPSRAM->EPCTRL[ep - 1]) +/** + * @brief Get buffer control register for endpoint. + */ +#define BUF_CTRL(ep) (USB_DPSRAM->BUFCTRL[ep]) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief USB1 driver identifier. + */ +#if (RP_USB_USE_USBD1 == TRUE) || 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 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, +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Buffer mode for isochronous in buffer control register. + */ +static uint16_t usb_isochronous_buffer_mode(uint16_t size) { + switch (size) { + case 128: + return 0; + case 256: + return 1; + case 512: + return 2; + case 1024: + return 3; + default: + return 0; + } +} + +/** + * @brief Calculate isochronous buffer size in valid step. + * @details Valid buffer size is one of 128, 256, 512 or 1024. + */ +static uint16_t usb_isochronous_buffer_size(uint16_t max_size) { + uint16_t size; + + /* Double buffer offset must be one of 128, 256, 512 or 1024. */ + size = ((max_size - 1) / 128 + 1) * 128; + if (size == 384) { + size = 512; + } else if (size == 640 || size == 768 || size > 1024) { + size = 1024; + } + return size; +} + +/** + * @brief Calculate next offset for buffer data, 64 bytes aligned. + */ +static uint16_t usb_buffer_next_offset(USBDriver *usbp, uint16_t size, bool is_double) { + uint32_t offset; + + offset = usbp->noffset; + usbp->noffset += is_double ? size * 2 : size; + + return offset; +} + +/** + * @brief Reset endpoint 0. + */ +static void reset_ep0(USBDriver *usbp) { + usbp->epc[0]->in_state->next_pid = 1U; + usbp->epc[0]->in_state->active = false; + usbp->epc[0]->in_state->stalled = false; +} + +/** + * @brief Reset specified endpoint. + */ +static void reset_endpoint(USBDriver *usbp, usbep_t ep, bool is_in) { + const USBEndpointConfig *epcp = usbp->epc[ep]; + + if (is_in) { + USBInEndpointState *in_state = epcp->in_state; + if (in_state) { + in_state->active = false; + in_state->stalled = false; + in_state->next_pid = 0U; + } + } else { + USBOutEndpointState *out_state = epcp->out_state; + if (out_state) { + out_state->active = false; + out_state->stalled = false; + out_state->next_pid = 0U; + } + } +} + +/** + * @brief Prepare buffer for receiving data. + */ +uint32_t usb_prepare_out_ep_buffer(USBDriver *usbp, usbep_t ep, uint8_t buffer_index) { + uint16_t buf_len; + uint32_t buf_ctrl = 0; + const USBEndpointConfig *epcp = usbp->epc[ep]; + USBOutEndpointState *iesp = usbp->epc[ep]->out_state; + + buf_len = epcp->out_maxsize < iesp->rxsize ? epcp->out_maxsize : iesp->rxsize; + + if (!(buf_len == 0 && buffer_index == 1)) { + if ((iesp->rxpkts == 1 && buffer_index == 0) || + (iesp->rxpkts == 2 && buffer_index == 1)) { + /* Last buffer */ + buf_ctrl |= USB_BUFFER_BUFFER0_LAST; + } + /* PID */ + buf_ctrl |= iesp->next_pid ? USB_BUFFER_BUFFER1_DATA_PID : USB_BUFFER_BUFFER0_DATA_PID; + iesp->next_pid ^= 1U; + + buf_ctrl |= USB_BUFFER_BUFFER0_AVAILABLE | + buf_len; + + iesp->active = true; + if (buffer_index) { + buf_ctrl = buf_ctrl << 16; + } + } + + return buf_ctrl; +} + +/** + * @brief Prepare for receiving data from host. + */ +static void usb_prepare_out_ep(USBDriver *usbp, usbep_t ep) { + uint32_t buf_ctrl; + uint32_t ep_ctrl; + + if (ep == 0) { + ep_ctrl = USB->SIECTRL; + } else { + ep_ctrl = EP_CTRL(ep).OUT; + } + + /* Fill first buffer */ + buf_ctrl = usb_prepare_out_ep_buffer(usbp, ep, 0); + + /* To avoid short packet, we use single buffered here. */ + /* Single buffered */ + ep_ctrl &= ~(USB_EP_BUFFER_DOUBLE | USB_EP_BUFFER_IRQ_DOUBLE_EN); + ep_ctrl |= USB_EP_BUFFER_IRQ_EN; + + if (ep == 0) { + USB->SIECTRL = ep_ctrl; + } else { + EP_CTRL(ep).OUT = ep_ctrl; + } + + BUF_CTRL(ep).OUT |= buf_ctrl; +} + +/** + * @brief Prepare buffer for sending data. + */ +static uint32_t usb_prepare_in_ep_buffer(USBDriver *usbp, usbep_t ep, uint8_t buffer_index) { + uint8_t *buff; + uint16_t buf_len; + uint32_t buf_ctrl = 0; + const USBEndpointConfig *epcp = usbp->epc[ep]; + USBInEndpointState *iesp = usbp->epc[ep]->in_state; + + /* txsize - txlast gives size of data to be sent but not yet in the buffer */ + buf_len = epcp->in_maxsize < iesp->txsize - iesp->txlast ? + epcp->in_maxsize : iesp->txsize - iesp->txlast; + + if (buf_len > 0) { + iesp->txlast += buf_len; + + if (iesp->txsize <= iesp->txlast) { + /* Last buffer */ + buf_ctrl |= USB_BUFFER_BUFFER0_LAST; + } + /* PID */ + buf_ctrl |= iesp->next_pid ? USB_BUFFER_BUFFER1_DATA_PID : USB_BUFFER_BUFFER0_DATA_PID; + iesp->next_pid ^= 1U; + + /* Copy data into hardware buffer */ + buff = (uint8_t*)iesp->hw_buf + (buffer_index == 0 ? 0 : iesp->buf_size); + memcpy((void *)buff, (void *)iesp->txbuf, buf_len); + iesp->txbuf += buf_len; + + buf_ctrl |= USB_BUFFER_BUFFER0_FULL | + USB_BUFFER_BUFFER0_AVAILABLE | + buf_len; + + iesp->active = true; + if (buffer_index) { + buf_ctrl = buf_ctrl << 16; + } + } + + return buf_ctrl; +} + +/** + * @brief Prepare endpoint for sending data. + */ +static void usb_prepare_in_ep(USBDriver *usbp, usbep_t ep) { + uint32_t buf_ctrl; + uint32_t ep_ctrl; + USBInEndpointState *iesp = usbp->epc[ep]->in_state; + + if (ep == 0) { + ep_ctrl = USB->SIECTRL; + } else { + ep_ctrl = EP_CTRL(ep).IN; + } + + /* Fill first buffer */ + buf_ctrl = usb_prepare_in_ep_buffer(usbp, ep, 0); + + /* Second buffer if required */ + /* iesp->txsize - iesp->txlast gives size even not in buffer */ + if (iesp->txsize - iesp->txlast > 0) { + buf_ctrl |= usb_prepare_in_ep_buffer(usbp, ep, 1); + } + + if (buf_ctrl & USB_BUFFER_BUFFER1_AVAILABLE) { + /* Double buffered */ + ep_ctrl &= ~USB_EP_BUFFER_IRQ_EN; + ep_ctrl |= USB_EP_BUFFER_DOUBLE | USB_EP_BUFFER_IRQ_DOUBLE_EN; + } else { + /* Single buffered */ + ep_ctrl &= ~(USB_EP_BUFFER_DOUBLE | USB_EP_BUFFER_IRQ_DOUBLE_EN); + ep_ctrl |= USB_EP_BUFFER_IRQ_EN; + } + + if (ep == 0) { + USB->SIECTRL = ep_ctrl; + } else { + EP_CTRL(ep).IN = ep_ctrl; + } + + BUF_CTRL(ep).IN |= buf_ctrl; +} + +/** + * @brief Work on an endpoint after transfer. + */ +static void usb_serve_endpoint(USBDriver *usbp, usbep_t ep, bool is_in) { + const USBEndpointConfig *epcp = usbp->epc[ep]; + USBOutEndpointState *oesp; + USBInEndpointState *iesp; + uint16_t n; + + if (is_in) { + /* IN endpoint */ + iesp = usbp->epc[ep]->in_state; + + /* txlast is size sent + size of last buffer */ + iesp->txcnt = iesp->txlast; + n = iesp->txsize - iesp->txcnt; + if (n > 0) { + /* Transfer not completed, there are more packets to send. */ + usb_prepare_in_ep(usbp, ep); + } else { +#ifdef USB_DEBUG + cmd_send(CMD_EP_DONE, 0); +#endif + /* Transfer complete */ + _usb_isr_invoke_in_cb(usbp, ep); + + reset_endpoint(usbp, ep, true); + } + } else { + /* OUT endpoint */ + oesp = usbp->epc[ep]->out_state; + + /* Length received */ + n = BUF_CTRL(ep).OUT & USB_BUFFER_BUFFER0_TRANS_LENGTH_Msk; + + /* Copy received data into user buffer */ + memcpy((void *)oesp->rxbuf, (void *)oesp->hw_buf, n); + oesp->rxbuf += n; + oesp->rxcnt += n; + oesp->rxsize -= n; + + oesp->rxpkts -= 1; + + /* Short packet or all packetes have been received. */ + if (oesp->rxpkts <= 0 || n <= epcp->out_maxsize) { +#ifdef USB_DEBUG + //cmd_send(CMD_EP_DONE, 0); +#endif + /* Transifer complete */ + _usb_isr_invoke_out_cb(usbp, ep); + + reset_endpoint(usbp, ep, false); + } else { + /* Receive remained data */ + usb_prepare_out_ep(usbp, ep); + } + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers and threads. */ +/*===========================================================================*/ + +#if RP_USB_USE_USBD1 || defined(__DOXYGEN__) + +/** + * @brief USB low priority interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) { + uint32_t ints; + USBDriver *usbp = &USBD1; + + OSAL_IRQ_PROLOGUE(); + + ints = USB->INTS; + + /* USB setup packet handling. */ + if (ints & USB_INTS_SETUP_REQ) { +#ifdef USB_DEBUG + cmd_send(CMD_SETUP, 0); +#endif + USB->CLR.SIESTATUS = USB_SIE_STATUS_SETUP_REC; + _usb_isr_invoke_setup_cb(usbp, 0); + + reset_ep0(usbp); + } + + /* USB bus reset condition handling. */ + if (ints & USB_INTS_BUS_RESET) { +#ifdef USB_DEBUG + //cmd_send(CMD_RESET, 0); +#endif + USB->CLR.SIESTATUS = USB_SIE_STATUS_BUS_RESET; + + /* Reset device address. */ + USB->DEVADDRCTRL = 0; + + /* Reset all endpoint. */ + /* + for (int i = 1; i < USB_ENDOPOINTS_NUMBER; i++) { + reset_endpoint(usbp, i, true); + reset_endpoint(usbp, i, false); + } + */ + _usb_reset(usbp); + } + + /* USB bus SUSPEND condition handling.*/ + if (ints & USB_INTS_DEV_SUSPEND) { + USB->CLR.SIESTATUS = USB_SIE_STATUS_SUSPENDED; + + _usb_suspend(usbp); + } + + /* Resume condition handling */ + if (ints & USB_INTS_DEV_RESUME_FROM_HOST) { + USB->CLR.SIESTATUS = USB_SIE_STATUS_RESUME; + + _usb_wakeup(usbp); + } + + /* SOF handling.*/ + if (ints & USB_INTS_DEV_SOF) { + _usb_isr_invoke_sof_cb(usbp); + + /* Clear SOF flag by reading SOF_RD */ + (void)USB->SOFRD; + } + + /* Endpoint events handling.*/ + if (ints & USB_INTS_BUFF_STATUS) { +#ifdef USB_DEBUG + //cmd_send(CMD_BUFF_STATUS, 0); +#endif + uint32_t buf_status = USB->BUFSTATUS; + uint32_t bit = 1U; + for (uint8_t i = 0; buf_status && i < 32; i++) { + if (buf_status & bit) { + /* Clear flag */ + USB->SET.BUFSTATUS = bit; + + /* Finish on the endpoint or transfer remained data */ + usb_serve_endpoint(&USBD1, i >> 1U, (i & 1U) == 0); + + buf_status &= ~bit; + } + bit <<= 1U; + } + } + + if (ints & USB_INTE_ERROR_DATA_SEQ) { +#ifdef USB_DEBUG + cmd_send(CMD_DATA_ERROR, 0); +#endif + USB->CLR.SIESTATUS = USB_SIE_STATUS_DATA_SEQ_ERROR; + } + + OSAL_IRQ_EPILOGUE(); +} + +#endif /* RP_USB_USE_USBD1 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level USB driver initialization. + * + * @notapi + */ +void usb_lld_init(void) { +#if RP_USB_USE_USBD1 == TRUE + /* Driver initialization.*/ + usbObjectInit(&USBD1); + + /* Reset buffer offset. */ + USBD1.noffset = 0; +#endif +} + +/** + * @brief Configures and activates the USB peripheral. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_start(USBDriver *usbp) { +#if RP_USB_USE_USBD1 == TRUE + if (&USBD1 == usbp) { + if (usbp->state == USB_STOP) { + /* Reset usb controller */ + hal_lld_peripheral_reset(RESETS_ALLREG_USBCTRL); + hal_lld_peripheral_unreset(RESETS_ALLREG_USBCTRL); + + /* Clear any previous state in dpram */ + memset(USB_DPSRAM, 0, sizeof(*USB_DPSRAM)); + + /* Mux the controller to the onboard usb phy */ + USB->MUXING = USB_USB_MUXING_SOFTCON | USB_USB_MUXING_TO_PHY; + +#if RP_USB_FORCE_VBUS_DETECT == TRUE + /* Force VBUS detect so the device thinks it is plugged into a host */ + USB->PWR = USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN | USB_USB_PWR_VBUS_DETECT; +#else +#ifdef usb_vbus_detect + /* If VBUS is detected by pin without USB VBUS DET pin, + * define usb_vbus_detect which returns true if VBUS is enabled. + */ + if (usb_vbus_detect) { + USB->PWR = USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN | USB_USB_PWR_VBUS_DETECT; + } +#endif /* usb_vbus_detect */ +#endif /* RP_USB_FORCE_VBUS_DETECT */ + + /* Reset procedure enforced on driver start.*/ + usb_lld_reset(usbp); + + /* Enable the USB controller in device mode. */ + USB->MAINCTRL = USB_MAIN_CTRL_CONTROLLER_EN; + + /* Enable an interrupt per EP0 transaction */ + USB->SIECTRL = USB_SIE_CTRL_EP0_INT_1BUF; + + /* Enable interrupts */ + USB->INTE = USB_INTE_SETUP_REQ | + USB_INTE_DEV_RESUME_FROM_HOST | + USB_INTE_DEV_SUSPEND | + USB_INTE_BUS_RESET | + USB_INTE_BUFF_STATUS | + USB_INTE_ERROR_DATA_SEQ; +#if RP_USB_USE_SOF_INTR == TRUE + USB->INTE |= USB_INTE_DEV_SOF; +#endif /* RP_USB_USE_SOF_INTR */ + + /* Enable USB interrupt. */ + nvicEnableVector(RP_USBCTRL_IRQ_NUMBER, 2); + + /* Present full speed device by enabling pull up on DP */ + USB->SET.SIECTRL = USB_SIE_CTRL_PULLUP_EN; + } + } +#endif +} + +/** + * @brief Deactivates the USB peripheral. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_stop(USBDriver *usbp) { +#if RP_USB_USE_USBD1 == TRUE + if (&USBD1 == usbp) { + if (usbp->state == USB_READY) { + /* Disable interrupt */ + USB->INTE = 0; + + /* Disable controller */ + USB->CLR.MAINCTRL = USB_MAIN_CTRL_CONTROLLER_EN; + } + } +#endif +} + +/** + * @brief USB low level reset routine. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void usb_lld_reset(USBDriver *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) { +#ifdef USB_DEBUG + cmd_send(CMD_SET_ADDR, 0); +#endif + USB->DEVADDRCTRL |= USB_ADDR_ENDP0_ADDRESS_Msk & (usbp->address << USB_ADDR_ENDP0_ADDRESS_Pos); + + reset_ep0(usbp); +} + +/** + * @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) { + (void)usbp; + + uint16_t buf_size; + uint16_t buf_offset; + uint32_t buf_ctrl; + const USBEndpointConfig *epcp = usbp->epc[ep]; + + if (ep == 0) { + epcp->in_state->hw_buf = (uint8_t*)&USB_DPSRAM->EP0BUF0; + epcp->in_state->buf_size = 64; + USB->SET.SIECTRL = USB_SIE_CTRL_EP0_DOUBLE_BUF; + epcp->in_state->next_pid = 1U; + epcp->in_state->active = false; + epcp->in_state->stalled = false; + return; + } + + if (epcp->in_state) { + buf_ctrl = 0; + epcp->in_state->active = false; + epcp->in_state->stalled = false; + epcp->in_state->next_pid = 0U; + + if (epcp->ep_mode == USB_EP_MODE_TYPE_ISOC) { + buf_size = usb_isochronous_buffer_size(epcp->in_maxsize); + buf_ctrl |= usb_isochronous_buffer_mode(buf_size) << USB_BUFFER_DOUBLE_BUFFER_OFFSET_Pos; + } else { + buf_size = 64; + } + buf_offset = usb_buffer_next_offset(usbp, buf_size, true); + epcp->in_state->hw_buf = (uint8_t*)&USB_DPSRAM->DATA[buf_offset]; + epcp->in_state->buf_size = buf_size; + + EP_CTRL(ep).IN |= USB_EP_EN | + (epcp->ep_mode << USB_EP_TYPE_Pos) | + buf_offset; + BUF_CTRL(ep).IN |= buf_ctrl; + } + + if (epcp->out_state) { + buf_ctrl = 0; + epcp->out_state->active = false; + epcp->out_state->stalled = false; + epcp->out_state->next_pid = 0U; + + if (epcp->ep_mode == USB_EP_MODE_TYPE_ISOC) { + buf_size = usb_isochronous_buffer_size(epcp->in_maxsize); + buf_ctrl |= usb_isochronous_buffer_mode(buf_size) << USB_BUFFER_DOUBLE_BUFFER_OFFSET_Pos; + } else { + buf_size = 64; + } + buf_offset = usb_buffer_next_offset(usbp, buf_offset, false); + epcp->out_state->hw_buf = (uint8_t*)&USB_DPSRAM->DATA[buf_offset]; + epcp->out_state->buf_size = buf_size; + + EP_CTRL(ep).OUT |= USB_EP_EN | + (epcp->ep_mode << USB_EP_TYPE_Pos) | + buf_offset; + BUF_CTRL(ep).OUT |= buf_ctrl; + } +} + +/** + * @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) { + uint8_t ep; + + /* Ignore zero */ + for (ep = 1; ep <= USB_ENDOPOINTS_NUMBER; ep++) { + usbp->epc[ep]->in_state->active = false; + usbp->epc[ep]->in_state->stalled = false; + usbp->epc[ep]->in_state->next_pid = 0; + EP_CTRL(ep).IN &= ~USB_EP_EN; + + usbp->epc[ep]->out_state->active = false; + usbp->epc[ep]->out_state->stalled = false; + usbp->epc[ep]->out_state->next_pid = 0; + EP_CTRL(ep).OUT &= ~USB_EP_EN; + } +} + +/** + * @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; + USBOutEndpointState *out_state = usbp->epc[ep]->out_state; + + if (out_state) { + if (out_state->active) { + return EP_STATUS_ACTIVE; + } else if (out_state->stalled) { + return EP_STATUS_STALLED; + } + } + return EP_STATUS_DISABLED; +} + +/** + * @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; + USBInEndpointState *in_state = usbp->epc[ep]->in_state; + + if (in_state) { + if (in_state->active) { + return EP_STATUS_ACTIVE; + } else if (in_state->stalled) { + return EP_STATUS_STALLED; + } + } + return EP_STATUS_DISABLED; +} + +/** + * @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) { + (void)usbp; + (void)ep; +#ifdef USB_DEBUG + cmd_send(CMD_READ_SETUP, 2); + data_send(*((uint32_t*)USB_DPSRAM->SETUPPACKET)); + data_send(*((uint32_t*)(USB_DPSRAM->SETUPPACKET + 4))); +#endif + /* Copy data from hardware buffer to user buffer */ + memcpy((void *)buf, (void *)USB_DPSRAM->SETUPPACKET, 8); +} + +/** + * @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; + USBOutEndpointState *oesp = usbp->epc[ep]->out_state; +#ifdef USB_DEBUG + //cmd_send(CMD_START_OUT, 0); +#endif + /* Transfer initialization.*/ + if (oesp->rxsize == 0) { + /* Special case for zero sized packets.*/ + oesp->rxpkts = 1; + } else { + oesp->rxpkts = (uint16_t)((oesp->rxsize + usbp->epc[ep]->out_maxsize - 1) / + usbp->epc[ep]->out_maxsize); + } + + /* Prepare OUT endpoint. */ + usb_prepare_out_ep(usbp, ep); +} + +/** + * @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) { + USBInEndpointState *iesp = usbp->epc[ep]->in_state; +#ifdef USB_DEBUG + cmd_send(CMD_START_IN, 0); +#endif + iesp->txlast = 0; + + /* Prepare IN endpoint. */ + usb_prepare_in_ep(usbp, ep); +} + +/** + * @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; + + if (ep == 0) { + USB->SET.EPSTALLARM = USB_EP_STALL_ARM_EP0_OUT; + } + BUF_CTRL(ep).OUT |= USB_BUFFER_STALL; + usbp->epc[ep]->out_state->stalled = true; +} + +/** + * @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; + + if (ep == 0) { + USB->SET.EPSTALLARM = USB_EP_STALL_ARM_EP0_IN; + } + BUF_CTRL(ep).IN |= USB_BUFFER_STALL; + usbp->epc[ep]->in_state->stalled = true; +} + +/** + * @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; + + if (ep == 0) { + USB->CLR.EPSTALLARM = USB_EP_STALL_ARM_EP0_OUT; + } + BUF_CTRL(ep).OUT &= ~USB_BUFFER_STALL; + usbp->epc[ep]->out_state->stalled = false; +} + +/** + * @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; + + if (ep == 0) { + USB->CLR.EPSTALLARM = USB_EP_STALL_ARM_EP0_IN; + } + BUF_CTRL(ep).IN &= ~USB_BUFFER_STALL; + usbp->epc[ep]->in_state->stalled = false; +} + +#endif /* HAL_USE_USB == TRUE */ + +/** @} */ diff --git a/os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.h b/os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.h new file mode 100644 index 00000000..25374d87 --- /dev/null +++ b/os/hal/ports/RP/LLD/USBDv1/hal_usb_lld.h @@ -0,0 +1,429 @@ +/* + ChibiOS - Copyright (C) 2006..2018 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 USBv1/hal_usb_lld.h + * @brief RP2040 USB subsystem low level driver header. + * + * @addtogroup USB + * @{ + */ + +#ifndef HAL_USB_LLD_H +#define HAL_USB_LLD_H + +#if HAL_USE_USB || defined(__DOXYGEN__) + +#include "rp2040_usb.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +#if !defined(RP_USB_USE_USBD1) +#error "RP_USB_USE_USBD1 not defined in registry" +#endif + +/** + * @brief Maximum endpoint address. + */ +#define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER + +/** + * @brief Status stage handling method. + */ +#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW + +/** + * @brief Address ack handling + */ +#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_HW + +/** + * @brief This device requires the address change after the status packet. + */ +#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of an IN endpoint state structure. + */ +typedef struct { + /** + * @brief Requested transmit transfer size. + */ + size_t txsize; + /** + * @brief Transmitted bytes so far. + */ + size_t txcnt; + /** + * @brief Pointer to the transmission linear buffer. + */ + const uint8_t *txbuf; +#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + thread_reference_t thread; +#endif + /* End of the mandatory fields.*/ + /** + * @brief Last received size of data. + */ + size_t txlast; + /** + * @brief Endpoint is active. + */ + bool active; + /** + * @brief Endpoint is stalled. + */ + bool stalled; + /** + * @brief Data PID used by next transfer. + */ + uint8_t next_pid; + /** + * @brief Buffer in the hardware. + */ + uint8_t *hw_buf; + /** + * @brief Buffer size. + */ + uint16_t buf_size; +} USBInEndpointState; + +/** + * @brief Type of an OUT endpoint state structure. + */ +typedef struct { + /** + * @brief Requested receive transfer size. + */ + size_t rxsize; + /** + * @brief Received bytes so far. + */ + size_t rxcnt; + /** + * @brief Pointer to the receive linear buffer. + */ + uint8_t *rxbuf; +#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + thread_reference_t thread; +#endif + /* End of the mandatory fields.*/ + /** + * @brief Number of packets to receive. + */ + uint16_t rxpkts; + /** + * @brief Endpoint is active. + */ + bool active; + /** + * @brief Endpoint is stalled. + */ + bool stalled; + /** + * @brief Data PID used by next transfer. + */ + uint8_t next_pid; + /** + * @brief Buffer in the hardware. + */ + uint8_t *hw_buf; + /** + * @brief Buffer size. + */ + uint16_t buf_size; +} 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 callback is not required. + */ + usbepcallback_t in_cb; + /** + * @brief OUT endpoint notification callback. + * @details This field must be set to @p NULL if callback is not required. + */ + 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 field must be set to @p NULL if the IN endpoint is not + * used. + */ + USBInEndpointState *in_state; + /** + * @brief @p USBEndpointState associated to the OUT endpoint. + * @details This field must be set to @p NULL if the OUT endpoint is not + * used. + */ + USBOutEndpointState *out_state; + /* End of the mandatory fields.*/ +} 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; + /** + * @brief State of the driver when a suspend happened. + */ + usbstate_t saved_state; +#if defined(USB_DRIVER_EXT_FIELDS) + USB_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Next offset of buffer. + */ + uint16_t noffset; +}; + +/*===========================================================================*/ +/* 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) \ + (USB->SOFRD & USB_SOF_RD_COUNT_Msk) + +/** + * @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 Connects the USB device. + * + * @api + */ +#if !defined(usb_lld_connect_bus) +#define usb_lld_connect_bus(usbp) \ + do { \ + USB->SET.SIECTRL = USB_SIE_CTRL_PULLUP_EN; \ + } while (false) +#endif + +/** + * @brief Disconnect the USB device. + * + * @api + */ +#if !defined(usb_lld_disconnect_bus) +#define usb_lld_disconnect_bus(usbp) \ + do { \ + USB->CLR.SIECTRL = USB_SIE_CTRL_PULLUP_EN; \ + } while (false) +#endif + +/** + * @brief Start of host wake-up procedure. + * + * @notapi + */ +#define usb_lld_wakeup_host(usbp) \ + do { \ + USB->SET.SIECTRL = USB_SIE_CTRL_RESUME; \ + } while (false) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if RP_USB_USE_USBD1 && !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_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 /* HAL_USB_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/RP/LLD/USBDv1/rp2040_usb.h b/os/hal/ports/RP/LLD/USBDv1/rp2040_usb.h new file mode 100644 index 00000000..ee726eee --- /dev/null +++ b/os/hal/ports/RP/LLD/USBDv1/rp2040_usb.h @@ -0,0 +1,472 @@ +/* + ChibiOS - Copyright (C) 2006..2018 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 USBDv1/rp2040_usb.h + * @brief RP2040 USB registers layout header. + * @note This file requires definitions from the RP2040 header files. + * + * @addtogroup USB + * @{ + */ + +#ifndef RP2040_USB_H +#define RP2040_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 15 + + +#define USB_ADDR_ENDP0_ENDPOINT_Pos 16U +#define USB_ADDR_ENDP0_ENDPOINT_Msk (0xFU << USB_ADDR_ENDP0_ENDPOINT_Pos) +#define USB_ADDR_ENDP0_ADDRESS_Pos 0U +#define USB_ADDR_ENDP0_ADDRESS_Msk (0x7FU << USB_ADDR_ENDP0_ADDRESS_Pos) + +#define USB_ADDR_ENDP_INTEP_PREAMBLE (1U << 26) +#define USB_ADDR_ENDP_INTEP_DIR (1U << 25) +#define USB_ADDR_ENDP_ENDPOINT_Pos 16U +#define USB_ADDR_ENDP_ENDPOINT_Msk (0xFU << USB_ADDR_ENDP_ENDPOINT_Pos) +#define USB_ADDR_ENDP_ADDRESS_Pos 0U +#define USB_ADDR_ENDP_ADDRESS_Msk (0x7FU << USB_ADDR_ENDP_ADDRESS_Pos) + +#define USB_MAIN_CTRL_SIM_TIMING (1U << 31) +#define USB_MAIN_CTRL_HOST_NDEVICE (1U << 1) +#define USB_MAIN_CTRL_CONTROLLER_EN (1U << 0) + +#define USB_SOF_WR_COUNT_Pos 0U +#define USB_SOF_WR_COUNT_Msk (0x3FF << USB_SOF_WR_COUNT_Pos) + +#define USB_SOF_RD_COUNT_Pos 0U +#define USB_SOF_RD_COUNT_Msk (0x3FF << USB_SOF_RD_COUNT_Pos) + +#define USB_SIE_CTRL_EP0_INT_STALL (1U << 31) +#define USB_SIE_CTRL_EP0_DOUBLE_BUF (1U << 30) +#define USB_SIE_CTRL_EP0_INT_1BUF (1U << 29) +#define USB_SIE_CTRL_EP0_INT_2BUF (1U << 28) +#define USB_SIE_CTRL_EP0_INT_NAK (1U << 27) +#define USB_SIE_CTRL_DIRECT_EN (1U << 26) +#define USB_SIE_CTRL_DIRECT_DP (1U << 25) +#define USB_SIE_CTRL_DIRECT_DM (1U << 24) +#define USB_SIE_CTRL_TRANSCEIVER_PD (1U << 18) +#define USB_SIE_CTRL_RPU_OPT (1U << 17) +#define USB_SIE_CTRL_PULLUP_EN (1U << 16) +#define USB_SIE_CTRL_PULLDOWN_EN (1U << 15) +#define USB_SIE_CTRL_RESET_BUS (1U << 13) +#define USB_SIE_CTRL_RESUME (1U << 12) +#define USB_SIE_CTRL_VBUS_EN (1U << 11) +#define USB_SIE_CTRL_KEEP_ALIVE_EN (1U << 10) +#define USB_SIE_CTRL_SOF_EN (1U << 9) +#define USB_SIE_CTRL_SOF_SYNC (1U << 8) +#define USB_SIE_CTRL_PREAMBLE_EN (1U << 6) +#define USB_SIE_CTRL_STOP_TRANS (1U << 4) +#define USB_SIE_CTRL_RECEIVE_DATA (1U << 3) +#define USB_SIE_CTRL_SEND_DATA (1U << 2) +#define USB_SIE_CTRL_SEND_SETUP (1U << 1) +#define USB_SIE_CTRL_START_TRANS (1U << 0) + +#define USB_SIE_STATUS_DATA_SEQ_ERROR (1U << 31) +#define USB_SIE_STATUS_ACK_REC (1U << 30) +#define USB_SIE_STATUS_STALL_REC (1U << 29) +#define USB_SIE_STATUS_NAK_REC (1U << 28) +#define USB_SIE_STATUS_RX_TIMEOUT (1U << 27) +#define USB_SIE_STATUS_RX_OVERFLOW (1U << 26) +#define USB_SIE_STATUS_BIT_STUFF_ERROR (1U << 25) +#define USB_SIE_STATUS_CRC_ERROR (1U << 24) +#define USB_SIE_STATUS_BUS_RESET (1U << 19) +#define USB_SIE_STATUS_TRANS_COMPLETE (1U << 18) +#define USB_SIE_STATUS_SETUP_REC (1U << 17) +#define USB_SIE_STATUS_CONNECTED (1U << 16) +#define USB_SIE_STATUS_RESUME (1U << 11) +#define USB_SIE_STATUS_VBUS_OVER_CURR (1U << 10) +#define USB_SIE_STATUS_SPEED_Pos 8U +#define USB_SIE_STATUS_SPEED_Msk (0x3U << USB_SIE_STATUS_SPEED_Pos) +#define USB_SIE_STATUS_SUSPENDED (1U << 4) +#define USB_SIE_STATUS_LINE_STATE_Pos 2U +#define USB_SIE_STATUS_LINE_STATE_Msk (0x3U << USB_SIE_STATUS_LINE_STATE_Pos) +#define USB_SIE_STATUS_VBUS_DETECTED (1U << 0) + +#define USB_INT_EP_CTRL_INT_EP_ACTIVE_Pos 0U +#define USB_INT_EP_CTRL_INT_EP_ACTIVE_Msk (0xFFFE << USB_INT_EP_CTRL_INT_EP_ACTIVE_Pos) + +#define USB_BUFF_STATUS_EP15_OUT (1U << 31) +#define USB_BUFF_STATUS_EP15_IN (1U << 30) +#define USB_BUFF_STATUS_EP14_OUT (1U << 29) +#define USB_BUFF_STATUS_EP14_IN (1U << 28) +#define USB_BUFF_STATUS_EP13_OUT (1U << 27) +#define USB_BUFF_STATUS_EP13_IN (1U << 26) +#define USB_BUFF_STATUS_EP12_OUT (1U << 25) +#define USB_BUFF_STATUS_EP12_IN (1U << 24) +#define USB_BUFF_STATUS_EP11_OUT (1U << 23) +#define USB_BUFF_STATUS_EP11_IN (1U << 22) +#define USB_BUFF_STATUS_EP10_OUT (1U << 21) +#define USB_BUFF_STATUS_EP10_IN (1U << 20) +#define USB_BUFF_STATUS_EP9_OUT (1U << 19) +#define USB_BUFF_STATUS_EP9_IN (1U << 18) +#define USB_BUFF_STATUS_EP8_OUT (1U << 17) +#define USB_BUFF_STATUS_EP8_IN (1U << 16) +#define USB_BUFF_STATUS_EP7_OUT (1U << 15) +#define USB_BUFF_STATUS_EP7_IN (1U << 14) +#define USB_BUFF_STATUS_EP6_OUT (1U << 13) +#define USB_BUFF_STATUS_EP6_IN (1U << 12) +#define USB_BUFF_STATUS_EP5_OUT (1U << 11) +#define USB_BUFF_STATUS_EP5_IN (1U << 10) +#define USB_BUFF_STATUS_EP4_OUT (1U << 9) +#define USB_BUFF_STATUS_EP4_IN (1U << 8) +#define USB_BUFF_STATUS_EP3_OUT (1U << 7) +#define USB_BUFF_STATUS_EP3_IN (1U << 6) +#define USB_BUFF_STATUS_EP2_OUT (1U << 5) +#define USB_BUFF_STATUS_EP2_IN (1U << 4) +#define USB_BUFF_STATUS_EP1_OUT (1U << 3) +#define USB_BUFF_STATUS_EP1_IN (1U << 2) +#define USB_BUFF_STATUS_EP0_OUT (1U << 1) +#define USB_BUFF_STATUS_EP0_IN (1U << 0) + +#define USB_BUFF_CPU_SHOULD_HANDLE_EP15_OUT (1U << 31) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP15_IN (1U << 30) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP14_OUT (1U << 29) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP14_IN (1U << 28) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP13_OUT (1U << 27) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP13_IN (1U << 26) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP12_OUT (1U << 25) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP12_IN (1U << 24) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP11_OUT (1U << 23) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP11_IN (1U << 22) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP10_OUT (1U << 21) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP10_IN (1U << 20) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP9_OUT (1U << 19) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP9_IN (1U << 18) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP8_OUT (1U << 17) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP8_IN (1U << 16) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP7_OUT (1U << 15) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP7_IN (1U << 14) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP6_OUT (1U << 13) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP6_IN (1U << 12) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP5_OUT (1U << 11) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP5_IN (1U << 10) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP4_OUT (1U << 9) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP4_IN (1U << 8) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP3_OUT (1U << 7) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP3_IN (1U << 6) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP2_OUT (1U << 5) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP2_IN (1U << 4) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP1_OUT (1U << 3) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP1_IN (1U << 2) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP0_OUT (1U << 1) +#define USB_BUFF_CPU_SHOULD_HANDLE_EP0_IN (1U << 0) + +#define USB_EP_ABORT_EP15_OUT (1U << 31) +#define USB_EP_ABORT_EP15_IN (1U << 30) +#define USB_EP_ABORT_EP14_OUT (1U << 29) +#define USB_EP_ABORT_EP14_IN (1U << 28) +#define USB_EP_ABORT_EP13_OUT (1U << 27) +#define USB_EP_ABORT_EP13_IN (1U << 26) +#define USB_EP_ABORT_EP12_OUT (1U << 25) +#define USB_EP_ABORT_EP12_IN (1U << 24) +#define USB_EP_ABORT_EP11_OUT (1U << 23) +#define USB_EP_ABORT_EP11_IN (1U << 22) +#define USB_EP_ABORT_EP10_OUT (1U << 21) +#define USB_EP_ABORT_EP10_IN (1U << 20) +#define USB_EP_ABORT_EP9_OUT (1U << 19) +#define USB_EP_ABORT_EP9_IN (1U << 18) +#define USB_EP_ABORT_EP8_OUT (1U << 17) +#define USB_EP_ABORT_EP8_IN (1U << 16) +#define USB_EP_ABORT_EP7_OUT (1U << 15) +#define USB_EP_ABORT_EP7_IN (1U << 14) +#define USB_EP_ABORT_EP6_OUT (1U << 13) +#define USB_EP_ABORT_EP6_IN (1U << 12) +#define USB_EP_ABORT_EP5_OUT (1U << 11) +#define USB_EP_ABORT_EP5_IN (1U << 10) +#define USB_EP_ABORT_EP4_OUT (1U << 9) +#define USB_EP_ABORT_EP4_IN (1U << 8) +#define USB_EP_ABORT_EP3_OUT (1U << 7) +#define USB_EP_ABORT_EP3_IN (1U << 6) +#define USB_EP_ABORT_EP2_OUT (1U << 5) +#define USB_EP_ABORT_EP2_IN (1U << 4) +#define USB_EP_ABORT_EP1_OUT (1U << 3) +#define USB_EP_ABORT_EP1_IN (1U << 2) +#define USB_EP_ABORT_EP0_OUT (1U << 1) +#define USB_EP_ABORT_EP0_IN (1U << 0) + +#define USB_EP_ABORT_DONE_EP15_OUT (1U << 31) +#define USB_EP_ABORT_DONE_EP15_IN (1U << 30) +#define USB_EP_ABORT_DONE_EP14_OUT (1U << 29) +#define USB_EP_ABORT_DONE_EP14_IN (1U << 28) +#define USB_EP_ABORT_DONE_EP13_OUT (1U << 27) +#define USB_EP_ABORT_DONE_EP13_IN (1U << 26) +#define USB_EP_ABORT_DONE_EP12_OUT (1U << 25) +#define USB_EP_ABORT_DONE_EP12_IN (1U << 24) +#define USB_EP_ABORT_DONE_EP11_OUT (1U << 23) +#define USB_EP_ABORT_DONE_EP11_IN (1U << 22) +#define USB_EP_ABORT_DONE_EP10_OUT (1U << 21) +#define USB_EP_ABORT_DONE_EP10_IN (1U << 20) +#define USB_EP_ABORT_DONE_EP9_OUT (1U << 19) +#define USB_EP_ABORT_DONE_EP9_IN (1U << 18) +#define USB_EP_ABORT_DONE_EP8_OUT (1U << 17) +#define USB_EP_ABORT_DONE_EP8_IN (1U << 16) +#define USB_EP_ABORT_DONE_EP7_OUT (1U << 15) +#define USB_EP_ABORT_DONE_EP7_IN (1U << 14) +#define USB_EP_ABORT_DONE_EP6_OUT (1U << 13) +#define USB_EP_ABORT_DONE_EP6_IN (1U << 12) +#define USB_EP_ABORT_DONE_EP5_OUT (1U << 11) +#define USB_EP_ABORT_DONE_EP5_IN (1U << 10) +#define USB_EP_ABORT_DONE_EP4_OUT (1U << 9) +#define USB_EP_ABORT_DONE_EP4_IN (1U << 8) +#define USB_EP_ABORT_DONE_EP3_OUT (1U << 7) +#define USB_EP_ABORT_DONE_EP3_IN (1U << 6) +#define USB_EP_ABORT_DONE_EP2_OUT (1U << 5) +#define USB_EP_ABORT_DONE_EP2_IN (1U << 4) +#define USB_EP_ABORT_DONE_EP1_OUT (1U << 3) +#define USB_EP_ABORT_DONE_EP1_IN (1U << 2) +#define USB_EP_ABORT_DONE_EP0_OUT (1U << 1) +#define USB_EP_ABORT_DONE_EP0_IN (1U << 0) + +#define USB_EP_STALL_ARM_EP0_OUT (1U << 1) +#define USB_EP_STALL_ARM_EP0_IN (1U << 0) + +#define USB_NAK_POLL_DELAY_FS_Pos 16U +#define USB_NAK_POLL_DELAY_FS_Msk (0x3FF << USB_NAK_POLL_DELAY_FS_Pos) +#define USB_NAK_POLL_DELAY_LS_Pos 0U +#define USB_NAK_POLL_DELAY_LS_Msk (0x3FF << USB_NAK_POLL_DELAY_LS_Pos) + +#define USB_EP_STATUS_STALL_NAK_EP15_OUT (1U << 31) +#define USB_EP_STATUS_STALL_NAK_EP15_IN (1U << 30) +#define USB_EP_STATUS_STALL_NAK_EP14_OUT (1U << 29) +#define USB_EP_STATUS_STALL_NAK_EP14_IN (1U << 28) +#define USB_EP_STATUS_STALL_NAK_EP13_OUT (1U << 27) +#define USB_EP_STATUS_STALL_NAK_EP13_IN (1U << 26) +#define USB_EP_STATUS_STALL_NAK_EP12_OUT (1U << 25) +#define USB_EP_STATUS_STALL_NAK_EP12_IN (1U << 24) +#define USB_EP_STATUS_STALL_NAK_EP11_OUT (1U << 23) +#define USB_EP_STATUS_STALL_NAK_EP11_IN (1U << 22) +#define USB_EP_STATUS_STALL_NAK_EP10_OUT (1U << 21) +#define USB_EP_STATUS_STALL_NAK_EP10_IN (1U << 20) +#define USB_EP_STATUS_STALL_NAK_EP9_OUT (1U << 19) +#define USB_EP_STATUS_STALL_NAK_EP9_IN (1U << 18) +#define USB_EP_STATUS_STALL_NAK_EP8_OUT (1U << 17) +#define USB_EP_STATUS_STALL_NAK_EP8_IN (1U << 16) +#define USB_EP_STATUS_STALL_NAK_EP7_OUT (1U << 15) +#define USB_EP_STATUS_STALL_NAK_EP7_IN (1U << 14) +#define USB_EP_STATUS_STALL_NAK_EP6_OUT (1U << 13) +#define USB_EP_STATUS_STALL_NAK_EP6_IN (1U << 12) +#define USB_EP_STATUS_STALL_NAK_EP5_OUT (1U << 11) +#define USB_EP_STATUS_STALL_NAK_EP5_IN (1U << 10) +#define USB_EP_STATUS_STALL_NAK_EP4_OUT (1U << 9) +#define USB_EP_STATUS_STALL_NAK_EP4_IN (1U << 8) +#define USB_EP_STATUS_STALL_NAK_EP3_OUT (1U << 7) +#define USB_EP_STATUS_STALL_NAK_EP3_IN (1U << 6) +#define USB_EP_STATUS_STALL_NAK_EP2_OUT (1U << 5) +#define USB_EP_STATUS_STALL_NAK_EP2_IN (1U << 4) +#define USB_EP_STATUS_STALL_NAK_EP1_OUT (1U << 3) +#define USB_EP_STATUS_STALL_NAK_EP1_IN (1U << 2) +#define USB_EP_STATUS_STALL_NAK_EP0_OUT (1U << 1) +#define USB_EP_STATUS_STALL_NAK_EP0_IN (1U << 0) + +#define USB_USB_MUXING_SOFTCON (1U << 3) +#define USB_USB_MUXING_TO_DIGITAL_PAD (1U << 2) +#define USB_USB_MUXING_TO_EXTPHY (1U << 1) +#define USB_USB_MUXING_TO_PHY (1U << 0) + +#define USB_USB_PWR_OVERCURR_DETECT_EN (1U << 5) +#define USB_USB_PWR_OVERCURR_DETECT (1U << 4) +#define USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN (1U << 3) +#define USB_USB_PWR_VBUS_DETECT (1U << 2) +#define USB_USB_PWR_VBUS_EN_OVERRIDE_EN (1U << 1) +#define USB_USB_PWR_VBUS_EN (1U << 0) + +#define USB_USBPHY_DIRECT_DM_OVV (1U << 22) +#define USB_USBPHY_DIRECT_DP_OVV (1U << 21) +#define USB_USBPHY_DIRECT_DM_OVCN (1U << 20) +#define USB_USBPHY_DIRECT_DP_OVCN (1U << 19) +#define USB_USBPHY_DIRECT_RX_DM (1U << 18) +#define USB_USBPHY_DIRECT_RX_DP (1U << 17) +#define USB_USBPHY_DIRECT_RX_DD (1U << 16) +#define USB_USBPHY_DIRECT_TX_DIFFMODE (1U << 15) +#define USB_USBPHY_DIRECT_TX_FSSLEW (1U << 14) +#define USB_USBPHY_DIRECT_TX_PD (1U << 13) +#define USB_USBPHY_DIRECT_RX_PD (1U << 12) +#define USB_USBPHY_DIRECT_TX_DM (1U << 11) +#define USB_USBPHY_DIRECT_TX_DP (1U << 10) +#define USB_USBPHY_DIRECT_TX_DM_OE (1U << 9) +#define USB_USBPHY_DIRECT_TX_DP_OE (1U << 8) +#define USB_USBPHY_DIRECT_DM_PULLDN_EN (1U << 6) +#define USB_USBPHY_DIRECT_DM_PULLUP_EN (1U << 5) +#define USB_USBPHY_DIRECT_DM_PULLUP_HISEL (1U << 4) +#define USB_USBPHY_DIRECT_DP_PULLDN_EN (1U << 1) +#define USB_USBPHY_DIRECT_DP_PULLUP_EN (1U << 1) +#define USB_USBPHY_DIRECT_DP_PULLUP_HISEL (1U << 0) + +#define USB_USBPHY_DIRECT_OVERRIDE_TX_DIFFMODE_OVERRIDE_EN (1U << 15) +#define USB_USBPHY_DIRECT_OVERRIDE_DM_PULLUP_OVERRIDE_EN (1U << 12) +#define USB_USBPHY_DIRECT_OVERRIDE_TX_FSSLEW_OVERRIDE_EN (1U << 11) +#define USB_USBPHY_DIRECT_OVERRIDE_TX_PD_OVERRIDE_EN (1U << 10) +#define USB_USBPHY_DIRECT_OVERRIDE_RX_PD_OVERRIDE_EN (1U << 9) +#define USB_USBPHY_DIRECT_OVERRIDE_TX_DM_OVERRIDE_EN (1U << 8) +#define USB_USBPHY_DIRECT_OVERRIDE_TX_DP_OVERRIDE_EN (1U << 7) +#define USB_USBPHY_DIRECT_OVERRIDE_TX_DM_OE_OVERRIDE_EN (1U << 6) +#define USB_USBPHY_DIRECT_OVERRIDE_TX_DP_OE_OVERRIDE_EN (1U << 5) +#define USB_USBPHY_DIRECT_OVERRIDE_DM_PULLDN_EN_OVERRIDE_EN (1U << 4) +#define USB_USBPHY_DIRECT_OVERRIDE_DP_PULLDN_EN_OVERRIDE_EN (1U << 3) +#define USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN (1U << 2) +#define USB_USBPHY_DIRECT_OVERRIDE_DM_PULLUP_HISEL_OVERRIDE_EN (1U << 1) +#define USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_HISEL_OVERRIDE_EN (1U << 0) + +#define USB_USBPHY_TRIM_DM_PULLDN_TRIM_Pos 8 +#define USB_USBPHY_TRIM_DM_PULLDN_TRIM_Msk (0x1F << USB_PHY_TRIM_DP_PULLDN_TRIM_Pos) +#define USB_USBPHY_TRIM_DP_PULLDN_TRIM_Pos 0 +#define USB_USBPHY_TRIM_DP_PULLDN_TRIM_Msk (0x1F << USB_PHY_TRIM_DM_PULLDN_TRIM_Pos) + +#define USB_INTR_EP_STALL_NAK (1U << 19) +#define USB_INTR_ABORT_DONE (1U << 18) +#define USB_INTR_DEV_SOF (1U << 17) +#define USB_INTR_SETUP_REQ (1U << 16) +#define USB_INTR_DEV_RESUME_FROM_HOST (1U << 15) +#define USB_INTR_DEV_SUSPEND (1U << 14) +#define USB_INTR_DEV_CONN_DIS (1U << 13) +#define USB_INTR_BUS_RESET (1U << 12) +#define USB_INTR_VBUS_DETECT (1U << 11) +#define USB_INTR_STALL (1U << 10) +#define USB_INTR_ERROR_CRC (1U << 9) +#define USB_INTR_ERROR_BIT_STUFF (1U << 8) +#define USB_INTR_ERROR_RX_OVERFLOW (1U << 7) +#define USB_INTR_ERROR_RX_TIMEOUT (1U << 6) +#define USB_INTR_ERROR_DATA_SEQ (1U << 5) +#define USB_INTR_BUFF_STATUS (1U << 4) +#define USB_INTR_TRANS_COMPLETE (1U << 3) +#define USB_INTR_HOST_SOF (1U << 2) +#define USB_INTR_HOST_RESUME (1U << 1) +#define USB_INTR_HOST_CONN_DIS (1U << 0) + +#define USB_INTE_EP_STALL_NAK (1U << 19) +#define USB_INTE_ABORT_DONE (1U << 18) +#define USB_INTE_DEV_SOF (1U << 17) +#define USB_INTE_SETUP_REQ (1U << 16) +#define USB_INTE_DEV_RESUME_FROM_HOST (1U << 15) +#define USB_INTE_DEV_SUSPEND (1U << 14) +#define USB_INTE_DEV_CONN_DIS (1U << 13) +#define USB_INTE_BUS_RESET (1U << 12) +#define USB_INTE_VBUS_DETECT (1U << 11) +#define USB_INTE_STALL (1U << 10) +#define USB_INTE_ERROR_CRC (1U << 9) +#define USB_INTE_ERROR_BIT_STUFF (1U << 8) +#define USB_INTE_ERROR_RX_OVERFLOW (1U << 7) +#define USB_INTE_ERROR_RX_TIMEOUT (1U << 6) +#define USB_INTE_ERROR_DATA_SEQ (1U << 5) +#define USB_INTE_BUFF_STATUS (1U << 4) +#define USB_INTE_TRANS_COMPLETE (1U << 3) +#define USB_INTE_HOST_SOF (1U << 2) +#define USB_INTE_HOST_RESUME (1U << 1) +#define USB_INTE_HOST_CONN_DIS (1U << 0) + +#define USB_INTF_EP_STALL_NAK (1U << 19) +#define USB_INTF_ABORT_DONE (1U << 18) +#define USB_INTF_DEV_SOF (1U << 17) +#define USB_INTF_SETUP_REQ (1U << 16) +#define USB_INTF_DEV_RESUME_FROM_HOST (1U << 15) +#define USB_INTF_DEV_SUSPEND (1U << 14) +#define USB_INTF_DEV_CONN_DIS (1U << 13) +#define USB_INTF_BUS_RESET (1U << 12) +#define USB_INTF_VBUS_DETECT (1U << 11) +#define USB_INTF_STALL (1U << 10) +#define USB_INTF_ERROR_CRC (1U << 9) +#define USB_INTF_ERROR_BIT_STUFF (1U << 8) +#define USB_INTF_ERROR_RX_OVERFLOW (1U << 7) +#define USB_INTF_ERROR_RX_TIMEOUT (1U << 6) +#define USB_INTF_ERROR_DATA_SEQ (1U << 5) +#define USB_INTF_BUFF_STATUS (1U << 4) +#define USB_INTF_TRANS_COMPLETE (1U << 3) +#define USB_INTF_HOST_SOF (1U << 2) +#define USB_INTF_HOST_RESUME (1U << 1) +#define USB_INTF_HOST_CONN_DIS (1U << 0) + +#define USB_INTS_EP_STALL_NAK (1U << 19) +#define USB_INTS_ABORT_DONE (1U << 18) +#define USB_INTS_DEV_SOF (1U << 17) +#define USB_INTS_SETUP_REQ (1U << 16) +#define USB_INTS_DEV_RESUME_FROM_HOST (1U << 15) +#define USB_INTS_DEV_SUSPEND (1U << 14) +#define USB_INTS_DEV_CONN_DIS (1U << 13) +#define USB_INTS_BUS_RESET (1U << 12) +#define USB_INTS_VBUS_DETECT (1U << 11) +#define USB_INTS_STALL (1U << 10) +#define USB_INTS_ERROR_CRC (1U << 9) +#define USB_INTS_ERROR_BIT_STUFF (1U << 8) +#define USB_INTS_ERROR_RX_OVERFLOW (1U << 7) +#define USB_INTS_ERROR_RX_TIMEOUT (1U << 6) +#define USB_INTS_ERROR_DATA_SEQ (1U << 5) +#define USB_INTS_BUFF_STATUS (1U << 4) +#define USB_INTS_TRANS_COMPLETE (1U << 3) +#define USB_INTS_HOST_SOF (1U << 2) +#define USB_INTS_HOST_RESUME (1U << 1) +#define USB_INTS_HOST_CONN_DIS (1U << 0) + +typedef struct { + __IO uint8_t SETUPPACKET[8]; + struct { + __IO uint32_t IN; + __IO uint32_t OUT; + } EPCTRL[15]; + struct { + __IO uint32_t IN; + __IO uint32_t OUT; + } BUFCTRL[16]; + __IO uint8_t EP0BUF0[64]; + __IO uint8_t EP0BUF1[64]; + __IO uint8_t DATA[3712]; +} USB_DPSRAM_TypeDef; + +#define __AHBPERIPH_BASE 0x50000000U + +#define __USB_DPSRAM_BASE (__AHBPERIPH_BASE + 0x00100000U) + +#define USB_DPSRAM ((USB_DPSRAM_TypeDef *) __USB_DPSRAM_BASE) + +// Endpoint control register +#define USB_EP_EN (1U << 31) +#define USB_EP_BUFFER_DOUBLE (1U << 30) +#define USB_EP_BUFFER_IRQ_EN (1U << 29) +#define USB_EP_BUFFER_IRQ_DOUBLE_EN (1U << 28) +#define USB_EP_TYPE_Pos 26U +#define USB_EP_TYPE_Msk (0x3 << USB_EP_TYPE_Pos) +#define USB_EP_IRQ_STALL (1U << 17) +#define USB_EP_IRQ_NAK (1U << 16) +#define USB_EP_ADDR_OFFSET_Pos 0U +#define USB_EP_ADDR_OFFSET_Msk (0x7F << USB_EP_ADDR_OFFSET_Pos) + +// Buffer control register +#define USB_BUFFER_BUFFER1_FULL (1U << 31) +#define USB_BUFFER_BUFFER1_LAST (1U << 30) +#define USB_BUFFER_BUFFER1_DATA_PID (1U << 29) +#define USB_BUFFER_DOUBLE_BUFFER_OFFSET_Pos 27U +#define USB_BUFFER_DOUBLE_BUFFER_OFFSET_Msk (0x3 << USB_BUFFER_DOUBLE_BUFFER_OFFSET_Pos) +#define USB_BUFFER_BUFFER1_AVAILABLE (1U << 26) +#define USB_BUFFER_BUFFER1_TRANS_LENGTH_Pos 16U +#define USB_BUFFER_BUFFER1_TRANS_LENGTH_Msk (0x3FF << USB_BUFFER_BUFFER1_TRANS_LENGTH_Pos) +#define USB_BUFFER_BUFFER0_FULL (1U << 15) +#define USB_BUFFER_BUFFER0_LAST (1U << 14) +#define USB_BUFFER_BUFFER0_DATA_PID (1U << 13) +#define USB_BUFFER_RESET_BUFFER (1U << 12) +// Send STALL for devices, STALL received for host +#define USB_BUFFER_STALL (1U << 11) +#define USB_BUFFER_BUFFER0_AVAILABLE (1U << 10) +#define USB_BUFFER_BUFFER0_TRANS_LENGTH_Pos 0U +#define USB_BUFFER_BUFFER0_TRANS_LENGTH_Msk (0x3FF << USB_BUFFER_BUFFER0_TRANS_LENGTH_Pos) + +#endif /* RP2040_USB_H */ + +/** @} */ diff --git a/os/hal/ports/RP/RP2040/platform.mk b/os/hal/ports/RP/RP2040/platform.mk new file mode 100644 index 00000000..d067978d --- /dev/null +++ b/os/hal/ports/RP/RP2040/platform.mk @@ -0,0 +1,19 @@ +include ${CHIBIOS}/os/hal/ports/RP/RP2040/platform.mk + +ifeq ($(USE_SMART_BUILD),yes) + +# Configuration files directory +ifeq ($(CONFDIR),) + CONFDIR = . +endif + +HALCONF := $(strip $(shell cat $(CONFDIR)/halconf.h $(CONFDIR)/halconf_community.h | egrep -e "\#define")) + +else +endif + +include ${CHIBIOS_CONTRIB}/os/hal/ports/RP/LLD/USBDv1/driver.mk + +# Shared variables +ALLCSRC += $(PLATFORMSRC_CONTRIB) +ALLINC += $(PLATFORMINC_CONTRIB) diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/.cproject b/testhal/RP/RP2040/RT-RP2040-PICO-HID/.cproject new file mode 100644 index 00000000..f808ccb5 --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/.cproject @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/.project b/testhal/RP/RP2040/RT-RP2040-PICO-HID/.project new file mode 100644 index 00000000..e1c25eae --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/.project @@ -0,0 +1,48 @@ + + + RT-RP2040-PICO-HID + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + board + 2 + CHIBIOS/os/hal/boards/RP_PICO_RP2040 + + + os + 2 + CHIBIOS/os + + + pico-sdk + 2 + CHIBIOS/ext/pico-sdk/src + + + test + 2 + CHIBIOS/test + + + diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/Makefile b/testhal/RP/RP2040/RT-RP2040-PICO-HID/Makefile new file mode 100644 index 00000000..bf67f9ad --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/Makefile @@ -0,0 +1,208 @@ +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +# Compiler options here. +ifeq ($(USE_OPT),) + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 +endif + +# C specific options here (added to USE_OPT). +ifeq ($(USE_COPT),) + USE_COPT = +endif + +# C++ specific options here (added to USE_OPT). +ifeq ($(USE_CPPOPT),) + USE_CPPOPT = -fno-rtti +endif + +# Enable this if you want the linker to remove unused code and data. +ifeq ($(USE_LINK_GC),) + USE_LINK_GC = yes +endif + +# Linker extra options here. +ifeq ($(USE_LDOPT),) + USE_LDOPT = +endif + +# Enable this if you want link time optimizations (LTO). +ifeq ($(USE_LTO),) + USE_LTO = yes +endif + +# Enable this if you want to see the full log while compiling. +ifeq ($(USE_VERBOSE_COMPILE),) + USE_VERBOSE_COMPILE = no +endif + +# If enabled, this option makes the build process faster by not compiling +# modules not used in the current configuration. +ifeq ($(USE_SMART_BUILD),) + USE_SMART_BUILD = yes +endif + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Stack size to be allocated to the Cortex-M process stack. This stack is +# the stack used by the main() thread. +ifeq ($(USE_PROCESS_STACKSIZE),) + USE_PROCESS_STACKSIZE = 0x200 +endif + +# Stack size to the allocated to the Cortex-M main/exceptions stack. This +# stack is used for processing interrupts and exceptions. +ifeq ($(USE_EXCEPTIONS_STACKSIZE),) + USE_EXCEPTIONS_STACKSIZE = 0x200 +endif + +# Enables the use of FPU (no, softfp, hard). +ifeq ($(USE_FPU),) + USE_FPU = no +endif + +# FPU-related options. +ifeq ($(USE_FPU_OPT),) + USE_FPU_OPT = -mfloat-abi=$(USE_FPU) -mfpu=fpv4-sp-d16 +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, target, sources and paths +# + +# Define project name here +PROJECT = ch + +# Target settings. +MCU = cortex-m0plus + +# Imported source files and paths. +CHIBIOS := ../../../../../ChibiOS +CONFDIR := ./cfg +BUILDDIR := ./build +DEPDIR := ./.dep +CHIBIOS_CONTRIB := ../../../.. + +# Licensing files. +include $(CHIBIOS)/os/license/license.mk +# Startup files. +include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_rp2040.mk +# HAL-OSAL files (optional). +#include $(CHIBIOS)/os/hal/hal.mk +include $(CHIBIOS_CONTRIB)/os/hal/hal.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/RP/RP2040/platform.mk +include $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040/board.mk +include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk +# RTOS files (optional). +include $(CHIBIOS)/os/rt/rt.mk +include $(CHIBIOS)/os/common/ports/ARMv6-M-RP2/compilers/GCC/mk/port.mk +# Auto-build files in ./source recursively. +include $(CHIBIOS)/tools/mk/autobuild.mk +# Other files (optional). +include $(CHIBIOS)/os/test/test.mk +include $(CHIBIOS)/test/rt/rt_test.mk +include $(CHIBIOS)/test/oslib/oslib_test.mk +include $(CHIBIOS)/os/various/pico_bindings/pico-sdk.mk +include $(CHIBIOS)/os/hal/lib/streams/streams.mk +include $(CHIBIOS)/os/various/shell/shell.mk + +# Define linker script file here +LDSCRIPT= $(STARTUPLD)/RP2040_RAM.ld +#LDSCRIPT= ./RP2040_FLASH.ld + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CSRC = $(ALLCSRC) \ + $(TESTSRC) \ + main.c c1_main.c usbcfg.c + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CPPSRC = $(ALLCPPSRC) + +# List ASM source files here. +ASMSRC = $(ALLASMSRC) + +# List ASM with preprocessor source files here. +ASMXSRC = $(ALLXASMSRC) + +# Inclusion directories. +INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC) + +# Define C warning options here. +CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes + +# Define C++ warning options here. +CPPWARN = -Wall -Wextra -Wundef + +# +# Project, target, sources and paths +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +UDEFS = -DCRT0_VTOR_INIT=1 -DCRT0_EXTRA_CORES_NUMBER=1 -DPICO_NO_FPGA_CHECK -DNDEBUG -DUSB_DEBUG + +# Define ASM defines here +UADEFS = -DCRT0_VTOR_INIT=1 -DCRT0_EXTRA_CORES_NUMBER=1 + +# List all user directories here +UINCDIR = + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = +#$(PICOSDKROOT)/build/src/rp2_common/boot_stage2/bs2_default_padded_checksummed.S + +# +# End of user section +############################################################################## + +############################################################################## +# Common rules +# + +RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk +include $(RULESPATH)/arm-none-eabi.mk +include $(RULESPATH)/rules.mk + +# +# Common rules +############################################################################## + +############################################################################## +# Custom rules +# + +ELF2UF2 := $(PICOSDKROOT)/build/elf2uf2/elf2uf2 + +#OUTFILES += $(BUILDDIR)/$(PROJECT).uf2 + +%.uf2: %.elf +ifeq ($(USE_VERBOSE_COMPILE),yes) + $(ELF2UF2) $< $@ +else + @echo Creating $@ + @$(ELF2UF2) $< $@ +endif + +# +# Custom rules +############################################################################## diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/RP2040_FLASH.ld b/testhal/RP/RP2040/RT-RP2040-PICO-HID/RP2040_FLASH.ld new file mode 100644 index 00000000..3f65661e --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/RP2040_FLASH.ld @@ -0,0 +1,119 @@ +/* + ChibiOS - Copyright (C) 2006..2021 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. +*/ + +/* + * RP2040 memory setup. + */ +MEMORY +{ + flash0 (rx) : org = 0x00000000, len = 16k /* ROM */ + flash1 (rx) : org = 0x10000000, len = 2048k /* XIP (length TBD) */ + flash2 (rx) : org = 0x00000000, len = 0 + flash3 (rx) : org = 0x00000000, len = 0 + flash4 (rx) : org = 0x00000000, len = 0 + flash5 (rx) : org = 0x00000000, len = 0 + flash6 (rx) : org = 0x00000000, len = 0 + flash7 (rx) : org = 0x00000000, len = 0 + ram0 (wx) : org = 0x20000000, len = 256k /* SRAM0 striped */ + ram1 (wx) : org = 0x00000000, len = 256k /* SRAM0 non striped */ + ram2 (wx) : org = 0x00000000, len = 0 + ram3 (wx) : org = 0x00000000, len = 0 + ram4 (wx) : org = 0x20040000, len = 4k /* SRAM4 */ + ram5 (wx) : org = 0x20041000, len = 4k /* SRAM5 */ + ram6 (wx) : org = 0x00000000, len = 0 + ram7 (wx) : org = 0x20041f00, len = 256 /* SRAM5 boot */ + /* ram8 (wx) : org = 0x15000000, len = 16k */ /* XIP cache */ + /* ram9 (wx) : org = 0x50100000, len = 4k */ /* USB DPRAM */ +} + +/* For each data/text section two region are defined, a virtual region + and a load region (_LMA suffix).*/ + +/* Flash region to be used for exception vectors.*/ +REGION_ALIAS("VECTORS_FLASH", flash1); +REGION_ALIAS("VECTORS_FLASH_LMA", flash1); + +/* Flash region to be used for constructors and destructors.*/ +REGION_ALIAS("XTORS_FLASH", flash1); +REGION_ALIAS("XTORS_FLASH_LMA", flash1); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash1); +REGION_ALIAS("TEXT_FLASH_LMA", flash1); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash1); +REGION_ALIAS("RODATA_FLASH_LMA", flash1); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash1); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash1); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash1); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("MAIN_STACK_RAM", ram4); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram4); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("C1_MAIN_STACK_RAM", ram5); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("C1_PROCESS_STACK_RAM", ram5); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); +REGION_ALIAS("DATA_RAM_LMA", flash1); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for the default heap.*/ +REGION_ALIAS("HEAP_RAM", ram0); + +SECTIONS +{ + .flash_begin : { + __flash_binary_start = .; + } > flash1 + + .boot2 : { + __boot2_start__ = .; + KEEP (*(.boot2)) + __boot2_end__ = .; + } > flash1 +} + +/* Generic rules inclusion.*/ +INCLUDE rules_stacks.ld +INCLUDE rules_stacks_c1.ld +INCLUDE rules_code_with_boot2.ld +INCLUDE rules_data.ld +INCLUDE rules_memory.ld + +SECTIONS +{ + .flash_end : { + __flash_binary_end = .; + } > flash1 +} diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/c1_main.c b/testhal/RP/RP2040/RT-RP2040-PICO-HID/c1_main.c new file mode 100644 index 00000000..cb59b755 --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/c1_main.c @@ -0,0 +1,82 @@ +/* + ChibiOS - Copyright (C) 2006..2018 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. +*/ + +#include "ch.h" +#include "hal.h" + +#ifdef USB_DEBUG + +#include "rp_fifo.h" + +#include "chprintf.h" + +uint8_t remained_data = 0; + +void process_command(uint32_t data) { + if (remained_data > 0) { + remained_data -= 1; + chprintf((BaseSequentialStream *)&SIOD0, "0x%X\r\n", data); + } else { + uint8_t cmd = (data & 0xFF000000) >> 24; + uint8_t length = (data & 0xFF0000) >> 16; + if (length > 0) { + remained_data = length; + } + chprintf((BaseSequentialStream *)&SIOD0, "%X\r\n", cmd); + } +} +#endif // USB_DEBUG + +/** + * Core 1 entry point. + */ +void c1_main(void) { + + /* + * Starting a new OS instance running on this core, we need to wait for + * system initialization on the other side. + */ + chSysWaitSystemState(ch_sys_running); + chInstanceObjectInit(&ch1, &ch_core1_cfg); + + /* It is alive now.*/ + chSysUnlock(); + +#ifdef USB_DEBUG + /* + * Setting up GPIOs. + */ + palSetLineMode(0U, PAL_MODE_ALTERNATE_UART); + palSetLineMode(1U, PAL_MODE_ALTERNATE_UART); + + /* + * Activates the UART0 SIO driver using the default configuration. + */ + sioStart(&SIOD0, NULL); + sioStartOperation(&SIOD0, NULL); + + chThdSleepMilliseconds(100); + chprintf((BaseSequentialStream *)&SIOD0, "-- Started in c1\r\n"); +#endif // USB_DEBUG + + /* + * Normal main() thread activity, in this demo it does nothing except + * sleeping in a loop (re)spawning a shell. + */ + while (true) { + chThdSleepMilliseconds(200); + } +} diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/chconf.h b/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/chconf.h new file mode 100644 index 00000000..1540aabb --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/chconf.h @@ -0,0 +1,823 @@ +/* + ChibiOS - Copyright (C) 2006..2020 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 rt/templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_7_0_ + +/*===========================================================================*/ +/** + * @name System settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Handling of instances. + * @note If enabled then threads assigned to various instances can + * interact each other using the same synchronization objects. + * If disabled then each OS instance is a separate world, no + * direct interactions are handled by the OS. + */ +#if !defined(CH_CFG_SMP_MODE) +#define CH_CFG_SMP_MODE TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_ST_RESOLUTION) +#define CH_CFG_ST_RESOLUTION 32 +#endif + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#if !defined(CH_CFG_ST_FREQUENCY) +#define CH_CFG_ST_FREQUENCY 1000000 +#endif + +/** + * @brief Time intervals data size. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_INTERVALS_SIZE) +#define CH_CFG_INTERVALS_SIZE 32 +#endif + +/** + * @brief Time types data size. + * @note Allowed values are 16 or 32 bits. + */ +#if !defined(CH_CFG_TIME_TYPES_SIZE) +#define CH_CFG_TIME_TYPES_SIZE 32 +#endif + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#if !defined(CH_CFG_ST_TIMEDELTA) +#define CH_CFG_ST_TIMEDELTA 20 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#if !defined(CH_CFG_TIME_QUANTUM) +#define CH_CFG_TIME_QUANTUM 0 +#endif + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#if !defined(CH_CFG_NO_IDLE_THREAD) +#define CH_CFG_NO_IDLE_THREAD FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_OPTIMIZE_SPEED) +#define CH_CFG_OPTIMIZE_SPEED TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TM) +#define CH_CFG_USE_TM TRUE +#endif + +/** + * @brief Time Stamps APIs. + * @details If enabled then the time time stamps APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TIMESTAMP) +#define CH_CFG_USE_TIMESTAMP TRUE +#endif + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_REGISTRY) +#define CH_CFG_USE_REGISTRY TRUE +#endif + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_WAITEXIT) +#define CH_CFG_USE_WAITEXIT TRUE +#endif + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_SEMAPHORES) +#define CH_CFG_USE_SEMAPHORES TRUE +#endif + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#endif + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MUTEXES) +#define CH_CFG_USE_MUTEXES TRUE +#endif + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#endif + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_CONDVARS) +#define CH_CFG_USE_CONDVARS TRUE +#endif + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#endif + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_EVENTS) +#define CH_CFG_USE_EVENTS TRUE +#endif + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#if !defined(CH_CFG_USE_EVENTS_TIMEOUT) +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#endif + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MESSAGES) +#define CH_CFG_USE_MESSAGES TRUE +#endif + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#if !defined(CH_CFG_USE_MESSAGES_PRIORITY) +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#endif + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#if !defined(CH_CFG_USE_DYNAMIC) +#define CH_CFG_USE_DYNAMIC TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name OSLIB options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_MAILBOXES) +#define CH_CFG_USE_MAILBOXES TRUE +#endif + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCORE) +#define CH_CFG_USE_MEMCORE TRUE +#endif + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#if !defined(CH_CFG_MEMCORE_SIZE) +#define CH_CFG_MEMCORE_SIZE 0 +#endif + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#if !defined(CH_CFG_USE_HEAP) +#define CH_CFG_USE_HEAP TRUE +#endif + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMPOOLS) +#define CH_CFG_USE_MEMPOOLS TRUE +#endif + +/** + * @brief Objects FIFOs APIs. + * @details If enabled then the objects FIFOs APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_FIFOS) +#define CH_CFG_USE_OBJ_FIFOS TRUE +#endif + +/** + * @brief Pipes APIs. + * @details If enabled then the pipes APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_PIPES) +#define CH_CFG_USE_PIPES TRUE +#endif + +/** + * @brief Objects Caches APIs. + * @details If enabled then the objects caches APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_CACHES) +#define CH_CFG_USE_OBJ_CACHES TRUE +#endif + +/** + * @brief Delegate threads APIs. + * @details If enabled then the delegate threads APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_DELEGATES) +#define CH_CFG_USE_DELEGATES TRUE +#endif + +/** + * @brief Jobs Queues APIs. + * @details If enabled then the jobs queues APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_JOBS) +#define CH_CFG_USE_JOBS TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Objects factory options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Objects Factory APIs. + * @details If enabled then the objects factory APIs are included in the + * kernel. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_CFG_USE_FACTORY) +#define CH_CFG_USE_FACTORY TRUE +#endif + +/** + * @brief Maximum length for object names. + * @details If the specified length is zero then the name is stored by + * pointer but this could have unintended side effects. + */ +#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#endif + +/** + * @brief Enables the registry of generic objects. + */ +#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#endif + +/** + * @brief Enables factory for generic buffers. + */ +#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#endif + +/** + * @brief Enables factory for semaphores. + */ +#if !defined(CH_CFG_FACTORY_SEMAPHORES) +#define CH_CFG_FACTORY_SEMAPHORES TRUE +#endif + +/** + * @brief Enables factory for mailboxes. + */ +#if !defined(CH_CFG_FACTORY_MAILBOXES) +#define CH_CFG_FACTORY_MAILBOXES TRUE +#endif + +/** + * @brief Enables factory for objects FIFOs. + */ +#if !defined(CH_CFG_FACTORY_OBJ_FIFOS) +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#endif + +/** + * @brief Enables factory for Pipes. + */ +#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_PIPES TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_STATISTICS) +#define CH_DBG_STATISTICS FALSE +#endif + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_SYSTEM_STATE_CHECK) +#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#endif + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_CHECKS) +#define CH_DBG_ENABLE_CHECKS FALSE +#endif + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_ASSERTS) +#define CH_DBG_ENABLE_ASSERTS FALSE +#endif + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_MASK) +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#endif + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_BUFFER_SIZE) +#define CH_DBG_TRACE_BUFFER_SIZE 128 +#endif + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#if !defined(CH_DBG_ENABLE_STACK_CHECK) +#define CH_DBG_ENABLE_STACK_CHECK FALSE +#endif + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_FILL_THREADS) +#define CH_DBG_FILL_THREADS FALSE +#endif + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#if !defined(CH_DBG_THREADS_PROFILING) +#define CH_DBG_THREADS_PROFILING FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System structure extension. + * @details User fields added to the end of the @p ch_system_t structure. + */ +#define CH_CFG_SYSTEM_EXTRA_FIELDS \ + /* Add system custom fields here.*/ + +/** + * @brief System initialization hook. + * @details User initialization code added to the @p chSysInit() function + * just before interrupts are enabled globally. + */ +#define CH_CFG_SYSTEM_INIT_HOOK() { \ + /* Add system initialization code here.*/ \ +} + +/** + * @brief OS instance structure extension. + * @details User fields added to the end of the @p os_instance_t structure. + */ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ + /* Add OS instance custom fields here.*/ + +/** + * @brief OS instance initialization hook. + * + * @param[in] oip pointer to the @p os_instance_t structure + */ +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ + /* Add OS instance initialization code here.*/ \ +} + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p _thread_init() function. + * + * @note It is invoked from within @p _thread_init() and implicitly from all + * the threads creation APIs. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + * + * @param[in] ntp thread being switched in + * @param[in] otp thread being switched out + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** + * @brief Runtime Faults Collection Unit hook. + * @details This hook is invoked each time new faults are collected and stored. + */ +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ + /* Faults handling code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#ifdef USB_DEBUG +#define PORT_HANDLE_FIFO_MESSAGE(core, message) \ + if (core == 0U) { process_command(message); } +#endif /* USB_DEBUG */ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/halconf.h b/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/halconf.h new file mode 100644 index 00000000..27434ddb --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/halconf.h @@ -0,0 +1,553 @@ +/* + ChibiOS - Copyright (C) 2006..2020 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 templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef HALCONF_H +#define HALCONF_H + +#define _CHIBIOS_HAL_CONF_ +#define _CHIBIOS_HAL_CONF_VER_7_1_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the cryptographic subsystem. + */ +#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__) +#define HAL_USE_CRY FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EFlash subsystem. + */ +#if !defined(HAL_USE_EFL) || defined(__DOXYGEN__) +#define HAL_USE_EFL FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SIO subsystem. + */ +#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__) +#define HAL_USE_SIO TRUE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the TRNG subsystem. + */ +#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__) +#define HAL_USE_TRNG FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB TRUE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/** + * @brief Enables the WSPI subsystem. + */ +#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__) +#define HAL_USE_WSPI FALSE +#endif + +/*===========================================================================*/ +/* PAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__) +#define PAL_USE_CALLBACKS FALSE +#endif + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__) +#define PAL_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/** + * @brief Enforces the driver to use direct callbacks rather than OSAL events. + */ +#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__) +#define CAN_ENFORCE_USE_CALLBACKS FALSE +#endif + +/*===========================================================================*/ +/* CRY driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the SW fall-back of the cryptographic driver. + * @details When enabled, this option, activates a fall-back software + * implementation for algorithms not supported by the underlying + * hardware. + * @note Fall-back implementations may not be present for all algorithms. + */ +#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_USE_FALLBACK FALSE +#endif + +/** + * @brief Makes the driver forcibly use the fall-back implementations. + */ +#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_ENFORCE_FALLBACK FALSE +#endif + +/*===========================================================================*/ +/* DAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__) +#define DAC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define DAC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the zero-copy API. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/** + * @brief OCR initialization constant for V20 cards. + */ +#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__) +#define SDC_INIT_OCR_V20 0x50FF8000U +#endif + +/** + * @brief OCR initialization constant for non-V20 cards. + */ +#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__) +#define SDC_INIT_OCR 0x80100000U +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 16 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SIO driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SIO_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SIO_DEFAULT_BITRATE 115200 +#endif + +/** + * @brief Support for thread synchronization API. + */ +#if !defined(SIO_USE_SYNCHRONIZATION) || defined(__DOXYGEN__) +#define SIO_USE_SYNCHRONIZATION TRUE +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 256 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/** + * @brief Serial over USB number of buffers. + * @note The default is 2 buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_NUMBER 2 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables circular transfers APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__) +#define SPI_USE_CIRCULAR FALSE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/** + * @brief Handling method for SPI CS line. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__) +#define SPI_SELECT_MODE SPI_SELECT_MODE_LINE +#endif + +/*===========================================================================*/ +/* UART driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__) +#define UART_USE_WAIT FALSE +#endif + +/** + * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define UART_USE_MUTUAL_EXCLUSION FALSE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* WSPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__) +#define WSPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define WSPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +#include "halconf_community.h" + +#endif /* HALCONF_H */ + +/** @} */ diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/halconf_community.h b/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/halconf_community.h new file mode 100644 index 00000000..fb7ebf6b --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/halconf_community.h @@ -0,0 +1,180 @@ +/* + ChibiOS - Copyright (C) 2014 Uladzimir Pylinsky aka barthess + + 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. +*/ + +#ifndef HALCONF_COMMUNITY_H +#define HALCONF_COMMUNITY_H + +/** + * @brief Enables the community overlay. + */ +#if !defined(HAL_USE_COMMUNITY) || defined(__DOXYGEN__) +#define HAL_USE_COMMUNITY TRUE +#endif + +/** + * @brief Enables the FSMC subsystem. + */ +#if !defined(HAL_USE_FSMC) || defined(__DOXYGEN__) +#define HAL_USE_FSMC FALSE +#endif + +/** + * @brief Enables the NAND subsystem. + */ +#if !defined(HAL_USE_NAND) || defined(__DOXYGEN__) +#define HAL_USE_NAND FALSE +#endif + +/** + * @brief Enables the 1-wire subsystem. + */ +#if !defined(HAL_USE_ONEWIRE) || defined(__DOXYGEN__) +#define HAL_USE_ONEWIRE FALSE +#endif + +/** + * @brief Enables the EICU subsystem. + */ +#if !defined(HAL_USE_EICU) || defined(__DOXYGEN__) +#define HAL_USE_EICU FALSE +#endif + +/** + * @brief Enables the CRC subsystem. + */ +#if !defined(HAL_USE_CRC) || defined(__DOXYGEN__) +#define HAL_USE_CRC FALSE +#endif + +/** + * @brief Enables the RNG subsystem. + */ +#if !defined(HAL_USE_RNG) || defined(__DOXYGEN__) +#define HAL_USE_RNG FALSE +#endif + +/** + * @brief Enables the EEPROM subsystem. + */ +#if !defined(HAL_USE_EEPROM) || defined(__DOXYGEN__) +#define HAL_USE_EEPROM FALSE +#endif + +/** + * @brief Enables the TIMCAP subsystem. + */ +#if !defined(HAL_USE_TIMCAP) || defined(__DOXYGEN__) +#define HAL_USE_TIMCAP FALSE +#endif + +/** + * @brief Enables the TIMCAP subsystem. + */ +#if !defined(HAL_USE_COMP) || defined(__DOXYGEN__) +#define HAL_USE_COMP FALSE +#endif + +/** + * @brief Enables the QEI subsystem. + */ +#if !defined(HAL_USE_QEI) || defined(__DOXYGEN__) +#define HAL_USE_QEI FALSE +#endif + +/** + * @brief Enables the USBH subsystem. + */ +#if !defined(HAL_USE_USBH) || defined(__DOXYGEN__) +#define HAL_USE_USBH FALSE +#endif + +/** + * @brief Enables the USB_MSD subsystem. + */ +#if !defined(HAL_USE_USB_MSD) || defined(__DOXYGEN__) +#define HAL_USE_USB_MSD FALSE +#endif + +/** + * @brief Enables the USB_HID subsystem. + */ +#if !defined(HAL_USE_USB_HID) || defined(__DOXYGEN__) +#define HAL_USE_USB_HID TRUE +#endif + +/*===========================================================================*/ +/* FSMCNAND driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the @p nandAcquireBus() and @p nanReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(NAND_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define NAND_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* 1-wire driver related settings. */ +/*===========================================================================*/ +/** + * @brief Enables strong pull up feature. + * @note Disabling this option saves both code and data space. + */ +#define ONEWIRE_USE_STRONG_PULLUP FALSE + +/** + * @brief Enables search ROM feature. + * @note Disabling this option saves both code and data space. + */ +#define ONEWIRE_USE_SEARCH_ROM TRUE + +/*===========================================================================*/ +/* QEI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables discard of overlow + */ +#if !defined(QEI_USE_OVERFLOW_DISCARD) || defined(__DOXYGEN__) +#define QEI_USE_OVERFLOW_DISCARD FALSE +#endif + +/** + * @brief Enables min max of overlow + */ +#if !defined(QEI_USE_OVERFLOW_MINMAX) || defined(__DOXYGEN__) +#define QEI_USE_OVERFLOW_MINMAX FALSE +#endif + +/*===========================================================================*/ +/* EEProm driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables 24xx series I2C eeprom device driver. + * @note Disabling this option saves both code and data space. + */ +#define EEPROM_USE_EE24XX FALSE + /** + * @brief Enables 25xx series SPI eeprom device driver. + * @note Disabling this option saves both code and data space. + */ +#define EEPROM_USE_EE25XX FALSE + +#endif /* HALCONF_COMMUNITY_H */ + +/** @} */ diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/mcuconf.h b/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/mcuconf.h new file mode 100644 index 00000000..c45cde0a --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/cfg/mcuconf.h @@ -0,0 +1,80 @@ +/* + ChibiOS - Copyright (C) 2006..2021 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. +*/ + +#ifndef MCUCONF_H +#define MCUCONF_H + +/* + * RP2040_MCUCONF drivers configuration. + * + * IRQ priorities: + * 3...0 Lowest...Highest. + * + * DMA priorities: + * 0...1 Lowest...Highest. + */ + +#define RP2040_MCUCONF + +/* + * HAL driver system settings. + */ +#define RP_NO_INIT FALSE +#define RP_CORE1_START TRUE +#define RP_CORE1_VECTORS_TABLE _vectors +#define RP_CORE1_ENTRY_POINT _crt0_c1_entry +#define RP_CORE1_STACK_END __c1_main_stack_end__ + +/* + * IRQ system settings. + */ +#define RP_IRQ_SYSTICK_PRIORITY 2 +#define RP_IRQ_TIMER_ALARM0_PRIORITY 2 +#define RP_IRQ_TIMER_ALARM1_PRIORITY 2 +#define RP_IRQ_TIMER_ALARM2_PRIORITY 2 +#define RP_IRQ_TIMER_ALARM3_PRIORITY 2 +#define RP_IRQ_UART0_PRIORITY 3 +#define RP_IRQ_UART1_PRIORITY 3 +#define RP_IRQ_SPI0_PRIORITY 2 +#define RP_IRQ_SPI1_PRIORITY 2 + +/* + * SIO driver system settings. + */ +#define RP_SIO_USE_UART0 TRUE +#define RP_SIO_USE_UART1 TRUE + +/* + * SPI driver system settings. + */ +#define RP_SPI_USE_SPI0 FALSE +#define RP_SPI_USE_SPI1 FALSE +#define RP_SPI_SPI0_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY +#define RP_SPI_SPI0_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY +#define RP_SPI_SPI1_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY +#define RP_SPI_SPI1_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY +#define RP_SPI_SPI0_DMA_PRIORITY 1 +#define RP_SPI_SPI1_DMA_PRIORITY 1 +#define RP_SPI_DMA_ERROR_HOOK(spip) + +/* + * USB driver system settings. + */ +#define RP_USB_USE_USBD1 TRUE +#define RP_USB_FORCE_VBUS_DETECT TRUE +#define RP_USB_USE_SOF_INTR FALSE + +#endif /* MCUCONF_H */ diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/debug/RT-RP2040-PICO (build-ch.elf)(OpenOCD, Flash and Run).launch b/testhal/RP/RP2040/RT-RP2040-PICO-HID/debug/RT-RP2040-PICO (build-ch.elf)(OpenOCD, Flash and Run).launch new file mode 100644 index 00000000..e9ddc915 --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/debug/RT-RP2040-PICO (build-ch.elf)(OpenOCD, Flash and Run).launch @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/debug/RT-RP2040-PICO (build-ch.elf)(OpenOCD, Just Run).launch b/testhal/RP/RP2040/RT-RP2040-PICO-HID/debug/RT-RP2040-PICO (build-ch.elf)(OpenOCD, Just Run).launch new file mode 100644 index 00000000..8f0e86ea --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/debug/RT-RP2040-PICO (build-ch.elf)(OpenOCD, Just Run).launch @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/main.c b/testhal/RP/RP2040/RT-RP2040-PICO-HID/main.c new file mode 100644 index 00000000..4da985be --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/main.c @@ -0,0 +1,124 @@ +/* + ChibiOS - Copyright (C) 2006..2018 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. +*/ + +#include "ch.h" +#include "hal.h" + +//#include "chprintf.h" + +#include "usbcfg.h" + +#define LED_GREEN_PIN 25U + +//semaphore_t blinker_sem; + +/* + * Green LED blinker thread, times are in milliseconds. + */ +static CH_SYS_CORE0_MEMORY THD_WORKING_AREA(waThread1, 128); +static THD_FUNCTION(Thread1, arg) { + + (void)arg; + chRegSetThreadName("blinker"); + while (true) { + //chSemWait(&blinker_sem); + systime_t time = USBD1.state == USB_ACTIVE ? 125 : 1000; + chThdSleepMilliseconds(time); + palToggleLine(LED_GREEN_PIN); + } +} + +/* + * Application entry point. + */ +int main(void) { + + /* + * Shared objects initialization. + */ + //chSemObjectInit(&blinker_sem, 0); + + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + chSysInit(); + +/* + palSetLineMode(0U, PAL_MODE_ALTERNATE_UART); + palSetLineMode(1U, PAL_MODE_ALTERNATE_UART); +*/ + /* + * Activates the UART0 SIO driver using the default configuration. + */ + /* + sioStart(&SIOD0, NULL); + sioStartOperation(&SIOD0, NULL); +*/ + /* + * Initializes a USB HID driver. + */ + + hidObjectInit(&UHD1); + hidStart(&UHD1, &usbhidcfg); + + /* + * Activates the USB driver and then the USB bus pull-up on D+. + * Note, a delay is inserted in order to not have to disconnect the cable + * after a reset. + */ + //chprintf((BaseSequentialStream *)&SIOD0, "-- Start usb connection\r\n"); + + usbDisconnectBus(usbhidcfg.usbp); + chThdSleepMilliseconds(1000); + usbStart(usbhidcfg.usbp, &usbcfg); + usbConnectBus(usbhidcfg.usbp); + + /* + * Setting up GPIOs. + */ + palSetLineMode(LED_GREEN_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_RP_PAD_DRIVE12); + + /* + * Creates the blinker thread. + */ + chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); + + //BaseSequentialStream *chp = &SIOD0; + //chprintf((BaseSequentialStream *)&SIOD0, "-- Started in c0\r\n"); + + /* + * Normal main() thread activity, in this demo it does nothing except + * sleeping in a loop. + */ + while (true) { +/* + if (usbhidcfg.usbp->state == USB_ACTIVE) { + uint8_t report; + size_t n = hidGetReport(0, &report, sizeof(report)); + hidWriteReport(&UHD1, &report, n); + n = hidReadReportt(&UHD1, &report, sizeof(report), TIME_IMMEDIATE); + if (n > 0) + hidSetReport(0, &report, n); + } +*/ + chThdSleepMilliseconds(500); + } +} diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/rules_code_with_boot2.ld b/testhal/RP/RP2040/RT-RP2040-PICO-HID/rules_code_with_boot2.ld new file mode 100644 index 00000000..b066c249 --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/rules_code_with_boot2.ld @@ -0,0 +1,80 @@ +/* + ChibiOS - Copyright (C) 2006..2018 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. +*/ + +ENTRY(Reset_Handler) + +SECTIONS +{ + .vectors : ALIGN(256) + { + KEEP(*(.vectors)) + } > VECTORS_FLASH AT > VECTORS_FLASH_LMA + + .xtors : ALIGN(4) + { + __init_array_base__ = .; + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + __init_array_end__ = .; + __fini_array_base__ = .; + KEEP(*(.fini_array)) + KEEP(*(SORT(.fini_array.*))) + __fini_array_end__ = .; + } > XTORS_FLASH AT > XTORS_FLASH_LMA + + .text : ALIGN_WITH_INPUT + { + __text_base__ = .; + *(.text) + *(.text.*) + *(.glue_7t) + *(.glue_7) + *(.gcc*) + __text_end__ = .; + } > TEXT_FLASH AT > TEXT_FLASH_LMA + + .rodata : ALIGN(4) + { + __rodata_base__ = .; + *(.rodata) + *(.rodata.*) + . = ALIGN(4); + __rodata_end__ = .; + } > RODATA_FLASH AT > RODATA_FLASH_LMA + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > VARIOUS_FLASH AT > VARIOUS_FLASH_LMA + + .ARM.exidx : { + __exidx_base__ = .; + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end__ = .; + __exidx_end = .; + } > VARIOUS_FLASH AT > VARIOUS_FLASH_LMA + + .eh_frame_hdr : + { + *(.eh_frame_hdr) + } > VARIOUS_FLASH AT > VARIOUS_FLASH_LMA + + .eh_frame : ONLY_IF_RO + { + *(.eh_frame) + } > VARIOUS_FLASH AT > VARIOUS_FLASH_LMA +} diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/usbcfg.c b/testhal/RP/RP2040/RT-RP2040-PICO-HID/usbcfg.c new file mode 100644 index 00000000..eb5f49d9 --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/usbcfg.c @@ -0,0 +1,418 @@ +/* + Copyright (C) 2016 Jonathan Struebel + + 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 usbcfg.c + * @brief USB driver config. + * + * @addtogroup USB + * @{ + */ +#include "hal.h" +#include "usbcfg.h" + +/* + * Endpoints to be used for USBD1. + */ +#define USBD1_DATA_REQUEST_EP 1 +#define USBD1_DATA_AVAILABLE_EP 1 + +/* + * USB HID Driver structure. + */ +USBHIDDriver UHD1; + +/* + * Data used for feedback + */ +uint8_t increment_var = 0; + +/* + * USB Device Descriptor. + */ +static const uint8_t hid_device_descriptor_data[18] = { + USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */ + 0x00, /* bDeviceClass. */ + 0x00, /* bDeviceSubClass. */ + 0x00, /* bDeviceProtocol. */ + 0x40, /* bMaxPacketSize. */ + 0x0179, /* idVendor. */ + 0x0002, /* idProduct. */ + 0x0200, /* bcdDevice. */ + 1, /* iManufacturer. */ + 2, /* iProduct. */ + 3, /* iSerialNumber. */ + 1) /* bNumConfigurations. */ +}; + +/* + * Device Descriptor wrapper. + */ +static const USBDescriptor hid_device_descriptor = { + sizeof hid_device_descriptor_data, + hid_device_descriptor_data +}; + +/* + * Configuration Descriptor tree for a HID device + * + * The HID Specifications version 1.11 require the following order: + * - Configuration Descriptor + * - Interface Descriptor + * - HID Descriptor + * - Endpoints Descriptors + */ +#define HID_DESCRIPTOR_OFFSET 18 +#define HID_DESCRIPTOR_SIZE USB_DESC_HID_SIZE + +static const uint8_t hid_configuration_descriptor_data[41] = { + /* Configuration Descriptor.*/ + USB_DESC_CONFIGURATION(41, /* wTotalLength. */ + 0x01, /* bNumInterfaces. */ + 0x01, /* bConfigurationValue. */ + 0, /* iConfiguration. */ + 0xC0, /* bmAttributes (self powered). */ + 50), /* bMaxPower (100mA). */ + /* Interface Descriptor.*/ + USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */ + 0x00, /* bAlternateSetting. */ + 0x02, /* bNumEndpoints. */ + 0x03, /* bInterfaceClass (HID Interface + Class). */ + 0x00, /* bInterfaceSubClass (None). */ + 0x00, /* bInterfaceProtocol (None). */ + 0), /* iInterface. */ + /* HID Descriptor.*/ + USB_DESC_HID (0x0110, /* bcdHID. */ + 0x00, /* bCountryCode. */ + 0x01, /* bNumDescriptors. */ + 0x22, /* bDescriptorType (Report + Descriptor). */ + 34), /* wDescriptorLength. */ + /* Endpoint 1 Descriptor.*/ + USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/ + 0x03, /* bmAttributes (Interrupt). */ + 0x0040, /* wMaxPacketSize. */ + 0x0A), /* bInterval (10ms). */ + /* Endpoint 1 Descriptor.*/ + USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/ + 0x03, /* bmAttributes (Interrupt). */ + 0x0040, /* wMaxPacketSize. */ + 0x0A) /* bInterval (10ms). */ +}; + +/* + * Configuration Descriptor wrapper. + */ +static const USBDescriptor hid_configuration_descriptor = { + sizeof hid_configuration_descriptor_data, + hid_configuration_descriptor_data +}; + +/* + * HID Descriptor wrapper. + */ +static const USBDescriptor hid_descriptor = { + HID_DESCRIPTOR_SIZE, + &hid_configuration_descriptor_data[HID_DESCRIPTOR_OFFSET] +}; + +/* + * HID Report Descriptor + * + * This is the description of the format and the content of the + * different IN or/and OUT reports that your application can + * receive/send + * + * See "Device Class Definition for Human Interface Devices (HID)" + * (http://www.usb.org/developers/hidpage/HID1_11.pdf) for the + * detailed description of all the fields + */ +static const uint8_t hid_report_descriptor_data[] = { + USB_DESC_BYTE (0x06), /* Usage Page - */ + USB_DESC_WORD (0xFF00), /* Vendor Defined. */ + USB_DESC_BYTE (0x09), /* Usage - */ + USB_DESC_BYTE (0x01), /* Vendor Defined. */ + USB_DESC_BYTE (0xA1), /* Collection - */ + USB_DESC_BYTE (0x01), /* Application. */ + + USB_DESC_BYTE (0x09), /* Usage - */ + USB_DESC_BYTE (0x01), /* Vendor Defined. */ + USB_DESC_BYTE (0x15), /* Logical Minimum - */ + USB_DESC_BYTE (0x00), /* 0. */ + USB_DESC_BYTE (0x26), /* Logical Maximum - */ + USB_DESC_WORD (0x00FF), /* 255. */ + USB_DESC_BYTE (0x75), /* Report size - */ + USB_DESC_BYTE (0x08), /* 8 bits. */ + USB_DESC_BYTE (0x95), /* Report count - */ + USB_DESC_BYTE (0x01), /* 1. */ + USB_DESC_BYTE (0x81), /* Input - */ + USB_DESC_BYTE (0x02), /* Data, Variable, Absolute. */ + + USB_DESC_BYTE (0x09), /* Usage - */ + USB_DESC_BYTE (0x01), /* Vendor Defined. */ + USB_DESC_BYTE (0x15), /* Logical Minimum - */ + USB_DESC_BYTE (0x00), /* 0. */ + USB_DESC_BYTE (0x26), /* Logical Maximum - */ + USB_DESC_WORD (0x00FF), /* 255. */ + USB_DESC_BYTE (0x75), /* Report Size - */ + USB_DESC_BYTE (0x08), /* 8 bits. */ + USB_DESC_BYTE (0x95), /* Report Count - */ + USB_DESC_BYTE (0x01), /* 1. */ + USB_DESC_BYTE (0x91), /* Output - */ + USB_DESC_BYTE (0x02), /* Data, Variable, Absolute. */ + + USB_DESC_BYTE (0xC0) /* End Collection. */ +}; + +/* + * HID Report Descriptor wrapper + */ +static const USBDescriptor hid_report_descriptor = { + sizeof hid_report_descriptor_data, + hid_report_descriptor_data +}; + +/* + * U.S. English language identifier. + */ +static const uint8_t hid_string0[] = { + USB_DESC_BYTE(2+2*1), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */ +}; + +/* + * Vendor string. + */ +static const uint8_t hid_string1[] = { + USB_DESC_BYTE(2+2*7), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + 'N', 0, 'o', 0, 'p', 0, 'e', 0, 'L', 0, 'a', 0, 'b', 0, +}; + +/* + * Device Description string. + */ +static const uint8_t hid_string2[] = { + USB_DESC_BYTE(2+5*2), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + 'C', 0, 'h', 0, 'T', 0, 's', 0, 'y', 0, +}; + +/* + * Serial Number string. + */ +static const uint8_t hid_string3[] = { + USB_DESC_BYTE(2+2*3), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + '0' + CH_KERNEL_MAJOR, 0, + '0' + CH_KERNEL_MINOR, 0, + '0' + CH_KERNEL_PATCH, 0 +}; + +/* + * Strings wrappers array. + */ +static const USBDescriptor hid_strings[] = { + {sizeof hid_string0, hid_string0}, + {sizeof hid_string1, hid_string1}, + {sizeof hid_string2, hid_string2}, + {sizeof hid_string3, hid_string3} +}; + +/* + * Handles the GET_DESCRIPTOR callback. All required descriptors must be + * handled here. + */ +static const USBDescriptor *get_descriptor(USBDriver *usbp, + uint8_t dtype, + uint8_t dindex, + uint16_t lang) { + (void)usbp; + (void)lang; + switch (dtype) { + case USB_DESCRIPTOR_DEVICE: + return &hid_device_descriptor; + case USB_DESCRIPTOR_CONFIGURATION: + return &hid_configuration_descriptor; + case USB_DESCRIPTOR_STRING: + if (dindex < 4) + return &hid_strings[dindex]; + case USB_DESCRIPTOR_INTERFACE: + break; + case USB_DESCRIPTOR_ENDPOINT: + break; + case USB_DESCRIPTOR_HID: + return &hid_descriptor; + case HID_REPORT: + return &hid_report_descriptor; + default: + break; + } + return NULL; +} + +/** + * @brief IN EP1 state. + */ +static USBInEndpointState ep1instate; + +/** + * @brief OUT EP1 state. + */ +static USBOutEndpointState ep1outstate; + +/** + * @brief EP1 initialization structure (both IN and OUT). + */ +static const USBEndpointConfig ep1config = { + USB_EP_MODE_TYPE_INTR, + NULL, + hidDataTransmitted, + hidDataReceived, + 0x0040, + 0x0040, + &ep1instate, + &ep1outstate, +}; + +/* + * Handles the USB driver global events. + */ +static void usb_event(USBDriver *usbp, usbevent_t event) { +// (void)usbp; + switch (event) { + case USB_EVENT_RESET: + return; + case USB_EVENT_ADDRESS: + return; + case USB_EVENT_CONFIGURED: + osalSysLockFromISR(); + + /* Enables the endpoints specified into the configuration. + Note, this callback is invoked from an ISR so I-Class functions + must be used.*/ + usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config); + + /* Resetting the state of the CDC subsystem.*/ + hidConfigureHookI(&UHD1); + + osalSysUnlockFromISR(); + return; + case USB_EVENT_UNCONFIGURED: + return; + case USB_EVENT_SUSPEND: + return; + case USB_EVENT_WAKEUP: + return; + case USB_EVENT_STALLED: + return; + } + return; +} + +static bool req_handler(USBDriver *usbp) { + size_t n; + + if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) { + switch (usbp->setup[1]) { + case HID_GET_REPORT: + n = hidGetReport(0, &increment_var, sizeof(increment_var)); + usbSetupTransfer(usbp, &increment_var, n, NULL); + return true; + default: + return hidRequestsHook(usbp); + } + } + return hidRequestsHook(usbp); +} + +#if 0 +/* + * Handles the USB driver global events. + */ +static void sof_handler(USBDriver *usbp) { + + (void)usbp; + + osalSysLockFromISR(); + sduSOFHookI(&SDU1); + osalSysUnlockFromISR(); +} +#endif + +/** + * @brief Generate HID Report + * @details This function generates the data for an HID report so + * that it can be transferred to the host. + * + * @param[in] id report ID + * @param[out] bp data buffer pointer + * @param[in] n the maximum number of bytes for data buffer + * @return number of bytes of report in data buffer + */ +size_t hidGetReport(uint8_t id, uint8_t *bp, size_t n) { + + (void) id; + (void) n; + + increment_var++; + *bp = increment_var; + return sizeof(increment_var); +} + +/** + * @brief Set HID Report + * @details This function sets the data for an HID report + * that was transferred from the host. + * + * @param[in] id report ID + * @param[in] bp data buffer pointer + * @param[in] n the number of bytes in data buffer + * @return The operation status. + * @retval MSG_OK if the report was set. + */ +msg_t hidSetReport(uint8_t id, uint8_t *bp, size_t n) { + + (void) id; + (void) n; + + increment_var = *bp; + return MSG_OK; +} + +/* + * USB driver configuration. + */ +const USBConfig usbcfg = { + usb_event, + get_descriptor, + req_handler, + NULL + /*sof_handler*/ +}; + +/* + * USB HID driver configuration. + */ +const USBHIDConfig usbhidcfg = { + &USBD1, + USBD1_DATA_REQUEST_EP, + USBD1_DATA_AVAILABLE_EP +}; + +/** @} */ diff --git a/testhal/RP/RP2040/RT-RP2040-PICO-HID/usbcfg.h b/testhal/RP/RP2040/RT-RP2040-PICO-HID/usbcfg.h new file mode 100644 index 00000000..3d69417f --- /dev/null +++ b/testhal/RP/RP2040/RT-RP2040-PICO-HID/usbcfg.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2016 Jonathan Struebel + + 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 usbcfg.h + * @brief USB driver config header. + * + * @addtogroup USB + * @{ + */ + +#ifndef USBCFG_H +#define USBCFG_H + +#include "hal_usb_hid.h" + +extern const USBConfig usbcfg; +extern const USBHIDConfig usbhidcfg; +extern USBHIDDriver UHD1; + +#ifdef __cplusplus +extern "C" { +#endif + size_t hidGetReport(uint8_t id, uint8_t *bp, size_t n); + msg_t hidSetReport(uint8_t id, uint8_t *bp, size_t n); +#ifdef __cplusplus +} +#endif + +#endif /* USBCFG_H */ + +/** @} */