27 #include <libopencm3/stm32/rcc.h> 28 #include <libopencm3/stm32/gpio.h> 29 #include <libopencm3/stm32/timer.h> 30 #include <libopencm3/cm3/nvic.h> 31 #include <libopencm3/stm32/exti.h> 32 #include <libopencmsis/core_cm3.h> 42 #define UART_SOFT_RX_PORT0 B 43 #define UART_SOFT_RX_PIN0 9 44 //#define UART_SOFT_RX_PORT1 A 45 //#define UART_SOFT_RX_PIN1 0 46 //#define UART_SOFT_RX_PORT2 A 47 //#define UART_SOFT_RX_PIN2 0 48 //#define UART_SOFT_RX_PORT3 A 49 //#define UART_SOFT_RX_PIN3 0 50 #define UART_SOFT_TX_PORT0 B 51 #define UART_SOFT_TX_PIN0 8 52 //#define UART_SOFT_TX_PORT1 A 53 //#define UART_SOFT_TX_PIN1 0 54 //#define UART_SOFT_TX_PORT2 A 55 //#define UART_SOFT_TX_PIN2 0 56 //#define UART_SOFT_TX_PORT3 A 57 //#define UART_SOFT_TX_PIN3 0 61 #define UART_SOFT_BUFFER 128 103 #if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0)) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1)) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2)) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN0)) 104 #define UART_SOFT_RX_TIMER 3 106 #if (defined(UART_SOFT_TX_PORT0) && defined(UART_SOFT_TX_PIN0)) || (defined(UART_SOFT_TX_PORT1) && defined(UART_SOFT_TX_PIN1)) || (defined(UART_SOFT_TX_PORT2) && defined(UART_SOFT_TX_PIN2)) || (defined(UART_SOFT_TX_PORT3) && defined(UART_SOFT_TX_PIN0)) 107 #define UART_SOFT_TX_TIMER 4 111 static const uint32_t
timer_flags[4] = {TIM_SR_CC1IF,TIM_SR_CC2IF,TIM_SR_CC3IF,TIM_SR_CC4IF};
112 static const uint32_t
timer_interrupt[4] = {TIM_DIER_CC1IE,TIM_DIER_CC2IE,TIM_DIER_CC3IE,TIM_DIER_CC4IE};
113 static const enum tim_oc_id
timer_oc[4] = {TIM_OC1,TIM_OC2,TIM_OC3,TIM_OC4};
121 #if defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) 131 for (uint8_t rx=0; rx<4; rx++) {
135 if (!rx_baudrates || rx_baudrates[rx]==0) {
142 rcc_periph_clock_enable(RCC_AFIO);
152 #if defined(UART_SOFT_TX_PORT0) && defined(UART_SOFT_TX_PIN0) 160 for (uint8_t tx=0; tx<4; tx++) {
164 if (!tx_baudrates || tx_baudrates[tx]==0) {
174 #if defined(UART_SOFT_RX_TIMER) 182 #if defined(UART_SOFT_TX_TIMER) 194 #if defined(UART_SOFT_RX_TIMER) 221 for (uint8_t rx=0; rx<4; rx++) {
252 #if defined(UART_SOFT_TX_TIMER) 312 for (uint8_t tx=0; tx<4; tx++) {
343 for (uint8_t rx=0; rx<4; rx++) {
365 #if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==0) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==0) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==0) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==0) 368 exti_reset_request(EXTI0);
372 #if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==1) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==1) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==1) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==1) 375 exti_reset_request(EXTI1);
379 #if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==2) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==2) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==2) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==2) 382 exti_reset_request(EXTI2);
386 #if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==3) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==3) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==3) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==3) 389 exti_reset_request(EXTI3);
393 #if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==4) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==4) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==4) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==4) 396 exti_reset_request(EXTI4);
400 #if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && (UART_SOFT_RX_PIN0==5 || UART_SOFT_RX_PIN0==6 || UART_SOFT_RX_PIN0==7 || UART_SOFT_RX_PIN0==8 || UART_SOFT_RX_PIN0==9)) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && (UART_SOFT_RX_PIN1==5 || UART_SOFT_RX_PIN1==6 || UART_SOFT_RX_PIN1==7 || UART_SOFT_RX_PIN1==8 || UART_SOFT_RX_PIN1==9)) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && (UART_SOFT_RX_PIN2==5 || UART_SOFT_RX_PIN2==6 || UART_SOFT_RX_PIN2==7 || UART_SOFT_RX_PIN2==8 || UART_SOFT_RX_PIN2==9)) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && (UART_SOFT_RX_PIN3==5 || UART_SOFT_RX_PIN3==6 || UART_SOFT_RX_PIN3==7 || UART_SOFT_RX_PIN3==8 || UART_SOFT_RX_PIN3==9)) 403 exti_reset_request(EXTI5|EXTI6|EXTI7|EXTI8|EXTI9);
407 #if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && (UART_SOFT_RX_PIN0==10 || UART_SOFT_RX_PIN0==11 || UART_SOFT_RX_PIN0==12 || UART_SOFT_RX_PIN0==13 || UART_SOFT_RX_PIN0==14 || UART_SOFT_RX_PIN0==15)) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && (UART_SOFT_RX_PIN1==10 || UART_SOFT_RX_PIN1==11 || UART_SOFT_RX_PIN1==12 || UART_SOFT_RX_PIN1==13 || UART_SOFT_RX_PIN1==14 || UART_SOFT_RX_PIN1==15)) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && (UART_SOFT_RX_PIN2==10 || UART_SOFT_RX_PIN2==11 || UART_SOFT_RX_PIN2==12 || UART_SOFT_RX_PIN2==13 || UART_SOFT_RX_PIN2==14 || UART_SOFT_RX_PIN2==15)) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && (UART_SOFT_RX_PIN3==10 || UART_SOFT_RX_PIN3==11 || UART_SOFT_RX_PIN3==12 || UART_SOFT_RX_PIN3==13 || UART_SOFT_RX_PIN3==14 || UART_SOFT_RX_PIN3==15)) 408 void exti15_10_isr(
void)
410 exti_reset_request(EXTI10|EXTI11|EXTI12|EXTI13|EXTI14|EXTI15);
void uart_soft_putbyte_nonblocking(uint8_t uart, uint8_t byte)
put byte in buffer to be transmitted on UART port
#define TIM_ISR(x)
get interrupt service routine for timer base on TIM identifier
uint32_t exti
UART receive external interrupt.
#define RCC_GPIO(x)
get RCC for GPIO based on GPIO identifier
volatile bool buffer_byte_used
signal a byte has been stored in temporary buffer
#define UART_SOFT_RX_PORT0
port for receive signal for UART port 0
uint32_t baudrate
UART receive baud rate.
uint32_t rcc
UART receive port peripheral clock.
#define NVIC_TIM_IRQ(x)
get NVIC IRQ for timer base on TIM identifier
void uart_soft_flush(uint8_t uart)
ensure all bytes are transmitted for the UART
volatile bool transmit
flag to know it transmission is ongoing
#define UART_SOFT_TX_PIN0
pin for transmit signal for UART port 0
#define NVIC_EXTI_IRQ(x)
get NVIC IRQ for external interrupt base on external interrupt/pin
volatile uint8_t buffer_used
how much data is available
#define UART_SOFT_RX_PIN0
pin for receive signal for UART port 0
static void uart_soft_transmit(uint8_t uart)
start transmitting a byte from the buffer
library to control up to 4 independent receive and transmit software UART ports (API) ...
volatile uint8_t buffer_i
index of current data to be read out
global definitions and methods (API)
#define GPIO(x)
get GPIO based on GPIO identifier
volatile uint8_t bit
next UART frame bit to receive
uint32_t baudrate
UART receive baud rate.
void uart_soft_putbyte_blocking(uint8_t uart, uint8_t byte)
transmit byte on UART port
#define RCC_TIM(x)
get RCC for timer based on TIM identifier
#define UART_SOFT_TX_PORT0
port for transmit signal for UART port 0
uint32_t port
UART receive port.
uint8_t uart_soft_getbyte(uint8_t uart)
get received byte from UART port
volatile bool lock
put lock when changing buffer_i or buffer_used
volatile uint8_t bit
next UART frame bit to transmit
volatile uint8_t buffer_used
how much data is available
uint16_t pin
UART receive pin.
UART receive state definition.
UART transmit state definition.
volatile uint8_t byte
byte being transmitted
#define EXTI(x)
get external interrupt based on pin identifier
#define UART_SOFT_TX_TIMER
timer peripheral for transmit signals
volatile uint8_t byte
byte being received
volatile uint8_t buffer_i
index of current data to be read out
void exti9_5_isr(void)
GPIO interrupt service routine to detect UART receive activity.
static uint8_t * buffer
input/output buffer for read/write commands/functions
uint32_t port
UART receive port.
static const uint32_t timer_interrupt[4]
the interrupt enable for the compare units
static enum tim_oc_id timer_oc[4]
the output compares for the compare units
volatile uint16_t state
GPIO state for receive pin.
uint32_t irq
UART receive interrupt request.
volatile uint8_t buffer_byte
to temporary store byte while locked
#define LENGTH(x)
get the length of an array
#define UART_SOFT_RX_TIMER
timer peripheral for receive signals
volatile uint8_t buffer[UART_SOFT_BUFFER]
receive buffer
bool uart_soft_setup(uint32_t *rx_baudrates, uint32_t *tx_baudrates)
setup software UART ports
volatile uint8_t buffer[UART_SOFT_BUFFER]
receive buffer
#define TIM(x)
get TIM based on TIM identifier
uint32_t rcc
UART receive port peripheral clock.
static struct soft_uart_tx_state * uart_soft_tx_states[4]
states of UART transmit ports (up to 4)
#define UART_SOFT_BUFFER
buffer size for receive and transmit buffers
static struct soft_uart_rx_state * uart_soft_rx_states[4]
states of UART receive ports (up to 4)
static const uint32_t timer_flags[4]
the interrupt flags for the compare units
uint16_t pin
UART receive pin.
static void uart_soft_receive_activity(void)
central function handling receive signal activity
volatile bool uart_soft_received[4]
if data has been received from UART port and is available to be read