CuVoodoo STM32F1 firmware template
busvoodoo_rs485.c
Go to the documentation of this file.
1 /* This program is free software: you can redistribute it and/or modify
2  * it under the terms of the GNU General Public License as published by
3  * the Free Software Foundation, either version 3 of the License, or
4  * (at your option) any later version.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program. If not, see <http://www.gnu.org/licenses/>.
13  *
14  */
21 /* standard libraries */
22 #include <stdint.h> // standard integer types
23 #include <stdlib.h> // standard utilities
24 #include <string.h> // string utilities
25 
26 /* STM32 (including CM3) libraries */
27 #include <libopencm3/stm32/gpio.h> // general purpose input output library
28 #include <libopencm3/stm32/rcc.h> // real-time control clock library
29 #include <libopencm3/stm32/usart.h> // USART utilities
30 
31 /* own libraries */
32 #include "global.h" // board definitions
33 #include "print.h" // printing utilities
34 #include "menu.h" // menu definitions
35 #include "busvoodoo_global.h" // BusVoodoo definitions
36 #include "busvoodoo_oled.h" // OLED utilities
37 #include "busvoodoo_uart_generic.h" // generic UART mode
38 #include "busvoodoo_rs485.h" // own definitions
39 
43 #define BUSVOODOO_RS485_USART 2
47 static void busvoodoo_rs485_drive_enable(void)
48 {
49  gpio_set(GPIO(BUSVOODOO_RS485_DE_PORT), GPIO(BUSVOODOO_RS485_DE_PIN)); // set high to enable RS-485 transceiver driver
50 }
51 
54 {
55  gpio_clear(GPIO(BUSVOODOO_RS485_DE_PORT), GPIO(BUSVOODOO_RS485_DE_PIN)); // set low to disable RS-485 transceiver driver
56 }
57 
60 {
61  gpio_clear(GPIO(BUSVOODOO_RS485_RE_PORT), GPIO(BUSVOODOO_RS485_RE_PIN)); // set high to low enable RS-485 transceiver receiver
62 }
63 
66 {
67  gpio_set(GPIO(BUSVOODOO_RS485_RE_PORT), GPIO(BUSVOODOO_RS485_RE_PIN)); // set high to disable RS-485 transceiver receiver
68 }
69 
73  .usart_rcc = RCC_USART(BUSVOODOO_RS485_USART),
74  .usart_rst = RST_USART(BUSVOODOO_RS485_USART),
75  .multidrive = false,
86  .hwflowctl = false,
87  .rts_port = 0,
88  .rts_pin = 0,
89  .rts_rcc = 0,
90  .cts_port = 0,
91  .cts_pin = 0,
92  .cts_rcc = 0,
93 };
94 
100 static bool busvoodoo_rs485_setup(char** prefix, const char* line)
101 {
102  bool complete = false; // is the setup complete
103  if (NULL==line) { // first call
104  busvoodoo_uart_generic_configure(&busvoodoo_uart_generic_rs485); // provide the RS-485 specific information
105  }
106  complete = busvoodoo_uart_generic_setup(prefix, line); // configure underlying generic UART
107  if (complete) { // generic configuration finished
108  gpio_clear(GPIO(BUSVOODOO_RS485_DE_PORT), GPIO(BUSVOODOO_RS485_DE_PIN)); // set low to disable RS-485 transceiver drive
109  gpio_set_mode(GPIO(BUSVOODOO_RS485_DE_PORT), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(BUSVOODOO_RS485_DE_PIN)); // setup RS-485 Drive Enable GPIO as output (pulled low to disable by default)
110  gpio_set(GPIO(BUSVOODOO_RS485_RE_PORT), GPIO(BUSVOODOO_RS485_RE_PIN)); // set RS-485 transceiver Receive Enable pin high to disable received
111  gpio_set_mode(GPIO(BUSVOODOO_RS485_RE_PORT), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(BUSVOODOO_RS485_RE_PIN)); // setup RS-485 Receive Enable GPIO as output (pulled high to disable by default)
112  busvoodoo_led_blue_off(); // disable blue LED because there is no activity
113  *prefix = "RS-485/422"; // display mode
114  busvoodoo_oled_text_left(*prefix); // set mode title on OLED display
115  const char* pinout_io[10] = {"GND", "5V", "3V3", "LV", NULL, NULL, NULL, NULL, NULL, NULL}; // RS-485 mode I/O pinout
116  for (uint8_t i=0; i<LENGTH(pinout_io) && i<LENGTH(busvoodoo_global_pinout_io); i++) {
117  busvoodoo_global_pinout_io[i] = pinout_io[i]; // set pin names
118  }
119 #if BUSVOODOO_HARDWARE_VERSION==0
120  const char* pinout_rscan[5] = {"HV", NULL, NULL, "B", "A"}; // RS-485 mode RS/CAN pinout for hardware version 0
121 #else
122  const char* pinout_rscan[5] = {"HV", NULL, "A", "B", NULL}; // RS-485 mode RS/CAN pinout
123 #endif
124  for (uint8_t i=0; i<LENGTH(pinout_rscan) && i<LENGTH(busvoodoo_global_pinout_rscan); i++) {
125  busvoodoo_global_pinout_rscan[i] = pinout_rscan[i]; // set pin names
126  }
127  const char* pinout[10] = {pinout_rscan[0], pinout_io[0], pinout_rscan[1], pinout_io[2], pinout_rscan[2], pinout_io[4], pinout_rscan[3], pinout_io[6], pinout_rscan[4], pinout_io[8]}; // pinout to display
128  busvoodoo_oled_text_pinout((const char**)pinout, false); // set pinout on display
129  busvoodoo_oled_update(); // update display to show text and pinout
130  }
131  return complete;
132 }
133 
136 static void busvoodoo_rs485_exit(void)
137 {
138  busvoodoo_uart_generic_exit(); // exiting the underlying generic UART does everything we need
139  gpio_set(GPIO(BUSVOODOO_RS485_RE_PORT), GPIO(BUSVOODOO_RS485_RE_PIN)); // set high to disable RS-485 transceiver receiver
140  gpio_clear(GPIO(BUSVOODOO_RS485_DE_PORT), GPIO(BUSVOODOO_RS485_DE_PIN)); // set low to disable RS-485 transceiver driver
141 }
142 
144  .name = "rs485",
145  .description = "Recommended Standard 485/422",
146  .full_only = true,
147  .setup = &busvoodoo_rs485_setup,
149  .commands_nb = busvoodoo_uart_generic_commands_nb,
150  .exit = &busvoodoo_rs485_exit,
151 };
#define USART_TX_PORT(x)
get port for USART transmit pin based on USART identifier
Definition: global.h:194
#define RCC_USART(x)
get RCC for USART based on USART identifier
Definition: global.h:186
bool busvoodoo_uart_generic_setup(char **prefix, const char *line)
setup generic UART mode
BusVoodoo global definitions and methods (API)
void busvoodoo_oled_text_pinout(const char *pins[10], bool io_connector)
draw pin names on bottom (blue) part in display buffer
const char * name
name of the mode (i.e.
static void busvoodoo_rs485_receive_enable(void)
enable RS-485 transceiver received to allow receiving
#define RCC_USART_PORT(x)
get RCC for USART port based on USART identifier
Definition: global.h:210
void busvoodoo_oled_update(void)
update OLED display RAM with current display buffer
const char * busvoodoo_global_pinout_rscan[5]
RS/CAN connector pinout.
global definitions and methods (API)
#define GPIO(x)
get GPIO based on GPIO identifier
Definition: global.h:103
#define BUSVOODOO_RS485_RE_PORT
RS-485 pin to enable receiver (active low, pulled up)
static bool busvoodoo_rs485_setup(char **prefix, const char *line)
setup RS-485 mode
void busvoodoo_led_blue_off(void)
switch off blue LED
static void busvoodoo_rs485_drive_enable(void)
enable RS-485 transceiver driver to allow transmitting
#define USART_RX_PIN(x)
get pin for USART receive pin based on USART identifier
Definition: global.h:204
#define USART_TX_PIN(x)
get pin for USART transmit pin based on USART identifier
Definition: global.h:202
uint32_t usart
USART peripheral base address.
#define RST_USART(x)
get RST for USART based on USART identifier
Definition: global.h:188
#define USART(x)
get USART based on USART identifier
Definition: global.h:184
#define BUSVOODOO_RS485_DE_PORT
RS-485 pin to enable transmitter (active high, pulled low)
void busvoodoo_uart_generic_exit(void)
exit genetic UART mode
UART specific methods that will be called by the generic methods.
const char * busvoodoo_global_pinout_io[10]
I/O connector pinout.
#define busvoodoo_uart_generic_commands_nb
number of commands supported by the generic UART mode
#define USART_RX_PORT(x)
get port for USART receive pin based on USART identifier
Definition: global.h:196
bool busvoodoo_uart_generic_configure(const struct busvoodoo_uart_generic_specific_t *conf)
provide the generic USART with mode specific information
static void busvoodoo_rs485_receive_disable(void)
enable RS-485 transceiver received to allow receiving
BusVoodoo generic UART mode (API)
#define BUSVOODOO_RS485_DE_PIN
RS-485 pin to enable transmitter (active high, pulled low)
void busvoodoo_oled_text_left(char *text)
draw mode text on top (yellow) left side in display buffer
const struct menu_command_t busvoodoo_uart_generic_commands[busvoodoo_uart_generic_commands_nb]
commands supported by the generic UART mode
#define LENGTH(x)
get the length of an array
Definition: global.h:26
static void busvoodoo_rs485_drive_disable(void)
enable RS-485 transceiver driver to allow transmitting
#define BUSVOODOO_RS485_RE_PIN
RS-485 pin to enable receiver (active low, pulled up)
static const struct busvoodoo_uart_generic_specific_t busvoodoo_uart_generic_rs485
RS-485 specific methods that will be called by the generic methods.
library to show BusVoodoo mode information on SSD1306 OLED display: name, activity, pinout (API)
BusVoodoo mode interface.
BusVoodoo RS-485/422 mode (API)
static void busvoodoo_rs485_exit(void)
exit RS-485 mode
#define BUSVOODOO_RS485_USART
USART peripheral.
const struct busvoodoo_mode_t busvoodoo_rs485_mode
RS-485 mode interface definition.