mirror of
https://github.com/eddyem/stm32samples.git
synced 2026-02-28 03:44:30 +03:00
Seems like all U[S]ARTs works well. Tested on speeds up to 2Mbaud (as CH340 can).
This commit is contained in:
@@ -50,13 +50,18 @@ void debug_newline_only(){
|
||||
RB_write(&dbgrb, (const uint8_t*)&nl, 1);
|
||||
}
|
||||
|
||||
// print by lines until there's place in USB ringbuffer
|
||||
void print_debug_messages(){
|
||||
if(!Config_mode) return;
|
||||
uint8_t rcvbuf[256];
|
||||
do{
|
||||
int n = RB_readto(&dbgrb, '\n', rcvbuf, 256);
|
||||
if(n == 0) break;
|
||||
else if(n < 0) n = -n; // partial string: longer than 256 bytes
|
||||
int l = RB_datalento(&dbgrb, '\n');
|
||||
if(l < 1) break;
|
||||
int freesize = USB_sendbufspace(ICFG);
|
||||
if(freesize < l) break;
|
||||
if(l > 256) l = 256;
|
||||
int n = RB_read(&dbgrb, rcvbuf, l);
|
||||
if(n < 1) break; // empty or busy
|
||||
USB_send(ICFG, rcvbuf, n);
|
||||
}while(1);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#else
|
||||
#define DBG(str)
|
||||
#define DBGs(str)
|
||||
#define DBGch(ch)
|
||||
#define DBGn()
|
||||
#define DBGpri()
|
||||
#endif
|
||||
|
||||
@@ -45,8 +45,8 @@ int main(void){
|
||||
USBPU_OFF();
|
||||
USB_setup();
|
||||
//uint32_t ctr = Tms;
|
||||
usb_LineCoding lc = {9600, 0, 0, 8};
|
||||
for(int i = 0; i < 5; ++i) usart_config(i, &lc); // configure all U[S]ARTs for default data
|
||||
//usb_LineCoding lc = {9600, 0, 0, 8};
|
||||
//for(int i = 0; i < 5; ++i) usart_config(i, &lc); // configure all U[S]ARTs for default data
|
||||
USBPU_ON();
|
||||
while(1){
|
||||
// Put here code working WITOUT USB connected
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 18.0.2, 2026-02-16T23:57:09. -->
|
||||
<!-- Written by QtCreator 18.0.2, 2026-02-17T23:35:31. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
||||
@@ -95,8 +95,7 @@ static const char* erpg(const char *str){
|
||||
static void sendoverU(uint8_t ifno, char *str){
|
||||
int len = strlen(str);
|
||||
CFGWR("try to send "); CFGWRn(str);
|
||||
str[len] = '\n';
|
||||
len = usart_send(ifno, (const uint8_t*)str, len+1);
|
||||
len = usart_send(ifno, (const uint8_t*)str, len);
|
||||
CFGWR("sent "); CFGWR(i2str(len)); CFGWR("bytes\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ringbuffer.h"
|
||||
|
||||
static int datalen(ringbuffer *b){
|
||||
@@ -24,7 +26,7 @@ static int datalen(ringbuffer *b){
|
||||
|
||||
// stored data length
|
||||
int RB_datalen(ringbuffer *b){
|
||||
if(b->busy) return -1;
|
||||
if(!b || b->busy) return -1;
|
||||
b->busy = 1;
|
||||
int l = datalen(b);
|
||||
b->busy = 0;
|
||||
@@ -32,7 +34,7 @@ int RB_datalen(ringbuffer *b){
|
||||
}
|
||||
|
||||
static int hasbyte(ringbuffer *b, uint8_t byte){
|
||||
if(b->head == b->tail) return -1; // no data in buffer
|
||||
if(!b || b->head == b->tail) return -1; // no data in buffer
|
||||
int startidx = b->head;
|
||||
if(b->head > b->tail){ //
|
||||
for(int found = b->head; found < b->length; ++found)
|
||||
@@ -51,18 +53,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){
|
||||
if(b->busy) return -1;
|
||||
if(!b || 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){
|
||||
*what += n;
|
||||
@@ -76,9 +73,9 @@ 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;
|
||||
}
|
||||
@@ -94,20 +91,27 @@ 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){
|
||||
if(b->busy) return -1;
|
||||
if(!b || b->busy || !s || len < 1) return -1;
|
||||
b->busy = 1;
|
||||
int r = read(b, s, len);
|
||||
b->busy = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -120,21 +124,29 @@ static int readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){
|
||||
* @return amount of bytes written (negative, if len<data in buffer or buffer is busy)
|
||||
*/
|
||||
int RB_readto(ringbuffer *b, uint8_t byte, uint8_t *s, int len){
|
||||
if(b->busy) return -1;
|
||||
if(!b || b->busy || !s || len < 1) return -1;
|
||||
b->busy = 1;
|
||||
int n = readto(b, byte, s, len);
|
||||
b->busy = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
int RB_datalento(ringbuffer *b, uint8_t byte){
|
||||
if(!b || b->busy) return -1;
|
||||
b->busy = 1;
|
||||
int n = lento(b, byte);
|
||||
b->busy = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
return l;
|
||||
@@ -148,7 +160,7 @@ 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){
|
||||
if(b->busy) return -1;
|
||||
if(!b || b->busy || !str || l < 1) return -1;
|
||||
b->busy = 1;
|
||||
int w = write(b, str, l);
|
||||
b->busy = 0;
|
||||
@@ -157,7 +169,7 @@ int RB_write(ringbuffer *b, const uint8_t *str, int l){
|
||||
|
||||
// just delete all information in buffer `b`
|
||||
int RB_clearbuf(ringbuffer *b){
|
||||
if(b->busy) return -1;
|
||||
if(!b || b->busy) return -1;
|
||||
b->busy = 1;
|
||||
b->head = 0;
|
||||
b->tail = 0;
|
||||
|
||||
@@ -38,4 +38,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);
|
||||
|
||||
@@ -46,7 +46,7 @@ typedef struct {
|
||||
// maybe DMA1ch2 would be for SPI1Rx (or SSI should be @ SPI3), in this case USART3 would be interrupt-driven
|
||||
// IF1[0]: USART3 APB2 72 MHz DMA1ch2 DMA1ch3 PB14
|
||||
// IF2[1]: USART1 APB1 36 MHz DMA1ch4 DMA1ch5 PB0
|
||||
// IF3[2]: USART2 APB2 72 MHz DMA1ch6 DMA1ch7 PA1
|
||||
// IF3[2]: USART2 APB2 72 MHz DMA1ch7 DMA1ch6 PA1
|
||||
// IF4[3]: UART4 APB2 72 MHz DMA2ch5 DMA2ch3
|
||||
// IF5[4]: UART5 APB2 72 MHz - - - interrupt-driven
|
||||
// IF6[5]: (CAN)
|
||||
@@ -54,19 +54,20 @@ typedef struct {
|
||||
static const USART_Config UC[USARTSNO] = {
|
||||
[0] = {.instance = USART3, .pclk_freq = 36000000, .UIRQn = USART3_IRQn, .DIRQn = DMA1_Channel2_IRQn, .dma_controller = DMA1, .dma_rx_channel = DMA1_Channel3, .dma_tx_channel = DMA1_Channel2, .TTCflag = DMA_ISR_TCIF2, .DEport = GPIOB, .DEpin = 1<<14 },
|
||||
[1] = {.instance = USART1, .pclk_freq = 72000000, .UIRQn = USART1_IRQn, .DIRQn = DMA1_Channel4_IRQn, .dma_controller = DMA1, .dma_rx_channel = DMA1_Channel5, .dma_tx_channel = DMA1_Channel4, .TTCflag = DMA_ISR_TCIF4, .DEport = GPIOB, .DEpin = 1<<0 },
|
||||
[2] = {.instance = USART2, .pclk_freq = 36000000, .UIRQn = USART2_IRQn, .DIRQn = DMA1_Channel7_IRQn, .dma_controller = DMA1, .dma_rx_channel = DMA1_Channel6, .dma_tx_channel = DMA1_Channel7, .TTCflag = DMA_ISR_TCIF7, .DEport = GPIOB, .DEpin = 1<<1 },
|
||||
[2] = {.instance = USART2, .pclk_freq = 36000000, .UIRQn = USART2_IRQn, .DIRQn = DMA1_Channel7_IRQn, .dma_controller = DMA1, .dma_rx_channel = DMA1_Channel6, .dma_tx_channel = DMA1_Channel7, .TTCflag = DMA_ISR_TCIF7, .DEport = GPIOA, .DEpin = 1<<1 },
|
||||
[3] = {.instance = UART4, .pclk_freq = 36000000, .UIRQn = UART4_IRQn, .DIRQn = DMA2_Channel5_IRQn, .dma_controller = DMA2, .dma_rx_channel = DMA2_Channel3, .dma_tx_channel = DMA2_Channel5, .TTCflag = DMA_ISR_TCIF5 },
|
||||
[4] = {.instance = UART5, .pclk_freq = 36000000, .UIRQn = UART5_IRQn }, // no DMA
|
||||
};
|
||||
|
||||
// buffers for DMA or interrupt-driven data management
|
||||
static uint8_t inbuffers[USARTSNO][DMARXBUFSZ];
|
||||
static uint16_t inbufidx[USARTSNO] = {0}; // for interrupt-driven - index of next character (also amount of received bytes)
|
||||
static uint16_t inbufidx[USARTSNO] = {0}; // for interrupt-driven - index of next character (also amount of received bytes)
|
||||
static uint8_t outbuffers[USARTSNO][DMATXBUFSZ];
|
||||
static uint16_t outbufidx[USARTSNO] = {0}; // index of next char to transmit over interrupt
|
||||
static uint16_t outbuflen[USARTSNO] = {0}; // length of data to transmit over interrupt [equal 0 if nothing to send]
|
||||
static uint8_t need2send[USARTSNO] = {0}; // flags from IDLE interrupt to send data portion
|
||||
static uint8_t TXrdy[USARTSNO] = {1,1,1,1,1}; // TX DMA ready
|
||||
static uint16_t outbufidx[USARTSNO] = {0}; // index of next char to transmit over interrupt
|
||||
static uint16_t outbuflen[USARTSNO] = {0}; // length of data to transmit over interrupt [equal 0 if nothing to send]
|
||||
static uint8_t need2send[USARTSNO] = {0}; // flags from IDLE interrupt to send data portion
|
||||
static uint8_t TXrdy[USARTSNO] = {1,1,1,1,1}; // TX DMA ready
|
||||
static int dma_read_idx[USARTSNO] = {0}; // start of data in DMA inbuffers
|
||||
// there's no way to tell recipient about overfull, so we will just "eat" spare data!
|
||||
|
||||
|
||||
@@ -172,7 +173,7 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){
|
||||
R->CPAR = (uint32_t) &U->RDR;
|
||||
R->CMAR = (uint32_t) inbuffers[ifNo];
|
||||
R->CNDTR = DMARXBUFSZ;
|
||||
R->CCR = DMA_CCR_MINC | DMA_CCR_EN; // | DMA_CCR_TCIE
|
||||
R->CCR = DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_EN; // manage circular buffer in polling
|
||||
// enable U[S]ART DMA
|
||||
U->CR3 = USART_CR3_DMAT | USART_CR3_DMAR;
|
||||
}else{
|
||||
@@ -200,7 +201,16 @@ void usart_start(uint8_t ifNo){
|
||||
const USART_Config *cfg = &UC[ifNo];
|
||||
cfg->instance->CR1 |= USART_CR1_UE;
|
||||
NVIC_EnableIRQ(cfg->UIRQn);
|
||||
if(cfg->dma_controller) NVIC_EnableIRQ(cfg->DIRQn);
|
||||
if(cfg->dma_controller){ // reset Rx DMA
|
||||
volatile DMA_Channel_TypeDef *R = cfg->dma_rx_channel;
|
||||
dma_read_idx[ifNo] = 0;
|
||||
R->CCR = 0;
|
||||
R->CPAR = (uint32_t) &cfg->instance->RDR;
|
||||
R->CMAR = (uint32_t) inbuffers[ifNo];
|
||||
R->CNDTR = DMARXBUFSZ;
|
||||
R->CCR = DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_EN;
|
||||
NVIC_EnableIRQ(cfg->DIRQn);
|
||||
}
|
||||
DBGch('0' + ifNo);
|
||||
DBG("U[S]ART started");
|
||||
}
|
||||
@@ -213,13 +223,11 @@ void usart_stop(uint8_t ifNo){
|
||||
if(ifNo >= USARTSNO || UC[ifNo].instance == NULL) return;
|
||||
const USART_Config *cfg = &UC[ifNo];
|
||||
cfg->instance->CR1 &= ~USART_CR1_UE;
|
||||
if(cfg->DEport) RX485(cfg->DEport, cfg->DEpin);
|
||||
/*
|
||||
if(cfg->dma_controller){
|
||||
NVIC_DisableIRQ(cfg->DIRQn);
|
||||
}
|
||||
NVIC_DisableIRQ(cfg->UIRQn);
|
||||
*/
|
||||
if(cfg->DEport) RX485(cfg->DEport, cfg->DEpin);
|
||||
DBGch('0' + ifNo);
|
||||
DBG("U[S]ART stopped");
|
||||
}
|
||||
@@ -234,11 +242,28 @@ void usarts_process(){
|
||||
if(!(cfg->instance->CR1 & USART_CR1_UE)) continue; // USART disabled
|
||||
if(cfg->dma_controller){ // DMA-driven
|
||||
// Input data
|
||||
int write_idx = DMARXBUFSZ - cfg->dma_rx_channel->CNDTR; // next symbol to be written
|
||||
int available = (write_idx - dma_read_idx[i] + DMARXBUFSZ) % DMARXBUFSZ; // length of data available
|
||||
if(need2send[i] && available == 0) need2send[i] = 0;
|
||||
if(available >= USB_TXBUFSZ || need2send[i]){ // enough data or lonely couple of bytes
|
||||
// copy data in one or two chunks (wrap handling)
|
||||
if(dma_read_idx[i] + available <= DMARXBUFSZ){ // head before tail
|
||||
USB_send(i, &inbuffers[i][dma_read_idx[i]], available);
|
||||
}else{ // head after tail - two chunks
|
||||
uint32_t first = DMARXBUFSZ - dma_read_idx[i];
|
||||
USB_send(i, &inbuffers[i][dma_read_idx[i]], first);
|
||||
USB_send(i, inbuffers[i], available - first);
|
||||
}
|
||||
DBG("USART -> USB over DMA");
|
||||
dma_read_idx[i] = write_idx; // update read pointer
|
||||
}
|
||||
#if 0
|
||||
if(DMARXBUFSZ - cfg->dma_rx_channel->CNDTR > DMARXBUFSZ/2 || need2send[i]){
|
||||
volatile DMA_Channel_TypeDef *R = cfg->dma_rx_channel;
|
||||
R->CCR &= ~DMA_CCR_EN; // pause DMA input transactions
|
||||
register int l = DMARXBUFSZ - R->CNDTR;
|
||||
if(l){ // have some input data -> send and restart DMA
|
||||
DBG("need");
|
||||
if(USB_send(i, inbuffers[i], l)){
|
||||
DBG("USART -> USB over DMA");
|
||||
// restart DMA only in case of succesfull sent or if failed, but have ability of buffer overfull
|
||||
@@ -249,6 +274,7 @@ void usarts_process(){
|
||||
}
|
||||
R->CCR |= DMA_CCR_EN; // re-enable DMA
|
||||
}
|
||||
#endif
|
||||
// Output data
|
||||
if(TXrdy[i]){ // ready to send new data
|
||||
int got = USB_receive(i, outbuffers[i], DMATXBUFSZ);
|
||||
@@ -308,7 +334,7 @@ void usarts_process(){
|
||||
int usart_send(uint8_t ifNo, const uint8_t *data, int len){
|
||||
if(ifNo >= USARTSNO || !data || len < 1) return 0;
|
||||
const USART_Config *cfg = &UC[ifNo];
|
||||
if(TXrdy[ifNo] == 0 || (!cfg->instance->CR1 & USART_CR1_UE)) return -1; // busy or not active
|
||||
if(TXrdy[ifNo] == 0 || !(cfg->instance->CR1 & USART_CR1_UE)) return -1; // busy or not active
|
||||
if(len > DMATXBUFSZ) len = DMATXBUFSZ;
|
||||
memcpy(outbuffers[ifNo], data, len);
|
||||
if(cfg->dma_controller){
|
||||
@@ -350,7 +376,6 @@ static void usart_isr(uint8_t ifno){
|
||||
volatile USART_TypeDef *U = cfg->instance;
|
||||
// for every flag we should also check if it's IRQ active
|
||||
if((U->ISR & USART_ISR_RXNE) && (U->CR1 & USART_CR1_RXNEIE)){ // got new byte
|
||||
DBG("RXNE");
|
||||
if(inbufidx[ifno] == DMARXBUFSZ) (void) U->RDR; // throw away data: buffer overfull
|
||||
else inbuffers[ifno][ inbufidx[ifno]++ ] = U->RDR; // put new byte into buffer
|
||||
}
|
||||
@@ -358,22 +383,17 @@ static void usart_isr(uint8_t ifno){
|
||||
if(U->ISR & USART_ISR_IDLE){ // try to send collected data (DMA-driven)
|
||||
need2send[ifno] = 1; // seems like data portion is over - try to send it
|
||||
U->ICR = USART_ICR_IDLECF;
|
||||
DBG("IDLE");
|
||||
}
|
||||
if((U->ISR & USART_ISR_TXE) && (U->CR1 & USART_CR1_TXEIE)){ // send next byte if need (interrupt-driven)
|
||||
DBG("TXE");
|
||||
if(outbuflen[ifno] > outbufidx[ifno]){
|
||||
U->TDR = outbuffers[ifno][ outbufidx[ifno]++ ];
|
||||
}else if(U->CR1 & USART_CR1_TXEIE){
|
||||
U->CR1 &= ~USART_CR1_TXEIE; // disable interrupt: no data to send
|
||||
TXrdy[ifno] = 1;
|
||||
DBG("TXRDY");
|
||||
}
|
||||
}
|
||||
if(U->ISR & USART_ISR_TC){ // switch RS-485 to Rx after transmission complete
|
||||
DBG("TC");
|
||||
if(cfg->DEport){
|
||||
DBG("485 -> RX");
|
||||
RX485(cfg->DEport, cfg->DEpin);
|
||||
U->CR1 &= ~USART_CR1_TE;
|
||||
U->CR1 |= USART_CR1_RE;
|
||||
@@ -390,7 +410,7 @@ void uart4_exti34_isr(){ usart_isr(3); }
|
||||
void uart5_exti35_isr(){ usart_isr(4); }
|
||||
|
||||
// DMA Tx interrupts (to arm ready flag)
|
||||
void dma1_channel2_isr(){ DBG("DMA1 done"); TXrdy[0] = 1; DMA1->IFCR = DMA_IFCR_CTCIF2; }
|
||||
void dma1_channel4_isr(){ DBG("DMA2 done"); TXrdy[1] = 1; DMA1->IFCR = DMA_IFCR_CTCIF4; }
|
||||
void dma1_channel6_isr(){ DBG("DMA3 done"); TXrdy[2] = 1; DMA1->IFCR = DMA_IFCR_CTCIF6; }
|
||||
void dma2_channel5_isr(){ DBG("DMA4 done"); TXrdy[3] = 1; DMA2->IFCR = DMA_IFCR_CTCIF5; }
|
||||
void dma1_channel2_isr(){ TXrdy[0] = 1; DMA1->IFCR = DMA_IFCR_CTCIF2; }
|
||||
void dma1_channel4_isr(){ TXrdy[1] = 1; DMA1->IFCR = DMA_IFCR_CTCIF4; }
|
||||
void dma1_channel7_isr(){ TXrdy[2] = 1; DMA1->IFCR = DMA_IFCR_CTCIF7; }
|
||||
void dma2_channel5_isr(){ TXrdy[3] = 1; DMA2->IFCR = DMA_IFCR_CTCIF5; }
|
||||
|
||||
@@ -22,11 +22,8 @@
|
||||
#include "usb_dev.h"
|
||||
|
||||
// DMA linear buffers for Rx/Tx
|
||||
#define DMARXBUFSZ 128
|
||||
#define DMATXBUFSZ 128
|
||||
// ringbuffers for collected data
|
||||
#define USARTRXRBSZ 256
|
||||
#define USARTTXRBSZ 256
|
||||
#define DMARXBUFSZ 512
|
||||
#define DMATXBUFSZ 512
|
||||
|
||||
void usart_config(uint8_t ifNo, usb_LineCoding *lc);
|
||||
void usart_start(uint8_t ifNo);
|
||||
|
||||
@@ -184,14 +184,11 @@ void usb_class_request(config_pack_t *req, uint8_t *data, uint16_t datalen){
|
||||
case REQ_RECIPIENT_INTERFACE:
|
||||
switch(req->bRequest){
|
||||
case SET_LINE_CODING:
|
||||
//DBG("SLC");
|
||||
if(!data || !datalen) break; // wait for data
|
||||
//DBG("test");
|
||||
if(datalen == sizeof(usb_LineCoding))
|
||||
linecoding_handler(ifno, (usb_LineCoding*)data);
|
||||
break;
|
||||
case GET_LINE_CODING:
|
||||
DBG("GLC");
|
||||
EP_WriteIRQ(0, (uint8_t*)&lineCoding[ifno], sizeof(lineCoding));
|
||||
break;
|
||||
case SET_CONTROL_LINE_STATE:
|
||||
@@ -226,17 +223,26 @@ 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;
|
||||
if(ifno != ICFG) 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;
|
||||
@@ -255,7 +261,6 @@ int USB_send(uint8_t ifno, const uint8_t *buf, int len){
|
||||
}
|
||||
}
|
||||
if(buf[len-1] == '\n' && lastdsz[ifno] < 0){
|
||||
if(ifno != ICFG) DBG("send_next");
|
||||
send_next(ifno);
|
||||
}
|
||||
return TRUE;
|
||||
@@ -279,7 +284,6 @@ int USB_putbyte(uint8_t ifno, uint8_t byte){
|
||||
}
|
||||
// send line if got EOL
|
||||
if(byte == '\n' && lastdsz[ifno] < 0){
|
||||
if(ifno != ICFG) DBG("send_next");
|
||||
send_next(ifno);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
@@ -55,6 +55,7 @@ void linecoding_handler(uint8_t ifno, usb_LineCoding *lc);
|
||||
#define CFGWRn(s) do{USB_sendstr(ICFG, s); USB_putbyte(ICFG, '\n');}while(0)
|
||||
#define CFGn() USB_putbyte(ICFG, '\n')
|
||||
|
||||
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);
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#define BUILD_NUMBER "110"
|
||||
#define BUILD_DATE "2026-02-16"
|
||||
#define BUILD_NUMBER "140"
|
||||
#define BUILD_DATE "2026-02-17"
|
||||
|
||||
Reference in New Issue
Block a user