still have unknown problems

This commit is contained in:
eddyem 2023-04-26 23:15:52 +03:00
parent b9cb9f6428
commit 3c7687bb0e
11 changed files with 108 additions and 78 deletions

View File

@ -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;
}
}

View File

@ -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){
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
}
}

Binary file not shown.

View File

@ -19,13 +19,14 @@
#include <math.h>
#include <stm32f3.h>
#include <string.h>
#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);
}
}

View File

@ -21,7 +21,7 @@
#include <stdint.h>
#include <string.h>
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);

View File

@ -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<<ifNo);
bufisempty[ifNo] = 0;
RB_clearbuf((ringbuffer*)&rbout[ifNo]);
return 0; // timeout - interface is down
}
len -= a;
buf += a;
if(bufisempty[ifNo]){
@ -74,7 +79,7 @@ int USB_send(int ifNo, const uint8_t *buf, int len){
}
int USB_putbyte(int ifNo, uint8_t byte){
if(!usbON) return 0;
if(!USBON(ifNo)) return 0;
while(0 == RB_write((ringbuffer*)&rbout[ifNo], &byte, 1)){
if(bufisempty[ifNo]){
bufisempty[ifNo] = 0;
@ -85,7 +90,7 @@ int USB_putbyte(int ifNo, uint8_t byte){
}
int USB_sendstr(int ifNo, const char *string){
if(!string || !usbON) return 0;
if(!string || !USBON(ifNo)) return 0;
int len = 0;
const char *b = string;
while(*b++) ++len;

View File

@ -39,12 +39,13 @@
#define USART2_EPNO 3
#define USART3_EPNO 4
#define CAN_EPNO 6
#define DBG_EPNO 7
#define DBG_EPNO 2
#define USARTMAX_EPNO USART3_EPNO
// functional indexes
#define CMD_IDX (CMD_EPNO-1)
#define CAN_IDX (CAN_EPNO-1)
#define DBG_IDX (DBG_EPNO-1)
#define MAX_IDX 7
extern volatile ringbuffer rbout[], rbin[];
extern volatile uint8_t bufisempty[], bufovrfl[];

View File

@ -32,7 +32,7 @@ static uint16_t USB_Addr = 0;
uint8_t ep0databuf[EP0DATABUF_SIZE], setupdatabuf[EP0DATABUF_SIZE];
config_pack_t *setup_packet = (config_pack_t*) setupdatabuf;
volatile uint8_t usbON = 0; // device disconnected from terminal
volatile uint8_t usbON = 0;
// definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor
#define bcdUSB_L 0x00
@ -95,8 +95,8 @@ static const uint8_t USB_ConfigDescriptor[] = {
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol (0 or 1?)
0x02, // Interface string index
0x00, // bFunctionProtocol
0x00, // iFunction
/*---------------------------------------------------------------------------*/
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
@ -176,8 +176,8 @@ static const uint8_t USB_ConfigDescriptor[] = {
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol (0 or 1?)
0x02, // iFunction
0x00, // bFunctionProtocol
0x00, // iFunction
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
@ -257,8 +257,8 @@ static const uint8_t USB_ConfigDescriptor[] = {
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol (0 or 1?)
0x02, // iFunction
0x00, // bFunctionProtocol
0x00, // iFunction
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
@ -338,8 +338,8 @@ static const uint8_t USB_ConfigDescriptor[] = {
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol (0 or 1?)
0x02, // iFunction
0x00, // bFunctionProtocol
0x00, // iFunction
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
@ -419,8 +419,8 @@ static const uint8_t USB_ConfigDescriptor[] = {
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol (0 or 1?)
0x02, // iFunction
0x00, // bFunctionProtocol
0x00, // iFunction
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
@ -500,8 +500,8 @@ static const uint8_t USB_ConfigDescriptor[] = {
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol (0 or 1?)
0x02, // iFunction
0x00, // bFunctionProtocol
0x00, // iFunction
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
@ -581,8 +581,8 @@ static const uint8_t USB_ConfigDescriptor[] = {
0x02, // bInterfaceCount
0x02, // bFunctionClass: CDC
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol (0 or 1?)
0x02, // iFunction
0x00, // bFunctionProtocol
0x00, // iFunction
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
@ -681,24 +681,6 @@ static void const *StringDescriptor[iDESCR_AMOUNT] = {
[iINTERFACE_DESCR_DBG] = &ID6
};
/*
* default handlers
*/
// SET_LINE_CODING
static void linecoding_handler(int ifNo, usb_LineCoding *lc){
if(ifNo < USART1_EPNO || ifNo > 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<<iFno); // interface is disconnected
break;
default:
DBG("U");
break;
}
if(setup_packet->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]);

View File

@ -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<<ifno))
extern volatile uint8_t usbON;
extern config_pack_t *setup_packet;
extern uint8_t ep0databuf[], setupdatabuf[];

View File

@ -75,6 +75,7 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*f
// standard IRQ handler
void usb_lp_isr(){
static uint8_t oldusbon = 0; // to store flags while suspended
if(USB->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;
}
}

View File

@ -1,2 +1,2 @@
#define BUILD_NUMBER "56"
#define BUILD_DATE "2023-04-23"
#define BUILD_NUMBER "77"
#define BUILD_DATE "2023-04-26"