/* * This file is part of the libopencm3 project. * * Copyright (C) 2010 Gareth McMullin * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ #include #include #include #include #include #include #include "../usb/usb_private.h" #include "common/st_usbfs_core.h" static usbd_device *st_usbfs_v1_usbd_init(void); const struct _usbd_driver st_usbfs_v1_usb_driver = { .init = st_usbfs_v1_usbd_init, .set_address = st_usbfs_set_address, .ep_setup = st_usbfs_ep_setup, .ep_reset = st_usbfs_endpoints_reset, .ep_stall_set = st_usbfs_ep_stall_set, .ep_stall_get = st_usbfs_ep_stall_get, .ep_nak_set = st_usbfs_ep_nak_set, .ep_write_packet = st_usbfs_ep_write_packet, .ep_read_packet = st_usbfs_ep_read_packet, .poll = st_usbfs_poll, }; /** Initialize the USB device controller hardware of the STM32. */ static usbd_device *st_usbfs_v1_usbd_init(void) { rcc_periph_clock_enable(RCC_USB); SET_REG(USB_CNTR_REG, 0); SET_REG(USB_BTABLE_REG, 0); SET_REG(USB_ISTR_REG, 0); /* Enable RESET, SUSPEND, RESUME and CTR interrupts. */ SET_REG(USB_CNTR_REG, USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM); return &st_usbfs_dev; } void st_usbfs_copy_to_pm(volatile void *const vPM, const void *const buf, const uint16_t len) { const uint16_t *const src = buf; volatile uint32_t *const packet_memory = vPM; const size_t blocks = (len + 1U) >> 1U; for (size_t idx = 0U; idx < blocks; ++idx) { packet_memory[idx] = src[idx]; } } /** * Copy a data buffer from packet memory. * * @param buf Source pointer to data buffer. * @param vPM Destination pointer into packet memory. * @param len Number of bytes to copy. */ void st_usbfs_copy_from_pm(void *const buf, const volatile void *const vPM, const uint16_t len) { uint16_t *const dest = buf; const volatile uint16_t *const packet_memory = vPM; const size_t blocks = len >> 1U; for (size_t idx = 0; idx < blocks; ++idx) { dest[idx] = packet_memory[idx << 1U]; } if (len & 1U) { *(uint8_t *)(dest + blocks) = packet_memory[blocks << 1U]; } }