bldc/applications/app_uartcomm.c

250 lines
8.6 KiB
C
Raw Normal View History

2014-08-10 12:51:13 -07:00
/*
2019-02-18 10:30:19 -08:00
Copyright 2016 - 2019 Benjamin Vedder benjamin@vedder.se
2014-08-10 12:51:13 -07:00
2016-11-04 07:18:34 -07:00
This file is part of the VESC firmware.
The VESC firmware is free software: you can redistribute it and/or modify
2014-08-10 12:51:13 -07:00
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
2016-11-04 07:18:34 -07:00
The VESC firmware is distributed in the hope that it will be useful,
2014-08-10 12:51:13 -07:00
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
2021-01-05 09:39:45 -08:00
*/
2014-08-10 12:51:13 -07:00
#include "app.h"
#include "ch.h"
#include "hal.h"
#include "hw.h"
2014-08-10 12:51:13 -07:00
#include "packet.h"
#include "commands.h"
2014-08-10 12:51:13 -07:00
// Settings
2021-01-05 09:39:45 -08:00
// By default 7/8 pin uart is index 0, builtin BLE is index 1, and third uart is index 2
2014-08-10 12:51:13 -07:00
#define BAUDRATE 115200
2021-01-05 09:39:45 -08:00
#ifndef UART_NUMBER
#ifdef HW_UART_3_DEV
#define UART_NUMBER 3
#else
#ifdef HW_UART_P_DEV
#define UART_NUMBER 2
#else
#define UART_NUMBER 1
#endif
#endif
#endif
2014-08-10 12:51:13 -07:00
// Threads
static THD_FUNCTION(packet_process_thread, arg);
2022-01-16 12:57:12 -08:00
static THD_WORKING_AREA(packet_process_thread_wa, 2048);
2014-08-10 12:51:13 -07:00
// Variables
2019-02-18 10:30:19 -08:00
static volatile bool thread_is_running = false;
2021-01-05 09:39:45 -08:00
static volatile bool uart_is_running[UART_NUMBER] = {false};
static mutex_t send_mutex[UART_NUMBER];
static bool send_mutex_init_done[UART_NUMBER] = {false};
static SerialConfig uart_cfg[UART_NUMBER] = {{
2021-01-13 12:51:55 -08:00
BAUDRATE,
0,
USART_CR2_LINEN,
0
2021-01-05 12:30:41 -08:00
}};
2021-01-05 09:39:45 -08:00
// Different for Rx and Tx because it is possible for hardware to use different UART driver
// for Rx and Tx, feature not a bug XD
static SerialDriver *serialPortDriverTx[UART_NUMBER];
static SerialDriver *serialPortDriverRx[UART_NUMBER];
static stm32_gpio_t * TxGpioPort[UART_NUMBER];
static stm32_gpio_t * RxGpioPort[UART_NUMBER];
2021-01-05 12:30:41 -08:00
static uint8_t TxGpioPin[UART_NUMBER], RxGpioPin[UART_NUMBER], gpioAF[UART_NUMBER];
2021-01-13 09:05:16 -08:00
static PACKET_STATE_t packet_state[UART_NUMBER];
2021-03-31 00:54:59 -07:00
static bool pins_enabled[UART_NUMBER];
2020-01-12 12:25:21 -08:00
2014-08-10 12:51:13 -07:00
// Private functions
2021-01-05 09:39:45 -08:00
static void process_packet(unsigned char *data, unsigned int len, unsigned int port_number);
2021-01-13 12:51:55 -08:00
static void write_packet(unsigned char *data, unsigned int len, unsigned int port_number);
2014-08-10 12:51:13 -07:00
2021-01-15 05:01:16 -08:00
static void process_packet_1(unsigned char *data, unsigned int len) {process_packet(data,len,UART_PORT_COMM_HEADER);}
static void write_packet_1(unsigned char *data, unsigned int len) {write_packet(data,len,UART_PORT_COMM_HEADER);}
2021-01-13 12:51:55 -08:00
static void send_packet_1(unsigned char *data, unsigned int len) {app_uartcomm_send_packet(data,len,UART_PORT_COMM_HEADER);}
2020-01-12 12:25:21 -08:00
2021-01-15 05:01:16 -08:00
static void process_packet_2(unsigned char *data, unsigned int len) {process_packet(data,len,UART_PORT_BUILTIN);}
static void write_packet_2(unsigned char *data, unsigned int len) {write_packet(data,len,UART_PORT_BUILTIN);}
2021-01-13 12:51:55 -08:00
static void send_packet_2(unsigned char *data, unsigned int len) {app_uartcomm_send_packet(data,len,UART_PORT_BUILTIN);}
2014-08-10 12:51:13 -07:00
2021-01-15 05:01:16 -08:00
static void process_packet_3(unsigned char *data, unsigned int len) {process_packet(data,len,UART_PORT_EXTRA_HEADER);}
static void write_packet_3(unsigned char *data, unsigned int len) {write_packet(data,len,UART_PORT_EXTRA_HEADER);}
2021-01-13 12:51:55 -08:00
static void send_packet_3(unsigned char *data, unsigned int len) {app_uartcomm_send_packet(data,len,UART_PORT_EXTRA_HEADER);}
2019-02-18 10:30:19 -08:00
2021-01-05 09:39:45 -08:00
typedef void (*data_func) (unsigned char *data, unsigned int len);
static data_func write_functions[3] = {write_packet_1, write_packet_2, write_packet_3};
static data_func process_functions[3] = {process_packet_1, process_packet_2, process_packet_3};
static data_func send_functions[3] = {send_packet_1, send_packet_2, send_packet_3};
2014-08-10 12:51:13 -07:00
2021-01-05 09:39:45 -08:00
static void write_packet(unsigned char *data, unsigned int len, unsigned int port_number) {
2021-01-13 12:51:55 -08:00
if (port_number >= UART_NUMBER) {
2021-01-05 09:39:45 -08:00
return;
}
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
if (uart_is_running[port_number]) {
sdWrite(serialPortDriverTx[port_number], data, len);
}
2020-01-12 12:25:21 -08:00
}
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
static void process_packet(unsigned char *data, unsigned int len, unsigned int port_number) {
2021-01-13 12:51:55 -08:00
if (port_number >= UART_NUMBER) {
2021-01-05 09:39:45 -08:00
return;
2019-02-18 10:30:19 -08:00
}
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
commands_process_packet(data, len, send_functions[port_number]);
2020-01-12 12:25:21 -08:00
}
2021-01-05 09:39:45 -08:00
void app_uartcomm_initialize(void) {
serialPortDriverTx[0] = &HW_UART_DEV;
serialPortDriverRx[0] = &HW_UART_DEV;
uart_cfg[0].speed = BAUDRATE;
2021-03-31 00:54:59 -07:00
RxGpioPort[0] = HW_UART_RX_PORT; RxGpioPin[0] = HW_UART_RX_PIN;
TxGpioPort[0] = HW_UART_TX_PORT; TxGpioPin[0] = HW_UART_TX_PIN;
2021-01-05 12:30:41 -08:00
gpioAF[0] = HW_UART_GPIO_AF;
2021-01-13 12:51:55 -08:00
2020-01-12 12:25:21 -08:00
#ifdef HW_UART_P_DEV
#ifdef HW_UART_P_DEV_TX
2021-01-05 09:39:45 -08:00
serialPortDriverTx[1] = &HW_UART_P_DEV_TX;
2020-01-12 12:25:21 -08:00
#else
2021-01-05 09:39:45 -08:00
serialPortDriverTx[1] = &HW_UART_P_DEV;
2019-02-18 10:30:19 -08:00
#endif
2021-01-05 09:39:45 -08:00
serialPortDriverRx[1] = &HW_UART_P_DEV;
uart_cfg[1].speed = HW_UART_P_BAUD;
RxGpioPort[1] = HW_UART_P_RX_PORT; RxGpioPin[1] = HW_UART_P_RX_PIN;
TxGpioPort[1] = HW_UART_P_TX_PORT; TxGpioPin[1] = HW_UART_P_TX_PIN;
2021-01-05 12:30:41 -08:00
gpioAF[1] = HW_UART_P_GPIO_AF;
2021-01-05 09:39:45 -08:00
#endif
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
#ifdef HW_UART_3_DEV
serialPortDriverTx[2] = &HW_UART_3_DEV;
serialPortDriverRx[2] = &HW_UART_3_DEV;
uart_cfg[2].speed = HW_UART_3_BAUD;
RxGpioPort[2] = HW_UART_3_RX_PORT; RxGpioPin[2] = HW_UART_3_RX_PIN;
2021-03-31 00:54:59 -07:00
TxGpioPort[2] = HW_UART_3_TX_PORT; TxGpioPin[2] = HW_UART_3_TX_PIN;
2021-01-05 12:30:41 -08:00
gpioAF[2] = HW_UART_3_GPIO_AF;
2020-01-12 12:25:21 -08:00
#endif
2019-02-18 10:30:19 -08:00
}
2021-01-13 12:51:55 -08:00
void app_uartcomm_start(UART_PORT port_number) {
2021-01-05 09:39:45 -08:00
if(port_number >= UART_NUMBER){
return;
}
2019-02-18 10:30:19 -08:00
2021-01-13 09:05:16 -08:00
packet_init(write_functions[port_number], process_functions[port_number], &packet_state[port_number]);
2021-01-13 12:51:55 -08:00
2019-02-18 10:30:19 -08:00
if (!thread_is_running) {
chThdCreateStatic(packet_process_thread_wa, sizeof(packet_process_thread_wa),
2021-01-13 12:51:55 -08:00
NORMALPRIO, packet_process_thread, NULL);
2019-02-18 10:30:19 -08:00
thread_is_running = true;
}
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
sdStart(serialPortDriverRx[port_number], &uart_cfg[port_number]);
2021-01-05 12:30:41 -08:00
sdStart(serialPortDriverTx[port_number], &uart_cfg[port_number]);
2021-01-05 09:39:45 -08:00
uart_is_running[port_number] = true;
2021-01-13 12:51:55 -08:00
2021-01-05 12:30:41 -08:00
palSetPadMode(TxGpioPort[port_number], TxGpioPin[port_number], PAL_MODE_ALTERNATE(gpioAF[port_number]) |
2021-01-13 12:51:55 -08:00
PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_PULLUP);
2021-01-05 12:30:41 -08:00
palSetPadMode(RxGpioPort[port_number], RxGpioPin[port_number], PAL_MODE_ALTERNATE(gpioAF[port_number]) |
2021-01-13 12:51:55 -08:00
PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUDR_PULLUP);
2021-03-31 00:54:59 -07:00
pins_enabled[port_number] = true;
2014-09-20 04:41:18 -07:00
}
2014-08-10 12:51:13 -07:00
2021-01-13 12:51:55 -08:00
void app_uartcomm_stop(UART_PORT port_number) {
if(port_number >= UART_NUMBER) {
2021-01-05 09:39:45 -08:00
return;
}
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
if (uart_is_running[port_number]) {
sdStop(serialPortDriverRx[port_number]);
sdStop(serialPortDriverTx[port_number]);
palSetPadMode(TxGpioPort[port_number], TxGpioPin[port_number], PAL_MODE_INPUT_PULLUP);
palSetPadMode(RxGpioPort[port_number], RxGpioPin[port_number], PAL_MODE_INPUT_PULLUP);
uart_is_running[port_number] = false;
}
// Notice that the processing thread is kept running in case this call is made from it.
2016-11-04 07:18:34 -07:00
}
2021-01-13 12:51:55 -08:00
void app_uartcomm_send_packet(unsigned char *data, unsigned int len, UART_PORT port_number) {
if (port_number >= UART_NUMBER) {
2021-01-05 09:39:45 -08:00
return;
2019-02-18 10:30:19 -08:00
}
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
if (!send_mutex_init_done[port_number]) {
chMtxObjectInit(&send_mutex[port_number]);
send_mutex_init_done[port_number] = true;
2020-01-12 12:25:21 -08:00
}
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
chMtxLock(&send_mutex[port_number]);
2021-01-13 09:05:16 -08:00
packet_send_packet(data, len, &packet_state[port_number]);
2021-01-05 09:39:45 -08:00
chMtxUnlock(&send_mutex[port_number]);
2020-01-12 12:25:21 -08:00
}
2021-01-13 12:51:55 -08:00
void app_uartcomm_configure(uint32_t baudrate, bool enabled, UART_PORT port_number) {
if (port_number >= UART_NUMBER) {
2021-01-05 12:30:41 -08:00
return;
2014-08-10 12:51:13 -07:00
}
2021-01-13 12:51:55 -08:00
if (baudrate > 0) {
2021-01-05 09:39:45 -08:00
uart_cfg[port_number].speed = baudrate;
}
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
if (thread_is_running && uart_is_running[port_number]) {
sdStart(serialPortDriverRx[port_number], &uart_cfg[port_number]);
2021-01-13 12:51:55 -08:00
2021-03-31 00:54:59 -07:00
if (enabled && !pins_enabled[port_number]) {
palSetPadMode(TxGpioPort[port_number], TxGpioPin[port_number], PAL_MODE_ALTERNATE(gpioAF[port_number]) |
PAL_STM32_OSPEED_HIGHEST |
PAL_STM32_PUDR_PULLUP);
palSetPadMode(RxGpioPort[port_number], RxGpioPin[port_number], PAL_MODE_ALTERNATE(gpioAF[port_number]) |
PAL_STM32_OSPEED_HIGHEST |
PAL_STM32_PUDR_PULLUP);
pins_enabled[port_number] = true;
} else if (!enabled && pins_enabled[port_number]) {
palSetPadMode(TxGpioPort[port_number], TxGpioPin[port_number], PAL_MODE_INPUT);
palSetPadMode(RxGpioPort[port_number], RxGpioPin[port_number], PAL_MODE_INPUT);
pins_enabled[port_number] = false;
}
}
2014-08-10 12:51:13 -07:00
}
static THD_FUNCTION(packet_process_thread, arg) {
2014-08-10 12:51:13 -07:00
(void)arg;
2021-01-13 12:51:55 -08:00
chRegSetThreadName("uartcomm proc");
2021-01-13 12:51:55 -08:00
2021-01-05 09:39:45 -08:00
event_listener_t el[UART_NUMBER];
2021-01-13 09:05:16 -08:00
for(int port_number = 0; port_number < UART_NUMBER; port_number++) {
chEvtRegisterMaskWithFlags(&(*serialPortDriverRx[port_number]).event, &el[port_number], EVENT_MASK(0), CHN_INPUT_AVAILABLE);
2021-01-05 09:39:45 -08:00
}
2021-01-13 12:51:55 -08:00
2019-02-18 10:30:19 -08:00
for(;;) {
chEvtWaitAnyTimeout(ALL_EVENTS, ST2MS(10));
2021-01-13 12:51:55 -08:00
2019-02-18 10:30:19 -08:00
bool rx = true;
while (rx) {
rx = false;
2021-01-13 09:05:16 -08:00
for(int port_number = 0; port_number < UART_NUMBER; port_number++) {
if (uart_is_running[port_number]) {
msg_t res = sdGetTimeout(serialPortDriverRx[port_number], TIME_IMMEDIATE);
2021-01-05 09:39:45 -08:00
if (res != MSG_TIMEOUT) {
2021-01-13 09:05:16 -08:00
packet_process_byte(res, &packet_state[port_number]);
2021-01-05 09:39:45 -08:00
rx = true;
}
}
2019-02-18 10:30:19 -08:00
}
2014-08-10 12:51:13 -07:00
}
}
}
2021-01-05 09:39:45 -08:00