diff --git a/F3:F303/Seven_CDCs/cmdproto.c b/F3:F303/Seven_CDCs/cmdproto.c index 72387cc..cf607fe 100644 --- a/F3:F303/Seven_CDCs/cmdproto.c +++ b/F3:F303/Seven_CDCs/cmdproto.c @@ -20,16 +20,17 @@ #include "debug.h" #include "strfunc.h" #include "usb.h" +#include "usb_lib.h" // USBON #include "version.inc" #define SEND(str) do{USB_sendstr(CMD_IDX, str);}while(0) #define SENDN(str) do{USB_sendstr(CMD_IDX, str); USB_putbyte(CMD_IDX, '\n');}while(0) extern volatile uint32_t Tms; -extern uint8_t usbON; const char* helpmsg = "https://github.com/eddyem/stm32samples/tree/master/F3:F303/PL2303 build#" BUILD_NUMBER " @ " BUILD_DATE "\n" + "2..7 - send next string to given EP\n" "'i' - print USB->ISTR state\n" "'N' - read number (dec, 0xhex, 0oct, bbin) and show it in decimal\n" "'R' - software reset\n" @@ -53,8 +54,7 @@ void parse_cmd(const char *buf){ break; case 'U': SEND("USB status: "); - if(usbON) SENDN("ON"); - else SENDN("OFF"); + SENDN(uhex2str(usbON)); break; case 'W': SENDN("Wait for reboot"); @@ -68,9 +68,20 @@ void parse_cmd(const char *buf){ } uint32_t Num = 0; const char *nxt; - switch(*buf){ // long messages + char cmd = *buf++; + if(cmd > '0'+CMD_EPNO && cmd <= '0'+DBG_EPNO){ // send data to iface + cmd -= '1'; + if(USBON(cmd)){ + SENDN("OK"); + USB_sendstr(cmd, buf); + USB_putbyte(cmd, '\n'); + }else{ + SENDN("Not connected"); + } + return; + } + switch(cmd){ // long messages case 'N': - ++buf; nxt = getnum(buf, &Num); if(buf == nxt){ if(Num == 0) SENDN("Wrong number"); @@ -84,7 +95,7 @@ void parse_cmd(const char *buf){ }else SEND("\n"); break; default: - SEND(buf); + SEND(buf-1); // echo return; } } diff --git a/F3:F303/Seven_CDCs/main.c b/F3:F303/Seven_CDCs/main.c index 3cf3ff1..9de99b7 100644 --- a/F3:F303/Seven_CDCs/main.c +++ b/F3:F303/Seven_CDCs/main.c @@ -19,6 +19,7 @@ #include "cmdproto.h" #include "debug.h" #include "hardware.h" +#include "strfunc.h" #include "usart.h" #include "usb.h" @@ -30,6 +31,9 @@ void sys_tick_handler(void){ ++Tms; } +static const char *ebufovr = "ERROR: USB buffer overflow or string was too long\n"; +static const char *idxnames[MAX_IDX] = {"CMD", "USART1", "USART2", "USART3", "NOFUNCT", "CAN", "DBG"}; + int main(void){ char inbuff[MAXSTRLEN+1]; USBPU_OFF(); @@ -49,14 +53,32 @@ int main(void){ if(Tms - ctr > 499){ ctr = Tms; pin_toggle(GPIOB, 1 << 1 | 1 << 0); // toggle LED @ PB0 - //DBG("blink\n"); + //DBGmesg(u2str(Tms)); + //DBGnl(); } - int l = USB_receivestr(CMD_IDX, inbuff, MAXSTRLEN); - if(l < 0) USB_sendstr(CMD_IDX, "ERROR: USB buffer overflow or string was too long\n"); - else if(l){ - parse_cmd(inbuff); + for(int i = 0; i < MAX_IDX; ++i){ + int l = USB_receivestr(i, inbuff, MAXSTRLEN); + if(l < 0){ + USB_sendstr(DBG_IDX, ebufovr); + if(i == CMD_IDX) USB_sendstr(CMD_IDX, ebufovr); + continue; + } + if(l == 0) continue; + USB_sendstr(DBG_IDX, idxnames[i]); + USB_sendstr(DBG_IDX, "> "); + USB_sendstr(DBG_IDX, inbuff); + USB_putbyte(DBG_IDX, '\n'); + USB_sendstr(CMD_IDX, idxnames[i]); + USB_sendstr(CMD_IDX, "> "); + USB_sendstr(CMD_IDX, inbuff); + USB_putbyte(CMD_IDX, '\n'); + switch(i){ + case CMD_IDX: + parse_cmd(inbuff); + break; + default: + break; + } } - l = USB_receivestr(DBG_IDX, inbuff, MAXSTRLEN); - if(l) USB_sendstr(DBG_IDX, inbuff); // just echo back all from USB-DBG interface } } diff --git a/F3:F303/Seven_CDCs/sevenCDCs.bin b/F3:F303/Seven_CDCs/sevenCDCs.bin index 202f361..a3b872e 100755 Binary files a/F3:F303/Seven_CDCs/sevenCDCs.bin and b/F3:F303/Seven_CDCs/sevenCDCs.bin differ diff --git a/F3:F303/Seven_CDCs/strfunc.c b/F3:F303/Seven_CDCs/strfunc.c index d599669..69f10ea 100644 --- a/F3:F303/Seven_CDCs/strfunc.c +++ b/F3:F303/Seven_CDCs/strfunc.c @@ -19,13 +19,14 @@ #include #include #include +#include "usb.h" /** * @brief hexdump - dump hex array by 16 bytes in string - * @param sendfun - function to send data + * @param ifno - USB interface number * @param arr - array to dump * @param len - length of `arr` */ -void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len){ +void hexdump(int ifno, uint8_t *arr, uint16_t len){ char buf[52], *bptr = buf; for(uint16_t l = 0; l < len; ++l, ++arr){ for(int16_t j = 1; j > -1; --j){ @@ -36,14 +37,14 @@ void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len){ if(l % 16 == 15){ *bptr++ = '\n'; *bptr = 0; - sendfun(buf); + USB_sendstr(ifno, buf); bptr = buf; }else *bptr++ = ' '; } if(bptr != buf){ *bptr++ = '\n'; *bptr = 0; - sendfun(buf); + USB_sendstr(ifno, buf); } } diff --git a/F3:F303/Seven_CDCs/strfunc.h b/F3:F303/Seven_CDCs/strfunc.h index a63ac4b..fc61644 100644 --- a/F3:F303/Seven_CDCs/strfunc.h +++ b/F3:F303/Seven_CDCs/strfunc.h @@ -21,7 +21,7 @@ #include #include -void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len); +void hexdump(int ifno, uint8_t *arr, uint16_t len); const char *u2str(uint32_t val); const char *i2str(int32_t i); const char *uhex2str(uint32_t val); diff --git a/F3:F303/Seven_CDCs/usb.c b/F3:F303/Seven_CDCs/usb.c index 04edb91..b0feeb7 100644 --- a/F3:F303/Seven_CDCs/usb.c +++ b/F3:F303/Seven_CDCs/usb.c @@ -36,33 +36,38 @@ volatile uint8_t bufovrfl[WORK_EPs] = {0}; // here and later: ifNo is index of buffers, i.e. ifNo = epno-1 !!! void send_next(int ifNo){ if(bufisempty[ifNo]) return; - static int lastdsz = 0; + static uint8_t lastdsz[WORK_EPs] = {0}; int buflen = RB_read((ringbuffer*)&rbout[ifNo], (uint8_t*)usbbuff, USB_TRBUFSZ); if(!buflen){ - if(lastdsz == 64) EP_Write(ifNo+1, NULL, 0); // send ZLP after 64 bits packet when nothing more to send - lastdsz = 0; + if(lastdsz[ifNo] == 64) EP_Write(ifNo+1, NULL, 0); // send ZLP after 64 bits packet when nothing more to send + lastdsz[ifNo] = 0; bufisempty[ifNo] = 1; return; } EP_Write(ifNo+1, (uint8_t*)usbbuff, buflen); - lastdsz = buflen; + lastdsz[ifNo] = buflen; } // blocking send full content of ring buffer int USB_sendall(int ifNo){ while(!bufisempty[ifNo]){ - if(!usbON) return 0; + if(!USBON(ifNo)) return 0; } return 1; } // put `buf` into queue to send int USB_send(int ifNo, const uint8_t *buf, int len){ - if(!buf || !usbON || !len) return 0; + if(!buf || !USBON(ifNo) || !len) return 0; uint32_t T = Tms; while(len){ int a = RB_write((ringbuffer*)&rbout[ifNo], buf, len); - if(a == 0 && Tms - T > 5) return 0; // timeout + if(a == 0 && Tms - T > 5){ + usbON &= ~(1< USARTMAX_EPNO) return; - usart_config(ifNo + 1 - USART1_EPNO, lc); -} - -// SET_CONTROL_LINE_STATE -static void clstate_handler(int __attribute__((unused)) ifNo, uint16_t __attribute__((unused)) val){ -} - -// SEND_BREAK -static void break_handler(int __attribute__((unused)) ifNo){ -} - 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){ @@ -772,17 +754,20 @@ static void rxtx_Handler(uint8_t epno){ uint8_t buf[USB_TRBUFSZ]; int idx = epno - 1; uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]); - DBGmesg("RxTx="); DBGmesg(u2str(epno)); - DBGmesg(", epst="); DBGmesg(u2str(epstatus)); DBGnl(); + //uint16_t epstatus = USB->EPnR[epno]; if(RX_FLAG(epstatus)){ + epstatus = (epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_CTR_RX)) ^ USB_EPnR_STAT_RX; // keep stat Tx & set valid RX, clear CTR Rx + USB->EPnR[epno] = epstatus; + //USB->EPnR[epno] = (KEEP_DTOG(epstatus) & ~USB_EPnR_CTR_RX) ^ USB_EPnR_STAT_RX; uint8_t sz = EP_Read(epno, (uint8_t*)buf); if(sz){ if(RB_write((ringbuffer*)&rbin[idx], buf, sz) != sz) bufovrfl[idx] = 1; } - epstatus = (epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_CTR_RX)) ^ USB_EPnR_STAT_RX; // keep stat Tx & set valid RX, clear CTR Rx - USB->EPnR[epno] = epstatus; + // set ACK Rx + USB->EPnR[epno] = (KEEP_DTOG(USB->EPnR[epno]) & ~(USB_EPnR_STAT_TX)) ^ USB_EPnR_STAT_RX; }else{ - USB->EPnR[epno] = (epstatus & ~(USB_EPnR_CTR_TX)); // clear TX ctr + USB->EPnR[epno] = (epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_CTR_TX)) ^ USB_EPnR_STAT_RX; // clear TX ctr + //USB->EPnR[epno] = (KEEP_DTOG_STAT(epstatus) & ~(USB_EPnR_CTR_TX)); // clear TX ctr send_next(idx); } } @@ -799,7 +784,6 @@ static inline void std_h2d_req(){ for(uint8_t i = 1; i <= WORK_EPs; ++i){ EP_Init(i, EP_TYPE_BULK, USB_TRBUFSZ, USB_TRBUFSZ, rxtx_Handler); } - usbON = 1; break; default: break; @@ -823,6 +807,8 @@ void EP0_Handler(uint8_t __attribute__((unused)) epno){ usb_LineCoding *lc; // calculate iFno (EP number minus 1) by setup_packet->wIndex (bInterfaceNumber): iFno = wIndex >> 1 int iFno = setup_packet->wIndex >> 1; + DBGmesg(uhex2str(epstatus)); + DBGmesg(" - "); hexdump(DBG_IDX, (uint8_t*)setup_packet, sizeof(config_pack_t)); if(rxflag && SETUP_FLAG(epstatus)){ switch(reqtype){ case STANDARD_DEVICE_REQUEST_TYPE: // standard device request @@ -841,22 +827,24 @@ void EP0_Handler(uint8_t __attribute__((unused)) epno){ case CONTROL_REQUEST_TYPE: switch(setup_packet->bRequest){ case GET_LINE_CODING: - DBG("GET_LINE_CODING from"); DBGmesg(u2str(iFno)); DBGnl(); + DBG("GLC"); lc = getLineCoding(iFno); if(!lc) EP_WriteIRQ(0, (uint8_t *)0, 0); else EP_WriteIRQ(0, (uint8_t*)&lc, sizeof(usb_LineCoding)); break; case SET_LINE_CODING: // omit this for next stage, when data will come + DBG("SLC"); break; case SET_CONTROL_LINE_STATE: - DBG("SET_CONTROL_LINE_STATE from"); DBGmesg(u2str(iFno)); DBGnl(); - clstate_handler(iFno, setup_packet->wValue); + DBG("SCLS"); + usbON |= 1 << iFno; // now this interface is connected break; case SEND_BREAK: - DBG("SEND_BREAK from"); DBGmesg(u2str(iFno)); DBGnl(); - break_handler(iFno); + DBG("B"); + usbON &= ~(1<bRequest != GET_LINE_CODING) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement @@ -867,15 +855,13 @@ void EP0_Handler(uint8_t __attribute__((unused)) epno){ }else if(rxflag){ // got data over EP0 or host acknowlegement if(endpoints[0].rx_cnt){ if(setup_packet->bRequest == SET_LINE_CODING){ - DBG("SET_LINE_CODING from"); DBGmesg(u2str(iFno)); DBGnl(); - linecoding_handler(iFno, (usb_LineCoding*)ep0databuf); + usart_config(iFno + 1 - USART1_EPNO, (usb_LineCoding*)ep0databuf); } } } else if(TX_FLAG(epstatus)){ // package transmitted // now we can change address after enumeration if ((USB->DADDR & USB_DADDR_ADD) != USB_Addr){ USB->DADDR = USB_DADDR_EF | USB_Addr; - usbON = 0; } } epstatus = KEEP_DTOG(USB->EPnR[0]); diff --git a/F3:F303/Seven_CDCs/usb_lib.h b/F3:F303/Seven_CDCs/usb_lib.h index e0cd1c2..993e6dc 100644 --- a/F3:F303/Seven_CDCs/usb_lib.h +++ b/F3:F303/Seven_CDCs/usb_lib.h @@ -153,6 +153,8 @@ typedef struct { } __attribute__ ((packed)) usb_LineCoding; extern ep_t endpoints[]; +// device disconnected from terminal (BIT flags!!!) +#define USBON(ifno) (usbON & (1<ISTR & USB_ISTR_RESET){ usbON = 0; // Reinit registers @@ -111,6 +112,7 @@ void usb_lp_isr(){ if(endpoints[n].func) endpoints[n].func(n); } if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep + oldusbon = usbON; usbON = 0; USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE; USB->ISTR = ~USB_ISTR_SUSP; @@ -118,7 +120,7 @@ void usb_lp_isr(){ if(USB->ISTR & USB_ISTR_WKUP){ // wakeup USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags USB->ISTR = ~USB_ISTR_WKUP; - usbON = 1; + usbON = oldusbon; } } diff --git a/F3:F303/Seven_CDCs/version.inc b/F3:F303/Seven_CDCs/version.inc index 70e8760..6a70e07 100644 --- a/F3:F303/Seven_CDCs/version.inc +++ b/F3:F303/Seven_CDCs/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "56" -#define BUILD_DATE "2023-04-23" +#define BUILD_NUMBER "77" +#define BUILD_DATE "2023-04-26"