mirror of
https://github.com/eddyem/stm32samples.git
synced 2026-02-28 03:44:30 +03:00
start adding U[S]ART support (need DMA)
This commit is contained in:
@@ -38,7 +38,7 @@ Inner USB interfaces (IFx):
|
|||||||
| 12 | (VREF-) | | | |
|
| 12 | (VREF-) | | | |
|
||||||
| 13 | (VREF+) | | | |
|
| 13 | (VREF+) | | | |
|
||||||
| 14 | PA0 | NC | | |
|
| 14 | PA0 | NC | | |
|
||||||
| 15 | PA1 | USART2 DE | AF7 | RS-485 (3) DE |
|
| 15 | PA1 | USART2 DE | AF7 or PP | RS-485 (3) DE |
|
||||||
| 16 | PA2 | USART2 TX | AF7 | RS-485 (3) Tx |
|
| 16 | PA2 | USART2 TX | AF7 | RS-485 (3) Tx |
|
||||||
| 17 | PA3 | USART2 RX | AF7 | RS-485 (3) Rx |
|
| 17 | PA3 | USART2 RX | AF7 | RS-485 (3) Rx |
|
||||||
| 18 | PF4 | NC | | |
|
| 18 | PF4 | NC | | |
|
||||||
@@ -58,7 +58,7 @@ Inner USB interfaces (IFx):
|
|||||||
| 32 | (VDD) | | | |
|
| 32 | (VDD) | | | |
|
||||||
| 33 | PB12 | NC | | |
|
| 33 | PB12 | NC | | |
|
||||||
| 34 | PB13 | NC | | |
|
| 34 | PB13 | NC | | |
|
||||||
| 35 | PB14 | USART3 DE | AF7 | RS-485 (1) DE |
|
| 35 | PB14 | USART3 DE | AF7 or PP | RS-485 (1) DE |
|
||||||
| 36 | PB15 | | | |
|
| 36 | PB15 | | | |
|
||||||
| 37 | PC6 | NC | | |
|
| 37 | PC6 | NC | | |
|
||||||
| 38 | PC7 | NC | | |
|
| 38 | PC7 | NC | | |
|
||||||
@@ -91,5 +91,33 @@ Inner USB interfaces (IFx):
|
|||||||
|
|
||||||
### Some comments.
|
### Some comments.
|
||||||
|
|
||||||
|
Interfaces:
|
||||||
|
|
||||||
|
- IF1: RS-485 over USART3.
|
||||||
|
- IF2: RS-485 over USART1.
|
||||||
|
- IF3: RS-485 over USART2.
|
||||||
|
- IF4: RS-232 over UART4.
|
||||||
|
- IF5: RS-232 or RS-422 (by jumpers "IF5" and "SSI") over UART5.
|
||||||
|
- IF6: CAN bus.
|
||||||
|
- IF7: SSI (inaccessible when RS-422 selected) or interface for device configuration (if jumper "Config mode" is opened when device started").
|
||||||
|
|
||||||
|
|
||||||
|
DMA1 channels:
|
||||||
|
|
||||||
|
- Ch2: USART3_Tx
|
||||||
|
- Ch3: USART3_Rx
|
||||||
|
- Ch4: USART1_Tx
|
||||||
|
- Ch5: USART1_Rx
|
||||||
|
- Ch6: USART2_Rx
|
||||||
|
- Ch7: USART2_Tx
|
||||||
|
|
||||||
|
DMA2 channels:
|
||||||
|
|
||||||
|
- Ch3: UART4_Rx
|
||||||
|
- Ch5: UART4_Tx
|
||||||
|
|
||||||
|
UART5 have no DMA channels, so used in interrupts.
|
||||||
|
|
||||||
|
|
||||||
### Sorted by ports (with AF numbers).
|
### Sorted by ports (with AF numbers).
|
||||||
|
|
||||||
|
|||||||
37
F3:F303/InterfaceBoard/debug.h
Normal file
37
F3:F303/InterfaceBoard/debug.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the multiiface 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 "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
|
||||||
|
|
||||||
|
|
||||||
@@ -21,7 +21,10 @@
|
|||||||
uint8_t Config_mode = 0;
|
uint8_t Config_mode = 0;
|
||||||
|
|
||||||
static inline void gpio_setup(){
|
static inline void gpio_setup(){
|
||||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; // for USART and LEDs
|
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_DMA1EN | RCC_AHBENR_DMA2EN;
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_CANEN | RCC_APB1ENR_USART2EN | RCC_APB1ENR_USART3EN
|
||||||
|
| RCC_APB1ENR_UART4EN | RCC_APB1ENR_UART5EN;
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||||
for(int i = 0; i < 10000; ++i) nop();
|
for(int i = 0; i < 10000; ++i) nop();
|
||||||
// USB - alternate function 14 @ pins PA11/PA12; SWD - AF0 @PA13/14
|
// USB - alternate function 14 @ pins PA11/PA12; SWD - AF0 @PA13/14
|
||||||
GPIOA->AFR[1] = AFRf(14, 11) | AFRf(14, 12);
|
GPIOA->AFR[1] = AFRf(14, 11) | AFRf(14, 12);
|
||||||
|
|||||||
@@ -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-02-12T23:15:35. -->
|
<!-- Written by QtCreator 18.0.2, 2026-02-14T00:56:14. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
debug.h
|
||||||
flash.c
|
flash.c
|
||||||
flash.h
|
flash.h
|
||||||
hardware.c
|
hardware.c
|
||||||
@@ -9,6 +10,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_descr.c
|
usb_descr.c
|
||||||
|
|||||||
214
F3:F303/InterfaceBoard/usart.c
Normal file
214
F3:F303/InterfaceBoard/usart.c
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MultiInterface project.
|
||||||
|
* Copyright 2022 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 <stm32f3.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "hardware.h"
|
||||||
|
#include "strfunc.h"
|
||||||
|
#include "usart.h"
|
||||||
|
#include "usb_descr.h" // InterfacesAmount, IFx
|
||||||
|
|
||||||
|
static volatile int idatalen = 0; // received data line length (including '\n')
|
||||||
|
// USARTs registers by interface number [IF1..IF7], index=epNo-1
|
||||||
|
static volatile USART_TypeDef *USARTx[InterfacesAmount] = {USART3, USART1, USART2, UART4, UART5, NULL, NULL};
|
||||||
|
static int usartByIfNo[] = {0, ISerial1, ISerial2, ISerial0, ISerial3, ISerial4}; // USARTx -> index x
|
||||||
|
// APB1/APB2 bus speeds:
|
||||||
|
static const uint32_t usart_clocks[INTERFACES_AMOUNT] = {
|
||||||
|
72000000, // USART3 on APB2 (72 MHz)
|
||||||
|
36000000, // USART1 on APB1 (36 MHz)
|
||||||
|
72000000, // USART2 on APB2 (72 MHz)
|
||||||
|
72000000, // UART4 on APB2 (72 MHz)
|
||||||
|
72000000, // UART5 on APB2 (72 MHz)
|
||||||
|
0, // not used
|
||||||
|
0 // not used
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
volatile int linerdy = 0, // received data ready
|
||||||
|
dlen = 0, // length of data (including '\n') in current buffer
|
||||||
|
bufovr = 0; // input buffer overfull
|
||||||
|
|
||||||
|
|
||||||
|
static void usart_putchar(int no, uint8_t ch){
|
||||||
|
while(!(USARTx[no]->ISR & USART_ISR_TXE));
|
||||||
|
USARTx[no]->TDR = ch;
|
||||||
|
}
|
||||||
|
void usart_sendn(uint8_t ifNo, const uint8_t *str, int L){
|
||||||
|
if (!str || L < 0 || ifNo < 1 || ifNo > USARTSNO)
|
||||||
|
return;
|
||||||
|
for(int i = 0; i < L; ++i){
|
||||||
|
usart_putchar(ifNo, str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup all USARTs
|
||||||
|
void usarts_setup(){
|
||||||
|
// clock
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_USART2EN | RCC_APB1ENR_USART3EN;
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||||
|
for(int i = 0; i < USARTSNO; ++i)
|
||||||
|
usart_config(i + USART1_IDX, lineCodings);
|
||||||
|
NVIC_EnableIRQ(USART1_IRQn);
|
||||||
|
NVIC_EnableIRQ(USART2_IRQn);
|
||||||
|
NVIC_EnableIRQ(USART3_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: fixme for different settings
|
||||||
|
//lineCoding.dwDTERate = speeds[usartNo];
|
||||||
|
//lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
|
||||||
|
//lineCoding.bParityType = USB_CDC_NO_PARITY;
|
||||||
|
//lineCoding.bDataBits = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief usart_config - configure US[A]RT based on usb_LineCoding
|
||||||
|
* @param ifNo - interface index [0..6]
|
||||||
|
* @param lc (io) - linecoding (modified to real speeds)
|
||||||
|
*/
|
||||||
|
void usart_config(uint8_t ifNo, usb_LineCoding *lc){
|
||||||
|
if(ifNo >= INTERFACES_AMOUNT || USARTx[ifNo] == NULL) return;
|
||||||
|
volatile USART_TypeDef *U = USARTx[ifNo];
|
||||||
|
uint32_t peripheral_clock = usart_clocks[ifNo];
|
||||||
|
// 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 / lc->dwDTERate;
|
||||||
|
lc->dwDTERate = peripheral_clock / U->BRR;
|
||||||
|
|
||||||
|
// ----- Data bits & Parity -----
|
||||||
|
uint32_t cr1 = 0;
|
||||||
|
uint32_t data_bits = lc->bDataBits;
|
||||||
|
uint32_t parity_type = lc->bParityType;
|
||||||
|
// Parity enable/disable and type
|
||||||
|
if(parity_type != USB_CDC_NO_PARITY){
|
||||||
|
cr1 |= USART_CR1_PCE; // Parity enabled
|
||||||
|
if(parity_type == USB_CDC_ODD_PARITY){
|
||||||
|
cr1 |= USART_CR1_PS; // Odd parity
|
||||||
|
// MARK and SPACE parity are not natively supported; treat as even or ignore.
|
||||||
|
}else if(parity_type == USB_CDC_MARK_PARITY || parity_type == USB_CDC_SPACE_PARITY){
|
||||||
|
lc->bParityType = USB_CDC_EVEN_PARITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word length (M bits) depends on data bits and parity
|
||||||
|
// M[1:0] encoding: 00 = 8 bits, 01 = 9 bits, 10 = 7 bits
|
||||||
|
if(cr1 & USART_CR1_PCE){
|
||||||
|
// Parity enabled -> total frame length = data bits + 1 parity bit
|
||||||
|
if(data_bits == 6){
|
||||||
|
// 6 data + 1 parity = 7 bits total -> M=10 (7-bit mode)
|
||||||
|
cr1 |= USART_CR1_M1;
|
||||||
|
}else if(data_bits == 7){
|
||||||
|
// 7 data + 1 parity = 8 bits total -> M=00 (8-bit mode)
|
||||||
|
// do nothing
|
||||||
|
}else if(data_bits == 8){
|
||||||
|
// 8 data + 1 parity = 9 bits total -> M=01 (9-bit mode)
|
||||||
|
cr1 |= USART_CR1_M0; // M0=1, M1=0
|
||||||
|
}else{
|
||||||
|
// Unsupported (9 data bits with parity would be 10 bits total)
|
||||||
|
// Fallback to 8 data + parity
|
||||||
|
cr1 |= USART_CR1_M0;
|
||||||
|
lc->bDataBits = 8;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// Parity disabled
|
||||||
|
if(data_bits == 7){
|
||||||
|
cr1 |= USART_CR1_M1; // M1=1, M0=0 -> 7-bit mode
|
||||||
|
}else if(data_bits == 8){
|
||||||
|
// do nothing M=00
|
||||||
|
}else if(data_bits == 9){
|
||||||
|
cr1 |= USART_CR1_M0; // M0=1, M1=0 -> 9-bit mode
|
||||||
|
}else{
|
||||||
|
// Unsupported (5,6 bits) -> fallback to 8 bits
|
||||||
|
lc->bDataBits = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----- Stop bits -----
|
||||||
|
uint32_t cr2 = 0;
|
||||||
|
switch(lc->bCharFormat){ // usb_LineCoding have no 0.5 stop bits field
|
||||||
|
case USB_CDC_1_5_STOP_BITS:
|
||||||
|
cr2 |= USART_CR2_STOP_0 | USART_CR2_STOP_1; // 1.5 stop bits -> CR2=11
|
||||||
|
break;
|
||||||
|
case USB_CDC_2_STOP_BITS:
|
||||||
|
cr2 |= USART_CR2_STOP_1; // 2 stop bits -> CR2=10
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// do nothing: default to 1 stop bit -> CR2=00
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write CR2 (stop bits)
|
||||||
|
U->CR2 = cr2;
|
||||||
|
// Enable transmitter, receiver, and RX interrupt (optional)
|
||||||
|
cr1 |= USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_RXNEIE;
|
||||||
|
U->CR1 = cr1;
|
||||||
|
|
||||||
|
// Wait for the idle frame to complete (optional)
|
||||||
|
uint32_t tmout = 16000000;
|
||||||
|
while(!(U->ISR & USART_ISR_TC)){
|
||||||
|
if (--tmout == 0) break;
|
||||||
|
}
|
||||||
|
U->ICR = 0xFFFFFFFF; // Clear flags again
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: leave only uart5_exti35_isr, other - over DMA
|
||||||
|
// UART5 [IF5] Tx - over finite-state machine
|
||||||
|
|
||||||
|
/*
|
||||||
|
DMA1 channels:
|
||||||
|
- Ch2: USART3_Tx [IF1]
|
||||||
|
- Ch3: USART3_Rx [IF1]
|
||||||
|
- Ch4: USART1_Tx [IF2]
|
||||||
|
- Ch5: USART1_Rx [IF2]
|
||||||
|
- Ch6: USART2_Rx [IF3]
|
||||||
|
- Ch7: USART2_Tx [IF3]
|
||||||
|
|
||||||
|
DMA2 channels:
|
||||||
|
- Ch3: UART4_Rx [IF4]
|
||||||
|
- Ch5: UART4_Tx [IF4]
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void usart_isr(int usartno, volatile USART_TypeDef *U){
|
||||||
|
int iface = usartByIfNo[usartno]; // interface
|
||||||
|
if(U->ISR & USART_ISR_RXNE){
|
||||||
|
USB_putbyte(iface, U->RDR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void usart1_exti25_isr(){
|
||||||
|
usart_isr(1, USART1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usart2_exti26_isr(){
|
||||||
|
usart_isr(2, USART2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usart3_exti28_isr(){
|
||||||
|
usart_isr(3, USART3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart4_exti34_isr(){
|
||||||
|
usart_isr(4, UART4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart5_exti35_isr(){
|
||||||
|
usart_isr(5, UART5);
|
||||||
|
}
|
||||||
26
F3:F303/InterfaceBoard/usart.h
Normal file
26
F3:F303/InterfaceBoard/usart.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the multiiface 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 "hardware.h"
|
||||||
|
#include "usb_dev.h"
|
||||||
|
|
||||||
|
void usarts_setup();
|
||||||
|
void usart_config(uint8_t ifNo, usb_LineCoding *lc);
|
||||||
|
void usart_sendn(uint8_t ifNo, const uint8_t *str, int L);
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
// amount of interfaces
|
// amount of interfaces
|
||||||
#define InterfacesAmount 7
|
#define InterfacesAmount 7
|
||||||
// index of interface (ep number minus one)
|
// index of interface (ep number minus one): IF1..IF7
|
||||||
#define ISerial0 0
|
#define ISerial0 0
|
||||||
#define ISerial1 1
|
#define ISerial1 1
|
||||||
#define ISerial2 2
|
#define ISerial2 2
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
#include "usart.h"
|
||||||
#include "usb_descr.h"
|
#include "usb_descr.h"
|
||||||
#include "usb_dev.h"
|
#include "usb_dev.h"
|
||||||
|
|
||||||
@@ -59,20 +60,13 @@ static volatile ringbuffer rbin[InterfacesAmount] = {IBUF(0), IBUF(1), IBUF(2),
|
|||||||
static volatile int lastdsz[InterfacesAmount] = {-1, -1, -1, -1, -1, -1, -1};
|
static volatile int lastdsz[InterfacesAmount] = {-1, -1, -1, -1, -1, -1, -1};
|
||||||
|
|
||||||
static void chkin(uint8_t ifno){
|
static void chkin(uint8_t ifno){
|
||||||
static int ovrflctr = 0; // "antistall" counter
|
|
||||||
if(bufovrfl[ifno]) return; // allow user to know that previous buffer was overflowed and cleared
|
if(bufovrfl[ifno]) return; // allow user to know that previous buffer was overflowed and cleared
|
||||||
if(!rcvbuflen[ifno]) return;
|
if(!rcvbuflen[ifno]) return;
|
||||||
int w = RB_write((ringbuffer*)&rbin[ifno], (uint8_t*)rcvbuf[ifno], rcvbuflen[ifno]);
|
int w = RB_write((ringbuffer*)&rbin[ifno], (uint8_t*)rcvbuf[ifno], rcvbuflen[ifno]);
|
||||||
if(w < 0){ // buffer busy
|
if(w < 0){
|
||||||
return;
|
return;
|
||||||
}else if(w == 0){ // no enough space or (WTF) incoming string larger than buffer size
|
|
||||||
if(rcvbuflen[ifno] > rbin[ifno].length || ++ovrflctr > 9999){
|
|
||||||
bufovrfl[ifno] = 1; // real overflow in case if ringbuffer's size less than USB buffer
|
|
||||||
ovrflctr = 0;
|
|
||||||
}else{
|
|
||||||
return; // not enough space
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if(w != rcvbuflen[ifno]) bufovrfl[ifno] = 1;
|
||||||
rcvbuflen[ifno] = 0;
|
rcvbuflen[ifno] = 0;
|
||||||
uint16_t status = KEEP_DTOG(USB->EPnR[1+ifno]); // don't change DTOG
|
uint16_t status = KEEP_DTOG(USB->EPnR[1+ifno]); // don't change DTOG
|
||||||
USB->EPnR[1+ifno] = (status & ~(USB_EPnR_STAT_TX|USB_EPnR_CTR_RX)) ^ USB_EPnR_STAT_RX; // prepare to get next data portion
|
USB->EPnR[1+ifno] = (status & ~(USB_EPnR_STAT_TX|USB_EPnR_CTR_RX)) ^ USB_EPnR_STAT_RX; // prepare to get next data portion
|
||||||
@@ -103,7 +97,7 @@ static void send_next(uint8_t ifno){
|
|||||||
// data IN/OUT handler
|
// data IN/OUT handler
|
||||||
static void rxtx_handler(){
|
static void rxtx_handler(){
|
||||||
uint8_t epno = (USB->ISTR & USB_ISTR_EPID), ifno = epno - 1;
|
uint8_t epno = (USB->ISTR & USB_ISTR_EPID), ifno = epno - 1;
|
||||||
if(epno > InterfacesAmount){
|
if(ifno > InterfacesAmount-1){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]);
|
uint16_t epstatus = KEEP_DTOG(USB->EPnR[epno]);
|
||||||
@@ -123,8 +117,8 @@ static void rxtx_handler(){
|
|||||||
|
|
||||||
// SET_LINE_CODING
|
// SET_LINE_CODING
|
||||||
void linecoding_handler(uint8_t ifno, usb_LineCoding *lc){
|
void linecoding_handler(uint8_t ifno, usb_LineCoding *lc){
|
||||||
|
usart_config(ifno, lc); // lc would be real speed!
|
||||||
lineCoding[ifno] = *lc;
|
lineCoding[ifno] = *lc;
|
||||||
// TODO: set up interfaces
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear IN/OUT buffers on connection
|
// clear IN/OUT buffers on connection
|
||||||
@@ -137,7 +131,6 @@ static void clearbufs(uint8_t ifno){
|
|||||||
while(Tms - T0 < 10){
|
while(Tms - T0 < 10){
|
||||||
if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break;
|
if(1 == RB_clearbuf((ringbuffer*)&rbout[ifno])) break;
|
||||||
}
|
}
|
||||||
rcvbuflen[ifno] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SET_CONTROL_LINE_STATE
|
// SET_CONTROL_LINE_STATE
|
||||||
@@ -208,7 +201,7 @@ int USB_sendall(uint8_t ifno){
|
|||||||
uint32_t T0 = Tms;
|
uint32_t T0 = Tms;
|
||||||
while(lastdsz[ifno] > 0){
|
while(lastdsz[ifno] > 0){
|
||||||
if(Tms - T0 > DISCONN_TMOUT){
|
if(Tms - T0 > DISCONN_TMOUT){
|
||||||
break_handler(ifno);
|
//break_handler(ifno);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(!CDCready[ifno]) return FALSE;
|
if(!CDCready[ifno]) return FALSE;
|
||||||
@@ -223,7 +216,7 @@ int USB_send(uint8_t ifno, const uint8_t *buf, int len){
|
|||||||
uint32_t T0 = Tms;
|
uint32_t T0 = Tms;
|
||||||
while(len){
|
while(len){
|
||||||
if(Tms - T0 > DISCONN_TMOUT){
|
if(Tms - T0 > DISCONN_TMOUT){
|
||||||
break_handler(ifno);
|
//break_handler(ifno);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(!CDCready[ifno]) return FALSE;
|
if(!CDCready[ifno]) return FALSE;
|
||||||
@@ -254,7 +247,7 @@ int USB_putbyte(uint8_t ifno, uint8_t byte){
|
|||||||
uint32_t T0 = Tms;
|
uint32_t T0 = Tms;
|
||||||
while((l = RB_write((ringbuffer*)&rbout[ifno], &byte, 1)) != 1){
|
while((l = RB_write((ringbuffer*)&rbout[ifno], &byte, 1)) != 1){
|
||||||
if(Tms - T0 > DISCONN_TMOUT){
|
if(Tms - T0 > DISCONN_TMOUT){
|
||||||
break_handler(ifno);
|
//break_handler(ifno);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(!CDCready[ifno]) return FALSE;
|
if(!CDCready[ifno]) return FALSE;
|
||||||
|
|||||||
Reference in New Issue
Block a user