Fixed some F105/F107 USB issues. Added user callback on SOF.

Made examples depend on lib.
This commit is contained in:
Gareth McMullin 2011-10-29 21:30:26 +13:00
parent f9a28a3d5e
commit b05a5dcf2a
7 changed files with 36 additions and 15 deletions

View File

@ -46,7 +46,7 @@ lib:
fi; \
done
examples:
examples: lib
$(Q)for i in $(addsuffix /*/*,$(addprefix $@/,$(TARGETS))); do \
if [ -d $$i ]; then \
printf " BUILD $$i\n"; \

View File

@ -39,7 +39,7 @@
#define OTG_FS_GCCFG MMIO32(USB_OTG_FS_BASE + 0x038)
#define OTG_FS_CID MMIO32(USB_OTG_FS_BASE + 0x03C)
#define OTG_FS_HPTXFSIZ MMIO32(USB_OTG_FS_BASE + 0x100)
#define OTG_FS_DIEPTXF(x) MMIO32(USB_OTG_FS_BASE + 0x104 + 4*(x))
#define OTG_FS_DIEPTXF(x) MMIO32(USB_OTG_FS_BASE + 0x104 + 4*(x-1))
/* Host-mode Control and Status Registers */
#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400)
@ -81,7 +81,7 @@
#define OTG_FS_PCGCCTL MMIO32(USB_OTG_FS_BASE + 0xE00)
/* Data FIFO */
#define OTG_FS_FIFO(x) ((u32*)(USB_OTG_FS_BASE + (((x) + 1) << 12)))
#define OTG_FS_FIFO(x) ((volatile u32*)(USB_OTG_FS_BASE + (((x) + 1) << 12)))
/* Global CSRs */
/* OTG_FS AHB configuration register (OTG_FS_GAHBCFG) */
@ -100,8 +100,7 @@
#define OTG_FS_GUSBCFG_FHMOD 0x20000000
#define OTG_FS_GUSBCFG_FDMOD 0x40000000
#define OTG_FS_GUSBCFG_CTXPKT 0x80000000
/* WARNING: not in reference manual */
#define OTG_FS_GUSBCFG_PHYSEL (1 << 6)
#define OTG_FS_GUSBCFG_PHYSEL (1 << 7)
/* OTG_FS reset register (OTG_FS_GRSTCTL) */
#define OTG_FS_GRSTCTL_AHBIDL (1 << 31)

View File

@ -41,6 +41,7 @@ extern void usbd_set_control_buffer_size(u16 size);
extern void usbd_register_reset_callback(void (*callback)(void));
extern void usbd_register_suspend_callback(void (*callback)(void));
extern void usbd_register_resume_callback(void (*callback)(void));
extern void usbd_register_sof_callback(void (*callback)(void));
typedef int (*usbd_control_callback)(struct usb_setup_data *req, u8 **buf,
u16 *len, void (**complete)(struct usb_setup_data *req));

View File

@ -80,6 +80,11 @@ void usbd_register_resume_callback(void (*callback)(void))
_usbd_device.user_callback_resume = callback;
}
void usbd_register_sof_callback(void (*callback)(void))
{
_usbd_device.user_callback_sof = callback;
}
void usbd_set_control_buffer_size(u16 size)
{
_usbd_device.ctrl_buf_len = size;

View File

@ -300,6 +300,10 @@ static void stm32f103_poll(void)
_usbd_device.user_callback_resume();
}
if (istr & USB_ISTR_SOF)
if (istr & USB_ISTR_SOF) {
if (_usbd_device.user_callback_sof)
_usbd_device.user_callback_sof();
USB_CLR_ISTR_SOF();
}
}

View File

