diff --git a/include/libopencm3/stm32/common/st_usbfs_v2.h b/include/libopencm3/stm32/common/st_usbfs_v2.h new file mode 100644 index 00000000..d85f4427 --- /dev/null +++ b/include/libopencm3/stm32/common/st_usbfs_v2.h @@ -0,0 +1,109 @@ +/** @addtogroup usb_defines + */ +/* + * This file is part of the libopencm3 project. + * + * 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 . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + * + * Additional definitions for F0 devices : + * -F0x0 (RM0360), + * -F04x, F0x2, F0x8 (RM0091) + */ + +/** @cond */ +#ifdef LIBOPENCM3_ST_USBFS_H +/** @endcond */ +#ifndef LIBOPENCM3_ST_USBFS_V2_H +#define LIBOPENCM3_ST_USBFS_V2_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Register definitions */ +/*****************************************************************************/ + +#define USB_LPMCSR_REG (&MMIO32(USB_DEV_FS_BASE + 0x54)) +#define USB_BCDR_REG (&MMIO32(USB_DEV_FS_BASE + 0x58)) + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- USB control register masks / bits ----------------------------------- */ + +#define USB_CNTR_L1REQM (1 << 7) +#define USB_CNTR_L1RESUME (1 << 5) + +/* --- USB interrupt status register masks / bits -------------------------- */ + +#define USB_ISTR_L1REQ (1 << 7) + +/* --- LPM control and status register USB_LPMCSR Values --------------------*/ + +#define USB_LPMCSR_BESL_SHIFT 4 +#define USB_LPMCSR_BESL (15 << USB_LPMCSR_BESL_SHIFT) + +#define USB_LPMCSR_REMWAKE (1 << 3) +#define USB_LPMCSR_LPMACK (1 << 1) +#define USB_LPMCSR_LPMEN (1 << 0) + +/* --- Battery Charging Detector Values ----------------------------------------------------------*/ + +#define USB_BCDR_DPPU (1 << 15) +#define USB_BCDR_PS2DET (1 << 7) +#define USB_BCDR_SDET (1 << 6) +#define USB_BCDR_PDET (1 << 5) +#define USB_BCDR_DCDET (1 << 4) +#define USB_BCDR_SDEN (1 << 3) +#define USB_BCDR_PDEN (1 << 2) +#define USB_BCDR_DCDEN (1 << 1) +#define USB_BCDR_BCDEN (1 << 0) + +/* --- USB BTABLE registers ------------------------------------------------ */ + +#define USB_EP_TX_ADDR(ep) \ + ((uint16_t *)(USB_PMA_BASE + (USB_GET_BTABLE + (ep) * 8 + 0) * 1)) + +#define USB_EP_TX_COUNT(ep) \ + ((uint16_t *)(USB_PMA_BASE + (USB_GET_BTABLE + (ep) * 8 + 2) * 1)) + +#define USB_EP_RX_ADDR(ep) \ + ((uint16_t *)(USB_PMA_BASE + (USB_GET_BTABLE + (ep) * 8 + 4) * 1)) + +#define USB_EP_RX_COUNT(ep) \ + ((uint16_t *)(USB_PMA_BASE + (USB_GET_BTABLE + (ep) * 8 + 6) * 1)) + +/* --- USB BTABLE manipulators --------------------------------------------- */ + +#define USB_GET_EP_TX_BUFF(ep) \ + (USB_PMA_BASE + (uint8_t *)(USB_GET_EP_TX_ADDR(ep) * 1)) + +#define USB_GET_EP_RX_BUFF(ep) \ + (USB_PMA_BASE + (uint8_t *)(USB_GET_EP_RX_ADDR(ep) * 1)) + +#endif +/** @cond */ +#else +#error "st_usbfs_v2.h should not be included directly, only via st_usbfs.h" +#endif +/** @endcond */ + diff --git a/include/libopencm3/stm32/f0/st_usbfs.h b/include/libopencm3/stm32/f0/st_usbfs.h new file mode 100644 index 00000000..7b65d2b8 --- /dev/null +++ b/include/libopencm3/stm32/f0/st_usbfs.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * 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 . + */ +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + */ + +#ifndef LIBOPENCM3_ST_USBFS_H +# error Do not include directly ! +#else + +#include + +#endif diff --git a/include/libopencm3/stm32/st_usbfs.h b/include/libopencm3/stm32/st_usbfs.h index 6befced9..f0d1f5f4 100644 --- a/include/libopencm3/stm32/st_usbfs.h +++ b/include/libopencm3/stm32/st_usbfs.h @@ -23,7 +23,9 @@ #include #include -#if defined(STM32F1) +#if defined(STM32F0) +# include +#elif defined(STM32F1) # include #elif defined(STM32F3) # include diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index e2447c38..449b48a1 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -55,6 +55,7 @@ typedef struct _usbd_device usbd_device; extern const usbd_driver st_usbfs_v1_usb_driver; extern const usbd_driver stm32f107_usb_driver; extern const usbd_driver stm32f207_usb_driver; +extern const usbd_driver st_usbfs_v2_usb_driver; #define otgfs_usb_driver stm32f107_usb_driver #define otghs_usb_driver stm32f207_usb_driver diff --git a/lib/stm32/f0/Makefile b/lib/stm32/f0/Makefile index 0378e730..152f2d7a 100644 --- a/lib/stm32/f0/Makefile +++ b/lib/stm32/f0/Makefile @@ -44,6 +44,9 @@ OBJS += gpio_common_all.o gpio_common_f0234.o crc_common_all.o \ spi_common_f03.o flash_common_f01.o dac_common_all.o \ timer_common_all.o rcc_common_all.o crs.o +OBJS += usb.o usb_control.o usb_standard.o +OBJS += st_usbfs_core.o st_usbfs_v2.o + VPATH += ../../usb:../:../../cm3:../common include ../../Makefile.include diff --git a/lib/stm32/st_usbfs_v2.c b/lib/stm32/st_usbfs_v2.c new file mode 100644 index 00000000..db2cf7cf --- /dev/null +++ b/lib/stm32/st_usbfs_v2.c @@ -0,0 +1,93 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * Copyright (C) 2014 Kuldeep Singh Dhaka + * + * 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 "../usb/usb_private.h" +#include "common/st_usbfs_core.h" + +static usbd_device *st_usbfs_v2_usbd_init(void); + +const struct _usbd_driver st_usbfs_v2_usb_driver = { + .init = st_usbfs_v2_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_v2_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); + SET_REG(USB_BCDR_REG, USB_BCDR_DPPU); + return &st_usbfs_dev; +} + +void st_usbfs_copy_to_pm(volatile void *vPM, const void *buf, uint16_t len) +{ + /* + * This is a bytewise copy, so it always works, even on CM0(+) + * that don't support unaligned accesses. + */ + const uint8_t *lbuf = buf; + volatile uint16_t *PM = vPM; + uint32_t i; + for (i = 0; i < len; i += 2) { + *PM++ = (uint16_t)lbuf[i+1] << 8 | lbuf[i]; + } +} + +/** + * 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 *buf, const volatile void *vPM, uint16_t len) +{ + uint16_t *lbuf = buf; + const volatile uint16_t *PM = vPM; + uint8_t odd = len & 1; + + for (len >>= 1; len; PM++, lbuf++, len--) { + *lbuf = *PM; + } + + if (odd) { + *(uint8_t *) lbuf = *(uint8_t *) PM; + } +} diff --git a/tests/gadget-zero/Makefile.stm32f072disco b/tests/gadget-zero/Makefile.stm32f072disco new file mode 100644 index 00000000..b9f668bd --- /dev/null +++ b/tests/gadget-zero/Makefile.stm32f072disco @@ -0,0 +1,43 @@ +## +## This file is part of the libopencm3 project. +## +## 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 . +## + +BOARD = stm32f072disco +PROJECT = usb-gadget0-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../shared + +CFILES = main-$(BOARD).c +CFILES += usb-gadget0.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../.. + +### This section can go to an arch shared rules eventually... +LDSCRIPT = ../../lib/stm32/f0/stm32f07xzb.ld +OPENCM3_LIB = opencm3_stm32f0 +OPENCM3_DEFS = -DSTM32F0 +#FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +ARCH_FLAGS = -mthumb -mcpu=cortex-m0 $(FP_FLAGS) +#OOCD_INTERFACE = stlink-v2 +#OOCD_TARGET = stm32f4x +OOCD_FILE = openocd.stm32f072disco.cfg + +include ../rules.mk diff --git a/tests/gadget-zero/main-stm32f072disco.c b/tests/gadget-zero/main-stm32f072disco.c new file mode 100644 index 00000000..20286bee --- /dev/null +++ b/tests/gadget-zero/main-stm32f072disco.c @@ -0,0 +1,66 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Karl Palsson + * + * 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-gadget0.h" + +// no trace on cm0 #define ER_DEBUG +#ifdef ER_DEBUG +#define ER_DPRINTF(fmt, ...) \ + do { printf(fmt, ## __VA_ARGS__); } while (0) +#else +#define ER_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +#include "trace.h" +void trace_send_blocking8(int stimulus_port, char c) { + (void)stimulus_port; + (void)c; +} + + +int main(void) +{ + rcc_clock_setup_in_hsi48_out_48mhz(); + crs_autotrim_usb_enable(); + rcc_set_usbclk_source(HSI48); + rcc_set_sysclk_source(HSI48); + + /* LED on custom board for boot progress */ + rcc_periph_clock_enable(RCC_GPIOC); + gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO7); + gpio_set(GPIOC, GPIO7); + + usbd_device *usbd_dev = gadget0_init(&st_usbfs_v2_usb_driver, "stm32f072disco"); + + ER_DPRINTF("bootup complete\n"); + gpio_clear(GPIOC, GPIO7); + while (1) { + usbd_poll(usbd_dev); + } + +} + diff --git a/tests/gadget-zero/openocd.stm32f072disco.cfg b/tests/gadget-zero/openocd.stm32f072disco.cfg new file mode 100644 index 00000000..b16f9693 --- /dev/null +++ b/tests/gadget-zero/openocd.stm32f072disco.cfg @@ -0,0 +1,14 @@ +source [find interface/stlink-v2.cfg] +set WORKAREASIZE 0x4000 +source [find target/stm32f0x.cfg] + +# serial of my f072 disco board. +hla_serial "Q?o\x06PgHW#$\x16?" + +# no trace on cm0 +#tpiu config internal swodump.stm32f4disco.log uart off 168000000 + +# Uncomment to reset on connect, for grabbing under WFI et al +reset_config srst_only srst_nogate +# reset_config srst_only srst_nogate connect_assert_srst + diff --git a/tests/gadget-zero/test_gadget0.py b/tests/gadget-zero/test_gadget0.py index 6c22ae50..1b579662 100644 --- a/tests/gadget-zero/test_gadget0.py +++ b/tests/gadget-zero/test_gadget0.py @@ -9,6 +9,7 @@ import unittest DUT_SERIAL = "stm32f4disco" #DUT_SERIAL = "stm32f103-generic" #DUT_SERIAL = "stm32l1-generic" +#DUT_SERIAL = "stm32f072disco" class find_by_serial(object): def __init__(self, serial):