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 eec87c5..00fde62 100755 Binary files a/F303-nolib/PL2303/pl2303.bin and b/F303-nolib/PL2303/pl2303.bin differ 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