|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- #include "usb_dev.h"
- #define USB_DESC_LIST_DEFINE
- #include "usb_desc.h"
- #include "usb_serial.h"
- #include <string.h>
- #include "debug/printf.h"
-
-
-
- typedef struct endpoint_struct endpoint_t;
-
- struct endpoint_struct {
- uint32_t config;
- uint32_t current;
- uint32_t next;
- uint32_t status;
- uint32_t pointer0;
- uint32_t pointer1;
- uint32_t pointer2;
- uint32_t pointer3;
- uint32_t pointer4;
- uint32_t reserved;
- uint32_t setup0;
- uint32_t setup1;
- transfer_t *first_transfer;
- transfer_t *last_transfer;
- void (*callback_function)(transfer_t *completed_transfer);
- uint32_t unused1;
- };
-
-
-
- endpoint_t endpoint_queue_head[(NUM_ENDPOINTS+1)*2] __attribute__ ((used, aligned(4096)));
-
- transfer_t endpoint0_transfer_data __attribute__ ((used, aligned(32)));
- transfer_t endpoint0_transfer_ack __attribute__ ((used, aligned(32)));
-
-
- typedef union {
- struct {
- union {
- struct {
- uint8_t bmRequestType;
- uint8_t bRequest;
- };
- uint16_t wRequestAndType;
- };
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
- };
- struct {
- uint32_t word1;
- uint32_t word2;
- };
- uint64_t bothwords;
- } setup_t;
-
- static setup_t endpoint0_setupdata;
- static uint32_t endpoint0_notify_mask=0;
- static uint32_t endpointN_notify_mask=0;
-
- volatile uint8_t usb_configuration = 0;
- static uint8_t endpoint0_buffer[8];
- static uint8_t usb_reboot_timer = 0;
-
-
- static void isr(void);
- static void endpoint0_setup(uint64_t setupdata);
- static void endpoint0_transmit(const void *data, uint32_t len, int notify);
- static void endpoint0_receive(void *data, uint32_t len, int notify);
- static void endpoint0_complete(void);
-
-
-
-
- void usb_init(void)
- {
-
-
-
- PMU_REG_3P0 = PMU_REG_3P0_OUTPUT_TRG(0x0F) | PMU_REG_3P0_BO_OFFSET(6)
- | PMU_REG_3P0_ENABLE_LINREG;
-
- usb_init_serialnumber();
-
-
-
- CCM_CCGR6 |= CCM_CCGR6_USBOH3(CCM_CCGR_ON);
-
-
-
-
-
-
-
-
-
-
-
-
- #if 1
- if ((USBPHY1_PWD & (USBPHY_PWD_RXPWDRX | USBPHY_PWD_RXPWDDIFF | USBPHY_PWD_RXPWD1PT1
- | USBPHY_PWD_RXPWDENV | USBPHY_PWD_TXPWDV2I | USBPHY_PWD_TXPWDIBIAS
- | USBPHY_PWD_TXPWDFS)) || (USB1_USBMODE & USB_USBMODE_CM_MASK)) {
-
-
- USBPHY1_CTRL_SET = USBPHY_CTRL_SFTRST;
- USB1_USBCMD |= USB_USBCMD_RST;
- int count=0;
- while (USB1_USBCMD & USB_USBCMD_RST) count++;
- NVIC_CLEAR_PENDING(IRQ_USB1);
- USBPHY1_CTRL_CLR = USBPHY_CTRL_SFTRST;
-
- printf("USB reset took %d loops\n", count);
-
-
-
-
-
-
-
- delay(100);
- }
- #endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- USBPHY1_CTRL_CLR = USBPHY_CTRL_CLKGATE;
- USBPHY1_PWD = 0;
-
-
-
- USB1_USBMODE = USB_USBMODE_CM(2) | USB_USBMODE_SLOM;
- memset(endpoint_queue_head, 0, sizeof(endpoint_queue_head));
- endpoint_queue_head[0].config = (64 << 16) | (1 << 15);
- endpoint_queue_head[1].config = (64 << 16);
- USB1_ENDPOINTLISTADDR = (uint32_t)&endpoint_queue_head;
-
-
- USB1_USBINTR = USB_USBINTR_UE | USB_USBINTR_UEE |
- USB_USBINTR_URE | USB_USBINTR_SLE;
-
- attachInterruptVector(IRQ_USB1, &isr);
- NVIC_ENABLE_IRQ(IRQ_USB1);
-
-
-
-
- USB1_USBCMD |= USB_USBCMD_RS;
- }
-
-
- static void isr(void)
- {
-
-
-
-
- uint32_t status = USB1_USBSTS;
- USB1_USBSTS = status;
-
-
-
-
-
- if (status & USB_USBSTS_UI) {
-
- uint32_t setupstatus = USB1_ENDPTSETUPSTAT;
-
- while (setupstatus) {
- USB1_ENDPTSETUPSTAT = setupstatus;
- setup_t s;
- do {
- USB1_USBCMD |= USB_USBCMD_SUTW;
- s.word1 = endpoint_queue_head[0].setup0;
- s.word2 = endpoint_queue_head[0].setup1;
- } while (!(USB1_USBCMD & USB_USBCMD_SUTW));
- USB1_USBCMD &= ~USB_USBCMD_SUTW;
-
- USB1_ENDPTFLUSH = (1<<16) | (1<<0);
- while (USB1_ENDPTFLUSH & ((1<<16) | (1<<0))) ;
- endpoint0_notify_mask = 0;
- endpoint0_setup(s.bothwords);
- setupstatus = USB1_ENDPTSETUPSTAT;
- }
- uint32_t completestatus = USB1_ENDPTCOMPLETE;
- if (completestatus) {
- USB1_ENDPTCOMPLETE = completestatus;
-
- if (completestatus & endpoint0_notify_mask) {
- endpoint0_notify_mask = 0;
- endpoint0_complete();
- }
- if (completestatus & endpointN_notify_mask) {
-
- }
- }
- }
- if (status & USB_USBSTS_URI) {
- USB1_ENDPTSETUPSTAT = USB1_ENDPTSETUPSTAT;
- USB1_ENDPTCOMPLETE = USB1_ENDPTCOMPLETE;
- while (USB1_ENDPTPRIME != 0) ;
- USB1_ENDPTFLUSH = 0xFFFFFFFF;
- if ((USB1_PORTSC1 & USB_PORTSC1_PR)) {
-
- } else {
-
-
-
- }
-
-
-
-
-
-
- }
- if (status & USB_USBSTS_PCI) {
- if (USB1_PORTSC1 & USB_PORTSC1_HSP) {
-
- } else {
-
- }
- }
- if (status & USB_USBSTS_SLI) {
-
- }
- if (status & USB_USBSTS_UEI) {
-
- }
- if ((USB1_USBINTR & USB_USBINTR_SRE) && (status & USB_USBSTS_SRI)) {
- printf("sof %d\n", usb_reboot_timer);
- if (usb_reboot_timer) {
- if (--usb_reboot_timer == 0) {
- asm("bkpt #251");
- }
- } else {
-
- USB1_USBINTR &= ~USB_USBINTR_SRE;
- }
- }
- }
-
-
-
-
- static void endpoint0_setup(uint64_t setupdata)
- {
- setup_t setup;
- uint32_t datalen = 0;
- const usb_descriptor_list_t *list;
-
- setup.bothwords = setupdata;
- switch (setup.wRequestAndType) {
- case 0x0500:
- endpoint0_receive(NULL, 0, 0);
- USB1_DEVICEADDR = USB_DEVICEADDR_USBADR(setup.wValue) | USB_DEVICEADDR_USBADRA;
- return;
- case 0x0900:
- usb_configuration = setup.wValue;
-
- volatile uint32_t *reg = &USB1_ENDPTCTRL1;
- const uint32_t *cfg = usb_endpoint_config_table;
- int i;
- for (i=0; i < NUM_ENDPOINTS; i++) {
- uint32_t n = *cfg++;
- *reg = n;
-
- uint32_t m = n & ~(USB_ENDPTCTRL_TXR | USB_ENDPTCTRL_RXR);
- *reg = m;
-
-
- reg++;
- }
-
- endpoint_queue_head[CDC_ACM_ENDPOINT*2+1].config = (CDC_ACM_ENDPOINT << 16);
- endpoint_queue_head[CDC_RX_ENDPOINT*2+0].config = (CDC_RX_SIZE << 16) | (1 << 29);
- endpoint_queue_head[CDC_TX_ENDPOINT*2+1].config = (CDC_TX_SIZE << 16) | (1 << 29);
-
-
- endpoint0_receive(NULL, 0, 0);
- return;
-
- case 0x0680:
- case 0x0681:
-
- for (list = usb_descriptor_list; list->addr != NULL; list++) {
- if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
- if ((setup.wValue >> 8) == 3) {
-
-
- datalen = *(list->addr);
- } else {
- datalen = list->length;
- }
- if (datalen > setup.wLength) datalen = setup.wLength;
- endpoint0_transmit(list->addr, datalen, 0);
- return;
- }
- }
- break;
- case 0x2221:
-
-
- case 0x2321:
- endpoint0_receive(NULL, 0, 0);
- return;
- case 0x2021:
- if (setup.wLength != 7) break;
- endpoint0_setupdata.bothwords = setupdata;
- endpoint0_receive(endpoint0_buffer, 7, 1);
- return;
- }
- USB1_ENDPTCTRL0 = 0x000010001;
- }
-
- static void endpoint0_transmit(const void *data, uint32_t len, int notify)
- {
-
- if (len > 0) {
-
- endpoint0_transfer_data.next = 1;
- endpoint0_transfer_data.status = (len << 16) | (1<<7);
- uint32_t addr = (uint32_t)data;
- endpoint0_transfer_data.pointer0 = addr;
- endpoint0_transfer_data.pointer1 = addr + 4096;
- endpoint0_transfer_data.pointer2 = addr + 8192;
- endpoint0_transfer_data.pointer3 = addr + 12288;
- endpoint0_transfer_data.pointer4 = addr + 16384;
-
- endpoint_queue_head[1].next = (uint32_t)&endpoint0_transfer_data;
- endpoint_queue_head[1].status = 0;
- USB1_ENDPTPRIME |= (1<<16);
- while (USB1_ENDPTPRIME) ;
- }
- endpoint0_transfer_ack.next = 1;
- endpoint0_transfer_ack.status = (1<<7) | (notify ? (1 << 15) : 0);
- endpoint0_transfer_ack.pointer0 = 0;
- endpoint_queue_head[0].next = (uint32_t)&endpoint0_transfer_ack;
- endpoint_queue_head[0].status = 0;
- USB1_ENDPTPRIME |= (1<<0);
- endpoint0_notify_mask = (notify ? (1 << 0) : 0);
- while (USB1_ENDPTPRIME) ;
- }
-
- static void endpoint0_receive(void *data, uint32_t len, int notify)
- {
-
- if (len > 0) {
-
- endpoint0_transfer_data.next = 1;
- endpoint0_transfer_data.status = (len << 16) | (1<<7);
- uint32_t addr = (uint32_t)data;
- endpoint0_transfer_data.pointer0 = addr;
- endpoint0_transfer_data.pointer1 = addr + 4096;
- endpoint0_transfer_data.pointer2 = addr + 8192;
- endpoint0_transfer_data.pointer3 = addr + 12288;
- endpoint0_transfer_data.pointer4 = addr + 16384;
-
- endpoint_queue_head[0].next = (uint32_t)&endpoint0_transfer_data;
- endpoint_queue_head[0].status = 0;
- USB1_ENDPTPRIME |= (1<<0);
- while (USB1_ENDPTPRIME) ;
- }
- endpoint0_transfer_ack.next = 1;
- endpoint0_transfer_ack.status = (1<<7) | (notify ? (1 << 15) : 0);
- endpoint0_transfer_ack.pointer0 = 0;
- endpoint_queue_head[1].next = (uint32_t)&endpoint0_transfer_ack;
- endpoint_queue_head[1].status = 0;
- USB1_ENDPTPRIME |= (1<<16);
- endpoint0_notify_mask = (notify ? (1 << 16) : 0);
- while (USB1_ENDPTPRIME) ;
- }
-
-
-
-
- static void endpoint0_complete(void)
- {
- setup_t setup;
-
- setup.bothwords = endpoint0_setupdata.bothwords;
-
- #ifdef CDC_STATUS_INTERFACE
- if (setup.wRequestAndType == 0x2021 ) {
- memcpy(usb_cdc_line_coding, endpoint0_buffer, 7);
- printf("usb_cdc_line_coding, baud=%u\n", usb_cdc_line_coding[0]);
- if (usb_cdc_line_coding[0] == 134) {
- USB1_USBINTR |= USB_USBINTR_SRE;
- usb_reboot_timer = 80;
- }
- }
- #endif
- }
-
- void usb_prepare_transfer(transfer_t *transfer, const void *data, uint32_t len, uint32_t param)
- {
- transfer->next = 1;
- transfer->status = (len << 16) | (1<<7);
- uint32_t addr = (uint32_t)data;
- transfer->pointer0 = addr;
- transfer->pointer1 = addr + 4096;
- transfer->pointer2 = addr + 8192;
- transfer->pointer3 = addr + 12288;
- transfer->pointer4 = addr + 16384;
- transfer->callback_param = param;
- }
-
- void usb_transmit(int endpoint_number, transfer_t *transfer)
- {
-
-
-
- if (endpoint_number < 2 || endpoint_number > NUM_ENDPOINTS) return;
- endpoint_t *endpoint = &endpoint_queue_head[endpoint_number * 2 + 1];
- if (endpoint->callback_function) {
- transfer->status |= (1<<15);
- } else {
-
-
- }
- uint32_t mask = 1 << (endpoint_number + 16);
- __disable_irq();
- #if 0
- if (endpoint->last_transfer) {
- if (!(endpoint->last_transfer->status & (1<<7))) {
- endpoint->last_transfer->next = (uint32_t)transfer;
- } else {
-
- endpoint->last_transfer->next = (uint32_t)transfer;
- if (USB1_ENDPTPRIME & mask) {
- endpoint->last_transfer = transfer;
- __enable_irq();
- printf(" case 2a\n");
- return;
- }
- uint32_t stat;
- uint32_t cmd = USB1_USBCMD;
- do {
- USB1_USBCMD = cmd | USB_USBCMD_ATDTW;
- stat = USB1_ENDPTSTATUS;
- } while (!(USB1_USBCMD & USB_USBCMD_ATDTW));
- USB1_USBCMD = cmd & ~USB_USBCMD_ATDTW;
- if (stat & mask) {
- endpoint->last_transfer = transfer;
- __enable_irq();
- printf(" case 2b\n");
- return;
- }
- }
- } else {
- endpoint->first_transfer = transfer;
- }
- endpoint->last_transfer = transfer;
- #endif
-
- endpoint->next = (uint32_t)transfer;
- endpoint->status = 0;
- USB1_ENDPTPRIME |= mask;
- while (USB1_ENDPTPRIME & mask) ;
- __enable_irq();
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|