[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:
Felix Ruess
2012-10-17 00:54:00 +02:00
parent 0fe2f7a783
commit 6be3882435
9 changed files with 57 additions and 25 deletions
@@ -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);
+1 -1
View File
@@ -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) {
+25 -7
View File
@@ -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); }
+10 -6
View File
@@ -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
+3 -1
View File
@@ -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
+9 -3
View File
@@ -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);
+3 -3
View File
@@ -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)
+1 -1
View File
@@ -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
+4 -2
View File
@@ -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