forked from lucysrausch/hoverboard-firmware-hack
Major UART communication improvement
- the UART communication is improved based on UART Idle line detection interrupt - an Rx ring buffer is used to manage the UART incoming data - both Tx and Rx are efficiently handled using DMA - added posibility for User commnds via UART in DEBUG mode
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,5 @@
|
||||
build/*
|
||||
!build/hover.hex
|
||||
.pio/
|
||||
.pioenvs/
|
||||
.vscode/
|
||||
|
31
Inc/config.h
31
Inc/config.h
@ -9,7 +9,9 @@
|
||||
#define DELAY_IN_MAIN_LOOP 5 // in ms. default 5. it is independent of all the timing critical stuff. do not touch if you do not know what you are doing.
|
||||
|
||||
#define TIMEOUT 5 // number of wrong / missing input commands before emergency off
|
||||
#define START_FRAME 0xAAAA // serial command start-of-frame magic word
|
||||
#define SERIAL_START_FRAME 0xABCD // [-] Start frame definition for serial commands
|
||||
#define SERIAL_TIMEOUT 160 // [-] Serial timeout duration for the received data. 160 ~= 0.8 sec. Calculation: 0.8 sec / 0.005 sec
|
||||
#define SERIAL_BUFFER_SIZE 64 // [bytes] Size of Serial Rx buffer. Make sure it is always larger than the structure size
|
||||
|
||||
// ############################### GENERAL ###############################
|
||||
|
||||
@ -47,7 +49,11 @@
|
||||
// ############################### SERIAL DEBUG ###############################
|
||||
|
||||
#define DEBUG_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuck or lcd) is used!
|
||||
#define DEBUG_BAUD 115200 // UART baud rate
|
||||
#if defined(DEBUG_SERIAL_USART2)
|
||||
#define USART2_BAUD 115200 // UART baud rate
|
||||
#elif defined(DEBUG_SERIAL_USART3)
|
||||
#define USART3_BAUD 115200 // UART baud rate
|
||||
#endif
|
||||
//#define DEBUG_SERIAL_SERVOTERM // Software for plotting graphs: https://github.com/STMBL/Servoterm-app
|
||||
#define DEBUG_SERIAL_ASCII // "1:345 2:1337 3:0 4:0 5:0 6:0 7:0 8:0\r\n"
|
||||
|
||||
@ -55,7 +61,11 @@
|
||||
|
||||
// ###### CONTROL VIA UART (serial) ######
|
||||
//#define CONTROL_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used!
|
||||
#define CONTROL_BAUD 19200 // control via usart from eg an Arduino or raspberry
|
||||
#if defined(CONTROL_SERIAL_USART2)
|
||||
#define USART2_BAUD 19200 // UART baud rate
|
||||
#elif defined(CONTROL_SERIAL_USART3)
|
||||
#define USART3_BAUD 19200 // UART baud rate
|
||||
#endif
|
||||
// for Arduino, use void loop(void){ Serial.write((uint8_t *) &steer, sizeof(steer)); Serial.write((uint8_t *) &speed, sizeof(speed));delay(20); }
|
||||
|
||||
// ###### CONTROL VIA RC REMOTE ######
|
||||
@ -155,6 +165,14 @@ else {\
|
||||
#error DEBUG_I2C_LCD and DEBUG_SERIAL_USART3 not allowed. it is on the same cable.
|
||||
#endif
|
||||
|
||||
#if defined(CONTROL_SERIAL_USART2) && defined(CONTROL_SERIAL_USART3)
|
||||
#error CONTROL_SERIAL_USART2 and CONTROL_SERIAL_USART3 not allowed, choose one.
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART2) && defined(DEBUG_SERIAL_USART3)
|
||||
#error DEBUG_SERIAL_USART2 and DEBUG_SERIAL_USART3 not allowed, choose one.
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_SERIAL_USART2
|
||||
#if defined CONTROL_DEFINED
|
||||
#error select exactly 1 input method in config.h!
|
||||
@ -162,6 +180,13 @@ else {\
|
||||
#define CONTROL_DEFINED
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_SERIAL_USART3
|
||||
#if defined CONTROL_DEFINED
|
||||
#error select exactly 1 input method in config.h!
|
||||
#endif
|
||||
#define CONTROL_DEFINED
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_PPM
|
||||
#if defined CONTROL_DEFINED
|
||||
#error select exactly 1 input method in config.h!
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "config.h"
|
||||
|
||||
#define LEFT_HALL_U_PIN GPIO_PIN_5
|
||||
#define LEFT_HALL_V_PIN GPIO_PIN_6
|
||||
@ -141,10 +142,12 @@
|
||||
#define SIGN(a) (((a) < 0.0) ? (-1.0) : (((a) > 0.0) ? (1.0) : (0.0)))
|
||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
||||
#define SCALE(value, high, max) MIN(MAX(((max) - (value)) / ((max) - (high)), 0.0), 1.0)
|
||||
#define IN_RANGE(x, low, up) (((x) >= (low)) && ((x) <= (up)))
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN3(a, b, c) MIN(a, MIN(b, c))
|
||||
#define MAX3(a, b, c) MAX(a, MAX(b, c))
|
||||
#define ARRAY_LEN(x) (uint32_t)(sizeof(x) / sizeof(*(x)))
|
||||
|
||||
typedef struct {
|
||||
uint16_t rr1;
|
||||
@ -158,3 +161,19 @@ typedef struct {
|
||||
uint16_t temp;
|
||||
uint16_t l_rx2;
|
||||
} adc_buf_t;
|
||||
|
||||
typedef struct{
|
||||
uint16_t start;
|
||||
int16_t steer;
|
||||
int16_t speed;
|
||||
uint16_t checksum;
|
||||
} SerialCommand;
|
||||
|
||||
void usart2_rx_check(void);
|
||||
void usart3_rx_check(void);
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(DEBUG_SERIAL_USART3)
|
||||
void usart_process_debug(uint8_t *userCommand, uint32_t len);
|
||||
#endif
|
||||
#if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3)
|
||||
void usart_process_command(SerialCommand *command_in, SerialCommand *command_out, uint8_t usart_idx);
|
||||
#endif
|
@ -27,4 +27,5 @@ void MX_GPIO_Init(void);
|
||||
void MX_TIM_Init(void);
|
||||
void MX_ADC1_Init(void);
|
||||
void MX_ADC2_Init(void);
|
||||
void UART_Init(void);
|
||||
void UART2_Init(void);
|
||||
void UART3_Init(void);
|
||||
|
@ -56,7 +56,13 @@ void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void DMA1_Channel1_IRQHandler(void);
|
||||
void DMA1_Channel2_IRQHandler(void);
|
||||
void DMA1_Channel3_IRQHandler(void);
|
||||
void DMA1_Channel6_IRQHandler(void);
|
||||
void DMA1_Channel7_IRQHandler(void);
|
||||
void DMA2_Channel4_5_IRQHandler(void);
|
||||
void USART2_IRQHandler(void);
|
||||
void USART3_IRQHandler(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ const uint8_t hall_to_pos[8] = {
|
||||
0,
|
||||
};
|
||||
|
||||
inline void blockPWM(int pwm, int pos, int *u, int *v, int *w) {
|
||||
void blockPWM(int pwm, int pos, int *u, int *v, int *w) {
|
||||
switch(pos) {
|
||||
case 0:
|
||||
*u = 0;
|
||||
@ -75,7 +75,7 @@ inline void blockPWM(int pwm, int pos, int *u, int *v, int *w) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void blockPhaseCurrent(int pos, int u, int v, int *q) {
|
||||
void blockPhaseCurrent(int pos, int u, int v, int *q) {
|
||||
switch(pos) {
|
||||
case 0:
|
||||
*q = u - v;
|
||||
|
59
Src/comms.c
59
Src/comms.c
@ -5,16 +5,8 @@
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
|
||||
UART_HandleTypeDef huart2;
|
||||
|
||||
#ifdef DEBUG_SERIAL_USART3
|
||||
#define UART_DMA_CHANNEL DMA1_Channel2
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SERIAL_USART2
|
||||
#define UART_DMA_CHANNEL DMA1_Channel7
|
||||
#endif
|
||||
|
||||
extern UART_HandleTypeDef huart2;
|
||||
extern UART_HandleTypeDef huart3;
|
||||
|
||||
volatile uint8_t uart_buf[100];
|
||||
volatile int16_t ch_buf[8];
|
||||
@ -37,28 +29,49 @@ void consoleScope() {
|
||||
uart_buf[8] = CLAMP(ch_buf[7]+127, 0, 255);
|
||||
uart_buf[9] = '\n';
|
||||
|
||||
if(UART_DMA_CHANNEL->CNDTR == 0) {
|
||||
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN;
|
||||
UART_DMA_CHANNEL->CNDTR = 10;
|
||||
UART_DMA_CHANNEL->CMAR = (uint32_t)uart_buf;
|
||||
UART_DMA_CHANNEL->CCR |= DMA_CCR_EN;
|
||||
#ifdef DEBUG_SERIAL_USART2
|
||||
if(__HAL_DMA_GET_COUNTER(huart2.hdmatx) == 0) {
|
||||
HAL_UART_Transmit_DMA(&huart2, (uint8_t *)uart_buf, strLength);
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_SERIAL_USART3
|
||||
if(__HAL_DMA_GET_COUNTER(huart3.hdmatx) == 0) {
|
||||
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)uart_buf, strLength);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined DEBUG_SERIAL_ASCII && (defined DEBUG_SERIAL_USART2 || defined DEBUG_SERIAL_USART3)
|
||||
memset(uart_buf, 0, sizeof(uart_buf));
|
||||
sprintf(uart_buf, "1:%i 2:%i 3:%i 4:%i 5:%i 6:%i 7:%i 8:%i\r\n", ch_buf[0], ch_buf[1], ch_buf[2], ch_buf[3], ch_buf[4], ch_buf[5], ch_buf[6], ch_buf[7]);
|
||||
int strLength;
|
||||
strLength = sprintf((char *)(uintptr_t)uart_buf,
|
||||
"1:%i 2:%i 3:%i 4:%i 5:%i 6:%i 7:%i 8:%i\r\n",
|
||||
ch_buf[0], ch_buf[1], ch_buf[2], ch_buf[3], ch_buf[4], ch_buf[5], ch_buf[6], ch_buf[7]);
|
||||
|
||||
if(UART_DMA_CHANNEL->CNDTR == 0) {
|
||||
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN;
|
||||
UART_DMA_CHANNEL->CNDTR = strlen(uart_buf);
|
||||
UART_DMA_CHANNEL->CMAR = (uint32_t)uart_buf;
|
||||
UART_DMA_CHANNEL->CCR |= DMA_CCR_EN;
|
||||
#ifdef DEBUG_SERIAL_USART2
|
||||
if(__HAL_DMA_GET_COUNTER(huart2.hdmatx) == 0) {
|
||||
HAL_UART_Transmit_DMA(&huart2, (uint8_t *)uart_buf, strLength);
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_SERIAL_USART3
|
||||
if(__HAL_DMA_GET_COUNTER(huart3.hdmatx) == 0) {
|
||||
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)uart_buf, strLength);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void consoleLog(char *message)
|
||||
{
|
||||
HAL_UART_Transmit_DMA(&huart2, (uint8_t *)message, strlen(message));
|
||||
#if defined DEBUG_SERIAL_ASCII && (defined DEBUG_SERIAL_USART2 || defined DEBUG_SERIAL_USART3)
|
||||
#ifdef DEBUG_SERIAL_USART2
|
||||
if(__HAL_DMA_GET_COUNTER(huart2.hdmatx) == 0) {
|
||||
HAL_UART_Transmit_DMA(&huart2, (uint8_t *)message, strlen((char *)(uintptr_t)message));
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_SERIAL_USART3
|
||||
if(__HAL_DMA_GET_COUNTER(huart3.hdmatx) == 0) {
|
||||
HAL_UART_Transmit_DMA(&huart3, (uint8_t *)message, strlen((char *)(uintptr_t)message));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
197
Src/control.c
197
Src/control.c
@ -17,6 +17,33 @@ extern I2C_HandleTypeDef hi2c2;
|
||||
DMA_HandleTypeDef hdma_i2c2_rx;
|
||||
DMA_HandleTypeDef hdma_i2c2_tx;
|
||||
|
||||
extern UART_HandleTypeDef huart2;
|
||||
extern UART_HandleTypeDef huart3;
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
extern uint8_t rx_buffer_L[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer
|
||||
static uint32_t rx_buffer_L_len = ARRAY_LEN(rx_buffer_L);
|
||||
#endif
|
||||
#if defined(CONTROL_SERIAL_USART2)
|
||||
extern uint16_t timeoutCntSerial_L; // Timeout counter for Rx Serial command
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
extern uint8_t rx_buffer_R[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer
|
||||
static uint32_t rx_buffer_R_len = ARRAY_LEN(rx_buffer_R);
|
||||
#endif
|
||||
#if defined(CONTROL_SERIAL_USART3)
|
||||
extern uint16_t timeoutCntSerial_R; // Timeout counter for Rx Serial command
|
||||
#endif
|
||||
|
||||
#if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3)
|
||||
extern SerialCommand command;
|
||||
static SerialCommand command_raw;
|
||||
static uint32_t command_len = sizeof(command);
|
||||
extern uint8_t timeoutFlagSerial; // Timeout Flag for Rx Serial command: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONTROL_PPM
|
||||
uint16_t ppm_captured_value[PPM_NUM_CHANNELS + 1] = {500, 500};
|
||||
uint16_t ppm_captured_value_buffer[PPM_NUM_CHANNELS+1] = {500, 500};
|
||||
@ -24,8 +51,6 @@ uint32_t ppm_timeout = 0;
|
||||
|
||||
bool ppm_valid = true;
|
||||
|
||||
#define IN_RANGE(x, low, up) (((x) >= (low)) && ((x) <= (up)))
|
||||
|
||||
void PPM_ISR_Callback() {
|
||||
// Dummy loop with 16 bit count wrap around
|
||||
uint16_t rc_delay = TIM2->CNT;
|
||||
@ -117,3 +142,171 @@ void Nunchuck_Read() {
|
||||
//setScopeChannel(2, (int)nunchuck_data[5] & 1);
|
||||
//setScopeChannel(3, ((int)nunchuck_data[5] >> 1) & 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for new data received on USART2 with DMA: refactored function from https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx
|
||||
* - this function is called for every USART IDLE line detection, in the USART interrupt handler
|
||||
*/
|
||||
void usart2_rx_check(void)
|
||||
{
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
static uint32_t old_pos;
|
||||
uint32_t pos;
|
||||
pos = rx_buffer_L_len - __HAL_DMA_GET_COUNTER(huart2.hdmarx); // Calculate current position in buffer
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART2)
|
||||
if (pos != old_pos) { // Check change in received data
|
||||
if (pos > old_pos) { // "Linear" buffer mode: check if current position is over previous one
|
||||
usart_process_debug(&rx_buffer_L[old_pos], pos - old_pos); // Process data
|
||||
} else { // "Overflow" buffer mode
|
||||
usart_process_debug(&rx_buffer_L[old_pos], rx_buffer_L_len - old_pos); // First Process data from the end of buffer
|
||||
if (pos > 0) { // Check and continue with beginning of buffer
|
||||
usart_process_debug(&rx_buffer_L[0], pos); // Process remaining data
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_SERIAL_USART2
|
||||
|
||||
#ifdef CONTROL_SERIAL_USART2
|
||||
uint8_t *ptr;
|
||||
if (pos != old_pos) { // Check change in received data
|
||||
ptr = (uint8_t *)&command_raw; // Initialize the pointer with command_raw address
|
||||
if (pos > old_pos && (pos - old_pos) == command_len) { // "Linear" buffer mode: check if current position is over previous one AND data length equals expected length
|
||||
memcpy(ptr, &rx_buffer_L[old_pos], command_len); // Copy data. This is possible only if command_raw is contiguous! (meaning all the structure members have the same size)
|
||||
usart_process_command(&command_raw, &command, 2); // Process data
|
||||
} else if ((rx_buffer_L_len - old_pos + pos) == command_len) { // "Overflow" buffer mode: check if data length equals expected length
|
||||
memcpy(ptr, &rx_buffer_L[old_pos], rx_buffer_L_len - old_pos); // First copy data from the end of buffer
|
||||
if (pos > 0) { // Check and continue with beginning of buffer
|
||||
ptr += rx_buffer_L_len - old_pos; // Move to correct position in command_raw
|
||||
memcpy(ptr, &rx_buffer_L[0], pos); // Copy remaining data
|
||||
}
|
||||
usart_process_command(&command_raw, &command, 2); // Process data
|
||||
}
|
||||
}
|
||||
#endif // CONTROL_SERIAL_USART2
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
old_pos = pos; // Update old position
|
||||
if (old_pos == rx_buffer_L_len) { // Check and manually update if we reached end of buffer
|
||||
old_pos = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for new data received on USART3 with DMA: refactored function from https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx
|
||||
* - this function is called for every USART IDLE line detection, in the USART interrupt handler
|
||||
*/
|
||||
void usart3_rx_check(void)
|
||||
{
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
static uint32_t old_pos;
|
||||
uint32_t pos;
|
||||
pos = rx_buffer_R_len - __HAL_DMA_GET_COUNTER(huart3.hdmarx); // Calculate current position in buffer
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART3)
|
||||
if (pos != old_pos) { // Check change in received data
|
||||
if (pos > old_pos) { // "Linear" buffer mode: check if current position is over previous one
|
||||
usart_process_debug(&rx_buffer_R[old_pos], pos - old_pos); // Process data
|
||||
} else { // "Overflow" buffer mode
|
||||
usart_process_debug(&rx_buffer_R[old_pos], rx_buffer_R_len - old_pos); // First Process data from the end of buffer
|
||||
if (pos > 0) { // Check and continue with beginning of buffer
|
||||
usart_process_debug(&rx_buffer_R[0], pos); // Process remaining data
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_SERIAL_USART3
|
||||
|
||||
#ifdef CONTROL_SERIAL_USART3
|
||||
uint8_t *ptr;
|
||||
if (pos != old_pos) { // Check change in received data
|
||||
ptr = (uint8_t *)&command_raw; // Initialize the pointer with command_raw address
|
||||
if (pos > old_pos && (pos - old_pos) == command_len) { // "Linear" buffer mode: check if current position is over previous one AND data length equals expected length
|
||||
memcpy(ptr, &rx_buffer_R[old_pos], command_len); // Copy data. This is possible only if command_raw is contiguous! (meaning all the structure members have the same size)
|
||||
usart_process_command(&command_raw, &command, 3); // Process data
|
||||
} else if ((rx_buffer_R_len - old_pos + pos) == command_len) { // "Overflow" buffer mode: check if data length equals expected length
|
||||
memcpy(ptr, &rx_buffer_R[old_pos], rx_buffer_R_len - old_pos); // First copy data from the end of buffer
|
||||
if (pos > 0) { // Check and continue with beginning of buffer
|
||||
ptr += rx_buffer_R_len - old_pos; // Move to correct position in command_raw
|
||||
memcpy(ptr, &rx_buffer_R[0], pos); // Copy remaining data
|
||||
}
|
||||
usart_process_command(&command_raw, &command, 3); // Process data
|
||||
}
|
||||
}
|
||||
#endif // CONTROL_SERIAL_USART3
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
old_pos = pos; // Update old position
|
||||
if (old_pos == rx_buffer_R_len) { // Check and manually update if we reached end of buffer
|
||||
old_pos = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Rx debug user command input
|
||||
*/
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(DEBUG_SERIAL_USART3)
|
||||
void usart_process_debug(uint8_t *userCommand, uint32_t len)
|
||||
{
|
||||
for (; len > 0; len--, userCommand++) {
|
||||
if (*userCommand != '\n' && *userCommand != '\r') { // Do not accept 'new line' and 'carriage return' commands
|
||||
consoleLog("-- Command received --\r\n");
|
||||
// handle_input(*userCommand); // -> Create this function to handle the user commands
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // SERIAL_DEBUG
|
||||
|
||||
/*
|
||||
* Process command Rx data
|
||||
* - if the command_in data is valid (correct START_FRAME and checksum) copy the command_in to command_out
|
||||
*/
|
||||
#if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3)
|
||||
void usart_process_command(SerialCommand *command_in, SerialCommand *command_out, uint8_t usart_idx)
|
||||
{
|
||||
uint16_t checksum;
|
||||
if (command_in->start == SERIAL_START_FRAME) {
|
||||
checksum = (uint16_t)(command_in->start ^ command_in->steer ^ command_in->speed);
|
||||
if (command_in->checksum == checksum) {
|
||||
*command_out = *command_in;
|
||||
if (usart_idx == 2) { // Sideboard USART2
|
||||
#ifdef CONTROL_SERIAL_USART2
|
||||
timeoutCntSerial_L = 0; // Reset timeout counter
|
||||
timeoutFlagSerial = 0; // Clear timeout flag
|
||||
#endif
|
||||
} else if (usart_idx == 3) { // Sideboard USART3
|
||||
#ifdef CONTROL_SERIAL_USART3
|
||||
timeoutCntSerial_R = 0; // Reset timeout counter
|
||||
timeoutFlagSerial = 0; // Clear timeout flag
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* UART User Error Callback
|
||||
* - According to the STM documentation, when a DMA transfer error occurs during a DMA read or a write access,
|
||||
* the faulty channel is automatically disabled through a hardware clear of its EN bit
|
||||
* - For hoverboard applications, the UART communication can be unrealiable, disablind the DMA transfer
|
||||
* - therefore the DMA needs to be re-started
|
||||
*/
|
||||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *uartHandle) {
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2)
|
||||
if(uartHandle->Instance == USART2) {
|
||||
HAL_UART_Receive_DMA(uartHandle, (uint8_t *)rx_buffer_L, sizeof(rx_buffer_L));
|
||||
}
|
||||
#endif
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3)
|
||||
if(uartHandle->Instance == USART3) {
|
||||
HAL_UART_Receive_DMA(uartHandle, (uint8_t *)rx_buffer_R, sizeof(rx_buffer_R));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
83
Src/main.c
83
Src/main.c
@ -19,6 +19,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "defines.h"
|
||||
#include "setup.h"
|
||||
@ -35,20 +36,12 @@ extern volatile adc_buf_t adc_buffer;
|
||||
//LCD_PCF8574_HandleTypeDef lcd;
|
||||
extern I2C_HandleTypeDef hi2c2;
|
||||
extern UART_HandleTypeDef huart2;
|
||||
extern UART_HandleTypeDef huart3;
|
||||
|
||||
int cmd1; // normalized input values. -1000 to 1000
|
||||
int cmd2;
|
||||
int cmd3;
|
||||
|
||||
typedef struct{
|
||||
uint16_t start_of_frame;
|
||||
int16_t steer;
|
||||
int16_t speed;
|
||||
uint16_t checksum;
|
||||
} Serialcommand;
|
||||
|
||||
volatile Serialcommand command;
|
||||
|
||||
uint8_t button1, button2;
|
||||
|
||||
int steer; // global variable for steering. -1000 to 1000
|
||||
@ -77,6 +70,25 @@ extern uint8_t nunchuck_data[6];
|
||||
extern volatile uint16_t ppm_captured_value[PPM_NUM_CHANNELS+1];
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
uint8_t rx_buffer_L[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer
|
||||
#endif
|
||||
#if defined(CONTROL_SERIAL_USART2)
|
||||
uint16_t timeoutCntSerial_L = 0; // Timeout counter for Rx Serial command
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
uint8_t rx_buffer_R[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer
|
||||
#endif
|
||||
#if defined(CONTROL_SERIAL_USART3)
|
||||
uint16_t timeoutCntSerial_R = 0; // Timeout counter for Rx Serial command
|
||||
#endif
|
||||
|
||||
#if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3)
|
||||
SerialCommand command;
|
||||
uint8_t timeoutFlagSerial = 0; // Timeout Flag for Rx Serial command: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data)
|
||||
#endif
|
||||
|
||||
int milli_vel_error_sum = 0;
|
||||
|
||||
|
||||
@ -126,8 +138,11 @@ int main(void) {
|
||||
MX_ADC1_Init();
|
||||
MX_ADC2_Init();
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(DEBUG_SERIAL_USART3)
|
||||
UART_Init();
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
UART2_Init();
|
||||
#endif
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
UART3_Init();
|
||||
#endif
|
||||
|
||||
HAL_GPIO_WritePin(OFF_PORT, OFF_PIN, 1);
|
||||
@ -156,9 +171,11 @@ int main(void) {
|
||||
Nunchuck_Init();
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_SERIAL_USART2
|
||||
UART_Control_Init();
|
||||
HAL_UART_Receive_DMA(&huart2, (uint8_t *)&command, sizeof(command));
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
HAL_UART_Receive_DMA(&huart2, (uint8_t *)rx_buffer_L, sizeof(rx_buffer_L));
|
||||
#endif
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
HAL_UART_Receive_DMA(&huart3, (uint8_t *)rx_buffer_R, sizeof(rx_buffer_R));
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_I2C_LCD
|
||||
@ -219,20 +236,30 @@ int main(void) {
|
||||
timeout = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_SERIAL_USART2
|
||||
if (command.start_of_frame == START_FRAME &&
|
||||
command.checksum ==(uint16_t)(START_FRAME ^ command.steer ^ command.speed)) {
|
||||
cmd1 = CLAMP((int16_t)command.steer, -1000, 1000);
|
||||
cmd2 = CLAMP((int16_t)command.speed, -1000, 1000);
|
||||
} else { // restart DMA to hopefully get back in sync
|
||||
// Try a periodic reset
|
||||
if (main_loop_counter % 25 == 0) {
|
||||
HAL_UART_DMAStop(&huart2);
|
||||
HAL_UART_Receive_DMA(&huart2, (uint8_t *)&command, sizeof(command));
|
||||
}
|
||||
}
|
||||
timeout = 0;
|
||||
#endif
|
||||
#if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3)
|
||||
if (IN_RANGE(command.steer, -1000, 1000) && IN_RANGE(command.speed, -1000, 1000)) {
|
||||
cmd1 = command.steer;
|
||||
cmd2 = command.speed;
|
||||
}
|
||||
#if defined(CONTROL_SERIAL_USART2)
|
||||
if (timeoutCntSerial_L++ >= SERIAL_TIMEOUT) { // Timeout qualification
|
||||
timeoutFlagSerial = 1; // Timeout detected
|
||||
timeoutCntSerial_L = SERIAL_TIMEOUT; // Limit timout counter value
|
||||
}
|
||||
#endif
|
||||
#if defined(CONTROL_SERIAL_USART3)
|
||||
if (timeoutCntSerial_R++ >= SERIAL_TIMEOUT) { // Timeout qualification
|
||||
timeoutFlagSerial = 1; // Timeout detected
|
||||
timeoutCntSerial_R = SERIAL_TIMEOUT; // Limit timout counter value
|
||||
}
|
||||
#endif
|
||||
if (timeoutFlagSerial) { // In case of timeout bring the system to a Safe State
|
||||
cmd1 = 0;
|
||||
cmd2 = 0;
|
||||
}
|
||||
|
||||
timeout = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_MOTOR_TEST
|
||||
if (motor_test_direction == 1) cmd2 += 1;
|
||||
|
331
Src/setup.c
331
Src/setup.c
@ -44,182 +44,235 @@ ADC_HandleTypeDef hadc1;
|
||||
ADC_HandleTypeDef hadc2;
|
||||
I2C_HandleTypeDef hi2c2;
|
||||
UART_HandleTypeDef huart2;
|
||||
UART_HandleTypeDef huart3;
|
||||
|
||||
DMA_HandleTypeDef hdma_usart2_rx;
|
||||
DMA_HandleTypeDef hdma_usart2_tx;
|
||||
DMA_HandleTypeDef hdma_usart3_rx;
|
||||
DMA_HandleTypeDef hdma_usart3_tx;
|
||||
volatile adc_buf_t adc_buffer;
|
||||
|
||||
|
||||
#ifdef CONTROL_SERIAL_USART2
|
||||
|
||||
|
||||
void UART_Control_Init() {
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
__HAL_RCC_USART2_CLK_ENABLE();
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
/* USART2 init function */
|
||||
void UART2_Init(void)
|
||||
{
|
||||
/* DMA controller clock enable */
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
|
||||
/* DMA1_Channel6_IRQn interrupt configuration */
|
||||
//HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 6);
|
||||
//HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
|
||||
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 6);
|
||||
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
|
||||
/* DMA1_Channel7_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 5, 7);
|
||||
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
|
||||
|
||||
|
||||
huart2.Instance = USART2;
|
||||
huart2.Init.BaudRate = CONTROL_BAUD;
|
||||
huart2.Init.BaudRate = USART2_BAUD;
|
||||
huart2.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart2.Init.StopBits = UART_STOPBITS_1;
|
||||
huart2.Init.Parity = UART_PARITY_NONE;
|
||||
huart2.Init.Mode = UART_MODE_TX_RX;
|
||||
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
// huart2.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
HAL_UART_Init(&huart2);
|
||||
|
||||
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
/* USER CODE BEGIN USART2_MspInit 0 */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/* USER CODE END USART2_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_USART2_CLK_ENABLE();
|
||||
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP; //GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //GPIO_MODE_AF_PP;
|
||||
// GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* Peripheral DMA init*/
|
||||
|
||||
hdma_usart2_rx.Instance = DMA1_Channel6;
|
||||
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR; //DMA_NORMAL;
|
||||
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
HAL_DMA_Init(&hdma_usart2_rx);
|
||||
|
||||
__HAL_LINKDMA(&huart2,hdmarx,hdma_usart2_rx);
|
||||
|
||||
hdma_usart2_tx.Instance = DMA1_Channel7;
|
||||
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
HAL_DMA_Init(&hdma_usart2_tx);
|
||||
__HAL_LINKDMA(&huart2,hdmatx,hdma_usart2_tx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SERIAL_USART3
|
||||
void UART_Init() {
|
||||
__HAL_RCC_USART3_CLK_ENABLE();
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
/* USART3 init function */
|
||||
void UART3_Init(void)
|
||||
{
|
||||
/* DMA controller clock enable */
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
|
||||
UART_HandleTypeDef huart3;
|
||||
huart3.Instance = USART3;
|
||||
huart3.Init.BaudRate = DEBUG_BAUD;
|
||||
huart3.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart3.Init.StopBits = UART_STOPBITS_1;
|
||||
huart3.Init.Parity = UART_PARITY_NONE;
|
||||
huart3.Init.Mode = UART_MODE_TX;
|
||||
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
/* DMA interrupt init */
|
||||
/* DMA1_Channel2_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
|
||||
/* DMA1_Channel3_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
|
||||
|
||||
huart3.Instance = USART3;
|
||||
huart3.Init.BaudRate = USART3_BAUD;
|
||||
huart3.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart3.Init.StopBits = UART_STOPBITS_1;
|
||||
huart3.Init.Parity = UART_PARITY_NONE;
|
||||
huart3.Init.Mode = UART_MODE_TX_RX;
|
||||
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
HAL_UART_Init(&huart3);
|
||||
|
||||
USART3->CR3 |= USART_CR3_DMAT; // | USART_CR3_DMAR | USART_CR3_OVRDIS;
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
DMA1_Channel2->CCR = 0;
|
||||
DMA1_Channel2->CPAR = (uint32_t) & (USART3->DR);
|
||||
DMA1_Channel2->CNDTR = 0;
|
||||
DMA1_Channel2->CCR = DMA_CCR_MINC | DMA_CCR_DIR;
|
||||
DMA1->IFCR = DMA_IFCR_CTCIF2 | DMA_IFCR_CHTIF2 | DMA_IFCR_CGIF2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SERIAL_USART2
|
||||
void UART_Init() {
|
||||
__HAL_RCC_USART2_CLK_ENABLE();
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(uartHandle->Instance==USART2)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_MspInit 0 */
|
||||
|
||||
UART_HandleTypeDef huart2;
|
||||
huart2.Instance = USART2;
|
||||
huart2.Init.BaudRate = DEBUG_BAUD;
|
||||
huart2.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart2.Init.StopBits = UART_STOPBITS_1;
|
||||
huart2.Init.Parity = UART_PARITY_NONE;
|
||||
huart2.Init.Mode = UART_MODE_TX;
|
||||
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
HAL_UART_Init(&huart2);
|
||||
/* USER CODE END USART2_MspInit 0 */
|
||||
/* USART2 clock enable */
|
||||
__HAL_RCC_USART2_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**USART2 GPIO Configuration
|
||||
PA2 ------> USART2_TX
|
||||
PA3 ------> USART2_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
USART2->CR3 |= USART_CR3_DMAT; // | USART_CR3_DMAR | USART_CR3_OVRDIS;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
/* USART2 DMA Init */
|
||||
/* USART2_RX Init */
|
||||
hdma_usart2_rx.Instance = DMA1_Channel6;
|
||||
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
|
||||
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
HAL_DMA_Init(&hdma_usart2_rx);
|
||||
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
|
||||
|
||||
DMA1_Channel7->CCR = 0;
|
||||
DMA1_Channel7->CPAR = (uint32_t) & (USART2->DR);
|
||||
DMA1_Channel7->CNDTR = 0;
|
||||
DMA1_Channel7->CCR = DMA_CCR_MINC | DMA_CCR_DIR;
|
||||
DMA1->IFCR = DMA_IFCR_CTCIF7 | DMA_IFCR_CHTIF7 | DMA_IFCR_CGIF7;
|
||||
/* USART2_TX Init */
|
||||
hdma_usart2_tx.Instance = DMA1_Channel7;
|
||||
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
HAL_DMA_Init(&hdma_usart2_tx);
|
||||
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx);
|
||||
|
||||
/* USART2 interrupt Init */
|
||||
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(USART2_IRQn);
|
||||
/* USER CODE BEGIN USART2_MspInit 1 */
|
||||
__HAL_UART_ENABLE_IT (uartHandle, UART_IT_IDLE); // Enable the USART IDLE line detection interrupt
|
||||
/* USER CODE END USART2_MspInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART3)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART3_MspInit 0 */
|
||||
/* USART3 clock enable */
|
||||
__HAL_RCC_USART3_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**USART3 GPIO Configuration
|
||||
PB10 ------> USART3_TX
|
||||
PB11 ------> USART3_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USART3 DMA Init */
|
||||
/* USART3_RX Init */
|
||||
hdma_usart3_rx.Instance = DMA1_Channel3;
|
||||
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;
|
||||
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
HAL_DMA_Init(&hdma_usart3_rx);
|
||||
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart3_rx);
|
||||
|
||||
/* USART3_TX Init */
|
||||
hdma_usart3_tx.Instance = DMA1_Channel2;
|
||||
hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart3_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
HAL_DMA_Init(&hdma_usart3_tx);
|
||||
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart3_tx);
|
||||
|
||||
/* USART3 interrupt Init */
|
||||
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(USART3_IRQn);
|
||||
/* USER CODE BEGIN USART3_MspInit 1 */
|
||||
__HAL_UART_ENABLE_IT (uartHandle, UART_IT_IDLE); // Enable the USART IDLE line detection interrupt
|
||||
/* USER CODE END USART3_MspInit 1 */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
void UART_Init() {
|
||||
__HAL_RCC_USART2_CLK_ENABLE();
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
UART_HandleTypeDef huart2;
|
||||
huart2.Instance = USART2;
|
||||
huart2.Init.BaudRate = 115200;
|
||||
huart2.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart2.Init.StopBits = UART_STOPBITS_1;
|
||||
huart2.Init.Parity = UART_PARITY_NONE;
|
||||
huart2.Init.Mode = UART_MODE_TX;
|
||||
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
HAL_UART_Init(&huart2);
|
||||
if(uartHandle->Instance==USART2)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_MspDeInit 0 */
|
||||
|
||||
USART2->CR3 |= USART_CR3_DMAT; // | USART_CR3_DMAR | USART_CR3_OVRDIS;
|
||||
/* USER CODE END USART2_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART2_CLK_DISABLE();
|
||||
|
||||
/**USART2 GPIO Configuration
|
||||
PA2 ------> USART2_TX
|
||||
PA3 ------> USART2_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
/* USART2 DMA DeInit */
|
||||
HAL_DMA_DeInit(uartHandle->hdmarx);
|
||||
HAL_DMA_DeInit(uartHandle->hdmatx);
|
||||
|
||||
DMA1_Channel7->CCR = 0;
|
||||
DMA1_Channel7->CPAR = (uint32_t) & (USART3->DR);
|
||||
DMA1_Channel7->CNDTR = 0;
|
||||
DMA1_Channel7->CCR = DMA_CCR_MINC | DMA_CCR_DIR;
|
||||
DMA1->IFCR = DMA_IFCR_CTCIF7 | DMA_IFCR_CHTIF7 | DMA_IFCR_CGIF7;
|
||||
}
|
||||
*/
|
||||
/* USART2 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(USART2_IRQn);
|
||||
/* USER CODE BEGIN USART2_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART2_MspDeInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART3)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART3_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART3_CLK_DISABLE();
|
||||
|
||||
/**USART3 GPIO Configuration
|
||||
PB10 ------> USART3_TX
|
||||
PB11 ------> USART3_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
|
||||
|
||||
/* USART3 DMA DeInit */
|
||||
HAL_DMA_DeInit(uartHandle->hdmarx);
|
||||
HAL_DMA_DeInit(uartHandle->hdmatx);
|
||||
|
||||
/* USART3 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(USART3_IRQn);
|
||||
/* USER CODE BEGIN USART3_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART3_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
DMA_HandleTypeDef hdma_i2c2_rx;
|
||||
DMA_HandleTypeDef hdma_i2c2_tx;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "stm32f1xx.h"
|
||||
#include "stm32f1xx_it.h"
|
||||
#include "config.h"
|
||||
#include "defines.h"
|
||||
|
||||
extern DMA_HandleTypeDef hdma_i2c2_rx;
|
||||
extern DMA_HandleTypeDef hdma_i2c2_tx;
|
||||
@ -42,9 +43,12 @@ extern I2C_HandleTypeDef hi2c2;
|
||||
|
||||
extern DMA_HandleTypeDef hdma_usart2_rx;
|
||||
extern DMA_HandleTypeDef hdma_usart2_tx;
|
||||
extern DMA_HandleTypeDef hdma_usart3_rx;
|
||||
extern DMA_HandleTypeDef hdma_usart3_tx;
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
extern UART_HandleTypeDef huart2;
|
||||
extern UART_HandleTypeDef huart3;
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
@ -226,7 +230,7 @@ void EXTI3_IRQHandler(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_SERIAL_USART2
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
void DMA1_Channel6_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
|
||||
@ -253,6 +257,74 @@ void DMA1_Channel7_IRQHandler(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
/**
|
||||
* @brief This function handles DMA1 channel2 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel2_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart3_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel3 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel3_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel3_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel3_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart3_rx);
|
||||
/* USER CODE BEGIN DMA1_Channel3_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel3_IRQn 1 */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)
|
||||
/**
|
||||
* @brief This function handles USART2 global interrupt.
|
||||
*/
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_IRQn 0 */
|
||||
|
||||
/* USER CODE END USART2_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart2);
|
||||
/* USER CODE BEGIN USART2_IRQn 1 */
|
||||
if(RESET != __HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_IDLE)) { // Check for IDLE line interrupt
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart2); // Clear IDLE line flag (otherwise it will continue to enter interrupt)
|
||||
usart2_rx_check(); // Check for data to process
|
||||
}
|
||||
/* USER CODE END USART2_IRQn 1 */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
|
||||
/**
|
||||
* @brief This function handles USART3 global interrupt.
|
||||
*/
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_IRQn 0 */
|
||||
|
||||
/* USER CODE END USART2_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart3);
|
||||
/* USER CODE BEGIN USART2_IRQn 1 */
|
||||
if(RESET != __HAL_UART_GET_IT_SOURCE(&huart3, UART_IT_IDLE)) { // Check for IDLE line interrupt
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart3); // Clear IDLE line flag (otherwise it will continue to enter interrupt)
|
||||
usart3_rx_check(); // Check for data to process
|
||||
}
|
||||
/* USER CODE END USART2_IRQn 1 */
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F1xx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
|
31
platformio.ini
Normal file
31
platformio.ini
Normal file
@ -0,0 +1,31 @@
|
||||
; PlatformIO Project Configuration File2
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
include_dir = Inc
|
||||
src_dir = Src
|
||||
|
||||
;=================== VARIANT SELECTION ==========================
|
||||
|
||||
[env:genericSTM32F103RC]
|
||||
platform = ststm32
|
||||
framework = stm32cube
|
||||
board = genericSTM32F103RC
|
||||
debug_tool = stlink
|
||||
upload_protocol = stlink
|
||||
|
||||
; Serial Port settings (make sure the COM port is correct)
|
||||
monitor_port = COM5
|
||||
monitor_speed = 115200
|
||||
|
||||
build_flags =
|
||||
-DUSE_HAL_DRIVER
|
||||
-DSTM32F103xE
|
||||
-Wl,-T./STM32F103RCTx_FLASH.ld
|
||||
-Wl,-lc
|
||||
-Wl,-lm
|
||||
-g -ggdb ; to generate correctly the 'firmware.elf' for STM STUDIO vizualization
|
||||
# -Wl,-lnosys
|
||||
|
||||
;================================================================
|
||||
|
Reference in New Issue
Block a user