mirror of
https://github.com/eddyem/stm32samples.git
synced 2026-03-20 00:30:57 +03:00
start with USART (now DEBUG-compile is unavialable)
This commit is contained in:
@@ -12,4 +12,9 @@ New interface allows you to configure GPIO and use it's base functions: in/out/A
|
|||||||
|
|
||||||
## DMA channels
|
## DMA channels
|
||||||
|
|
||||||
DMA1 channel1: ADC.
|
DMA1 channel 1: ADC
|
||||||
|
|
||||||
|
DMA1 channel 4: USART[1,2]_TX
|
||||||
|
|
||||||
|
DMA1 channel 5: USART[1,2]_RX
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
#include "usart.h"
|
||||||
|
|
||||||
static uint16_t monitor_mask[2] = {0}; // pins to monitor == 1 (ONLY GPIO and ADC)
|
static uint16_t monitor_mask[2] = {0}; // pins to monitor == 1 (ONLY GPIO and ADC)
|
||||||
static uint16_t oldstates[2][16] = {0}; // previous state (16 bits - as some pins could be analog)
|
static uint16_t oldstates[2][16] = {0}; // previous state (16 bits - as some pins could be analog)
|
||||||
@@ -155,6 +156,7 @@ TRUE_INLINE int8_t get_adc_channel(uint8_t port, uint8_t pin){
|
|||||||
int gpio_reinit(){
|
int gpio_reinit(){
|
||||||
bzero(monitor_mask, sizeof(monitor_mask));
|
bzero(monitor_mask, sizeof(monitor_mask));
|
||||||
bzero(oldstates, sizeof(oldstates));
|
bzero(oldstates, sizeof(oldstates));
|
||||||
|
usartconf_t UC = {0}; // fill next
|
||||||
for(int port = 0; port < 2; port++){
|
for(int port = 0; port < 2; port++){
|
||||||
GPIO_TypeDef *gpio = (port == 0) ? GPIOA : GPIOB;
|
GPIO_TypeDef *gpio = (port == 0) ? GPIOA : GPIOB;
|
||||||
for(int pin = 0; pin < 16; pin++){
|
for(int pin = 0; pin < 16; pin++){
|
||||||
@@ -200,6 +202,9 @@ int gpio_reinit(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: configure USART, SPI etc
|
// TODO: configure USART, SPI etc
|
||||||
|
if(UC.No && usart_config(&UC)){
|
||||||
|
if(!usart_start()) return FALSE;
|
||||||
|
}
|
||||||
// also chech cfg->monitor!
|
// also chech cfg->monitor!
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ extern "C"{
|
|||||||
#include "gpioproto.h"
|
#include "gpioproto.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "gpioproto.h"
|
#include "gpioproto.h"
|
||||||
|
#include "usart.h"
|
||||||
#undef USBIF
|
#undef USBIF
|
||||||
#define USBIF IGPIO
|
#define USBIF IGPIO
|
||||||
#include "strfunc.h"
|
#include "strfunc.h"
|
||||||
@@ -571,6 +572,7 @@ void GPIO_process(){
|
|||||||
if(alert & pinmask) pin_getter(port, i);
|
if(alert & pinmask) pin_getter(port, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
usart_process(NULL, 0);
|
||||||
if(l == 0) return;
|
if(l == 0) return;
|
||||||
if(l < 0) SEND("ERROR: USB buffer overflow or string was too long\n");
|
if(l < 0) SEND("ERROR: USB buffer overflow or string was too long\n");
|
||||||
else{
|
else{
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ TRUE_INLINE void gpio_setup(){ // setup some common GPIO
|
|||||||
void hardware_setup(){
|
void hardware_setup(){
|
||||||
// enable all active GPIO clocking
|
// enable all active GPIO clocking
|
||||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;
|
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;
|
||||||
|
RCC->APB1ENR |= RCC_APB2ENR_USART1EN;
|
||||||
|
RCC->APB2ENR |= RCC_APB1ENR_USART2EN;
|
||||||
gpio_setup();
|
gpio_setup();
|
||||||
//gpio_reinit();
|
//gpio_reinit();
|
||||||
adc_setup();
|
adc_setup();
|
||||||
|
|||||||
@@ -17,10 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "can.h"
|
#include "can.h"
|
||||||
|
#include "canproto.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "gpioproto.h"
|
#include "gpioproto.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "canproto.h"
|
|
||||||
|
|
||||||
volatile uint32_t Tms = 0;
|
volatile uint32_t Tms = 0;
|
||||||
|
|
||||||
|
|||||||
263
F0:F030,F042,F072/usbcan_gpio/usart.c
Normal file
263
F0:F030,F042,F072/usbcan_gpio/usart.c
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the usbcangpio project.
|
||||||
|
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stm32f0.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ringbuffer.h"
|
||||||
|
#include "usart.h"
|
||||||
|
|
||||||
|
// We share DMAch4/5 for both USARTs, so only one can work in a time!!!
|
||||||
|
|
||||||
|
#define USARTSNO 2
|
||||||
|
|
||||||
|
// buffers for DMA or interrupt-driven data management
|
||||||
|
// here we use INDEX (usart number minus 1)
|
||||||
|
static uint8_t inbuffer[DMARXBUFSZ]; // DMA in buffer
|
||||||
|
static uint8_t rbbuffer[RXRBSZ]; // for in ringbuffer
|
||||||
|
static uint8_t outbuffer[DMATXBUFSZ]; // DMA out buffer
|
||||||
|
static uint8_t TXrdy = 1; // TX DMA ready
|
||||||
|
static uint8_t RXrdy = 0; // == 1 when got IDLE or '\n' (only when `monitoring` is on
|
||||||
|
static uint8_t textformat = 0; // out by '\n'-terminated lines
|
||||||
|
static uint8_t monitor = 0; // monitor USART rx
|
||||||
|
static int dma_read_idx = 0; // start of data in DMA inbuffers
|
||||||
|
static int curUSARTidx = -1; // working USART index (0/1), -1 if unconfigured
|
||||||
|
|
||||||
|
static ringbuffer RBin = {.data = rbbuffer, .length = RXRBSZ};
|
||||||
|
|
||||||
|
static volatile USART_TypeDef* const Usarts[USARTSNO] = {USART1, USART2};
|
||||||
|
static uint8_t const UIRQs[USARTSNO] = {USART1_IRQn, USART2_IRQn};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief usart_config - configure US[A]RT based on usb_LineCoding
|
||||||
|
* @param usartconf (io) - (modified to real speeds)
|
||||||
|
* @return TRUE if all OK
|
||||||
|
*/
|
||||||
|
int usart_config(usartconf_t *usartconf){
|
||||||
|
SYSCFG->CFGR1 |= SYSCFG_CFGR1_USART1RX_DMA_RMP | SYSCFG_CFGR1_USART1TX_DMA_RMP; // both USARTs on DMA1ch4(tx)/5(rx)
|
||||||
|
// all clocking and GPIO config should be done in hardware_setup() & gpio_reinit()!
|
||||||
|
if(!usartconf) return FALSE;
|
||||||
|
if(curUSARTidx != -1) usart_stop(); // disable previous USART if enabled
|
||||||
|
uint8_t No = usartconf->No;
|
||||||
|
if(No >= USARTSNO || No < 1 || usartconf->speed < USART_MIN_SPEED) return FALSE;
|
||||||
|
--No; // now this is an INDEX!
|
||||||
|
volatile USART_TypeDef *U = Usarts[No];
|
||||||
|
uint32_t peripheral_clock = 48000000;
|
||||||
|
// Disable USART while configuring
|
||||||
|
U->CR1 = 0;
|
||||||
|
U->ICR = 0xFFFFFFFF; // Clear all interrupt flags
|
||||||
|
// Assuming oversampling by 16 (default after reset). For higher baud rates you might use by 8.
|
||||||
|
U->BRR = peripheral_clock / (usartconf->speed);
|
||||||
|
usartconf->speed= peripheral_clock / U->BRR; // fix for real speed
|
||||||
|
uint32_t cr1 = 0;
|
||||||
|
// format: 8N1, so CR2 used only for character match (if need)
|
||||||
|
if(usartconf->monitor){
|
||||||
|
if(usartconf->textproto){
|
||||||
|
U->CR2 = USART_CR2_ADD_VAL('\n');
|
||||||
|
cr1 |= USART_CR1_CMIE;
|
||||||
|
}else cr1 |= USART_CR1_IDLEIE; // monitor binary data by IDLE flag
|
||||||
|
}
|
||||||
|
textformat = usartconf->textproto;
|
||||||
|
monitor = usartconf->monitor;
|
||||||
|
// Enable transmitter, receiver, and interrupts (optional)
|
||||||
|
if(usartconf->Rxen) cr1 |= USART_CR1_RE;
|
||||||
|
if(usartconf->Txen){
|
||||||
|
cr1 |= USART_CR1_TE;
|
||||||
|
// DMA Tx
|
||||||
|
volatile DMA_Channel_TypeDef *T = DMA1_Channel4;
|
||||||
|
T->CCR = 0;
|
||||||
|
T->CPAR = (uint32_t) &U->TDR;
|
||||||
|
T->CCR = DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE;
|
||||||
|
}
|
||||||
|
// Main config
|
||||||
|
U->CR1 = cr1;
|
||||||
|
curUSARTidx = No;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start NUMBER
|
||||||
|
int usart_start(){
|
||||||
|
if(curUSARTidx == -1) return FALSE;
|
||||||
|
volatile USART_TypeDef *U = Usarts[curUSARTidx];
|
||||||
|
if(monitor) NVIC_EnableIRQ(UIRQs[curUSARTidx]);
|
||||||
|
NVIC_EnableIRQ(DMA1_Channel4_5_IRQn);
|
||||||
|
// reset Rx DMA
|
||||||
|
if(U->CR1 & USART_CR1_RE){
|
||||||
|
volatile DMA_Channel_TypeDef *R = DMA1_Channel5;
|
||||||
|
dma_read_idx = 0;
|
||||||
|
R->CCR = 0;
|
||||||
|
R->CPAR = (uint32_t) U->RDR;
|
||||||
|
R->CMAR = (uint32_t) inbuffer;
|
||||||
|
R->CNDTR = DMARXBUFSZ;
|
||||||
|
R->CCR = DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_EN;
|
||||||
|
RB_clearbuf(&RBin);
|
||||||
|
}
|
||||||
|
U->CR1 |= USART_CR1_UE; // enable USARTx
|
||||||
|
U->ICR = 0xFFFFFFFF; // Clear flags
|
||||||
|
// Wait for the idle frame to complete (optional)
|
||||||
|
uint32_t tmout = 16000000;
|
||||||
|
while(!(U->ISR & USART_ISR_TC)){
|
||||||
|
if (--tmout == 0) break;
|
||||||
|
}
|
||||||
|
TXrdy = 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief usart_stop - turn off U[S]ART for given interface
|
||||||
|
* @param ifNo - interface number
|
||||||
|
*/
|
||||||
|
void usart_stop(){
|
||||||
|
if(curUSARTidx == -1) return;
|
||||||
|
Usarts[curUSARTidx]->CR1 &= ~USART_CR1_UE;
|
||||||
|
NVIC_DisableIRQ(DMA1_Channel4_5_IRQn);
|
||||||
|
NVIC_DisableIRQ(UIRQs[curUSARTidx]);
|
||||||
|
curUSARTidx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief usart_receive - receive data from USART by user request (return none if monitor == 1)
|
||||||
|
* @param buf (io) - user buffer
|
||||||
|
* @param len - `buf` length
|
||||||
|
* @return -1 if USART not configured or amount of data from ringbuffer
|
||||||
|
*/
|
||||||
|
int usart_receive(uint8_t *buf, int len){
|
||||||
|
if(curUSARTidx == -1) return -1;
|
||||||
|
if(textformat){
|
||||||
|
int toN = RB_datalento(&RBin, '\n');
|
||||||
|
if(toN == 0) return 0;
|
||||||
|
if(toN < len) len = toN; // read only until '\n' in text format
|
||||||
|
}
|
||||||
|
int got = RB_read(&RBin, buf, len);
|
||||||
|
if(got < 0) got = 0;
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief usart_process - send/receive processing
|
||||||
|
* Try to send data from output ringbuffer, check input DMA buffer and full input ringbuffer
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief usart_process - USART data processing
|
||||||
|
* @param buf - buffer for "async" messages (when monitor==1)
|
||||||
|
* @param len - length of `buf`
|
||||||
|
* @return amount of bytes read or -1 if USART isn't active
|
||||||
|
*/
|
||||||
|
int usart_process(uint8_t *buf, int len){
|
||||||
|
if(curUSARTidx == -1 || !(Usarts[curUSARTidx]->CR1 & USART_CR1_UE)) return -1; // none activated or started
|
||||||
|
int ret = 0; // returned value
|
||||||
|
// Input data
|
||||||
|
int write_idx = DMARXBUFSZ - DMA1_Channel5->CNDTR; // next symbol to be written
|
||||||
|
int available = (write_idx - dma_read_idx); // length of data available
|
||||||
|
if(available < 0) available += DMARXBUFSZ; // write to the left of read
|
||||||
|
if(available){
|
||||||
|
if(RXrdy){
|
||||||
|
if(buf && len > 0){
|
||||||
|
if(len < available) available = len;
|
||||||
|
}else RXrdy = 0;
|
||||||
|
}
|
||||||
|
// TODO: force copying data to "async" buffer in case of overflow danger
|
||||||
|
if(available >= (DMARXBUFSZ/2) || RXrdy){ // enough data or lonely couple of bytes but need to show
|
||||||
|
// copy data in one or two chunks (wrap handling)
|
||||||
|
int wrOK = FALSE;
|
||||||
|
if(dma_read_idx + available <= DMARXBUFSZ){ // head before tail
|
||||||
|
if(RXrdy){
|
||||||
|
memcpy(buf, &inbuffer[dma_read_idx], available);
|
||||||
|
ret = available;
|
||||||
|
wrOK = TRUE;
|
||||||
|
}else{
|
||||||
|
if(available == RB_write(&RBin, &inbuffer[dma_read_idx], available)) wrOK = TRUE;
|
||||||
|
}
|
||||||
|
}else{ // head after tail - two chunks
|
||||||
|
int first = DMARXBUFSZ - dma_read_idx;
|
||||||
|
if(RXrdy){
|
||||||
|
memcpy(buf, &inbuffer[dma_read_idx], first);
|
||||||
|
memcpy(buf, inbuffer, available - first);
|
||||||
|
ret = available;
|
||||||
|
wrOK = TRUE;
|
||||||
|
}else{
|
||||||
|
if((first == RB_write(&RBin, &inbuffer[dma_read_idx], first)) &&
|
||||||
|
(available - first) == RB_write(&RBin, inbuffer, available - first)) wrOK = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(wrOK){
|
||||||
|
RXrdy = 0;
|
||||||
|
dma_read_idx = write_idx; // update read pointer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
// Output data
|
||||||
|
if(TXrdy){ // ready to send new data - here we can process RBout, if have
|
||||||
|
int got = RB_read...
|
||||||
|
if(got > 0){ // send next data portion
|
||||||
|
volatile DMA_Channel_TypeDef *T = cfg->dma_tx_channel;
|
||||||
|
T->CCR &= ~DMA_CCR_EN;
|
||||||
|
T->CMAR = (uint32_t) outbuffers[i];
|
||||||
|
T->CNDTR = got;
|
||||||
|
TXrdy = 0;
|
||||||
|
T->CCR |= DMA_CCR_EN; // start new transmission
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send data buffer
|
||||||
|
int usart_send(const uint8_t *data, int len){
|
||||||
|
if(curUSARTidx == -1 || !data || len < 1) return 0;
|
||||||
|
if(TXrdy == 0) return -1;
|
||||||
|
if(len > DMATXBUFSZ) len = DMATXBUFSZ;
|
||||||
|
memcpy(outbuffer, data, len);
|
||||||
|
volatile DMA_Channel_TypeDef *T = DMA1_Channel4;
|
||||||
|
T->CCR &= ~DMA_CCR_EN;
|
||||||
|
T->CMAR = (uint32_t) outbuffer;
|
||||||
|
T->CNDTR = len;
|
||||||
|
TXrdy = 0;
|
||||||
|
T->CCR |= DMA_CCR_EN; // start new transmission
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief usart_isr - U[S]ART interrupt: IDLE (for DMA-driven) or
|
||||||
|
* @param ifno - interface index
|
||||||
|
*/
|
||||||
|
static void usart_isr(){
|
||||||
|
if(curUSARTidx == -1) return; // WTF???
|
||||||
|
volatile USART_TypeDef *U = Usarts[curUSARTidx];
|
||||||
|
// IDLE active when we monitor binary data
|
||||||
|
if((U->ISR & USART_ISR_IDLE) && (U->CR1 & USART_CR1_IDLEIE)){ // try to send collected data (DMA-driven)
|
||||||
|
RXrdy = 1; // seems like data portion is over - try to send it
|
||||||
|
}
|
||||||
|
if((U->ISR & USART_ISR_CMF) && (U->CR1 & USART_CR1_CMIE)){ // character match -> the same for text data
|
||||||
|
RXrdy = 1;
|
||||||
|
}
|
||||||
|
U->ICR = 0xffffffff; // clear all flags
|
||||||
|
}
|
||||||
|
|
||||||
|
void dma1_channel4_5_isr(){ // TX ready, channel5
|
||||||
|
if(DMA1->ISR & DMA_ISR_TCIF5){
|
||||||
|
TXrdy = 1;
|
||||||
|
DMA1->IFCR = DMA_IFCR_CTCIF5;
|
||||||
|
DMA1_Channel4->CCR &= ~DMA_CCR_EN; // disable DMA channel until next send
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// U[S]ART interrupts
|
||||||
|
void usart1_isr() {usart_isr();}
|
||||||
|
void usart2_isr() {usart_isr();}
|
||||||
48
F0:F030,F042,F072/usbcan_gpio/usart.h
Normal file
48
F0:F030,F042,F072/usbcan_gpio/usart.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the usbcangpio project.
|
||||||
|
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// DMA linear buffers for Rx/Tx
|
||||||
|
#define DMARXBUFSZ 128
|
||||||
|
#define DMATXBUFSZ 128
|
||||||
|
// incoming ring buffer - only if there's a lot of data in DMA RX buffer
|
||||||
|
#define RXRBSZ 256
|
||||||
|
|
||||||
|
#define USART_MIN_SPEED 1024
|
||||||
|
#define USART_MAX_SPEED 1000000
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint32_t speed; // baudrate
|
||||||
|
uint8_t No : 2; // Usart number (1/2)
|
||||||
|
uint8_t Rxen : 1; // enable rx
|
||||||
|
uint8_t Txen : 1; // enable tx
|
||||||
|
uint8_t textproto : 1; // match '\n' and force output by lines (if there's enough place in buffers and monitor == 1)
|
||||||
|
uint8_t monitor : 1; // async output by incoming (over '\n', IDLE or buffer full)
|
||||||
|
} usartconf_t;
|
||||||
|
|
||||||
|
int usart_config(usartconf_t *config);
|
||||||
|
int usart_start();
|
||||||
|
void usart_stop();
|
||||||
|
|
||||||
|
int usart_process(uint8_t *buf, int len);
|
||||||
|
|
||||||
|
int usart_receive(uint8_t *buf, int len);
|
||||||
|
int usart_send(const uint8_t *data, int len);
|
||||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 18.0.2, 2026-03-10T22:39:58. -->
|
<!-- Written by QtCreator 18.0.2, 2026-03-11T23:40:18. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ ringbuffer.c
|
|||||||
ringbuffer.h
|
ringbuffer.h
|
||||||
strfunc.c
|
strfunc.c
|
||||||
strfunc.h
|
strfunc.h
|
||||||
|
usart.c
|
||||||
|
usart.h
|
||||||
usb.c
|
usb.c
|
||||||
usb.h
|
usb.h
|
||||||
usb_defs.h
|
usb_defs.h
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "132"
|
#define BUILD_NUMBER "146"
|
||||||
#define BUILD_DATE "2026-03-10"
|
#define BUILD_DATE "2026-03-11"
|
||||||
|
|||||||
Reference in New Issue
Block a user