Fixed some F105/F107 USB issues. Added user callback on SOF.
Made examples depend on lib.
This commit is contained in:
parent
f9a28a3d5e
commit
b05a5dcf2a
2
Makefile
2
Makefile
@ -46,7 +46,7 @@ lib:
|
|||||||
fi; \
|
fi; \
|
||||||
done
|
done
|
||||||
|
|
||||||
examples:
|
examples: lib
|
||||||
$(Q)for i in $(addsuffix /*/*,$(addprefix $@/,$(TARGETS))); do \
|
$(Q)for i in $(addsuffix /*/*,$(addprefix $@/,$(TARGETS))); do \
|
||||||
if [ -d $$i ]; then \
|
if [ -d $$i ]; then \
|
||||||
printf " BUILD $$i\n"; \
|
printf " BUILD $$i\n"; \
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#define OTG_FS_GCCFG MMIO32(USB_OTG_FS_BASE + 0x038)
|
#define OTG_FS_GCCFG MMIO32(USB_OTG_FS_BASE + 0x038)
|
||||||
#define OTG_FS_CID MMIO32(USB_OTG_FS_BASE + 0x03C)
|
#define OTG_FS_CID MMIO32(USB_OTG_FS_BASE + 0x03C)
|
||||||
#define OTG_FS_HPTXFSIZ MMIO32(USB_OTG_FS_BASE + 0x100)
|
#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 */
|
/* Host-mode Control and Status Registers */
|
||||||
#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400)
|
#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400)
|
||||||
@ -81,7 +81,7 @@
|
|||||||
#define OTG_FS_PCGCCTL MMIO32(USB_OTG_FS_BASE + 0xE00)
|
#define OTG_FS_PCGCCTL MMIO32(USB_OTG_FS_BASE + 0xE00)
|
||||||
|
|
||||||
/* Data FIFO */
|
/* 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 */
|
/* Global CSRs */
|
||||||
/* OTG_FS AHB configuration register (OTG_FS_GAHBCFG) */
|
/* OTG_FS AHB configuration register (OTG_FS_GAHBCFG) */
|
||||||
@ -100,8 +100,7 @@
|
|||||||
#define OTG_FS_GUSBCFG_FHMOD 0x20000000
|
#define OTG_FS_GUSBCFG_FHMOD 0x20000000
|
||||||
#define OTG_FS_GUSBCFG_FDMOD 0x40000000
|
#define OTG_FS_GUSBCFG_FDMOD 0x40000000
|
||||||
#define OTG_FS_GUSBCFG_CTXPKT 0x80000000
|
#define OTG_FS_GUSBCFG_CTXPKT 0x80000000
|
||||||
/* WARNING: not in reference manual */
|
#define OTG_FS_GUSBCFG_PHYSEL (1 << 7)
|
||||||
#define OTG_FS_GUSBCFG_PHYSEL (1 << 6)
|
|
||||||
|
|
||||||
/* OTG_FS reset register (OTG_FS_GRSTCTL) */
|
/* OTG_FS reset register (OTG_FS_GRSTCTL) */
|
||||||
#define OTG_FS_GRSTCTL_AHBIDL (1 << 31)
|
#define OTG_FS_GRSTCTL_AHBIDL (1 << 31)
|
||||||
|
@ -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_reset_callback(void (*callback)(void));
|
||||||
extern void usbd_register_suspend_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_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,
|
typedef int (*usbd_control_callback)(struct usb_setup_data *req, u8 **buf,
|
||||||
u16 *len, void (**complete)(struct usb_setup_data *req));
|
u16 *len, void (**complete)(struct usb_setup_data *req));
|
||||||
|
@ -80,6 +80,11 @@ void usbd_register_resume_callback(void (*callback)(void))
|
|||||||
_usbd_device.user_callback_resume = callback;
|
_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)
|
void usbd_set_control_buffer_size(u16 size)
|
||||||
{
|
{
|
||||||
_usbd_device.ctrl_buf_len = size;
|
_usbd_device.ctrl_buf_len = size;
|
||||||
|
@ -300,6 +300,10 @@ static void stm32f103_poll(void)
|
|||||||
_usbd_device.user_callback_resume();
|
_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();
|
USB_CLR_ISTR_SOF();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libopencm3/stm32/rcc.h>
|
|
||||||
#include <libopencm3/cm3/common.h>
|
#include <libopencm3/cm3/common.h>
|
||||||
#include <libopencm3/stm32/tools.h>
|
#include <libopencm3/stm32/tools.h>
|
||||||
#include <libopencm3/stm32/otg_fs.h>
|
#include <libopencm3/stm32/otg_fs.h>
|
||||||
@ -29,6 +28,7 @@
|
|||||||
/* Receive FIFO size in 32-bit words */
|
/* Receive FIFO size in 32-bit words */
|
||||||
#define RX_FIFO_SIZE 128
|
#define RX_FIFO_SIZE 128
|
||||||
static uint16_t fifo_mem_top;
|
static uint16_t fifo_mem_top;
|
||||||
|
static uint16_t fifo_mem_top_ep0;
|
||||||
|
|
||||||
static u8 force_nak[4];
|
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. */
|
/** Initialize the USB device controller hardware of the STM32. */
|
||||||
static void stm32f107_usbd_init(void)
|
static void stm32f107_usbd_init(void)
|
||||||
{
|
{
|
||||||
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
|
|
||||||
OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS;
|
OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS;
|
||||||
|
|
||||||
/* WARNING: Undocumented! Select internal PHY */
|
|
||||||
OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_PHYSEL;
|
OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_PHYSEL;
|
||||||
/* Enable VBUS sensing in device mode and power down the phy */
|
/* Enable VBUS sensing in device mode and power down the phy */
|
||||||
OTG_FS_GCCFG |= OTG_FS_GCCFG_VBUSBSEN | OTG_FS_GCCFG_PWRDWN;
|
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;
|
OTG_FS_GNPTXFSIZ = ((max_size / 4) << 16) | RX_FIFO_SIZE;
|
||||||
fifo_mem_top += max_size / 4;
|
fifo_mem_top += max_size / 4;
|
||||||
|
fifo_mem_top_ep0 = fifo_mem_top;
|
||||||
|
|
||||||
return;
|
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_DIEPTSIZ(addr) = (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
|
||||||
OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA |
|
OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA |
|
||||||
OTG_FS_DIEPCTL0_SNAK | (type << 18) |
|
OTG_FS_DIEPCTL0_SNAK | (type << 18) |
|
||||||
OTG_FS_DIEPCTL0_USBAEP |
|
OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID |
|
||||||
(addr << 22) | max_size;
|
(addr << 22) | max_size;
|
||||||
|
|
||||||
if (callback) {
|
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_DOEPTSIZ(addr) = doeptsiz[addr];
|
||||||
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
|
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
|
||||||
OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK |
|
OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK |
|
||||||
|
OTG_FS_DOEPCTLX_SD0PID |
|
||||||
(type << 18) | max_size;
|
(type << 18) | max_size;
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
@ -181,7 +181,7 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
|
|||||||
static void stm32f107_endpoints_reset(void)
|
static void stm32f107_endpoints_reset(void)
|
||||||
{
|
{
|
||||||
/* The core resets the endpoints automatically on reset */
|
/* 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)
|
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;
|
addr &= 0x7F;
|
||||||
|
|
||||||
|
/* Return if endpoint is already enabled. */
|
||||||
|
if(OTG_FS_DTXFSTS(addr) < (len >> 2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Enable endpoint for transmission */
|
/* Enable endpoint for transmission */
|
||||||
OTG_FS_DIEPTSIZ(addr) = (1 << 19) | len;
|
OTG_FS_DIEPTSIZ(addr) = (1 << 19) | len;
|
||||||
OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_CNAK;
|
OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_CNAK;
|
||||||
|
|
||||||
/* Copy buffer to endpoint FIFO */
|
/* 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) {
|
for(i = len; i > 0; i -= 4) {
|
||||||
*fifo++ = *buf32++;
|
*fifo++ = *buf32++;
|
||||||
}
|
}
|
||||||
@ -270,16 +274,19 @@ static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len)
|
|||||||
len = MIN(len, rxbcnt[addr]);
|
len = MIN(len, rxbcnt[addr]);
|
||||||
rxbcnt[addr] = 0;
|
rxbcnt[addr] = 0;
|
||||||
|
|
||||||
u32 *fifo = OTG_FS_FIFO(addr);
|
volatile u32 *fifo = OTG_FS_FIFO(addr);
|
||||||
for(i = len; i >= 4; i -= 4) {
|
for(i = len; i >= 4; i -= 4) {
|
||||||
*buf32++ = *fifo++;
|
*buf32++ = *fifo++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i) {
|
if(i) {
|
||||||
extra = *fifo;
|
extra = *fifo++;
|
||||||
memcpy(buf32, &extra, i);
|
memcpy(buf32, &extra, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(len == 8)
|
||||||
|
extra = *fifo++;
|
||||||
|
|
||||||
OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
|
OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
|
||||||
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
|
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
|
||||||
(force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK);
|
(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) {
|
if (intsts & OTG_FS_GINTSTS_ENUMDNE) {
|
||||||
/* Handle USB RESET condition */
|
/* Handle USB RESET condition */
|
||||||
OTG_FS_GINTSTS = OTG_FS_GINTSTS_ENUMDNE;
|
OTG_FS_GINTSTS = OTG_FS_GINTSTS_ENUMDNE;
|
||||||
|
fifo_mem_top = RX_FIFO_SIZE;
|
||||||
_usbd_reset();
|
_usbd_reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -347,7 +355,10 @@ static void stm32f107_poll(void)
|
|||||||
OTG_FS_GINTSTS = OTG_FS_GINTSTS_WKUPINT;
|
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;
|
OTG_FS_GINTSTS = OTG_FS_GINTSTS_SOF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ extern struct _usbd_device {
|
|||||||
void (*user_callback_reset)(void);
|
void (*user_callback_reset)(void);
|
||||||
void (*user_callback_suspend)(void);
|
void (*user_callback_suspend)(void);
|
||||||
void (*user_callback_resume)(void);
|
void (*user_callback_resume)(void);
|
||||||
|
void (*user_callback_sof)(void);
|
||||||
|
|
||||||
struct user_control_callback {
|
struct user_control_callback {
|
||||||
usbd_control_callback cb;
|
usbd_control_callback cb;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user