aboutsummaryrefslogtreecommitdiff
path: root/platform/stm32f0xx/usbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/stm32f0xx/usbc.c')
-rw-r--r--platform/stm32f0xx/usbc.c357
1 files changed, 0 insertions, 357 deletions
diff --git a/platform/stm32f0xx/usbc.c b/platform/stm32f0xx/usbc.c
deleted file mode 100644
index 4fe68147..00000000
--- a/platform/stm32f0xx/usbc.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (c) 2015 Travis Geiselbrecht
- * Copyright (c) 2015 Erik Gilling
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <reg.h>
-#include <trace.h>
-#include <debug.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <err.h>
-#include <dev/usb.h>
-#include <dev/usbc.h>
-#include <arch/arm/cm.h>
-#include <platform/rcc.h>
-#include <platform/stm32.h>
-#include <platform/usbc.h>
-
-#include <stm32f0xx_hal_pcd.h>
-
-#define LOCAL_TRACE 0
-
-#define NUM_EP 5
-
-// This driver is a shim between the LK usbc api and the STMico Cube api.
-// Ideally this would be a full native driver. Given how long it took to
-// debug this one, I don't have the patience to make it native.
-
-struct ep_status {
- bool ack_ep0_in;
- usbc_transfer_t *transfer;
-};
-
-static struct {
- bool do_resched;
-
- struct ep_status ep_in[NUM_EP];
- struct ep_status ep_out[NUM_EP];
-
- uint32_t pma_highwater;
-
- PCD_HandleTypeDef handle;
-} usbc;
-
-uint32_t stm32_usbc_pma_alloc(uint32_t size) {
- // TODO(konkers): Fail on OOM
- uint32_t addr = usbc.pma_highwater;
- usbc.pma_highwater += size;
- return addr;
-}
-
-void stm32_usbc_early_init(stm32_usb_clk_t clock_source)
-{
- // TODO(konkers): add usb clock source to rcc.
-#if 0
- if (clock_source == STM32_USB_CLK_HSI48) {
- RCC_USBCLKConfig(RCC_USBCLK_HSI48);
- } else {
- RCC_USBCLKConfig(RCC_USBCLK_PLLCLK);
- }
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
-#endif
-}
-
-void stm32_usbc_init(void)
-{
- LTRACE_ENTRY;
-
- usbc.pma_highwater = 0x40;
-
- // Set LL Driver parameters
- usbc.handle.Instance = USB;
- usbc.handle.Init.dev_endpoints = 4;
- usbc.handle.Init.ep0_mps = 0x40;
- usbc.handle.Init.phy_itface = PCD_PHY_EMBEDDED;
- usbc.handle.Init.speed = PCD_SPEED_FULL;
- usbc.handle.Init.low_power_enable = 0;
- usbc.handle.Init.lpm_enable = 0;
- usbc.handle.Init.battery_charging_enable = 0;
-
- // Initialize LL Driver
- HAL_PCD_Init(&usbc.handle);
-
- HAL_PCDEx_PMAConfig(&usbc.handle, 0x00, PCD_SNG_BUF,
- stm32_usbc_pma_alloc(0x40));
- HAL_PCDEx_PMAConfig(&usbc.handle, 0x80, PCD_SNG_BUF,
- stm32_usbc_pma_alloc(0x40));
-
-}
-
-void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
-{
- LTRACE_ENTRY;
- // Enable USB FS Clock
- stm32_rcc_set_enable(STM32_RCC_CLK_USB, true);
- NVIC_EnableIRQ(USB_IRQn);
-}
-
-void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
-{
- LTRACEF("epnum %u\n", epnum);
-
- if (epnum == 0) {
- usbc_ep0_ack();
- } else if (usbc.ep_out[epnum].transfer) {
- // completing a transfer
- usbc_transfer_t *t = usbc.ep_out[epnum].transfer;
- usbc.ep_out[epnum].transfer = NULL;
-
- LTRACEF("completing transfer %p\n", t);
-
- PCD_EPTypeDef *ep = &hpcd->OUT_ep[epnum];
- t->bufpos = ep->xfer_count;
- t->result = 0;
- t->callback(epnum, t);
- usbc.do_resched = true;
- }
-}
-
-void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
-{
- PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
- LTRACEF("epnum %u, xfer count %u len %u\n", epnum, ep->xfer_count, ep->xfer_len);
-
- if (epnum == 0) {
- // TODO(konkers): implement multi packet.
- struct ep_status *ep = &usbc.ep_in[0];
- if (ep->ack_ep0_in) {
- // in transfer done, ready for receive status
- HAL_PCD_EP_Receive(&usbc.handle, 0, 0, 0);
- }
- } else {
- // in transfer done
- if (usbc.ep_in[epnum].transfer) {
- // completing a transfer
- usbc_transfer_t *t = usbc.ep_in[epnum].transfer;
- usbc.ep_in[epnum].transfer = NULL;
-
- LTRACEF("completing transfer %p\n", t);
-
- PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
- t->bufpos = ep->xfer_count;
- t->result = 0;
- t->callback(epnum, t);
- usbc.do_resched = true;
- }
- }
-}
-
-void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
-{
- //LTRACE_ENTRY;
-
- union usb_callback_args args;
- args.setup = (struct usb_setup *)hpcd->Setup;
-
- usbc_callback(USB_CB_SETUP_MSG, &args);
- usbc.do_resched = true;
-}
-
-void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
-{
- //LTRACE_ENTRY;
-}
-
-void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
-{
- LTRACE_ENTRY;
-
-
- /* fail all the outstanding transactions */
- for (uint i = 0; i < NUM_EP; i++) {
- if (usbc.ep_in[i].transfer) {
- usbc_transfer_t *t = usbc.ep_in[i].transfer;
- usbc.ep_in[i].transfer = NULL;
- t->result = ERR_CANCELLED;
- t->callback(i, t);
- }
- if (usbc.ep_out[i].transfer) {
- usbc_transfer_t *t = usbc.ep_out[i].transfer;
- usbc.ep_out[i].transfer = NULL;
- t->result = ERR_CANCELLED;
- t->callback(i, t);
- }
- }
-
- HAL_PCD_EP_Open(&usbc.handle, 0, 0x40, PCD_EP_TYPE_CTRL);
- HAL_PCD_EP_Open(&usbc.handle, 0x80, 0x40, PCD_EP_TYPE_CTRL);
-
- usbc_callback(USB_CB_RESET, NULL);
- usbc.do_resched = true;
-}
-
-void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
-{
- LTRACE_ENTRY;
- usbc_callback(USB_CB_SUSPEND, NULL);
-}
-
-void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
-{
- LTRACE_ENTRY;
- usbc_callback(USB_CB_RESUME, NULL);
-}
-
-void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
-{
- LTRACEF("epnum %u\n", epnum);
-}
-
-void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
-{
- LTRACEF("epnum %u\n", epnum);
-}
-
-void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
-{
- LTRACE_ENTRY;
-}
-
-void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
-{
- LTRACE_ENTRY;
-}
-
-status_t usbc_set_active(bool active)
-{
- LTRACEF("active %u\n", active);
-
- if (active) {
- HAL_PCD_Start(&usbc.handle);
- } else {
- HAL_PCD_Stop(&usbc.handle);
- }
-
- return NO_ERROR;
-}
-
-void usbc_set_address(uint8_t address)
-{
- LTRACEF("address %u\n", address);
- HAL_PCD_SetAddress(&usbc.handle, address);
-}
-
-void usbc_ep0_ack(void)
-{
- LTRACE;
-
- struct ep_status *ep = &usbc.ep_in[0];
- ep->ack_ep0_in = false;
- HAL_PCD_EP_Transmit(&usbc.handle, 0, 0, 0);
-}
-
-void usbc_ep0_stall(void)
-{
- LTRACE;
-
- HAL_PCD_EP_SetStall(&usbc.handle, 0x80);
-}
-
-void usbc_ep0_send(const void *buf, size_t len, size_t maxlen)
-{
- LTRACEF("buf %p, len %zu, maxlen %zu\n", buf, len, maxlen);
-
- struct ep_status *ep = &usbc.ep_in[0];
- ep->ack_ep0_in = true;
- HAL_PCD_EP_Transmit(&usbc.handle, 0, (void *)buf, MIN(len, maxlen));
-}
-
-void usbc_ep0_recv(void *buf, size_t len, ep_callback cb)
-{
- PANIC_UNIMPLEMENTED;
-}
-
-status_t usbc_setup_endpoint(ep_t ep, ep_dir_t dir, uint width, ep_type_t type)
-{
- LTRACEF("ep %u dir %u width %u\n", ep, dir, width);
-
- DEBUG_ASSERT(ep <= NUM_EP);
- // PCD_EP_TYPE* and USB_* have the same values. Let's make sure that
- // doesn't change.
- DEBUG_ASSERT(PCD_EP_TYPE_CTRL == USB_CTRL);
- DEBUG_ASSERT(PCD_EP_TYPE_ISOC == USB_ISOC);
- DEBUG_ASSERT(PCD_EP_TYPE_BULK == USB_BULK);
- DEBUG_ASSERT(PCD_EP_TYPE_INTR == USB_INTR);
-
- uint8_t ep_addr = ep | ((dir == USB_IN) ? 0x80 : 0);
-
- HAL_PCDEx_PMAConfig(&usbc.handle, ep_addr, PCD_SNG_BUF,
- stm32_usbc_pma_alloc(width));
-
- HAL_StatusTypeDef ret = HAL_PCD_EP_Open(&usbc.handle, ep_addr, width, type);
-
- return (ret == HAL_OK) ? NO_ERROR : ERR_GENERIC;
-}
-
-bool usbc_is_highspeed(void)
-{
- return false;
-}
-
-status_t usbc_queue_rx(ep_t ep, usbc_transfer_t *transfer)
-{
- LTRACEF("ep %u, transfer %p (buf %p, buflen %zu)\n", ep, transfer, transfer->buf, transfer->buflen);
-
- DEBUG_ASSERT(ep <= NUM_EP);
- DEBUG_ASSERT(usbc.ep_out[ep].transfer == NULL);
-
- usbc.ep_out[ep].transfer = transfer;
- HAL_PCD_EP_Receive(&usbc.handle, ep, transfer->buf, transfer->buflen);
-
- return NO_ERROR;
-}
-
-status_t usbc_queue_tx(ep_t ep, usbc_transfer_t *transfer)
-{
- LTRACEF("ep %u, transfer %p (buf %p, buflen %zu)\n", ep, transfer, transfer->buf, transfer->buflen);
-
- DEBUG_ASSERT(ep <= NUM_EP);
- DEBUG_ASSERT(usbc.ep_in[ep].transfer == NULL);
-
- usbc.ep_in[ep].transfer = transfer;
- HAL_PCD_EP_Transmit(&usbc.handle, ep, transfer->buf, transfer->buflen);
-
- return NO_ERROR;
-}
-
-void stm32_USB_IRQ(void)
-{
- arm_cm_irq_entry();
- //LTRACE_ENTRY;
-
- usbc.do_resched = false;
- HAL_PCD_IRQHandler(&usbc.handle);
-
- arm_cm_irq_exit(usbc.do_resched);
-}