mirror of
https://github.com/eddyem/stm32samples.git
synced 2026-02-28 03:44:30 +03:00
some USB fixes
This commit is contained in:
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 18.0.2, 2026-02-09T20:28:07. -->
|
<!-- Written by QtCreator 18.0.2, 2026-02-13T20:51:37. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@@ -23,7 +23,9 @@
|
|||||||
#include "usb_dev.h" // printout
|
#include "usb_dev.h" // printout
|
||||||
#include <string.h> // memcpy
|
#include <string.h> // 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 const uint32_t FLASH_blocksize = (uint32_t)&_BLOCKSIZE;
|
||||||
static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
|
static uint32_t maxCnum = 1024 / sizeof(user_conf); // can't use blocksize here
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,13 @@ static void proc_enc(uint8_t idx){
|
|||||||
USB_sendstr(iface, str);
|
USB_sendstr(iface, str);
|
||||||
USB_putbyte(iface, '\n');
|
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;
|
if(the_conf.flags.monit) monitT[idx] = Tms;
|
||||||
else if(testflag) spi_start_enc(idx);
|
else if(testflag) spi_start_enc(idx);
|
||||||
}
|
}
|
||||||
@@ -142,7 +148,7 @@ int main(){
|
|||||||
else if(l) parse_cmd(inbuff);
|
else if(l) parse_cmd(inbuff);
|
||||||
// check if interface connected/disconnected
|
// check if interface connected/disconnected
|
||||||
// (we CAN'T do much debug output in interrupt functions like linecoding_handler etc, so do it here)
|
// (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]){
|
if(oldCDCready[i] != CDCready[i]){
|
||||||
CMDWR("Interface ");
|
CMDWR("Interface ");
|
||||||
CMDWR(u2str(i));
|
CMDWR(u2str(i));
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ uint8_t *spi_read_enc(uint8_t encno){
|
|||||||
// @return FALSE if SPI is busy
|
// @return FALSE if SPI is busy
|
||||||
// here `encodernum` is 0 (SPI1) or 1 (SPI2), not 1/2 as SPI index!
|
// here `encodernum` is 0 (SPI1) or 1 (SPI2), not 1/2 as SPI index!
|
||||||
int spi_start_enc(int encodernum){
|
int spi_start_enc(int encodernum){
|
||||||
|
// CMDWR("startenc: "); USB_putbyte(I_CMD, '0'+encodernum); newline(I_CMD);
|
||||||
int spiidx = encodernum + 1;
|
int spiidx = encodernum + 1;
|
||||||
if(spiidx < 1 || spiidx > AMOUNT_OF_SPI) return FALSE;
|
if(spiidx < 1 || spiidx > AMOUNT_OF_SPI) return FALSE;
|
||||||
if(spi_status[spiidx] != SPI_READY) return FALSE;
|
if(spi_status[spiidx] != SPI_READY) return FALSE;
|
||||||
|
|||||||
@@ -69,14 +69,21 @@ static volatile ringbuffer rbin[bTotNumEndpoints] = {IBUF(0), IBUF(1), IBUF(2)};
|
|||||||
static volatile int lastdsz[bTotNumEndpoints] = {-1, -1, -1};
|
static volatile int lastdsz[bTotNumEndpoints] = {-1, -1, -1};
|
||||||
|
|
||||||
static void chkin(uint8_t ifno){
|
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(bufovrfl[ifno]) return; // allow user to know that previous buffer was overflowed and cleared
|
||||||
if(!rcvbuflen[ifno]) return;
|
if(!rcvbuflen[ifno]) return;
|
||||||
int w = RB_write((ringbuffer*)&rbin[ifno], (uint8_t*)rcvbuf[ifno], rcvbuflen[ifno]);
|
int w = RB_write((ringbuffer*)&rbin[ifno], (uint8_t*)rcvbuf[ifno], rcvbuflen[ifno]);
|
||||||
if(w < 0){
|
if(w < 0){ // buffer busy
|
||||||
DBG("Can't write into buffer");
|
DBG("Can't write into buffer: busy");
|
||||||
return;
|
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");
|
DBG("Put data into buffer");
|
||||||
rcvbuflen[ifno] = 0;
|
rcvbuflen[ifno] = 0;
|
||||||
uint16_t status = KEEP_DTOG(USB->EPnR[1+ifno]); // don't change DTOG
|
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
|
// data IN/OUT handler
|
||||||
static void rxtx_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");
|
DBG("rxtx_handler");
|
||||||
DBGs(uhex2str(ifno));
|
DBGs(uhex2str(ifno));
|
||||||
if(ifno > bTotNumEndpoints-1){
|
if(epno > bTotNumEndpoints){
|
||||||
DBG("wrong ifno");
|
DBG("wrong ifno");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t epstatus = KEEP_DTOG(USB->EPnR[1+ifno]);
|
uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]);
|
||||||
if(RX_FLAG(epstatus)){ // receive data
|
if(RX_FLAG(epstatus)){ // receive data
|
||||||
DBG("Got data");
|
DBG("Got data");
|
||||||
if(rcvbuflen[ifno]){
|
if(rcvbuflen[ifno]){
|
||||||
@@ -126,13 +133,13 @@ static void rxtx_handler(){
|
|||||||
rcvbuflen[ifno] = 0;
|
rcvbuflen[ifno] = 0;
|
||||||
DBG("OVERFULL");
|
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]));
|
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
|
chkin(ifno); // try to write current data into RXbuf if it's not busy
|
||||||
}else{ // tx successfull
|
}else{ // tx successfull
|
||||||
DBG("Tx OK");
|
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);
|
send_next(ifno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,6 +161,7 @@ static void clearbufs(uint8_t ifno){
|
|||||||
while(Tms - T0 < 10){
|
while(Tms - T0 < 10){
|
||||||
if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break;
|
if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break;
|
||||||
}
|
}
|
||||||
|
rcvbuflen[ifno] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SET_CONTROL_LINE_STATE
|
// SET_CONTROL_LINE_STATE
|
||||||
@@ -161,9 +169,9 @@ void WEAK clstate_handler(uint8_t ifno, uint16_t val){
|
|||||||
DBG("clstate_handler");
|
DBG("clstate_handler");
|
||||||
DBGs(uhex2str(ifno));
|
DBGs(uhex2str(ifno));
|
||||||
DBGs(uhex2str(val));
|
DBGs(uhex2str(val));
|
||||||
|
if(val) clearbufs(ifno); // clear buffers on connect
|
||||||
CDCready[ifno] = val; // CONTROL_DTR | CONTROL_RTS -> interface connected; 0 -> disconnected
|
CDCready[ifno] = val; // CONTROL_DTR | CONTROL_RTS -> interface connected; 0 -> disconnected
|
||||||
lastdsz[ifno] = -1;
|
lastdsz[ifno] = -1;
|
||||||
if(val) clearbufs(ifno);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEND_BREAK - disconnect interface and clear its buffers
|
// SEND_BREAK - disconnect interface and clear its buffers
|
||||||
@@ -173,7 +181,6 @@ void WEAK break_handler(uint8_t ifno){
|
|||||||
DBGs(uhex2str(ifno));
|
DBGs(uhex2str(ifno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// USB is configured: setup endpoints
|
// USB is configured: setup endpoints
|
||||||
void set_configuration(){
|
void set_configuration(){
|
||||||
DBG("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;
|
if(!CDCready[ifno]) return FALSE;
|
||||||
IWDG->KR = IWDG_REFRESH;
|
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){
|
if(a > 0){
|
||||||
len -= a;
|
len -= a;
|
||||||
buf += 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);
|
int l = RB_readto((ringbuffer*)&rbin[ifno], '\n', (uint8_t*)buf, len);
|
||||||
if(l < 1){
|
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]));
|
while(1 != RB_clearbuf((ringbuffer*)&rbin[ifno]));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void clstate_handler(uint8_t ifno, uint16_t val);
|
|||||||
void linecoding_handler(uint8_t ifno, usb_LineCoding *lc);
|
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
|
// 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
|
// sizes of ringbuffers for outgoing and incoming data
|
||||||
#define RBOUTSZ (512)
|
#define RBOUTSZ (512)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "130"
|
#define BUILD_NUMBER "144"
|
||||||
#define BUILD_DATE "2026-02-09"
|
#define BUILD_DATE "2026-02-13"
|
||||||
|
|||||||
@@ -23,7 +23,8 @@
|
|||||||
#include "usb_descr.h" // descriptors
|
#include "usb_descr.h" // descriptors
|
||||||
#include <string.h> // memcpy
|
#include <string.h> // 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 const uint32_t FLASH_blocksize = (uint32_t)&_BLOCKSIZE;
|
||||||
static uint32_t maxCnum = 2048 / sizeof(user_conf); // can't use blocksize here
|
static uint32_t maxCnum = 2048 / sizeof(user_conf); // can't use blocksize here
|
||||||
|
|
||||||
|
|||||||
@@ -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 volatile int lastdsz[InterfacesAmount] = {-1, -1, -1, -1, -1, -1, -1};
|
||||||
|
|
||||||
static void chkin(uint8_t ifno){
|
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(bufovrfl[ifno]) return; // allow user to know that previous buffer was overflowed and cleared
|
||||||
if(!rcvbuflen[ifno]) return;
|
if(!rcvbuflen[ifno]) return;
|
||||||
int w = RB_write((ringbuffer*)&rbin[ifno], (uint8_t*)rcvbuf[ifno], rcvbuflen[ifno]);
|
int w = RB_write((ringbuffer*)&rbin[ifno], (uint8_t*)rcvbuf[ifno], rcvbuflen[ifno]);
|
||||||
if(w < 0){
|
if(w < 0){ // buffer busy
|
||||||
return;
|
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;
|
rcvbuflen[ifno] = 0;
|
||||||
uint16_t status = KEEP_DTOG(USB->EPnR[1+ifno]); // don't change DTOG
|
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
|
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
|
// data IN/OUT handler
|
||||||
static void rxtx_handler(){
|
static void rxtx_handler(){
|
||||||
uint8_t epno = (USB->ISTR & USB_ISTR_EPID), ifno = epno - 1;
|
uint8_t epno = (USB->ISTR & USB_ISTR_EPID), ifno = epno - 1;
|
||||||
if(ifno > InterfacesAmount-1){
|
if(epno > InterfacesAmount){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]);
|
uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]);
|
||||||
@@ -130,6 +137,7 @@ static void clearbufs(uint8_t ifno){
|
|||||||
while(Tms - T0 < 10){
|
while(Tms - T0 < 10){
|
||||||
if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break;
|
if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break;
|
||||||
}
|
}
|
||||||
|
rcvbuflen[ifno] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SET_CONTROL_LINE_STATE
|
// SET_CONTROL_LINE_STATE
|
||||||
@@ -200,7 +208,7 @@ int USB_sendall(uint8_t ifno){
|
|||||||
uint32_t T0 = Tms;
|
uint32_t T0 = Tms;
|
||||||
while(lastdsz[ifno] > 0){
|
while(lastdsz[ifno] > 0){
|
||||||
if(Tms - T0 > DISCONN_TMOUT){
|
if(Tms - T0 > DISCONN_TMOUT){
|
||||||
//break_handler(ifno);
|
break_handler(ifno);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(!CDCready[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;
|
uint32_t T0 = Tms;
|
||||||
while(len){
|
while(len){
|
||||||
if(Tms - T0 > DISCONN_TMOUT){
|
if(Tms - T0 > DISCONN_TMOUT){
|
||||||
//break_handler(ifno);
|
break_handler(ifno);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(!CDCready[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;
|
uint32_t T0 = Tms;
|
||||||
while((l = RB_write((ringbuffer*)&rbout[ifno], &byte, 1)) != 1){
|
while((l = RB_write((ringbuffer*)&rbout[ifno], &byte, 1)) != 1){
|
||||||
if(Tms - T0 > DISCONN_TMOUT){
|
if(Tms - T0 > DISCONN_TMOUT){
|
||||||
//break_handler(ifno);
|
break_handler(ifno);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(!CDCready[ifno]) return FALSE;
|
if(!CDCready[ifno]) return FALSE;
|
||||||
|
|||||||
1
F3:F303/USB_template/Readme
Normal file
1
F3:F303/USB_template/Readme
Normal file
@@ -0,0 +1 @@
|
|||||||
|
The more fresh USB see in InterfaceBoard
|
||||||
1
F3:F303/USB_template_CDC/Readme
Normal file
1
F3:F303/USB_template_CDC/Readme
Normal file
@@ -0,0 +1 @@
|
|||||||
|
The more fresh USB see in InterfaceBoard
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
The more fresh USB see in F3:InterfaceBoard
|
||||||
|
|
||||||
Actual snipper for all MCUs (just fix usbhw.c and usbhw.h)
|
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().
|
If USB DP/DM pins need to be setting up, do it before calling USB_setup().
|
||||||
|
|||||||
Reference in New Issue
Block a user