diff --git a/F0:F030,F042,F072/usbcan_gpio/Makefile b/F0:F030,F042,F072/usbcan_gpio/Makefile index 3607fae..12e87d8 100644 --- a/F0:F030,F042,F072/usbcan_gpio/Makefile +++ b/F0:F030,F042,F072/usbcan_gpio/Makefile @@ -10,3 +10,6 @@ DEFINES := -DUSB2_16 include ../makefile.f0 include ../../makefile.stm32 + +$(OBJDIR)/gpioproto.o: gpioproto.c $(VERSION_FILE) +$(OBJDIR)/canproto.o: canproto.c $(VERSION_FILE) diff --git a/F0:F030,F042,F072/usbcan_gpio/gpioproto.c b/F0:F030,F042,F072/usbcan_gpio/gpioproto.c index afcbda2..b76d98f 100644 --- a/F0:F030,F042,F072/usbcan_gpio/gpioproto.c +++ b/F0:F030,F042,F072/usbcan_gpio/gpioproto.c @@ -104,7 +104,9 @@ static const char *cmd_parser(char *buf){ case 'i': return setiface(buf); default: - return buf-1; // echo wrong data + // echo wrong data with terminating '\n' + SENDn(buf-1); + return NULL; } } // "short" commands @@ -138,8 +140,9 @@ static const char *cmd_parser(char *buf){ void GPIO_process(){ char inbuff[MAXSTRLEN]; int l = RECV(inbuff, MAXSTRLEN); + if(l == 0) return; if(l < 0) SEND("ERROR: USB buffer overflow or string was too long\n"); - else if(l){ + else{ const char *ans = cmd_parser(inbuff); if(ans) SEND(ans); } diff --git a/F0:F030,F042,F072/usbcan_gpio/ringbuffer.c b/F0:F030,F042,F072/usbcan_gpio/ringbuffer.c index 24c8b61..389c9e7 100644 --- a/F0:F030,F042,F072/usbcan_gpio/ringbuffer.c +++ b/F0:F030,F042,F072/usbcan_gpio/ringbuffer.c @@ -19,6 +19,8 @@ #include #include "ringbuffer.h" +#define CHK(b) do{if(!b) return -1;}while(0) + static int datalen(ringbuffer *b){ if(b->tail >= b->head) return (b->tail - b->head); else return (b->length - b->head + b->tail); @@ -26,7 +28,9 @@ static int datalen(ringbuffer *b){ // stored data length int RB_datalen(ringbuffer *b){ - if(!b || b->busy) return -1; + CHK(b); + if(0 == datalen(b)) return 0; // don't block for empty RO operations + if(b->busy) return -1; b->busy = 1; int l = datalen(b); b->busy = 0; @@ -34,7 +38,7 @@ int RB_datalen(ringbuffer *b){ } static int hasbyte(ringbuffer *b, uint8_t byte){ - if(!b || b->head == b->tail) return -1; // no data in buffer + if(b->head == b->tail) return -1; // no data in buffer int startidx = b->head; if(b->head > b->tail){ // for(int found = b->head; found < b->length; ++found) @@ -53,7 +57,8 @@ static int hasbyte(ringbuffer *b, uint8_t byte){ * @return index if found, -1 if none or busy */ int RB_hasbyte(ringbuffer *b, uint8_t byte){ - if(!b || b->busy) return -1; + CHK(b); + if(b->busy) return -1; b->busy = 1; int ret = hasbyte(b, byte); b->busy = 0; @@ -91,7 +96,10 @@ static int read(ringbuffer *b, uint8_t *s, int len){ * @return bytes read or -1 if busy */ int RB_read(ringbuffer *b, uint8_t *s, int len){ - if(!b || b->busy || !s || len < 1) return -1; + CHK(b); + if(!s || len < 1) return -1; + if(0 == datalen(b)) return 0; + if(b->busy) return -1; b->busy = 1; int r = read(b, s, len); b->busy = 0; @@ -124,7 +132,10 @@ static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ * @return amount of bytes written (negative, if lenbusy) return -1; + CHK(b); + if(!s || len < 1) return -1; + if(0 == datalen(b)) return 0; + if(b->busy) return -1; b->busy = 1; int n = 0; if(s && len > 0){ @@ -137,7 +148,9 @@ int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ } int RB_datalento(ringbuffer *b, uint8_t byte){ - if(!b || b->busy) return -1; + CHK(b); + if(0 == datalen(b)) return 0; + if(b->busy) return -1; b->busy = 1; int n = lento(b, byte); b->busy = 0; @@ -167,7 +180,10 @@ static int write(ringbuffer *b, const uint8_t *str, int l){ * @return amount of bytes written or -1 if busy */ int RB_write(ringbuffer *b, const uint8_t *str, int l){ - if(!b || b->busy || !str || l < 1) return -1; + CHK(b); + if(!str || l < 1) return -1; + if(b->length - datalen(b) < 2) return 0; + if(b->busy) return -1; b->busy = 1; int w = write(b, str, l); b->busy = 0; @@ -176,10 +192,12 @@ int RB_write(ringbuffer *b, const uint8_t *str, int l){ // just delete all information in buffer `b` int RB_clearbuf(ringbuffer *b){ - if(!b || b->busy) return -1; + CHK(b); + if(b->busy) return -1; b->busy = 1; b->head = 0; b->tail = 0; + bzero(b->data, b->length); b->busy = 0; return 1; } diff --git a/F0:F030,F042,F072/usbcan_gpio/usb_dev.c b/F0:F030,F042,F072/usbcan_gpio/usb_dev.c index 249db9f..6d015cf 100644 --- a/F0:F030,F042,F072/usbcan_gpio/usb_dev.c +++ b/F0:F030,F042,F072/usbcan_gpio/usb_dev.c @@ -119,13 +119,15 @@ static void rxtx_handler(){ } } -// clear IN/OUT buffers on connection -static void clearbufs(uint8_t ifno){ +static void clearRbuf(uint8_t ifno){ uint32_t T0 = Tms; while(Tms - T0 < 10){ // wait no more than 10ms if(1 == RB_clearbuf((ringbuffer*)&rbin[ifno])) break; } - T0 = Tms; +} + +static void clearTbuf(uint8_t ifno){ + uint32_t T0 = Tms; while(Tms - T0 < 10){ if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break; } @@ -144,7 +146,8 @@ void clstate_handler(uint8_t ifno, uint16_t val){ CDCready[ifno] = val; // CONTROL_DTR | CONTROL_RTS -> interface connected; 0 -> disconnected lastdsz[ifno] = -1; if(val){ - clearbufs(ifno); + clearRbuf(ifno); + clearTbuf(ifno); EP_reset(EPNO(ifno)); // usart_start(ifno); }//else usart_stop(ifno); // turn of USART (if it is @ this interface) @@ -306,7 +309,7 @@ int USB_receive(uint8_t ifno, uint8_t *buf, int len){ if(!CDCready[ifno]) return 0; chkin(ifno); // rxtx_handler could leave last message unwritten if buffer was busy if(bufovrfl[ifno]){ - while(1 != RB_clearbuf((ringbuffer*)&rbin[ifno])); // run watchdog in case of problems + clearRbuf(ifno); bufovrfl[ifno] = 0; return -1; } @@ -325,7 +328,7 @@ int USB_receivestr(uint8_t ifno, char *buf, int len){ if(!CDCready[ifno]) return 0; chkin(ifno); // rxtx_handler could leave last message unwritten if buffer was busy if(bufovrfl[ifno]){ - while(1 != RB_clearbuf((ringbuffer*)&rbin[ifno])); + clearRbuf(ifno); bufovrfl[ifno] = 0; return -1; } @@ -333,7 +336,7 @@ int USB_receivestr(uint8_t ifno, char *buf, int len){ if(l < 1){ if((rbin[ifno].length <= RB_datalen((ringbuffer*)&rbin[ifno]) + 1) || (RB_datalento((ringbuffer*)&rbin[ifno], '\n') > len - 1)){ // buffer is full but no '\n' found or string too long - while(1 != RB_clearbuf((ringbuffer*)&rbin[ifno])); + clearRbuf(ifno); return -1; } return 0; diff --git a/F0:F030,F042,F072/usbcan_gpio/usb_lib.c b/F0:F030,F042,F072/usbcan_gpio/usb_lib.c index 3bdfd8c..8ed4e0e 100644 --- a/F0:F030,F042,F072/usbcan_gpio/usb_lib.c +++ b/F0:F030,F042,F072/usbcan_gpio/usb_lib.c @@ -301,10 +301,14 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*f } // refresh EP after interface reconnected -void EP_reset(uint8_t number){ - if(number >= STM32ENDPOINTS) return; - USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX; - USB_BTABLE->EP[number].USB_COUNT_TX = 0; +void EP_reset(uint8_t epno){ + if(epno >= STM32ENDPOINTS) return; + // keep DTOGs (don't write 1 to them), clear CTR (write 0 to them) + // and set STAT to VALID (write 1 where was 0) + uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]); + USB->EPnR[epno] = (epstatus & ~(USB_EPnR_CTR_TX|USB_EPnR_CTR_RX)) ^ + (USB_EPnR_STAT_RX | USB_EPnR_STAT_TX); + USB_BTABLE->EP[epno].USB_COUNT_TX = 0; } // standard IRQ handler diff --git a/F0:F030,F042,F072/usbcan_gpio/usb_lib.h b/F0:F030,F042,F072/usbcan_gpio/usb_lib.h index 18ede16..1dfb3a8 100644 --- a/F0:F030,F042,F072/usbcan_gpio/usb_lib.h +++ b/F0:F030,F042,F072/usbcan_gpio/usb_lib.h @@ -345,7 +345,7 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*f 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); -void EP_reset(uint8_t number); +void EP_reset(uint8_t epno); // could be [re]defined in usb_dev.c extern void usb_class_request(config_pack_t *packet, uint8_t *data, uint16_t datalen); diff --git a/F0:F030,F042,F072/usbcan_gpio/usbcangpio.bin b/F0:F030,F042,F072/usbcan_gpio/usbcangpio.bin index 8716eef..1a75ca5 100755 Binary files a/F0:F030,F042,F072/usbcan_gpio/usbcangpio.bin and b/F0:F030,F042,F072/usbcan_gpio/usbcangpio.bin differ diff --git a/F0:F030,F042,F072/usbcan_gpio/version.inc b/F0:F030,F042,F072/usbcan_gpio/version.inc index b49f3d3..789476e 100644 --- a/F0:F030,F042,F072/usbcan_gpio/version.inc +++ b/F0:F030,F042,F072/usbcan_gpio/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "81" +#define BUILD_NUMBER "85" #define BUILD_DATE "2026-03-07" diff --git a/F3:F303/InterfaceBoard/TODO b/F3:F303/InterfaceBoard/TODO new file mode 100644 index 0000000..8fdc6eb --- /dev/null +++ b/F3:F303/InterfaceBoard/TODO @@ -0,0 +1 @@ +add fixes to ringbuffer and make EP_reset @ each reconnection (like in F0/usbcan_gpio).