diff --git a/.gitignore b/.gitignore
index eb48f105..f620aae1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
build/*
!build/hover.hex
+.pio/
+.pioenvs/
+.vscode/
diff --git a/Inc/config.h b/Inc/config.h
index dfe17d2f..e9ccb92c 100644
--- a/Inc/config.h
+++ b/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!
diff --git a/Inc/defines.h b/Inc/defines.h
index dc66f4f9..a742e5ba 100644
--- a/Inc/defines.h
+++ b/Inc/defines.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,20 @@ 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
+void UART_DisableRxErrors(UART_HandleTypeDef *huart);
\ No newline at end of file
diff --git a/Inc/setup.h b/Inc/setup.h
index a024fe6b..e6c31b42 100644
--- a/Inc/setup.h
+++ b/Inc/setup.h
@@ -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);
diff --git a/Inc/stm32f1xx_it.h b/Inc/stm32f1xx_it.h
index 237a392e..fa312a9b 100644
--- a/Inc/stm32f1xx_it.h
+++ b/Inc/stm32f1xx_it.h
@@ -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
}
diff --git a/Src/bldc.c b/Src/bldc.c
index e5c609cd..47c004d1 100644
--- a/Src/bldc.c
+++ b/Src/bldc.c
@@ -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;
diff --git a/Src/comms.c b/Src/comms.c
index 5e437a18..b26d8adb 100644
--- a/Src/comms.c
+++ b/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
}
diff --git a/Src/control.c b/Src/control.c
index 9ffdfd2a..8ff352b8 100644
--- a/Src/control.c
+++ b/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,169 @@ 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
+
+/**
+ * @brief Disable Rx Errors detection interrupts on UART peripheral (since we do not want DMA to be stopped)
+ * The incorrect data will be filtered based on the START_FRAME and checksum.
+ * @param huart: UART handle.
+ * @retval None
+ */
+#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || \
+ defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
+void UART_DisableRxErrors(UART_HandleTypeDef *huart)
+{
+ /* Disable PE (Parity Error) interrupts */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+
+ /* Disable EIE (Frame error, noise error, overrun error) interrupts */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+}
+#endif
+
diff --git a/Src/main.c b/Src/main.c
index 369ed89b..4115daa3 100644
--- a/Src/main.c
+++ b/Src/main.c
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*/
+#include
#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,13 @@ 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));
+ UART_DisableRxErrors(&huart2);
+ #endif
+ #if defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
+ HAL_UART_Receive_DMA(&huart3, (uint8_t *)rx_buffer_R, sizeof(rx_buffer_R));
+ UART_DisableRxErrors(&huart3);
#endif
#ifdef DEBUG_I2C_LCD
@@ -219,20 +238,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;
diff --git a/Src/setup.c b/Src/setup.c
index 8de657a0..3e021a1d 100644
--- a/Src/setup.c
+++ b/Src/setup.c
@@ -44,182 +44,238 @@ 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();
+#if defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || \
+ defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)
+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);
+
+ /* 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);
+
+ /* 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_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);
+ GPIO_InitStruct.Pin = GPIO_PIN_11;
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- 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;
+ /* 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 */
+
+ /* 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);
+
+ /* USART2 DMA DeInit */
+ HAL_DMA_DeInit(uartHandle->hdmarx);
+ HAL_DMA_DeInit(uartHandle->hdmatx);
+
+ /* 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);
- USART2->CR3 |= USART_CR3_DMAT; // | USART_CR3_DMAR | USART_CR3_OVRDIS;
+ /* USART3 DMA DeInit */
+ HAL_DMA_DeInit(uartHandle->hdmarx);
+ HAL_DMA_DeInit(uartHandle->hdmatx);
- 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);
+ /* USART3 interrupt Deinit */
+ HAL_NVIC_DisableIRQ(USART3_IRQn);
+ /* USER CODE BEGIN USART3_MspDeInit 1 */
- 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;
-}
-*/
+ /* USER CODE END USART3_MspDeInit 1 */
+ }
+}
+#endif
DMA_HandleTypeDef hdma_i2c2_rx;
DMA_HandleTypeDef hdma_i2c2_tx;
diff --git a/Src/stm32f1xx_it.c b/Src/stm32f1xx_it.c
index 8ca24ee5..5c2b8acb 100644
--- a/Src/stm32f1xx_it.c
+++ b/Src/stm32f1xx_it.c
@@ -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. */
diff --git a/platformio.ini b/platformio.ini
new file mode 100644
index 00000000..1b2f8f21
--- /dev/null
+++ b/platformio.ini
@@ -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
+
+;================================================================
+