From d46a604d6f4a270c9ff239fb0bdb4e8ca079663d Mon Sep 17 00:00:00 2001 From: eddyem Date: Tue, 21 May 2019 11:41:41 +0300 Subject: [PATCH] Working code for STM32F103 PL2303 emulation --- F1-nolib/F1_testbrd/Makefile | 5 +- F1-nolib/F1_testbrd/hardware.c | 4 +- F1-nolib/F1_testbrd/hardware.h | 2 + F1-nolib/F1_testbrd/main.c | 50 ++++++++++++------- F1-nolib/F1_testbrd/pl2303.bin | Bin 3460 -> 6956 bytes F1-nolib/F1_testbrd/usart.c | 40 +++++++++++++-- F1-nolib/F1_testbrd/usart.h | 4 ++ F1-nolib/F1_testbrd/usb.c | 48 +++++++++--------- F1-nolib/F1_testbrd/usb_defs.h | 43 +++++++++++------ F1-nolib/F1_testbrd/usb_lib.c | 86 ++++++++++++++++++++++++--------- F1-nolib/F1_testbrd/usb_lib.h | 8 +-- 11 files changed, 200 insertions(+), 90 deletions(-) diff --git a/F1-nolib/F1_testbrd/Makefile b/F1-nolib/F1_testbrd/Makefile index 6038e57..ec0a80c 100644 --- a/F1-nolib/F1_testbrd/Makefile +++ b/F1-nolib/F1_testbrd/Makefile @@ -42,8 +42,7 @@ DFUUTIL := $(shell which dfu-util) ############################################################################### # Source files OBJDIR = mk -#SRC := $(wildcard *.c) -SRC = adc.c hardware.c main.c usart.c +SRC := $(wildcard *.c) OBJS := $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o)) STARTUP = $(OBJDIR)/startup.o OBJS += $(STARTUP) @@ -70,7 +69,7 @@ LDFLAGS += -T$(LDSCRIPT) ############################################################################### # Used libraries -LDLIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +LDLIBS += -lc $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU) -DSTM32F10X_$(DENSITY) diff --git a/F1-nolib/F1_testbrd/hardware.c b/F1-nolib/F1_testbrd/hardware.c index 6f55196..8be5d07 100644 --- a/F1-nolib/F1_testbrd/hardware.c +++ b/F1-nolib/F1_testbrd/hardware.c @@ -62,9 +62,11 @@ static inline void adc_setup(){ | DMA_CCR_CIRC | DMA_CCR_PL | DMA_CCR_EN; // continuous mode & DMA; enable vref & Tsens; wake up ADC ADC1->CR2 |= ADC_CR2_DMA | ADC_CR2_TSVREFE | ADC_CR2_CONT | ADC_CR2_ADON; + // wait for Tstab - at least 1us + while(++ctr < 0xff) nop(); // calibration ADC1->CR2 |= ADC_CR2_RSTCAL; - while((ADC1->CR2 & ADC_CR2_RSTCAL) && ++ctr < 0xfffff); + ctr = 0; while((ADC1->CR2 & ADC_CR2_RSTCAL) && ++ctr < 0xfffff); ADC1->CR2 |= ADC_CR2_CAL; ctr = 0; while((ADC1->CR2 & ADC_CR2_CAL) && ++ctr < 0xfffff); // turn ON ADC diff --git a/F1-nolib/F1_testbrd/hardware.h b/F1-nolib/F1_testbrd/hardware.h index 627649e..b0d8928 100644 --- a/F1-nolib/F1_testbrd/hardware.h +++ b/F1-nolib/F1_testbrd/hardware.h @@ -41,6 +41,8 @@ // USB pullup (not used in STM32F0x2!) - PA13 #define USBPU_port GPIOA #define USBPU_pin (1<<13) +#define USBPU_ON() pin_clear(USBPU_port, USBPU_pin) +#define USBPU_OFF() pin_set(USBPU_port, USBPU_pin) #define LED_blink(x) pin_toggle(x ## _port, x ## _pin) #define LED_on(x) pin_clear(x ## _port, x ## _pin) diff --git a/F1-nolib/F1_testbrd/main.c b/F1-nolib/F1_testbrd/main.c index 70aa8f5..8615a2a 100644 --- a/F1-nolib/F1_testbrd/main.c +++ b/F1-nolib/F1_testbrd/main.c @@ -24,13 +24,9 @@ #include "usart.h" #include "usb.h" #include "usb_lib.h" -#include // memcpy volatile uint32_t Tms = 0; -#define USB_send(x) do{}while(0) - - /* Called when systick fires */ void sys_tick_handler(void){ ++Tms; @@ -127,30 +123,29 @@ char *parse_cmd(char *buf){ return NULL; } -/* // usb getline char *get_USB(){ - static char tmpbuf[129], *curptr = tmpbuf; - static int rest = 128; + static char tmpbuf[512], *curptr = tmpbuf; + static int rest = 511; int x = USB_receive(curptr, rest); curptr[x] = 0; if(!x) return NULL; - SEND("got: "); - SEND(curptr); - newline(); if(curptr[x-1] == '\n'){ curptr = tmpbuf; - rest = 128; + rest = 511; return tmpbuf; } curptr += x; rest -= x; if(rest <= 0){ // buffer overflow + SEND("USB buffer overflow!\n"); curptr = tmpbuf; - rest = 128; + rest = 511; } return NULL; -}*/ +} + +//int8_t dump = 0; int main(void){ uint32_t lastT = 0, lastB = 0, LEDperiod = 499; sysreset(); @@ -169,26 +164,47 @@ int main(void){ } RCC->CSR |= RCC_CSR_RMVF; // remove reset flags - //USB_setup(); + USBPU_OFF(); + USB_setup(); iwdg_setup(); + USBPU_ON(); while (1){ IWDG->KR = IWDG_REFRESH; // refresh watchdog + /*if(dump){ + SEND("\nin buffer:\n"); + uint16_t buf[32]; + uint32_t *in = (uint32_t *)endpoints[0].rx_buf; + for(int i = 0; i < 32; ++i, ++in) + buf[i] = *(uint16_t*)in; + hexdump((uint8_t*)buf, 64); + SEND("\nout buffer:\n"); + in = (uint32_t *)endpoints[0].tx_buf; + for(int i = 0; i < 32; ++i, ++in) + buf[i] = *(uint16_t*)in; + hexdump((uint8_t*)buf, 64); + SEND("Config:\n"); + hexdump((uint8_t*)&setup_packet, sizeof(setup_packet)); + newline(); + hexdump16((uint16_t*)USB_BTABLE, 64); + newline(); + dump = 0; + }*/ if(lastT > Tms || Tms - lastT > LEDperiod){ LED_blink(LED0); lastT = Tms; transmit_tbuf(); // non-blocking transmission of data from UART buffer every 0.5s } - //usb_proc(); + usb_proc(); int r = 0; char *txt, *ans; - /*if((txt = get_USB())){ + if((txt = get_USB())){ ans = parse_cmd(txt); SEND("Received data over USB:\n"); SEND(txt); newline(); if(ans) USB_send(ans); - }*/ + } if(usartrx()){ // usart1 received data, store in in buffer r = usart_getline(&txt); if(r){ diff --git a/F1-nolib/F1_testbrd/pl2303.bin b/F1-nolib/F1_testbrd/pl2303.bin index 76b111860c6bf7c64496da3fafdde2fde59bd3ad..f9821fa01160b82ac4b691d808af4b590f55854e 100755 GIT binary patch literal 6956 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 -1; --j){ + register uint8_t half = (x >> (4*j+8*i)) & 0x0f; + if(half < 10) usart_putchar(half + '0'); + else usart_putchar(half - 10 + 'a'); + } + } + if(l % 8 == 7) usart_putchar('\n'); + else if(l & 1) usart_putchar(' '); + } +} + +void hexdump32(uint32_t *arr, uint16_t len){ + for(uint16_t l = 0; l < len; ++l, ++arr){ + uint16_t x = (uint16_t)arr[l]; + for(int8_t i = 0; i < 2; ++i){ + for(int16_t j = 1; j > -1; --j){ + register uint8_t half = (x >> (4*j+8*i)) & 0x0f; + if(half < 10) usart_putchar(half + '0'); + else usart_putchar(half - 10 + 'a'); + } + } + if(l % 8 == 7) usart_putchar('\n'); else if(l & 1) usart_putchar(' '); } } diff --git a/F1-nolib/F1_testbrd/usart.h b/F1-nolib/F1_testbrd/usart.h index 70fd3c2..a48b92c 100644 --- a/F1-nolib/F1_testbrd/usart.h +++ b/F1-nolib/F1_testbrd/usart.h @@ -38,8 +38,10 @@ #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) #else #define MSG(str) +#define DBG(str) #endif #define usartrx() (linerdy) @@ -57,5 +59,7 @@ char *u2str(uint32_t val); void printu(uint32_t val); void printuhex(uint32_t val); void hexdump(uint8_t *arr, uint16_t len); +void hexdump16(uint16_t *arr, uint16_t len); +void hexdump32(uint32_t *arr, uint16_t len); #endif // __USART_H__ diff --git a/F1-nolib/F1_testbrd/usb.c b/F1-nolib/F1_testbrd/usb.c index 771c92d..cb3a88e 100644 --- a/F1-nolib/F1_testbrd/usb.c +++ b/F1-nolib/F1_testbrd/usb.c @@ -20,11 +20,9 @@ * MA 02110-1301, USA. * */ - #include "usb.h" #include "usb_lib.h" #include "usart.h" -#include // memcpy, memmove // incoming buffer size #define IDATASZ (256) @@ -37,9 +35,13 @@ static int8_t usbON = 0; // ==1 when USB fully configured // interrupt IN handler (never used?) static uint16_t EP1_Handler(ep_t ep){ if (ep.rx_flag){ +#ifdef EBUG +SEND("EP1OUT: "); printu(ep.rx_cnt); usart_putchar('\n'); +#endif ep.status = SET_VALID_TX(ep.status); ep.status = KEEP_STAT_RX(ep.status); }else if (ep.tx_flag){ +DBG("EP1IN"); ep.status = SET_VALID_RX(ep.status); ep.status = SET_STALL_TX(ep.status); } @@ -52,7 +54,7 @@ static uint16_t EP23_Handler(ep_t ep){ int rd = ep.rx_cnt, rest = IDATASZ - idatalen; if(rd){ if(rd <= rest){ - idatalen += EP_Read(2, &incoming_data[idatalen]); + idatalen += EP_Read(2, (uint16_t*)&incoming_data[idatalen]); ovfl = 0; }else{ ep.status = SET_NAK_RX(ep.status); @@ -73,24 +75,22 @@ static uint16_t EP23_Handler(ep_t ep){ } void USB_setup(){ - RCC->APB1ENR |= RCC_APB1ENR_CRSEN | RCC_APB1ENR_USBEN; // enable CRS (hsi48 sync) & USB - RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB - RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48 - uint32_t tmout = 16000000; - while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;} - FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; - CRS->CFGR &= ~CRS_CFGR_SYNCSRC; - CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source - CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim - CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only - RCC->CFGR |= RCC_CFGR_SW; - // allow RESET and CTRM interrupts - USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM; - // clear flags - USB->ISTR = 0; - // and activate pullup - USB->BCDR |= USB_BCDR_DPPU; - NVIC_EnableIRQ(USB_IRQn); + NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); + RCC->APB1ENR |= RCC_APB1ENR_USBEN; + USB->CNTR = USB_CNTR_FRES; // Force USB Reset + for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms + //uint32_t ctr = 0; + USB->CNTR = 0; + USB->BTABLE = 0; + USB->DADDR = 0; + USB->ISTR = 0; + USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts + /*USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_PMAOVRM | + USB_CNTR_ERRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_SOFM | + USB_CNTR_ESOFM;*/ + NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); + NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn ); } void usb_proc(){ @@ -133,9 +133,11 @@ int USB_receive(char *buf, int bufsize){ if(!bufsize || !idatalen) return 0; USB->CNTR = 0; int sz = (idatalen > bufsize) ? bufsize : idatalen, rest = idatalen - sz; - memcpy(buf, incoming_data, sz); + for(int i = 0; i < sz; ++i) buf[i] = incoming_data[i]; if(rest > 0){ - memmove(incoming_data, &incoming_data[sz], rest); + uint8_t *ptr = &incoming_data[sz]; + for(int i = 0; i < rest; ++i) incoming_data[i] = *ptr++; + //memmove(incoming_data, &incoming_data[sz], rest); - hardfault on memcpy&memmove idatalen = rest; }else idatalen = 0; if(ovfl){ diff --git a/F1-nolib/F1_testbrd/usb_defs.h b/F1-nolib/F1_testbrd/usb_defs.h index d5cc1ce..d6bc03f 100644 --- a/F1-nolib/F1_testbrd/usb_defs.h +++ b/F1-nolib/F1_testbrd/usb_defs.h @@ -27,13 +27,14 @@ #include +// max endpoints number +#define STM32ENDPOINTS 8 /** * Buffers size definition **/ -// !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!! -#define USB_BTABLE_SIZE 1024 +#define USB_BTABLE_SIZE 512 // first 64 bytes of USB_BTABLE are registers! -#define USB_EP0_BASEADDR 64 +//#define USB_EP0_BASEADDR 64 // for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303) #define USB_EP0_BUFSZ 64 // USB transmit buffer size (64 for PL2303) @@ -42,7 +43,12 @@ #define USB_RXBUFSZ 64 #define USB_BTABLE_BASE 0x40006000 +#define USB_BASE ((uint32_t)0x40005C00) +#define USB ((USB_TypeDef *) USB_BASE) + +#ifdef USB_BTABLE #undef USB_BTABLE +#endif #define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE)) #define USB_ISTR_EPID 0x0000000F #define USB_FNR_LSOF_0 0x00000800 @@ -71,36 +77,41 @@ #define USB_COUNTn_NUM_BLOCK 0x00007C00 #define USB_COUNTn_RX 0x0000003F +#ifdef USB_TypeDef #define USB_TypeDef USB_TypeDef_custom +#endif -typedef struct{ - __IO uint32_t EPnR[8]; - __IO uint32_t RESERVED1; - __IO uint32_t RESERVED2; - __IO uint32_t RESERVED3; - __IO uint32_t RESERVED4; - __IO uint32_t RESERVED5; - __IO uint32_t RESERVED6; - __IO uint32_t RESERVED7; - __IO uint32_t RESERVED8; +typedef struct { + __IO uint32_t EPnR[STM32ENDPOINTS]; + __IO uint32_t RESERVED[STM32ENDPOINTS]; __IO uint32_t CNTR; __IO uint32_t ISTR; __IO uint32_t FNR; __IO uint32_t DADDR; __IO uint32_t BTABLE; - __IO uint32_t LPMCSR; - __IO uint32_t BCDR; } USB_TypeDef; +/* typedef struct{ __IO uint16_t USB_ADDR_TX; + __IO uint16_t res1; __IO uint16_t USB_COUNT_TX; + __IO uint16_t res2; __IO uint16_t USB_ADDR_RX; + __IO uint16_t res3; __IO uint16_t USB_COUNT_RX; + __IO uint16_t res4; +} USB_EPDATA_TypeDef;*/ + +typedef struct{ + __IO uint32_t USB_ADDR_TX; + __IO uint32_t USB_COUNT_TX; + __IO uint32_t USB_ADDR_RX; + __IO uint32_t USB_COUNT_RX; } USB_EPDATA_TypeDef; typedef struct{ - __IO USB_EPDATA_TypeDef EP[8]; + __IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS]; } USB_BtableDef; #endif // __USB_DEFS_H__ diff --git a/F1-nolib/F1_testbrd/usb_lib.c b/F1-nolib/F1_testbrd/usb_lib.c index c359cb5..d543269 100644 --- a/F1-nolib/F1_testbrd/usb_lib.c +++ b/F1-nolib/F1_testbrd/usb_lib.c @@ -23,14 +23,13 @@ #include #include "usb_lib.h" -#include // memcpy #include "usart.h" -ep_t endpoints[ENDPOINTS_NUM]; +ep_t endpoints[STM32ENDPOINTS]; static usb_dev_t USB_Dev; static usb_LineCoding lineCoding = {115200, 0, 0, 8}; -static config_pack_t setup_packet; +config_pack_t setup_packet; static uint8_t ep0databuf[EP0DATABUF_SIZE]; static uint8_t ep0dbuflen = 0; @@ -264,7 +263,6 @@ static uint16_t EP0_Handler(ep_t ep){ std_d2h_req(); }else{ std_h2d_req(); - // send ZLP EP_WriteIRQ(0, (uint8_t *)0, 0); } epstatus = SET_NAK_RX(epstatus); @@ -272,7 +270,6 @@ static uint16_t EP0_Handler(ep_t ep){ break; case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request if(setup_packet.bRequest == CLEAR_FEATURE){ - // send ZLP EP_WriteIRQ(0, (uint8_t *)0, 0); epstatus = SET_NAK_RX(epstatus); epstatus = SET_VALID_TX(epstatus); @@ -337,10 +334,9 @@ static uint16_t EP0_Handler(ep_t ep){ return epstatus; } -static uint16_t lastaddr = USB_EP0_BASEADDR; +static uint16_t lastaddr = LASTADDR_DEFAULT; /** * Endpoint initialisation - * !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!! * @param number - EP num (0...7) * @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT) * @param txsz - transmission buffer size @ USB/CAN buffer @@ -349,12 +345,12 @@ static uint16_t lastaddr = USB_EP0_BASEADDR; * @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)){ - if(number >= ENDPOINTS_NUM) return 4; // out of configured amount + 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 USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; - if(rxsz & 1 || rxsz > 992) return 3; // wrong rx buffer size + if(rxsz & 1 || rxsz > 512) return 3; // wrong rx buffer size uint16_t countrx = 0; if(rxsz < 64) countrx = rxsz / 2; else{ @@ -362,18 +358,18 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t countrx = 31 + rxsz / 32; } USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; - endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr); + endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr*2); lastaddr += txsz; USB_BTABLE->EP[number].USB_COUNT_TX = 0; USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; - endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr); + endpoints[number].rx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr*2); lastaddr += rxsz; - // buffer size: Table127 of RM USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; endpoints[number].func = func; return 0; } +//extern int8_t dump; // standard IRQ handler void usb_isr(){ if (USB->ISTR & USB_ISTR_RESET){ @@ -382,8 +378,10 @@ void usb_isr(){ USB->ISTR = 0; // Endpoint 0 - CONTROL // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! - lastaddr = USB_EP0_BASEADDR; // roll back to beginning of buffer - EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler); + 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 @@ -394,6 +392,7 @@ void usb_isr(){ uint8_t n = USB->ISTR & USB_ISTR_EPID; // copy status register uint16_t epstatus = USB->EPnR[n]; + // dump = 1; // Calculate flags endpoints[n].rx_flag = (epstatus & USB_EPnR_CTR_RX) ? 1 : 0; endpoints[n].setup_flag = (epstatus & USB_EPnR_SETUP) ? 1 : 0; @@ -404,12 +403,12 @@ void usb_isr(){ if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) if(n == 0){ // control endpoint if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack - memcpy(&setup_packet, endpoints[0].rx_buf, sizeof(setup_packet)); + EP_Read(0, (uint16_t*)&setup_packet); ep0dbuflen = 0; // interrupt handler will be called later }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf ep0dbuflen = endpoints[0].rx_cnt; - memcpy(ep0databuf, endpoints[0].rx_buf, ep0dbuflen); + EP_Read(0, (uint16_t*)&ep0databuf); } } }else{ // IN interrupt - transmit data, only CTR_TX == 1 @@ -430,6 +429,45 @@ void usb_isr(){ } } +/* + if (USB->ISTR & USB_ISTR_PMAOVR) { + MSG("PMAOVR\n"); + // Handle PMAOVR status + } + if (USB->ISTR & USB_ISTR_SUSP) { + MSG("SUSP\n"); + if (USB->DADDR & 0x7f) { + USB->DADDR = 0; + USB->CNTR &= ~ 0x800; + } + } + if (USB->ISTR & USB_ISTR_ERR) { + MSG("ERR\n"); + // Handle Error + } + if (USB->ISTR & USB_ISTR_WKUP) { + MSG("WKUP\n"); + // Handle Wakeup + } + if (USB->ISTR & USB_ISTR_SOF) { + MSG("SOF\n"); + // Handle SOF + } + if (USB->ISTR & USB_ISTR_ESOF) { + MSG("ESOF\n"); + // Handle ESOF + } + USB->ISTR = 0; +*/ + +void usb_lp_can_rx0_isr(){ + usb_isr(); +} + +void usb_hp_can_tx_isr(){ + usb_isr(); +} + /** * Write data to EP buffer (called from IRQ handler) * @param number - EP number @@ -442,8 +480,9 @@ void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){ 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; - for (i = 0; i < N2; i++){ - endpoints[number].tx_buf[i] = buf16[i]; + uint32_t *out = (uint32_t *)endpoints[number].tx_buf; + for(i = 0; i < N2; ++i, ++out){ + *out = buf16[i]; } USB_BTABLE->EP[number].USB_COUNT_TX = size; } @@ -469,13 +508,14 @@ void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){ * @param *buf - user array for data * @return amount of data read */ -int EP_Read(uint8_t number, uint8_t *buf){ - int n = endpoints[number].rx_cnt; +int EP_Read(uint8_t number, uint16_t *buf){ + int n = (endpoints[number].rx_cnt + 1) >> 1; + uint32_t *in = (uint32_t *)endpoints[number].rx_buf; if(n){ - for(int i = 0; i < n; ++i) - buf[i] = endpoints[number].rx_buf[i]; + for(int i = 0; i < n; ++i, ++in) + buf[i] = *(uint16_t*)in; } - return n; + return endpoints[number].rx_cnt; } // USB status diff --git a/F1-nolib/F1_testbrd/usb_lib.h b/F1-nolib/F1_testbrd/usb_lib.h index 0651e5f..25398c5 100644 --- a/F1-nolib/F1_testbrd/usb_lib.h +++ b/F1-nolib/F1_testbrd/usb_lib.h @@ -29,9 +29,10 @@ #include "usb_defs.h" #define EP0DATABUF_SIZE (64) +#define LASTADDR_DEFAULT (STM32ENDPOINTS * 8) // Max EP amount (EP0 + other used) -#define ENDPOINTS_NUM 4 +//#define ENDPOINTS_NUM 4 // bmRequestType & 0x7f #define STANDARD_DEVICE_REQUEST_TYPE 0 #define STANDARD_ENDPOINT_REQUEST_TYPE 2 @@ -145,7 +146,7 @@ typedef struct { // endpoints state typedef struct __ep_t{ uint16_t *tx_buf; // transmission buffer address - uint8_t *rx_buf; // reception buffer address + uint16_t *rx_buf; // reception buffer address uint16_t (*func)(); // endpoint action function uint16_t status; // status flags unsigned rx_cnt : 10; // received data counter @@ -190,10 +191,9 @@ 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 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, uint8_t *buf); +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();