diff --git a/F3:F303/PL2303/pl2303.creator.user.7bd84e3 b/F3:F303/PL2303/pl2303.creator.user.7bd84e3 new file mode 100644 index 0000000..aa79e75 --- /dev/null +++ b/F3:F303/PL2303/pl2303.creator.user.7bd84e3 @@ -0,0 +1,171 @@ + + + + + + EnvironmentId + {7bd84e39-ca37-46d3-be9d-99ebea85bc0d} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + KOI8-R + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + false + true + *.md, *.MD, Makefile + false + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 2 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} + 0 + 0 + 0 + + /Big/Data/00__Electronics/STM32/F303-nolib/blink + + + + all + + true + GenericProjectManager.GenericMakeStep + + 1 + Сборка + Сборка + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + GenericProjectManager.GenericMakeStep + + 1 + Очистка + Очистка + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Default + GenericProjectManager.GenericBuildConfiguration + + 1 + + + 0 + Развёртывание + Развёртывание + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + 2 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/F3:F303/Seven_CDCs/7CDCs.files b/F3:F303/Seven_CDCs/7CDCs.files index 3d78e2d..a912955 100644 --- a/F3:F303/Seven_CDCs/7CDCs.files +++ b/F3:F303/Seven_CDCs/7CDCs.files @@ -1,10 +1,13 @@ cmdproto.c cmdproto.h +debug.h hardware.c hardware.h main.c ringbuffer.c ringbuffer.h +strfunc.c +strfunc.h usart.c usart.h usb.c diff --git a/F3:F303/Seven_CDCs/cmdproto.c b/F3:F303/Seven_CDCs/cmdproto.c index bcd5aba..72387cc 100644 --- a/F3:F303/Seven_CDCs/cmdproto.c +++ b/F3:F303/Seven_CDCs/cmdproto.c @@ -1,6 +1,6 @@ /* * This file is part of the SevenCDCs project. - * Copyright 2022 Edward V. Emelianov . + * Copyright 202 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +17,8 @@ */ #include "cmdproto.h" +#include "debug.h" +#include "strfunc.h" #include "usb.h" #include "version.inc" @@ -24,136 +26,7 @@ #define SENDN(str) do{USB_sendstr(CMD_IDX, str); USB_putbyte(CMD_IDX, '\n');}while(0) extern volatile uint32_t Tms; - -char *omit_spaces(const char *buf){ - while(*buf){ - if(*buf > ' ') break; - ++buf; - } - return (char*)buf; -} - -// In case of overflow return `buf` and N==0xffffffff -// read decimal number & return pointer to next non-number symbol -static char *getdec(const char *buf, uint32_t *N){ - char *start = (char*)buf; - uint32_t num = 0; - while(*buf){ - char c = *buf; - if(c < '0' || c > '9'){ - break; - } - if(num > 429496729 || (num == 429496729 && c > '5')){ // overflow - *N = 0xffffff; - return start; - } - num *= 10; - num += c - '0'; - ++buf; - } - *N = num; - return (char*)buf; -} -// read hexadecimal number (without 0x prefix!) -static char *gethex(const char *buf, uint32_t *N){ - char *start = (char*)buf; - uint32_t num = 0; - while(*buf){ - char c = *buf; - uint8_t M = 0; - if(c >= '0' && c <= '9'){ - M = '0'; - }else if(c >= 'A' && c <= 'F'){ - M = 'A' - 10; - }else if(c >= 'a' && c <= 'f'){ - M = 'a' - 10; - } - if(M){ - if(num & 0xf0000000){ // overflow - *N = 0xffffff; - return start; - } - num <<= 4; - num += c - M; - }else{ - break; - } - ++buf; - } - *N = num; - return (char*)buf; -} -// read octal number (without 0 prefix!) -static char *getoct(const char *buf, uint32_t *N){ - char *start = (char*)buf; - uint32_t num = 0; - while(*buf){ - char c = *buf; - if(c < '0' || c > '7'){ - break; - } - if(num & 0xe0000000){ // overflow - *N = 0xffffff; - return start; - } - num <<= 3; - num += c - '0'; - ++buf; - } - *N = num; - return (char*)buf; -} -// read binary number (without b prefix!) -static char *getbin(const char *buf, uint32_t *N){ - char *start = (char*)buf; - uint32_t num = 0; - while(*buf){ - char c = *buf; - if(c < '0' || c > '1'){ - break; - } - if(num & 0x80000000){ // overflow - *N = 0xffffff; - return start; - } - num <<= 1; - if(c == '1') num |= 1; - ++buf; - } - *N = num; - return (char*)buf; -} - -/** - * @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111) - * @param buf - buffer with number and so on - * @param N - the number read - * @return pointer to first non-number symbol in buf - * (if it is == buf, there's no number or if *N==0xffffffff there was overflow) - */ -char *getnum(const char *txt, uint32_t *N){ - char *nxt = NULL; - char *s = omit_spaces(txt); - if(*s == '0'){ // hex, oct or 0 - if(s[1] == 'x' || s[1] == 'X'){ // hex - nxt = gethex(s+2, N); - if(nxt == s+2) nxt = (char*)txt; - }else if(s[1] > '0'-1 && s[1] < '8'){ // oct - nxt = getoct(s+1, N); - if(nxt == s+1) nxt = (char*)txt; - }else{ // 0 - nxt = s+1; - *N = 0; - } - }else if(*s == 'b' || *s == 'B'){ - nxt = getbin(s+1, N); - if(nxt == s+1) nxt = (char*)txt; - }else{ - nxt = getdec(s, N); - if(nxt == s) nxt = (char*)txt; - } - return nxt; -} +extern uint8_t usbON; const char* helpmsg = "https://github.com/eddyem/stm32samples/tree/master/F3:F303/PL2303 build#" BUILD_NUMBER " @ " BUILD_DATE "\n" @@ -164,16 +37,14 @@ const char* helpmsg = "'W' - test watchdog\n" ; - -extern uint8_t usbON; void parse_cmd(const char *buf){ if(buf[1] == '\n' || !buf[1]){ // one symbol commands switch(*buf){ case 'i': SEND("USB->ISTR="); - SEND(u2hexstr(USB->ISTR)); + SEND(uhex2str(USB->ISTR)); SEND(", USB->CNTR="); - SENDN(u2hexstr(USB->CNTR)); + SENDN(uhex2str(USB->CNTR)); break; case 'R': SENDN("Soft reset"); @@ -196,7 +67,7 @@ void parse_cmd(const char *buf){ return; } uint32_t Num = 0; - char *nxt; + const char *nxt; switch(*buf){ // long messages case 'N': ++buf; @@ -217,41 +88,3 @@ void parse_cmd(const char *buf){ return; } } - - -// return string with number `val` -char *u2str(uint32_t val){ - static char strbuf[11]; - char *bufptr = &strbuf[10]; - *bufptr = 0; - if(!val){ - *(--bufptr) = '0'; - }else{ - while(val){ - *(--bufptr) = val % 10 + '0'; - val /= 10; - } - } - return bufptr; -} - -char *u2hexstr(uint32_t val){ - static char strbuf[11] = "0x"; - char *sptr = strbuf + 2; - uint8_t *ptr = (uint8_t*)&val + 3; - int8_t i, j, z=1; - for(i = 0; i < 4; ++i, --ptr){ - if(*ptr == 0){ // omit leading zeros - if(i == 3) z = 0; - if(z) continue; - } - else z = 0; - for(j = 1; j > -1; --j){ - uint8_t half = (*ptr >> (4*j)) & 0x0f; - if(half < 10) *sptr++ = half + '0'; - else *sptr++ = half - 10 + 'a'; - } - } - *sptr = 0; - return strbuf; -} diff --git a/F3:F303/Seven_CDCs/cmdproto.h b/F3:F303/Seven_CDCs/cmdproto.h index f41a242..c58ffad 100644 --- a/F3:F303/Seven_CDCs/cmdproto.h +++ b/F3:F303/Seven_CDCs/cmdproto.h @@ -1,6 +1,6 @@ /* * This file is part of the SevenCDCs project. - * Copyright 2022 Edward V. Emelianov . + * Copyright 2023 Edward V. Emelianov . * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,17 +17,7 @@ */ #pragma once -#ifndef PROTO_H__ -#define PROTO_H__ #include -extern uint8_t starttest; - void parse_cmd(const char *buf); -char *omit_spaces(const char *buf); -char *getnum(const char *buf, uint32_t *N); -char *u2str(uint32_t val); -char *u2hexstr(uint32_t val); - -#endif // PROTO_H__ diff --git a/F3:F303/Seven_CDCs/debug.h b/F3:F303/Seven_CDCs/debug.h new file mode 100644 index 0000000..793ff6b --- /dev/null +++ b/F3:F303/Seven_CDCs/debug.h @@ -0,0 +1,34 @@ +/* + * This file is part of the 7CDCs project. + * Copyright 2023 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "usb.h" + +#ifdef EBUG +#define DBG(str) do{USB_sendstr(DBG_IDX, __FILE__ " (L" STR(__LINE__) "): " str); newline(DBG_IDX);}while(0) +#define DBGmesg(str) do{USB_sendstr(DBG_IDX, str);}while(0) +#define DBGnl() newline(DBG_IDX) +#else +#define DBG(str) +#define DBGmesg(str) +#define DBGnl() +#endif + +#define MSG(str) do{USB_sendstr(DBG_IDX, str); newline(DBG_IDX);}while(0) + diff --git a/F3:F303/Seven_CDCs/main.c b/F3:F303/Seven_CDCs/main.c index e9bdfb4..3cf3ff1 100644 --- a/F3:F303/Seven_CDCs/main.c +++ b/F3:F303/Seven_CDCs/main.c @@ -16,8 +16,9 @@ * along with this program. If not, see . */ -#include "hardware.h" #include "cmdproto.h" +#include "debug.h" +#include "hardware.h" #include "usart.h" #include "usb.h" @@ -48,11 +49,14 @@ int main(void){ if(Tms - ctr > 499){ ctr = Tms; pin_toggle(GPIOB, 1 << 1 | 1 << 0); // toggle LED @ PB0 + //DBG("blink\n"); } 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){ parse_cmd(inbuff); } + l = USB_receivestr(DBG_IDX, inbuff, MAXSTRLEN); + if(l) USB_sendstr(DBG_IDX, inbuff); // just echo back all from USB-DBG interface } } diff --git a/F3:F303/Seven_CDCs/sevenCDCs.bin b/F3:F303/Seven_CDCs/sevenCDCs.bin index d2324ac..202f361 100755 Binary files a/F3:F303/Seven_CDCs/sevenCDCs.bin and b/F3:F303/Seven_CDCs/sevenCDCs.bin differ diff --git a/F3:F303/Seven_CDCs/strfunc.c b/F3:F303/Seven_CDCs/strfunc.c new file mode 100644 index 0000000..d599669 --- /dev/null +++ b/F3:F303/Seven_CDCs/strfunc.c @@ -0,0 +1,343 @@ +/* + * This file is part of the 7CDCs project. + * Copyright 2023 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +/** + * @brief hexdump - dump hex array by 16 bytes in string + * @param sendfun - function to send data + * @param arr - array to dump + * @param len - length of `arr` + */ +void hexdump(int (*sendfun)(const char *s), 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){ + register uint8_t half = (*arr >> (4*j)) & 0x0f; + if(half < 10) *bptr++ = half + '0'; + else *bptr++ = half - 10 + 'a'; + } + if(l % 16 == 15){ + *bptr++ = '\n'; + *bptr = 0; + sendfun(buf); + bptr = buf; + }else *bptr++ = ' '; + } + if(bptr != buf){ + *bptr++ = '\n'; + *bptr = 0; + sendfun(buf); + } +} + +/** + * @brief _2str - convert value into string buffer + * @param val - |value| + * @param minus - ==0 if value > 0 + * @return buffer with number + */ +static char *_2str(uint32_t val, uint8_t minus){ + static char strbuf[12]; + char *bufptr = &strbuf[11]; + *bufptr = 0; + if(!val){ + *(--bufptr) = '0'; + }else{ + while(val){ + uint32_t x = val / 10; + *(--bufptr) = (val - 10*x) + '0'; + val = x; + //*(--bufptr) = val % 10 + '0'; + //val /= 10; + } + } + if(minus) *(--bufptr) = '-'; + return bufptr; +} + +// return string with number `val` +char *u2str(uint32_t val){ + return _2str(val, 0); +} +char *i2str(int32_t i){ + uint8_t minus = 0; + uint32_t val; + if(i < 0){ + minus = 1; + val = -i; + }else val = i; + return _2str(val, minus); +} + +/** + * @brief uhex2str - print 32bit unsigned int as hex + * @param val - value + * @return string with number + */ +char *uhex2str(uint32_t val){ + static char buf[12] = "0x"; + int npos = 2; + uint8_t *ptr = (uint8_t*)&val + 3; + int8_t i, j, z=1; + for(i = 0; i < 4; ++i, --ptr){ + if(*ptr == 0){ // omit leading zeros + if(i == 3) z = 0; + if(z) continue; + } + else z = 0; + for(j = 1; j > -1; --j){ + uint8_t half = (*ptr >> (4*j)) & 0x0f; + if(half < 10) buf[npos++] = half + '0'; + else buf[npos++] = half - 10 + 'a'; + } + } + buf[npos] = 0; + return buf; +} + +/** + * @brief omit_spaces - eliminate leading spaces and other trash in string + * @param buf - string + * @return - pointer to first character in `buf` > ' ' + */ +const char *omit_spaces(const char *buf){ + while(*buf){ + if(*buf > ' ') break; + ++buf; + } + return buf; +} + +/** + * @brief getdec - read decimal number & return pointer to next non-number symbol + * @param buf - string + * @param N - number read + * @return Next non-number symbol. In case of overflow return `buf` and N==0xffffffff + */ +static const char *getdec(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '9'){ + break; + } + if(num > 429496729 || (num == 429496729 && c > '5')){ // overflow + *N = 0xffffff; + return start; + } + num *= 10; + num += c - '0'; + ++buf; + } + *N = num; + return buf; +} +// read hexadecimal number (without 0x prefix!) +static const char *gethex(const char *buf, uint32_t *N){ + const char *start = buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + uint8_t M = 0; + if(c >= '0' && c <= '9'){ + M = '0'; + }else if(c >= 'A' && c <= 'F'){ + M = 'A' - 10; + }else if(c >= 'a' && c <= 'f'){ + M = 'a' - 10; + } + if(M){ + if(num & 0xf0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 4; + num += c - M; + }else{ + break; + } + ++buf; + } + *N = num; + return buf; +} +// read octal number (without 0 prefix!) +static const char *getoct(const char *buf, uint32_t *N){ + const char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '7'){ + break; + } + if(num & 0xe0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 3; + num += c - '0'; + ++buf; + } + *N = num; + return buf; +} +// read binary number (without b prefix!) +static const char *getbin(const char *buf, uint32_t *N){ + const char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '1'){ + break; + } + if(num & 0x80000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 1; + if(c == '1') num |= 1; + ++buf; + } + *N = num; + return buf; +} + +/** + * @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111) + * @param buf - buffer with number and so on + * @param N - the number read + * @return pointer to first non-number symbol in buf + * (if it is == buf, there's no number or if *N==0xffffffff there was overflow) + */ +const char *getnum(const char *txt, uint32_t *N){ + const char *nxt = NULL; + const char *s = omit_spaces(txt); + if(*s == '0'){ // hex, oct or 0 + if(s[1] == 'x' || s[1] == 'X'){ // hex + nxt = gethex(s+2, N); + if(nxt == s+2) nxt = (char*)txt; + }else if(s[1] > '0'-1 && s[1] < '8'){ // oct + nxt = getoct(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ // 0 + nxt = s+1; + *N = 0; + } + }else if(*s == 'b' || *s == 'B'){ + nxt = getbin(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ + nxt = getdec(s, N); + if(nxt == s) nxt = (char*)txt; + } + return nxt; +} + +// get signed integer +const char *getint(const char *txt, int32_t *I){ + const char *s = omit_spaces(txt); + int32_t sign = 1; + uint32_t U; + if(*s == '-'){ + sign = -1; + ++s; + } + const char *nxt = getnum(s, &U); + if(nxt == s) return txt; + if(U & 0x80000000) return txt; // overfull + *I = sign * (int32_t)U; + return nxt; +} + +/* +void mymemcpy(char *dest, const char *src, int len){ + if(len < 1) return; + while(len--) *dest++ = *src++; +} +*/ + +// be careful: if pow10 would be bigger you should change str[] size! +static const float pwr10[] = {1.f, 10.f, 100.f, 1000.f, 10000.f}; +static const float rounds[] = {0.5f, 0.05f, 0.005f, 0.0005f, 0.00005f}; +#define P10L (sizeof(pwr10)/sizeof(uint32_t) - 1) +char * float2str(float x, uint8_t prec){ + static char str[16] = {0}; // -117.5494E-36\0 - 14 symbols max! + if(prec > P10L) prec = P10L; + if(isnan(x)){ memcpy(str, "NAN", 4); return str;} + else{ + int i = isinf(x); + if(i){memcpy(str, "-INF", 5); if(i == 1) return str+1; else return str;} + } + char *s = str + 14; // go to end of buffer + uint8_t minus = 0; + if(x < 0){ + x = -x; + minus = 1; + } + int pow = 0; // xxxEpow + // now convert float to 1.xxxE3y + while(x > 1000.f){ + x /= 1000.f; + pow += 3; + } + if(x > 0.) while(x < 1.){ + x *= 1000.f; + pow -= 3; + } + // print Eyy + if(pow){ + uint8_t m = 0; + if(pow < 0){pow = -pow; m = 1;} + while(pow){ + register int p10 = pow/10; + *s-- = '0' + (pow - 10*p10); + pow = p10; + } + if(m) *s-- = '-'; + *s-- = 'E'; + } + // now our number is in [1, 1000] + uint32_t units; + if(prec){ + units = (uint32_t) x; + uint32_t decimals = (uint32_t)((x-units+rounds[prec])*pwr10[prec]); + // print decimals + while(prec){ + register int d10 = decimals / 10; + *s-- = '0' + (decimals - 10*d10); + decimals = d10; + --prec; + } + // decimal point + *s-- = '.'; + }else{ // without decimal part + units = (uint32_t) (x + 0.5); + } + // print main units + if(units == 0) *s-- = '0'; + else while(units){ + register uint32_t u10 = units / 10; + *s-- = '0' + (units - 10*u10); + units = u10; + } + if(minus) *s-- = '-'; + return s+1; +} diff --git a/F3:F303/Seven_CDCs/strfunc.h b/F3:F303/Seven_CDCs/strfunc.h new file mode 100644 index 0000000..a63ac4b --- /dev/null +++ b/F3:F303/Seven_CDCs/strfunc.h @@ -0,0 +1,32 @@ +/* + * This file is part of the 7CDCs project. + * Copyright 2023 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +void hexdump(int (*sendfun)(const char *s), uint8_t *arr, uint16_t len); +const char *u2str(uint32_t val); +const char *i2str(int32_t i); +const char *uhex2str(uint32_t val); +const char *getnum(const char *txt, uint32_t *N); +const char *omit_spaces(const char *buf); +const char *getint(const char *txt, int32_t *I); +//void mymemcpy(char *dest, const char *src, int len); +char * float2str(float x, uint8_t prec); diff --git a/F3:F303/Seven_CDCs/usart.c b/F3:F303/Seven_CDCs/usart.c index 1da5114..447290a 100644 --- a/F3:F303/Seven_CDCs/usart.c +++ b/F3:F303/Seven_CDCs/usart.c @@ -30,17 +30,18 @@ volatile int linerdy = 0, // received data ready dlen = 0, // length of data (including '\n') in current buffer bufovr = 0; // input buffer overfull // USARTs speeds -static int speeds[USARTSNO+1] = {0}; +static usb_LineCoding lineCodings[USARTSNO+1] = { + {115200, USB_CDC_1_STOP_BITS, USB_CDC_NO_PARITY, 8}, {0}}; -usb_LineCoding *getLineCoding(int usartNo){ - static usb_LineCoding lineCoding; // `static` - to return pointer to it - if(usartNo < 1 || usartNo > USARTSNO) return NULL; -// TODO: fixme - lineCoding.dwDTERate = speeds[usartNo]; - lineCoding.bCharFormat = USB_CDC_1_STOP_BITS; - lineCoding.bParityType = USB_CDC_NO_PARITY; - lineCoding.bDataBits = 8; - return &lineCoding; +usb_LineCoding *getLineCoding(int ifNo){ + int usartNo = ifNo - USART1_EPNO + 1; + if(usartNo < 1 || usartNo > USARTSNO) return lineCodings; + return & lineCodings[usartNo]; +// TODO: fixme for different settings + //lineCoding.dwDTERate = speeds[usartNo]; + //lineCoding.bCharFormat = USB_CDC_1_STOP_BITS; + //lineCoding.bParityType = USB_CDC_NO_PARITY; + //lineCoding.bDataBits = 8; } void usart_putchar(uint8_t ch){ @@ -64,9 +65,11 @@ void usarts_setup(){ NVIC_EnableIRQ(USART3_IRQn); } -void usart_config(uint8_t usartNo, usb_LineCoding *lc){ - if(!usartNo || usartNo > USARTSNO) return; - speeds[usartNo] = lc->dwDTERate; +void usart_config(uint8_t ifNo, usb_LineCoding *lc){ + int usartNo = ifNo - USART1_EPNO + 1; + if(usartNo < 1 || usartNo > USARTSNO) return; + lineCodings[usartNo] = *lc; + // FIXME: change also parity and so on volatile USART_TypeDef *U = USARTx[usartNo]; U->ICR = 0xffffffff; // clear all flags U->BRR = SysFreq / lc->dwDTERate; diff --git a/F3:F303/Seven_CDCs/usart.h b/F3:F303/Seven_CDCs/usart.h index 64bacfd..2d40ee7 100644 --- a/F3:F303/Seven_CDCs/usart.h +++ b/F3:F303/Seven_CDCs/usart.h @@ -29,8 +29,8 @@ extern volatile int linerdy, bufovr; void usarts_setup(); -void usart_config(uint8_t usartNo, usb_LineCoding *lc); +void usart_config(uint8_t ifNo, usb_LineCoding *lc); void usart_sendn(const uint8_t *str, int L); -usb_LineCoding *getLineCoding(int usartNo); +usb_LineCoding *getLineCoding(int ifNo); #endif // __USART_H__ diff --git a/F3:F303/Seven_CDCs/usb.c b/F3:F303/Seven_CDCs/usb.c index a2bae45..04edb91 100644 --- a/F3:F303/Seven_CDCs/usb.c +++ b/F3:F303/Seven_CDCs/usb.c @@ -30,7 +30,7 @@ volatile ringbuffer rbout[WORK_EPs] = {OBUF(0), OBUF(1), OBUF(2), OBUF(3), OBUF( #define IBUF(N) {.data = ibuf[N], .length = RBOUTSZ, .head = 0, .tail = 0} volatile ringbuffer rbin[WORK_EPs] = {IBUF(0), IBUF(1), IBUF(2), IBUF(3), IBUF(4), IBUF(5), IBUF(6)}; // transmission is succesfull -volatile uint8_t bufisempty[WORK_EPs] = {1,1,1,1,1,1}; +volatile uint8_t bufisempty[WORK_EPs] = {1,1,1,1,1,1,1}; volatile uint8_t bufovrfl[WORK_EPs] = {0}; // here and later: ifNo is index of buffers, i.e. ifNo = epno-1 !!! @@ -39,12 +39,12 @@ void send_next(int ifNo){ static int lastdsz = 0; int buflen = RB_read((ringbuffer*)&rbout[ifNo], (uint8_t*)usbbuff, USB_TRBUFSZ); if(!buflen){ - if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send + if(lastdsz == 64) EP_Write(ifNo+1, NULL, 0); // send ZLP after 64 bits packet when nothing more to send lastdsz = 0; bufisempty[ifNo] = 1; return; } - EP_Write(3, (uint8_t*)usbbuff, buflen); + EP_Write(ifNo+1, (uint8_t*)usbbuff, buflen); lastdsz = buflen; } @@ -59,8 +59,10 @@ int USB_sendall(int ifNo){ // put `buf` into queue to send int USB_send(int ifNo, const uint8_t *buf, int len){ if(!buf || !usbON || !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 len -= a; buf += a; if(bufisempty[ifNo]){ @@ -126,4 +128,3 @@ int USB_receivestr(int ifNo, char *buf, int len){ } return l; } - diff --git a/F3:F303/Seven_CDCs/usb.h b/F3:F303/Seven_CDCs/usb.h index af1d699..1daba82 100644 --- a/F3:F303/Seven_CDCs/usb.h +++ b/F3:F303/Seven_CDCs/usb.h @@ -31,12 +31,6 @@ #define STR_HELPER(s) #s #define STR(s) STR_HELPER(s) -#ifdef EBUG -#define DBG(str) do{USB_sendstr(__FILE__ " (L" STR(__LINE__) "): " str); newline();}while(0) -#else -#define DBG(str) -#endif - // total amount of working EPs #define WORK_EPs 7 // functional EPs @@ -45,10 +39,12 @@ #define USART2_EPNO 3 #define USART3_EPNO 4 #define CAN_EPNO 6 +#define DBG_EPNO 7 #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) extern volatile ringbuffer rbout[], rbin[]; extern volatile uint8_t bufisempty[], bufovrfl[]; diff --git a/F3:F303/Seven_CDCs/usb_lib.c b/F3:F303/Seven_CDCs/usb_lib.c index ee41396..48756b7 100644 --- a/F3:F303/Seven_CDCs/usb_lib.c +++ b/F3:F303/Seven_CDCs/usb_lib.c @@ -17,6 +17,10 @@ */ #include +#include "debug.h" +#ifdef EBUG +#include "strfunc.h" +#endif #include "usart.h" #include "usb.h" #include "usb_lib.h" @@ -48,8 +52,8 @@ static const uint8_t USB_DeviceDescriptor[] = { bDeviceSubClass, // bDeviceSubClass bDeviceProtocol, // bDeviceProtocol USB_EP0_BUFSZ, // bMaxPacketSize - // 0483:5740 (VID:PID) - stm32 VCP - 0x83, 0x04, 0x40, 0x57, + // 0483:5740 (VID:PID) - stm32 VCP + 0x83, 0x04, 0x40, 0x57, 0x00, // bcdDevice_Ver_L 0x02, // bcdDevice_Ver_H iMANUFACTURER_DESCR, // iManufacturer @@ -768,6 +772,8 @@ 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(); if(RX_FLAG(epstatus)){ uint8_t sz = EP_Read(epno, (uint8_t*)buf); if(sz){ @@ -793,6 +799,7 @@ 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; @@ -814,6 +821,8 @@ void EP0_Handler(uint8_t __attribute__((unused)) epno){ uint8_t dev2host = (setup_packet->bmRequestType & 0x80) ? 1 : 0; int rxflag = RX_FLAG(epstatus); usb_LineCoding *lc; + // calculate iFno (EP number minus 1) by setup_packet->wIndex (bInterfaceNumber): iFno = wIndex >> 1 + int iFno = setup_packet->wIndex >> 1; if(rxflag && SETUP_FLAG(epstatus)){ switch(reqtype){ case STANDARD_DEVICE_REQUEST_TYPE: // standard device request @@ -832,17 +841,20 @@ void EP0_Handler(uint8_t __attribute__((unused)) epno){ case CONTROL_REQUEST_TYPE: switch(setup_packet->bRequest){ case GET_LINE_CODING: - lc = getLineCoding(1); // TODO: HOW can we change number of interface??? + DBG("GET_LINE_CODING from"); DBGmesg(u2str(iFno)); DBGnl(); + 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 break; case SET_CONTROL_LINE_STATE: - clstate_handler(1, setup_packet->wValue); // TODO: how can we check iface number??? + DBG("SET_CONTROL_LINE_STATE from"); DBGmesg(u2str(iFno)); DBGnl(); + clstate_handler(iFno, setup_packet->wValue); break; case SEND_BREAK: - break_handler(1); // TODO: how can we check iface number??? + DBG("SEND_BREAK from"); DBGmesg(u2str(iFno)); DBGnl(); + break_handler(iFno); break; default: break; @@ -855,8 +867,8 @@ 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){ - // TODO: how can we check iface number??? - linecoding_handler(1, (usb_LineCoding*)ep0databuf); + DBG("SET_LINE_CODING from"); DBGmesg(u2str(iFno)); DBGnl(); + linecoding_handler(iFno, (usb_LineCoding*)ep0databuf); } } } else if(TX_FLAG(epstatus)){ // package transmitted diff --git a/F3:F303/Seven_CDCs/usb_lib.h b/F3:F303/Seven_CDCs/usb_lib.h index 3bead86..e0cd1c2 100644 --- a/F3:F303/Seven_CDCs/usb_lib.h +++ b/F3:F303/Seven_CDCs/usb_lib.h @@ -98,16 +98,6 @@ enum{ #define LANG_US (uint16_t)0x0409 -#if 0 -typedef struct{ - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t *bString; -} string_descriptor_t; - -#define _USB_STRING_(name, str) string_descriptor_t name = {(sizeof(str) + 2), STRING_DESCRIPTOR, str} -#endif - #define _USB_STRING_(name, str) \ static const struct name \ { \ @@ -162,14 +152,6 @@ typedef struct { uint8_t bDataBits; } __attribute__ ((packed)) usb_LineCoding; -typedef struct { - uint8_t bmRequestType; - uint8_t bNotificationType; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} __attribute__ ((packed)) usb_cdc_notification; - extern ep_t endpoints[]; extern volatile uint8_t usbON; extern config_pack_t *setup_packet; diff --git a/F3:F303/Seven_CDCs/usbhw.c b/F3:F303/Seven_CDCs/usbhw.c index 3414927..d00efb8 100644 --- a/F3:F303/Seven_CDCs/usbhw.c +++ b/F3:F303/Seven_CDCs/usbhw.c @@ -118,6 +118,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; } } diff --git a/F3:F303/Seven_CDCs/version.inc b/F3:F303/Seven_CDCs/version.inc index bb6dca5..70e8760 100644 --- a/F3:F303/Seven_CDCs/version.inc +++ b/F3:F303/Seven_CDCs/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "47" -#define BUILD_DATE "2023-04-18" +#define BUILD_NUMBER "56" +#define BUILD_DATE "2023-04-23"