From 024d256563d867ba120bcd92f4bfce1acbd1dff8 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Mon, 23 Mar 2026 23:08:08 +0300 Subject: [PATCH] fixed USB --- .../usbcan_gpio/usbcangpio.creator.user | 4 +- F1:F103/BISS_C_encoders/Makefile | 2 +- F1:F103/BISS_C_encoders/encoders.bin | Bin 15760 -> 14660 bytes F1:F103/BISS_C_encoders/encoders.creator.user | 4 +- F1:F103/BISS_C_encoders/flash.h | 4 +- F1:F103/BISS_C_encoders/main.c | 4 +- F1:F103/BISS_C_encoders/proto.c | 4 +- F1:F103/BISS_C_encoders/ringbuffer.c | 64 ++++-- F1:F103/BISS_C_encoders/ringbuffer.h | 7 +- F1:F103/BISS_C_encoders/usb_descr.c | 67 ++---- F1:F103/BISS_C_encoders/usb_descr.h | 12 +- F1:F103/BISS_C_encoders/usb_dev.c | 217 ++++++++---------- F1:F103/BISS_C_encoders/usb_dev.h | 6 +- F1:F103/BISS_C_encoders/usb_lib.c | 200 +++++++++------- F1:F103/BISS_C_encoders/usb_lib.h | 53 ++++- F1:F103/BISS_C_encoders/version.inc | 4 +- 16 files changed, 357 insertions(+), 295 deletions(-) diff --git a/F0:F030,F042,F072/usbcan_gpio/usbcangpio.creator.user b/F0:F030,F042,F072/usbcan_gpio/usbcangpio.creator.user index 1ffe426..2bc265d 100644 --- a/F0:F030,F042,F072/usbcan_gpio/usbcangpio.creator.user +++ b/F0:F030,F042,F072/usbcan_gpio/usbcangpio.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -155,6 +155,7 @@ true 0 true + 2 @@ -190,6 +191,7 @@ true 0 true + 2 diff --git a/F1:F103/BISS_C_encoders/Makefile b/F1:F103/BISS_C_encoders/Makefile index 8496007..3aa2506 100644 --- a/F1:F103/BISS_C_encoders/Makefile +++ b/F1:F103/BISS_C_encoders/Makefile @@ -6,4 +6,4 @@ LDSCRIPT ?= stm32f103xB.ld DEFINES := -DSTM32F10X_MD include ../makefile.f1 -include ../makefile.stm32 +include ../../makefile.stm32 diff --git a/F1:F103/BISS_C_encoders/encoders.bin b/F1:F103/BISS_C_encoders/encoders.bin index efe98a1fe7def3c7b2cf625b52dd241f53a33222..0068880672a2f05352c1ce30673ccd292a923bce 100755 GIT binary patch literal 14660 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 Te?&oJ@V&nuQ_$%A&%gf-QoLCi literal 15760 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 LYYggrfByS#APZ(# diff --git a/F1:F103/BISS_C_encoders/encoders.creator.user b/F1:F103/BISS_C_encoders/encoders.creator.user index 32c15f4..df0650b 100644 --- a/F1:F103/BISS_C_encoders/encoders.creator.user +++ b/F1:F103/BISS_C_encoders/encoders.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -154,6 +154,7 @@ true 0 true + 2 @@ -189,6 +190,7 @@ true 0 true + 2 diff --git a/F1:F103/BISS_C_encoders/flash.h b/F1:F103/BISS_C_encoders/flash.h index 2a8266a..6177fe7 100644 --- a/F1:F103/BISS_C_encoders/flash.h +++ b/F1:F103/BISS_C_encoders/flash.h @@ -47,8 +47,8 @@ typedef struct{ typedef struct __attribute__((packed, aligned(4))){ uint16_t userconf_sz; // "magick number" uint16_t send232_interval; // interval (ms) of sending data to SSII over RS-232 (or 0 - not to send) - uint16_t iInterface[bTotNumEndpoints][MAX_IINTERFACE_SZ]; // hryunikod! - uint8_t iIlengths[bTotNumEndpoints]; + uint16_t iInterface[InterfacesAmount][MAX_IINTERFACE_SZ]; // hryunikod! + uint8_t iIlengths[InterfacesAmount]; uint8_t encbits; // encoder bits: 26 or 32 uint8_t encbufsz; // encoder buffer size (up to ENCODER_BUFSZ_MAX) uint8_t minzeros; // min/max zeros in preamble when searching start of record diff --git a/F1:F103/BISS_C_encoders/main.c b/F1:F103/BISS_C_encoders/main.c index 5a3f87a..f6ac060 100644 --- a/F1:F103/BISS_C_encoders/main.c +++ b/F1:F103/BISS_C_encoders/main.c @@ -124,7 +124,7 @@ static void proc_enc(uint8_t idx){ int main(){ uint32_t lastT = 0, usartT = 0; - uint8_t oldCDCready[bTotNumEndpoints] = {0}; + uint8_t oldCDCready[InterfacesAmount] = {0}; StartHSE(); flashstorage_init(); hw_setup(); @@ -148,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 = 1; i < bTotNumEndpoints; ++i){ + for(int i = 1; i < InterfacesAmount; ++i){ if(oldCDCready[i] != CDCready[i]){ CMDWR("Interface "); CMDWR(u2str(i)); diff --git a/F1:F103/BISS_C_encoders/proto.c b/F1:F103/BISS_C_encoders/proto.c index b096ddb..0438baa 100644 --- a/F1:F103/BISS_C_encoders/proto.c +++ b/F1:F103/BISS_C_encoders/proto.c @@ -133,7 +133,7 @@ static errcode_e sendenc(cmd_e idx, char *par){ } static errcode_e setiface(cmd_e idx, char *par){ - if(idx < C_setiface1 || idx >= C_setiface1 + bTotNumEndpoints) return ERR_BADCMD; + if(idx < C_setiface1 || idx >= C_setiface1 + InterfacesAmount) return ERR_BADCMD; idx -= C_setiface1; // now it is an index of iIlengths if(par && *par){ int l = strlen(par); @@ -364,7 +364,7 @@ static errcode_e dumpconf(cmd_e _U_ idx, char _U_ *par){ CMDWR("userconf_sz="); CMDWR(u2str(the_conf.userconf_sz)); CMDWR("\ncurrentconfidx="); CMDWR(i2str(currentconfidx)); CMDn(); - for(int i = 0; i < bTotNumEndpoints; ++i) + for(int i = 0; i < InterfacesAmount; ++i) setiface(C_setiface1 + i, NULL); setboolpar(C_autom, NULL); setuintpar(C_amperiod, NULL); diff --git a/F1:F103/BISS_C_encoders/ringbuffer.c b/F1:F103/BISS_C_encoders/ringbuffer.c index d444ec6..bc2af8d 100644 --- a/F1:F103/BISS_C_encoders/ringbuffer.c +++ b/F1:F103/BISS_C_encoders/ringbuffer.c @@ -15,9 +15,12 @@ * along with this program. If not, see . */ -#include // memcpy +#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); @@ -25,6 +28,8 @@ static int datalen(ringbuffer *b){ // stored data length int RB_datalen(ringbuffer *b){ + 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); @@ -52,17 +57,13 @@ 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){ + CHK(b); if(b->busy) return -1; b->busy = 1; int ret = hasbyte(b, byte); b->busy = 0; return ret; } -/* -// poor memcpy -static void mcpy(uint8_t *targ, const uint8_t *src, int l){ - while(l--) *targ++ = *src++; -}*/ // increment head or tail TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){ @@ -77,10 +78,8 @@ static int read(ringbuffer *b, uint8_t *s, int len){ int _1st = b->length - b->head; if(_1st > l) _1st = l; if(_1st > len) _1st = len; - //mcpy(s, b->data + b->head, _1st); memcpy(s, b->data + b->head, _1st); if(_1st < len && l > _1st){ - //mcpy(s+_1st, b->data, l - _1st); memcpy(s+_1st, b->data, l - _1st); incr(b, &b->head, l); return l; @@ -97,6 +96,9 @@ 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){ + 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); @@ -104,13 +106,20 @@ int RB_read(ringbuffer *b, uint8_t *s, int len){ return r; } -static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ +// length of data from current position to `byte` (including byte) +static int lento(ringbuffer *b, uint8_t byte){ int idx = hasbyte(b, byte); if(idx < 0) return 0; int partlen = idx + 1 - b->head; // now calculate length of new data portion if(idx < b->head) partlen += b->length; - if(partlen > len) return -read(b, s, len); + return partlen; +} + +static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ + int partlen = lento(b, byte); + if(!partlen) return 0; + if(partlen > len) return -1; return read(b, s, partlen); } @@ -118,27 +127,45 @@ static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){ * @brief RB_readto fill array `s` with data until byte `byte` (with it) * @param b - ringbuffer * @param byte - check byte - * @param s - buffer to write data - * @param len - length of `s` + * @param s - buffer to write data or NULL to clear data + * @param len - length of `s` or 0 to clear data * @return amount of bytes written (negative, if lenbusy) return -1; b->busy = 1; - int n = readto(b, byte, s, len); + int n = 0; + if(s && len > 0){ + n = readto(b, byte, s, len); + }else{ + incr(b, &b->head, lento(b, byte)); // just throw data out + } b->busy = 0; return n; } +int RB_datalento(ringbuffer *b, uint8_t byte){ + CHK(b); + if(0 == datalen(b)) return 0; + if(b->busy) return -1; + b->busy = 1; + int n = lento(b, byte); + b->busy = 0; + return n; +} + +// if l < rest of buffer, truncate and return actually written bytes static int write(ringbuffer *b, const uint8_t *str, int l){ int r = b->length - 1 - datalen(b); // rest length - if(l > r || !l) return 0; + if(r < 1) return 0; + if(l > r) l = r; int _1st = b->length - b->tail; if(_1st > l) _1st = l; - //mcpy(b->data + b->tail, str, _1st); memcpy(b->data + b->tail, str, _1st); if(_1st < l){ // add another piece from start - //mcpy(b->data, str+_1st, l-_1st); memcpy(b->data, str+_1st, l-_1st); } incr(b, &b->tail, l); @@ -153,6 +180,9 @@ 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){ + 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); @@ -162,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){ + 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/F1:F103/BISS_C_encoders/ringbuffer.h b/F1:F103/BISS_C_encoders/ringbuffer.h index 5643b5a..e7312bb 100644 --- a/F1:F103/BISS_C_encoders/ringbuffer.h +++ b/F1:F103/BISS_C_encoders/ringbuffer.h @@ -17,6 +17,8 @@ #pragma once +#include + #if defined STM32F0 #include #elif defined STM32F1 @@ -25,14 +27,12 @@ #include #endif -#include - typedef struct{ uint8_t *data; // data buffer const int length; // its length int head; // head index int tail; // tail index - volatile atomic_int busy; // == TRUE if buffer is busy now + volatile int busy; // == TRUE if buffer is busy now } ringbuffer; int RB_read(ringbuffer *b, uint8_t *s, int len); @@ -40,4 +40,5 @@ int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len); int RB_hasbyte(ringbuffer *b, uint8_t byte); int RB_write(ringbuffer *b, const uint8_t *str, int l); int RB_datalen(ringbuffer *b); +int RB_datalento(ringbuffer *b, uint8_t byte); int RB_clearbuf(ringbuffer *b); diff --git a/F1:F103/BISS_C_encoders/usb_descr.c b/F1:F103/BISS_C_encoders/usb_descr.c index fd1688d..233d5af 100644 --- a/F1:F103/BISS_C_encoders/usb_descr.c +++ b/F1:F103/BISS_C_encoders/usb_descr.c @@ -20,11 +20,6 @@ #include "flash.h" #include "usb_descr.h" -#undef DBG -#define DBG(x) -#undef DBGs -#define DBGs(x) - // low/high for uint16_t #define L16(x) (x & 0xff) #define H16(x) (x >> 8) @@ -63,7 +58,7 @@ static const uint8_t USB_DeviceQualifierDescriptor[] = { 0 // Reserved }; -#define wTotalLength (USB_DT_CONFIG_SIZE + bTotNumEndpoints * 66) +#define wTotalLength (USB_DT_CONFIG_SIZE + (bTotNumEndpoints * 66)) /* * _1stI - number of first interface @@ -166,7 +161,7 @@ static const uint8_t USB_ConfigDescriptor[] = { //const uint8_t HID_ReportDescriptor[]; _USB_LANG_ID_(LD, LANG_US); -_USB_STRING_(SD, u"0.0.1"); +_USB_STRING_(SD, u"0.0.2"); _USB_STRING_(MD, u"eddy@sao.ru"); _USB_STRING_(PD, u"USB BISS-C encoders controller"); @@ -177,7 +172,7 @@ typedef struct{ uint8_t bDescriptorType; uint16_t bString[MAX_IINTERFACE_SZ]; }iidescr_t; -static iidescr_t iids[bTotNumEndpoints] = { +static iidescr_t iids[InterfacesAmount] = { _USB_IIDESCR_(u"encoder_cmd"), _USB_IIDESCR_(u"encoder_X"), _USB_IIDESCR_(u"encoder_Y"), @@ -197,12 +192,8 @@ static void wr0(const uint8_t *buf, uint16_t size, uint16_t askedsize){ if(askedsize < size) size = askedsize; // shortened request if(size < USB_EP0BUFSZ){ EP_WriteIRQ(0, buf, size); - DBG("short wr0"); - DBGs(uhex2str(size)); return; } - DBG("long wr0"); - DBGs(uhex2str(size)); while(size){ uint16_t l = size; if(l > USB_EP0BUFSZ) l = USB_EP0BUFSZ; @@ -215,7 +206,7 @@ static void wr0(const uint8_t *buf, uint16_t size, uint16_t askedsize){ // keep DTOGs, clear CTR_RX,TX, set TX VALID, leave stat_Rx USB->EPnR[0] = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX|USB_EPnR_STAT_RX)) ^ USB_EPnR_STAT_TX; - uint32_t ctr = 10000; + uint32_t ctr = 1000000; while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0){IWDG->KR = IWDG_REFRESH;}; if((USB->ISTR & USB_ISTR_CTR) == 0){ return; @@ -229,42 +220,32 @@ void get_descriptor(config_pack_t *pack){ uint8_t descrtype = pack->wValue >> 8, descridx = pack->wValue & 0xff; switch(descrtype){ - case DEVICE_DESCRIPTOR: - DBG("DEVICE_DESCRIPTOR"); - wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor), pack->wLength); - break; - case CONFIGURATION_DESCRIPTOR: - DBG("CONFIGURATION_DESCRIPTOR"); - wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor), pack->wLength); - break; - case STRING_DESCRIPTOR: - DBG("STRING_DESCRIPTOR"); - if(descridx < iDESCR_AMOUNT){ - wr0((const uint8_t *)StringDescriptor[descridx], *((uint8_t*)StringDescriptor[descridx]), pack->wLength); - DBGs(uhex2str(descridx)); - }else{ - EP_WriteIRQ(0, NULL, 0); - DBG("Wrong index"); - DBGs(uhex2str(descridx)); - } - break; - case DEVICE_QUALIFIER_DESCRIPTOR: - DBG("DEVICE_QUALIFIER_DESCRIPTOR"); - wr0(USB_DeviceQualifierDescriptor, sizeof(USB_DeviceQualifierDescriptor), pack->wLength); - break; - /* case HID_REPORT_DESCRIPTOR: - wr0(HID_ReportDescriptor, sizeof(HID_ReportDescriptor), pack->wLength); - break;*/ - default: - break; + case DEVICE_DESCRIPTOR: + wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor), pack->wLength); + break; + case CONFIGURATION_DESCRIPTOR: + wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor), pack->wLength); + break; + case STRING_DESCRIPTOR: + if(descridx < iDESCR_AMOUNT){ + wr0((const uint8_t *)StringDescriptor[descridx], *((uint8_t*)StringDescriptor[descridx]), pack->wLength); + }else{ + EP_WriteIRQ(0, NULL, 0); + } + break; + case DEVICE_QUALIFIER_DESCRIPTOR: + wr0(USB_DeviceQualifierDescriptor, sizeof(USB_DeviceQualifierDescriptor), pack->wLength); + break; + default: + break; } } // change values of iInterface by content of global config void setup_interfaces(){ - for(int i = 0; i < bTotNumEndpoints; ++i){ + for(int i = 0; i < InterfacesAmount; ++i){ if(the_conf.iIlengths[i]){ - iids[i].bLength = the_conf.iIlengths[i]; + iids[i].bLength = the_conf.iIlengths[i] + 2; // +2 - for bLength and bDescriptorType memcpy(iids[i].bString, the_conf.iInterface[i], the_conf.iIlengths[i]); } iids[i].bDescriptorType = 0x03; diff --git a/F1:F103/BISS_C_encoders/usb_descr.h b/F1:F103/BISS_C_encoders/usb_descr.h index 8c0ffd2..6654d70 100644 --- a/F1:F103/BISS_C_encoders/usb_descr.h +++ b/F1:F103/BISS_C_encoders/usb_descr.h @@ -32,8 +32,16 @@ #define bNumConfigurations 1 // amount of interfaces and endpoints (except 0) used -#define bNumInterfaces 6 -#define bTotNumEndpoints 3 +#define InterfacesAmount 3 +// EP number of interface +#define EPNO(i) (i + 1) +// interface number of EPno +#define IFNO(e) (e - 1) + +// amount of interfaces (including virtual) except 0 +#define bNumInterfaces (2*InterfacesAmount) +// amount of endpoints used +#define bTotNumEndpoints (1+InterfacesAmount) // powered #define BusPowered (1<<7) diff --git a/F1:F103/BISS_C_encoders/usb_dev.c b/F1:F103/BISS_C_encoders/usb_dev.c index b61aea8..c420d2a 100644 --- a/F1:F103/BISS_C_encoders/usb_dev.c +++ b/F1:F103/BISS_C_encoders/usb_dev.c @@ -38,56 +38,41 @@ #define CONTROL_DTR 0x01 #define CONTROL_RTS 0x02 -// It's good to use debug here ONLY to debug into USART! -// never try to debug USB into USB!!! -#undef DBG -#define DBG(x) -#undef DBGs -#define DBGs(x) - extern volatile uint32_t Tms; // inbuf overflow when receiving -static volatile uint8_t bufovrfl[bTotNumEndpoints] = {0}; +static volatile uint8_t bufovrfl[InterfacesAmount] = {0}; // receive buffer: hold data until chkin() call -static uint8_t volatile rcvbuf[bTotNumEndpoints][USB_RXBUFSZ]; -static uint8_t volatile rcvbuflen[bTotNumEndpoints] = {0}; +static uint8_t volatile rcvbuf[InterfacesAmount][USB_RXBUFSZ] __attribute__((aligned(4))); +static uint8_t volatile rcvbuflen[InterfacesAmount] = {0}; // line coding #define DEFLC {115200, 0, 0, 8} -static usb_LineCoding lineCoding[bTotNumEndpoints] = {DEFLC, DEFLC, DEFLC}; +static usb_LineCoding lineCoding[InterfacesAmount] = {DEFLC, DEFLC, DEFLC}; // CDC configured and ready to use -volatile uint8_t CDCready[bTotNumEndpoints] = {0}; +volatile uint8_t CDCready[InterfacesAmount] = {0}; // ring buffers for incoming and outgoing data -static uint8_t obuf[bTotNumEndpoints][RBOUTSZ], ibuf[bTotNumEndpoints][RBINSZ]; +static uint8_t obuf[InterfacesAmount][RBOUTSZ], ibuf[InterfacesAmount][RBINSZ]; #define OBUF(N) {.data = obuf[N], .length = RBOUTSZ, .head = 0, .tail = 0} -static volatile ringbuffer rbout[bTotNumEndpoints] = {OBUF(0), OBUF(1), OBUF(2)}; +static volatile ringbuffer rbout[InterfacesAmount] = {OBUF(0), OBUF(1), OBUF(2)}; #define IBUF(N) {.data = ibuf[N], .length = RBINSZ, .head = 0, .tail = 0} -static volatile ringbuffer rbin[bTotNumEndpoints] = {IBUF(0), IBUF(1), IBUF(2)}; +static volatile ringbuffer rbin[InterfacesAmount] = {IBUF(0), IBUF(1), IBUF(2)}; // last send data size (<0 if USB transfer ready) -static volatile int lastdsz[bTotNumEndpoints] = {-1, -1, -1}; +static volatile int lastdsz[InterfacesAmount] = {-1, -1, -1}; +// check incoming data and set ACK if need 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){ // buffer busy - DBG("Can't write into buffer: busy"); + if(w < 0){ 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 - } } - DBG("Put data into buffer"); + 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 + uint16_t status = KEEP_DTOG(USB->EPnR[EPNO(ifno)]); // don't change DTOG + USB->EPnR[EPNO(ifno)] = (status & ~(USB_EPnR_STAT_TX|USB_EPnR_CTR_RX)) ^ USB_EPnR_STAT_RX; // prepare to get next data portion } // called from transmit EP to send next data portion or by user - when new transmission starts @@ -100,97 +85,83 @@ static void send_next(uint8_t ifno){ } if(buflen == 0){ if(lastdsz[ifno] == USB_TXBUFSZ){ - EP_Write(1+ifno, NULL, 0); // send ZLP after 64 bits packet when nothing more to send + EP_Write(EPNO(ifno), NULL, 0); // send ZLP after 64 bits packet when nothing more to send lastdsz[ifno] = 0; }else lastdsz[ifno] = -1; // OK. User can start sending data return; }else if(buflen < 0){ - DBG("Buff busy"); lastdsz[ifno] = -1; return; } - DBG("Got data in buf"); - DBGs(uhex2str(buflen)); - DBGs(uhex2str(ifno)); - EP_Write(1+ifno, (uint8_t*)usbbuff, buflen); + EP_Write(EPNO(ifno), (uint8_t*)usbbuff, buflen); lastdsz[ifno] = buflen; } // data IN/OUT handler static void rxtx_handler(){ - uint8_t epno = (USB->ISTR & USB_ISTR_EPID), ifno = epno - 1; - DBG("rxtx_handler"); - DBGs(uhex2str(ifno)); - if(epno > bTotNumEndpoints){ - DBG("wrong ifno"); + uint8_t epno = (USB->ISTR & USB_ISTR_EPID), ifno = IFNO(epno); + if(ifno > InterfacesAmount-1){ return; } uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]); if(RX_FLAG(epstatus)){ // receive data - DBG("Got data"); if(rcvbuflen[ifno]){ bufovrfl[ifno] = 1; // lost last data rcvbuflen[ifno] = 0; - DBG("OVERFULL"); } rcvbuflen[ifno] = EP_Read(epno, (uint8_t*)rcvbuf[ifno]); - DBGs(uhex2str(rcvbuflen[ifno])); 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[epno] = (epstatus & ~(USB_EPnR_CTR_TX | USB_EPnR_STAT_TX)) ^ USB_EPnR_STAT_RX; send_next(ifno); } } -// weak handlers: change them somewhere else if you want to setup USART -// SET_LINE_CODING -void WEAK linecoding_handler(uint8_t ifno, usb_LineCoding *lc){ - lineCoding[ifno] = *lc; - DBG("linecoding_handler"); - DBGs(uhex2str(ifno)); -} - -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; } - rcvbuflen[ifno] = 0; +} + +// SET_LINE_CODING +void linecoding_handler(uint8_t ifno, usb_LineCoding *lc){ + lineCoding[ifno] = *lc; } // SET_CONTROL_LINE_STATE -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 +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){ + clearRbuf(ifno); + clearTbuf(ifno); + EP_reset(EPNO(ifno)); + } } // SEND_BREAK - disconnect interface and clear its buffers -void WEAK break_handler(uint8_t ifno){ +// this is a fake handler as classic CDC ACM never receives this +void break_handler(uint8_t ifno){ CDCready[ifno] = 0; - DBG("break_handler()"); - DBGs(uhex2str(ifno)); } -// USB is configured: setup endpoints +// Interface is configured: setup endpoints void set_configuration(){ - DBG("set_configuration()"); - for(int i = 0; i < bTotNumEndpoints; ++i){ + for(int i = 0; i < InterfacesAmount; ++i){ IWDG->KR = IWDG_REFRESH; - int r = EP_Init(1+i, EP_TYPE_BULK, USB_TXBUFSZ, USB_RXBUFSZ, rxtx_handler); + int r = EP_Init(EPNO(i), EP_TYPE_BULK, USB_TXBUFSZ, USB_RXBUFSZ, rxtx_handler); if(r){ - DBG("Can't init EP"); - DBGs(uhex2str(i)); - DBGs(uhex2str(r)); + // OOPS, can't init EP. What to do? Cry? + break; } } } @@ -200,45 +171,33 @@ void usb_class_request(config_pack_t *req, uint8_t *data, uint16_t datalen){ uint8_t recipient = REQUEST_RECIPIENT(req->bmRequestType); uint8_t dev2host = (req->bmRequestType & 0x80) ? 1 : 0; uint8_t ifno = req->wIndex >> 1; - if(ifno > bTotNumEndpoints-1 && ifno != 0xff){ - DBG("wrong ifno"); + if(ifno > InterfacesAmount-1){ // wrong interface number + EP_WriteIRQ(0, NULL, 0); return; } - DBG("usb_class_request"); - DBGs(uhex2str(req->bRequest)); switch(recipient){ - case REQ_RECIPIENT_INTERFACE: - switch(req->bRequest){ - case SET_LINE_CODING: - DBG("SET_LINE_CODING"); - if(!data || !datalen) break; // wait for data - if(datalen == sizeof(usb_LineCoding)) - linecoding_handler(ifno, (usb_LineCoding*)data); - break; - case GET_LINE_CODING: - DBG("GET_LINE_CODING"); - EP_WriteIRQ(0, (uint8_t*)&lineCoding[ifno], sizeof(lineCoding)); - break; - case SET_CONTROL_LINE_STATE: - DBG("SET_CONTROL_LINE_STATE"); - clstate_handler(ifno, req->wValue); - break; - case SEND_BREAK: - DBG("SEND_BREAK"); - break_handler(ifno); - break; - default: - DBG("Wrong"); - DBGs(uhex2str(req->bRequest)); - DBGs(uhex2str(datalen)); - } + case REQ_RECIPIENT_INTERFACE: + switch(req->bRequest){ + case SET_LINE_CODING: + if(!data || !datalen) break; // wait for data + if(datalen == sizeof(usb_LineCoding)) + linecoding_handler(ifno, (usb_LineCoding*)data); + break; + case GET_LINE_CODING: + EP_WriteIRQ(0, (uint8_t*)&lineCoding[ifno], sizeof(lineCoding)); + break; + case SET_CONTROL_LINE_STATE: + clstate_handler(ifno, req->wValue); + break; + case SEND_BREAK: + break_handler(ifno); + break; + default: // WTF? + break; + } break; - default: - DBG("Wrong"); - DBGs(uhex2str(recipient)); - DBGs(uhex2str(datalen)); - DBGs(uhex2str(req->bRequest)); - if(dev2host) EP_WriteIRQ(0, NULL, 0); + default: // WTF? + if(dev2host) EP_WriteIRQ(0, NULL, 0); } if(!dev2host) EP_WriteIRQ(0, NULL, 0); } @@ -248,7 +207,6 @@ int USB_sendall(uint8_t ifno){ uint32_t T0 = Tms; while(lastdsz[ifno] > 0){ if(Tms - T0 > DISCONN_TMOUT){ - break_handler(ifno); return FALSE; } if(!CDCready[ifno]) return FALSE; @@ -257,17 +215,25 @@ int USB_sendall(uint8_t ifno){ return TRUE; } +// return amount of free space in buffer +int USB_sendbufspace(uint8_t ifno){ + if(!CDCready[ifno]) return 0; + return rbout[ifno].length - RB_datalen((ringbuffer*)&rbout[ifno]); +} + // put `buf` into queue to send int USB_send(uint8_t ifno, const uint8_t *buf, int len){ - if(!buf || !CDCready[ifno] || !len) return FALSE; - DBG("USB_send"); + if(!buf || !CDCready[ifno] || !len){ + return FALSE; + } uint32_t T0 = Tms; while(len){ if(Tms - T0 > DISCONN_TMOUT){ - break_handler(ifno); return FALSE; } - if(!CDCready[ifno]) return FALSE; + if(!CDCready[ifno]){ + return FALSE; + } IWDG->KR = IWDG_REFRESH; int l = RB_datalen((ringbuffer*)&rbout[ifno]); if(l < 0) continue; @@ -285,7 +251,9 @@ int USB_send(uint8_t ifno, const uint8_t *buf, int len){ if(lastdsz[ifno] < 0) send_next(ifno); } } - if(buf[len-1] == '\n' && lastdsz[ifno] < 0) send_next(ifno); + if(buf[len-1] == '\n' && lastdsz[ifno] < 0){ + send_next(ifno); + } return TRUE; } @@ -295,7 +263,6 @@ 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); return FALSE; } if(!CDCready[ifno]) return FALSE; @@ -306,7 +273,9 @@ int USB_putbyte(uint8_t ifno, uint8_t byte){ } } // send line if got EOL - if(byte == '\n' && lastdsz[ifno] < 0) send_next(ifno); + if(byte == '\n' && lastdsz[ifno] < 0){ + send_next(ifno); + } return TRUE; } @@ -317,6 +286,10 @@ int USB_sendstr(uint8_t ifno, const char *string){ return USB_send(ifno, (const uint8_t*)string, len); } +int USB_rcvlen(uint8_t ifno){ + return RB_datalen((ringbuffer*)&rbin[ifno]); +} + /** * @brief USB_receive - get binary data from receiving ring-buffer * @param buf (i) - buffer for received data @@ -324,17 +297,15 @@ int USB_sendstr(uint8_t ifno, const char *string){ * @return amount of received bytes (negative, if overfull happened) */ 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]){ - DBG("Buffer overflow"); - DBGs(uhex2str(ifno)); - while(1 != RB_clearbuf((ringbuffer*)&rbin[ifno])); // run watchdog in case of problems + clearRbuf(ifno); bufovrfl[ifno] = 0; return -1; } int sz = RB_read((ringbuffer*)&rbin[ifno], buf, len); if(sz < 0) return 0; // buffer in writting state - DBG("usb read"); return sz; } @@ -345,24 +316,22 @@ int USB_receive(uint8_t ifno, uint8_t *buf, int len){ * @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared) */ 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; } int l = RB_readto((ringbuffer*)&rbin[ifno], '\n', (uint8_t*)buf, len); if(l < 1){ - //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])); + 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 + clearRbuf(ifno); return -1; } return 0; } - if(l == 0) return 0; buf[l-1] = 0; // replace '\n' with strend return l; } - diff --git a/F1:F103/BISS_C_encoders/usb_dev.h b/F1:F103/BISS_C_encoders/usb_dev.h index 7308630..064f473 100644 --- a/F1:F103/BISS_C_encoders/usb_dev.h +++ b/F1:F103/BISS_C_encoders/usb_dev.h @@ -40,14 +40,14 @@ typedef struct { uint8_t bDataBits; } __attribute__ ((packed)) usb_LineCoding; -extern volatile uint8_t CDCready[bTotNumEndpoints]; +extern volatile uint8_t CDCready[InterfacesAmount]; void break_handler(uint8_t ifno); 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 (1000) +#define DISCONN_TMOUT (2) // sizes of ringbuffers for outgoing and incoming data #define RBOUTSZ (512) @@ -69,9 +69,11 @@ void linecoding_handler(uint8_t ifno, usb_LineCoding *lc); #define DBGs(s) #endif +int USB_sendbufspace(uint8_t ifno); int USB_sendall(uint8_t ifno); int USB_send(uint8_t ifno, const uint8_t *buf, int len); int USB_putbyte(uint8_t ifno, uint8_t byte); int USB_sendstr(uint8_t ifno, const char *string); +int USB_rcvlen(uint8_t ifno); int USB_receive(uint8_t ifno, uint8_t *buf, int len); int USB_receivestr(uint8_t ifno, char *buf, int len); diff --git a/F1:F103/BISS_C_encoders/usb_lib.c b/F1:F103/BISS_C_encoders/usb_lib.c index 2779402..8ed4e0e 100644 --- a/F1:F103/BISS_C_encoders/usb_lib.c +++ b/F1:F103/BISS_C_encoders/usb_lib.c @@ -20,15 +20,10 @@ #include "usb_descr.h" #include "usb_dev.h" -#undef DBG -#define DBG(x) -#undef DBGs -#define DBGs(x) - static ep_t endpoints[STM32ENDPOINTS]; static uint16_t USB_Addr = 0; -static uint8_t setupdatabuf[EP0DATABUF_SIZE]; +static uint8_t setupdatabuf[EP0DATABUF_SIZE] __attribute__((aligned(4))); static config_pack_t *setup_packet = (config_pack_t*) setupdatabuf; volatile uint8_t usbON = 0; // device is configured and active @@ -37,20 +32,15 @@ static inline void std_d2h_req(){ uint16_t st = 0; switch(setup_packet->bRequest){ case GET_DESCRIPTOR: - DBG("GET_DESCRIPTOR"); get_descriptor(setup_packet); break; case GET_STATUS: - DBG("GET_STATUS"); EP_WriteIRQ(0, (uint8_t *)&st, 2); // send status: Bus Powered break; case GET_CONFIGURATION: - DBG("GET_CONFIGURATION"); EP_WriteIRQ(0, (uint8_t*)&configuration, 1); break; default: - DBG("Wrong"); - DBGs(uhex2str(setup_packet->bRequest)); EP_WriteIRQ(0, NULL, 0); break; } @@ -59,21 +49,16 @@ static inline void std_d2h_req(){ static inline void std_h2d_req(){ switch(setup_packet->bRequest){ case SET_ADDRESS: - DBG("SET_ADDRESS"); // new address will be assigned later - after acknowlegement or request to host USB_Addr = setup_packet->wValue; - DBGs(uhex2str(USB_Addr)); break; case SET_CONFIGURATION: - DBG("SET_CONFIGURATION"); // Now device configured configuration = setup_packet->wValue; set_configuration(); usbON = 1; break; default: - DBG("Wrong"); - DBGs(uhex2str(setup_packet->bRequest)); break; } } @@ -83,7 +68,6 @@ void WEAK usb_standard_request(){ uint8_t dev2host = (setup_packet->bmRequestType & 0x80) ? 1 : 0; switch(recipient){ case REQ_RECIPIENT_DEVICE: - DBG("REQ_RECIPIENT_DEVICE"); if(dev2host){ std_d2h_req(); }else{ @@ -91,49 +75,34 @@ void WEAK usb_standard_request(){ } break; case REQ_RECIPIENT_INTERFACE: - DBG("REQ_RECIPIENT_INTERFACE"); if(dev2host && setup_packet->bRequest == GET_DESCRIPTOR){ get_descriptor(setup_packet); } break; case REQ_RECIPIENT_ENDPOINT: - DBG("REQ_RECIPIENT_ENDPOINT"); if(setup_packet->bRequest == CLEAR_FEATURE){ - }else{ - DBG("Wrong"); - } + }else{ /* wrong */ } break; default: - DBG("Wrong"); - DBGs(uhex2str(recipient)); break; } if(!dev2host) EP_WriteIRQ(0, NULL, 0); } void WEAK usb_class_request(config_pack_t *req, uint8_t _U_ *data, uint16_t _U_ datalen){ - DBG("REQ_TYPE_CLASS"); switch(req->bRequest){ case GET_INTERFACE: - DBG("GI"); break; case SET_CONFIGURATION: // set featuring by req->wValue - DBG("SC"); break; default: - DBG("Wrong"); - DBGs(uhex2str(req->bmRequestType)); - DBGs(uhex2str(req->bRequest)); - DBGs(uhex2str(req->wIndex)); - DBGs(uhex2str(req->wLength)); - DBGs(uhex2str(req->wValue)); + break; } if(0 == (setup_packet->bmRequestType & 0x80)) // host2dev EP_WriteIRQ(0, NULL, 0); } void WEAK usb_vendor_request(config_pack_t _U_ *packet, uint8_t _U_ *data, uint16_t _U_ datalen){ - DBG("vendor"); if(0 == (setup_packet->bmRequestType & 0x80)) // host2dev EP_WriteIRQ(0, NULL, 0); } @@ -149,18 +118,16 @@ bmRequestType: 76543210 */ static void EP0_Handler(){ uint8_t ep0dbuflen = 0; - uint8_t ep0databuf[EP0DATABUF_SIZE]; + uint8_t ep0databuf[EP0DATABUF_SIZE] __attribute__((aligned(4))); uint16_t epstatus = KEEP_DTOG(USB->EPnR[0]); // EP0R on input -> return this value after modifications int rxflag = RX_FLAG(epstatus); - if(rxflag){ DBG("EP0_Handler"); } // check direction if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack - DBG("USB_EPnR_SETUP"); EP_Read(0, setupdatabuf); // interrupt handler will be called later }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf - if(endpoints[0].rx_cnt){ DBG("data"); DBGs(uhex2str(endpoints[0].rx_cnt));} + //if(endpoints[0].rx_cnt){ } ep0dbuflen = EP_Read(0, ep0databuf); } } @@ -169,23 +136,16 @@ static void EP0_Handler(){ switch(reqtype){ case REQ_TYPE_STANDARD: if(SETUP_FLAG(epstatus)){ - DBG("REQ_TYPE_STANDARD"); usb_standard_request(); - }else{ - DBG("REQ_TYPE_STANDARD without SETUP_FLAG"); - } + }else{ } break; case REQ_TYPE_CLASS: - DBG("REQ_TYPE_CLASS"); usb_class_request(setup_packet, ep0databuf, ep0dbuflen); break; case REQ_TYPE_VENDOR: - DBG("REQ_TYPE_VENDOR"); usb_vendor_request(setup_packet, ep0databuf, ep0dbuflen); break; default: - DBG("Wrong"); - DBGs(uhex2str(reqtype)); EP_WriteIRQ(0, NULL, 0); break; } @@ -195,8 +155,6 @@ static void EP0_Handler(){ if ((USB->DADDR & USB_DADDR_ADD) != USB_Addr){ USB->DADDR = USB_DADDR_EF | USB_Addr; usbON = 0; - DBG("Enum"); - DBGs(uhex2str(USB_Addr)); } } //epstatus = KEEP_DTOG(USB->EPnR[0]); @@ -214,9 +172,14 @@ static void EP0_Handler(){ */ void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){ if(size > endpoints[number].txbufsz) size = endpoints[number].txbufsz; +#ifndef USB32 uint16_t N2 = (size + 1) >> 1; // the buffer is 16-bit, so we should copy data as it would be uint16_t uint16_t *buf16 = (uint16_t *)buf; +#else + int N4 = (size + 3) >> 2; + uint32_t *buf32 = (uint32_t *)buf; +#endif #if defined USB1_16 // very bad: what if `size` is odd? uint32_t *out = (uint32_t *)endpoints[number].tx_buf; @@ -225,13 +188,19 @@ void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){ } #elif defined USB2_16 // use memcpy instead? - for(int i = 0; i < N2; i++){ + for(int i = 0; i < N2; ++i){ endpoints[number].tx_buf[i] = buf16[i]; } +#elif defined USB32 + for(int i = 0; i < N4; ++i) endpoints[number].tx_buf[i] = buf32[i]; #else -#error "Define USB1_16 or USB2_16" +#error "Define USB1_16 / USB2_16 / USB32" #endif +#ifndef USB32 USB_BTABLE->EP[number].USB_COUNT_TX = size; +#else + USB_BTABLE->EP[number].USB_ADDR_COUNT_TX = (USB_BTABLE->EP[number].USB_ADDR_COUNT_TX & 0xffff) | (size << 16); +#endif } /** @@ -266,8 +235,12 @@ int EP_Read(uint8_t number, uint8_t *buf){ // use memcpy instead? for(int i = 0; i < sz; ++i) buf[i] = endpoints[number].rx_buf[i]; +#elif defined USB32 + uint32_t *u32buf = (uint32_t*) buf; + int N4 = (sz + 3) >> 2; + for(int i = 0; i < N4; ++i) u32buf[i] = endpoints[number].rx_buf[i]; #else -#error "Define USB1_16 or USB2_16" +#error "Define USB1_16 / USB2_16 / USB32" #endif return sz; } @@ -284,11 +257,16 @@ static uint16_t lastaddr = LASTADDR_DEFAULT; * @return 0 if all OK */ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(ep_t ep)){ +#ifdef STM32G0 + // in STM32G0 all buffers should be aligned by 32 bits + if(txsz & 3) txsz = ((txsz >> 2)+1) << 2; + if(rxsz & 3) rxsz = ((rxsz >> 2)+1) << 2; +#endif if(number >= STM32ENDPOINTS) return 4; // out of configured amount if(txsz > USB_BTABLE_SIZE/ACCESSZ || rxsz > USB_BTABLE_SIZE/ACCESSZ) return 1; // buffer too large if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA); - USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1; + USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX; if(rxsz & 1) return 3; // wrong rx buffer size uint16_t countrx = 0; if(rxsz < 64) countrx = rxsz / 2; @@ -296,25 +274,49 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*f if(rxsz & 0x1f) return 3; // should be multiple of 32 countrx = 31 + rxsz / 32; } - USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; +#ifdef USB32 + endpoints[number].tx_buf = (uint32_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); +#else endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); +#endif endpoints[number].txbufsz = txsz; - lastaddr += txsz; +#ifdef USB32 + USB_BTABLE->EP[number].USB_ADDR_COUNT_TX = (uint32_t) lastaddr; +#else + USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; USB_BTABLE->EP[number].USB_COUNT_TX = 0; - USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; +#endif + lastaddr += txsz; +#ifdef USB32 + endpoints[number].rx_buf = (uint32_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); + USB_BTABLE->EP[number].USB_ADDR_COUNT_RX = (uint32_t) lastaddr | countrx << 26; +#else endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ); - lastaddr += rxsz; + USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; +#endif + lastaddr += rxsz; endpoints[number].func = func; return 0; } +// refresh EP after interface reconnected +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 void USB_IRQ(){ uint32_t CNTR = USB->CNTR; USB->CNTR = 0; - if(USB->ISTR & USB_ISTR_RESET){ - DBG("USB_ISTR_RESET"); + uint32_t istr = USB->ISTR; + if(istr & USB_ISTR_RESET){ usbON = 0; // Reinit registers CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM; @@ -323,45 +325,56 @@ void USB_IRQ(){ lastaddr = LASTADDR_DEFAULT; // clear address, leave only enable bit USB->DADDR = USB_DADDR_EF; - USB->ISTR = ~USB_ISTR_RESET; + //USB->ISTR = ~(USB_ISTR_RESET); // clear all flags if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0BUFSZ, USB_EP0BUFSZ, EP0_Handler)){ - DBG("Can't init EP0"); return; }; } - if(USB->ISTR & USB_ISTR_CTR){ + if(istr & USB_ISTR_CTR){ // EP number - uint8_t n = USB->ISTR & USB_ISTR_EPID; + uint8_t n = istr & USB_ISTR_EPID; + if (istr & USB_ISTR_DIR){ // OUT + }else{ // IN + } // copy received bytes amount - endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter + endpoints[n].rx_cnt = +#ifdef USB32 + (USB_BTABLE->EP[n].USB_ADDR_COUNT_RX >> 16) & 0x3FF; +#else + USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter +#endif // call EP handler if(endpoints[n].func) endpoints[n].func(); } - if(USB->ISTR & USB_ISTR_WKUP){ // wakeup - DBG("USB_ISTR_WKUP"); -#ifndef STM32F0 - CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE | USB_CNTR_WKUPM); // clear suspend flags -#else + if(istr & USB_ISTR_WKUP){ // wakeup +#if defined STM32F0 CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LPMODE | USB_CNTR_WKUPM); -#endif - USB->ISTR = ~USB_ISTR_WKUP; - } - if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep - DBG("USB_ISTR_SUSP"); - usbON = 0; -#ifndef STM32F0 - CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE | USB_CNTR_WKUPM; +#elif defined STM32G0 + CNTR &= ~(USB_CNTR_SUSPEN | USB_CNTR_PDWN | USB_CNTR_WKUPM); #else + CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE | USB_CNTR_WKUPM); // clear suspend flags +#endif + //USB->ISTR = ~USB_ISTR_WKUP; + } + if(istr & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep + usbON = 0; +#if defined STM32F0 CNTR |= USB_CNTR_FSUSP | USB_CNTR_LPMODE | USB_CNTR_WKUPM; +#elif defined STM32G0 + CNTR |= USB_CNTR_SUSPEN | USB_CNTR_WKUPM; +#else + CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE | USB_CNTR_WKUPM; #endif CNTR &= ~(USB_CNTR_SUSPM); - USB->ISTR = ~USB_ISTR_SUSP; + //USB->ISTR = ~USB_ISTR_SUSP; } + USB->ISTR = 0; // clear all flags USB->CNTR = CNTR; // rewoke interrupts } // here we suppose that all PIN settings done in hw_setup earlier void USB_setup(){ + lastaddr = LASTADDR_DEFAULT; // clear last address settings #if defined STM32F3 NVIC_DisableIRQ(USB_LP_IRQn); // remap USB LP & Wakeup interrupts to 75 and 76 - works only on pure F303 @@ -371,6 +384,7 @@ void USB_setup(){ NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); #elif defined STM32F0 + // All is clocking from HSI48 NVIC_DisableIRQ(USB_IRQn); RCC->APB1ENR |= RCC_APB1ENR_CRSEN; RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB @@ -383,16 +397,33 @@ void USB_setup(){ CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only RCC->CFGR |= RCC_CFGR_SW; +#elif defined STM32G0 + NVIC_DisableIRQ(USB_UCPD1_2_IRQn); + PWR->CR2 |= PWR_CR2_USV; // enable USB powering + //RCC->APBENR2 |= RCC_APBENR2_SYSCFGEN; // enable tacting of SYSCFG + // independent clocking of USB from HSI48 + RCC->CR |= RCC_CR_HSI48ON; + uint32_t tmout = 16000000; + while(!(RCC->CR & RCC_CR_HSI48RDY)) if(--tmout == 0) break; + RCC->CCIPR2 &= ~RCC_CCIPR2_USBSEL; // select HSI48 for USB + RCC->APBENR1 |= RCC_APBENR1_CRSEN; // CRS clocking + CRS->CFGR = (31LL << CRS_CFGR_FELIM_Pos) | // tolerance (usually 31) + (48000LL / 1LL - 1LL) << CRS_CFGR_RELOAD_Pos | // 48MHz / 1kHZ (SOF) + CRS_CFGR_SYNCSRC_1; // USB SOF as sync source (0x2) + CRS->CR |= CRS_CR_AUTOTRIMEN | CRS_CR_CEN; // Enable autotrim and turn on Clock Recovery System + RCC->APBENR1 |= RCC_APBENR1_USBEN; #endif +#ifndef STM32G0 RCC->APB1ENR |= RCC_APB1ENR_USBEN; - //?? USB->CNTR = USB_CNTR_FRES; // Force USB Reset - for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms - USB->CNTR = 0; USB->BTABLE = 0; +#else + USB->CNTR = USB_CNTR_USBRST; +#endif + for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms + USB->CNTR = USB_CNTR_RESETM; // allow only reset interrupts USB->DADDR = 0; USB->ISTR = 0; - USB->CNTR = USB_CNTR_RESETM; // allow only reset interrupts #if defined STM32F3 NVIC_EnableIRQ(USB_LP_IRQn); #elif defined STM32F1 @@ -400,8 +431,11 @@ void USB_setup(){ #elif defined STM32F0 USB->BCDR |= USB_BCDR_DPPU; NVIC_EnableIRQ(USB_IRQn); +#elif defined STM32G0 + USB->BCDR |= USB_BCDR_DPPU; // turn ON DP pullup + NVIC_EnableIRQ(USB_UCPD1_2_IRQn); #endif - setup_interfaces(); + setup_interfaces(); // refresh interfaces' names } @@ -411,4 +445,6 @@ void usb_lp_isr() __attribute__ ((alias ("USB_IRQ"))); void usb_lp_can_rx0_isr() __attribute__ ((alias ("USB_IRQ"))); #elif defined STM32F0 void usb_isr() __attribute__ ((alias ("USB_IRQ"))); +#elif defined STM32G0 +void usb_ucpd1_2_isr() __attribute__ ((alias ("USB_IRQ"))); #endif diff --git a/F1:F103/BISS_C_encoders/usb_lib.h b/F1:F103/BISS_C_encoders/usb_lib.h index c6e70b0..1dfb3a8 100644 --- a/F1:F103/BISS_C_encoders/usb_lib.h +++ b/F1:F103/BISS_C_encoders/usb_lib.h @@ -19,6 +19,10 @@ #include #include +#ifndef _U_ +#define _U_ __attribute__((unused)) +#endif + /****************************************************************** * Hardware registers etc * *****************************************************************/ @@ -30,6 +34,8 @@ #define USB_BASE ((uint32_t)0x40005C00) #elif defined STM32F3 #include +#elif defined STM32G0 +#include #endif // max endpoints number @@ -38,14 +44,16 @@ * Buffers size definition **/ -// F0 - USB2_16; F1 - USB1_16; F3 - 1/2 depending on series -#if !defined USB1_16 && !defined USB2_16 +// F0 - USB2_16; F1 - USB1_16; F3 - 1/2 depending on series; G0 - USB32 +#if !defined USB1_16 && !defined USB2_16 && !defined USB32 #if defined STM32F0 #define USB2_16 #elif defined STM32F1 #define USB1_16 +#elif defined STM32G0 +#define USB32 #else -#error "Can't determine USB1_16 or USB2_16, define by hands" +#error "Can't determine USB1_16/USB2_16/USB32, define by hands" #endif #endif @@ -59,8 +67,8 @@ #if defined STM32F0 #define USB_BTABLE_SIZE 1024 #elif defined STM32F3 -#define USB_BTABLE_SIZE 512 -#warning "Please, check real buffer size due to docs" +#define USB_BTABLE_SIZE 1024 +//#warning "Please, check real buffer size due to docs" #else #error "define STM32F0 or STM32F3" #endif @@ -68,16 +76,21 @@ #if defined STM32F0 #define USB_BTABLE_SIZE 768 #elif defined STM32F3 -#define USB_BTABLE_SIZE 512 -#warning "Please, check real buffer size due to docs" +#define USB_BTABLE_SIZE 768 +#elif defined STM32G0 +#define USB_BTABLE_SIZE 2048 +//#warning "Please, check real buffer size due to docs" #else // STM32F103: 1024 bytes but with 32-bit addressing #define USB_BTABLE_SIZE 1024 #endif #endif // NOCAN // first 64 bytes of USB_BTABLE are registers! - +#ifndef STM32G0 #define USB_BTABLE_BASE 0x40006000 +#else +#define USB_BTABLE_BASE 0x40009800 +#endif #define USB ((USB_TypeDef *) USB_BASE) #ifdef USB_BTABLE @@ -120,8 +133,12 @@ typedef struct { __IO uint32_t ISTR; __IO uint32_t FNR; __IO uint32_t DADDR; +#ifndef USB32 __IO uint32_t BTABLE; -#ifdef STM32F0 +#else + __IO uint32_t RESERVED1; // there's no BTABLE register in STM32G0 +#endif +#if defined STM32F0 || defined USB32 __IO uint32_t LPMCSR; __IO uint32_t BCDR; #endif @@ -135,16 +152,19 @@ typedef struct{ __IO uint16_t USB_ADDR_RX; __IO uint16_t USB_COUNT_RX; #define ACCESSZ (1) -#define BUFTYPE uint8_t #elif defined USB1_16 __IO uint32_t USB_ADDR_TX; __IO uint32_t USB_COUNT_TX; __IO uint32_t USB_ADDR_RX; __IO uint32_t USB_COUNT_RX; #define ACCESSZ (2) -#define BUFTYPE uint16_t +#elif defined USB32 + // 32-bit registers: addr & count in one! + __IO uint32_t USB_ADDR_COUNT_TX; + __IO uint32_t USB_ADDR_COUNT_RX; +#define ACCESSZ (1) #else -#error "Define USB1_16 or USB2_16" +#error "Define USB1_16 (16 bits over 32bit register), USB2_16 (16 bits over 16 bit register) or USB32 (32 bist over 32 bit register)" #endif } USB_EPDATA_TypeDef; @@ -303,9 +323,17 @@ typedef struct { // endpoints state typedef struct{ +#ifdef USB32 + uint32_t *tx_buf; // transmission buffer address +#else uint16_t *tx_buf; // transmission buffer address +#endif uint16_t txbufsz; // transmission buffer size +#ifdef USB32 + uint32_t *rx_buf; // reception buffer address +#else uint8_t *rx_buf; // reception buffer address +#endif void (*func)(); // endpoint action function unsigned rx_cnt : 10; // received data counter } ep_t; @@ -317,6 +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 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/F1:F103/BISS_C_encoders/version.inc b/F1:F103/BISS_C_encoders/version.inc index ebc3fa9..b4b67d4 100644 --- a/F1:F103/BISS_C_encoders/version.inc +++ b/F1:F103/BISS_C_encoders/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "144" -#define BUILD_DATE "2026-02-13" +#define BUILD_NUMBER "147" +#define BUILD_DATE "2026-03-23"