usb: Add st_usbfs_v2 for f0/l0 devices

Based on previous work, add a new driver for the v2 usb peripheral found on
stm32f0 and l0 devices.

Correspondingly, add a usb gadget zero test suite for the f0.  L0 device level
code isn't yet ready, but will add the test case when it moves in.

Work by Frantisek Burian, Kuldeep
Singh Dhaka, Robin Kreis, fenugrec and zyp on irc, and all those forgotten.
This commit is contained in:
Karl Palsson 2015-10-02 01:30:25 +00:00
parent cffaf1ee60
commit f5eb96caf3
10 changed files with 360 additions and 1 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY !
* Use top-level <libopencm3/stm32/st_usbfs.h>
*
* 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 <libopencm3/stm32/common/st_usbfs_common.h>
/*****************************************************************************/
/* 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 */

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY !
* Use top-level <libopencm3/stm32/st_usbfs.h>
*/
#ifndef LIBOPENCM3_ST_USBFS_H
# error Do not include directly !
#else
#include <libopencm3/stm32/common/st_usbfs_v2.h>
#endif

View File

@ -23,7 +23,9 @@
#include <libopencm3/cm3/common.h>
#include <libopencm3/stm32/memorymap.h>
#if defined(STM32F1)
#if defined(STM32F0)
# include <libopencm3/stm32/f0/st_usbfs.h>
#elif defined(STM32F1)
# include <libopencm3/stm32/f1/st_usbfs.h>
#elif defined(STM32F3)
# include <libopencm3/stm32/f3/st_usbfs.h>

View File

@ -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

View File

@ -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

93
lib/stm32/st_usbfs_v2.c Normal file
View File

@ -0,0 +1,93 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
* Copyright (C) 2014 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/common.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/tools.h>
#include <libopencm3/stm32/st_usbfs.h>
#include <libopencm3/usb/usbd.h>
#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;
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
##
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

View File

@ -0,0 +1,66 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Karl Palsson <karlp@tweak.net.au>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/crs.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/flash.h>
#include <libopencm3/stm32/rcc.h>
#include <stdio.h>
#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);
}
}

View File

@ -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

View File

@ -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):