diff --git a/.gitignore b/.gitignore index a08af4e..8a76b48 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,9 @@ F1/client-term/client *.files *.includes +*.cflags +*.config +*.creator* +*.cxxflags +*.files +*.includes diff --git a/F1-nolib/CDC_ACM/cdcacm.bin b/F1-nolib/CDC_ACM/cdcacm.bin index ccafeba..46c7c54 100755 Binary files a/F1-nolib/CDC_ACM/cdcacm.bin and b/F1-nolib/CDC_ACM/cdcacm.bin differ diff --git a/F1-nolib/CDC_ACM/main.c b/F1-nolib/CDC_ACM/main.c index 24f5653..4e24697 100644 --- a/F1-nolib/CDC_ACM/main.c +++ b/F1-nolib/CDC_ACM/main.c @@ -193,7 +193,7 @@ int main(void){ USB_send((uint8_t*)"USART overflow!\n", 16); } uint8_t tmpbuf[USB_RXBUFSZ], *txt; - uint16_t x = USB_receive(tmpbuf); + uint8_t x = USB_receive(tmpbuf); if(x){ //for(int _ = 0; _ < 7000000; ++_)nop(); //USB_send(tmpbuf, x); diff --git a/F1-nolib/CDC_ACM/usb.c b/F1-nolib/CDC_ACM/usb.c index 45eabfa..3af52c9 100644 --- a/F1-nolib/CDC_ACM/usb.c +++ b/F1-nolib/CDC_ACM/usb.c @@ -67,7 +67,6 @@ void USB_setup(){ DBG("USB irq enabled"); } - static int usbwr(const uint8_t *buf, uint16_t l){ uint32_t ctra = 1000000; while(--ctra && tx_succesfull == 0){ @@ -97,14 +96,14 @@ static void send_next(){ // unblocking sending - just fill a buffer void USB_send(const uint8_t *buf, uint16_t len){ if(!usbON || !len) return; - if(len > USB_TXBUFSZ-1){ - USB_send_blk(buf, len); - return; - } if(len > USB_TXBUFSZ-1 - buflen){ usbwr(usbbuff, buflen); buflen = 0; } + if(len > USB_TXBUFSZ-1){ + USB_send_blk(buf, len); + return; + } while(len--) usbbuff[buflen++] = *buf++; } @@ -128,7 +127,6 @@ void USB_send_blk(const uint8_t *buf, uint16_t len){ } } - void usb_proc(){ switch(USB_Dev.USB_Status){ case USB_STATE_CONFIGURED: diff --git a/F1-nolib/CDC_ACM/usb_lib.c b/F1-nolib/CDC_ACM/usb_lib.c index 943fde7..a25a31d 100644 --- a/F1-nolib/CDC_ACM/usb_lib.c +++ b/F1-nolib/CDC_ACM/usb_lib.c @@ -198,6 +198,7 @@ static void wr0(const uint8_t *buf, uint16_t size){ if(setup_packet.wLength < size) size = setup_packet.wLength; // shortened request if(size < endpoints[0].txbufsz){ EP_WriteIRQ(0, buf, size); + return; } while(size){ uint16_t l = size; @@ -305,8 +306,6 @@ bmRequestType: 76543210 */ /** * Endpoint0 (control) handler - * @param ep - endpoint state - * @return data written to EP0R */ static void EP0_Handler(){ uint8_t reqtype = setup_packet.bmRequestType & 0x7f; @@ -487,7 +486,7 @@ void usb_lp_can_rx0_isr(){ */ void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){ uint8_t i; - if(size > USB_TXBUFSZ) size = USB_TXBUFSZ; + if(size > endpoints[number].txbufsz) size = endpoints[number].txbufsz; uint16_t N2 = (size + 1) >> 1; // the buffer is 16-bit, so we should copy data as it would be uint16_t uint16_t *buf16 = (uint16_t *)buf; diff --git a/F1-nolib/PL2303/pl2303.bin b/F1-nolib/PL2303/pl2303.bin index 6805c73..81a55a6 100755 Binary files a/F1-nolib/PL2303/pl2303.bin and b/F1-nolib/PL2303/pl2303.bin differ diff --git a/F1-nolib/PL2303/usb_lib.c b/F1-nolib/PL2303/usb_lib.c index 86436e6..db9635b 100644 --- a/F1-nolib/PL2303/usb_lib.c +++ b/F1-nolib/PL2303/usb_lib.c @@ -438,7 +438,7 @@ void usb_lp_can_rx0_isr(){ */ void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){ uint8_t i; - if(size > USB_TXBUFSZ) size = USB_TXBUFSZ; + if(size > endpoints[number].txbufsz) size = endpoints[number].txbufsz; uint16_t N2 = (size + 1) >> 1; // the buffer is 16-bit, so we should copy data as it would be uint16_t uint16_t *buf16 = (uint16_t *)buf; diff --git a/F1-nolib/USB_HID/hardware.h b/F1-nolib/USB_HID/hardware.h index 0f3c11f..961e042 100644 --- a/F1-nolib/USB_HID/hardware.h +++ b/F1-nolib/USB_HID/hardware.h @@ -27,8 +27,8 @@ #include "stm32f1.h" // LED - blinking each second -#define LED_port GPIOA -#define LED_pin (1<<0) +#define LED_port GPIOC +#define LED_pin (1<<13) // USB pullup (not used in STM32F0x2!) - PA13 #define USBPU_port GPIOA diff --git a/F1-nolib/USB_HID/main.c b/F1-nolib/USB_HID/main.c index 1384434..602f474 100644 --- a/F1-nolib/USB_HID/main.c +++ b/F1-nolib/USB_HID/main.c @@ -34,13 +34,13 @@ void sys_tick_handler(void){ static void hw_setup(){ // Enable clocks to the GPIO subsystems (PB for ADC), turn on AFIO clocking to disable SWD/JTAG - RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN; + RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN; // turn off SWJ/JTAG - AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE; + //AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE; // turn off USB pullup GPIOA->ODR = (1<<13); - // Set led (PA0) as opendrain output - GPIOA->CRL = CRL(0, CNF_ODOUTPUT|MODE_SLOW); + // Set led (PC13) as opendrain output + GPIOC->CRH = CRH(13, CNF_ODOUTPUT|MODE_SLOW); // Set USB pullup (PA13) as opendrain output GPIOA->CRH = CRH(13, CNF_ODOUTPUT|MODE_SLOW); } @@ -111,7 +111,7 @@ static char *parse_cmd(char *buf){ break; case 'C': SEND("USB "); - if(!USB_configured()) SEND("dis"); + if(!usbON) SEND("dis"); SEND("connected\n"); break; case 'K': diff --git a/F1-nolib/USB_HID/usart.c b/F1-nolib/USB_HID/usart.c index 2c0f730..c16ab3f 100644 --- a/F1-nolib/USB_HID/usart.c +++ b/F1-nolib/USB_HID/usart.c @@ -53,7 +53,10 @@ int usart_getline(char **line){ // transmit current tbuf and swap buffers void transmit_tbuf(){ uint32_t tmout = 72000; - while(!txrdy){if(--tmout == 0) return;}; // wait for previos buffer transmission + while(!txrdy){ // wait for previos buffer transmission + IWDG->KR = IWDG_REFRESH; + if(--tmout == 0) return; + } register int l = odatalen[tbufno]; if(!l) return; txrdy = 0; @@ -66,7 +69,10 @@ void transmit_tbuf(){ } void usart_putchar(const char ch){ - for(int i = 0; odatalen[tbufno] == UARTBUFSZO && i < 1024; ++i) transmit_tbuf(); + for(int i = 0; odatalen[tbufno] == UARTBUFSZO && i < 1024; ++i){ + IWDG->KR = IWDG_REFRESH; + transmit_tbuf(); + } tbuf[tbufno][odatalen[tbufno]++] = ch; } diff --git a/F1-nolib/USB_HID/usart.h b/F1-nolib/USB_HID/usart.h index a48b92c..eb722cc 100644 --- a/F1-nolib/USB_HID/usart.h +++ b/F1-nolib/USB_HID/usart.h @@ -38,7 +38,7 @@ #ifdef EBUG #define MSG(str) do{SEND(__FILE__ " (L" STR(__LINE__) "): " str);}while(0) -#define DBG(str) do{SEND(str); usart_putchar('\n'); }while(0) +#define DBG(str) do{SEND(str); usart_putchar('\n'); transmit_tbuf();}while(0) #else #define MSG(str) #define DBG(str) diff --git a/F1-nolib/USB_HID/usb.c b/F1-nolib/USB_HID/usb.c index e3a5f70..67bf72b 100644 --- a/F1-nolib/USB_HID/usb.c +++ b/F1-nolib/USB_HID/usb.c @@ -25,24 +25,25 @@ #include "usb_lib.h" #include "usart.h" -// incoming buffer size -#define IDATASZ (256) -static volatile uint8_t tx_succesfull = 0; -static int8_t usbON = 0; // ==1 when USB fully configured +static volatile uint8_t tx_succesfull = 1; // interrupt IN handler -static uint16_t EP1_Handler(ep_t ep){ - if(ep.tx_flag){ +static void EP1_Handler(){ + uint16_t epstatus = KEEP_DTOG(USB->EPnR[1]); + if(RX_FLAG(epstatus)) epstatus = (epstatus & ~USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_RX; // set valid RX + else{ tx_succesfull = 1; - ep.status = SET_VALID_RX(ep.status); - ep.status = SET_VALID_TX(ep.status); + epstatus = epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_STAT_RX); } - return ep.status; + // clear CTR + epstatus = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX)); + USB->EPnR[1] = epstatus; } void USB_setup(){ NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); + DBG("USB setup"); RCC->APB1ENR |= RCC_APB1ENR_USBEN; USB->CNTR = USB_CNTR_FRES; // Force USB Reset for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms @@ -52,11 +53,10 @@ void USB_setup(){ USB->ISTR = 0; USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); - NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn ); } void usb_proc(){ - if(USB_GetState() == USB_CONFIGURE_STATE){ // USB configured - activate other endpoints + if(USB_Dev.USB_Status == USB_STATE_CONFIGURED){ // USB configured - activate other endpoints if(!usbON){ // endpoints not activated EP_Init(1, EP_TYPE_INTERRUPT, USB_TXBUFSZ, 0, EP1_Handler); // IN1 - transmit usbON = 1; @@ -67,14 +67,16 @@ void usb_proc(){ } void USB_send(uint8_t *buf, uint16_t size){ - if(!usbON) return; + if(!usbON || !size) return; uint16_t ctr = 0; while(size){ uint16_t s = (size > USB_KEYBOARD_REPORT_SIZE) ? USB_KEYBOARD_REPORT_SIZE : size; tx_succesfull = 0; EP_Write(1, (uint8_t*)&buf[ctr], s); uint32_t ctra = 1000000; - while(--ctra && tx_succesfull == 0); + while(--ctra && tx_succesfull == 0){ + IWDG->KR = IWDG_REFRESH; + } if(!tx_succesfull){ DBG("Error sending data!"); } @@ -83,10 +85,3 @@ void USB_send(uint8_t *buf, uint16_t size){ } } -/** - * @brief USB_configured - * @return 1 if USB is in configured state - */ -int USB_configured(){ - return usbON; -} diff --git a/F1-nolib/USB_HID/usb.h b/F1-nolib/USB_HID/usb.h index a8655aa..9847331 100644 --- a/F1-nolib/USB_HID/usb.h +++ b/F1-nolib/USB_HID/usb.h @@ -31,6 +31,5 @@ void USB_setup(); void usb_proc(); void USB_send(uint8_t *buf, uint16_t size); -int USB_configured(); #endif // __USB_H__ diff --git a/F1-nolib/USB_HID/usb_lib.c b/F1-nolib/USB_HID/usb_lib.c index 6e66720..3ce80c5 100644 --- a/F1-nolib/USB_HID/usb_lib.c +++ b/F1-nolib/USB_HID/usb_lib.c @@ -27,8 +27,10 @@ ep_t endpoints[STM32ENDPOINTS]; -static usb_dev_t USB_Dev; -config_pack_t setup_packet; +usb_dev_t USB_Dev; +static config_pack_t setup_packet; + +uint8_t usbON = 0; // device disconnected from terminal // definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor #define bcdUSB_L 0x00 @@ -175,14 +177,37 @@ static const uint8_t USB_ConfigDescriptor[] = { 0x01, /* bInterval: */ }; -_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US); -_USB_STRING_(USB_StringSerialDescriptor, u"0"); -_USB_STRING_(USB_StringManufacturingDescriptor, u"SAO RAS"); -_USB_STRING_(USB_StringProdDescriptor, u"USB HID mouse+keyboard"); +USB_LANG_ID(USB_StringLangDescriptor, LANG_US); +USB_STRING(USB_StringSerialDescriptor, u"01"); +USB_STRING(USB_StringManufacturingDescriptor, u"Eddy @ SAO RAS"); +USB_STRING(USB_StringProdDescriptor, u"USB HID mouse+keyboard"); static void wr0(const uint8_t *buf, uint16_t size){ - if(setup_packet.wLength < size) size = setup_packet.wLength; - EP_WriteIRQ(0, buf, size); + if(setup_packet.wLength < size) size = setup_packet.wLength; // shortened request + if(size < endpoints[0].txbufsz){ + EP_WriteIRQ(0, buf, size); + return; + } + while(size){ + uint16_t l = size; + if(l > endpoints[0].txbufsz) l = endpoints[0].txbufsz; + EP_WriteIRQ(0, buf, l); + buf += l; + size -= l; + uint8_t needzlp = (l == endpoints[0].txbufsz) ? 1 : 0; + if(size || needzlp){ // send last data buffer + uint16_t status = KEEP_DTOG(USB->EPnR[0]); + // keep DTOGs, clear CTR_RX,TX, set TX VALID, leave stat_Rx + USB->EPnR[0] = (status & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX|USB_EPnR_STAT_RX)) + ^ USB_EPnR_STAT_TX; + uint32_t ctr = 1000000; + while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0){IWDG->KR = IWDG_REFRESH;}; + if((USB->ISTR & USB_ISTR_CTR) == 0){ + return; + } + if(needzlp) EP_WriteIRQ(0, (uint8_t*)0, 0); + } + } } static inline void get_descriptor(){ @@ -216,6 +241,11 @@ static inline void get_descriptor(){ wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]); break; default: + MSG("WTF?"); +#ifdef EBUG + printuhex(setup_packet.wValue); + newline(); +#endif break; } } @@ -246,7 +276,7 @@ static inline void std_h2d_req(){ break; case SET_CONFIGURATION: // Now device configured - USB_Dev.USB_Status = USB_CONFIGURE_STATE; + USB_Dev.USB_Status = USB_STATE_CONFIGURED; configuration = setup_packet.wValue; break; default: @@ -254,46 +284,17 @@ static inline void std_h2d_req(){ } } -static uint16_t WriteHID_descriptor(uint16_t status){ - uint16_t rest = sizeof(HID_ReportDescriptor); - uint8_t *ptr = (uint8_t*)HID_ReportDescriptor; - while(rest){ - uint16_t l = rest; - if(l > endpoints[0].txbufsz) l = endpoints[0].txbufsz; - EP_WriteIRQ(0, ptr, l); - ptr += l; - rest -= l; - uint8_t needzlp = (l == endpoints[0].txbufsz) ? 1 : 0; - if(rest || needzlp){ // send last data buffer - status = SET_NAK_RX(status); - status = SET_VALID_TX(status); - status = KEEP_DTOG_TX(status); - status = KEEP_DTOG_RX(status); - status = CLEAR_CTR_RX(status); - status = CLEAR_CTR_TX(status); - USB->ISTR = 0; - USB->EPnR[0] = status; - uint32_t ctr = 1000000; - while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0); - if((USB->ISTR & USB_ISTR_CTR) == 0){MSG("ERR\n");}; - USB->ISTR = 0; - status = USB->EPnR[0]; - if(needzlp) EP_WriteIRQ(0, (uint8_t*)0, 0); - } - } - return status; -} - /** * Endpoint0 (control) handler * @param ep - endpoint state * @return data written to EP0R */ -static uint16_t EP0_Handler(ep_t ep){ - uint16_t epstatus = ep.status; // EP0R on input -> return this value after modifications +static void EP0_Handler(){ + uint16_t epstatus = USB->EPnR[0]; // EP0R on input -> return this value after modifications uint8_t reqtype = setup_packet.bmRequestType & 0x7f; uint8_t dev2host = (setup_packet.bmRequestType & 0x80) ? 1 : 0; - if ((ep.rx_flag) && (ep.setup_flag)){ + int rxflag = RX_FLAG(epstatus); + if(rxflag && SETUP_FLAG(epstatus)){ switch(reqtype){ case STANDARD_DEVICE_REQUEST_TYPE: // standard device request if(dev2host){ @@ -302,62 +303,44 @@ static uint16_t EP0_Handler(ep_t ep){ std_h2d_req(); EP_WriteIRQ(0, (uint8_t *)0, 0); } - epstatus = SET_NAK_RX(epstatus); - epstatus = SET_VALID_TX(epstatus); break; case STANDARD_INTERFACE_REQUEST_TYPE: if(dev2host && setup_packet.bRequest == GET_DESCRIPTOR){ if(setup_packet.wValue == HID_REPORT_DESCRIPTOR){ - epstatus = WriteHID_descriptor(epstatus); + DBG("HID_REPORT_DESCRIPTOR"); + wr0(HID_ReportDescriptor, sizeof(HID_ReportDescriptor)); } } - epstatus = SET_NAK_RX(epstatus); - epstatus = SET_VALID_TX(epstatus); break; case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request if(setup_packet.bRequest == CLEAR_FEATURE){ EP_WriteIRQ(0, (uint8_t *)0, 0); - epstatus = SET_NAK_RX(epstatus); - epstatus = SET_VALID_TX(epstatus); } break; case CONTROL_REQUEST_TYPE: if(setup_packet.bRequest == SET_IDLE_REQUEST){ EP_WriteIRQ(0, (uint8_t *)0, 0); - epstatus = SET_NAK_RX(epstatus); - epstatus = SET_VALID_TX(epstatus); }else if (setup_packet.bRequest == SET_FEAUTRE){ //set_featuring = 1; - epstatus = SET_VALID_RX(epstatus); - epstatus = KEEP_STAT_TX(epstatus); } break; default: EP_WriteIRQ(0, (uint8_t *)0, 0); - epstatus = SET_NAK_RX(epstatus); - epstatus = SET_VALID_TX(epstatus); + MSG("WTF?"); } - }else if (ep.rx_flag || ep.tx_flag){ // got data over EP0 or host acknowlegement || package transmitted - if(ep.rx_flag){ - /*if (set_featuring){ - set_featuring = 0; - // here we can do something with ep.rx_buf - set_feature - }*/ - }else{ // tx - // now we can change address after enumeration - if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){ - USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr; - // change state to ADRESSED - USB_Dev.USB_Status = USB_ADRESSED_STATE; - } + }else if(TX_FLAG(epstatus)){ + // now we can change address after enumeration + if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){ + USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr; + // change state to ADRESSED + USB_Dev.USB_Status = USB_STATE_ADDRESSED; } - // end of transaction - epstatus = CLEAR_DTOG_RX(epstatus); - epstatus = CLEAR_DTOG_TX(epstatus); - epstatus = SET_VALID_RX(epstatus); - epstatus = SET_VALID_TX(epstatus); } - return epstatus; + epstatus = KEEP_DTOG(USB->EPnR[0]); + if(rxflag) epstatus ^= USB_EPnR_STAT_TX; // start ZLP/data transmission + else epstatus &= ~USB_EPnR_STAT_TX; // or leave unchanged + // keep DTOGs, clear CTR_RX,TX, set RX VALID + USB->EPnR[0] = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_RX; } static uint16_t lastaddr = LASTADDR_DEFAULT; @@ -370,7 +353,7 @@ static uint16_t lastaddr = LASTADDR_DEFAULT; * @param uint16_t (*func)(ep_t *ep) - EP handler function * @return 0 if all OK */ -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep)){ +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ if(number >= STM32ENDPOINTS) return 4; // out of configured amount if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable @@ -397,32 +380,28 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t } // standard IRQ handler -void usb_isr(){ - // disallow interrupts - //USB->CNTR = 0; - if (USB->ISTR & USB_ISTR_RESET){ - USB->ISTR = 0; - USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM; +void usb_lp_can_rx0_isr(){ + if(USB->ISTR & USB_ISTR_RESET){ + usbON = 0; + DBG("RESET"); + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; // Endpoint 0 - CONTROL // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! lastaddr = LASTADDR_DEFAULT; - if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ - DBG("Err init EP0"); - } // clear address, leave only enable bit USB->DADDR = USB_DADDR_EF; // state is default - wait for enumeration - USB_Dev.USB_Status = USB_DEFAULT_STATE; + USB_Dev.USB_Status = USB_STATE_DEFAULT; + USB->ISTR = ~USB_ISTR_RESET; + if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){ + return; + } } if(USB->ISTR & USB_ISTR_CTR){ // EP number uint8_t n = USB->ISTR & USB_ISTR_EPID; // copy status register uint16_t epstatus = USB->EPnR[n]; - // Calculate flags - endpoints[n].rx_flag = (epstatus & USB_EPnR_CTR_RX) ? 1 : 0; - endpoints[n].setup_flag = (epstatus & USB_EPnR_SETUP) ? 1 : 0; - endpoints[n].tx_flag = (epstatus & USB_EPnR_CTR_TX) ? 1 : 0; // copy received bytes amount endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter // check direction @@ -436,29 +415,17 @@ void usb_isr(){ }else{ // IN interrupt - transmit data, only CTR_TX == 1 // enumeration end could be here (if EP0) } - // prepare status field for EP handler - endpoints[n].status = epstatus; - // call EP handler (even if it will change EPnR, it should return new status) - epstatus = endpoints[n].func(endpoints[n]); - // keep DTOG state - epstatus = KEEP_DTOG_TX(epstatus); - epstatus = KEEP_DTOG_RX(epstatus); - // clear all RX/TX flags - epstatus = CLEAR_CTR_RX(epstatus); - epstatus = CLEAR_CTR_TX(epstatus); - // refresh EPnR - USB->EPnR[n] = epstatus; + if(endpoints[n].func) endpoints[n].func(endpoints[n]); + } + if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep + usbON = 0; + USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; + USB->ISTR = ~USB_ISTR_SUSP; + } + if(USB->ISTR & USB_ISTR_WKUP){ // wakeup + USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags + USB->ISTR = ~USB_ISTR_WKUP; } - // allow interrupts again - // USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM; -} - -void usb_lp_can_rx0_isr(){ - usb_isr(); -} - -void usb_hp_can_tx_isr(){ - usb_isr(); } /** @@ -487,13 +454,10 @@ void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){ * @param size - its size */ void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){ - uint16_t status = USB->EPnR[number]; EP_WriteIRQ(number, buf, size); - status = SET_NAK_RX(status); - status = SET_VALID_TX(status); - status = KEEP_DTOG_TX(status); - status = KEEP_DTOG_RX(status); - USB->EPnR[number] = status; + uint16_t status = KEEP_DTOG(USB->EPnR[number]); + // keep DTOGs, clear CTR_TX & set TX VALID to start transmission + USB->EPnR[number] = (status & ~(USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_TX; } /* @@ -502,16 +466,15 @@ void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){ * @return amount of data read */ int EP_Read(uint8_t number, uint16_t *buf){ - int n = (endpoints[number].rx_cnt + 1) >> 1; + int sz = endpoints[number].rx_cnt; + if(!sz) return 0; + endpoints[number].rx_cnt = 0; + int n = (sz + 1) >> 1; uint32_t *in = (uint32_t *)endpoints[number].rx_buf; if(n){ for(int i = 0; i < n; ++i, ++in) buf[i] = *(uint16_t*)in; } - return endpoints[number].rx_cnt; + return sz; } -// USB status -uint8_t USB_GetState(){ - return USB_Dev.USB_Status; -} diff --git a/F1-nolib/USB_HID/usb_lib.h b/F1-nolib/USB_HID/usb_lib.h index 8a29d62..06b0972 100644 --- a/F1-nolib/USB_HID/usb_lib.h +++ b/F1-nolib/USB_HID/usb_lib.h @@ -71,41 +71,31 @@ #define CONTROL_DTR 0x01 #define CONTROL_RTS 0x02 -// wValue -#define DEVICE_DESCRIPTOR 0x100 -#define CONFIGURATION_DESCRIPTOR 0x200 -#define STRING_LANG_DESCRIPTOR 0x300 -#define STRING_MAN_DESCRIPTOR 0x301 -#define STRING_PROD_DESCRIPTOR 0x302 -#define STRING_SN_DESCRIPTOR 0x303 -#define DEVICE_QUALIFIER_DESCRIPTOR 0x600 +// wValue = DESCR_TYPE<<8 | DESCR_INDEX +#define DEVICE_DESCRIPTOR 0x0100 +#define CONFIGURATION_DESCRIPTOR 0x0200 +#define STRING_LANG_DESCRIPTOR 0x0300 +#define STRING_MAN_DESCRIPTOR 0x0301 +#define STRING_PROD_DESCRIPTOR 0x0302 +#define STRING_SN_DESCRIPTOR 0x0303 +#define DEVICE_QUALIFIER_DESCRIPTOR 0x0600 #define HID_REPORT_DESCRIPTOR 0x2200 -// EPnR bits manipulation -#define CLEAR_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? R : (R & (~USB_EPnR_DTOG_RX)) -#define SET_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? (R & (~USB_EPnR_DTOG_RX)) : R -#define TOGGLE_DTOG_RX(R) (R | USB_EPnR_DTOG_RX) -#define KEEP_DTOG_RX(R) (R & (~USB_EPnR_DTOG_RX)) -#define CLEAR_DTOG_TX(R) (R & USB_EPnR_DTOG_TX) ? R : (R & (~USB_EPnR_DTOG_TX)) -#define SET_DTOG_TX(R) (R & USB_EPnR_DTOG_TX) ? (R & (~USB_EPnR_DTOG_TX)) : R -#define TOGGLE_DTOG_TX(R) (R | USB_EPnR_DTOG_TX) -#define KEEP_DTOG_TX(R) (R & (~USB_EPnR_DTOG_TX)) -#define SET_VALID_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX) | (R & (~USB_EPnR_STAT_RX)) -#define SET_NAK_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX_1) | (R & (~USB_EPnR_STAT_RX)) -#define SET_STALL_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX_0) | (R & (~USB_EPnR_STAT_RX)) -#define KEEP_STAT_RX(R) (R & (~USB_EPnR_STAT_RX)) -#define SET_VALID_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX) | (R & (~USB_EPnR_STAT_TX)) -#define SET_NAK_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX_1) | (R & (~USB_EPnR_STAT_TX)) -#define SET_STALL_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX_0) | (R & (~USB_EPnR_STAT_TX)) -#define KEEP_STAT_TX(R) (R & (~USB_EPnR_STAT_TX)) -#define CLEAR_CTR_RX(R) (R & (~USB_EPnR_CTR_RX)) -#define CLEAR_CTR_TX(R) (R & (~USB_EPnR_CTR_TX)) -#define CLEAR_CTR_RX_TX(R) (R & (~(USB_EPnR_CTR_TX | USB_EPnR_CTR_RX))) +#define RX_FLAG(epstat) (epstat & USB_EPnR_CTR_RX) +#define TX_FLAG(epstat) (epstat & USB_EPnR_CTR_TX) +#define SETUP_FLAG(epstat) (epstat & USB_EPnR_SETUP) + +// keep all DTOGs and STATs +#define KEEP_DTOG_STAT(EPnR) (EPnR & ~(USB_EPnR_STAT_RX|USB_EPnR_STAT_TX|USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX)) +#define KEEP_DTOG(EPnR) (EPnR & ~(USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX)) // USB state: uninitialized, addressed, ready for use -#define USB_DEFAULT_STATE 0 -#define USB_ADRESSED_STATE 1 -#define USB_CONFIGURE_STATE 2 +typedef enum{ + USB_STATE_DEFAULT, + USB_STATE_ADDRESSED, + USB_STATE_CONFIGURED, + USB_STATE_CONNECTED +} USB_state; // EP types #define EP_TYPE_BULK 0x00 @@ -115,7 +105,7 @@ #define LANG_US (uint16_t)0x0409 -#define _USB_STRING_(name, str) \ +#define USB_STRING(name, str) \ static const struct name \ { \ uint8_t bLength; \ @@ -125,7 +115,7 @@ static const struct name \ } \ name = {sizeof(name), 0x03, str} -#define _USB_LANG_ID_(name, lng_id) \ +#define USB_LANG_ID(name, lng_id) \ \ static const struct name \ { \ @@ -151,12 +141,8 @@ typedef struct __ep_t{ uint16_t *tx_buf; // transmission buffer address uint16_t txbufsz; // transmission buffer size uint16_t *rx_buf; // reception buffer address - uint16_t (*func)(); // endpoint action function - uint16_t status; // status flags + void (*func)(); // endpoint action function unsigned rx_cnt : 10; // received data counter - unsigned tx_flag : 1; // transmission flag - unsigned rx_flag : 1; // reception flag - unsigned setup_flag : 1; // this is setup packet (only for EP0) } ep_t; // USB status & its address @@ -165,42 +151,15 @@ typedef struct { uint16_t USB_Addr; }usb_dev_t; -typedef struct { - uint32_t dwDTERate; - uint8_t bCharFormat; - #define USB_CDC_1_STOP_BITS 0 - #define USB_CDC_1_5_STOP_BITS 1 - #define USB_CDC_2_STOP_BITS 2 - uint8_t bParityType; - #define USB_CDC_NO_PARITY 0 - #define USB_CDC_ODD_PARITY 1 - #define USB_CDC_EVEN_PARITY 2 - #define USB_CDC_MARK_PARITY 3 - #define USB_CDC_SPACE_PARITY 4 - uint8_t bDataBits; -} __attribute__ ((packed)) usb_LineCoding; - -typedef struct { - uint8_t bmRequestType; - uint8_t bNotificationType; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} __attribute__ ((packed)) usb_cdc_notification; - extern ep_t endpoints[]; +extern usb_dev_t USB_Dev; +extern uint8_t usbON; void USB_Init(); -uint8_t USB_GetState(); -int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep)); +void USB_ResetState(); +int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)); void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size); void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size); int EP_Read(uint8_t number, uint16_t *buf); -usb_LineCoding getLineCoding(); - -void WEAK linecoding_handler(usb_LineCoding *lc); -void WEAK clstate_handler(uint16_t val); -void WEAK break_handler(); -void WEAK vendor_handler(config_pack_t *packet); #endif // __USB_LIB_H__ diff --git a/F1-nolib/USB_HID/usbhid103.bin b/F1-nolib/USB_HID/usbhid103.bin index 580dfda..eebdad4 100755 Binary files a/F1-nolib/USB_HID/usbhid103.bin and b/F1-nolib/USB_HID/usbhid103.bin differ