@ -17,7 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/cm3/common.h>
#include <libopencm3/stm32/tools.h>
#include <libopencm3/stm32/otg_fs.h>
@ -29,6 +28,7 @@
/* Receive FIFO size in 32-bit words */
#define RX_FIFO_SIZE 128
static uint16_t fifo_mem_top;
static uint16_t fifo_mem_top_ep0;
static u8 force_nak[4];
@ -64,10 +64,8 @@ const struct _usbd_driver stm32f107_usb_driver = {
/** Initialize the USB device controller hardware of the STM32. */
static void stm32f107_usbd_init(void)
{
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS;
/* WARNING: Undocumented! Select internal PHY */
OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_PHYSEL;
/* Enable VBUS sensing in device mode and power down the phy */
OTG_FS_GCCFG |= OTG_FS_GCCFG_VBUSBSEN | OTG_FS_GCCFG_PWRDWN;
@ -141,6 +139,7 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
OTG_FS_GNPTXFSIZ = ((max_size / 4) << 16) | RX_FIFO_SIZE;
fifo_mem_top += max_size / 4;
fifo_mem_top_ep0 = fifo_mem_top;
return;
}
@ -152,7 +151,7 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
OTG_FS_DIEPTSIZ(addr) = (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA |
OTG_FS_DIEPCTL0_SNAK | (type << 18) |
OTG_FS_DIEPCTL0_USBAEP |
OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID |
(addr << 22) | max_size;
if (callback) {
@ -168,6 +167,7 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK |
OTG_FS_DOEPCTLX_SD0PID |
(type << 18) | max_size;
if (callback) {
@ -181,7 +181,7 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
static void stm32f107_endpoints_reset(void)
{
/* The core resets the endpoints automatically on reset */
fifo_mem_top = RX_FIFO_SIZE;
fifo_mem_top = fifo_mem_top_ep0;
}
static void stm32f107_ep_stall_set(u8 addr, u8 stall)
@ -242,12 +242,16 @@ static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len)
addr &= 0x7F;
/* Return if endpoint is already enabled. */
if(OTG_FS_DTXFSTS(addr) < (len >> 2))
return 0;
/* Enable endpoint for transmission */
OTG_FS_DIEPTSIZ(addr) = (1 << 19) | len;
OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_CNAK;
/* Copy buffer to endpoint FIFO */
u32 *fifo = OTG_FS_FIFO(addr);
volatile u32 *fifo = OTG_FS_FIFO(addr);
for(i = len; i > 0; i -= 4) {
*fifo++ = *buf32++;
}
@ -270,16 +274,19 @@ static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len)
len = MIN(len, rxbcnt[addr]);
rxbcnt[addr] = 0;
u32 *fifo = OTG_FS_FIFO(addr);
volatile u32 *fifo = OTG_FS_FIFO(addr);
for(i = len; i >= 4; i -= 4) {
*buf32++ = *fifo++;
}
if(i) {
extra = *fifo;
extra = *fifo++;
memcpy(buf32, &extra, i);
}
if(len == 8)
extra = *fifo++;
OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
(force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK);
@ -296,6 +303,7 @@ static void stm32f107_poll(void)
if (intsts & OTG_FS_GINTSTS_ENUMDNE) {
/* Handle USB RESET condition */
OTG_FS_GINTSTS = OTG_FS_GINTSTS_ENUMDNE;
fifo_mem_top = RX_FIFO_SIZE;
_usbd_reset();
return;
}
@ -347,7 +355,10 @@ static void stm32f107_poll(void)
OTG_FS_GINTSTS = OTG_FS_GINTSTS_WKUPINT;
}
if (intsts & OTG_FS_GINTSTS_SOF)
if (intsts & OTG_FS_GINTSTS_SOF) {
if (_usbd_device.user_callback_sof)
_usbd_device.user_callback_sof();
OTG_FS_GINTSTS = OTG_FS_GINTSTS_SOF;
}
}

View File

@ -42,6 +42,7 @@ extern struct _usbd_device {
void (*user_callback_reset)(void);
void (*user_callback_suspend)(void);
void (*user_callback_resume)(void);
void (*user_callback_sof)(void);
struct user_control_callback {
usbd_control_callback cb;