From 6c4b2773a8cf2109b2cc0aff1d04d1741c2b841b Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Tue, 15 Feb 2022 21:14:41 +0300 Subject: [PATCH] add ringbuffer to USB F303 (still can't do more than 3.2Mbaud) --- F303-nolib/PL2303/hardware.h | 2 + F303-nolib/PL2303/main.c | 11 ++++ F303-nolib/PL2303/pl2303.bin | Bin 6828 -> 8092 bytes F303-nolib/PL2303/proto.c | 17 ++++++ F303-nolib/PL2303/proto.h | 2 + F303-nolib/PL2303/ringbuffer.c | 86 ++++++++++++++++++++++++++++++ F303-nolib/PL2303/ringbuffer.h | 33 ++++++++++++ F303-nolib/PL2303/usb.c | 94 ++++++++++----------------------- F303-nolib/PL2303/usb.h | 3 ++ F303-nolib/PL2303/usbhw.c | 9 ++-- 10 files changed, 188 insertions(+), 69 deletions(-) create mode 100644 F303-nolib/PL2303/ringbuffer.c create mode 100644 F303-nolib/PL2303/ringbuffer.h diff --git a/F303-nolib/PL2303/hardware.h b/F303-nolib/PL2303/hardware.h index d1888a7..91dfdc5 100644 --- a/F303-nolib/PL2303/hardware.h +++ b/F303-nolib/PL2303/hardware.h @@ -22,6 +22,8 @@ #include +extern volatile uint32_t Tms; + void hw_setup(); #endif // __HARDWARE_H__ diff --git a/F303-nolib/PL2303/main.c b/F303-nolib/PL2303/main.c index b2e5b01..887503d 100644 --- a/F303-nolib/PL2303/main.c +++ b/F303-nolib/PL2303/main.c @@ -23,6 +23,9 @@ #define USBBUFSZ 127 +const char *test = "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789S123456789T123456789U123456789V123456789W123456789X123456789Y\n" + "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789S123456789T123456789U123456789V123456789W123456789X123456789Y\n"; + volatile uint32_t Tms = 0; void sys_tick_handler(void){ @@ -89,5 +92,13 @@ int main(void){ const char *ans = parse_cmd(txt); if(ans) USB_send(ans); } + if(Tlast){ + usart_send("Tlast="); usart_send(u2str(Tlast)); usart_putchar('\n'); + Tlast = 0; + } + if(starttest){ + --starttest; + USB_send(test); + } } } diff --git a/F303-nolib/PL2303/pl2303.bin b/F303-nolib/PL2303/pl2303.bin index eec87c5b85def5bb126a585a10dbf6be2ca93932..00fde62181e435a6226d97f96507245a317847f5 100755 GIT binary patch delta 4071 zcmc&%eNfJ;b1;|f(t;w>zE90B6*0 z7p$l1QIBQUKeW2DTIWuuo~;?}j+}~2MNeDnmQ>worL}QKNnJO+RX##X!k#xkdQSaA z|Jd2Wd2)a6d!Ntu`MvK;US0Eiy$Jh(&D4W>DN5Qk0@r+~4i!30p8@i1n`?c1$5{MU z(C;w#Uit&t@0*zTeHH&Zdi~kg__l}?aKMQl!r6Meb` z-|WXVU-gCT9V}L~6ScR+>1=hnY9*1$Nw13&IX&9o1i2(G9bmpTeW(N${taO`;8ND- z5_paFO(_8LEU6f9FaykK7|9hLBU2x3kw%m&$ZgU&Ws%t7?Qm~&)$tph?kTZyGY>_n z2D!K|YP3Jg>-o9qsyN8KF_5{rHVoAn<2)W`+xqiS&w!^5zxz=FC@+BA9^(a&yJtXN zALCHh9b<9)6C87~MjSWBYH-|v;~Qfd7UYUpwE$wVRT#?~oV+Y9`Jh_(IGSzIE5{lY z6ZT3*W|*wT6H%SzOcX4;kCKDrX^^L9p>$0MWNUnGnu(LWzQFb9dU=dI19DcvZAt=f zolyrsUKTeA)}zm$J(x}eiES(j@F*S0Bt9Qkyez(biUt7FUxWG1<594K{MGDyus1Q- z@gQ}*ZU#z6gCPH7_RUB(2K;2U6l?h^3i6p*TFc2PJs8#hLZHk8^+^VePyzQE3rcYA4`>e)PUF!yr9-KPbmH{2 zynpiK$+rlwgU%EW$yd3-u&-Mkn47K{u^2XYGndl9*8(H2p@wuem3J>kPuVC)pvIRy z4gQzgURiJE!7yhu_%vl!e)l29pBk(PtT&Ngf&6YCb7=U2ynBPKz~nrA{z8_lP_%#t zL}-C$r2%!Wv|p_eU%=7Tze4cJdmA>g?(I)`6Md7x!AwA7R^#KHkGoi3+}K{E3g<*g zA(VmK*Uxab7AT@5Z!&~-japyc_Hy3B|H28zEZ=-|(XA8aQM=LT+vR$|8!zrKD#F)A zNqt^`i0e|L#1;+R=kmL?!fGsLUw0K>=YvwaJlv<_EJlc?)ju3i__r2R4*fZ-jgr;G z2IU|J`q0vp&w*(ow3@f_V6^#c+$-UY7$$D$^6+k&YW6~^Kj>F*Hx)36R85$o&e!1t zgWf03=XM)XVCu>y{Ql}PjKm_;$@!?g|7N#WZcmGssKQxM@|&Sckg*|H!tE+hN6B+o zvm3c*zjenuQRu6}t@Ta(u5e3!4M%=IH(eWl#L>s$rs&^fRAPzEuARnsNwV&GIu{Lr zXfXKd+~gTEU(N69rd6-)U#$8OtolK$y5iHTRhRdpp{X!YwK-9>(Ko*xKrZjsnDFrE z2Tb1hX(>%^@73g9iZg!eprT&EsS=A%>H)RIFZ!?++d2+bPlRY4)wqy!M{(h~>DOb8 z5wh;Ve2t-sH(^tjx28HZ#b8MH=@+_7Lu9(hx;Htqu{exWMRp!WIfQb@3Q!N>GaaQF zG2JYb%4-lmic*FG;_YDnH3GU(Jou!vAnTqBq+wDe9GItQQhTfTV;mUnr4_Nd9dpz6 z_WV zo>onr+=Z;AmCrNcc4w}S_@S&Zc$-I2=Vcj6r3_LBgGiz!nH-c)g-m=UulJoDNA5Re z`ihYIX-W&9_mS7BuNJjI5&NK_QW`)Af*naQ~S`? zd{VDLa#myKF?XELalZe##*`6cTS>jyz=SjDR;=F;poFv`f2Kmz!&~F9Ivg607^olC z%A0v&GYowa(Iqx+T|zrIu@;oRry^#)LgfDz0ptNC&nY}jA4VSdP_z&s}3TL9dF+_G7)_?G#Qu(Um`j5f4 z&TinGO%-@7y%jsqobvH+FKQGi7ex)xBSnT{)WF#E-n^M*a1z9oO)BczLf3}Q!>YGK z!xy4YExI;y^Ul38s6yuq3(lX8or$ays19An{HDVZdX3T6E*6SavrwizM{3nBt<;d- zzKq_Mr&0P)E67L((toG;P${{V?$LjUv%7HiEIt>tf(cFOpGzH*b6L9h1iq#WsyT9< z$LMExDuu;5Pb;O(nN6xjhhf4#_+sYINWp1T zpi1;D_0f<6>JW~1A%0yoSednwq`Zz8E$__Uqd2V`9MAre)KOJB9Yj^&!A{*!lj4P~ z9V`I#XDAaWGRi@e(n3&o6iUl-?nF1zJvleh#~*TTa(#9sjvFNLA26EJ9{5m|K1b1| zrfI+dm*%Vx^0jD>;9=y()6hHMm;G>GY(=*COTX?iM?CboTV#08mkB zty;6Tx~8@vi5yAPm_$uU)SN_I6160eGl^Q0$dyFyBoaMI*p@`=lgOJyHzm=Jl4wH` zwI@+W5^YSPo0I64B)WATiCFO_O>*{sTRhe-F0A_hrFg7eu}LHSQdgO?vE9M;^mg{% z+f#?+259eS*wE2&gY-vTE#qAeQiMJ^PAbfO@|KPgb`{&()ziz~+p~r3>AL6c?e}bB zJK3Lib>GkK=ApUm!@PR)!o+B%U%tjDY+%-;J(h@t-{?qw`nk>G?IJV hY(XB2I7r8z3ZrzF68fYn$)+}H){Jdcg<+|}(hRz>E$fJ8r;S8X7Tij!lXj^dD}hH$?44_p z{Xzd|{+O-bJNKS@&bjyf&bjx#U$ngbl`xzH)0hslXAqH9fK@+gLqXLUd-8do)iJ)H zAO75=U*K?G_T6jlcVXfCHT?hB)s?P_llwo)#LK)tghhYWl-X&Rxc>eFUzm8|FKOlV1kFXkxb2w#vzskFhiv}^hxG4q7bP^Op%7s(?Ik~xWyVn(PbY z-b`*qo6)2L`yTASk!;5PZ;;3;c))Dmf*Cy)?v`R z-^R?ln^=Wq%i1oedWSQ}pCd!$B~Zkq_Z%q6<@921iWP{=dBJuq3d&PSatxFMnXuo> zw4F;(8^e(U%l9Vu$0cVFY*(XR!6kz7cycA;<|Nc!j*?>mP&jmnqRZ~&#RQB)G2;$@ z+6*v)fK(OvfjiM>8q*679@N|x zslE7jM92@Yb9o@YoXzFI_%H^zI5jmTZ_HYu;p zCLS7QLpjmLNT-dw2+Fm7cKG~t<OF_?^U~yfZBIcJ}$Zl$5qh*_E3WFH^}Y zV{=ec6g?}Pog+EfD*5?*>^uI=((axbu>ni0H4XemsXqR=e?Wz!_q5GvCiHY|>uEXCX>3gt<(uTOtcUT2SaSt7>$3>)5Bs3V=Z)5}-gsdaZZW^P~h*Pb^u+bQ} z(46>wV;-lSBiS~wM#Lzl2IOYrU2dAf(%FPi86+lD8p*S|mDl=duiQKT5vD{a zks2{2xtdzB^m4VAarTDI(`@yOo*9)gV zYQZ{qFTAuJ#b4F&&$^C0u=4@`J3(eX{;jgMzl&5ui)2gZtom=LF7T}51Z zCcRWIn#Fu!XTm6D<5->OGuDiG637}xajlBdoS+sPk-dIo;wWMU0XjS^G;llX_ec|^ zN?QTi%wCs@_7u{S;{rm$(`AClSBp+F6O8B4a6YC7y6B=v^q< zpYMKGl-hNe7@81`Kg&nV71ChPy>JA_WE>08O902zGr9mDdTgw`OXv43{HDewGI87x zA``WQV8c=r_~%B5z?ygol(uDRS>P?8mS&Q%#AlQXfpsa$hgc;YX7VFoQqO1k4H7{K zYd}dyddAU}9`dqfP-V5Vr`p{rB}$LH$x}RvkKd0{7gXBD3nr zqgPZYetWKkJ>@BTzr|iPWAZwMgB98xgdP|+z~r9tEX7FUnjL>r;h``ddCy4gdT)AB zPPf=mCGs=JaO*V+A10oSl%oEbG}Y$E-FAyGH14+43F*b3q=$AuZ9KNO@>oB=f@f}1x9ctU2O0T9 z>9*`l1{nEj>7{HvY9|?aq-;l)$HUFTXtM14#5j5Pt>`EXcw;SS-$Gpw+e7T=b6=_< z*+bYy&o|2lm`P^TrTdg@qo!1S4oyJ>Hw{BwsxSV@$gA#AMth?~kk5`1Xkzf%j4t^fc4 diff --git a/F303-nolib/PL2303/proto.c b/F303-nolib/PL2303/proto.c index 2f9fb2f..7292ab8 100644 --- a/F303-nolib/PL2303/proto.c +++ b/F303-nolib/PL2303/proto.c @@ -19,6 +19,9 @@ #include "proto.h" #include "usart.h" #include "usb.h" + +uint8_t starttest = 50; + char *omit_spaces(const char *buf){ while(*buf){ if(*buf > ' ') break; @@ -154,6 +157,8 @@ const char* helpmsg = "'p' - toggle USB pullup\n" "'N' - read number (dec, 0xhex, 0oct, bbin) and show it in decimal\n" "'R' - software reset\n" + "'T' - test usb sending a very large message\n" + "'U' - get USB status\n" "'W' - test watchdog\n" ; @@ -168,6 +173,7 @@ static void add2buf(const char *s){ *bptr = 0; } +extern uint8_t usbON; const char *parse_cmd(const char *buf){ initbuf(); if(buf[1] == '\n' || !buf[1]){ // one symbol commands @@ -190,6 +196,17 @@ const char *parse_cmd(const char *buf){ usart_send("Soft reset\n"); NVIC_SystemReset(); break; + case 'T': + add2buf("STARTT="); + add2buf(u2str(Tms)); add2buf("\n"); + starttest = 10; + break; + case 'U': + add2buf("USB status: "); + if(usbON) add2buf("ON"); + else add2buf("OFF"); + add2buf("\n"); + break; case 'W': USB_send("Wait for reboot\n"); usart_send("Wait for reboot\n"); diff --git a/F303-nolib/PL2303/proto.h b/F303-nolib/PL2303/proto.h index bd7c53d..5cd7734 100644 --- a/F303-nolib/PL2303/proto.h +++ b/F303-nolib/PL2303/proto.h @@ -22,6 +22,8 @@ #include +extern uint8_t starttest; + const char *parse_cmd(const char *buf); char *omit_spaces(const char *buf); char *getnum(const char *buf, uint32_t *N); diff --git a/F303-nolib/PL2303/ringbuffer.c b/F303-nolib/PL2303/ringbuffer.c new file mode 100644 index 0000000..6b292ce --- /dev/null +++ b/F303-nolib/PL2303/ringbuffer.c @@ -0,0 +1,86 @@ +/* + * This file is part of the pl2303 project. + * Copyright 2022 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 "ringbuffer.h" +#include "usb.h" +#include "usb_lib.h" + +// ring buffer +static char ringbuffer[RBSIZE]; +// head - position of first data byte +// tail - position of last data byte + 1 +// head == tail - empty! So, buffer can't store more than RBSIZE-1 bytes of data! +static volatile int head = 0, tail = 0; + +static int datalen(){ + if(tail >= head) return (tail - head); + else return (RBSIZE - head + tail); +} +static int restlen(){ + return (RBSIZE - 1 - datalen()); +} + +TRUE_INLINE void incr(volatile int *what, int n){ + *what += n; + if(*what >= RBSIZE) *what -= RBSIZE; +} + +int RB_read(char s[BLOCKSIZE]){ + int l = datalen(); + if(!l) return 0; + if(l > BLOCKSIZE) l = BLOCKSIZE; + int _1st = RBSIZE - head; + if(_1st > l) _1st = l; + if(_1st > BLOCKSIZE) _1st = BLOCKSIZE; + memcpy(s, ringbuffer+head, _1st); + if(_1st < BLOCKSIZE && l > _1st){ + memcpy(s+_1st, ringbuffer, l-_1st); + incr(&head, l); + return l; + } + incr(&head ,_1st); + return _1st; +} + +static int addportion(const char *str, int l){ + int r = restlen(); + if(l > r) l = r; + if(!l) return 0; + int _1st = RBSIZE - tail; + if(_1st > l) _1st = l; + memcpy(ringbuffer+tail, str, _1st); + if(_1st < l){ // add another piece from start + memcpy(ringbuffer, str+_1st, l-_1st); + } + incr(&tail, l); + return l; +} + +void RB_write(const char *str, int l){ + if(!str || !*str) return; + if(!usbON) return; + while(l){ + send_next(); + int a = addportion(str, l); + l -= a; + str += a; + } +} diff --git a/F303-nolib/PL2303/ringbuffer.h b/F303-nolib/PL2303/ringbuffer.h new file mode 100644 index 0000000..3e8f004 --- /dev/null +++ b/F303-nolib/PL2303/ringbuffer.h @@ -0,0 +1,33 @@ +/* + * This file is part of the pl2303 project. + * Copyright 2022 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 +#ifndef RINGBUFFER_H__ +#define RINGBUFFER_H__ + +#include "usbhw.h" + +// ring buffer size in bytes +#define RBSIZE (512) +// max reading portion size +#define BLOCKSIZE (USB_TXBUFSZ) + +int RB_read(char s[BLOCKSIZE]); +void RB_write(const char *str, int l); + +#endif // RINGBUFFER_H__ diff --git a/F303-nolib/PL2303/usb.c b/F303-nolib/PL2303/usb.c index 28ce4e0..3224ddc 100644 --- a/F303-nolib/PL2303/usb.c +++ b/F303-nolib/PL2303/usb.c @@ -16,17 +16,39 @@ * along with this program. If not, see . */ +#include + +#include "hardware.h" +#include "ringbuffer.h" #include "usb.h" #include "usb_lib.h" +static char usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data static volatile uint8_t tx_succesfull = 1; static volatile uint8_t rxNE = 0; -static int sstrlen(const char *s){ - if(!s) return 0; - int l = 0; - while(*s++) ++l; - return l; +volatile uint32_t Tlast = 0; + +void send_next(){ + static int lastdsz = 0; + if(!tx_succesfull) return; + int buflen = RB_read(usbbuff); + if(!buflen){ + if(lastdsz) Tlast = Tms; + if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send + lastdsz = 0; + return; + } + tx_succesfull = 0; + EP_Write(3, (uint8_t*)usbbuff, buflen); + lastdsz = buflen; +} + +// put `buf` into queue to send +void USB_send(const char *buf){ + int len = strlen(buf); + if(!usbON || !len) return; + RB_write(buf, len); // this is a blocking procedure if there's too little free memory in buffer } // interrupt IN handler (never used?) @@ -45,6 +67,7 @@ static void transmit_Handler(){ // EP3IN uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[3]); // clear CTR keep DTOGs & STATs USB->EPnR[3] = (epstatus & ~(USB_EPnR_CTR_TX)); // clear TX ctr + send_next(); } static void receive_Handler(){ // EP2OUT @@ -53,67 +76,6 @@ static void receive_Handler(){ // EP2OUT USB->EPnR[2] = (epstatus & ~(USB_EPnR_CTR_RX)); // clear RX ctr } -static int usbwr(const char *buf, int l){ - uint32_t ctra = 1000000; - while(--ctra && tx_succesfull == 0){ - IWDG->KR = IWDG_REFRESH; - } - tx_succesfull = 0; - EP_Write(3, (uint8_t*)buf, l); - ctra = 1000000; - while(--ctra && tx_succesfull == 0){ - IWDG->KR = IWDG_REFRESH; - } - if(tx_succesfull == 0){usbON = 0; return 1;} // usb is OFF? - return 0; -} - -static char usbbuff[USB_TXBUFSZ-1]; // temporary buffer (63 - to prevent need of ZLP) -static int buflen = 0; // amount of symbols in usbbuff - -// send next up to 63 bytes of data in usbbuff -static void send_next(){ - if(!buflen || !tx_succesfull) return; - tx_succesfull = 0; - EP_Write(3, (uint8_t*)usbbuff, buflen); - buflen = 0; -} - -// blocking sending -static void USB_send_blk(const char *buf, int len){ - if(!usbON || !len) return; // USB disconnected - if(buflen){ - usbwr(usbbuff, buflen); - buflen = 0; - } - int needzlp = 0; - while(len){ - if(len == USB_TXBUFSZ) needzlp = 1; - int s = (len > USB_TXBUFSZ) ? USB_TXBUFSZ : len; - if(usbwr(buf, s)) return; - len -= s; - buf += s; - } - if(needzlp){ - usbwr(NULL, 0); - } -} - -// unblocking sending - just fill a buffer -void USB_send(const char *buf){ - int len = sstrlen(buf); - if(!usbON || !len) return; - if(len > USB_TXBUFSZ-1 - buflen){ - usbwr(usbbuff, buflen); - buflen = 0; - } - if(len > USB_TXBUFSZ-1){ - USB_send_blk(buf, len); - return; - } - while(len--) usbbuff[buflen++] = *buf++; -} - void usb_proc(){ switch(USB_Dev.USB_Status){ case USB_STATE_CONFIGURED: diff --git a/F303-nolib/PL2303/usb.h b/F303-nolib/PL2303/usb.h index 721b45c..cc697b7 100644 --- a/F303-nolib/PL2303/usb.h +++ b/F303-nolib/PL2303/usb.h @@ -24,7 +24,10 @@ #define BUFFSIZE (64) +extern volatile uint32_t Tlast; + void usb_proc(); +void send_next(); void USB_send(const char *buf); int USB_receive(char *buf); diff --git a/F303-nolib/PL2303/usbhw.c b/F303-nolib/PL2303/usbhw.c index e254e48..0afb321 100644 --- a/F303-nolib/PL2303/usbhw.c +++ b/F303-nolib/PL2303/usbhw.c @@ -27,11 +27,14 @@ void USB_setup(){ // setup pullup RCC->AHBENR |= RCC_AHBENR_GPIOAEN; USBPU_OFF(); - GPIOA->MODER = (GPIOA->MODER & (~GPIO_MODER_MODER15_Msk | GPIO_MODER_MODER11_Msk | GPIO_MODER_MODER12_Msk)) | - GPIO_MODER_MODER11_AF | GPIO_MODER_MODER12_AF | GPIO_MODER_MODER15_O; + //GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER15_Msk | GPIO_MODER_MODER11_Msk | GPIO_MODER_MODER12_Msk)) | + GPIOA->MODER = (GPIOA->MODER & (MODER_CLR(11) & MODER_CLR(12) & MODER_CLR(15))) | + (MODER_AF(11) | MODER_AF(12) | MODER_O(15)); + //(GPIO_MODER_MODER11_AF | GPIO_MODER_MODER12_AF | GPIO_MODER_MODER15_O); // USB - alternate function 14 @ pins PA11/PA12 GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH3_Msk | GPIO_AFRH_AFRH4_Msk)) | - (14 << (3 * 4)) | (14 << (4 * 4)); + //AFR1(14, 11) | AFR1(14, 12); + AFRf(14, 11) | AFRf(14, 12); RCC->APB1ENR |= RCC_APB1ENR_USBEN; USB->CNTR = USB_CNTR_FRES; // Force USB Reset for(uint32_t ctr = 0; ctr < 72000; ++ctr) nop(); // wait >1ms