From bf0d1a7b4114ca35a2000bd47d9c6d73c6e92ce2 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Mon, 14 Mar 2011 20:31:32 +1300 Subject: Connectivity line USB driver now enumerating correctly. --- include/libopencm3/stm32/otg_fs.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/libopencm3') diff --git a/include/libopencm3/stm32/otg_fs.h b/include/libopencm3/stm32/otg_fs.h index d39593e..34a7c85 100644 --- a/include/libopencm3/stm32/otg_fs.h +++ b/include/libopencm3/stm32/otg_fs.h @@ -297,6 +297,16 @@ #define OTG_FS_DIEPINTX_EPDISD (1 << 1) #define OTG_FS_DIEPINTX_XFRC (1 << 0) +/* OTG_FS Device IN Endpoint Interrupt Register (OTG_FS_DOEPINTx) */ +/* Bits 31:7 - Reserved */ +#define OTG_FS_DOEPINTX_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_FS_DOEPINTX_OTEPDIS (1 << 4) +#define OTG_FS_DOEPINTX_STUP (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_FS_DOEPINTX_EPDISD (1 << 1) +#define OTG_FS_DOEPINTX_XFRC (1 << 0) + /* OTG_FS Device OUT Endpoint 0 Transfer Size Regsiter (OTG_FS_DOEPTSIZ0) */ /* Bit 31 - Reserved */ #define OTG_FS_DIEPSIZ0_STUPCNT_1 (0x1 << 29) -- cgit v1.2.3 From 6bbc4c2f7cc17cf9cc18dc7110e7d9de2d4a8551 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 15 Mar 2011 20:33:02 +1300 Subject: Fixed non-control endpoints for connectivity line USB. --- include/libopencm3/stm32/otg_fs.h | 2 ++ lib/usb/usb_f107.c | 69 +++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 28 deletions(-) (limited to 'include/libopencm3') diff --git a/include/libopencm3/stm32/otg_fs.h b/include/libopencm3/stm32/otg_fs.h index 34a7c85..e1d7a6a 100644 --- a/include/libopencm3/stm32/otg_fs.h +++ b/include/libopencm3/stm32/otg_fs.h @@ -250,6 +250,7 @@ #define OTG_FS_DIEPCTL0_EPENA (1 << 31) #define OTG_FS_DIEPCTL0_EPDIS (1 << 30) /* Bits 29:28 - Reserved */ +#define OTG_FS_DIEPCTLX_SD0PID (1 << 28) #define OTG_FS_DIEPCTL0_SNAK (1 << 27) #define OTG_FS_DIEPCTL0_CNAK (1 << 26) #define OTG_FS_DIEPCTL0_TXFNUM_MASK (0xf << 22) @@ -270,6 +271,7 @@ #define OTG_FS_DOEPCTL0_EPENA (1 << 31) #define OTG_FS_DOEPCTL0_EPDIS (1 << 30) /* Bits 29:28 - Reserved */ +#define OTG_FS_DOEPCTLX_SD0PID (1 << 28) #define OTG_FS_DOEPCTL0_SNAK (1 << 27) #define OTG_FS_DOEPCTL0_CNAK (1 << 26) /* Bits 25:22 - Reserved */ diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c index 6357443..9a20b0b 100644 --- a/lib/usb/usb_f107.c +++ b/lib/usb/usb_f107.c @@ -25,6 +25,10 @@ #include +/* Receive FIFO size in 32-bit words */ +#define RX_FIFO_SIZE 128 +static uint16_t fifo_mem_top; + static void stm32f107_usbd_init(void); static void stm32f107_set_address(u8 addr); static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, @@ -55,7 +59,6 @@ const struct _usbd_driver stm32f107_usb_driver = { /** Initialize the USB device controller hardware of the STM32. */ static void stm32f107_usbd_init(void) { - int i; /* TODO: Enable interrupts on Reset, Transfer, Suspend and Resume */ OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS; @@ -82,9 +85,8 @@ static void stm32f107_usbd_init(void) /* Restart the phy clock */ OTG_FS_PCGCCTL = 0; - OTG_FS_GRXFSIZ = 128; - OTG_FS_GNPTXFSIZ = (128 << 16) | 128; - + OTG_FS_GRXFSIZ = RX_FIFO_SIZE; + fifo_mem_top = RX_FIFO_SIZE; /* Unmask interrupts for TX and RX */ OTG_FS_GINTMSK &= OTG_FS_GINTMSK_RXFLVLM; @@ -125,14 +127,21 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, OTG_FS_DOEPTSIZ(0) = doeptsiz[0]; OTG_FS_DOEPCTL(0) |= OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; + OTG_FS_GNPTXFSIZ = ((max_size / 4) << 16) | RX_FIFO_SIZE; + fifo_mem_top += max_size / 4; + return; } /* TODO: Configuration for other endpoints */ if (dir) { + OTG_FS_DIEPTXF(addr) = ((max_size / 4) << 16) | fifo_mem_top; + fifo_mem_top += max_size / 4; + 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 | (addr << 22) | max_size; if (callback) { @@ -147,7 +156,8 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr]; OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | - OTG_FS_DIEPCTL0_CNAK | (type << 18) | max_size; + OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK | + (type << 18) | max_size; if (callback) { _usbd_device. @@ -159,7 +169,8 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, static void stm32f107_endpoints_reset(void) { - /* TODO: Reset all endpoints. */ + /* The core resets the endpoints automatically on reset */ + fifo_mem_top = RX_FIFO_SIZE; } static void stm32f107_ep_stall_set(u8 addr, u8 stall) @@ -174,26 +185,29 @@ static void stm32f107_ep_stall_set(u8 addr, u8 stall) if(addr & 0x80) { addr &= 0x7F; - if(stall) + if(stall) { OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL; - else + } else { OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL; - /* TODO: Reset to DATA0 */ + OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTLX_SD0PID; + } } else { - if(stall) + if(stall) { OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_STALL; - else + } else { OTG_FS_DOEPCTL(addr) &= ~OTG_FS_DOEPCTL0_STALL; - /* TODO: Reset to DATA0 */ + OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTLX_SD0PID; + } } } static u8 stm32f107_ep_stall_get(u8 addr) { - /* TODO: return 1 if STALL set. */ - (void)addr; - - return 0; + /* return non-zero if STALL set. */ + if(addr & 0x80) + return (OTG_FS_DIEPCTL(addr&0x7f) & OTG_FS_DIEPCTL0_STALL)?1:0; + else + return (OTG_FS_DOEPCTL(addr) & OTG_FS_DOEPCTL0_STALL)?1:0; } static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len) @@ -249,11 +263,12 @@ static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len) static void stm32f107_poll(void) { - /* TODO: Read interrupt status register */ + /* Read interrupt status register */ u32 intsts = OTG_FS_GINTSTS; + int i; if (intsts & OTG_FS_GINTSTS_ENUMDNE) { - /* TODO: Handle USB RESET condition */ + /* Handle USB RESET condition */ OTG_FS_GINTSTS = OTG_FS_GINTSTS_ENUMDNE; _usbd_reset(); return; @@ -266,7 +281,8 @@ static void stm32f107_poll(void) u32 rxstsp = OTG_FS_GRXSTSP; u32 pktsts = rxstsp & OTG_FS_GRXSTSP_PKTSTS_MASK; if((pktsts != OTG_FS_GRXSTSP_PKTSTS_OUT) && - (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP)) return; + (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP)) + return; u8 ep = rxstsp & OTG_FS_GRXSTSP_EPNUM_MASK; u8 type; @@ -287,15 +303,12 @@ static void stm32f107_poll(void) * the XFRC bit must be checked in each OTG_FS_DIEPINT(x) */ /* TODO: Check on endpoint interrupt... */ - { - int i; - for (i = 0; i < 4; i++) { /* Iterate over endpoints */ - if(OTG_FS_DIEPINT(i) & OTG_FS_DIEPINTX_XFRC) { - /* Transfer complete */ - if (_usbd_device.user_callback_ctr[i][USB_TRANSACTION_IN]) - _usbd_device.user_callback_ctr[i][USB_TRANSACTION_IN] (i); - OTG_FS_DIEPINT(i) = OTG_FS_DIEPINTX_XFRC; - } + for (i = 0; i < 4; i++) { /* Iterate over endpoints */ + if(OTG_FS_DIEPINT(i) & OTG_FS_DIEPINTX_XFRC) { + /* Transfer complete */ + if (_usbd_device.user_callback_ctr[i][USB_TRANSACTION_IN]) + _usbd_device.user_callback_ctr[i][USB_TRANSACTION_IN] (i); + OTG_FS_DIEPINT(i) = OTG_FS_DIEPINTX_XFRC; } } -- cgit v1.2.3 From ef0ff192f769d6e043b4fdfc89cfbade61b9db14 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Wed, 30 Mar 2011 07:17:02 +1300 Subject: Added usbd_ep_nak_set() to force flow control on OUT endpoints. --- include/libopencm3/usb/usbd.h | 2 ++ lib/usb/usb.c | 6 ++++++ lib/usb/usb_f103.c | 21 ++++++++++++++++++++- lib/usb/usb_f107.c | 21 ++++++++++++++++++++- lib/usb/usb_private.h | 1 + 5 files changed, 49 insertions(+), 2 deletions(-) (limited to 'include/libopencm3') diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index fab6304..c73de07 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -65,6 +65,8 @@ extern u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len); extern void usbd_ep_stall_set(u8 addr, u8 stall); extern u8 usbd_ep_stall_get(u8 addr); +extern void usbd_ep_nak_set(u8 addr, u8 nak); + /* Optional */ extern void usbd_cable_connect(u8 on); diff --git a/lib/usb/usb.c b/lib/usb/usb.c index eb8e6d8..59c526d 100644 --- a/lib/usb/usb.c +++ b/lib/usb/usb.c @@ -127,3 +127,9 @@ u8 usbd_ep_stall_get(u8 addr) { return _usbd_device.driver->ep_stall_get(addr); } + +void usbd_ep_nak_set(u8 addr, u8 nak) +{ + _usbd_device.driver->ep_nak_set(addr, nak); +} + diff --git a/lib/usb/usb_f103.c b/lib/usb/usb_f103.c index ef97670..19f645d 100644 --- a/lib/usb/usb_f103.c +++ b/lib/usb/usb_f103.c @@ -30,10 +30,13 @@ static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, static void stm32f103_endpoints_reset(void); static void stm32f103_ep_stall_set(u8 addr, u8 stall); static u8 stm32f103_ep_stall_get(u8 addr); +static void stm32f103_ep_nak_set(u8 addr, u8 nak); static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len); static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len); static void stm32f103_poll(void); +static u8 force_nak[8]; + const struct _usbd_driver stm32f103_usb_driver = { .init = stm32f103_usbd_init, .set_address = stm32f103_set_address, @@ -41,6 +44,7 @@ const struct _usbd_driver stm32f103_usb_driver = { .ep_reset = stm32f103_endpoints_reset, .ep_stall_set = stm32f103_ep_stall_set, .ep_stall_get = stm32f103_ep_stall_get, + .ep_nak_set = stm32f103_ep_nak_set, .ep_write_packet = stm32f103_ep_write_packet, .ep_read_packet = stm32f103_ep_read_packet, .poll = stm32f103_poll, @@ -177,6 +181,20 @@ static u8 stm32f103_ep_stall_get(u8 addr) return 0; } +static void stm32f103_ep_nak_set(u8 addr, u8 nak) +{ + /* It does not make sence to force NAK on IN endpoints */ + if(addr & 0x80) + return; + + force_nak[addr] = nak; + + if(nak) + USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_NAK); + else + USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID); +} + /** * Copy a data buffer to packet memory. * @@ -236,7 +254,8 @@ static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len) usb_copy_from_pm(buf, USB_GET_EP_RX_BUFF(addr), len); USB_CLR_EP_RX_CTR(addr); - USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID); + if(!force_nak[addr]) + USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID); return len; } diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c index 9a20b0b..f106a05 100644 --- a/lib/usb/usb_f107.c +++ b/lib/usb/usb_f107.c @@ -29,6 +29,8 @@ #define RX_FIFO_SIZE 128 static uint16_t fifo_mem_top; +static u8 force_nak[4]; + static void stm32f107_usbd_init(void); static void stm32f107_set_address(u8 addr); static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, @@ -36,6 +38,7 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, static void stm32f107_endpoints_reset(void); static void stm32f107_ep_stall_set(u8 addr, u8 stall); static u8 stm32f107_ep_stall_get(u8 addr); +static void stm32f107_ep_nak_set(u8 addr, u8 nak); static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len); static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len); static void stm32f107_poll(void); @@ -51,6 +54,7 @@ const struct _usbd_driver stm32f107_usb_driver = { .ep_reset = stm32f107_endpoints_reset, .ep_stall_set = stm32f107_ep_stall_set, .ep_stall_get = stm32f107_ep_stall_get, + .ep_nak_set = stm32f107_ep_nak_set, .ep_write_packet = stm32f107_ep_write_packet, .ep_read_packet = stm32f107_ep_read_packet, .poll = stm32f107_poll, @@ -210,6 +214,20 @@ static u8 stm32f107_ep_stall_get(u8 addr) return (OTG_FS_DOEPCTL(addr) & OTG_FS_DOEPCTL0_STALL)?1:0; } +static void stm32f107_ep_nak_set(u8 addr, u8 nak) +{ + /* It does not make sence to force NAK on IN endpoints */ + if(addr & 0x80) + return; + + force_nak[addr] = nak; + + if(nak) + OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_SNAK; + else + OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_CNAK; +} + static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len) { const u32 *buf32 = buf; @@ -256,7 +274,8 @@ static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len) } OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr]; - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | OTG_FS_DOEPCTL0_CNAK; + OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | + (force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK); return len; } diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h index 1bc6b3f..40d59a1 100644 --- a/lib/usb/usb_private.h +++ b/lib/usb/usb_private.h @@ -78,6 +78,7 @@ struct _usbd_driver { void (*ep_setup)(u8 addr, u8 type, u16 max_size, void (*cb)(u8 ep)); void (*ep_reset)(void); void (*ep_stall_set)(u8 addr, u8 stall); + void (*ep_nak_set)(u8 addr, u8 nak); u8 (*ep_stall_get)(u8 addr); u16 (*ep_write_packet)(u8 addr, const void *buf, u16 len); u16 (*ep_read_packet)(u8 addr, void *buf, u16 len); -- cgit v1.2.3 From 3ac0ae839d710de6552f617934bed2f5f9629bec Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 24 Apr 2011 14:31:56 +1200 Subject: Added extra interrupt vectors for STM32 connectivity line. --- include/libopencm3/stm32/nvic.h | 8 ++++++++ lib/stm32/vector.c | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'include/libopencm3') diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h index ce8132f..d29c425 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/stm32/nvic.h @@ -138,6 +138,14 @@ #define NVIC_DMA2_CHANNEL2_IRQ 57 #define NVIC_DMA2_CHANNEL3_IRQ 58 #define NVIC_DMA2_CHANNEL4_5_IRQ 59 +#define NVIC_DMA2_CHANNEL5_IRQ 60 +#define NVIC_ETH_IRQ 61 +#define NVIC_ETH_WKUP_IRQ 62 +#define NVIC_CAN2_TX_IRQ 63 +#define NVIC_CAN2_RX0_IRQ 64 +#define NVIC_CAN2_RX1_IRQ 65 +#define NVIC_CAN2_SCE_IRQ 66 +#define NVIC_OTG_FS_IRQ 67 /* --- NVIC functions ------------------------------------------------------ */ diff --git a/lib/stm32/vector.c b/lib/stm32/vector.c index 4d3d510..39bd9a1 100644 --- a/lib/stm32/vector.c +++ b/lib/stm32/vector.c @@ -96,6 +96,15 @@ void WEAK dma2_channel1_isr(void); void WEAK dma2_channel2_isr(void); void WEAK dma2_channel3_isr(void); void WEAK dma2_channel4_5_isr(void); +void WEAK dma2_channel5_isr(void); +void WEAK eth_isr(void); +void WEAK eth_wkup_isr(void); +void WEAK can2_tx_isr(void); +void WEAK can2_rx0_isr(void); +void WEAK can2_rx1_isr(void); +void WEAK can2_sce_isr(void); +void WEAK otg_fs_isr(void); + __attribute__ ((section(".vectors"))) void (*const vector_table[]) (void) = { @@ -172,6 +181,14 @@ void (*const vector_table[]) (void) = { dma2_channel2_isr, dma2_channel3_isr, dma2_channel4_5_isr, + dma2_channel5_isr, + eth_isr, + eth_wkup_isr, + can2_tx_isr, + can2_rx0_isr, + can2_rx1_isr, + can2_sce_isr, + otg_fs_isr, }; void reset_handler(void) @@ -268,3 +285,12 @@ void null_handler(void) #pragma weak dma2_channel2_isr = null_handler #pragma weak dma2_channel3_isr = null_handler #pragma weak dma2_channel4_5_isr = null_handler +#pragma weak dma2_channel5_isr +#pragma weak eth_isr = null_handler +#pragma weak eth_wkup_isr = null_handler +#pragma weak can2_tx_isr = null_handler +#pragma weak can2_rx0_isr = null_handler +#pragma weak can2_rx1_isr = null_handler +#pragma weak can2_sce_isr = null_handler +#pragma weak otg_fs_isr = null_handler + -- cgit v1.2.3