mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-28 01:53:48 +08:00
[stm32][ground_segment] Add UART hardware flow control with libopencm3
* ground segment: serial ocaml lib, link and logalizer * Added UART hardware flow control to UART1 for STM32 To enable define UART1_HW_FLOW_CONTROL to 1 closes #283
This commit is contained in:
@@ -56,7 +56,7 @@ static inline void uart_set_baudrate(struct uart_periph* p, uint32_t baud) {
|
||||
((uartRegs_t *)(p->reg_addr))->fcr = UART_FIFO_8;
|
||||
}
|
||||
|
||||
void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud) {
|
||||
void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud, bool_t hw_flow_control __attribute__ ((unused))) {
|
||||
uart_disable_interrupts(p);
|
||||
uart_set_baudrate(p, baud);
|
||||
uart_enable_interrupts(p);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "fms/fms_serial_port.h"
|
||||
|
||||
|
||||
void uart_periph_set_baudrate(struct uart_periph* p, uint16_t baud) {
|
||||
void uart_periph_set_baudrate(struct uart_periph* p, uint16_t baud, bool_t hw_flow_control __attribute__ ((unused))) {
|
||||
struct FmsSerialPort* fmssp;
|
||||
// close serial port if already open
|
||||
if (p->reg_addr != NULL) {
|
||||
|
||||
@@ -29,15 +29,22 @@
|
||||
#include <libopencm3/stm32/f1/gpio.h>
|
||||
#include "std.h"
|
||||
|
||||
void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud) {
|
||||
void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud, bool_t hw_flow_control) {
|
||||
|
||||
/* Configure USART */
|
||||
usart_set_baudrate((u32)p->reg_addr, baud);
|
||||
usart_set_databits((u32)p->reg_addr, 8);
|
||||
usart_set_stopbits((u32)p->reg_addr, USART_STOPBITS_1);
|
||||
usart_set_parity((u32)p->reg_addr, USART_PARITY_NONE);
|
||||
usart_set_flow_control((u32)p->reg_addr, USART_FLOWCONTROL_NONE);
|
||||
usart_set_mode((u32)p->reg_addr, USART_MODE_TX_RX);
|
||||
|
||||
if (hw_flow_control) {
|
||||
usart_set_flow_control((u32)p->reg_addr, USART_FLOWCONTROL_RTS_CTS);
|
||||
}
|
||||
else {
|
||||
usart_set_flow_control((u32)p->reg_addr, USART_FLOWCONTROL_NONE);
|
||||
}
|
||||
|
||||
/* Enable USART1 Receive interrupts */
|
||||
USART_CR1((u32)p->reg_addr) |= USART_CR1_RXNEIE;
|
||||
|
||||
@@ -126,8 +133,19 @@ void uart1_init( void ) {
|
||||
gpio_set_mode(GPIO_BANK_USART1_RX, GPIO_MODE_INPUT,
|
||||
GPIO_CNF_INPUT_FLOAT, GPIO_USART1_RX);
|
||||
|
||||
/* Configure USART */
|
||||
uart_periph_set_baudrate(&uart1, UART1_BAUD);
|
||||
#if UART1_HW_FLOW_CONTROL
|
||||
#warning "USING UART1 FLOW CONTROL. Make sure to pull down CTS if you are not connecting any flow-control-capable hardware."
|
||||
gpio_set_mode(GPIO_BANK_USART1_RTS, GPIO_MODE_OUTPUT_50_MHZ,
|
||||
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_RTS);
|
||||
gpio_set_mode(GPIO_BANK_USART1_CTS, GPIO_MODE_INPUT,
|
||||
GPIO_CNF_INPUT_FLOAT, GPIO_USART1_CTS);
|
||||
|
||||
/* Configure USART1, enable hardware flow control*/
|
||||
uart_periph_set_baudrate(&uart1, UART1_BAUD, TRUE);
|
||||
#else
|
||||
/* Configure USART1, no flow control */
|
||||
uart_periph_set_baudrate(&uart1, UART1_BAUD, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usart1_isr(void) { usart_isr(&uart1); }
|
||||
@@ -155,7 +173,7 @@ void uart2_init( void ) {
|
||||
GPIO_CNF_INPUT_FLOAT, GPIO_USART2_RX);
|
||||
|
||||
/* Configure USART */
|
||||
uart_periph_set_baudrate(&uart2, UART2_BAUD);
|
||||
uart_periph_set_baudrate(&uart2, UART2_BAUD, FALSE);
|
||||
}
|
||||
|
||||
void usart2_isr(void) { usart_isr(&uart2); }
|
||||
@@ -185,7 +203,7 @@ void uart3_init( void ) {
|
||||
GPIO_CNF_INPUT_FLOAT, GPIO_USART3_PR_RX);
|
||||
|
||||
/* Configure USART */
|
||||
uart_periph_set_baudrate(&uart3, UART3_BAUD);
|
||||
uart_periph_set_baudrate(&uart3, UART3_BAUD, FALSE);
|
||||
}
|
||||
|
||||
void usart3_isr(void) { usart_isr(&uart3); }
|
||||
@@ -214,7 +232,7 @@ void uart5_init( void ) {
|
||||
GPIO_CNF_INPUT_FLOAT, GPIO_UART5_RX);
|
||||
|
||||
/* Configure USART */
|
||||
uart_periph_set_baudrate(&uart5, UART5_BAUD);
|
||||
uart_periph_set_baudrate(&uart5, UART5_BAUD, FALSE);
|
||||
}
|
||||
|
||||
void uart5_isr(void) { usart_isr(&uart5); }
|
||||
|
||||
@@ -57,7 +57,7 @@ struct uart_periph {
|
||||
};
|
||||
|
||||
extern void uart_periph_init(struct uart_periph* p);
|
||||
extern void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud);
|
||||
extern void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud, bool_t hw_flow_control);
|
||||
//extern void uart_periph_init_param(struct uart_periph* p, uint32_t baud, uint8_t mode, uint8_t fmode, char * dev);
|
||||
extern void uart_transmit(struct uart_periph* p, uint8_t data);
|
||||
extern bool_t uart_check_free_space(struct uart_periph* p, uint8_t len);
|
||||
@@ -82,7 +82,7 @@ extern void uart0_init(void);
|
||||
#define Uart0ChAvailable() UartChAvailable(uart0)
|
||||
#define Uart0Getch() UartGetch(uart0)
|
||||
#define Uart0TxRunning uart0.tx_running
|
||||
#define Uart0SetBaudrate(_b) uart_periph_set_baudrate(&uart0, _b)
|
||||
#define Uart0SetBaudrate(_b) uart_periph_set_baudrate(&uart0, _b, FALSE)
|
||||
//#define Uart0InitParam(_b, _m, _fm) uart_periph_init_param(&uart0, _b, _m, _fm, "")
|
||||
|
||||
#define UART0Init Uart0Init
|
||||
@@ -107,7 +107,11 @@ extern void uart1_init(void);
|
||||
#define Uart1ChAvailable() UartChAvailable(uart1)
|
||||
#define Uart1Getch() UartGetch(uart1)
|
||||
#define Uart1TxRunning uart1.tx_running
|
||||
#define Uart1SetBaudrate(_b) uart_periph_set_baudrate(&uart1, _b)
|
||||
#if UART1_HW_FLOW_CONTROL
|
||||
#define Uart1SetBaudrate(_b) uart_periph_set_baudrate(&uart1, _b, TRUE)
|
||||
#else
|
||||
#define Uart1SetBaudrate(_b) uart_periph_set_baudrate(&uart1, _b, FALSE)
|
||||
#endif
|
||||
//#define Uart1InitParam(_b, _m, _fm) uart_periph_init_param(&uart1, _b, _m, _fm, "")
|
||||
|
||||
#define UART1Init Uart1Init
|
||||
@@ -132,7 +136,7 @@ extern void uart2_init(void);
|
||||
#define Uart2ChAvailable() UartChAvailable(uart2)
|
||||
#define Uart2Getch() UartGetch(uart2)
|
||||
#define Uart2TxRunning uart2.tx_running
|
||||
#define Uart2SetBaudrate(_b) uart_periph_set_baudrate(&uart2, _b)
|
||||
#define Uart2SetBaudrate(_b) uart_periph_set_baudrate(&uart2, _b, FALSE)
|
||||
//#define Uart2InitParam(_b, _m, _fm) uart_periph_init_param(&uart2, _b, _m, _fm, "")
|
||||
|
||||
#define UART2Init Uart2Init
|
||||
@@ -157,7 +161,7 @@ extern void uart3_init(void);
|
||||
#define Uart3ChAvailable() UartChAvailable(uart3)
|
||||
#define Uart3Getch() UartGetch(uart3)
|
||||
#define Uart3TxRunning uart3.tx_running
|
||||
#define Uart3SetBaudrate(_b) uart_periph_set_baudrate(&uart3, _b)
|
||||
#define Uart3SetBaudrate(_b) uart_periph_set_baudrate(&uart3, _b, FALSE)
|
||||
//#define Uart3InitParam(_b, _m, _fm) uart_periph_init_param(&uart3, _b, _m, _fm, "")
|
||||
|
||||
#define UART3Init Uart3Init
|
||||
@@ -182,7 +186,7 @@ extern void uart5_init(void);
|
||||
#define Uart5ChAvailable() UartChAvailable(uart5)
|
||||
#define Uart5Getch() UartGetch(uart5)
|
||||
#define Uart5TxRunning uart5.tx_running
|
||||
#define Uart5SetBaudrate(_b) uart_periph_set_baudrate(&uart5, _b)
|
||||
#define Uart5SetBaudrate(_b) uart_periph_set_baudrate(&uart5, _b, FALSE)
|
||||
//#define Uart5InitParam(_b, _m, _fm) uart_periph_init_param(&uart5, _b, _m, _fm, "")
|
||||
|
||||
#define UART5Init Uart5Init
|
||||
|
||||
@@ -426,6 +426,7 @@ let () =
|
||||
let ivy_bus = ref Defivybus.default_ivy_bus
|
||||
and port = ref "/dev/ttyUSB0"
|
||||
and baudrate = ref "9600"
|
||||
and hw_flow_control = ref false
|
||||
and transport = ref "pprz"
|
||||
and uplink = ref true
|
||||
and audio = ref false
|
||||
@@ -443,6 +444,7 @@ let () =
|
||||
"-noac_info", Arg.Clear ac_info, (sprintf "Disables AC traffic info (uplink).");
|
||||
"-nouplink", Arg.Clear uplink, (sprintf "Disables the uplink (from the ground to the aircraft).");
|
||||
"-s", Arg.Set_string baudrate, (sprintf "<baudrate> Default is %s" !baudrate);
|
||||
"-hfc", Arg.Set hw_flow_control, "Enable UART hardware flow control (CTS/RTS)";
|
||||
"-local_timestamp", Arg.Unit (fun () -> add_timestamp := Some (Unix.gettimeofday ())), "Add local timestamp to messages sent over ivy";
|
||||
"-transport", Arg.Set_string transport, (sprintf "<transport> Available protocols are modem,pprz,pprz2 and xbee. Default is %s" !transport);
|
||||
"-udp", Arg.Set udp, "Listen a UDP connection on <udp_port>";
|
||||
@@ -475,7 +477,7 @@ let () =
|
||||
end else if !audio then
|
||||
Demod.init !port
|
||||
else if on_serial_device then
|
||||
Serial.opendev !port (Serial.speed_of_baudrate !baudrate)
|
||||
Serial.opendev !port (Serial.speed_of_baudrate !baudrate) !hw_flow_control
|
||||
else
|
||||
Unix.openfile !port [Unix.O_RDWR] 0o640
|
||||
in
|
||||
|
||||
@@ -40,7 +40,7 @@ static int baudrates[] = { B0, B50, B75, B110, B134, B150, B200, B300, B600, B12
|
||||
/****************************************************************************/
|
||||
/* Open serial device for requested protocoll */
|
||||
/****************************************************************************/
|
||||
value c_init_serial(value device, value speed)
|
||||
value c_init_serial(value device, value speed, value hw_flow_control)
|
||||
{
|
||||
struct termios orig_termios, cur_termios;
|
||||
|
||||
@@ -63,8 +63,14 @@ value c_init_serial(value device, value speed)
|
||||
cur_termios.c_oflag &=~(OPOST|ONLCR|OCRNL|ONOCR|ONLRET);
|
||||
|
||||
/* control modes */
|
||||
cur_termios.c_cflag &= ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL|CRTSCTS);
|
||||
cur_termios.c_cflag |= CREAD|CS8|CLOCAL;
|
||||
if (Bool_val(hw_flow_control)) {
|
||||
cur_termios.c_cflag &= ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL);
|
||||
cur_termios.c_cflag |= CREAD|CS8|CLOCAL|CRTSCTS;
|
||||
}
|
||||
else {
|
||||
cur_termios.c_cflag &= ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL|CRTSCTS);
|
||||
cur_termios.c_cflag |= CREAD|CS8|CLOCAL;
|
||||
}
|
||||
|
||||
/* local modes */
|
||||
cur_termios.c_lflag &= ~(ISIG|ICANON|IEXTEN|ECHO|FLUSHO|PENDIN);
|
||||
|
||||
@@ -77,13 +77,13 @@ let string_of_payload = fun x -> x
|
||||
let payload_of_string = fun x -> x
|
||||
|
||||
|
||||
external init_serial : string -> speed -> Unix.file_descr = "c_init_serial"
|
||||
external init_serial : string -> speed -> bool -> Unix.file_descr = "c_init_serial"
|
||||
external set_dtr : Unix.file_descr -> bool -> unit = "c_set_dtr"
|
||||
external set_speed : Unix.file_descr -> speed -> unit = "c_serial_set_baudrate"
|
||||
|
||||
let opendev device speed =
|
||||
let opendev device speed hw_flow_control =
|
||||
try
|
||||
init_serial device speed
|
||||
init_serial device speed hw_flow_control
|
||||
with
|
||||
Failure x ->
|
||||
failwith (Printf.sprintf "Error %s (%s)" x device)
|
||||
|
||||
@@ -49,7 +49,7 @@ type speed =
|
||||
|
||||
val speed_of_baudrate : string -> speed
|
||||
|
||||
val opendev : string -> speed -> Unix.file_descr
|
||||
val opendev : string -> speed -> bool -> Unix.file_descr
|
||||
val close : Unix.file_descr -> unit
|
||||
val set_dtr : Unix.file_descr -> bool -> unit
|
||||
val set_speed : Unix.file_descr -> speed -> unit
|
||||
|
||||
@@ -122,6 +122,7 @@ let was_running = ref false
|
||||
let bus = ref Defivybus.default_ivy_bus
|
||||
let port = ref "/dev/ttyUSB0"
|
||||
let baudrate = ref "9600"
|
||||
let hw_flow_control = ref false
|
||||
let file_to_load = ref ""
|
||||
let output_on_serial = ref false
|
||||
|
||||
@@ -177,7 +178,8 @@ let init = fun () ->
|
||||
[ "-b", Arg.String (fun x -> bus := x), (sprintf "<ivy bus> Default is %s" !bus);
|
||||
"-d", Arg.Set_string port, (sprintf "<port> Default is %s" !port);
|
||||
"-o", Arg.Set output_on_serial, "Output binary messages on serial port";
|
||||
"-s", Arg.Set_string baudrate, (sprintf "<baudrate> Default is %s" !baudrate)]
|
||||
"-s", Arg.Set_string baudrate, (sprintf "<baudrate> Default is %s" !baudrate);
|
||||
"-shfc", Arg.Set hw_flow_control, "Enable UART hardware flow control (CTS/RTS)";]
|
||||
(fun x -> file_to_load := x)
|
||||
"Usage: ";
|
||||
|
||||
@@ -187,7 +189,7 @@ let init = fun () ->
|
||||
|
||||
let serial_port =
|
||||
if !output_on_serial then
|
||||
Some (Unix.out_channel_of_descr (Serial.opendev !port (Serial.speed_of_baudrate !baudrate)))
|
||||
Some (Unix.out_channel_of_descr (Serial.opendev !port (Serial.speed_of_baudrate !baudrate) !hw_flow_control))
|
||||
else
|
||||
None in
|
||||
|
||||
|
||||
Reference in New Issue
Block a user