|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015 |
- #include "usb_dev.h"
- #define USB_DESC_LIST_DEFINE
- #include "usb_desc.h"
- #include "usb_serial.h"
- #include "usb_seremu.h"
- #include "usb_rawhid.h"
- #include "usb_keyboard.h"
- #include "usb_mouse.h"
- #include "usb_joystick.h"
- #include "usb_flightsim.h"
- #include "usb_touch.h"
- #include "usb_midi.h"
- #include "usb_audio.h"
- #include "core_pins.h"
- #include "avr/pgmspace.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;
- volatile uint8_t usb_high_speed = 0;
- static uint8_t endpoint0_buffer[8];
- static uint8_t sof_usage = 0;
- static uint8_t usb_reboot_timer = 0;
-
- extern uint8_t usb_descriptor_buffer[];
- extern const uint8_t usb_config_descriptor_480[];
- extern const uint8_t usb_config_descriptor_12[];
-
- void (*usb_timer0_callback)(void) = NULL;
- void (*usb_timer1_callback)(void) = NULL;
-
- 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);
-
-
- static void run_callbacks(endpoint_t *ep);
-
-
- FLASHMEM 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);
-
- printf("BURSTSIZE=%08lX\n", USB1_BURSTSIZE);
-
- USB1_BURSTSIZE = 0x0404;
- printf("BURSTSIZE=%08lX\n", USB1_BURSTSIZE);
- printf("USB1_TXFILLTUNING=%08lX\n", USB1_TXFILLTUNING);
-
-
-
-
-
-
-
-
-
-
-
-
- #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(25);
- }
- #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();
- }
- completestatus &= endpointN_notify_mask;
- #if 1
- if (completestatus) {
-
-
- uint32_t tx = completestatus >> 16;
- while (tx) {
- int p=__builtin_ctz(tx);
- run_callbacks(endpoint_queue_head + p * 2 + 1);
- tx &= ~(1<<p);
- }
-
-
- uint32_t rx = completestatus & 0xffff;
- while(rx) {
- int p=__builtin_ctz(rx);
- run_callbacks(endpoint_queue_head + p * 2);
- rx &= ~(1<<p);
- };
- }
- #else
- if (completestatus) {
- int i;
- for (i=2; i <= NUM_ENDPOINTS; i++) {
- if (completestatus & (1 << i)) {
- run_callbacks(endpoint_queue_head + i * 2);
- }
- if (completestatus & (1 << (i + 16))) {
- run_callbacks(endpoint_queue_head + i * 2 + 1);
- }
- }
- }
- #endif
-
- }
- }
- 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 defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE)
- usb_serial_reset();
- #endif
- endpointN_notify_mask = 0;
-
-
-
-
-
-
- }
- if (status & USB_USBSTS_TI0) {
- if (usb_timer0_callback != NULL) usb_timer0_callback();
- }
- if (status & USB_USBSTS_TI1) {
- if (usb_timer1_callback != NULL) usb_timer1_callback();
- }
- if (status & USB_USBSTS_PCI) {
- if (USB1_PORTSC1 & USB_PORTSC1_HSP) {
-
- usb_high_speed = 1;
- } else {
-
- usb_high_speed = 0;
- }
- }
- if (status & USB_USBSTS_SLI) {
-
- }
- if (status & USB_USBSTS_UEI) {
-
- }
- if ((USB1_USBINTR & USB_USBINTR_SRE) && (status & USB_USBSTS_SRI)) {
-
- if (usb_reboot_timer) {
- if (--usb_reboot_timer == 0) {
- usb_stop_sof_interrupts(NUM_INTERFACE);
- asm("bkpt #251");
- }
- }
- #ifdef MIDI_INTERFACE
- usb_midi_flush_output();
- #endif
- #ifdef MULTITOUCH_INTERFACE
- usb_touchscreen_update_callback();
- #endif
- #ifdef FLIGHTSIM_INTERFACE
- usb_flightsim_flush_output();
- #endif
- }
- }
-
-
- void usb_start_sof_interrupts(int interface)
- {
- __disable_irq();
- sof_usage |= (1 << interface);
- uint32_t intr = USB1_USBINTR;
- if (!(intr & USB_USBINTR_SRE)) {
- USB1_USBSTS = USB_USBSTS_SRI;
- USB1_USBINTR = intr | USB_USBINTR_SRE;
- }
- __enable_irq();
- }
-
- void usb_stop_sof_interrupts(int interface)
- {
- sof_usage &= ~(1 << interface);
- if (sof_usage == 0) {
- USB1_USBINTR &= ~USB_USBINTR_SRE;
- }
- }
-
-
-
-
-
-
- static uint8_t reply_buffer[8];
-
- static void endpoint0_setup(uint64_t setupdata)
- {
- setup_t setup;
- uint32_t endpoint, dir, ctrl;
- 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;
-
- #if defined(ENDPOINT2_CONFIG)
- USB1_ENDPTCTRL2 = ENDPOINT2_CONFIG;
- #endif
- #if defined(ENDPOINT3_CONFIG)
- USB1_ENDPTCTRL3 = ENDPOINT3_CONFIG;
- #endif
- #if defined(ENDPOINT4_CONFIG)
- USB1_ENDPTCTRL4 = ENDPOINT4_CONFIG;
- #endif
- #if defined(ENDPOINT5_CONFIG)
- USB1_ENDPTCTRL5 = ENDPOINT5_CONFIG;
- #endif
- #if defined(ENDPOINT6_CONFIG)
- USB1_ENDPTCTRL6 = ENDPOINT6_CONFIG;
- #endif
- #if defined(ENDPOINT7_CONFIG)
- USB1_ENDPTCTRL7 = ENDPOINT7_CONFIG;
- #endif
- #if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE)
- usb_serial_configure();
- #elif defined(SEREMU_INTERFACE)
- usb_seremu_configure();
- #endif
- #if defined(CDC2_STATUS_INTERFACE) && defined(CDC2_DATA_INTERFACE)
- usb_serial2_configure();
- #endif
- #if defined(CDC3_STATUS_INTERFACE) && defined(CDC3_DATA_INTERFACE)
- usb_serial3_configure();
- #endif
- #if defined(RAWHID_INTERFACE)
- usb_rawhid_configure();
- #endif
- #if defined(KEYBOARD_INTERFACE)
- usb_keyboard_configure();
- #endif
- #if defined(MOUSE_INTERFACE)
- usb_mouse_configure();
- #endif
- #if defined(FLIGHTSIM_INTERFACE)
- usb_flightsim_configure();
- #endif
- #if defined(JOYSTICK_INTERFACE)
- usb_joystick_configure();
- #endif
- #if defined(MULTITOUCH_INTERFACE)
- usb_touchscreen_configure();
- #endif
- #if defined(MIDI_INTERFACE)
- usb_midi_configure();
- #endif
- #if defined(AUDIO_INTERFACE)
- usb_audio_configure();
- #endif
- endpoint0_receive(NULL, 0, 0);
- return;
- case 0x0880:
- reply_buffer[0] = usb_configuration;
- endpoint0_transmit(reply_buffer, 1, 0);
- return;
- case 0x0080:
- reply_buffer[0] = 0;
- reply_buffer[1] = 0;
- endpoint0_transmit(reply_buffer, 2, 0);
- return;
- case 0x0082:
- endpoint = setup.wIndex & 0x7F;
- if (endpoint > 7) break;
- dir = setup.wIndex & 0x80;
- ctrl = *((uint32_t *)&USB1_ENDPTCTRL0 + endpoint);
- reply_buffer[0] = 0;
- reply_buffer[1] = 0;
- if ((dir && (ctrl & USB_ENDPTCTRL_TXS)) || (!dir && (ctrl & USB_ENDPTCTRL_RXS))) {
- reply_buffer[0] = 1;
- }
- endpoint0_transmit(reply_buffer, 2, 0);
- return;
- case 0x0302:
- endpoint = setup.wIndex & 0x7F;
- if (endpoint > 7) break;
- dir = setup.wIndex & 0x80;
- if (dir) {
- *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) |= USB_ENDPTCTRL_TXS;
- } else {
- *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) |= USB_ENDPTCTRL_RXS;
- }
- endpoint0_receive(NULL, 0, 0);
- return;
- case 0x0102:
- endpoint = setup.wIndex & 0x7F;
- if (endpoint > 7) break;
- dir = setup.wIndex & 0x80;
- if (dir) {
- *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) &= ~USB_ENDPTCTRL_TXS;
- } else {
- *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) &= ~USB_ENDPTCTRL_RXS;
- }
- 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) {
- uint32_t datalen;
- if ((setup.wValue >> 8) == 3) {
-
-
- datalen = *(list->addr);
- } else {
- datalen = list->length;
- }
- if (datalen > setup.wLength) datalen = setup.wLength;
-
-
- if (setup.wValue == 0x200) {
-
- const uint8_t *src = usb_config_descriptor_12;
- if (usb_high_speed) src = usb_config_descriptor_480;
- memcpy(usb_descriptor_buffer, src, datalen);
- } else if (setup.wValue == 0x700) {
-
- const uint8_t *src = usb_config_descriptor_480;
- if (usb_high_speed) src = usb_config_descriptor_12;
- memcpy(usb_descriptor_buffer, src, datalen);
- usb_descriptor_buffer[1] = 7;
- } else {
- memcpy(usb_descriptor_buffer, list->addr, datalen);
- }
-
- arm_dcache_flush_delete(usb_descriptor_buffer, datalen);
- endpoint0_transmit(usb_descriptor_buffer, datalen, 0);
- return;
- }
- }
- break;
- #if defined(CDC_STATUS_INTERFACE)
- case 0x2221:
- #ifdef CDC_STATUS_INTERFACE
- if (setup.wIndex == CDC_STATUS_INTERFACE) {
- usb_cdc_line_rtsdtr_millis = systick_millis_count;
- usb_cdc_line_rtsdtr = setup.wValue;
- }
- #endif
- #ifdef CDC2_STATUS_INTERFACE
- if (setup.wIndex == CDC2_STATUS_INTERFACE) {
- usb_cdc2_line_rtsdtr_millis = systick_millis_count;
- usb_cdc2_line_rtsdtr = setup.wValue;
- }
- #endif
- #ifdef CDC3_STATUS_INTERFACE
- if (setup.wIndex == CDC3_STATUS_INTERFACE) {
- usb_cdc3_line_rtsdtr_millis = systick_millis_count;
- usb_cdc3_line_rtsdtr = setup.wValue;
- }
- #endif
-
- 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;
- #endif
- #if defined(SEREMU_INTERFACE) || defined(KEYBOARD_INTERFACE)
- case 0x0921:
- if (setup.wLength <= sizeof(endpoint0_buffer)) {
-
- endpoint0_setupdata.bothwords = setup.bothwords;
- endpoint0_buffer[0] = 0xE9;
- endpoint0_receive(endpoint0_buffer, setup.wLength, 1);
- return;
- }
- break;
- #endif
- #if defined(AUDIO_INTERFACE)
- case 0x0B01:
- if (setup.wIndex == AUDIO_INTERFACE+1) {
- usb_audio_transmit_setting = setup.wValue;
- if (usb_audio_transmit_setting > 0) {
-
- }
- endpoint0_receive(NULL, 0, 0);
- return;
- } else if (setup.wIndex == AUDIO_INTERFACE+2) {
- usb_audio_receive_setting = setup.wValue;
- endpoint0_receive(NULL, 0, 0);
- return;
- }
- break;
- case 0x0A81:
- if (setup.wIndex == AUDIO_INTERFACE+1) {
- endpoint0_buffer[0] = usb_audio_transmit_setting;
- endpoint0_transmit(endpoint0_buffer, 1, 0);
- return;
- } else if (setup.wIndex == AUDIO_INTERFACE+2) {
- endpoint0_buffer[0] = usb_audio_receive_setting;
- endpoint0_transmit(endpoint0_buffer, 1, 0);
- return;
- }
- break;
- case 0x0121:
- case 0x0221:
- case 0x0321:
- case 0x0421:
-
- if (setup.wLength <= sizeof(endpoint0_buffer)) {
- endpoint0_setupdata.bothwords = setupdata;
- endpoint0_receive(endpoint0_buffer, setup.wLength, 1);
- return;
- }
- break;
- case 0x81A1:
- case 0x82A1:
- case 0x83A1:
- case 0x84A1:
- if (setup.wLength <= sizeof(endpoint0_buffer)) {
- uint32_t len;
- if (usb_audio_get_feature(&setup, endpoint0_buffer, &len)) {
-
- endpoint0_transmit(endpoint0_buffer, len, 0);
- return;
- }
- }
- break;
- case 0x81A2:
- if (setup.wLength >= 3) {
- endpoint0_buffer[0] = 44100 & 255;
- endpoint0_buffer[1] = 44100 >> 8;
- endpoint0_buffer[2] = 0;
- endpoint0_transmit(endpoint0_buffer, 3, 0);
- return;
- }
- break;
- #endif
- }
- 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_ENDPTCOMPLETE = (1<<0) | (1<<16);
- 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_ENDPTCOMPLETE = (1<<0) | (1<<16);
- 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 && setup.wIndex == CDC_STATUS_INTERFACE) {
- 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) {
- usb_start_sof_interrupts(NUM_INTERFACE);
- usb_reboot_timer = 80;
- }
- }
- #endif
- #ifdef CDC2_STATUS_INTERFACE
- if (setup.wRequestAndType == 0x2021 && setup.wIndex == CDC2_STATUS_INTERFACE) {
- memcpy(usb_cdc2_line_coding, endpoint0_buffer, 7);
- printf("usb_cdc2_line_coding, baud=%u\n", usb_cdc2_line_coding[0]);
- if (usb_cdc2_line_coding[0] == 134) {
- usb_start_sof_interrupts(NUM_INTERFACE);
- usb_reboot_timer = 80;
- }
- }
- #endif
- #ifdef CDC3_STATUS_INTERFACE
- if (setup.wRequestAndType == 0x2021 && setup.wIndex == CDC3_STATUS_INTERFACE) {
- memcpy(usb_cdc3_line_coding, endpoint0_buffer, 7);
- printf("usb_cdc3_line_coding, baud=%u\n", usb_cdc3_line_coding[0]);
- if (usb_cdc3_line_coding[0] == 134) {
- usb_start_sof_interrupts(NUM_INTERFACE);
- usb_reboot_timer = 80;
- }
- }
- #endif
- #ifdef KEYBOARD_INTERFACE
- if (setup.word1 == 0x02000921 && setup.word2 == ((1 << 16) | KEYBOARD_INTERFACE)) {
- keyboard_leds = endpoint0_buffer[0];
- endpoint0_transmit(NULL, 0, 0);
- }
- #endif
- #ifdef SEREMU_INTERFACE
- if (setup.word1 == 0x03000921 && setup.word2 == ((4<<16)|SEREMU_INTERFACE)
- && endpoint0_buffer[0] == 0xA9 && endpoint0_buffer[1] == 0x45
- && endpoint0_buffer[2] == 0xC2 && endpoint0_buffer[3] == 0x6B) {
- printf("seremu reboot request\n");
- usb_start_sof_interrupts(NUM_INTERFACE);
- usb_reboot_timer = 80;
- }
- #endif
- #ifdef AUDIO_INTERFACE
- if (setup.word1 == 0x02010121 ) {
- usb_audio_set_feature(&endpoint0_setupdata, endpoint0_buffer);
- }
- #endif
- }
-
- static void usb_endpoint_config(endpoint_t *qh, uint32_t config, void (*callback)(transfer_t *))
- {
- memset(qh, 0, sizeof(endpoint_t));
- qh->config = config;
- qh->next = 1;
- qh->callback_function = callback;
- }
-
- void usb_config_rx(uint32_t ep, uint32_t packet_size, int do_zlp, void (*cb)(transfer_t *))
- {
- uint32_t config = (packet_size << 16) | (do_zlp ? 0 : (1 << 29));
- if (ep < 2 || ep > NUM_ENDPOINTS) return;
- usb_endpoint_config(endpoint_queue_head + ep * 2, config, cb);
- if (cb) endpointN_notify_mask |= (1 << ep);
- }
-
- void usb_config_tx(uint32_t ep, uint32_t packet_size, int do_zlp, void (*cb)(transfer_t *))
- {
- uint32_t config = (packet_size << 16) | (do_zlp ? 0 : (1 << 29));
- if (ep < 2 || ep > NUM_ENDPOINTS) return;
- usb_endpoint_config(endpoint_queue_head + ep * 2 + 1, config, cb);
- if (cb) endpointN_notify_mask |= (1 << (ep + 16));
- }
-
- void usb_config_rx_iso(uint32_t ep, uint32_t packet_size, int mult, void (*cb)(transfer_t *))
- {
- if (mult < 1 || mult > 3) return;
- uint32_t config = (packet_size << 16) | (mult << 30);
- if (ep < 2 || ep > NUM_ENDPOINTS) return;
- usb_endpoint_config(endpoint_queue_head + ep * 2, config, cb);
- if (cb) endpointN_notify_mask |= (1 << ep);
- }
-
- void usb_config_tx_iso(uint32_t ep, uint32_t packet_size, int mult, void (*cb)(transfer_t *))
- {
- if (mult < 1 || mult > 3) return;
- uint32_t config = (packet_size << 16) | (mult << 30);
- if (ep < 2 || ep > NUM_ENDPOINTS) return;
- usb_endpoint_config(endpoint_queue_head + ep * 2 + 1, config, cb);
- if (cb) endpointN_notify_mask |= (1 << (ep + 16));
- }
-
-
-
- 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;
- }
-
- #if 0
- void usb_print_transfer_log(void)
- {
- uint32_t i, count;
- printf("log %d transfers\n", transfer_log_count);
- count = transfer_log_count;
- if (count > LOG_SIZE) count = LOG_SIZE;
-
- for (i=0; i < count; i++) {
- if (transfer_log_head == 0) transfer_log_head = LOG_SIZE;
- transfer_log_head--;
- uint32_t log = transfer_log[transfer_log_head];
- printf(" %c %X\n", log >> 8, (int)(log & 255));
- }
- }
- #endif
-
- static void schedule_transfer(endpoint_t *endpoint, uint32_t epmask, transfer_t *transfer)
- {
-
-
-
-
- if (endpoint->callback_function) {
- transfer->status |= (1<<15);
- }
- __disable_irq();
-
-
- transfer_t *last = endpoint->last_transfer;
- if (last) {
- last->next = (uint32_t)transfer;
- if (USB1_ENDPTPRIME & epmask) goto end;
-
-
- uint32_t status, cyccnt=ARM_DWT_CYCCNT;
- do {
- USB1_USBCMD |= USB_USBCMD_ATDTW;
- status = USB1_ENDPTSTATUS;
- } while (!(USB1_USBCMD & USB_USBCMD_ATDTW) && (ARM_DWT_CYCCNT - cyccnt < 2400));
-
- if (status & epmask) goto end;
-
- }
-
- endpoint->next = (uint32_t)transfer;
- endpoint->status = 0;
- USB1_ENDPTPRIME |= epmask;
- endpoint->first_transfer = transfer;
- end:
- endpoint->last_transfer = transfer;
- __enable_irq();
-
-
-
-
-
-
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- static void run_callbacks(endpoint_t *ep)
- {
-
- transfer_t *first = ep->first_transfer;
- if (first == NULL) return;
-
-
- uint32_t count = 0;
- transfer_t *t = first;
- while (1) {
- if (t->status & (1<<7)) {
-
-
- ep->first_transfer = t;
- break;
- }
- count++;
- t = (transfer_t *)t->next;
- if ((uint32_t)t == 1) {
-
-
- ep->first_transfer = NULL;
- ep->last_transfer = NULL;
- break;
- }
- }
-
- while (count) {
- transfer_t *next = (transfer_t *)first->next;
- ep->callback_function(first);
- first = next;
- count--;
- }
- }
-
- 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;
- uint32_t mask = 1 << (endpoint_number + 16);
- schedule_transfer(endpoint, mask, transfer);
- }
-
- void usb_receive(int endpoint_number, transfer_t *transfer)
- {
- if (endpoint_number < 2 || endpoint_number > NUM_ENDPOINTS) return;
- endpoint_t *endpoint = endpoint_queue_head + endpoint_number * 2;
- uint32_t mask = 1 << endpoint_number;
- schedule_transfer(endpoint, mask, transfer);
- }
-
- uint32_t usb_transfer_status(const transfer_t *transfer)
- {
- #if 0
- uint32_t status, cmd;
-
- cmd = USB1_USBCMD;
- while (1) {
- __disable_irq();
- USB1_USBCMD = cmd | USB_USBCMD_ATDTW;
- status = transfer->status;
- cmd = USB1_USBCMD;
- __enable_irq();
- if (cmd & USB_USBCMD_ATDTW) return status;
-
-
-
- }
- #else
- return transfer->status;
- #endif
- }
-
-
|