diff --git a/F1:F103/BISS_C_encoders/encoders.bin b/F1:F103/BISS_C_encoders/encoders.bin index 758d54c..efe98a1 100755 Binary files a/F1:F103/BISS_C_encoders/encoders.bin and b/F1:F103/BISS_C_encoders/encoders.bin differ diff --git a/F1:F103/BISS_C_encoders/encoders.creator.user b/F1:F103/BISS_C_encoders/encoders.creator.user index 3ddf322..32c15f4 100644 --- a/F1:F103/BISS_C_encoders/encoders.creator.user +++ b/F1:F103/BISS_C_encoders/encoders.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/F1:F103/BISS_C_encoders/flash.c b/F1:F103/BISS_C_encoders/flash.c index 8e8f9e4..da1feb3 100644 --- a/F1:F103/BISS_C_encoders/flash.c +++ b/F1:F103/BISS_C_encoders/flash.c @@ -23,7 +23,9 @@ #include "usb_dev.h" // printout #include // memcpy -extern const uint32_t __varsstart, _BLOCKSIZE; +extern const uint32_t _BLOCKSIZE; +extern const user_conf __varsstart; + static const uint32_t FLASH_blocksize = (uint32_t)&_BLOCKSIZE; static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here diff --git a/F1:F103/BISS_C_encoders/main.c b/F1:F103/BISS_C_encoders/main.c index 2cbf7d5..5a3f87a 100644 --- a/F1:F103/BISS_C_encoders/main.c +++ b/F1:F103/BISS_C_encoders/main.c @@ -111,7 +111,13 @@ static void proc_enc(uint8_t idx){ USB_sendstr(iface, str); USB_putbyte(iface, '\n'); } - if(result.error) spi_setup(1+idx); // reinit SPI in case of error + if(result.error){ + spi_setup(1+idx); // reinit SPI in case of error + if(CDCready[I_CMD] && the_conf.flags.debug){ + CMDWR("Err, restart SPI "); USB_putbyte(I_CMD, '1'+idx); CMDn(); + } + spi_start_enc(idx); // restart measurement + } if(the_conf.flags.monit) monitT[idx] = Tms; else if(testflag) spi_start_enc(idx); } @@ -142,7 +148,7 @@ int main(){ else if(l) parse_cmd(inbuff); // check if interface connected/disconnected // (we CAN'T do much debug output in interrupt functions like linecoding_handler etc, so do it here) - for(int i = 0; i < bTotNumEndpoints; ++i){ + for(int i = 1; i < bTotNumEndpoints; ++i){ if(oldCDCready[i] != CDCready[i]){ CMDWR("Interface "); CMDWR(u2str(i)); diff --git a/F1:F103/BISS_C_encoders/spi.c b/F1:F103/BISS_C_encoders/spi.c index 0a5ba10..483e79d 100644 --- a/F1:F103/BISS_C_encoders/spi.c +++ b/F1:F103/BISS_C_encoders/spi.c @@ -127,6 +127,7 @@ uint8_t *spi_read_enc(uint8_t encno){ // @return FALSE if SPI is busy // here `encodernum` is 0 (SPI1) or 1 (SPI2), not 1/2 as SPI index! int spi_start_enc(int encodernum){ + // CMDWR("startenc: "); USB_putbyte(I_CMD, '0'+encodernum); newline(I_CMD); int spiidx = encodernum + 1; if(spiidx < 1 || spiidx > AMOUNT_OF_SPI) return FALSE; if(spi_status[spiidx] != SPI_READY) return FALSE; diff --git a/F1:F103/BISS_C_encoders/usb_dev.c b/F1:F103/BISS_C_encoders/usb_dev.c index feee2f4..b61aea8 100644 --- a/F1:F103/BISS_C_encoders/usb_dev.c +++ b/F1:F103/BISS_C_encoders/usb_dev.c @@ -69,14 +69,21 @@ static volatile ringbuffer rbin[bTotNumEndpoints] = {IBUF(0), IBUF(1), IBUF(2)}; static volatile int lastdsz[bTotNumEndpoints] = {-1, -1, -1}; static void chkin(uint8_t ifno){ + static int ovrflctr = 0; // "antistall" counter if(bufovrfl[ifno]) return; // allow user to know that previous buffer was overflowed and cleared if(!rcvbuflen[ifno]) return; int w = RB_write((ringbuffer*)&rbin[ifno], (uint8_t*)rcvbuf[ifno], rcvbuflen[ifno]); - if(w < 0){ - DBG("Can't write into buffer"); + if(w < 0){ // buffer busy + DBG("Can't write into buffer: busy"); return; + }else if(w == 0){ // no enough space or (WTF) incoming string larger than buffer size + if(rcvbuflen[ifno] > rbin[ifno].length || ++ovrflctr > 9999){ + bufovrfl[ifno] = 1; // real overflow in case if ringbuffer's size less than USB buffer + ovrflctr = 0; + }else{ + return; // not enough space + } } - if(w != rcvbuflen[ifno]) bufovrfl[ifno] = 1; DBG("Put data into buffer"); rcvbuflen[ifno] = 0; uint16_t status = KEEP_DTOG(USB->EPnR[1+ifno]); // don't change DTOG @@ -111,14 +118,14 @@ static void send_next(uint8_t ifno){ // data IN/OUT handler static void rxtx_handler(){ - uint8_t ifno = (USB->ISTR & USB_ISTR_EPID) - 1; + uint8_t epno = (USB->ISTR & USB_ISTR_EPID), ifno = epno - 1; DBG("rxtx_handler"); DBGs(uhex2str(ifno)); - if(ifno > bTotNumEndpoints-1){ + if(epno > bTotNumEndpoints){ DBG("wrong ifno"); return; } - uint16_t epstatus = KEEP_DTOG(USB->EPnR[1+ifno]); + uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]); if(RX_FLAG(epstatus)){ // receive data DBG("Got data"); if(rcvbuflen[ifno]){ @@ -126,13 +133,13 @@ static void rxtx_handler(){ rcvbuflen[ifno] = 0; DBG("OVERFULL"); } - rcvbuflen[ifno] = EP_Read(1+ifno, (uint8_t*)rcvbuf[ifno]); + rcvbuflen[ifno] = EP_Read(epno, (uint8_t*)rcvbuf[ifno]); DBGs(uhex2str(rcvbuflen[ifno])); - USB->EPnR[1+ifno] = epstatus & ~(USB_EPnR_CTR_RX | USB_EPnR_STAT_RX | USB_EPnR_STAT_TX); // keep RX in STALL state until read data + USB->EPnR[epno] = epstatus & ~(USB_EPnR_CTR_RX | USB_EPnR_STAT_RX | USB_EPnR_STAT_TX); // keep RX in STALL state until read data chkin(ifno); // try to write current data into RXbuf if it's not busy }else{ // tx successfull DBG("Tx OK"); - USB->EPnR[1+ifno] = (epstatus & ~(USB_EPnR_CTR_TX | USB_EPnR_STAT_TX)) ^ USB_EPnR_STAT_RX; + USB->EPnR[epno] = (epstatus & ~(USB_EPnR_CTR_TX | USB_EPnR_STAT_TX)) ^ USB_EPnR_STAT_RX; send_next(ifno); } } @@ -154,6 +161,7 @@ static void clearbufs(uint8_t ifno){ while(Tms - T0 < 10){ if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break; } + rcvbuflen[ifno] = 0; } // SET_CONTROL_LINE_STATE @@ -161,9 +169,9 @@ void WEAK clstate_handler(uint8_t ifno, uint16_t val){ DBG("clstate_handler"); DBGs(uhex2str(ifno)); DBGs(uhex2str(val)); + if(val) clearbufs(ifno); // clear buffers on connect CDCready[ifno] = val; // CONTROL_DTR | CONTROL_RTS -> interface connected; 0 -> disconnected lastdsz[ifno] = -1; - if(val) clearbufs(ifno); } // SEND_BREAK - disconnect interface and clear its buffers @@ -173,7 +181,6 @@ void WEAK break_handler(uint8_t ifno){ DBGs(uhex2str(ifno)); } - // USB is configured: setup endpoints void set_configuration(){ DBG("set_configuration()"); @@ -262,7 +269,15 @@ int USB_send(uint8_t ifno, const uint8_t *buf, int len){ } if(!CDCready[ifno]) return FALSE; IWDG->KR = IWDG_REFRESH; - int a = RB_write((ringbuffer*)&rbout[ifno], buf, len); + int l = RB_datalen((ringbuffer*)&rbout[ifno]); + if(l < 0) continue; + int portion = rbout[ifno].length - 1 - l; + if(portion < 1){ + if(lastdsz[ifno] < 0) send_next(ifno); + continue; + } + if(portion > len) portion = len; + int a = RB_write((ringbuffer*)&rbout[ifno], buf, portion); if(a > 0){ len -= a; buf += a; @@ -338,7 +353,9 @@ int USB_receivestr(uint8_t ifno, char *buf, int len){ } int l = RB_readto((ringbuffer*)&rbin[ifno], '\n', (uint8_t*)buf, len); if(l < 1){ - if(rbin[ifno].length == RB_datalen((ringbuffer*)&rbin[ifno])){ // buffer is full but no '\n' found + //if(rbin[ifno].length < 1 + RB_datalen((ringbuffer*)&rbin[ifno])){ // buffer is full but no '\n' found + if(RB_datalen((ringbuffer*)&rbin[ifno]) >= len){ + CMDWRn("OVERFULL!"); while(1 != RB_clearbuf((ringbuffer*)&rbin[ifno])); return -1; } diff --git a/F1:F103/BISS_C_encoders/usb_dev.h b/F1:F103/BISS_C_encoders/usb_dev.h index 5641e20..7308630 100644 --- a/F1:F103/BISS_C_encoders/usb_dev.h +++ b/F1:F103/BISS_C_encoders/usb_dev.h @@ -47,7 +47,7 @@ void clstate_handler(uint8_t ifno, uint16_t val); void linecoding_handler(uint8_t ifno, usb_LineCoding *lc); // as ugly CDC have no BREAK after disconnected client in non-canonical mode, we should use timeout - more than 2ms -#define DISCONN_TMOUT (2) +#define DISCONN_TMOUT (1000) // sizes of ringbuffers for outgoing and incoming data #define RBOUTSZ (512) diff --git a/F1:F103/BISS_C_encoders/version.inc b/F1:F103/BISS_C_encoders/version.inc index 00fd981..ebc3fa9 100644 --- a/F1:F103/BISS_C_encoders/version.inc +++ b/F1:F103/BISS_C_encoders/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "130" -#define BUILD_DATE "2026-02-09" +#define BUILD_NUMBER "144" +#define BUILD_DATE "2026-02-13" diff --git a/F3:F303/InterfaceBoard/flash.c b/F3:F303/InterfaceBoard/flash.c index 496eaf2..7f62333 100644 --- a/F3:F303/InterfaceBoard/flash.c +++ b/F3:F303/InterfaceBoard/flash.c @@ -23,7 +23,8 @@ #include "usb_descr.h" // descriptors #include // memcpy -extern const uint32_t __varsstart, _BLOCKSIZE; +extern const uint32_t _BLOCKSIZE; +extern const user_conf __varsstart; static const uint32_t FLASH_blocksize = (uint32_t)&_BLOCKSIZE; static uint32_t maxCnum = 2048 / sizeof(user_conf); // can't use blocksize here diff --git a/F3:F303/InterfaceBoard/usb_dev.c b/F3:F303/InterfaceBoard/usb_dev.c index 0c90964..7256b33 100644 --- a/F3:F303/InterfaceBoard/usb_dev.c +++ b/F3:F303/InterfaceBoard/usb_dev.c @@ -59,13 +59,20 @@ static volatile ringbuffer rbin[InterfacesAmount] = {IBUF(0), IBUF(1), IBUF(2), static volatile int lastdsz[InterfacesAmount] = {-1, -1, -1, -1, -1, -1, -1}; static void chkin(uint8_t ifno){ + static int ovrflctr = 0; // "antistall" counter if(bufovrfl[ifno]) return; // allow user to know that previous buffer was overflowed and cleared if(!rcvbuflen[ifno]) return; int w = RB_write((ringbuffer*)&rbin[ifno], (uint8_t*)rcvbuf[ifno], rcvbuflen[ifno]); - if(w < 0){ + if(w < 0){ // buffer busy return; + }else if(w == 0){ // no enough space or (WTF) incoming string larger than buffer size + if(rcvbuflen[ifno] > rbin[ifno].length || ++ovrflctr > 9999){ + bufovrfl[ifno] = 1; // real overflow in case if ringbuffer's size less than USB buffer + ovrflctr = 0; + }else{ + return; // not enough space + } } - if(w != rcvbuflen[ifno]) bufovrfl[ifno] = 1; rcvbuflen[ifno] = 0; uint16_t status = KEEP_DTOG(USB->EPnR[1+ifno]); // don't change DTOG USB->EPnR[1+ifno] = (status & ~(USB_EPnR_STAT_TX|USB_EPnR_CTR_RX)) ^ USB_EPnR_STAT_RX; // prepare to get next data portion @@ -96,7 +103,7 @@ static void send_next(uint8_t ifno){ // data IN/OUT handler static void rxtx_handler(){ uint8_t epno = (USB->ISTR & USB_ISTR_EPID), ifno = epno - 1; - if(ifno > InterfacesAmount-1){ + if(epno > InterfacesAmount){ return; } uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]); @@ -130,6 +137,7 @@ static void clearbufs(uint8_t ifno){ while(Tms - T0 < 10){ if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break; } + rcvbuflen[ifno] = 0; } // SET_CONTROL_LINE_STATE @@ -200,7 +208,7 @@ int USB_sendall(uint8_t ifno){ uint32_t T0 = Tms; while(lastdsz[ifno] > 0){ if(Tms - T0 > DISCONN_TMOUT){ - //break_handler(ifno); + break_handler(ifno); return FALSE; } if(!CDCready[ifno]) return FALSE; @@ -215,7 +223,7 @@ int USB_send(uint8_t ifno, const uint8_t *buf, int len){ uint32_t T0 = Tms; while(len){ if(Tms - T0 > DISCONN_TMOUT){ - //break_handler(ifno); + break_handler(ifno); return FALSE; } if(!CDCready[ifno]) return FALSE; @@ -246,7 +254,7 @@ int USB_putbyte(uint8_t ifno, uint8_t byte){ uint32_t T0 = Tms; while((l = RB_write((ringbuffer*)&rbout[ifno], &byte, 1)) != 1){ if(Tms - T0 > DISCONN_TMOUT){ - //break_handler(ifno); + break_handler(ifno); return FALSE; } if(!CDCready[ifno]) return FALSE; diff --git a/F3:F303/USB_template/Readme b/F3:F303/USB_template/Readme new file mode 100644 index 0000000..dff4ff4 --- /dev/null +++ b/F3:F303/USB_template/Readme @@ -0,0 +1 @@ +The more fresh USB see in InterfaceBoard diff --git a/F3:F303/USB_template_CDC/Readme b/F3:F303/USB_template_CDC/Readme new file mode 100644 index 0000000..dff4ff4 --- /dev/null +++ b/F3:F303/USB_template_CDC/Readme @@ -0,0 +1 @@ +The more fresh USB see in InterfaceBoard diff --git a/snippets/usb_pl2303/Readme b/snippets/usb_pl2303/Readme index cf9dc25..7749373 100644 --- a/snippets/usb_pl2303/Readme +++ b/snippets/usb_pl2303/Readme @@ -1,3 +1,5 @@ +The more fresh USB see in F3:InterfaceBoard + Actual snipper for all MCUs (just fix usbhw.c and usbhw.h) If USB DP/DM pins need to be setting up, do it before calling USB_setup().