all interfaces works!

This commit is contained in:
Edward Emelianov
2026-02-12 23:16:48 +03:00
parent e17058b2de
commit 2fa218f695
13 changed files with 55 additions and 25 deletions

View File

@@ -0,0 +1 @@
fix error in USB_send (RB_write returns 0 in case of overflow!)

View File

@@ -2,7 +2,7 @@ BINARY := multiiface
# MCU code # MCU code
MCU := F303xc MCU := F303xc
# change this linking script depending on particular MCU model, # change this linking script depending on particular MCU model,
LDSCRIPT := stm32f303xC.ld LDSCRIPT := stm32f303xB.ld
DEFINES := -DUSB1_16 DEFINES := -DUSB1_16
include ../makefile.f3 include ../makefile.f3

View File

@@ -42,20 +42,26 @@ int main(void){
USB_setup(); USB_setup();
//uint32_t ctr = Tms; //uint32_t ctr = Tms;
USBPU_ON(); USBPU_ON();
int maxno = (Config_mode) ? ICFG : InterfacesAmount;
while(1){ while(1){
// Put here code working WITOUT USB connected // Put here code working WITOUT USB connected
if(!usbON) continue; if(!usbON) continue;
for(int i = 0; i < 6; ++i){ // just echo for first time for(int i = 0; i < maxno; ++i){ // just echo for first time
if(!CDCready[i]) continue;
int l = USB_receive(i, (uint8_t*)inbuff, MAXSTRLEN); int l = USB_receive(i, (uint8_t*)inbuff, MAXSTRLEN);
if(l) USB_send(i, (uint8_t*)inbuff, l); if(l) USB_send(i, (uint8_t*)inbuff, l);
} }
// and here is code what should run when USB connected // and here is code what should run when USB connected
if(Config_mode){ if(Config_mode && CDCready[ICFG]){
/*if(Tms - ctr > 999){
ctr = Tms;
CFGWR("I'm alive\n");
}*/
int l = USB_receivestr(ICFG, inbuff, MAXSTRLEN); int l = USB_receivestr(ICFG, inbuff, MAXSTRLEN);
if(l < 0) CFGWR("ERROR: USB buffer overflow or string was too long\n"); if(l < 0) CFGWR("ERROR: USB buffer overflow or string was too long\n");
else if(l){ else if(l){
const char *ans = parse_cmd(inbuff); const char *ans = parse_cmd(inbuff);
if(ans) CFGWR(ans); if(ans) CFGWRn(ans);
} }
} }
} }

View File

@@ -5,3 +5,4 @@
#define STM32F303xb #define STM32F303xb
#define __thumb2__ 1 #define __thumb2__ 1
#define __ARM_ARCH_7M__ #define __ARM_ARCH_7M__
#define USB1_16

View File

@@ -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-11T23:33:00. --> <!-- Written by QtCreator 18.0.2, 2026-02-12T23:15:35. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View File

