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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "app.h"
|
|
|
|
#include "ch.h"
|
|
|
|
#include "hal.h"
|
2014-09-19 18:22:38 -07:00
|
|
|
#include "hw.h"
|
2014-08-10 12:51:13 -07:00
|
|
|
#include "packet.h"
|
2014-09-19 18:22:38 -07:00
|
|
|
#include "commands.h"
|
|
|
|
|
|
|
|
#include <string.h>
|
2014-08-10 12:51:13 -07:00
|
|
|
|
|
|
|
// Settings
|
|
|
|
#define BAUDRATE 115200
|
|
|
|
#define PACKET_HANDLER 1
|
2019-02-18 10:30:19 -08:00
|
|
|
#define PACKET_HANDLER_P 2
|
2014-08-10 12:51:13 -07:00
|
|
|
|
|
|
|
// Threads
|
2015-10-08 14:09:39 -07:00
|
|
|
static THD_FUNCTION(packet_process_thread, arg);
|
|
|
|
static THD_WORKING_AREA(packet_process_thread_wa, 4096);
|
2014-08-10 12:51:13 -07:00
|
|
|
|
|
|
|
// Variables
|
2019-02-18 10:30:19 -08:00
|
|
|
static volatile bool thread_is_running = false;
|
|
|
|
static volatile bool uart_is_running = false;
|
|
|
|
static mutex_t send_mutex;
|
|
|
|
static bool send_mutex_init_done = false;
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2020-01-12 12:25:21 -08:00
|
|
|
#ifdef HW_UART_P_DEV
|
|
|
|
static mutex_t send_mutex_p;
|
|
|
|
static bool send_mutex_p_init_done = false;
|
|
|
|
#endif
|
|
|
|
|
2014-08-10 12:51:13 -07:00
|
|
|
// Private functions
|
2015-05-20 07:13:48 -07:00
|
|
|
static void process_packet(unsigned char *data, unsigned int len);
|
|
|
|
static void send_packet(unsigned char *data, unsigned int len);
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2020-01-12 12:25:21 -08:00
|
|
|
#ifdef HW_UART_P_DEV
|
|
|
|
static void process_packet_p(unsigned char *data, unsigned int len);
|
|
|
|
static void send_packet_p(unsigned char *data, unsigned int len);
|
|
|
|
#endif
|
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
static SerialConfig uart_cfg = {
|
2014-08-10 12:51:13 -07:00
|
|
|
BAUDRATE,
|
|
|
|
0,
|
|
|
|
USART_CR2_LINEN,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
#ifdef HW_UART_P_DEV
|
|
|
|
static volatile bool from_p_uart = false;
|
|
|
|
static volatile bool uart_p_is_running = false;
|
|
|
|
static SerialConfig uart_p_cfg = {
|
|
|
|
HW_UART_P_BAUD,
|
|
|
|
0,
|
|
|
|
USART_CR2_LINEN,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2015-05-20 07:13:48 -07:00
|
|
|
static void process_packet(unsigned char *data, unsigned int len) {
|
2019-03-04 10:23:38 -08:00
|
|
|
commands_process_packet(data, len, app_uartcomm_send_packet);
|
2014-09-19 18:22:38 -07:00
|
|
|
}
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
#ifdef HW_UART_P_DEV
|
2020-01-12 12:25:21 -08:00
|
|
|
static void process_packet_p(unsigned char *data, unsigned int len) {
|
|
|
|
commands_process_packet(data, len, app_uartcomm_send_packet_p);
|
|
|
|
}
|
2019-12-09 01:57:33 -08:00
|
|
|
#endif
|
2020-01-12 12:25:21 -08:00
|
|
|
|
|
|
|
static void send_packet(unsigned char *data, unsigned int len) {
|
2019-02-18 10:30:19 -08:00
|
|
|
if (uart_is_running) {
|
|
|
|
sdWrite(&HW_UART_DEV, data, len);
|
|
|
|
}
|
2020-01-12 12:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HW_UART_P_DEV
|
|
|
|
static void send_packet_p(unsigned char *data, unsigned int len) {
|
|
|
|
if (uart_p_is_running) {
|
|
|
|
#ifdef HW_UART_P_DEV_TX
|
|
|
|
sdWrite(&HW_UART_P_DEV_TX, data, len);
|
|
|
|
#else
|
|
|
|
sdWrite(&HW_UART_P_DEV, data, len);
|
2019-02-18 10:30:19 -08:00
|
|
|
#endif
|
2020-01-12 12:25:21 -08:00
|
|
|
}
|
2014-08-10 12:51:13 -07:00
|
|
|
}
|
2020-01-12 12:25:21 -08:00
|
|
|
#endif
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2014-09-18 14:00:14 -07:00
|
|
|
void app_uartcomm_start(void) {
|
2014-08-10 12:51:13 -07:00
|
|
|
packet_init(send_packet, process_packet, PACKET_HANDLER);
|
2017-09-04 12:12:43 -07:00
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
if (!thread_is_running) {
|
2017-09-04 12:12:43 -07:00
|
|
|
chThdCreateStatic(packet_process_thread_wa, sizeof(packet_process_thread_wa),
|
|
|
|
NORMALPRIO, packet_process_thread, NULL);
|
2019-02-18 10:30:19 -08:00
|
|
|
thread_is_running = true;
|
2017-09-04 12:12:43 -07:00
|
|
|
}
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
sdStart(&HW_UART_DEV, &uart_cfg);
|
2014-08-13 15:23:32 -07:00
|
|
|
palSetPadMode(HW_UART_TX_PORT, HW_UART_TX_PIN, PAL_MODE_ALTERNATE(HW_UART_GPIO_AF) |
|
2014-08-10 12:51:13 -07:00
|
|
|
PAL_STM32_OSPEED_HIGHEST |
|
|
|
|
PAL_STM32_PUDR_PULLUP);
|
2014-08-13 15:23:32 -07:00
|
|
|
palSetPadMode(HW_UART_RX_PORT, HW_UART_RX_PIN, PAL_MODE_ALTERNATE(HW_UART_GPIO_AF) |
|
2014-08-10 12:51:13 -07:00
|
|
|
PAL_STM32_OSPEED_HIGHEST |
|
|
|
|
PAL_STM32_PUDR_PULLUP);
|
2019-02-18 10:30:19 -08:00
|
|
|
|
|
|
|
uart_is_running = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void app_uartcomm_start_permanent(void) {
|
|
|
|
#ifdef HW_UART_P_DEV
|
2020-01-12 12:25:21 -08:00
|
|
|
packet_init(send_packet_p, process_packet_p, PACKET_HANDLER_P);
|
2019-02-18 10:30:19 -08:00
|
|
|
|
|
|
|
if (!thread_is_running) {
|
|
|
|
chThdCreateStatic(packet_process_thread_wa, sizeof(packet_process_thread_wa),
|
|
|
|
NORMALPRIO, packet_process_thread, NULL);
|
|
|
|
thread_is_running = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
sdStart(&HW_UART_P_DEV, &uart_p_cfg);
|
2019-12-09 01:57:33 -08:00
|
|
|
|
|
|
|
#ifdef HW_UART_P_DEV_TX
|
|
|
|
sdStart(&HW_UART_P_DEV_TX, &uart_p_cfg);
|
|
|
|
#endif
|
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
palSetPadMode(HW_UART_P_TX_PORT, HW_UART_P_TX_PIN, PAL_MODE_ALTERNATE(HW_UART_P_GPIO_AF) |
|
|
|
|
PAL_STM32_OSPEED_HIGHEST |
|
|
|
|
PAL_STM32_PUDR_PULLUP);
|
|
|
|
palSetPadMode(HW_UART_P_RX_PORT, HW_UART_P_RX_PIN, PAL_MODE_ALTERNATE(HW_UART_P_GPIO_AF) |
|
|
|
|
PAL_STM32_OSPEED_HIGHEST |
|
|
|
|
PAL_STM32_PUDR_PULLUP);
|
|
|
|
|
|
|
|
uart_p_is_running = true;
|
|
|
|
#endif
|
2014-09-20 04:41:18 -07:00
|
|
|
}
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2016-11-04 07:18:34 -07:00
|
|
|
void app_uartcomm_stop(void) {
|
2019-12-05 10:50:17 -08:00
|
|
|
if (uart_is_running) {
|
|
|
|
sdStop(&HW_UART_DEV);
|
|
|
|
palSetPadMode(HW_UART_TX_PORT, HW_UART_TX_PIN, PAL_MODE_INPUT_PULLUP);
|
|
|
|
palSetPadMode(HW_UART_RX_PORT, HW_UART_RX_PIN, PAL_MODE_INPUT_PULLUP);
|
|
|
|
uart_is_running = false;
|
|
|
|
}
|
2016-11-04 07:18:34 -07:00
|
|
|
|
2017-09-04 12:12:43 -07:00
|
|
|
// Notice that the processing thread is kept running in case this call is made from it.
|
2016-11-04 07:18:34 -07:00
|
|
|
}
|
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
void app_uartcomm_send_packet(unsigned char *data, unsigned int len) {
|
|
|
|
if (!send_mutex_init_done) {
|
|
|
|
chMtxObjectInit(&send_mutex);
|
|
|
|
send_mutex_init_done = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
chMtxLock(&send_mutex);
|
|
|
|
packet_send_packet(data, len, PACKET_HANDLER);
|
|
|
|
chMtxUnlock(&send_mutex);
|
|
|
|
}
|
|
|
|
|
2020-01-12 12:25:21 -08:00
|
|
|
void app_uartcomm_send_packet_p(unsigned char *data, unsigned int len) {
|
|
|
|
#ifdef HW_UART_P_DEV
|
|
|
|
if (!send_mutex_p_init_done) {
|
|
|
|
chMtxObjectInit(&send_mutex_p);
|
|
|
|
send_mutex_p_init_done = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
chMtxLock(&send_mutex_p);
|
|
|
|
packet_send_packet(data, len, PACKET_HANDLER_P);
|
|
|
|
chMtxUnlock(&send_mutex_p);
|
|
|
|
#else
|
|
|
|
(void)data;
|
|
|
|
(void)len;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-03-10 06:57:42 -07:00
|
|
|
void app_uartcomm_configure(uint32_t baudrate, bool permanent_enabled) {
|
2014-09-20 04:41:18 -07:00
|
|
|
uart_cfg.speed = baudrate;
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2019-12-05 10:50:17 -08:00
|
|
|
if (thread_is_running && uart_is_running) {
|
2019-02-18 10:30:19 -08:00
|
|
|
sdStart(&HW_UART_DEV, &uart_cfg);
|
2014-08-10 12:51:13 -07:00
|
|
|
}
|
2019-03-10 06:57:42 -07:00
|
|
|
|
|
|
|
#ifdef HW_UART_P_DEV
|
|
|
|
if (permanent_enabled) {
|
|
|
|
palSetPadMode(HW_UART_P_TX_PORT, HW_UART_P_TX_PIN, PAL_MODE_ALTERNATE(HW_UART_P_GPIO_AF) |
|
|
|
|
PAL_STM32_OSPEED_HIGHEST |
|
|
|
|
PAL_STM32_PUDR_PULLUP);
|
|
|
|
palSetPadMode(HW_UART_P_RX_PORT, HW_UART_P_RX_PIN, PAL_MODE_ALTERNATE(HW_UART_P_GPIO_AF) |
|
|
|
|
PAL_STM32_OSPEED_HIGHEST |
|
|
|
|
PAL_STM32_PUDR_PULLUP);
|
|
|
|
} else {
|
|
|
|
palSetPadMode(HW_UART_P_TX_PORT, HW_UART_P_TX_PIN, PAL_MODE_INPUT);
|
|
|
|
palSetPadMode(HW_UART_P_RX_PORT, HW_UART_P_RX_PIN, PAL_MODE_INPUT);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void)permanent_enabled;
|
|
|
|
#endif
|
2014-08-10 12:51:13 -07:00
|
|
|
}
|
|
|
|
|
2015-10-08 14:09:39 -07:00
|
|
|
static THD_FUNCTION(packet_process_thread, arg) {
|
2014-08-10 12:51:13 -07:00
|
|
|
(void)arg;
|
|
|
|
|
2020-03-16 10:32:39 -07:00
|
|
|
chRegSetThreadName("uartcomm proc");
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
event_listener_t el;
|
|
|
|
chEvtRegisterMaskWithFlags(&HW_UART_DEV.event, &el, EVENT_MASK(0), CHN_INPUT_AVAILABLE);
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
#ifdef HW_UART_P_DEV
|
|
|
|
event_listener_t elp;
|
|
|
|
chEvtRegisterMaskWithFlags(&HW_UART_P_DEV.event, &elp, EVENT_MASK(0), CHN_INPUT_AVAILABLE);
|
|
|
|
#endif
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
for(;;) {
|
2019-12-19 07:55:38 -08:00
|
|
|
chEvtWaitAnyTimeout(ALL_EVENTS, ST2MS(10));
|
2019-02-18 10:30:19 -08:00
|
|
|
|
|
|
|
bool rx = true;
|
|
|
|
while (rx) {
|
|
|
|
rx = false;
|
|
|
|
|
2019-12-05 10:50:17 -08:00
|
|
|
if (uart_is_running) {
|
|
|
|
msg_t res = sdGetTimeout(&HW_UART_DEV, TIME_IMMEDIATE);
|
|
|
|
if (res != MSG_TIMEOUT) {
|
2019-02-18 10:30:19 -08:00
|
|
|
#ifdef HW_UART_P_DEV
|
2019-12-05 10:50:17 -08:00
|
|
|
from_p_uart = false;
|
2019-02-18 10:30:19 -08:00
|
|
|
#endif
|
2019-12-05 10:50:17 -08:00
|
|
|
packet_process_byte(res, PACKET_HANDLER);
|
|
|
|
rx = true;
|
|
|
|
}
|
2019-02-18 10:30:19 -08:00
|
|
|
}
|
2014-08-10 12:51:13 -07:00
|
|
|
|
2019-02-18 10:30:19 -08:00
|
|
|
#ifdef HW_UART_P_DEV
|
2019-12-05 10:50:17 -08:00
|
|
|
msg_t res = sdGetTimeout(&HW_UART_P_DEV, TIME_IMMEDIATE);
|
2019-02-18 10:30:19 -08:00
|
|
|
if (res != MSG_TIMEOUT) {
|
|
|
|
from_p_uart = true;
|
|
|
|
packet_process_byte(res, PACKET_HANDLER_P);
|
|
|
|
rx = true;
|
2014-08-10 12:51:13 -07:00
|
|
|
}
|
2019-02-18 10:30:19 -08:00
|
|
|
#endif
|
2014-08-10 12:51:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|