106#include "../../lib/usb/usb_private.h"
111#define MAX_FIFO_RAM (4 * 1024)
170static inline void lm4f_usb_soft_disconnect(
void)
175static inline void lm4f_usb_soft_connect(
void)
180static void lm4f_set_address(
usbd_device *usbd_dev, uint8_t addr)
187static void lm4f_ep_setup(
usbd_device *usbd_dev, uint8_t addr, uint8_t type,
189 void (*callback) (
usbd_device *usbd_dev, uint8_t ep))
197 const bool dir_tx = addr & 0x80;
198 const uint8_t ep = addr & 0x0f;
204 if (max_size > 1024) {
207 }
else if (max_size > 512) {
210 }
else if (max_size > 256) {
213 }
else if (max_size > 128) {
216 }
else if (max_size > 64) {
219 }
else if (max_size > 32) {
222 }
else if (max_size > 16) {
225 }
else if (max_size > 8) {
249 usbd_dev->fifo_mem_top_ep0 = 64;
254 if (usbd_dev->fifo_mem_top + fifo_size >
MAX_FIFO_RAM) {
266 usbd_dev->user_callback_ctr[ep][USB_TRANSACTION_IN] =
279 usbd_dev->user_callback_ctr[ep][USB_TRANSACTION_OUT] =
289 usbd_dev->fifo_mem_top += fifo_size;
292static void lm4f_endpoints_reset(
usbd_device *usbd_dev)
298 usbd_dev->fifo_mem_top = 64;
301static void lm4f_ep_stall_set(
usbd_device *usbd_dev, uint8_t addr,
306 const uint8_t ep = addr & 0x0f;
307 const bool dir_tx = addr & 0x80;
333static uint8_t lm4f_ep_stall_get(
usbd_device *usbd_dev, uint8_t addr)
337 const uint8_t ep = addr & 0x0f;
338 const bool dir_tx = addr & 0x80;
351static void lm4f_ep_nak_set(
usbd_device *usbd_dev, uint8_t addr, uint8_t nak)
360static uint16_t lm4f_ep_write_packet(
usbd_device *usbd_dev, uint8_t addr,
361 const void *buf, uint16_t len)
363 const uint8_t ep = addr & 0xf;
380 for (i = 0; i < (len & ~0x3); i += 4) {
411static uint16_t lm4f_ep_read_packet(
usbd_device *usbd_dev, uint8_t addr,
412 void *buf, uint16_t len)
417 uint8_t ep = addr & 0xf;
421 rlen = (fifoin > len) ? len : fifoin;
428 for (len = 0; len < (rlen & ~0x3); len += 4) {
436 *((uint8_t *)(buf + len)) =
USB_FIFO8(ep);
469 const uint8_t usb_is =
USB_IS;
474 if ((usb_is &
USB_IM_SUSPEND) && (usbd_dev->user_callback_suspend)) {
475 usbd_dev->user_callback_suspend();
478 if ((usb_is &
USB_IM_RESUME) && (usbd_dev->user_callback_resume)) {
479 usbd_dev->user_callback_resume();
486 if ((usb_is &
USB_IM_SOF) && (usbd_dev->user_callback_sof)) {
487 usbd_dev->user_callback_sof();
501 enum _usbd_transaction type;
502 type = (usbd_dev->control_state.state != DATA_OUT &&
503 usbd_dev->control_state.state != LAST_DATA_OUT)
504 ? USB_TRANSACTION_SETUP :
506 if (type == USB_TRANSACTION_SETUP) {
507 lm4f_ep_read_packet(usbd_dev, 0, &usbd_dev->control_state.req, 8);
509 if (usbd_dev->user_callback_ctr[0][type]) {
511 user_callback_ctr[0][type](usbd_dev, 0);
516 tx_cb = usbd_dev->user_callback_ctr[0]
517 [USB_TRANSACTION_IN];
533 if ((usbd_dev->control_state.state != DATA_IN) &&
534 (usbd_dev->control_state.state != LAST_DATA_IN) &&
535 (usbd_dev->control_state.state != STATUS_IN)) {
546 for (i = 1; i < 8; i++) {
547 tx_cb = usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN];
548 rx_cb = usbd_dev->user_callback_ctr[i][USB_TRANSACTION_OUT];
550 if ((usb_txis & (1 << i)) && tx_cb) {
554 if ((usb_rxis & (1 << i)) && rx_cb) {
562static void lm4f_disconnect(
usbd_device *usbd_dev,
bool disconnected)
572 lm4f_usb_soft_disconnect();
574 lm4f_usb_soft_connect();
582static struct _usbd_device usbd_dev;
596 lm4f_usb_soft_disconnect();
600 for (i = 0; i < 1000; i++) {
620 lm4f_usb_soft_connect();
623 usbd_dev.fifo_mem_top = 64;
629#define RX_FIFO_SIZE 512
632 .init = lm4f_usbd_init,
633 .set_address = lm4f_set_address,
634 .ep_setup = lm4f_ep_setup,
635 .ep_reset = lm4f_endpoints_reset,
636 .ep_stall_set = lm4f_ep_stall_set,
637 .ep_stall_get = lm4f_ep_stall_get,
638 .ep_nak_set = lm4f_ep_nak_set,
639 .ep_write_packet = lm4f_ep_write_packet,
640 .ep_read_packet = lm4f_ep_read_packet,
642 .disconnect = lm4f_disconnect,
644 .set_address_before_status =
false,
645 .rx_fifo_size = RX_FIFO_SIZE,
void rcc_usb_pll_on(void)
Power up the USB PLL.
#define SYSCTL_IMC_USBPLLLIM
USB PLL Lock Raw Interrupt Status.
void periph_clock_enable(enum lm4f_clken periph)
Enable the clock source for the peripheral.
#define SYSCTL_IMC_PLLLIM
PLL Lock Raw Interrupt Status.
#define SYSCTL_RIS_USBPLLLRIS
USB PLL Lock Raw Interrupt Status.
#define USB_RXCSRL_STALL
Send Stall.
#define USB_FIFOSZ_SIZE_64
#define USB_FADDR_FUNCADDR_MASK
Function Address.
#define USB_CSRL0_RXRDYC
RXRDY Clear.
#define USB_FIFOSZ_SIZE_256
#define USB_TXCSRL_TXRDY
Transmit Packet Ready.
#define USB_FIFOSZ_SIZE_8
#define USB_IM_RESUME
RESUME signaling detected.
#define USB_RXCSRL_STALLED
Endpoint Stalled.
#define USB_CSRL0_TXRDY
Transmit Packet Ready.
#define USB_FIFOSZ_SIZE_32
#define USB_RXCSRH_ISO
Isochronous transfers.
#define USB_POWER_SOFTCONN
Soft Connect/Disconnect.
#define USB_IM_RESET
RESET signaling detected.
#define USB_FIFOSZ_SIZE_16
#define USB_IM_SOF
Start of frame.
#define USB_CSRL0_DATAEND
Data End.
#define USB_CSRL0_STALLED
Endpoint Stalled.
#define USB_FIFOSZ_SIZE_512
#define USB_CSRL0_RXRDY
Receive Packet Ready.
#define USB_TXCSRH_ISO
Isochronous transfers.
#define USB_CSRL0_STALL
Send Stall.
#define USB_FIFOSZ_SIZE_128
#define USB_TXCSRL_STALLED
Endpoint Stalled.
#define USB_IM_SUSPEND
SUSPEND signaling detected.
#define USB_EPIDX_MASK
Endpoint Index.
#define USB_TXCSRL_STALL
Send Stall.
#define USB_FIFOSZ_SIZE_1024
#define USB_FIFOSZ_SIZE_2048
struct _usbd_device usbd_device
void _usbd_reset(usbd_device *usbd_dev)
void usb_disable_interrupts(enum usb_interrupt ints, enum usb_ep_interrupt rx_ints, enum usb_ep_interrupt tx_ints)
Disable Specific USB Interrupts.
void usb_enable_interrupts(enum usb_interrupt ints, enum usb_ep_interrupt rx_ints, enum usb_ep_interrupt tx_ints)
Enable Specific USB Interrupts.
const struct _usbd_driver lm4f_usb_driver
#define USB_ENDPOINT_ATTR_ISOCHRONOUS