27 #include <libopencm3/stm32/gpio.h> 28 #include <libopencm3/stm32/rcc.h> 29 #include <libopencm3/stm32/usart.h> 42 #define BUSVOODOO_RS485_USART 2 46 static enum busvoodoo_rs485_setting_t { 47 BUSVOODOO_RS485_SETTING_NONE,
48 BUSVOODOO_RS485_SETTING_BAUDRATE,
49 BUSVOODOO_RS485_SETTING_DATABITS,
50 BUSVOODOO_RS485_SETTING_PARITY,
51 BUSVOODOO_RS485_SETTING_STOPBITS,
52 BUSVOODOO_RS485_SETTING_DONE,
70 bool complete =
false;
75 case BUSVOODOO_RS485_SETTING_NONE:
80 case BUSVOODOO_RS485_SETTING_BAUDRATE:
81 if (NULL==line || 0==strlen(line)) {
84 uint32_t baudrate = atoi(line);
85 if (baudrate>0 && baudrate<=2000000) {
95 case BUSVOODOO_RS485_SETTING_DATABITS:
96 if (NULL==line || 0==strlen(line)) {
99 uint8_t databits = atoi(line);
100 if (8==databits || 9==databits) {
113 case BUSVOODOO_RS485_SETTING_PARITY:
114 if (NULL==line || 0==strlen(line)) {
116 }
else if (1==strlen(line)) {
120 }
else if (
'2'==line[0]) {
123 }
else if (
'3'==line[0]) {
137 case BUSVOODOO_RS485_SETTING_STOPBITS:
138 if (NULL==line || 0==strlen(line)) {
140 }
else if (1==strlen(line)) {
144 }
else if (
'2'==line[0]) {
147 }
else if (
'3'==line[0]) {
150 }
else if (
'4'==line[0]) {
156 rcc_periph_clock_enable(RCC_AFIO);
174 *prefix =
"RS-485/422";
176 const char* pinout_io[10] = {
"GND",
"5V",
"3V3",
"LV", NULL, NULL, NULL, NULL, NULL, NULL};
180 #if BUSVOODOO_HARDWARE_VERSION==0 181 const char* pinout_rscan[5] = {
"HV", NULL, NULL,
"B",
"A"};
183 const char* pinout_rscan[5] = {
"HV", NULL,
"A",
"B", NULL};
188 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]};
239 printf(
"write: '%c'/0x", value);
289 }
else if (error_framing) {
291 }
else if (error_parity) {
310 uint32_t length = strlen(action);
311 if (NULL==action || 0==length) {
315 if (1==length &&
'r'==action[0]) {
319 for (uint32_t i=0; i<repetition; i++) {
322 }
else if (1==length &&
'u'==action[0]) {
326 printf(
"wait for %u us\n", repetition);
328 }
else if (1==length &&
'm'==action[0]) {
332 printf(
"wait for %u ms\n", repetition);
334 }
else if (
'0'==action[0]) {
339 for (uint32_t i=0; i<repetition; i++) {
342 }
else if (
'x'==action[1] ||
'b'==action[1]) {
344 }
else if (action[1]>=
'0' && action[1]<=
'9') {
349 }
else if (
'x'==action[0] && length>1) {
350 for (uint32_t i=1; i<length; i++) {
351 if (!((action[i]>=
'0' && action[i]<=
'9') || (action[i]>=
'a' && action[i]<=
'f') || (action[i]>=
'A' && action[i]<=
'F'))) {
358 uint32_t value = strtol(&action[1], NULL, 16);
359 for (uint32_t i=0; i<repetition; i++) {
362 }
else if (
'b'==action[0] && length>1) {
363 for (uint32_t i=1; i<length; i++) {
364 if (action[i]<
'0' || action[i]>
'1') {
371 uint32_t value = strtol(&action[1], NULL, 2);
372 for (uint32_t i=0; i<repetition; i++) {
375 }
else if (action[0]>=
'1' && action[0]<=
'9') {
376 for (uint32_t i=1; i<length; i++) {
377 if (action[i]<
'0' || action[i]>
'9') {
384 uint32_t value = strtol(&action[0], NULL, 10);
385 for (uint32_t i=0; i<repetition; i++) {
388 }
else if (length>=2 && (
'"'==action[0] ||
'\''==action[0]) && (action[length-1]==action[0])) {
392 for (uint32_t r=0; r<repetition; r++) {
393 for (uint32_t i=1; i<length-1; i++) {
411 if (NULL==argument || 0==strlen(argument)) {
412 printf(
"available actions (separated by space or ,):\n");
413 printf(
"0\twrite decimal value\n");
414 printf(
"0x0\twrite hexadecimal value\n");
415 printf(
"0b0\twrite binary value\n");
416 printf(
"\"a\"/'a'\twrite ASCII characters\n");
417 printf(
"r\tread value\n");
418 printf(
"u/m\twait 1 us/ms\n");
419 printf(
":n\trepeat action n times\n");
424 char* copy = calloc(strlen(argument)+1,
sizeof(
char));
428 strncpy(copy, argument, strlen(argument)+1);
431 printf(
"malformed action(s)\n");
433 printf(
"press any key to exit\n");
447 if (NULL==argument || 0==strlen(argument)) {
450 printf(
"press any key to exit\n");
455 printf(
"%c", ((
char*)(argument))[i]);
466 if (strcmp(argument,
"\r\n")) {
476 bool display_hex =
false;
477 bool display_bin =
false;
478 if (NULL!=argument && strlen(argument)>0) {
479 if (0==strcmp(argument,
"h") || 0==strcmp(argument,
"hex")) {
481 }
else if (0==strcmp(argument,
"b") || 0==strcmp(argument,
"bin")) {
484 printf(
"malformed argument\n");
488 printf(
"press any key to exit\n");
514 }
else if (display_bin) {
544 printf(
"press 5 times escape to exit\n");
546 uint8_t esc_count = 0;
589 printf(
"press any key to exit\n");
601 .command_description =
"perform protocol actions",
603 .argument_description =
"[actions]",
609 .command_description =
"show incoming data [in hexadecimal or binary]",
611 .argument_description =
"[hex|bin]",
617 .command_description =
"transmit ASCII text (empty for CR+LF)",
619 .argument_description =
"[text]",
624 .name =
"transceive",
625 .command_description =
"transmit and receive data",
627 .argument_description = NULL,
633 .command_description =
"verify incoming transmission for errors",
635 .argument_description = NULL,
642 .description =
"Recommended Standard 485/422",
#define USART_TX_PORT(x)
get port for USART transmit pin based on USART identifier
#define RCC_USART(x)
get RCC for USART based on USART identifier
static uint8_t busvoodoo_rs485_databits
RS-485 data bits.
#define BUSVOODOO_LED_PULSE
recommended duration in ms for pulsing LEDs to show activity
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.
void busvoodoo_led_blue_pulse(uint32_t ms)
pulse blue LED for short duration
static const struct menu_command_t busvoodoo_rs485_commands[]
RS-485 menu commands.
#define RCC_USART_PORT(x)
get RCC for USART port based on USART identifier
void busvoodoo_oled_update(void)
update OLED display RAM with current display buffer
static void busvoodoo_rs485_write(uint16_t value)
write to RS-485
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
void sleep_us(uint32_t duration)
go to sleep for some microseconds
static uint32_t busvoodoo_rs485_stopbits
RS-485 stop bits setting.
#define BUSVOODOO_RS485_RE_PORT
RS-485 pin to enable receiver (active low, pulled up)
static void busvoodoo_rs485_command_transmit(void *argument)
command to transmit a string
static bool busvoodoo_rs485_setup(char **prefix, const char *line)
setup RS-485 mode
void busvoodoo_led_blue_off(void)
switch off blue LED
#define USART_RX_PIN(x)
get pin for USART receive pin based on USART identifier
#define USART_TX_PIN(x)
get pin for USART transmit pin based on USART identifier
#define USART(x)
get USART based on USART identifier
#define BUSVOODOO_RS485_DE_PORT
RS-485 pin to enable transmitter (active high, pulled low)
char shortcut
short command code (0 if not available)
static void busvoodoo_rs485_command_receive(void *argument)
command to receive data
static void busvoodoo_rs485_read(void)
read from RS-485
const char * busvoodoo_global_pinout_io[10]
I/O connector pinout.
char user_input_get(void)
get user input
static bool busvoodoo_rs485_action(const char *action, uint32_t repetition, bool perform)
perform RS-485 action
char busvoodoo_global_string[64]
shared string buffer, i.e.
size_t snprintf(char *str, size_t size, const char *format,...)
print format string on string or user output
bool busvoodoo_global_actions(char *actions, bool perform, bool(*action_handler)(const char *action, uint32_t repetition, bool perform))
parse and perform actions
void sleep_ms(uint32_t duration)
go to sleep for some milliseconds
#define USART_RX_PORT(x)
get port for USART receive pin based on USART identifier
static enum busvoodoo_rs485_setting_t busvoodoo_rs485_setting
current mode setup stage
size_t printf(const char *format,...)
print format string on user output
static void busvoodoo_rs485_command_actions(void *argument)
command to perform actions
static uint32_t busvoodoo_rs485_baudrate
RS-485 baud rate (in bps)
printing utilities to replace the large printf from the standard library (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
static void busvoodoo_rs485_command_error(void *argument)
command to verify incoming transmission for error
#define LENGTH(x)
get the length of an array
static void busvoodoo_rs485_command_transceive(void *argument)
command to transmit and receive data
#define BUSVOODOO_RS485_RE_PIN
RS-485 pin to enable receiver (active low, pulled up)
library to show BusVoodoo mode information on SSD1306 OLED display: name, activity, pinout (API)
volatile bool user_input_available
flag set when user input is available
BusVoodoo mode interface.
BusVoodoo RS-485/422 mode (API)
static void busvoodoo_rs485_exit(void)
exit RS-485 mode
static uint32_t busvoodoo_rs485_parity
RS-485 parity setting.
#define BUSVOODOO_RS485_USART
USART peripheral.
const struct busvoodoo_mode_t busvoodoo_rs485_mode
RS-485 mode interface definition.