19 Commits

Author SHA1 Message Date
fb8ebc8ea4 Added define wrap for UART
- to completely disable UART init functions in case is not used
2020-06-26 11:33:33 +02:00
a4155f80a0 UART update
- disabled the Rx errors to avoid DMA stop and additional need to manage the UART error handler
2020-06-25 20:19:43 +02:00
f441588f68 Improved UART error recovery
- In case of an Rx error instead of stopping the complete UART, only the Rx DMA is aborted and restarted.
2020-06-23 20:02:17 +02:00
2f8b11449c 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
2020-06-22 08:37:59 +02:00
5af6ecd8bf Update README.md 2020-03-20 02:24:29 +01:00
79dd130028 Merge pull request #132 from hexagon5un/simple_serial_framing
minimalistic framing for UART command
2019-12-18 22:08:10 +01:00
3ee11fc248 fixed bug with signed/unsigned
needed explicit cast in checksum verification
2019-12-18 21:31:22 +01:00
c3fbbab485 a periodic usart reset works much better
tying the usart buffer clear to the 25*5 ms system tick makes sense
2019-12-18 15:42:51 +01:00
976ba2d44a minimalistic framing for UART command
copied the uart framing idea from
https://github.com/EmanuelFeru/hoverboard-firmware-hack-FOC

to use:
send $AAAA to start frame
then steer, speed as usual
and XOR($AAAA, steer, speed) as checksum

commands that don't match are ignored, and UART DMA is reset
hopefully this will set it up to catch the next one
re-send frequently.
2019-12-16 16:11:07 +01:00
2569b22640 Update README.md 2019-08-03 02:32:27 +02:00
000c0fccb8 Update README.md 2019-08-03 02:31:57 +02:00
23c4a3c8ac Update README.md 2019-08-02 23:10:33 +02:00
e9ebbcc1ac Update README.md 2019-08-02 23:08:36 +02:00
3e2cfe973a Fixed timeout. Now it is usable for other input methods than nunchuck.
Cosmetical cleanup in motor-test.
2019-06-01 16:17:48 +02:00
ffda2219f1 Added Motor-Test-Mode: Sweep motors slowly forward and backward without any input.
Better config-validation.
Fixed board temperature calculation and serial output when speed > 50.
2019-05-31 19:06:47 +02:00
2c666c8cb4 Merge pull request #95 from btsimonh/master
Add ref to BiPropellant to readme
2019-04-29 19:41:00 +02:00
e410438330 Merge pull request #24 from btsimonh/bipropellantref2
Add BiPropellant reference to readme
2019-04-29 07:27:33 +01:00
5fbd54d9ab Add BiPropellant reference to readme 2019-04-29 07:25:49 +01:00
226278b2fc Merge pull request #23 from NiklasFauth/master
update master
2019-04-29 07:23:04 +01:00
14 changed files with 1141 additions and 621 deletions

3
.gitignore vendored
View File

@ -1,2 +1,5 @@
build/*
!build/hover.hex
.pio/
.pioenvs/
.vscode/

View File

@ -9,10 +9,13 @@
#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 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 ###############################
// How to calibrate: connect GND and RX of a 3.3v uart-usb adapter to the right sensor board cable (be careful not to use the red wire of the cable. 15v will destroye verything.). if you are using nunchuck, disable it temporarily. enable DEBUG_SERIAL_USART3 and DEBUG_SERIAL_ASCII use asearial terminal.
// How to calibrate: connect GND and RX of a 3.3v uart-usb adapter to the right sensor board cable (be careful not to use the red wire of the cable. 15v will destroy everything.). if you are using nunchuck, disable it temporarily. enable DEBUG_SERIAL_USART3 and DEBUG_SERIAL_ASCII use asearial terminal.
// Battery voltage calibration: connect power source. see <How to calibrate>. write value nr 5 to BAT_CALIB_ADC. make and flash firmware. then you can verify voltage on value 6 (devide it by 100.0 to get calibrated voltage).
#define BAT_CALIB_REAL_VOLTAGE 43.0 // input voltage measured by multimeter
@ -46,25 +49,33 @@
// ############################### 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
//#define DEBUG_SERIAL_SERVOTERM
#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"
// ############################### INPUT ###############################
// ###### 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 ######
// left sensor board cable. Channel 1: steering, Channel 2: speed.
// left sensor board cable. Channel 1: steering, Channel 2: speed. Use a very short cable!
//#define CONTROL_PPM // use PPM-Sum as input. disable CONTROL_SERIAL_USART2!
//#define PPM_NUM_CHANNELS 6 // total number of PPM channels to receive, even if they are not used.
// ###### CONTROL VIA TWO POTENTIOMETERS ######
// ADC-calibration to cover the full poti-range: connect potis to left sensor board cable (0 to 3.3V) (do NOT use the red 15V wire in the cable!). see <How to calibrate>. turn the potis to minimum position, write value 1 to ADC1_MIN and value 2 to ADC2_MIN. turn to maximum position and repeat it for ADC?_MAX. make, flash and test it.
#define CONTROL_ADC // use ADC as input. disable CONTROL_SERIAL_USART2!
//#define CONTROL_ADC // use ADC as input. disable CONTROL_SERIAL_USART2!
#define ADC1_MIN 0 // min ADC1-value while poti at minimum-position (0 - 4095)
#define ADC1_MAX 4095 // max ADC1-value while poti at maximum-position (0 - 4095)
#define ADC2_MIN 0 // min ADC2-value while poti at minimum-position (0 - 4095)
@ -74,6 +85,11 @@
// left sensor board cable. keep cable short, use shielded cable, use ferrits, stabalize voltage in nunchuck, use the right one of the 2 types of nunchucks, add i2c pullups. use original nunchuck. most clones does not work very well.
//#define CONTROL_NUNCHUCK // use nunchuck as input. disable DEBUG_SERIAL_USART3!
// ###### MOTOR TEST MODE ######
// slowly move both wheels forward and backward, ignoring all inputs
#define CONTROL_MOTOR_TEST
#define CONTROL_MOTOR_TEST_MAX_SPEED 300 // sweep slowly from -MAX_SPEED to MAX_SPEED (0 - 1000)
// ############################### DRIVING BEHAVIOR ###############################
// inputs:
@ -149,6 +165,56 @@ else {\
#error DEBUG_I2C_LCD and DEBUG_SERIAL_USART3 not allowed. it is on the same cable.
#endif
#if defined CONTROL_PPM && defined CONTROL_ADC && defined CONTROL_NUNCHUCK || defined CONTROL_PPM && defined CONTROL_ADC || defined CONTROL_ADC && defined CONTROL_NUNCHUCK || defined CONTROL_PPM && defined CONTROL_NUNCHUCK
#error only 1 input method allowed. use CONTROL_PPM or CONTROL_ADC or CONTROL_NUNCHUCK.
#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!
#endif
#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!
#endif
#define CONTROL_DEFINED
#endif
#ifdef CONTROL_ADC
#if defined CONTROL_DEFINED
#error select exactly 1 input method in config.h!
#endif
#define CONTROL_DEFINED
#endif
#ifdef CONTROL_NUNCHUCK
#if defined CONTROL_DEFINED
#error select exactly 1 input method in config.h!
#endif
#define CONTROL_DEFINED
#endif
#ifdef CONTROL_MOTOR_TEST
#if defined CONTROL_DEFINED
#error select exactly 1 input method in config.h!
#endif
#define CONTROL_DEFINED
#endif
#ifndef CONTROL_DEFINED
#error select exactly 1 input method in config.h!
#endif

View File

@ -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);

View File

@ -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);

View File

@ -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
}

View File

@ -80,7 +80,7 @@ Most robust way for input is to use the ADC and potis. It works well even on 1m
---
## Examples
## Examples and links
Have a look at the config.h in the Inc directory. That's where you configure to firmware to match your project.
Currently supported: Wii Nunchuck, analog potentiometer and PPM-Sum signal from a RC remote.
@ -89,11 +89,25 @@ https://github.com/p-h-a-i-l/hoverboard-firmware-hack
If you need additional features like a boost button, have a look at the while(1) loop in the main.c
### Hoverboardhack for AT32F403RCT6 based mainboards
* [https://github.com/cloidnerux/hoverboard-firmware-hack](https://github.com/cloidnerux/hoverboard-firmware-hack)
### Hoverboardhack for split mainboards
* [https://github.com/flo199213/Hoverboard-Firmware-Hack-Gen2](https://github.com/flo199213/Hoverboard-Firmware-Hack-Gen2)
### Online Compiler
* [RoboDurdens awesome](https://github.com/RoboDurden) online compiler: [https://pionierland.de/hoverhack/](https://pionierland.de/hoverhack/)
### Additional Hardware
* [breakout/interconnect boards](https://github.com/Jan--Henrik/hoverboard-breakout) Breakout/Interconnection boards for hoverboard hacking.
### Projects based on it
* [Bidirectional UART communication](https://github.com/RoboDurden/hoverboard-firmware-hack) with Arduino example code
* [bobbycar-optimized firmware](https://github.com/larsmm/hoverboard-firmware-hack-bbcar) based on this one with driving modes, acceleration ramps and some other features
* [wheel chair](https://github.com/Lahorde/steer_speed_ctrl) controlled with a joystick or using a CC2650 sensortag to control it over bluetooth with pitch/roll.
* [TranspOtterNG](https://github.com/Jan--Henrik/transpOtterNG) TranspOtter is an open source semi self driving transportation platform based on hoverboard hardware
* [BiPropellant](https://github.com/bipropellant) - fork which focusses on reliable machine control, but also retains HoverBoard functionality if desired.

View File

@ -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;

View File

@ -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
}

View File

@ -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;
@ -105,8 +130,6 @@ void Nunchuck_Read() {
HAL_Delay(5);
if (HAL_I2C_Master_Receive(&hi2c2,0xA4,(uint8_t*)nunchuck_data, 6, 100) == HAL_OK) {
timeout = 0;
} else {
timeout++;
}
if (timeout > 3) {
@ -119,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

View File

@ -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,19 +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{
int16_t steer;
int16_t speed;
//uint32_t crc;
} Serialcommand;
volatile Serialcommand command;
uint8_t button1, button2;
int steer; // global variable for steering. -1000 to 1000
@ -67,17 +61,41 @@ extern volatile uint32_t timeout; // global variable for timeout
extern float batteryVoltage; // global variable for battery voltage
uint32_t inactivity_timeout_counter;
uint32_t main_loop_counter;
int32_t motor_test_direction = 1;
extern uint8_t nunchuck_data[6];
#ifdef CONTROL_PPM
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;
void poweroff() {
#ifndef CONTROL_MOTOR_TEST
if (abs(speed) < 20) {
#endif
buzzerPattern = 0;
enable = 0;
for (int i = 0; i < 8; i++) {
@ -86,7 +104,9 @@ void poweroff() {
}
HAL_GPIO_WritePin(OFF_PORT, OFF_PIN, 0);
while(1) {}
#ifndef CONTROL_MOTOR_TEST
}
#endif
}
@ -118,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);
@ -148,9 +171,13 @@ int main(void) {
Nunchuck_Init();
#endif
#ifdef CONTROL_SERIAL_USART2
UART_Control_Init();
HAL_UART_Receive_DMA(&huart2, (uint8_t *)&command, 4);
#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
@ -211,13 +238,38 @@ int main(void) {
timeout = 0;
#endif
#ifdef CONTROL_SERIAL_USART2
cmd1 = CLAMP((int16_t)command.steer, -1000, 1000);
cmd2 = CLAMP((int16_t)command.speed, -1000, 1000);
#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;
else cmd2 -= 1;
if (abs(cmd2) > CONTROL_MOTOR_TEST_MAX_SPEED) motor_test_direction = -motor_test_direction;
timeout = 0;
#endif
// ####### LOW-PASS FILTER #######
steer = steer * (1.0 - FILTER) + cmd1 * FILTER;
@ -252,7 +304,7 @@ int main(void) {
lastSpeedR = speedR;
if (inactivity_timeout_counter % 25 == 0) {
if (main_loop_counter % 25 == 0) {
// ####### CALC BOARD TEMPERATURE #######
board_temp_adc_filtered = board_temp_adc_filtered * 0.99 + (float)adc_buffer.temp * 0.01;
board_temp_deg_c = ((float)TEMP_CAL_HIGH_DEG_C - (float)TEMP_CAL_LOW_DEG_C) / ((float)TEMP_CAL_HIGH_ADC - (float)TEMP_CAL_LOW_ADC) * (board_temp_adc_filtered - (float)TEMP_CAL_LOW_ADC) + (float)TEMP_CAL_LOW_DEG_C;
@ -310,6 +362,9 @@ int main(void) {
if (inactivity_timeout_counter > (INACTIVITY_TIMEOUT * 60 * 1000) / (DELAY_IN_MAIN_LOOP + 1)) { // rest of main loop needs maybe 1ms
poweroff();
}
main_loop_counter += 1;
timeout++;
}
}

View File

@ -44,183 +44,239 @@ 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);
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 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
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);
/* 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 */
}
}
#endif
/*
void UART_Init() {
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
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);
USART2->CR3 |= USART_CR3_DMAT; // | USART_CR3_DMAR | USART_CR3_OVRDIS;
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);
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;
}
*/
DMA_HandleTypeDef hdma_i2c2_rx;
DMA_HandleTypeDef hdma_i2c2_tx;

