bldc/applications/app_uartcomm.c

216 lines
5.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/>.
*/
#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"
#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
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
// Private functions
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
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
static void process_packet(unsigned char *data, unsigned int len) {
commands_process_packet(data, len, app_uartcomm_send_packet);
}
2014-08-10 12:51:13 -07:00
static void send_packet(unsigned char *data, unsigned int len) {
2019-02-18 10:30:19 -08:00
#ifdef HW_UART_P_DEV
if (from_p_uart) {
if (uart_p_is_running) {
sdWrite(&HW_UART_P_DEV, data, len);
}
} else {
if (uart_is_running) {
sdWrite(&HW_UART_DEV, data, len);
}
2014-08-10 12:51:13 -07:00
}
2019-02-18 10:30:19 -08:00
#else
if (uart_is_running) {
sdWrite(&HW_UART_DEV, data, len);
}
#endif
2014-08-10 12:51:13 -07:00
}
void app_uartcomm_start(void) {
2014-08-10 12:51:13 -07:00
packet_init(send_packet, process_packet, PACKET_HANDLER);
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);
2019-02-18 10:30:19 -08:00
thread_is_running = true;
}
2014-08-10 12:51:13 -07:00
2019-02-18 10:30:19 -08:00
sdStart(&HW_UART_DEV, &uart_cfg);
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);
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
packet_init(send_packet, process_packet, PACKET_HANDLER);
packet_init(send_packet, process_packet, PACKET_HANDLER_P);
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);
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-02-18 10:30:19 -08:00
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);
2019-02-18 10:30:19 -08:00
uart_is_running = false;
2016-11-04 07:18:34 -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);
}
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-02-18 10:30:19 -08:00
if (thread_is_running) {
sdStart(&HW_UART_DEV, &uart_cfg);
uart_is_running = true;
2014-08-10 12:51:13 -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
}
static THD_FUNCTION(packet_process_thread, arg) {
2014-08-10 12:51:13 -07:00
(void)arg;
chRegSetThreadName("uartcomm process");
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(;;) {
chEvtWaitAny(ALL_EVENTS);
bool rx = true;
while (rx) {
rx = false;
msg_t res = sdGetTimeout(&HW_UART_DEV, TIME_IMMEDIATE);
if (res != MSG_TIMEOUT) {
#ifdef HW_UART_P_DEV
from_p_uart = false;
#endif
packet_process_byte(res, PACKET_HANDLER);
rx = true;
}
2014-08-10 12:51:13 -07:00
2019-02-18 10:30:19 -08:00
#ifdef HW_UART_P_DEV
res = sdGetTimeout(&HW_UART_P_DEV, TIME_IMMEDIATE);
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
}
}
}