@@ -57,15 +57,17 @@
// buffer sizes // buffer sizes
// for USB FS EP0 buffers are from 8 to 64 bytes long // for USB FS EP0 buffers are from 8 to 64 bytes long
#define USB_EP0BUFSZ 64 #define USB_EP0BUFSZ 16
// virtual // virtual
#define USB_EP1BUFSZ 10 #define USB_EP1BUFSZ 10
// Rx/Tx EPs (USB_BTABLE_SIZE-64-2*USB_EP0BUFSZ)/(2*InterfacesAmount) rounded to 8 // Rx/Tx EPs (USB_BTABLE_SIZE-64-2*USB_EP0BUFSZ)/(2*InterfacesAmount) rounded to 8
// 534 / 112 -> 4 // ([btable size] - [registers] - [EP0 buffers])/([interfaces buffers (Rx/Tx)])/8 (for rounding by 8 later)
#define _RTBUFSZ8 (((USB_BTABLE_SIZE) - 64 - (2 * (USB_EP0BUFSZ)))/(16 * (InterfacesAmount))) #define _RTBUFSZ8 (((USB_BTABLE_SIZE)/(ACCESSZ) - (LASTADDR_DEFAULT) - (2 * (USB_EP0BUFSZ)))/(16 * (InterfacesAmount)))
// 32 bytes; so we have free 86 bytes which can't be used // 32 bytes; so we have free 86 bytes which can't be used
#define USB_RXBUFSZ (8 * (_RTBUFSZ8)) #define USB_RXBUFSZ (8 * (_RTBUFSZ8))
#define USB_TXBUFSZ (8 * (_RTBUFSZ8)) #define USB_TXBUFSZ (8 * (_RTBUFSZ8))
//#define USB_RXBUFSZ 8
//#define USB_TXBUFSZ 8
// string descriptors // string descriptors
enum{ enum{

View File

@@ -95,21 +95,21 @@ 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;
if(ifno > InterfacesAmount-1){ if(ifno > InterfacesAmount-1){
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
if(rcvbuflen[ifno]){ if(rcvbuflen[ifno]){
bufovrfl[ifno] = 1; // lost last data bufovrfl[ifno] = 1; // lost last data
rcvbuflen[ifno] = 0; rcvbuflen[ifno] = 0;
} }
rcvbuflen[ifno] = EP_Read(1+ifno, (uint8_t*)rcvbuf[ifno]); rcvbuflen[ifno] = EP_Read(epno, (uint8_t*)rcvbuf[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
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);
} }
} }
@@ -200,7 +200,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,12 +215,20 @@ 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;
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;
@@ -238,7 +246,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;

View File

@@ -41,8 +41,8 @@ void break_handler(uint8_t ifno);
void clstate_handler(uint8_t ifno, uint16_t val); 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 - near 2s
#define DISCONN_TMOUT (2) #define DISCONN_TMOUT (2000)
// sizes of ringbuffers for outgoing and incoming data // sizes of ringbuffers for outgoing and incoming data
#define RBOUTSZ (256) #define RBOUTSZ (256)

View File

@@ -80,7 +80,7 @@ void WEAK usb_standard_request(){
} }
break; break;
case REQ_RECIPIENT_ENDPOINT: case REQ_RECIPIENT_ENDPOINT:
if(setup_packet->bRequest == CLEAR_FEATURE){ if(setup_packet->bRequest == CLEAR_FEATURE){ /* what to do here? */
}else{ /* wrong */ } }else{ /* wrong */ }
break; break;
default: default:
@@ -138,7 +138,7 @@ static void EP0_Handler(){
case REQ_TYPE_STANDARD: case REQ_TYPE_STANDARD:
if(SETUP_FLAG(epstatus)){ if(SETUP_FLAG(epstatus)){
usb_standard_request(); usb_standard_request();
}else{ } }else{ /* ??? */ }
break; break;
case REQ_TYPE_CLASS: case REQ_TYPE_CLASS:
usb_class_request(setup_packet, ep0databuf, ep0dbuflen); usb_class_request(setup_packet, ep0databuf, ep0dbuflen);

View File

@@ -63,7 +63,7 @@
#if defined STM32F0 #if defined STM32F0
#define USB_BTABLE_SIZE 1024 #define USB_BTABLE_SIZE 1024
#elif defined STM32F3 #elif defined STM32F3
#define USB_BTABLE_SIZE 726 #define USB_BTABLE_SIZE 1024
//#warning "Please, check real buffer size due to docs" //#warning "Please, check real buffer size due to docs"
#else #else
#error "define STM32F0 or STM32F3" #error "define STM32F0 or STM32F3"
@@ -72,7 +72,8 @@
#if defined STM32F0 #if defined STM32F0
#define USB_BTABLE_SIZE 768 #define USB_BTABLE_SIZE 768
#elif defined STM32F3 #elif defined STM32F3
#define USB_BTABLE_SIZE 726 // 1024 bytes for USB and 256 from them are for CAN (on lower F303 with half-addr ACCESSZ=2 !!!)
#define USB_BTABLE_SIZE 768
//#warning "Please, check real buffer size due to docs" //#warning "Please, check real buffer size due to docs"
#else // STM32F103: 1024 bytes but with 32-bit addressing #else // STM32F103: 1024 bytes but with 32-bit addressing
#define USB_BTABLE_SIZE 1024 #define USB_BTABLE_SIZE 1024

View File

@@ -1,2 +1,2 @@
#define BUILD_NUMBER "20" #define BUILD_NUMBER "41"
#define BUILD_DATE "2026-02-11" #define BUILD_DATE "2026-02-12"

View File

@@ -0,0 +1,11 @@
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 40K
ccmram (rwx) : ORIGIN = 0x10000000, LENGTH = 8K
}
PROVIDE(_BLOCKSIZE = 2048);
/* Include the common ld script. */
INCLUDE stm32f3.ld