From 73a0eeba8f1b1d9d82782474fbcea396390fe67b Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Mon, 16 Feb 2026 23:58:29 +0300 Subject: [PATCH] almost working U[S]ARTs --- F3:F303/InterfaceBoard/debug.h | 37 -------- F3:F303/InterfaceBoard/main.c | 6 +- F3:F303/InterfaceBoard/multiiface.bin | Bin 17208 -> 18580 bytes .../InterfaceBoard/multiiface.creator.user | 2 +- F3:F303/InterfaceBoard/multiiface.files | 3 +- F3:F303/InterfaceBoard/usart.c | 79 +++++++++++------- F3:F303/InterfaceBoard/usb_dev.c | 26 +++++- F3:F303/InterfaceBoard/version.inc | 4 +- 8 files changed, 79 insertions(+), 78 deletions(-) delete mode 100644 F3:F303/InterfaceBoard/debug.h diff --git a/F3:F303/InterfaceBoard/debug.h b/F3:F303/InterfaceBoard/debug.h deleted file mode 100644 index 76dbace..0000000 --- a/F3:F303/InterfaceBoard/debug.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of the multiiface project. - * Copyright 2026 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_dev.h" - -// debugging messages on config interface - -#ifdef EBUG -#define DBG(str) do{USB_sendstr(ICFG, __FILE__ " (L" STR(__LINE__) "): " str); newline(ICFG);}while(0) -#define DBGmesg(str) do{USB_sendstr(ICFG, str);}while(0) -#define DBGmesgn(str,n) do{USB_send(ICFG, str, n);}while(0) -#define DBGnl() newline(ICFG) -#else -#define DBG(str) -#define DBGmesg(str) -#define DBGmesgn(str,n) -#define DBGnl() -#endif - - diff --git a/F3:F303/InterfaceBoard/main.c b/F3:F303/InterfaceBoard/main.c index 583dc4c..2141933 100644 --- a/F3:F303/InterfaceBoard/main.c +++ b/F3:F303/InterfaceBoard/main.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include "Debug.h" #include "flash.h" #include "hardware.h" #include "proto.h" @@ -44,13 +45,14 @@ 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); + 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 if(!usbON) continue; usarts_process(); + DBGpri(); /*for(int i = 0; i < 6; ++i){ // just echo for first time if(!CDCready[i]) continue; int l = USB_receive(i, (uint8_t*)inbuff, MAXSTRLEN); diff --git a/F3:F303/InterfaceBoard/multiiface.bin b/F3:F303/InterfaceBoard/multiiface.bin index 7607b60421823c71cba257f6b80b67fc1e467398..80b875d147974a6805a2d7867fd5784730e13430 100755 GIT binary patch delta 7523 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 delta 6033 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 - + EnvironmentId diff --git a/F3:F303/InterfaceBoard/multiiface.files b/F3:F303/InterfaceBoard/multiiface.files index c99c82d..4102133 100644 --- a/F3:F303/InterfaceBoard/multiiface.files +++ b/F3:F303/InterfaceBoard/multiiface.files @@ -1,4 +1,5 @@ -debug.h +Debug.c +Debug.h flash.c flash.h hardware.c diff --git a/F3:F303/InterfaceBoard/usart.c b/F3:F303/InterfaceBoard/usart.c index 23ec043..cf12189 100644 --- a/F3:F303/InterfaceBoard/usart.c +++ b/F3:F303/InterfaceBoard/usart.c @@ -19,7 +19,7 @@ #include #include -#include "debug.h" +#include "Debug.h" #include "hardware.h" #include "strfunc.h" #include "usart.h" @@ -87,6 +87,7 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){ // Assuming oversampling by 16 (default after reset). For higher baud rates you might use by 8. U->BRR = peripheral_clock / lc->dwDTERate; lc->dwDTERate = peripheral_clock / U->BRR; + DBGs("New speed: "); DBGs(u2str(lc->dwDTERate)); DBGn(); // ----- Data bits & Parity ----- uint32_t cr1 = 0; @@ -102,6 +103,7 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){ lc->bParityType = USB_CDC_EVEN_PARITY; } } + DBGs("Parity: "); DBGch('0'+lc->bParityType); DBGn(); // Word length (M bits) depends on data bits and parity // M[1:0] encoding: 00 = 8 bits, 01 = 9 bits, 10 = 7 bits @@ -114,7 +116,7 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){ // 7 data + 1 parity = 8 bits total -> M=00 (8-bit mode) // do nothing }else{ - // Unsupported (8 or 9 data bits with parity would be 9/10 bits total) + // 8 or 9 data bits with parity would be 9/10 bits total // Fallback to 8 data + parity cr1 |= USART_CR1_M0; lc->bDataBits = 8; // ??? need to be tested @@ -130,6 +132,7 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){ lc->bDataBits = 8; } } + DBGs("Data bits: "); DBGch('0' + lc->bDataBits); DBGn(); // ----- Stop bits ----- uint32_t cr2 = 0; @@ -144,18 +147,21 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){ // do nothing: default to 1 stop bit -> CR2=00 break; } + DBGs("Stop bits: "); DBGch('0'+lc->bCharFormat); DBGn(); // Write CR2 (stop bits) U->CR2 = cr2; // Enable transmitter, receiver, and interrupts (optional) - cr1 |= USART_CR1_RE; + cr1 |= USART_CR1_RE | USART_CR1_IDLEIE; // enable idle interrupt to force small portions of data into ringbuffer if(cfg->DEport){ + DBG("485 -> RX"); RX485(cfg->DEport, cfg->DEpin); cr1 |= USART_CR1_TCIE; }else cr1 |= USART_CR1_TE; // ----- DMA ----- if(cfg->dma_controller){ // DMA-driven + DBG("DMA-driven"); volatile DMA_Channel_TypeDef *T = cfg->dma_tx_channel, *R = cfg->dma_rx_channel; // Tx DMA T->CCR = 0; @@ -169,8 +175,8 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){ R->CCR = DMA_CCR_MINC | DMA_CCR_EN; // | DMA_CCR_TCIE // enable U[S]ART DMA U->CR3 = USART_CR3_DMAT | USART_CR3_DMAR; - cr1 |= USART_CR1_IDLEIE; // enable idle interrupt to force small portions of data into ringbuffer }else{ + DBG("IRQ-driven"); cr1 |= USART_CR1_RXNEIE; // interrupt-driven inbufidx[ifNo] = 0; outbufidx[ifNo] = 0; @@ -183,6 +189,9 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){ if (--tmout == 0) break; } U->ICR = 0xFFFFFFFF; // Clear flags again + TXrdy[ifNo] = 1; + DBGch('0' + ifNo); + DBG("U[S]ART configured"); } // start when received DTR @@ -192,6 +201,8 @@ void usart_start(uint8_t ifNo){ cfg->instance->CR1 |= USART_CR1_UE; NVIC_EnableIRQ(cfg->UIRQn); if(cfg->dma_controller) NVIC_EnableIRQ(cfg->DIRQn); + DBGch('0' + ifNo); + DBG("U[S]ART started"); } /** @@ -201,21 +212,16 @@ void usart_start(uint8_t ifNo){ void usart_stop(uint8_t ifNo){ if(ifNo >= USARTSNO || UC[ifNo].instance == NULL) return; const USART_Config *cfg = &UC[ifNo]; - cfg->instance->CR1 = 0; + cfg->instance->CR1 &= ~USART_CR1_UE; if(cfg->DEport) RX485(cfg->DEport, cfg->DEpin); + /* if(cfg->dma_controller){ - cfg->dma_tx_channel->CCR = 0; - cfg->dma_rx_channel->CCR = 0; NVIC_DisableIRQ(cfg->DIRQn); - }else{ - NVIC_DisableIRQ(cfg->UIRQn); } -} - -static void msg(const char *txt, uint8_t ifno, int l){ - if(!Config_mode) return; - CFGWR("IF"); USB_putbyte(ICFG, '1' + ifno); CFGWR(": "); - CFGWR(txt); CFGWR(" ("); CFGWR(i2str(l)); CFGWR(" bytes)\n"); + NVIC_DisableIRQ(cfg->UIRQn); + */ + DBGch('0' + ifNo); + DBG("U[S]ART stopped"); } /** @@ -234,12 +240,11 @@ void usarts_process(){ register int l = DMARXBUFSZ - R->CNDTR; if(l){ // have some input data -> send and restart DMA if(USB_send(i, inbuffers[i], l)){ - msg("USART -> USB over DMA", i, l); + DBG("USART -> USB over DMA"); // restart DMA only in case of succesfull sent or if failed, but have ability of buffer overfull R->CMAR = (uint32_t) inbuffers[i]; R->CNDTR = DMARXBUFSZ; need2send[i] = 0; - if(cfg->DEport) TX485(cfg->DEport, cfg->DEpin); } } R->CCR |= DMA_CCR_EN; // re-enable DMA @@ -254,13 +259,14 @@ void usarts_process(){ T->CMAR = (uint32_t) outbuffers[i]; T->CNDTR = got; if(cfg->DEport){ // switch to Tx + DBG("485 -> TX"); TX485(cfg->DEport, cfg->DEpin); cfg->instance->CR1 &= ~USART_CR1_RE; cfg->instance->CR1 |= USART_CR1_TE; } - T->CCR |= DMA_CCR_EN; // start new transmission TXrdy[i] = 0; - msg("USB -> USART over DMA", i, got); + T->CCR |= DMA_CCR_EN; // start new transmission + DBG("USB -> USART over DMA"); } } }else{ // interrupt-driven @@ -272,7 +278,7 @@ void usarts_process(){ if(l && USB_send(i, inbuffers[i], l)){ need2send[i] = 0; inbufidx[i] = 0; - msg("USART -> USB over irq", i, l); + DBG("USART -> USB over irq"); } } U->CR1 |= USART_CR1_RXNEIE; // restore irq reaction @@ -281,6 +287,7 @@ void usarts_process(){ int got = USB_receive(i, outbuffers[i], DMATXBUFSZ); if(got > 0){ if(cfg->DEport){ // switch to Tx + DBG("485 -> TX"); TX485(cfg->DEport, cfg->DEpin); U->CR1 &= ~USART_CR1_RE; U->CR1 |= USART_CR1_TE; @@ -290,7 +297,7 @@ void usarts_process(){ TXrdy[i] = 0; U->TDR = outbuffers[i][0]; // start transmission U->CR1 |= USART_CR1_TXEIE; // enable TXE interrupt - msg("USB -> USART over irq", i, got); + DBG("USB -> USART over irq"); } } } @@ -300,8 +307,8 @@ void usarts_process(){ // Use this function only for debug purpose int usart_send(uint8_t ifNo, const uint8_t *data, int len){ if(ifNo >= USARTSNO || !data || len < 1) return 0; - if(TXrdy[ifNo] == 0) return -1; // busy const USART_Config *cfg = &UC[ifNo]; + 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){ @@ -311,15 +318,17 @@ int usart_send(uint8_t ifNo, const uint8_t *data, int len){ T->CMAR = (uint32_t) outbuffers[ifNo]; T->CNDTR = len; if(cfg->DEport){ // switch to Tx + DBG("485 -> TX"); TX485(cfg->DEport, cfg->DEpin); cfg->instance->CR1 &= ~USART_CR1_RE; cfg->instance->CR1 |= USART_CR1_TE; } - T->CCR |= DMA_CCR_EN; // start new transmission TXrdy[ifNo] = 0; + T->CCR |= DMA_CCR_EN; // start new transmission }else{ volatile USART_TypeDef *U = cfg->instance; if(cfg->DEport){ // switch to Tx + DBG("485 -> TX"); TX485(cfg->DEport, cfg->DEpin); U->CR1 &= ~USART_CR1_RE; U->CR1 |= USART_CR1_TE; @@ -339,24 +348,32 @@ int usart_send(uint8_t ifNo, const uint8_t *data, int len){ static void usart_isr(uint8_t ifno){ const USART_Config *cfg = &UC[ifno]; volatile USART_TypeDef *U = cfg->instance; - if(U->ISR & USART_ISR_RXNE){ // got new byte + // 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 } - if(U->ISR & USART_ISR_IDLE){ // try to send collected data + // IDLE active for both DMA- and interrupt-driven transitions + 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){ // send next byte if need + 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{ + }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; @@ -373,7 +390,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(){ TXrdy[1] = 1; DMA1->IFCR = DMA_IFCR_CTCIF2; } -void dma1_channel4_isr(){ TXrdy[2] = 1; DMA1->IFCR = DMA_IFCR_CTCIF4; } -void dma1_channel7_isr(){ TXrdy[0] = 1; DMA1->IFCR = DMA_IFCR_CTCIF7; } -void dma2_channel5_isr(){ TXrdy[3] = 1; DMA2->IFCR = DMA_IFCR_CTCIF5; } +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; } diff --git a/F3:F303/InterfaceBoard/usb_dev.c b/F3:F303/InterfaceBoard/usb_dev.c index b08dcfd..c063fb4 100644 --- a/F3:F303/InterfaceBoard/usb_dev.c +++ b/F3:F303/InterfaceBoard/usb_dev.c @@ -17,6 +17,7 @@ #include +#include "Debug.h" #include "hardware.h" #include "ringbuffer.h" #include "usart.h" @@ -45,7 +46,7 @@ static volatile uint8_t bufovrfl[InterfacesAmount] = {0}; static uint8_t volatile rcvbuf[InterfacesAmount][USB_RXBUFSZ]; static uint8_t volatile rcvbuflen[InterfacesAmount] = {0}; // line coding -#define DEFL {115200, 0, 0, 8} +#define DEFL {9600, 0, 0, 8} usb_LineCoding lineCoding[InterfacesAmount] = {DEFL,DEFL,DEFL,DEFL,DEFL,DEFL,DEFL}; // CDC configured and ready to use volatile uint8_t CDCready[InterfacesAmount] = {0}; @@ -117,9 +118,11 @@ static void rxtx_handler(){ // SET_LINE_CODING void linecoding_handler(uint8_t ifno, usb_LineCoding *lc){ + //DBGch('0' + ifno); + //DBG("Linecoding"); lineCoding[ifno] = *lc; usart_config(ifno, &lineCoding[ifno]); // lc would be real speed! - usart_start(ifno); + usart_start(ifno); // restart again with new configuration } // clear IN/OUT buffers on connection @@ -136,10 +139,13 @@ static void clearbufs(uint8_t ifno){ // SET_CONTROL_LINE_STATE void clstate_handler(uint8_t ifno, uint16_t val){ + //DBGch('0' + ifno); + //DBG("CLSTATE"); CDCready[ifno] = val; // CONTROL_DTR | CONTROL_RTS -> interface connected; 0 -> disconnected lastdsz[ifno] = -1; if(val){ clearbufs(ifno); + //usart_config(ifno, &lineCoding[ifno]); // SET_CONTROL_LINE_STATE could be without SET_LINE_CODING usart_start(ifno); }else usart_stop(ifno); // turn of USART (if it is @ this interface) } @@ -147,6 +153,8 @@ void clstate_handler(uint8_t ifno, uint16_t val){ // SEND_BREAK - disconnect interface and clear its buffers // this is a fake handler as classic CDC ACM never receives this void break_handler(uint8_t ifno){ + //DBGch('0' + ifno); + //DBG("BREAK"); CDCready[ifno] = 0; usart_stop(ifno); // turn of USART (if it is @ this interface) } @@ -176,11 +184,14 @@ 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: @@ -218,6 +229,7 @@ int USB_sendall(uint8_t 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"); uint32_t T0 = Tms; while(len){ if(Tms - T0 > DISCONN_TMOUT){ @@ -242,7 +254,10 @@ 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){ + if(ifno != ICFG) DBG("send_next"); + send_next(ifno); + } return TRUE; } @@ -263,7 +278,10 @@ 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){ + if(ifno != ICFG) DBG("send_next"); + send_next(ifno); + } return TRUE; } diff --git a/F3:F303/InterfaceBoard/version.inc b/F3:F303/InterfaceBoard/version.inc index b91822d..2f3d46b 100644 --- a/F3:F303/InterfaceBoard/version.inc +++ b/F3:F303/InterfaceBoard/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "97" -#define BUILD_DATE "2026-02-15" +#define BUILD_NUMBER "110" +#define BUILD_DATE "2026-02-16"