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++) {
132 if (!uart_soft_rx_states[rx]) {
135 if (!rx_baudrates || rx_baudrates[rx]==0) {
138 uart_soft_rx_states[rx]->
baudrate = rx_baudrates[rx];
139 rcc_periph_clock_enable(uart_soft_rx_states[rx]->
rcc);
140 gpio_set_mode(uart_soft_rx_states[rx]->
port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, uart_soft_rx_states[rx]->
pin);
141 gpio_set(uart_soft_rx_states[rx]->
port, uart_soft_rx_states[rx]->
pin);
142 rcc_periph_clock_enable(RCC_AFIO);
143 exti_select_source(uart_soft_rx_states[rx]->
exti, uart_soft_rx_states[rx]->
port);
144 exti_enable_request(uart_soft_rx_states[rx]->
exti);
145 exti_set_trigger(uart_soft_rx_states[rx]->
exti, EXTI_TRIGGER_BOTH);
146 nvic_enable_irq(uart_soft_rx_states[rx]->
irq);
147 uart_soft_rx_states[rx]->
state = gpio_get(uart_soft_rx_states[rx]->
port, uart_soft_rx_states[rx]->
pin);
148 uart_soft_rx_states[rx]->
bit = 0;
152 #if defined(UART_SOFT_TX_PORT0) && defined(UART_SOFT_TX_PIN0) 160 for (uint8_t tx=0; tx<4; tx++) {
161 if (!uart_soft_tx_states[tx]) {
164 if (!tx_baudrates || tx_baudrates[tx]==0) {
167 uart_soft_tx_states[tx]->
baudrate = tx_baudrates[tx];
168 rcc_periph_clock_enable(uart_soft_tx_states[tx]->
rcc);
169 gpio_set_mode(uart_soft_tx_states[tx]->
port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, uart_soft_tx_states[tx]->
pin);
170 gpio_set(uart_soft_tx_states[tx]->
port, uart_soft_tx_states[tx]->
pin);
174 #if defined(UART_SOFT_RX_TIMER) 182 #if defined(UART_SOFT_TX_TIMER) 194 #if defined(UART_SOFT_RX_TIMER) 197 if (uart>=4 || !uart_soft_rx_states[uart]) {
203 uart_soft_rx_states[uart]->
lock =
true;
204 uint8_t to_return = uart_soft_rx_states[uart]->
buffer[uart_soft_rx_states[uart]->
buffer_i];
207 uart_soft_rx_states[uart]->
lock =
false;
214 uart_soft_rx_states[uart]->
lock =
false;
221 for (uint8_t rx=0; rx<4; rx++) {
224 if (!uart_soft_rx_states[rx]) {
227 uart_soft_rx_states[rx]->
byte += ((gpio_get(uart_soft_rx_states[rx]->
port, uart_soft_rx_states[rx]->
pin)==0 ? 0 : 1)<<(uart_soft_rx_states[rx]->
bit-1));
228 if (uart_soft_rx_states[rx]->
bit<8) {
230 uart_soft_rx_states[rx]->
bit++;
232 if (uart_soft_rx_states[rx]->
lock) {
245 uart_soft_rx_states[rx]->
bit = 0;
252 #if defined(UART_SOFT_TX_TIMER) 255 if (uart>=4 || !uart_soft_tx_states[uart]) {
261 while (uart_soft_tx_states[uart]->
transmit) {
270 if (uart>=4 || !uart_soft_tx_states[uart]) {
273 if (uart_soft_tx_states[uart]->
transmit) {
279 uart_soft_tx_states[uart]->
byte = uart_soft_tx_states[uart]->
buffer[uart_soft_tx_states[uart]->
buffer_i];
282 uart_soft_tx_states[uart]->
bit = 0;
283 uart_soft_tx_states[uart]->
transmit =
true;
284 gpio_clear(uart_soft_tx_states[uart]->
port, uart_soft_tx_states[uart]->
pin);
292 if (uart>=4 || !uart_soft_tx_states[uart]) {
312 for (uint8_t tx=0; tx<4; tx++) {
315 if (!uart_soft_tx_states[tx]) {
318 if (uart_soft_tx_states[tx]->
bit<8) {
319 if ((uart_soft_tx_states[tx]->
byte>>uart_soft_tx_states[tx]->
bit)&0x01) {
320 gpio_set(uart_soft_tx_states[tx]->
port, uart_soft_tx_states[tx]->
pin);
322 gpio_clear(uart_soft_tx_states[tx]->
port, uart_soft_tx_states[tx]->
pin);
325 uart_soft_tx_states[tx]->
bit++;
326 }
else if (uart_soft_tx_states[tx]->
bit==8) {
327 gpio_set(uart_soft_tx_states[tx]->
port, uart_soft_tx_states[tx]->
pin);
329 uart_soft_tx_states[tx]->
bit++;
332 uart_soft_tx_states[tx]->
transmit =
false;
343 for (uint8_t rx=0; rx<4; rx++) {
344 if (!uart_soft_rx_states[rx]) {
347 if (uart_soft_rx_states[rx]->
state!=gpio_get(uart_soft_rx_states[rx]->
port, uart_soft_rx_states[rx]->
pin)) {
348 uart_soft_rx_states[rx]->
state = gpio_get(uart_soft_rx_states[rx]->
port, uart_soft_rx_states[rx]->
pin);
349 if (uart_soft_rx_states[rx]->
bit==0) {
350 if (uart_soft_rx_states[rx]->
state==0) {
354 uart_soft_rx_states[rx]->
byte = 0;
355 uart_soft_rx_states[rx]->
bit++;
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.
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