View File

@ -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. */

View File

@ -1,23 +1,23 @@
:020000040800F2
:1000000000C00020913D0008753D0008773D0008C4
:10001000793D00087B3D00087D3D000800000000A0
:100020000000000000000000000000007F3D00080C
:10003000813D000800000000833D0008853D000868
:10004000D93D0008D93D0008D93D0008D93D000838
:10005000D93D0008D93D0008D93D0008D93D000828
:10006000D93D0008D93D0008D93D0008A135000858
:10007000D93D0008D93D0008D93D0008D93D000808
:10008000D93D0008D93D0008D93D0008D93D0008F8
:10009000D93D0008D93D0008D93D0008D93D0008E8
:1000A000D93D0008D93D0008D93D0008D93D0008D8
:1000B000D93D0008D93D0008D93D0008D93D0008C8
:1000C000D93D0008D93D0008D93D0008D93D0008B8
:1000D000D93D0008D93D0008D93D0008D93D0008A8
:1000E000D93D0008D93D0008D93D0008D93D000898
:1000F000D93D0008D93D0008D93D0008D93D000888
:10010000D93D0008D93D0008D93D0008D93D000877
:10011000D93D0008D93D0008D93D0008D93D000867
:10012000D93D0008D93D0008D93D0008D93D000857
:1000000000C00020293D00080D3D00080F3D0008FC
:10001000113D0008133D0008153D000800000000D8
:10002000000000000000000000000000173D000874
:10003000193D0008000000001B3D00081D3D0008A0
:10004000713D0008713D0008713D0008713D0008D8
:10005000713D0008713D0008713D0008713D0008C8
:10006000713D0008713D0008713D000839350008F8
:10007000713D0008713D0008713D0008713D0008A8
:10008000713D0008713D0008713D0008713D000898
:10009000713D0008713D0008713D0008713D000888
:1000A000713D0008713D0008713D0008713D000878
:1000B000713D0008713D0008713D0008713D000868
:1000C000713D0008713D0008713D0008713D000858
:1000D000713D0008713D0008713D0008713D000848
:1000E000713D0008713D0008713D0008713D000838
:1000F000713D0008713D0008713D0008713D000828
:10010000713D0008713D0008713D0008713D000817
:10011000713D0008713D0008713D0008713D000807
:10012000713D0008713D0008713D0008713D0008F7
:1001300000000000000000000000000000000000BF
:1001400000000000000000000000000000000000AF
:10015000000000000000000000000000000000009F
@ -31,9 +31,9 @@
:1001D000000000000000000000000000000000001F
:0401E0005FF8E0F1F3
:1001E80010B5054C237833B9044B13B10448AFF369
:1001F80000800123237010BD88000020000000004B
:100208007046000808B5034B1BB103490348AFF318
:10021800008008BD000000008C0000207046000827
:1001F80000800123237010BD8C0000200000000047
:100208000846000808B5034B1BB103490348AFF380
:10021800008008BD0000000090000020084600088B
:10022800034613F8012B002AFBD1181A013870472E
:1002380081F0004102E000BF83F0004330B54FEA8F
:1002480041044FEA430594EA050F08BF90EA020FFC
@ -354,7 +354,7 @@
:1015F800624412F8100C13F4803F05D10C4B03FB26
:1016080000F007B010BC7047084B5B68C3F3404359
:10161800634413F8142C074BB3FBF2F300FB03F0FD
:10162800EFE70448EDE700BF8846000800100240D5
:10162800EFE70448EDE700BF20460008001002403D
:1016380000093D0000127A00594B1B6803F00703AC
:101648008B420CD2564A136823F007030B431360EE
:10165800136803F007038B4201D00120704770B56F
@ -378,12 +378,12 @@
:1017780023F46053296943EAC1035360FFF724FF48
:10178800084B5B68C3F30313074AD35CD840074B85
:101798001860002000F03EFD002070BD0120FCE72D
:1017A80000200240001002409C4600080000002073
:1017A80000200240001002403446000800000020DB
:1017B800014B1868704700BF0000002008B5FFF70C
:1017C800F7FF044B5B68C3F30223034AD35CD8409A
:1017D80008BD00BF00100240AC46000808B5FFF77E
:1017D80008BD00BF001002404446000808B5FFF7E6
:1017E800E7FF044B5B68C3F3C223034AD35CD840CA
:1017F80008BD00BF00100240AC46000830B4036AC0
:1017F80008BD00BF001002404446000830B4036A28
:1018080023F001030362056A4268846924F07304C3
:101818000B681C4325F002058B682B43104DA8422A
:1018280003D005F50065A84205D123F00803CD686B
@ -551,7 +551,7 @@
:1022480008B5074A136843F0100313600320FFF72B
:10225800CDFD0020FFF7DEFFFFF7DAFF002008BD05
:1022680000200240024A136801331360704700BF20
:10227800E0000020014B1868704700BFE000002014
:10227800E4000020014B1868704700BFE40000200C
:1022880030B583B00190FFF7F5FF0546019CB4F126
:10229800FF3F00D00134FFF7EDFF401BA042FAD307
:1022A80003B030BD7047000030B482B00023019302
@ -729,7 +729,7 @@
:102D68003046FEF785FF21463046FEF7ABFF0421CB
:102D78003046FEF7A7FF39463046FEF7A3FF2B681B
:102D880001221A633268136843F00103136019B013
:102D9800BDE8F08F00100240AC0100203C03002089
:102D9800BDE8F08F00100240B00100204003002081
:102DA800002C0140003401402DE9F04186B0424E2C
:102DB800B36943F40073B361B36903F40073009318
:102DC800009B3E4C3E4B23604FF48073A36000256C
@ -747,9 +747,9 @@
:102E8800019B114B1D60C3F80480104A9A60104AD8
:102E9800DA6040F6A2221A601A6842F001021A604B
:102EA8002A4629463846FEF7B3FF3846FEF7E4FFC0
:102EB80006B0BDE8F08100BF001002407402002097
:102EB80006B0BDE8F08100BF001002407802002093
:102EC8000024014000000140080002404C24014059
:102ED800E8020020F0B585B0284B9A6942F4806278
:102ED800EC020020F0B585B0284B9A6942F4806274
:102EE8009A619B6903F480630093009B244C254BF3
:102EF80023604FF48073A3600023E36063614FF4A1
:102F08006022E2616360052626612046FFF744FBE4
@ -760,394 +760,388 @@
:102F5800FFF7AAF9072303930197029601A92046D0
:102F6800FFF7A2F923689A6842F480729A609A6817
:102F780042F001029A6005B0F0BD00BF00100240A7
:102F880028010020002801400D4B1B681333262B15
:102F980014D810B500240B4B1C700B4B1C7005E0AB
:102FA8000A4B1C706420FFF76BF90134072CF7DD1E
:102FB800002220210648FFF796F8FEE7704700BF79
:102FC80094030020A8000020B4000020A4000020E2
:102FD8000008014030B597B002250C9501231093E5
:102FE800102311931395002414944FF46013159330
:102FF8000CA8FEF7FBF80F230793089509944FF4E4
:1030080080630A930B94294607A8FEF715FB0195E0
:103018004FF44043039301A8FFF770F8FEF7C8FB8D
:10302800084BA3FB00308009FEF732FF0420FEF7AF
:1030380045FF224621464FF0FF30FEF7E9FE17B064
:1030480030BD00BFD34D62102DE9F04F85B0FFF7BA
:10305800F7F8B34CA36943F00103A361A36903F034
:1030680001030393039B0320FEF7C0FE00221146D1
:103078006FF00B00FEF7CCFE002211466FF00A003D
:10308800FEF7C6FE002211466FF00900FEF7C0FEEB
:10309800002211466FF00400FEF7BAFE0022114626
:1030A8006FF00300FEF7B4FE002211466FF0010036
:1030B800FEF7AEFE002211464FF0FF30FEF7A8FEE5
:1030C800FFF788FF636923F001036361FFF772FC70
:1030D800FFF772FDFFF768FEFFF7FCFEFFF71EFC27
:1030E800012220218F48FEF7FEFF8F48FFF7B8F92D
:1030F8008E48FFF7B5F9082405E08D4B1C70642055
:10310800FFF7BEF8013C002CF7DA4FF0000A884BB5
:1031180083F800A0012204218648FEF7E4FF864BCD
:10312800188AFDF709FE0190844B01221A70D346D4
:103138004FE14FF47A7861E14FF47A7473E14FF418
:103148007A7642464B4620462946FDF777F80446EC
:103158000D4600227A4BFDF7B7FC80B96AA3D3E984
:10316800002320462946FDF791FC00285DD1204622
:103178002946FDF7B3FC074603E0724EE1E74FF43A
:103188007A77714B1A68714BA3FB0213DB0803EBC8
:10319800830303EB83039A4249D00AF13203BB420B
:1031A80014DDAAF1320ABA4510DA0BF13203B34240
:1031B8000CDDABF1320BB34508DA654B1B68042B09
:1031C80004D8644B1E607B42634A13600221554851
:1031D800FEF782FF38B1614B1B6823B9604B1B684F
:1031E800002B00F082805F4B1C685F492046FDF78A
:1031F80099FF28B15D4B1B681333262B40F2818061
:103208005B492046FDF78EFF002800F0BD80564937
:103218002046FDF7A5FF002800F0B680444B0522A4
:103228001A70544B06221A70BAE0464FA9E7019863
:10323800FDF762F936A3D3E90023FDF7B5F9044693
:103248000D46DFF8F480B8F81000FDF775FDFDF7BE
:1032580053F931A3D3E90023FDF7A6F902460B463B
:1032680020462946FCF7EAFFFDF760FC0546019079
:103278004149FDF7AFFC4149FDF7B6FD4049FDF76F
:10328800ABFC0446B8F80E10002000F029FDB8F891
:103298001210012000F024FD3146022000F020FD2C
:1032A8003946032000F01CFDB8F80C10042000F08B
:1032B80017FD34492B4B1868FDF796FDFDF75AFFAB
:1032C8000146052000F00CFD2846FDF753FF014696
:1032D800062000F005FD2046FDF74CFF01460720BB
:1032E80000F0FEFC00F002FD57E7144B00221A70B4
:1032F80002210C48FEF7F0FE0028F9D1FFF744FE42
:1033080071E7FFF741FE4BE00000000000408FC06E
:10331800AE47E17A14AEEF3F7B14AE47E17A843FC3
:10332800001002400008014074020020280100201B
:10333800A4000020000C0140E8020020B400002096
:1033480000408F4018FCFFFF7C0300201F85EB51D5
:1033580004000020C8000020C4000020D000002085
:10336800CC00002008000020CCCC064294030020AA
:1033780000000C42A800002000E0CE44083748BEF8
:1033880033330F420000C842734B1B6813F1320FEE
:1033980080F2CA80714B05221A70714B01221A7093
:1033A80087EAE773A3EBE773322B06DC86EAE6735A
:1033B800A3EBE673322B40F3BD806A4B00221A6000
:1033C800684B1A68684B9A4201D9FFF7DDFDB3468E
:1033D800BA460220FEF754FF644BDB899BB2B3F573
:1033E800805FBFF4A6AE614BDA89D889FDF7A8FCE7
:1033F8005F49FDF7ADFDFDF7BDFE80465D4BC3F8A7
:1034080000805A4B5B8A9BB2B3F5805FBFF494AEE1
:10341800564B5A8A588AFDF793FC5549FDF798FD93
:10342800FDF7A8FE0446544B1C60504AD3899BB252
:10343800B3F5FA6F94BF0023012350490B70538AE8
:103448009BB2B3F5FA6F94BF002301234C4A137063
:103458004C4B00221A604C4D2868FDF73BF838A306
:10346800D3E90023FDF7A0F806460F464046FDF7CE
:1034780031F835A3D3E90023FDF796F802460B4649
:1034880030463946FCF7DAFEFDF728FB0646286089
:10349800314D2868FDF71EF829A3D3E90023FDF76D
:1034A80083F8804689462046FDF714F826A3D3E919
:1034B8000023FDF779F802460B4640464946FCF7DB
:1034C800BDFEFDF70BFB2860FDF704F800222F4B2B
:1034D800FDF76AF804460D463046FCF7FBFF00226C
:1034E8002A4BFDF761F88046894602460B4620467E
:1034F8002946FCF7A1FE06460F460022244BFDF79D
:10350800E3FA00287FF41BAE11A3D3E90023304669
:103518003946FDF7BBFA00287FF42FAE304639460E
:10352800FDF7DCFA06460CE600230C4A13700C4A39
:10353800137035E70B4A13680133136040E700BF87
:10354800CDCCCCCCCCCCEC3F9A9999999999B93FF0
:103558000000000000408FC094030020A400002059
:10356800A80000207C03002000710200E80200206F
:103578003D0A83409C030020880300209803002014
:1035880084030020040000208C0300200000E03F9A
:1035980000408F4000000000774B02225A60774BB2
:1035A8001B68B3F57A7F5EDB2DE9F041744B1A682E
:1035B800744BA3FB02139B094FF47A7101FB13238D
:1035C8000BBB714C2068FCF797FF65A3D3E9002378
:1035D800FCF7EAFF06460F466C4B9889FDF7ACFBF3
:1035E8006B49FDF701FCFCF787FF5FA3D3E90023D4
:1035F800FCF7DAFF02460B4630463946FCF71EFE5A
:10360800FDF794FA2060614B5889624B1C68001BD7
:10361800FCF760FF56A3D3E90023FCF7C5FF00229F
:103628000023FDF733FA002852D1584B5889001B64
:10363800FCF750FF4EA3D3E90023FCF7B5FF0022A7
:10364800554BFDF741FA002852D1544B1B68052B06
:103658004ED8534B1B78002B4AD0524A536C43F434
:103668000043536449E00133444A1360474A908851
:103678004D490B68034403EBD3735B100B60D08890
:103688004A490B68034403EBD3735B100B60108843
:1036980047490B68034403EBD3735B100B605088F6
:1036A80044490B68034403EBD3735B100B605089E8
:1036B80038490B68034403EBD3735B100B60118923
:1036C8003D4A13680B4403EBD3735B1013607047D8
:1036D8002E4B5889001BFCF7FDFE25A3D3E90023D8
:1036E800FCF762FF0022354BFDF7D0F90028ACD07B
:1036F8002C4A536C23F400435364244B18892E4BF3
:103708001C68001BFCF7E6FE19A3D3E90023FCF7AD
:103718004BFF00220023FDF7B9F9002852D11B4BBB
:103728001889001BFCF7D6FE11A3D3E90023FCF788
:103738003BFF0022184BFDF7C7F9002852D1174B61
:103748001B68052B4ED8164B1B78002B4AD01C4AF9
:10375800536C43F40043536449E000BFAFF3008067
:10376800AE47E17A14AEEF3F7B14AE47E17A843F6F
:103778007B14AE47E17A943F00000240B800002075
:10378800AC000020D34D621008000020E8020020A1
:1037980017B9CE3C0C00002000002E400400002089
:1037A800B40000200034014014000020180000205C
:1037B8001C000020200000201000002000002EC067
:1037C800002C0140904B1889001BFCF783FE8CA34A
:1037D800D3E90023FCF7E8FE00228C4BFDF756F9ED
:1037E8000028ACD08A4A536C23F4004353648949B7
:1037F8008B6813F0200F0CBF012300238A6812F096
:10380800400F0CBF01220022896811F0800F0CBF05
:10381800012500258049886810F4806F0CBF0120BD
:1038280000208C6814F4006F0CBF01240024896800
:1038380011F4805F02EB450203EB4203774EF35C21
:1038480077490B600B6803F102030B600D68754B39
:1038580083FB0572A2EBE57202EB42024FEA4207D4
:10386800A5EB07020A600CBF02220022224400EBEB
:103878004202B05C6C4A1060106802301060106838
:1038880083FB0043A3EBE07303EB43035C00031BE0
:10389800136009685C488388644A12689A1AC38866
:1038A800634800681B1A052934D8DFE801F00323B0
:1038B80026292C2FD31A5F4A13605F4A13680133F5
:1038C80013605E4A14684CB35D4AA2FB0312120BE4
:1038D8005C4909680131B2FBF1F001FB1022EAB939
:1038E800B3FBF4F204FB1233EBB910215648FEF790
:1038F80000FC18E04F4B1A60DFE74E4B1A60DCE71C
:103908004C4A1360D9E74B4A1360D6E79B1A494AD9
:103918001360D2E7474B00221A60CEE7002210213D
:103928004948FEF7E0FB494BD3F800C03C4B1B6805
:10393800052B2BD8DFE803F00312171C2226CCF145
:10394800000064469C46424B1968374B1B68052BA0
:1039580052D8DFE803F01F3F43474B4E6446CCF193
:10396800000C0020EFE76046CCF1000C0024EAE7E9
:10397800CCF1000460464FF0000CE4E7CCF1000401
:103988000020E0E7CCF100000024DCE7002004463A
:103998008446D8E74E420F4619462C4B1B68002B2D
:1039A80040F398802B4B1D681D4B1B6805331D4A3F
:1039B80082FB03E2A2EBE37202EB42024FEA420E01
:1039C800A3EB0E02052A00F2B980DFE802F0456A8F
:1039D8006F74797E0F4649420026DEE70E4649425B
:1039E8000027DAE74F420E460021D6E74F4200266D
:1039F800D3E74E420027D0E7002637463146CCE7CA
:103A08007B14AE47E17A943FE802002000002EC004
:103A1800002C0140000C014000100140B446000891
:103A2800BC000020ABAAAA2AC00000201400002075
:103A380018000020B0000020AC000020A4000020E6
:103A48005917B7D1A800002000080140C400002081
:103A5800C8000020CC000020C5F10008AE4615467D
:103A6800654474444044964B1B68002B40F3D78050
:103A7800944B1B68944A126802F1050C934A82FB26
:103A88000CE2A2EBEC7202EB42024FEA420EACEB04
:103A98000E02052A00F2F980DFE802F058A8ADB25C
:103AA800B7BCAE466D424FF00008D9E7A8466D4254
:103AB8004FF0000ED4E7C5F1000EA8460025CFE769
:103AC800C5F1000E4FF00008CAE7C5F100084FF035
:103AD800000EC5E77E4B1D68C5F1000E7D4B1A68C8
:103AE80001327A4B83FB0283A3EBE27303EB4303BC
:103AF8004FEA4308A2EB0803052B1AD8DFE803F0C6
:103B08000323060A0E14A8461D46A9E7F0464FF0FF
:103B1800000EA5E7F046AE460025A1E72B46754600
:103B28009E464FF000089BE7A84675464FF0000EEA
:103B380096E74FF00008C646454691E74FF0000863
:103B4800C64645468CE74FF0000889E7C3F10008F0
:103B58009E461346194407EB0E0206EB080305F5CB
:103B68007A7540F2C676B54200F397800A2DB8BF41
:103B78000A25594E756304F57A7440F2C675AC424D
:103B880000F38E800A2CB8BF0A24534DAC6300F5AD
:103B98007A7040F2C674A04200F385800A28B8BF44
:103BA8000A204D4CE06301F57A7140F2C6708142FB
:103BB8007CDC0A29B8BF0A214848416302F57A72B9
:103BC80040F2C6718A4274DC0A2AB8BF0A22434905
:103BD8008A6303F57A7340F2C67293426CDC0A2B4F
:103BE800B8BF0A233D4AD363BDE8F0819E465B42D5
:103BF8004FF00008AEE798465B424FF0000EA9E789
:103C0800C3F1000E98460023A4E7C3F1000E4FF05D
:103C180000089FE7C3F100084FF0000E9AE7294B10
:103C28001B68C3F1000E284A12680132DFF89CC0F5
:103C38008CFB028CACEBE27C0CEB4C0C4FEA4C0896
:103C4800A2EB080CBCF1050F1AD8DFE80CF003232F
:103C5800060A0E14984663467CE7F0464FF0000EBD
:103C680078E7F0469E46002374E71A467346964660
:103C78004FF000086EE7984673464FF0000E69E76C
:103C88004FF00008C646434664E74FF00008C646B2
:103C980043465FE74FF000085CE740F2C67568E707
:103CA80040F2C67471E740F2C6707AE740F2C67116
:103CB80082E740F2C6728AE740F2C67392E700BF15
:103CC800C8000020D0000020C0000020ABAAAA2A0B
:103CD800CC000020BC00002000340140002C014032
:103CE800014B23F81010704704040020F0B587B08A
:103CF8001A4F64220021384600F090F818490A88C3
:103D0800B1F802C0888800B2CC8824B20D892DB2DF
:103D18004E8936B28B891BB2C98909B205910493C1
:103D280003960295019400900FFA8CF312B20D4994
:103D3800384600F07BF80C4B5B686BB90A4C23687B
:103D480023F0010323603846FCF76AFA6060E760F5
:103D5800236843F00103236007B0F0BDA0030020EF
:103D680004040020BC4600081C0002407047FEE71F
:103D7800FEE7FEE7FEE770477047704708B5FEF7B5
:103D880071FAFEF7ACF808BD002103E00B4B5B5855
:103D9800435004310A480B4B42189A42F6D30A4A58
:103DA80002E0002342F8043B084B9A42F9D3FEF79D
:103DB8008FFD00F00FF8FFF747F970472447000818
:103DC800000000208800002088000020180400203F
:103DD800FEE7000070B500250C4E0D4CA41BA41086
:103DE800A54209D100F040FC00250A4E0A4CA41B4C
:103DF800A410A54205D170BD56F825309847013565
:103E0800EEE756F8253098470135F2E71C470008D9
:103E18001C4700081C4700082047000803460244C6
:103E2800934200D1704703F8011BF9E70EB46FF015
:103E3800004100B59CB01DAB02900690079104911B
:103E48000848094953F8042B0591006802A9019311
:103E580000F066F80022029B1A701CB05DF804EBB3
:103E680003B07047240000200802FFFF2DE9F04747
:103E78008E6882469E420C469046994637D88A8973
:103E880012F4906F31D00223256809696F1A6569A9
:103E980005EB450595FBF3F509F101033B449D420C
:103EA80038BF1D46530530D5294600F035FB064678
:103EB80050B90C234FF0FF30CAF80030A38943F003
:103EC8004003A381BDE8F0873A46216900F0B4FABF
:103ED800A38923F4906343F08003A38126613E44C1
:103EE80026604E466561ED1BA5604E4500D94E46DD
:103EF80032464146206800F0AAFAA36800209B1BBE
:103F0800A36023681E442660DCE72A4600F05EFBB7
:103F180006460028E2D12169504600F0B1FAC8E708
:103F28002DE9F04F9DB003938B8980461D060C4602
:103F380016460FD50B696BB9402100F0EDFA2060E9
:103F4800206128B90C23C8F800304FF0FF30C7E0D3
:103F5800402363610023099320238DF829303023FF
:103F68004FF0010B8DF82A3037463D4615F8013BD6
:103F78000BB1252B3ED1B7EB060A0BD05346324680
:103F880021464046FFF772FF013000F0A480099BEC
:103F9800534409933B78002B00F09D8000234FF099
:103FA800FF32CDE90523049307938DF853301A9314
:103FB8002F46052217F8011B4F4800F02FFA049BE3
:103FC800D0B9D90644BF20228DF853201A0744BF20
:103FD8002B228DF853202A782A2A15D02F46002024
:103FE8000A25079A394611F8013B303B092B4DD970
:103FF800B8B10FE02F46B8E73F4A3D46801A0BFAA2
:1040080000F018430490D3E7039A111D1268039136
:10401800002A01DB079204E0524243F002030792B0
:1040280004933B782E2B0CD17B782A2B33D1039B1E
:1040380002371A1D1B680392002BB8BF4FF0FF33DD
:1040480005932E4D03223978284600F0E7F938B158
:104058004023401B03FA00F0049B013703430493F9
:104068003978062226487E1C8DF8281000F0D6F9EB
:10407800002838D0234B13BB039B073323F00703D7
:1040880008330393099B4B4409936DE705FB023200
:1040980001200F46A6E700230A2519460137059394
:1040A800384610F8012B303A092A03D9002BC8D01A
:1040B8000591C6E705FB012101230746F0E703AB9D
:1040C80000932246104B04A94046AFF30080B0F19C
:1040D800FF3F8146D6D1A3895B063FF536AF0998E5
:1040E8001DB0BDE8F08F03AB00932246064B04A930
:1040F800404600F081F8EAE7E8460008EE46000886
:10410800F246000800000000753E00082DE9F0475F
:1041180091461F468A680B6906469342B8BF134604
:10412800C9F8003091F843200C46DDF8208012B120
:104138000133C9F800302368990642BFD9F8003026
:104148000233C9F80030256815F0060507D104F1D7
:10415800190AE368D9F800209B1AAB4229DC94F8C5
:1041680043302268003318BF012392062ED404F18D
:10417800430239463046C047013021D02368E568FC
:1041880003F00603042B18BF0025D9F800204FF0D0
:10419800000908BFAD1AA368226908BF25EAE575BA
:1041A8009342C4BF9B1AED181A344D451AD100200A
:1041B80008E00123524639463046C047013003D152
:1041C8004FF0FF30BDE8F0870135C2E73020E11835
:1041D80081F843005A1C94F845102244023382F8AF
:1041E8004310C4E70123224639463046C047013010
:1041F800E6D009F10109D8E72DE9F04301F1430CB4
:104208000C46097E85B06E291746064698460C9AD4
:1042180000F0B38022D8632936D00AD8002900F0EC
:10422800B980582900F0838004F1420584F84210CF
:1042380032E0642901D06929F6D12068136805069F
:1042480003F104012AD51B681160002B03DA2D2223
:104258005B4284F843206F480A2239E0732900F052
:104268009D8008D86F2920D07029DDD1236843F0BC
:104278002003236003E0752917D07829D4D1782347
:10428800654884F8453055E0136804F14205191D66
:104298001B68116084F8423001238CE01B6810F021
:1042A800400F116018BF1BB2CFE713682568181DAF
:1042B8001060280601D51B6802E06806FBD51B883C
:1042C8006F2914BF0A2208225248002184F843109B
:1042D8006568002DA560C0F29580216821F0040171
:1042E8002160002B3DD1002D40F08E806546082AC4
:1042F8000BD12368DB0708D5236962689A42DEBFC1
:10430800302305F8013C05F1FF35ACEB05032361CB
:10431800CDF800803B4603AA21463046FFF7F6FE5B
:1043280001304DD14FF0FF3005B0BDE8F08339487A
:1043380084F84510136821681D1D1B6815600A065E
:104348000BD5CA0744BF41F0200121601BB9226880
:1043580022F0200222601022B7E74D0648BF9BB228
:10436800EFE76546B3FBF2F102FB1133C35C05F8D6
:10437800013D0B460029F5D1B9E713682568181DDA
:104388006169106028061B6801D5196002E06A0699
:10439800FBD51980002365462361B9E71368191D09
:1043A80011601D6862680021284600F037F808B1DE
:1043B800401B606063682361002384F84330A7E7EB
:1043C80023692A4639463046C0470130AAD02368B7
:1043D8009B0713D4E068039B9842B8BF1846A3E72D
:1043E80001234A4639463046C04701309AD0013544
:1043F800E368039A9B1AAB42F2DCEBE7002504F171
:104408001909F5E7002BACD1037804F1420584F8CB
:1044180042306CE7F94600080A47000810B5C9B2EF
:1044280002449042034601D1002303E01C78013086
:104438008C42F6D1184610BD10B5431E0A4491426D
:1044480000D110BD11F8014B03F8014FF7E788427E
:1044580010B501EB020307D8421E99420AD011F8A1
:10446800014B02F8014FF8E78342F5D98118D21AB7
:10447800D34200D110BD13F8014D01F8014DF7E703
:1044880038B50546002943D051F8043C0C1F002BD1
:10449800B8BFE41800F0D0F81E4A1368104633B9C4
:1044A800636014602846BDE8384000F0C6B8A342EF
:1044B8000BD921686218934201BF1A685B685218C9
:1044C800226063600460EDE713465A680AB1A242AD
:1044D800FAD919685818A0420BD120680144581815
:1044E80082421960DED110685268014419605A602E
:1044F800D8E702D90C232B60D4E7206821188A4218
:1045080001BF116852680918216062605C60C9E7E0
:1045180038BD00BFD400002070B5CD1C25F00305C0
:1045280008350C2D38BF0C25002D064601DBA942A5
:1045380003D90C233360002070BD00F07DF8214AB8
:104548001468214691B9204C23681BB9304600F005
:1045580063F820602946304600F05EF8431C24D1F9
:104568000C233046336000F068F8E4E70B685B1B07
:1045780018D40B2B0FD90B60CC18CD50304600F057
:104588005CF804F10B00231D20F00700C31AD3D0F8
:104598005A42E250D0E74B688C4216BF6360136002
:1045A8000C46EBE70C464968CCE7C41C24F003042E
:1045B800A04205D0211A304600F02EF80130CFD0A5
:1045C8002560DBE7D4000020D8000020F8B50746B6
:1045D80014460E4621B9BDE8F8401146FFF79CBFC6
:1045E80022B9FFF74DFF25462846F8BD00F026F80A
:1045F800A0420FD221463846FFF78EFF0546002815
:10460800F2D031462246FFF717FF31463846FFF70A
:1046180037FFE9E73546E7E738B50023054C054697
:104628000846236000F012F8431C02D1236803B146
:104638002B6038BD140400207047704751F8043CC3
:10464800181F002BBCBF0B58C0187047044A0549F7
:104658001368002B08BF0B461844106018467047B3
:10466800DC00002018040020F8B500BFF8BC08BC26
:104678009E467047F8B500BFF8BC08BC9E46704718
:1046880002030405060708090A0B0C0D0E0F10108B
:104698000102000000000000000000000102030405
:1046A80006070809000000000102030400000201D7
:1046B80004050300313A256920323A256920333A46
:1046C800256920343A256920353A256920363A2566
:1046D8006920373A256920383A25690D0A00000013
:1046E800232D302B2000686C4C00656667454647D3
:1046F8000030313233343536373839414243444556
:1047080046003031323334353637383961626364C4
:0447180065660000D2
:04471C000D02000882
:04472000E9010008A3
:1047240000A24A046400000000002042D0070000F8
:10473400D0070000D0070000D0070000D007000019
:10474400D007000028000020000000000000000046
:104754000000000000000000000000000000000055
:104764000000000000000000000000000000000045
:104774000000000000000000000000000000000035
:104784000000000000000000000000000000000025
:104794000000000000000000000000000000000015
:0847A40000000000000000000D
:0400000508003D9121
:102F88002C0100200028014010B50024094B1C70BA
:102F9800094B1C7005E0094B1C706420FFF770F9A1
:102FA8000134072CF7DD002220210548FFF79BF8A4
:102FB800FEE700BFAC000020B8000020A8000020F9
:102FC8000008014030B597B002250C9501231093F5
:102FD800102311931395002414944FF46013159340
:102FE8000CA8FEF703F90F230793089509944FF4EB
:102FF80080630A930B94294607A8FEF71DFB0195E9
:103008004FF44043039301A8FFF778F8FEF7D0FB8D
:10301800084BA3FB00308009FEF73AFF0420FEF7B7
:103028004DFF224621464FF0FF30FEF7F1FE17B064
:1030380030BD00BFD34D62102DE9F04F85B0FFF7CA
:10304800FFF8AB4CA36943F00103A361A36903F044
:1030580001030393039B0320FEF7C8FE00221146D9
:103068006FF00B00FEF7D4FE002211466FF00A0045
:10307800FEF7CEFE002211466FF00900FEF7C8FEEB
:10308800002211466FF00400FEF7C2FE002211462E
:103098006FF00300FEF7BCFE002211466FF001003E
:1030A800FEF7B6FE002211464FF0FF30FEF7B0FEE5
:1030B800FFF788FF636923F001036361FFF77AFC78
:1030C800FFF77AFDFFF770FEFFF704FFFFF726FC16
:1030D800012220218748FFF706F88748FFF7C0F943
:1030E8008648FFF7BDF9082405E0854B1C7064206D
:1030F800FFF7C6F8013C002CF7DA4FF0000A804BC6
:1031080083F800A0012204217E48FEF7ECFF7E4BE5
:10311800188AFDF711FE01907C4B01221A70D346E4
:1031280044E17B490A6801320A604BE14FF47A783E
:1031380032463B4620462946FDF780F804460D46B0
:103148000022744BFDF7C0FC88B963A3D3E90023C0
:1031580020462946FDF79AFC00285DD120462946DD
:10316800FDF7BCFC044604E0DFF8DC81E0E74FF43F
:103178007A740AF13203A34215DDAAF1320AA24594
:1031880011DA0BF1320343450DDDABF1320BC345C8
:1031980009DA614B1B68042B05D8604BC3F8008023
:1031A80063425F4A13605F4B1A685F4BA3FB0213CD
:1031B800DB0803EB830303EB83039A422ED002213F
:1031C8004C48FEF789FF30B1584B1B681BB9584B68
:1031D8001B68002B73D0574B1D6857492846FDF7CD
:1031E800A1FF20B1554B1B681333262B72D95449C4
:1031F8002846FDF797FF002800F0B0804E49284682
:10320800FDF7AEFF002800F0A9803D4B05221A709B
:103218004C4B06221A70ADE04B4CAAE70198FDF71B
:103228006BF92FA3D3E90023FDF7BEF906460F4635
:10323800354D288AFDF780FDFDF75EF92AA3D3E90D
:103248000023FDF7B1F902460B4630463946FCF734
:10325800F5FFFDF76BFC074601903C49FDF7BAFC0A
:103268003B49FDF7C1FD3B49FDF7B6FC0646414623
:10327800022000F001FD2146032000F0FDFCA98991
:10328800042000F0F9FC34492A4B1868FDF7ACFD1E
:10329800FDF770FF0146052000F0EEFC3846FDF70B
:1032A80069FF0146062000F0E7FC3046FDF762FFA3
:1032B8000146072000F0E0FC00F0E4FC7FE7134B38
:1032C80000221A7002210B48FEF706FF0028F9D1E8
:1032D800FFF75AFEFFF758FE0000000000408FC0BD
:1032E800AE47E17A14AEEF3F7B14AE47E17A843FF4
:1032F8000010024000080140780200202C01002044
:10330800A8000020000C0140EC020020B8000020BA
:103318009003002000408F4004000020CC000020D3
:10332800C8000020800300201F85EB51D400002036
:10333800D00000200C0000208FC221429C030020F6
:1033480000002842AC00002018FCFFFF00E0CE443B
:10335800083748BE33330F420000C842664B1B682B
:1033680013F1320F80F2AD80644B05221A70644B62
:1033780001221A7084EAE473A3EBE473322B06DCAF
:1033880088EAE873A3EBE873322B40F3A0805D4B27
:1033980000221A605B4B1A685B4B9A4200F29C80D1
:1033A8005A4A136801331360A246C3460520FEF744
:1033B80067FF574B1B68012B3FF4B3AE55490A68AA
:1033C800013A0A60534A176887EAE772A2EBE77284
:1033D800B2F5967F02DD5B424D4A13604E4B0022E8
:1033E8001A60DFF84481D8F80000FDF773F83CA3B1
:1033F800D3E90023FDF7D8F804460D46474B186873
:10340800FDF768F838A3D3E90023FDF7CDF80246A5
:103418000B4620462946FCF711FFFDF75FFB0646E1
:10342800C8F80000DFF8D080D8F80000FDF752F89F
:103438002BA3D3E90023FDF7B7F804460D46384619
:10344800FDF748F828A3D3E90023FDF7ADF80246B5
:103458000B4620462946FCF7F1FEFDF73FFBC8F86E
:103468000000FDF737F800222D4BFDF79DF80446C4
:103478000D463046FDF72EF80022294BFDF794F84B
:1034880006460F4602460B4620462946FCF7D4FE60
:10349800804689460022234BFDF716FB00287FF45F
:1034A80045AE13A3D3E9002340464946FDF7EEFA9B
:1034B80000287FF459AE40464946FDF70FFB804689
:1034C80036E600230D4A13700D4A137052E70D4A71
:1034D8001368013313605DE7FFF756FDAFF3008013
:1034E800666666666666EE3F9A9999999999A93FC4
:1034F8000000000000408FC09C030020A8000020AE
:10350800AC000020840300208038010080030020E4
:10351800080000209003002004000020A4030020DD
:103528000000E03F00408F409403002000000000AE
:10353800774B02225A60774B1B68B3F57A7F5EDBC4
:103548002DE9F041744B1A68744BA3FB02139B09D5
:103558004FF47A7101FB13230BBB714C2068FCF705
:10356800CBFF65A3D3E90023FDF71EF806460F46F7
:103578006C4B9889FDF7E0FB6B49FDF735FCFCF7D0
:10358800BBFF5FA3D3E90023FDF70EF802460B4605
:1035980030463946FCF752FEFDF7C8FA2060614B09
:1035A8005889624B1C68001BFCF794FF56A3D3E9AB
:1035B8000023FCF7F9FF00220023FDF767FA002833
:1035C80052D1584B5889001BFCF784FF4EA3D3E90E
:1035D8000023FCF7E9FF0022554BFDF775FA002898
:1035E80052D1544B1B68052B4ED8534B1B78002BDC
:1035F8004AD0524A536C43F40043536449E00133C0
:10360800444A1360474A90884D490B68034403EBCA
:10361800D3735B100B60D0884A490B68034403EBF3
:10362800D3735B100B60108847490B68034403EBA6
:10363800D3735B100B60508844490B68034403EB59
:10364800D3735B100B60508938490B68034403EB54
:10365800D3735B100B6011893D4A13680B4403EB6D
:10366800D3735B10136070472E4B5889001BFCF70F
:1036780031FF25A3D3E90023FCF796FF0022354B41
:10368800FDF704FA0028ACD02C4A536C23F400430D
:103698005364244B18892E4B1C68001BFCF71AFF37
:1036A80019A3D3E90023FCF77FFF00220023FDF7CD
:1036B800EDF9002852D11B4B1889001BFCF70AFFB3
:1036C80011A3D3E90023FCF76FFF0022184BFDF785
:1036D800FBF9002852D1174B1B68052B4ED8164B07
:1036E8001B78002B4AD01C4A536C43F400435364A4
:1036F80049E000BFAFF30080AE47E17A14AEEF3F78
:103708007B14AE47E17A843F7B14AE47E17A943F5D
:1037180000000240BC000020B0000020D34D621021
:103728000C000020EC02002017B9CE3C100000204D
:1037380000002E4004000020B800002000340140A2
:10374800180000201C000020200000202400002079
:103758001400002000002EC0002C0140904B188956
:10376800001BFCF7B7FE8CA3D3E90023FCF71CFF72
:1037780000228C4BFDF78AF90028ACD08A4A536C9A
:1037880023F40043536489498B6813F0200F0CBF5E
:10379800012300238A6812F0400F0CBF0122002287
:1037A800896811F0800F0CBF0125002580498868C1
:1037B80010F4806F0CBF012000208C6814F4006F97
:1037C8000CBF01240024896811F4805F02EB4502D4
:1037D80003EB4203774EF35C77490B600B6803F108
:1037E80002030B600D68754B83FB0572A2EBE57253
:1037F80002EB42024FEA4207A5EB07020A600CBF40
:1038080002220022224400EB4202B05C6C4A1060A3
:10381800106802301060106883FB0043A3EBE0736C
:1038280003EB43035C00031B136009685C4883884F
:10383800644A12689A1AC388634800681B1A0529E3
:1038480034D8DFE801F0032326292C2FD31A5F4A46
:1038580013605F4A1368013313605E4A14684CB3FF
:103868005D4AA2FB0312120B5C4909680131B2FBE5
:10387800F1F001FB1022EAB9B3FBF4F204FB1233B6
:10388800EBB910215648FEF734FC18E04F4B1A608C
:10389800DFE74E4B1A60DCE74C4A1360D9E74B4A26
:1038A8001360D6E79B1A494A1360D2E7474B0022B8
:1038B8001A60CEE7002210214948FEF714FC494B54
:1038C800D3F800C03C4B1B68052B2BD8DFE803F06E
:1038D8000312171C2226CCF1000064469C46424B7A
:1038E8001968374B1B68052B52D8DFE803F01F3FD8
:1038F80043474B4E6446CCF1000C0020EFE760468E
:10390800CCF1000C0024EAE7CCF1000460464FF04B
:10391800000CE4E7CCF100040020E0E7CCF1000063
:103928000024DCE7002004468446D8E74E420F46D0
:1039380019462C4B1B68002B40F398802B4B1D68B5
:103948001D4B1B6805331D4A82FB03E2A2EBE372A1
:1039580002EB42024FEA420EA3EB0E02052A00F2E6
:10396800B980DFE802F0456A6F74797E0F464942F4
:103978000026DEE70E4649420027DAE74F420E46A8
:103988000021D6E74F420026D3E74E420027D0E772
:10399800002637463146CCE77B14AE47E17A943FA0
:1039A800EC02002000002EC0002C0140000C014059
:1039B800001001404C460008C0000020ABAAAA2A0B
:1039C800C4000020180000201C000020B4000020C3
:1039D800B0000020A80000205917B7D1AC00002083
:1039E80000080140C8000020CC000020D0000020C2
:1039F800C5F10008AE461546654474444044964BEC
:103A08001B68002B40F3D780944B1B68944A1268BC
:103A180002F1050C934A82FB0CE2A2EBEC7202EB7A
:103A280042024FEA420EACEB0E02052A00F2F98080
:103A3800DFE802F058A8ADB2B7BCAE466D424FF011
:103A48000008D9E7A8466D424FF0000ED4E7C5F14B
:103A5800000EA8460025CFE7C5F1000E4FF000087C
:103A6800CAE7C5F100084FF0000EC5E77E4B1D6898
:103A7800C5F1000E7D4B1A6801327A4B83FB028335
:103A8800A3EBE27303EB43034FEA4308A2EB0803FB
:103A9800052B1AD8DFE803F00323060A0E14A846FC
:103AA8001D46A9E7F0464FF0000EA5E7F046AE46E2
:103AB8000025A1E72B4675469E464FF000089BE778
:103AC800A84675464FF0000E96E74FF00008C64628
:103AD800454691E74FF00008C64645468CE74FF04B
:103AE800000889E7C3F100089E461346194407EB0E
:103AF8000E0206EB080305F57A7540F2C676B54264
:103B080000F397800A2DB8BF0A25594E756304F54E
:103B18007A7440F2C675AC4200F38E800A2CB8BFA6
:103B28000A24534DAC6300F57A7040F2C674A04283
:103B380000F385800A28B8BF0A204D4CE06301F5E0
:103B48007A7140F2C67081427CDC0A29B8BF0A212A
:103B58004848416302F57A7240F2C6718A4274DCC1
:103B68000A2AB8BF0A2243498A6303F57A7340F2E6
:103B7800C67293426CDC0A2BB8BF0A233D4AD36352
:103B8800BDE8F0819E465B424FF00008AEE79846DC
:103B98005B424FF0000EA9E7C3F1000E98460023E0
:103BA800A4E7C3F1000E4FF000089FE7C3F1000837
:103BB8004FF0000E9AE7294B1B68C3F1000E284A04
:103BC80012680132DFF89CC08CFB028CACEBE27C03
:103BD8000CEB4C0C4FEA4C08A2EB080CBCF1050F9F
:103BE8001AD8DFE80CF00323060A0E149846634639
:103BF8007CE7F0464FF0000E78E7F0469E4600233B
:103C080074E71A46734696464FF000086EE79846E2
:103C180073464FF0000E69E74FF00008C64643466A
:103C280064E74FF00008C64643465FE74FF00008D8
:103C38005CE740F2C67568E740F2C67471E740F287
:103C4800C6707AE740F2C67182E740F2C6728AE728
:103C580040F2C67392E700BFCC000020D4000020D9
:103C6800C4000020ABAAAA2AD0000020C00000206F
:103C780000340140002C0140014B23F8101070471C
:103C88000C040020F0B587B01A4F64220021384692
:103C980000F090F818490A88B1F802C0888800B284
:103CA800CC8824B20D892DB24E8936B28B891BB2CD
:103CB800C98909B20591049303960295019400906D
:103CC8000FFA8CF312B20D49384600F07BF80C4B12
:103CD8005B686BB90A4C236823F0010323603846FC
:103CE800FCF79EFA6060E760236843F001032360F5
:103CF80007B0F0BDA80300200C04002054460008BB
:103D08001C0002407047FEE7FEE7FEE7FEE770474B
:103D18007047704708B5FEF7A5FAFEF7E0F808BD4A
:103D2800002103E00B4B5B58435004310A480B4B0E
:103D380042189A42F6D30A4A02E0002342F8043BAA
:103D4800084B9A42F9D3FEF7C3FD00F00FF8FFF7CE
:103D580073F97047BC460008000000208C00002062
:103D68008C00002020040020FEE7000070B500252C
:103D78000C4E0D4CA41BA410A54209D100F040FC28
:103D880000250A4E0A4CA41BA410A54205D170BDFB
:103D980056F8253098470135EEE756F8253098470C
:103DA8000135F2E7B4460008B4460008B4460008F6
:103DB800B846000803460244934200D1704703F80E
:103DC800011BF9E70EB46FF0004100B59CB01DABC4
:103DD80002900690079104910848094953F8042B6A
:103DE8000591006802A9019300F066F80022029B81
:103DF8001A701CB05DF804EB03B07047280000206F
:103E08000802FFFF2DE9F0478E6882469E420C4665
:103E18009046994637D88A8912F4906F31D0022398
:103E2800256809696F1A656905EB450595FBF3F582
:103E380009F101033B449D4238BF1D46530530D567
:103E4800294600F035FB064650B90C234FF0FF30E9
:103E5800CAF80030A38943F04003A381BDE8F08786
:103E68003A46216900F0B4FAA38923F4906343F039
:103E78008003A38126613E4426604E466561ED1BA2
:103E8800A5604E4500D94E4632464146206800F0AE
:103E9800AAFAA36800209B1BA36023681E4426601F
:103EA800DCE72A4600F05EFB06460028E2D12169DD
:103EB800504600F0B1FAC8E72DE9F04F9DB00393E2
:103EC8008B8980461D060C4616460FD50B696BB9C3
:103ED800402100F0EDFA2060206128B90C23C8F8D1
:103EE80000304FF0FF30C7E040236361002309939F
:103EF80020238DF8293030234FF0010B8DF82A301C
:103F080037463D4615F8013B0BB1252B3ED1B7EBA3
:103F1800060A0BD05346324621464046FFF772FF49
:103F2800013000F0A480099B534409933B78002B8F
:103F380000F09D8000234FF0FF32CDE90523049364
:103F480007938DF853301A932F46052217F8011B53
:103F58004F4800F02FFA049BD0B9D90644BF20225D
:103F68008DF853201A0744BF2B228DF853202A7846
:103F78002A2A15D02F4600200A25079A394611F813
:103F8800013B303B092B4DD9B8B10FE02F46B8E7BC
:103F98003F4A3D46801A0BFA00F018430490D3E7D5
:103FA800039A111D12680391002A01DB079204E0AD
:103FB800524243F00203079204933B782E2B0CD114
:103FC8007B782A2B33D1039B02371A1D1B68039277
:103FD800002BB8BF4FF0FF3305932E4D03223978DD
:103FE800284600F0E7F938B14023401B03FA00F0F7
:103FF800049B0137034304933978062226487E1C24
:104008008DF8281000F0D6F9002838D0234B13BBC0
:10401800039B073323F0070308330393099B4B449F
:1040280009936DE705FB023201200F46A6E700233E
:104038000A25194601370593384610F8012B303AFE
:10404800092A03D9002BC8D00591C6E705FB012131
:1040580001230746F0E703AB00932246104B04A95F
:104068004046AFF30080B0F1FF3F8146D6D1A38927
:104078005B063FF536AF09981DB0BDE8F08F03AB7E
:1040880000932246064B04A9404600F081F8EAE76F
:1040980080460008864600088A460008000000009E
:1040A8000D3E00082DE9F04791461F468A680B69C6
:1040B80006469342B8BF1346C9F8003091F843202A
:1040C8000C46DDF8208012B10133C9F800302368AE
:1040D800990642BFD9F800300233C9F80030256884
:1040E80015F0060507D104F1190AE368D9F800208C
:1040F8009B1AAB4229DC94F843302268003318BF7E
:10410800012392062ED404F1430239463046C047B3
:10411800013021D02368E56803F00603042B18BF9B
:104128000025D9F800204FF0000908BFAD1AA36890
:10413800226908BF25EAE5759342C4BF9B1AED18AA
:104148001A344D451AD1002008E001235246394659
:104158003046C047013003D14FF0FF30BDE8F0874B
:104168000135C2E73020E11881F843005A1C94F861
:1041780045102244023382F84310C4E70123224643
:1041880039463046C0470130E6D009F10109D8E781
:104198002DE9F04301F1430C0C46097E85B06E29E8
:1041A8001746064698460C9A00F0B38022D8632931
:1041B80036D00AD8002900F0B980582900F0838049
:1041C80004F1420584F8421032E0642901D06929DB
:1041D800F6D120681368050603F104012AD51B6887
:1041E8001160002B03DA2D225B4284F843206F48CC
:1041F8000A2239E0732900F09D8008D86F2920D061
:104208007029DDD1236843F02003236003E075297A
:1042180017D07829D4D17823654884F8453055E0FB
:10422800136804F14205191D1B68116084F84230B7
:1042380001238CE01B6810F0400F116018BF1BB2FF
:10424800CFE713682568181D1060280601D51B687C
:1042580002E06806FBD51B886F2914BF0A220822D2
:104268005248002184F843106568002DA560C0F20B
:104278009580216821F004012160002B3DD1002D9B
:1042880040F08E806546082A0BD12368DB0708D5E5
:10429800236962689A42DEBF302305F8013C05F1C4
:1042A800FF35ACEB05032361CDF800803B4603AA3C
:1042B80021463046FFF7F6FE01304DD14FF0FF3072
:1042C80005B0BDE8F083394884F8451013682168C3
:1042D8001D1D1B6815600A060BD5CA0744BF41F0AF
:1042E800200121601BB9226822F0200222601022DE
:1042F800B7E74D0648BF9BB2EFE76546B3FBF2F15F
:1043080002FB1133C35C05F8013D0B460029F5D1CA
:10431800B9E713682568181D6169106028061B68CD
:1043280001D5196002E06A06FBD5198000236546AD
:104338002361B9E71368191D11601D6862680021BF
:10434800284600F037F808B1401B606063682361B5
:10435800002384F84330A7E723692A4639463046C4
:10436800C0470130AAD023689B0713D4E068039B99
:104378009842B8BF1846A3E701234A463946304653
:10438800C04701309AD00135E368039A9B1AAB42C3
:10439800F2DCEBE7002504F11909F5E7002BACD1B5
:1043A800037804F1420584F842306CE7914600082E
:1043B800A246000810B5C9B202449042034601D192
:1043C800002303E01C7801308C42F6D1184610BD5A
:1043D80010B5431E0A44914200D110BD11F8014B9B
:1043E80003F8014FF7E7884210B501EB020307D83D
:1043F800421E99420AD011F8014B02F8014FF8E722
:104408008342F5D98118D21AD34200D110BD13F8CE
:10441800014D01F8014DF7E738B50546002943D0AD
:1044280051F8043C0C1F002BB8BFE41800F0D0F87A
:104438001E4A1368104633B9636014602846BDE805
:10444800384000F0C6B8A3420BD9216862189342DD
:1044580001BF1A685B685218226063600460EDE768
:1044680013465A680AB1A242FAD919685818A042E4
:104478000BD120680144581882421960DED11068B7
:104488005268014419605A60D8E702D90C232B609E
:10449800D4E7206821188A4201BF116852680918B8
:1044A800216062605C60C9E738BD00BFD8000020A9
:1044B80070B5CD1C25F0030508350C2D38BF0C252B
:1044C800002D064601DBA94203D90C2333600020E6
:1044D80070BD00F07DF8214A1468214691B9204C3E
:1044E80023681BB9304600F063F82060294630463F
:1044F80000F05EF8431C24D10C233046336000F0F2
:1045080068F8E4E70B685B1B18D40B2B0FD90B601A
:10451800CC18CD50304600F05CF804F10B00231D98
:1045280020F00700C31AD3D05A42E250D0E74B68B4
:104538008C4216BF636013600C46EBE70C46496873
:10454800CCE7C41C24F00304A04205D0211A30464D
:1045580000F02EF80130CFD02560DBE7D80000202E
:10456800DC000020F8B5074614460E4621B9BDE820
:10457800F8401146FFF79CBF22B9FFF74DFF2546CB
:104588002846F8BD00F026F8A0420FD2214638464A
:10459800FFF78EFF05460028F2D031462246FFF786
:1045A80017FF31463846FFF737FFE9E73546E7E7B3
:1045B80038B50023054C05460846236000F012F87C
:1045C800431C02D1236803B12B6038BD1C040020B2
:1045D8007047704751F8043C181F002BBCBF0B589C
:1045E800C0187047044A05491368002B08BF0B46DA
:1045F8001844106018467047E0000020200400208E
:10460800F8B500BFF8BC08BC9E467047F8B500BFB7
:08461800F8BC08BC9E46704787
:1046200002030405060708090A0B0C0D0E0F1010F3
:10463000010200000000000000000000010203046D
:10464000060708090000000001020304000002013F
:1046500004050300313A256920323A256920333AAE
:10466000256920343A256920353A256920363A25CE
:104670006920373A256920383A25690D0A0000007B
:10468000232D302B2000686C4C006566674546473B
:1046900000303132333435363738394142434445BE
:1046A000460030313233343536373839616263642D
:0446B000656600003B
:0446B4000D020008EB
:0446B800E90100080C
:1046BC0000A24A0464000000010000000000404217
:1046CC00D0070000D0070000D0070000D007000082
:1046DC00D0070000D00700002C00002000000000D4
:1046EC0000000000000000000000000000000000BE
:1046FC0000000000000000000000000000000000AE
:10470C00000000000000000000000000000000009D
:10471C00000000000000000000000000000000008D
:10472C00000000000000000000000000000000007D
:0C473C0000000000000000000000000071
:0400000508003D2989
:00000001FF

31
platformio.ini Normal file
View 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
;================================================================