ASCII Serial Com
Serial communication library between computers, microcontrollers, FPGAs, etc. Uses only ASCII. Not the most efficient protocol, but meant to be easy to read
Loading...
Searching...
No Matches
stm_usart.h
Go to the documentation of this file.
1#ifndef STM_USART_H
2#define STM_USART_H
3
4/** \file
5 *
6 * \brief To be used with the USART peripherals on STM32 microcontrollers
7 *
8 * */
9
10#include <libopencm3/stm32/gpio.h>
11#include <libopencm3/stm32/usart.h>
12#include <stdint.h>
13
14/** \brief Setup a USART
15 *
16 * Setup a USART in async, 8 bit, 1 stop bit, no parity, no flow-control, tx-rx
17 * mode.
18 *
19 * ## Notes
20 *
21 * **The user must setup the peripheral clocks for both this USART and the
22 * GPIO input/outpu port(s).**
23 *
24 * **The user must enable the USART when ready with:**
25 * `usart_enable(usart);`
26 *
27 * **This macro takes care of setting up the GPIO pins.**
28 *
29 * **Not sure if this works with UARTs or LPUARTs**
30 *
31 * ## Parameters
32 *
33 * usart: the USART you want to use like USART1, USART2, ...
34 *
35 * baud: the baud rate of the USART, uint32_t
36 *
37 * tx_port: GPIOA, GPIOB, ...
38 *
39 * tx_pin: GPIO0, GPIO1, ...
40 *
41 * tx_af: alternate function for the given pin/port to hook it up to the USART,
42 * e.g. GPIO_AF0, GPIO_AF1, ...
43 *
44 * rx_port: GPIOA, GPIOB, ...
45 *
46 * rx_pin: GPIO0, GPIO1, ...
47 *
48 * rx_af: alternate function for the given pin/port to hook it up to the USART,
49 * e.g. GPIO_AF0, GPIO_AF1, ...
50 *
51 */
52#define setup_usart(usart, baud, tx_port, tx_pin, tx_af, rx_port, rx_pin, \
53 rx_af) \
54 gpio_mode_setup(tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, tx_pin); \
55 gpio_set_af(tx_port, tx_af, tx_pin); \
56 \
57 gpio_mode_setup(rx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, rx_pin); \
58 gpio_set_af(rx_port, rx_af, rx_pin); \
59 \
60 usart_set_baudrate(usart, baud); \
61 usart_set_databits(usart, 8); \
62 usart_set_parity(usart, USART_PARITY_NONE); \
63 usart_set_stopbits(usart, USART_CR2_STOPBITS_1); \
64 usart_set_mode(usart, USART_MODE_TX_RX); \
65 usart_set_flow_control(usart, USART_FLOWCONTROL_NONE)
66
67/** \brief Define the ISR for a USART to push rx bytes to a circular buffer
68 *
69 * Defines the interrupt handler for the given USART. The interrupt handler
70 * will push all rx bytes to the back of the circular buffer the user provides.
71 *
72 * ## Notes
73 *
74 * **DON'T USE A SEMICOLON AFTER THIS MACRO.**
75 *
76 * **Use atomic operations to remove data from the front of the circular
77 * buffer** like `CM_ATOMIC_BLOCK() {}`
78 *
79 * **Make sure to setup the USART and run both**
80 * `nvic_enable_irq(NVIC_<usart>_IRQ);` and
81 * `usart_enable_rx_interrupt(<usart>);`
82 *
83 * **Not sure if this works with UARTs or LPUARTs**
84 *
85 * ## Parameters
86 *
87 * isr_name: usart1_isr, usart2_isr, ...
88 *
89 * usart: the USART you want to use like USART1, USART2, ...
90 *
91 * circular_buffer: a pointer to a circular_buffer_uint8 that you want received
92 * bytes pushed_back on.
93 *
94 */
95#define def_usart_isr_push_rx_to_circ_buf(isr_name, usart, circular_buffer) \
96 _Pragma("GCC diagnostic ignored \"-Wshadow\"") \
97 _Pragma("GCC diagnostic push") \
98 _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \
99 _Pragma("GCC diagnostic push") void \
100 isr_name(void) { \
101 _Pragma("GCC diagnostic pop") _Pragma( \
102 "GCC diagnostic pop") if (((USART_CR1(usart) & USART_CR1_RXNEIE) != \
103 0) && \
104 ((USART_ISR(usart) & USART_ISR_RXNE) != \
105 0)) { \
106 circular_buffer_push_back_uint8(circular_buffer, \
107 usart_recv(usart) & 0xFF); \
108 } \
109 }
110
111#endif