UART with sideboards works + major refactoring

► the mainboard can now send and receive Serial data from the sideboards
► heavy refactored the `main.c`. It was becoming too large to manage... Therefore, `util.c` and `util.h` was created
► added new functionality for `VARIANT_HOVERCAR` and variants with `CONTROL_ADC` in general:
- ADC limits auto-calibration mode (long press of the power button) - calibration will not be lost at power-off
- Max Current and Max Speed adjustment mode (long press followed by a short press of the power button) - calibration will not be lost at power-off
- added one sideboard functionality:
         - LEDs are used to display battery level,  Motor Enable, Errors, Reverse driving, Braking.
         - Photo sensors are used as push buttons: One for changing Control Mode, One for Activating/Deactivating the Field Weakening on the fly
This commit is contained in:
EmanuelFeru 2020-03-01 10:00:26 +01:00
parent 52e920c5ee
commit 72e6b30033
23 changed files with 1722 additions and 1223 deletions

View File

@ -1,181 +0,0 @@
/*
* File: filtLowPass.c
*
* Code generated for Simulink model 'filtLowPass'.
*
* Model version : 1.1167
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Sun Oct 6 22:11:53 2019
*
* Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex
* Emulation hardware selection:
* Differs from embedded hardware (MATLAB Host)
* Code generation objectives:
* 1. Execution efficiency
* 2. RAM efficiency
* Validation result: Not run
*/
#include "filtLowPass.h"
#ifndef UCHAR_MAX
#include <limits.h>
#endif
#if ( UCHAR_MAX != (0xFFU) ) || ( SCHAR_MAX != (0x7F) )
#error Code was generated for compiler with different sized uchar/char. \
Consider adjusting Test hardware word size settings on the \
Hardware Implementation pane to match your compiler word sizes as \
defined in limits.h of the compiler. Alternatively, you can \
select the Test hardware is the same as production hardware option and \
select the Enable portable word sizes option on the Code Generation > \
Verification pane for ERT based targets, which will disable the \
preprocessor word size checks.
#endif
#if ( USHRT_MAX != (0xFFFFU) ) || ( SHRT_MAX != (0x7FFF) )
#error Code was generated for compiler with different sized ushort/short. \
Consider adjusting Test hardware word size settings on the \
Hardware Implementation pane to match your compiler word sizes as \
defined in limits.h of the compiler. Alternatively, you can \
select the Test hardware is the same as production hardware option and \
select the Enable portable word sizes option on the Code Generation > \
Verification pane for ERT based targets, which will disable the \
preprocessor word size checks.
#endif
#if ( UINT_MAX != (0xFFFFFFFFU) ) || ( INT_MAX != (0x7FFFFFFF) )
#error Code was generated for compiler with different sized uint/int. \
Consider adjusting Test hardware word size settings on the \
Hardware Implementation pane to match your compiler word sizes as \
defined in limits.h of the compiler. Alternatively, you can \
select the Test hardware is the same as production hardware option and \
select the Enable portable word sizes option on the Code Generation > \
Verification pane for ERT based targets, which will disable the \
preprocessor word size checks.
#endif
#if ( ULONG_MAX != (0xFFFFFFFFU) ) || ( LONG_MAX != (0x7FFFFFFF) )
#error Code was generated for compiler with different sized ulong/long. \
Consider adjusting Test hardware word size settings on the \
Hardware Implementation pane to match your compiler word sizes as \
defined in limits.h of the compiler. Alternatively, you can \
select the Test hardware is the same as production hardware option and \
select the Enable portable word sizes option on the Code Generation > \
Verification pane for ERT based targets, which will disable the \
preprocessor word size checks.
#endif
#if 0
/* Skip this size verification because of preprocessor limitation */
#if ( ULLONG_MAX != (0xFFFFFFFFFFFFFFFFULL) ) || ( LLONG_MAX != (0x7FFFFFFFFFFFFFFFLL) )
#error Code was generated for compiler with different sized ulong_long/long_long. \
Consider adjusting Test hardware word size settings on the \
Hardware Implementation pane to match your compiler word sizes as \
defined in limits.h of the compiler. Alternatively, you can \
select the Test hardware is the same as production hardware option and \
select the Enable portable word sizes option on the Code Generation > \
Verification pane for ERT based targets, which will disable the \
preprocessor word size checks.
#endif
#endif
extern int16_T filtLowPass_l(int16_T rtu_u, uint16_T rtu_coef, DW_filtLowPass
*localDW);
/*===========*
* Constants *
*===========*/
#define RT_PI 3.14159265358979323846
#define RT_PIF 3.1415927F
#define RT_LN_10 2.30258509299404568402
#define RT_LN_10F 2.3025851F
#define RT_LOG10E 0.43429448190325182765
#define RT_LOG10EF 0.43429449F
#define RT_E 2.7182818284590452354
#define RT_EF 2.7182817F
/*
* UNUSED_PARAMETER(x)
* Used to specify that a function parameter (argument) is required but not
* accessed by the function body.
*/
#ifndef UNUSED_PARAMETER
# if defined(__LCC__)
# define UNUSED_PARAMETER(x) /* do nothing */
# else
/*
* This is the semi-ANSI standard way of indicating that an
* unused function parameter is required.
*/
# define UNUSED_PARAMETER(x) (void) (x)
# endif
#endif
/* Output and update for atomic system: '<Root>/filtLowPass' */
int16_T filtLowPass_l(int16_T rtu_u, uint16_T rtu_coef, DW_filtLowPass *localDW)
{
int32_T tmp;
int16_T rty_y_0;
/* Outputs for Atomic SubSystem: '<S1>/Low_Pass_Filter1' */
/* Sum: '<S2>/Sum1' incorporates:
* DataTypeConversion: '<S1>/Data Type Conversion'
* Product: '<S2>/Divide1'
* Product: '<S2>/Divide2'
* Sum: '<S2>/Sum5'
* UnitDelay: '<S2>/UnitDelay3'
*/
tmp = (((int16_T)(rtu_u << 4) * rtu_coef) >> 16) + (((int32_T)(65535U -
rtu_coef) * localDW->UnitDelay3_DSTATE) >> 16);
if (tmp > 32767) {
tmp = 32767;
} else {
if (tmp < -32768) {
tmp = -32768;
}
}
rty_y_0 = (int16_T)tmp;
/* Update for UnitDelay: '<S2>/UnitDelay3' incorporates:
* Sum: '<S2>/Sum1'
*/
localDW->UnitDelay3_DSTATE = (int16_T)tmp;
/* End of Outputs for SubSystem: '<S1>/Low_Pass_Filter1' */
return rty_y_0;
}
/* Model step function */
void filtLowPass_step(RT_MODEL *const rtM)
{
DW *rtDW = ((DW *) rtM->dwork);
ExtU *rtU = (ExtU *) rtM->inputs;
ExtY *rtY = (ExtY *) rtM->outputs;
/* Outputs for Atomic SubSystem: '<Root>/filtLowPass' */
/* Outport: '<Root>/y' incorporates:
* Inport: '<Root>/coef'
* Inport: '<Root>/u'
*/
rtY->y = (int16_T) filtLowPass_l(rtU->u, rtU->coef, &rtDW->filtLowPass_l2);
/* End of Outputs for SubSystem: '<Root>/filtLowPass' */
}
/* Model initialize function */
void filtLowPass_initialize(RT_MODEL *const rtM)
{
/* (no initialization code required) */
UNUSED_PARAMETER(rtM);
}
/*
* File trailer for generated code.
*
* [EOF]
*/

View File

@ -1,91 +0,0 @@
/*
* File: filtLowPass.h
*
* Code generated for Simulink model 'filtLowPass'.
*
* Model version : 1.1167
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Sun Oct 6 22:11:53 2019
*
* Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex
* Emulation hardware selection:
* Differs from embedded hardware (MATLAB Host)
* Code generation objectives:
* 1. Execution efficiency
* 2. RAM efficiency
* Validation result: Not run
*/
#ifndef RTW_HEADER_filtLowPass_h_
#define RTW_HEADER_filtLowPass_h_
#ifndef filtLowPass_COMMON_INCLUDES_
# define filtLowPass_COMMON_INCLUDES_
#include "rtwtypes.h"
#endif /* filtLowPass_COMMON_INCLUDES_ */
/* Macros for accessing real-time model data structure */
/* Forward declaration for rtModel */
typedef struct tag_RTM RT_MODEL;
/* Block signals and states (auto storage) for system '<Root>/filtLowPass' */
typedef struct {
int16_T UnitDelay3_DSTATE; /* '<S2>/UnitDelay3' */
} DW_filtLowPass;
/* Block signals and states (auto storage) for system '<Root>' */
typedef struct {
DW_filtLowPass filtLowPass_l2; /* '<Root>/filtLowPass' */
} DW;
/* External inputs (root inport signals with auto storage) */
typedef struct {
int16_T u; /* '<Root>/u' */
uint16_T coef; /* '<Root>/coef' */
} ExtU;
/* External outputs (root outports fed by signals with auto storage) */
typedef struct {
int16_T y; /* '<Root>/y' */
} ExtY;
/* Real-time Model Data Structure */
struct tag_RTM {
ExtU *inputs;
ExtY *outputs;
DW *dwork;
};
/* Model entry point functions */
extern void filtLowPass_initialize(RT_MODEL *const rtM);
extern void filtLowPass_step(RT_MODEL *const rtM);
/*-
* The generated code includes comments that allow you to trace directly
* back to the appropriate location in the model. The basic format
* is <system>/block_name, where system is the system number (uniquely
* assigned by Simulink) and block_name is the name of the block.
*
* Note that this particular code originates from a subsystem build,
* and has its own system numbers different from the parent model.
* Refer to the system hierarchy for this subsystem below, and use the
* MATLAB hilite_system command to trace the generated code back
* to the parent model. For example,
*
* hilite_system('BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass') - opens subsystem BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass
* hilite_system('BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass/Kp') - opens and selects block Kp
*
* Here is the system hierarchy for this model
*
* '<Root>' : 'BLDCmotorControl_FOC_R2017b_fixdt'
* '<S1>' : 'BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass'
* '<S2>' : 'BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass/Low_Pass_Filter1'
*/
#endif /* RTW_HEADER_filtLowPass_h_ */
/*
* File trailer for generated code.
*
* [EOF]
*/

View File

@ -3,9 +3,9 @@
* *
* Code generated for Simulink model 'filtLowPass'. * Code generated for Simulink model 'filtLowPass'.
* *
* Model version : 1.1165 * Model version : 1.1257
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017 * Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Sun Oct 6 22:00:52 2019 * C/C++ source code generated on : Mon Feb 24 20:31:06 2020
* *
* Target selection: ert.tlc * Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex * Embedded hardware selection: ARM Compatible->ARM Cortex
@ -81,7 +81,7 @@ preprocessor word size checks.
#endif #endif
#endif #endif
extern int32_T filtLowPass_l(int16_T rtu_u, uint16_T rtu_coef, DW_filtLowPass extern int32_T filtLowPass_l(int32_T rtu_u, uint16_T rtu_coef, DW_filtLowPass
*localDW); *localDW);
/*===========* /*===========*
@ -115,37 +115,35 @@ extern int32_T filtLowPass_l(int16_T rtu_u, uint16_T rtu_coef, DW_filtLowPass
#endif #endif
/* Output and update for atomic system: '<Root>/filtLowPass' */ /* Output and update for atomic system: '<Root>/filtLowPass' */
int32_T filtLowPass_l(int16_T rtu_u, uint16_T rtu_coef, DW_filtLowPass *localDW) int32_T filtLowPass_l(int32_T rtu_u, uint16_T rtu_coef, DW_filtLowPass *localDW)
{ {
int32_T q0; int32_T rtb_UnitDelay1;
int32_T q1; int64_T tmp;
int32_T rty_y_0; int32_T rty_y_0;
/* Outputs for Atomic SubSystem: '<S1>/Low_Pass_Filter1' */ /* UnitDelay: '<S2>/UnitDelay1' */
/* Sum: '<S2>/Sum1' incorporates: rtb_UnitDelay1 = localDW->UnitDelay1_DSTATE;
/* Product: '<S2>/Divide3' incorporates:
* DataTypeConversion: '<S1>/Data Type Conversion' * DataTypeConversion: '<S1>/Data Type Conversion'
* Product: '<S2>/Divide1' * Sum: '<S2>/Sum2'
* Product: '<S2>/Divide2'
* Sum: '<S2>/Sum5'
* UnitDelay: '<S2>/UnitDelay3'
*/ */
q0 = (int32_T)(((int64_T)(rtu_u << 16) * rtu_coef) >> 16); tmp = ((int64_T)((rtu_u << 4) - (rtb_UnitDelay1 >> 12)) * rtu_coef) >> 4;
q1 = (int32_T)(((int64_T)(65535U - rtu_coef) * localDW->UnitDelay3_DSTATE) >> if (tmp > 2147483647LL) {
16); tmp = 2147483647LL;
if ((q0 < 0) && (q1 < MIN_int32_T - q0)) {
rty_y_0 = MIN_int32_T;
} else if ((q0 > 0) && (q1 > MAX_int32_T - q0)) {
rty_y_0 = MAX_int32_T;
} else { } else {
rty_y_0 = q0 + q1; if (tmp < -2147483648LL) {
tmp = -2147483648LL;
}
} }
/* Update for UnitDelay: '<S2>/UnitDelay3' incorporates: /* Sum: '<S2>/Sum3' incorporates:
* Sum: '<S2>/Sum1' * Product: '<S2>/Divide3'
*/ */
localDW->UnitDelay3_DSTATE = rty_y_0; rty_y_0 = (int32_T)tmp + rtb_UnitDelay1;
/* End of Outputs for SubSystem: '<S1>/Low_Pass_Filter1' */ /* Update for UnitDelay: '<S2>/UnitDelay1' */
localDW->UnitDelay1_DSTATE = rty_y_0;
return rty_y_0; return rty_y_0;
} }

View File

@ -3,9 +3,9 @@
* *
* Code generated for Simulink model 'filtLowPass'. * Code generated for Simulink model 'filtLowPass'.
* *
* Model version : 1.1165 * Model version : 1.1257
* Simulink Coder version : 8.13 (R2017b) 24-Jul-2017 * Simulink Coder version : 8.13 (R2017b) 24-Jul-2017
* C/C++ source code generated on : Sun Oct 6 22:00:52 2019 * C/C++ source code generated on : Mon Feb 24 20:31:06 2020
* *
* Target selection: ert.tlc * Target selection: ert.tlc
* Embedded hardware selection: ARM Compatible->ARM Cortex * Embedded hardware selection: ARM Compatible->ARM Cortex
@ -31,7 +31,7 @@ typedef struct tag_RTM RT_MODEL;
/* Block signals and states (auto storage) for system '<Root>/filtLowPass' */ /* Block signals and states (auto storage) for system '<Root>/filtLowPass' */
typedef struct { typedef struct {
int32_T UnitDelay3_DSTATE; /* '<S2>/UnitDelay3' */ int32_T UnitDelay1_DSTATE; /* '<S2>/UnitDelay1' */
} DW_filtLowPass; } DW_filtLowPass;
/* Block signals and states (auto storage) for system '<Root>' */ /* Block signals and states (auto storage) for system '<Root>' */
@ -41,7 +41,7 @@ typedef struct {
/* External inputs (root inport signals with auto storage) */ /* External inputs (root inport signals with auto storage) */
typedef struct { typedef struct {
int16_T u; /* '<Root>/u' */ int32_T u; /* '<Root>/u' */
uint16_T coef; /* '<Root>/coef' */ uint16_T coef; /* '<Root>/coef' */
} ExtU; } ExtU;
@ -61,6 +61,12 @@ struct tag_RTM {
extern void filtLowPass_initialize(RT_MODEL *const rtM); extern void filtLowPass_initialize(RT_MODEL *const rtM);
extern void filtLowPass_step(RT_MODEL *const rtM); extern void filtLowPass_step(RT_MODEL *const rtM);
/*-
* These blocks were eliminated from the model due to optimizations:
*
* Block '<S2>/Scope1' : Unused code path elimination
*/
/*- /*-
* The generated code includes comments that allow you to trace directly * The generated code includes comments that allow you to trace directly
* back to the appropriate location in the model. The basic format * back to the appropriate location in the model. The basic format
@ -80,7 +86,7 @@ extern void filtLowPass_step(RT_MODEL *const rtM);
* *
* '<Root>' : 'BLDCmotorControl_FOC_R2017b_fixdt' * '<Root>' : 'BLDCmotorControl_FOC_R2017b_fixdt'
* '<S1>' : 'BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass' * '<S1>' : 'BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass'
* '<S2>' : 'BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass/Low_Pass_Filter1' * '<S2>' : 'BLDCmotorControl_FOC_R2017b_fixdt/filtLowPass/Low_Pass_Filter'
*/ */
#endif /* RTW_HEADER_filtLowPass_h_ */ #endif /* RTW_HEADER_filtLowPass_h_ */

View File

@ -25,7 +25,7 @@
// ########################## DEFINES ########################## // ########################## DEFINES ##########################
#define HOVER_SERIAL_BAUD 38400 // [-] Baud rate for HoverSerial (used to communicate with the hoverboard) #define HOVER_SERIAL_BAUD 38400 // [-] Baud rate for HoverSerial (used to communicate with the hoverboard)
#define SERIAL_BAUD 115200 // [-] Baud rate for built-in Serial (used for the Serial Monitor) #define SERIAL_BAUD 115200 // [-] Baud rate for built-in Serial (used for the Serial Monitor)
#define START_FRAME 0xAAAA // [-] Start frme definition for reliable serial communication #define START_FRAME 0xABCD // [-] Start frme definition for reliable serial communication
#define TIME_SEND 100 // [ms] Sending time interval #define TIME_SEND 100 // [ms] Sending time interval
#define SPEED_MAX_TEST 300 // [-] Maximum speed for testing #define SPEED_MAX_TEST 300 // [-] Maximum speed for testing
//#define DEBUG_RX // [-] Debug received data. Prints all bytes to serial (comment-out to disable) //#define DEBUG_RX // [-] Debug received data. Prints all bytes to serial (comment-out to disable)
@ -52,12 +52,11 @@ typedef struct{
uint16_t start; uint16_t start;
int16_t cmd1; int16_t cmd1;
int16_t cmd2; int16_t cmd2;
int16_t speedR;
int16_t speedL;
int16_t speedR_meas; int16_t speedR_meas;
int16_t speedL_meas; int16_t speedL_meas;
int16_t batVoltage; int16_t batVoltage;
int16_t boardTemp; int16_t boardTemp;
uint16_t cmdLed;
uint16_t checksum; uint16_t checksum;
} SerialFeedback; } SerialFeedback;
SerialFeedback Feedback; SerialFeedback Feedback;
@ -92,7 +91,7 @@ void Receive()
// Check for new data availability in the Serial buffer // Check for new data availability in the Serial buffer
if (HoverSerial.available()) { if (HoverSerial.available()) {
incomingByte = HoverSerial.read(); // Read the incoming byte incomingByte = HoverSerial.read(); // Read the incoming byte
bufStartFrame = ((uint16_t)(incomingBytePrev) << 8) + incomingByte; // Construct the start frame bufStartFrame = ((uint16_t)(incomingByte) << 8) | incomingBytePrev; // Construct the start frame
} }
else { else {
return; return;
@ -118,8 +117,8 @@ void Receive()
// Check if we reached the end of the package // Check if we reached the end of the package
if (idx == sizeof(SerialFeedback)) { if (idx == sizeof(SerialFeedback)) {
uint16_t checksum; uint16_t checksum;
checksum = (uint16_t)(NewFeedback.start ^ NewFeedback.cmd1 ^ NewFeedback.cmd2 ^ NewFeedback.speedR ^ NewFeedback.speedL checksum = (uint16_t)(NewFeedback.start ^ NewFeedback.cmd1 ^ NewFeedback.cmd2 ^ NewFeedback.speedR_meas ^ NewFeedback.speedL_meas
^ NewFeedback.speedR_meas ^ NewFeedback.speedL_meas ^ NewFeedback.batVoltage ^ NewFeedback.boardTemp); ^ NewFeedback.batVoltage ^ NewFeedback.boardTemp ^ NewFeedback.cmdLed);
// Check validity of the new data // Check validity of the new data
if (NewFeedback.start == START_FRAME && checksum == NewFeedback.checksum) { if (NewFeedback.start == START_FRAME && checksum == NewFeedback.checksum) {
@ -129,12 +128,11 @@ void Receive()
// Print data to built-in Serial // Print data to built-in Serial
Serial.print("1: "); Serial.print(Feedback.cmd1); Serial.print("1: "); Serial.print(Feedback.cmd1);
Serial.print(" 2: "); Serial.print(Feedback.cmd2); Serial.print(" 2: "); Serial.print(Feedback.cmd2);
Serial.print(" 3: "); Serial.print(Feedback.speedR); Serial.print(" 3: "); Serial.print(Feedback.speedR_meas);
Serial.print(" 4: "); Serial.print(Feedback.speedL); Serial.print(" 4: "); Serial.print(Feedback.speedL_meas);
Serial.print(" 5: "); Serial.print(Feedback.speedR_meas); Serial.print(" 5: "); Serial.print(Feedback.batVoltage);
Serial.print(" 6: "); Serial.print(Feedback.speedL_meas); Serial.print(" 6: "); Serial.print(Feedback.boardTemp);
Serial.print(" 7: "); Serial.print(Feedback.batVoltage); Serial.print(" 7: "); Serial.println(Feedback.cmdLed);
Serial.print(" 8: "); Serial.println(Feedback.boardTemp);
} else { } else {
Serial.println("Non-valid data skipped"); Serial.println("Non-valid data skipped");
} }
@ -161,7 +159,7 @@ void loop(void)
// Send commands // Send commands
if (iTimeSend > timeNow) return; if (iTimeSend > timeNow) return;
iTimeSend = timeNow + TIME_SEND; iTimeSend = timeNow + TIME_SEND;
Send(0, abs(iTest)); Send(0, SPEED_MAX_TEST - 2*abs(iTest));
// Calculate test command signal // Calculate test command signal
iTest += 10; iTest += 10;

View File

@ -67,11 +67,15 @@
#define BAT_CALIB_REAL_VOLTAGE 3970 // input voltage measured by multimeter (multiplied by 100). In this case 43.00 V * 100 = 4300 #define BAT_CALIB_REAL_VOLTAGE 3970 // input voltage measured by multimeter (multiplied by 100). In this case 43.00 V * 100 = 4300
#define BAT_CALIB_ADC 1492 // adc-value measured by mainboard (value nr 5 on UART debug output) #define BAT_CALIB_ADC 1492 // adc-value measured by mainboard (value nr 5 on UART debug output)
#define BAT_CELLS 10 // battery number of cells. Normal Hoverboard battery: 10s #define BAT_CELLS 10 // battery number of cells. Normal Hoverboard battery: 10s
#define BAT_LOW_LVL1_ENABLE 0 // to beep or not to beep, 1 or 0 #define BAT_LVL2_ENABLE 0 // to beep or not to beep, 1 or 0
#define BAT_LOW_LVL2_ENABLE 1 // to beep or not to beep, 1 or 0 #define BAT_LVL1_ENABLE 1 // to beep or not to beep, 1 or 0
#define BAT_LOW_LVL1 (360 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // gently beeps at this voltage level. [V*100/cell]. In this case 3.60 V/cell #define BAT_BLINK_INTERVAL 80 // battery led blink interval (80 loops * 5ms ~= 400ms)
#define BAT_LOW_LVL2 (350 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // your battery is almost empty. Charge now! [V*100/cell]. In this case 3.50 V/cell #define BAT_LVL5 (390 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // Green blink: no beep
#define BAT_LOW_DEAD (337 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // undervoltage poweroff. (while not driving) [V*100/cell]. In this case 3.37 V/cell #define BAT_LVL4 (380 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // Yellow: no beep
#define BAT_LVL3 (370 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // Yellow blink: no beep
#define BAT_LVL2 (360 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // Red: gently beep at this voltage level. [V*100/cell]. In this case 3.60 V/cell
#define BAT_LVL1 (350 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // Red blink: fast beep. Your battery is almost empty. Charge now! [V*100/cell]. In this case 3.50 V/cell
#define BAT_DEAD (337 * BAT_CELLS * BAT_CALIB_ADC) / BAT_CALIB_REAL_VOLTAGE // All leds off: undervoltage poweroff. (while not driving) [V*100/cell]. In this case 3.37 V/cell
// ######################## END OF BATTERY ############################### // ######################## END OF BATTERY ###############################
@ -135,15 +139,6 @@
#define PHASE_ADV_MAX 25 // [deg] Maximum Phase Advance angle (only for SIN). Higher angle results in higher maximum speed. #define PHASE_ADV_MAX 25 // [deg] Maximum Phase Advance angle (only for SIN). Higher angle results in higher maximum speed.
#define FIELD_WEAK_HI 1500 // [-] Input target High threshold for reaching maximum Field Weakening / Phase Advance. Do NOT set this higher than 1500. #define FIELD_WEAK_HI 1500 // [-] Input target High threshold for reaching maximum Field Weakening / Phase Advance. Do NOT set this higher than 1500.
#define FIELD_WEAK_LO 1000 // [-] Input target Low threshold for starting Field Weakening / Phase Advance. Do NOT set this higher than 1000. #define FIELD_WEAK_LO 1000 // [-] Input target Low threshold for starting Field Weakening / Phase Advance. Do NOT set this higher than 1000.
// Data checks - Do NOT touch
#if (FIELD_WEAK_ENA == 0)
#undef FIELD_WEAK_HI
#define FIELD_WEAK_HI 1000 // [-] This prevents the input target going beyond 1000 when Field Weakening is not enabled
#endif
#define INPUT_MAX MAX( 1000, FIELD_WEAK_HI) // [-] Defines the Input target maximum limitation
#define INPUT_MIN MIN(-1000,-FIELD_WEAK_HI) // [-] Defines the Input target minimum limitation
#define INPUT_MID INPUT_MAX / 2
// ########################### END OF MOTOR CONTROL ######################## // ########################### END OF MOTOR CONTROL ########################
@ -152,6 +147,7 @@
// Default settings will be applied at the end of this config file if not set before // Default settings will be applied at the end of this config file if not set before
#define INACTIVITY_TIMEOUT 8 // Minutes of not driving until poweroff. it is not very precise. #define INACTIVITY_TIMEOUT 8 // Minutes of not driving until poweroff. it is not very precise.
#define BEEPS_BACKWARD 1 // 0 or 1 #define BEEPS_BACKWARD 1 // 0 or 1
#define FLASH_WRITE_KEY 0x1234 // Flash writing key, used when writing data to flash memory
// #define SUPPORT_BUTTONS // Define for buttons support on ADC, Nunchuck // #define SUPPORT_BUTTONS // Define for buttons support on ADC, Nunchuck
/* FILTER is in fixdt(0,16,16): VAL_fixedPoint = VAL_floatingPoint * 2^16. In this case 6553 = 0.1 * 2^16 /* FILTER is in fixdt(0,16,16): VAL_fixedPoint = VAL_floatingPoint * 2^16. In this case 6553 = 0.1 * 2^16
@ -191,7 +187,7 @@
*/ */
// #define DEBUG_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! // #define DEBUG_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used!
#if defined(VARIANT_ADC) || defined(VARIANT_HOVERCAR) #if defined(VARIANT_ADC)
#define DEBUG_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used! #define DEBUG_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used!
#endif #endif
@ -238,8 +234,11 @@
// ############################ VARIANT_USART SETTINGS ############################ // ############################ VARIANT_USART SETTINGS ############################
#ifdef VARIANT_USART #ifdef VARIANT_USART
// #define SIDEBOARD_SERIAL_USART2
// #define CONTROL_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! For Arduino control check the hoverSerial.ino // #define CONTROL_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! For Arduino control check the hoverSerial.ino
// #define FEEDBACK_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! // #define FEEDBACK_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used!
// #define SIDEBOARD_SERIAL_USART3
#define CONTROL_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used! For Arduino control check the hoverSerial.ino #define CONTROL_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used! For Arduino control check the hoverSerial.ino
#define FEEDBACK_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used! #define FEEDBACK_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used!
#endif #endif
@ -302,7 +301,7 @@
#define CONTROL_ADC // use ADC as input. disable CONTROL_SERIAL_USART2, FEEDBACK_SERIAL_USART2, DEBUG_SERIAL_USART2! #define CONTROL_ADC // use ADC as input. disable CONTROL_SERIAL_USART2, FEEDBACK_SERIAL_USART2, DEBUG_SERIAL_USART2!
#define ADC_PROTECT_ENA // ADC Protection Enable flag. Use this flag to make sure the ADC is protected when GND or Vcc wire is disconnected #define ADC_PROTECT_ENA // ADC Protection Enable flag. Use this flag to make sure the ADC is protected when GND or Vcc wire is disconnected
#define ADC_PROTECT_TIMEOUT 30 // ADC Protection: number of wrong / missing input commands before safety state is taken #define ADC_PROTECT_TIMEOUT 30 // ADC Protection: number of wrong / missing input commands before safety state is taken
#define ADC_PROTECT_THRESH 400 // ADC Protection threshold below/above the MIN/MAX ADC values #define ADC_PROTECT_THRESH 300 // ADC Protection threshold below/above the MIN/MAX ADC values
#define ADC1_MIN 1000 // min ADC1-value while poti at minimum-position (0 - 4095) #define ADC1_MIN 1000 // min ADC1-value while poti at minimum-position (0 - 4095)
#define ADC1_MAX 2500 // max ADC1-value while poti at maximum-position (0 - 4095) #define ADC1_MAX 2500 // max ADC1-value while poti at maximum-position (0 - 4095)
#define ADC2_MIN 500 // min ADC2-value while poti at minimum-position (0 - 4095) #define ADC2_MIN 500 // min ADC2-value while poti at minimum-position (0 - 4095)
@ -311,6 +310,9 @@
#define STEER_COEFFICIENT 0 // 0.0f #define STEER_COEFFICIENT 0 // 0.0f
// #define INVERT_R_DIRECTION // Invert rotation of right motor // #define INVERT_R_DIRECTION // Invert rotation of right motor
// #define INVERT_L_DIRECTION // Invert rotation of left motor // #define INVERT_L_DIRECTION // Invert rotation of left motor
#define SIDEBOARD_SERIAL_USART3
#define FEEDBACK_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used!
// #define DEBUG_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used!
#endif #endif
// Multiple tap detection: default DOUBLE Tap on Brake pedal (4 pulses) // Multiple tap detection: default DOUBLE Tap on Brake pedal (4 pulses)
@ -323,12 +325,13 @@
// ############################ VARIANT_HOVERBOARD SETTINGS ############################ // ############################ VARIANT_HOVERBOARD SETTINGS ############################
// ##### ! NOT IMPLEMENTED YET ! ##### // Communication: [DONE]
// Balancing controller: [TODO]
#ifdef VARIANT_HOVERBOARD #ifdef VARIANT_HOVERBOARD
// #define CONTROL_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! For Arduino control check the hoverSerial.ino #define SIDEBOARD_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used!
// #define FEEDBACK_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! #define FEEDBACK_SERIAL_USART2
#define CONTROL_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used! For Arduino control check the hoverSerial.ino #define SIDEBOARD_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used!
#define FEEDBACK_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuk or lcd) is used! #define FEEDBACK_SERIAL_USART3
#endif #endif
// ######################## END OF VARIANT_HOVERBOARD SETTINGS ######################### // ######################## END OF VARIANT_HOVERBOARD SETTINGS #########################
@ -354,28 +357,26 @@
// ########################### UART SETIINGS ############################ // ########################### UART SETIINGS ############################
#if defined(FEEDBACK_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) || \ #if defined(FEEDBACK_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) || \
defined(FEEDBACK_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3) defined(FEEDBACK_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3)
#define START_FRAME 0xAAAA // [-] Start frame definition for serial commands #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_TIMEOUT 160 // [-] Serial timeout duration for the received data. 160 ~= 0.8 sec. Calculation: 0.8 sec / 0.005 sec
#endif #endif
#if defined(FEEDBACK_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) #if defined(FEEDBACK_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2)
#ifndef USART2_BAUD #ifndef USART2_BAUD
#define USART2_BAUD 38400 // UART2 baud rate (long wired cable) #define USART2_BAUD 38400 // UART2 baud rate (long wired cable)
#endif #endif
#define USART2_WORDLENGTH UART_WORDLENGTH_8B // UART_WORDLENGTH_8B or UART_WORDLENGTH_9B #define USART2_WORDLENGTH UART_WORDLENGTH_8B // UART_WORDLENGTH_8B or UART_WORDLENGTH_9B
#endif #endif
#if defined(FEEDBACK_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3) #if defined(FEEDBACK_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3)
#define USART3_BAUD 38400 // UART3 baud rate (short wired cable) #define USART3_BAUD 38400 // UART3 baud rate (short wired cable)
#define USART3_WORDLENGTH UART_WORDLENGTH_8B // UART_WORDLENGTH_8B or UART_WORDLENGTH_9B #define USART3_WORDLENGTH UART_WORDLENGTH_8B // UART_WORDLENGTH_8B or UART_WORDLENGTH_9B
#endif #endif
#if defined(FEEDBACK_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) #if defined(DEBUG_SERIAL_USART2)
#define UART_DMA_CHANNEL DMA1_Channel7 #define UART_DMA_CHANNEL_TX DMA1_Channel7
#endif #elif defined(DEBUG_SERIAL_USART3)
#define UART_DMA_CHANNEL_TX DMA1_Channel2
#if defined(FEEDBACK_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3)
#define UART_DMA_CHANNEL DMA1_Channel2
#endif #endif
// ########################### UART SETIINGS ############################ // ########################### UART SETIINGS ############################
@ -408,8 +409,12 @@
#error CONTROL_SERIAL_USART2 and CONTROL_SERIAL_USART3 not allowed, choose one. #error CONTROL_SERIAL_USART2 and CONTROL_SERIAL_USART3 not allowed, choose one.
#endif #endif
#if defined(FEEDBACK_SERIAL_USART2) && defined(FEEDBACK_SERIAL_USART3) #if defined(CONTROL_SERIAL_USART2) && defined(SIDEBOARD_SERIAL_USART2)
#error FEEDBACK_SERIAL_USART2 and FEEDBACK_SERIAL_USART3 not allowed, choose one. #error CONTROL_SERIAL_USART2 and SIDEBOARD_SERIAL_USART2 not allowed, choose one.
#endif
#if defined(CONTROL_SERIAL_USART3) && defined(SIDEBOARD_SERIAL_USART3)
#error CONTROL_SERIAL_USART3 and SIDEBOARD_SERIAL_USART3 not allowed, choose one.
#endif #endif
#if defined(DEBUG_SERIAL_USART2) && defined(FEEDBACK_SERIAL_USART2) #if defined(DEBUG_SERIAL_USART2) && defined(FEEDBACK_SERIAL_USART2)
@ -424,19 +429,19 @@
#error DEBUG_SERIAL_USART2 and DEBUG_SERIAL_USART3 not allowed, choose one. #error DEBUG_SERIAL_USART2 and DEBUG_SERIAL_USART3 not allowed, choose one.
#endif #endif
#if defined(CONTROL_ADC) && (defined(CONTROL_SERIAL_USART2) || defined(FEEDBACK_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2)) #if defined(CONTROL_ADC) && (defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) || defined(FEEDBACK_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2))
#error CONTROL_ADC and SERIAL_USART2 not allowed. It is on the same cable. #error CONTROL_ADC and SERIAL_USART2 not allowed. It is on the same cable.
#endif #endif
#if (defined(DEBUG_SERIAL_USART2) || defined(CONTROL_SERIAL_USART2)) && defined(CONTROL_PPM) #if (defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2)) && defined(CONTROL_PPM)
#error CONTROL_PPM and SERIAL_USART2 not allowed. It is on the same cable. #error CONTROL_PPM and SERIAL_USART2 not allowed. It is on the same cable.
#endif #endif
#if (defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)) && defined(CONTROL_NUNCHUK) #if (defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3)) && defined(CONTROL_NUNCHUK)
#error CONTROL_NUNCHUK and SERIAL_USART3 not allowed. It is on the same cable. #error CONTROL_NUNCHUK and SERIAL_USART3 not allowed. It is on the same cable.
#endif #endif
#if (defined(DEBUG_SERIAL_USART3) || defined(CONTROL_SERIAL_USART3)) && defined(DEBUG_I2C_LCD) #if (defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3)) && defined(DEBUG_I2C_LCD)
#error DEBUG_I2C_LCD and SERIAL_USART3 not allowed. It is on the same cable. #error DEBUG_I2C_LCD and SERIAL_USART3 not allowed. It is on the same cable.
#endif #endif
@ -444,12 +449,12 @@
#error only 1 input method allowed. use CONTROL_PPM or CONTROL_ADC or CONTROL_NUNCHUK. #error only 1 input method allowed. use CONTROL_PPM or CONTROL_ADC or CONTROL_NUNCHUK.
#endif #endif
#if defined(ADC_PROTECT_ENA) && ((ADC1_MIN - ADC_PROTECT_THRESH) <= 0 || (ADC1_MAX + ADC_PROTECT_THRESH) >= 4096) #if defined(ADC_PROTECT_ENA) && ((ADC1_MIN - ADC_PROTECT_THRESH) <= 0 || (ADC1_MAX + ADC_PROTECT_THRESH) >= 4095)
#warning ADC1 Protection NOT possible! Adjust the ADC thresholds. #warning ADC1 Protection NOT possible! Adjust the ADC thresholds.
#undef ADC_PROTECT_ENA #undef ADC_PROTECT_ENA
#endif #endif
#if defined(ADC_PROTECT_ENA) && ((ADC2_MIN - ADC_PROTECT_THRESH) <= 0 || (ADC2_MAX + ADC_PROTECT_THRESH) >= 4096) #if defined(ADC_PROTECT_ENA) && ((ADC2_MIN - ADC_PROTECT_THRESH) <= 0 || (ADC2_MAX + ADC_PROTECT_THRESH) >= 4095)
#warning ADC2 Protection NOT possible! Adjust the ADC thresholds. #warning ADC2 Protection NOT possible! Adjust the ADC thresholds.
#undef ADC_PROTECT_ENA #undef ADC_PROTECT_ENA
#endif #endif

View File

@ -150,33 +150,16 @@
typedef struct { typedef struct {
uint16_t dcr; uint16_t dcr;
uint16_t dcl; uint16_t dcl;
uint16_t rl1; uint16_t rlA;
uint16_t rl2; uint16_t rlB;
uint16_t rr1; uint16_t rrB;
uint16_t rr2; uint16_t rrC;
uint16_t batt1; uint16_t batt1;
uint16_t l_tx2; uint16_t l_tx2;
uint16_t temp; uint16_t temp;
uint16_t l_rx2; uint16_t l_rx2;
} adc_buf_t; } adc_buf_t;
typedef struct {
uint32_t t_timePrev;
uint8_t z_pulseCntPrev;
uint8_t b_hysteresis;
uint8_t b_multipleTap;
} MultipleTap;
// Define Beep functions
void longBeep(uint8_t freq);
void shortBeep(uint8_t freq);
// Define additional functions. Implementation is in main.c
void filtLowPass32(int16_t u, uint16_t coef, int32_t *y);
void mixerFcn(int16_t rtu_speed, int16_t rtu_steer, int16_t *rty_speedR, int16_t *rty_speedL);
void rateLimiter16(int16_t u, int16_t rate, int16_t *y);
void multipleTapDet(int16_t u, uint32_t timeNow, MultipleTap *x);
// Define I2C, Nunchuk, PPM functions // Define I2C, Nunchuk, PPM functions
void I2C_Init(void); void I2C_Init(void);
void Nunchuk_Init(void); void Nunchuk_Init(void);
@ -185,5 +168,15 @@ uint8_t Nunchuk_Ping(void);
void PPM_Init(void); void PPM_Init(void);
void PPM_ISR_Callback(void); void PPM_ISR_Callback(void);
// Sideboard definitions
#define LED1_SET (0x01)
#define LED2_SET (0x02)
#define LED3_SET (0x04)
#define LED4_SET (0x08)
#define LED5_SET (0x10)
#define SENSOR1_SET (0x01)
#define SENSOR2_SET (0x02)
#define SENSOR_MPU (0x04)
#endif #endif

View File

@ -178,12 +178,12 @@
#define PAGE_SIZE (uint32_t)FLASH_PAGE_SIZE /* Page size */ #define PAGE_SIZE (uint32_t)FLASH_PAGE_SIZE /* Page size */
/* EEPROM start address in Flash */ /* EEPROM start address in Flash */
#define EEPROM_START_ADDRESS ((uint32_t)ADDR_FLASH_PAGE_32) /* EEPROM emulation start address */ #define EEPROM_START_ADDRESS ((uint32_t)ADDR_FLASH_PAGE_64) /* EEPROM emulation start address */
/* Pages 0 and 1 base and end addresses */ /* Pages 0 and 1 base and end addresses */
#define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0000)) #define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
#define PAGE0_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1))) #define PAGE0_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))
#define PAGE0_ID ADDR_FLASH_PAGE_32 #define PAGE0_ID ADDR_FLASH_PAGE_64
#define PAGE1_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x10000)) #define PAGE1_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x10000))
#define PAGE1_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x10000 + PAGE_SIZE - 1)) #define PAGE1_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x10000 + PAGE_SIZE - 1))
@ -209,7 +209,7 @@
#define PAGE_FULL ((uint8_t)0x80) #define PAGE_FULL ((uint8_t)0x80)
/* Variables' number */ /* Variables' number */
#define NB_OF_VAR ((uint8_t)0x03) #define NB_OF_VAR ((uint8_t)0x09)
/* Exported types ------------------------------------------------------------*/ /* Exported types ------------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/

View File

@ -19,7 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once // Define to prevent recursive inclusion
#ifndef SETUP_H
#define SETUP_H
#include "stm32f1xx_hal.h" #include "stm32f1xx_hal.h"
@ -29,3 +31,6 @@ void MX_ADC1_Init(void);
void MX_ADC2_Init(void); void MX_ADC2_Init(void);
void UART2_Init(void); void UART2_Init(void);
void UART3_Init(void); void UART3_Init(void);
#endif

96
Inc/util.h Normal file
View File

@ -0,0 +1,96 @@
/**
* This file is part of the hoverboard-firmware-hack project.
*
* Copyright (C) 2020-2021 Emanuel FERU <aerdronix@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Define to prevent recursive inclusion
#ifndef UTIL_H
#define UTIL_H
#include <stdint.h>
#if defined(CONTROL_SERIAL_USART2) || defined(CONTROL_SERIAL_USART3)
#ifdef CONTROL_IBUS
typedef struct{
uint8_t start;
uint8_t type;
uint8_t channels[IBUS_NUM_CHANNELS*2];
uint8_t checksuml;
uint8_t checksumh;
} Serialcommand;
#else
typedef struct{
uint16_t start;
int16_t steer;
int16_t speed;
uint16_t checksum;
} Serialcommand;
#endif
#endif
#if defined(SIDEBOARD_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART3)
typedef struct{
uint16_t start;
int16_t roll;
int16_t pitch;
int16_t yaw;
uint16_t sensors;
uint16_t checksum;
} SerialSideboard;
#endif
// Initialization Functions
void BLDC_Init(void);
void Input_Lim_Init(void);
void Input_Init(void);
// General Functions
void poweronMelody(void);
void shortBeep(uint8_t freq);
void shortBeepMany(uint8_t cnt);
void longBeep(uint8_t freq);
void calcAvgSpeed(void);
void adcCalibLim(void);
void updateCurSpdLim(void);
void saveConfig(void);
// Poweroff Functions
void poweroff(void);
void poweroffPressCheck(void);
// Read Command Function
void readCommand(void);
// Sideboard functions
void sideboardLeds(uint8_t *leds);
void sideboardSensors(uint8_t sensors);
// Filtering Functions
void filtLowPass32(int32_t u, uint16_t coef, int32_t *y);
void rateLimiter16(int16_t u, int16_t rate, int16_t *y);
void mixerFcn(int16_t rtu_speed, int16_t rtu_steer, int16_t *rty_speedR, int16_t *rty_speedL);
// Multiple Tap Function
typedef struct {
uint32_t t_timePrev;
uint8_t z_pulseCntPrev;
uint8_t b_hysteresis;
uint8_t b_multipleTap;
} MultipleTap;
void multipleTapDet(int16_t u, uint32_t timeNow, MultipleTap *x);
#endif

View File

@ -75,7 +75,7 @@
<OPTFL> <OPTFL>
<tvExp>1</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>1</IsCurrentTarget> <IsCurrentTarget>0</IsCurrentTarget>
</OPTFL> </OPTFL>
<CpuCode>18</CpuCode> <CpuCode>18</CpuCode>
<DebugOpt> <DebugOpt>
@ -840,7 +840,7 @@
<OPTFL> <OPTFL>
<tvExp>1</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>0</IsCurrentTarget> <IsCurrentTarget>1</IsCurrentTarget>
</OPTFL> </OPTFL>
<CpuCode>18</CpuCode> <CpuCode>18</CpuCode>
<DebugOpt> <DebugOpt>
@ -1247,7 +1247,7 @@
<Group> <Group>
<GroupName>Startup</GroupName> <GroupName>Startup</GroupName>
<tvExp>0</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@ -1267,7 +1267,7 @@
<Group> <Group>
<GroupName>Src</GroupName> <GroupName>Src</GroupName>
<tvExp>0</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@ -1403,6 +1403,30 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>13</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Src\util.c</PathWithFileName>
<FilenameWithoutPath>util.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>14</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\Inc\config.h</PathWithFileName>
<FilenameWithoutPath>config.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group> </Group>
<Group> <Group>
@ -1413,7 +1437,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>13</FileNumber> <FileNumber>15</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1425,7 +1449,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>14</FileNumber> <FileNumber>16</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1437,7 +1461,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>15</FileNumber> <FileNumber>17</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1449,7 +1473,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>16</FileNumber> <FileNumber>18</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1461,7 +1485,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>17</FileNumber> <FileNumber>19</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1473,7 +1497,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>18</FileNumber> <FileNumber>20</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1485,7 +1509,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>19</FileNumber> <FileNumber>21</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1497,7 +1521,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>20</FileNumber> <FileNumber>22</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1509,7 +1533,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>21</FileNumber> <FileNumber>23</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1521,7 +1545,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>22</FileNumber> <FileNumber>24</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1533,7 +1557,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>23</FileNumber> <FileNumber>25</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1545,7 +1569,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>24</FileNumber> <FileNumber>26</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1557,7 +1581,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>25</FileNumber> <FileNumber>27</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1569,7 +1593,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>26</FileNumber> <FileNumber>28</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1581,7 +1605,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>27</FileNumber> <FileNumber>29</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1593,7 +1617,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>28</FileNumber> <FileNumber>30</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -1613,7 +1637,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>4</GroupNumber> <GroupNumber>4</GroupNumber>
<FileNumber>29</FileNumber> <FileNumber>31</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>

View File

@ -444,6 +444,16 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\Src\stm32f1xx_it.c</FilePath> <FilePath>..\Src\stm32f1xx_it.c</FilePath>
</File> </File>
<File>
<FileName>util.c</FileName>
<FileType>1</FileType>
<FilePath>..\Src\util.c</FilePath>
</File>
<File>
<FileName>config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Inc\config.h</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -984,6 +994,16 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\Src\stm32f1xx_it.c</FilePath> <FilePath>..\Src\stm32f1xx_it.c</FilePath>
</File> </File>
<File>
<FileName>util.c</FileName>
<FileType>1</FileType>
<FilePath>..\Src\util.c</FilePath>
</File>
<File>
<FileName>config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Inc\config.h</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -1592,6 +1612,16 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\Src\stm32f1xx_it.c</FilePath> <FilePath>..\Src\stm32f1xx_it.c</FilePath>
</File> </File>
<File>
<FileName>util.c</FileName>
<FileType>1</FileType>
<FilePath>..\Src\util.c</FilePath>
</File>
<File>
<FileName>config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Inc\config.h</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -2200,6 +2230,16 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\Src\stm32f1xx_it.c</FilePath> <FilePath>..\Src\stm32f1xx_it.c</FilePath>
</File> </File>
<File>
<FileName>util.c</FileName>
<FileType>1</FileType>
<FilePath>..\Src\util.c</FilePath>
</File>
<File>
<FileName>config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Inc\config.h</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -2808,6 +2848,16 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\Src\stm32f1xx_it.c</FilePath> <FilePath>..\Src\stm32f1xx_it.c</FilePath>
</File> </File>
<File>
<FileName>util.c</FileName>
<FileType>1</FileType>
<FilePath>..\Src\util.c</FilePath>
</File>
<File>
<FileName>config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Inc\config.h</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -3416,6 +3466,16 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\Src\stm32f1xx_it.c</FilePath> <FilePath>..\Src\stm32f1xx_it.c</FilePath>
</File> </File>
<File>
<FileName>util.c</FileName>
<FileType>1</FileType>
<FilePath>..\Src\util.c</FilePath>
</File>
<File>
<FileName>config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Inc\config.h</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -4024,6 +4084,16 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\Src\stm32f1xx_it.c</FilePath> <FilePath>..\Src\stm32f1xx_it.c</FilePath>
</File> </File>
<File>
<FileName>util.c</FileName>
<FileType>1</FileType>
<FilePath>..\Src\util.c</FilePath>
</File>
<File>
<FileName>config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Inc\config.h</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -4564,6 +4634,16 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\Src\stm32f1xx_it.c</FilePath> <FilePath>..\Src\stm32f1xx_it.c</FilePath>
</File> </File>
<File>
<FileName>util.c</FileName>
<FileType>1</FileType>
<FilePath>..\Src\util.c</FilePath>
</File>
<File>
<FileName>config.h</FileName>
<FileType>5</FileType>
<FilePath>..\Inc\config.h</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>

View File

@ -38,6 +38,7 @@ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \
Src/system_stm32f1xx.c \ Src/system_stm32f1xx.c \
Src/setup.c \ Src/setup.c \
Src/control.c \ Src/control.c \
Src/util.c \
Src/main.c \ Src/main.c \
Src/bldc.c \ Src/bldc.c \
Src/eeprom.c \ Src/eeprom.c \

View File

@ -83,7 +83,7 @@ Each motor is constantly monitored for errors. These errors are:
- **Error 002**: Hall sensor short circuit - **Error 002**: Hall sensor short circuit
- **Error 004**: Motor NOT able to spin (Possible causes: motor phase disconnected, MOSFET defective, operational Amplifier defective, motor blocked) - **Error 004**: Motor NOT able to spin (Possible causes: motor phase disconnected, MOSFET defective, operational Amplifier defective, motor blocked)
The error codes above are reported for each motor in the variables **errCode_Left** and **errCode_Right** for Left motor (long wired motor) and Right motor (short wired motor), respectively. In case of error, the motor power is reduced to 0, while an audible (fast beep) can be heard to notify the user. The error codes above are reported for each motor in the variables **rtY_Left.z_errCode** and **rtY_Right.z_errCode** for Left motor (long wired motor) and Right motor (short wired motor), respectively. In case of error, the motor power is reduced to 0, while an audible (fast beep) can be heard to notify the user.
### Demo videos ### Demo videos
@ -164,6 +164,7 @@ This firmware offers currently these variants (selectable in [platformio.ini](/p
- **VARIANT_PPM**: This is when you want to use a RC remote control with PPM Sum signal - **VARIANT_PPM**: This is when you want to use a RC remote control with PPM Sum signal
- **VARIANT_IBUS**: This is when you want to use a RC remote control with Flysky IBUS protocol connected to the Left sensor cable. - **VARIANT_IBUS**: This is when you want to use a RC remote control with Flysky IBUS protocol connected to the Left sensor cable.
- **VARIANT_HOVERCAR**: In this variant the motors are controlled by two pedals brake and throttle. Reverse is engaged by double tapping on the brake pedal at standstill. - **VARIANT_HOVERCAR**: In this variant the motors are controlled by two pedals brake and throttle. Reverse is engaged by double tapping on the brake pedal at standstill.
- **VARIANT_HOVERBOARD**: In this variant the mainboard reads the sideboards data. The sideboards need to be flashed with the hacked version. Only balancing controller is still to be implemented.
- **VARIANT_TRANSPOTTER**: This build is for transpotter which is a hoverboard based transportation system. For more details on how to build it check [here](https://github.com/NiklasFauth/hoverboard-firmware-hack/wiki/Build-Instruction:-TranspOtter) and [here](https://hackaday.io/project/161891-transpotter-ng). - **VARIANT_TRANSPOTTER**: This build is for transpotter which is a hoverboard based transportation system. For more details on how to build it check [here](https://github.com/NiklasFauth/hoverboard-firmware-hack/wiki/Build-Instruction:-TranspOtter) and [here](https://hackaday.io/project/161891-transpotter-ng).
Of course the firmware can be further customized for other needs or projects. Of course the firmware can be further customized for other needs or projects.

View File

@ -26,6 +26,7 @@
#include "defines.h" #include "defines.h"
#include "setup.h" #include "setup.h"
#include "config.h" #include "config.h"
#include "util.h"
// Matlab includes and defines - from auto-code generation // Matlab includes and defines - from auto-code generation
// ############################################################################### // ###############################################################################
@ -50,8 +51,6 @@ extern uint8_t ctrlModReq;
static int16_t curDC_max = (I_DC_MAX * A2BIT_CONV); static int16_t curDC_max = (I_DC_MAX * A2BIT_CONV);
int16_t curL_phaA = 0, curL_phaB = 0, curL_DC = 0; int16_t curL_phaA = 0, curL_phaB = 0, curL_DC = 0;
int16_t curR_phaB = 0, curR_phaC = 0, curR_DC = 0; int16_t curR_phaB = 0, curR_phaC = 0, curR_DC = 0;
uint8_t errCode_Left = 0;
uint8_t errCode_Right = 0;
volatile int pwml = 0; volatile int pwml = 0;
volatile int pwmr = 0; volatile int pwmr = 0;
@ -70,10 +69,10 @@ static uint8_t enableFin = 0;
static const uint16_t pwm_res = 64000000 / 2 / PWM_FREQ; // = 2000 static const uint16_t pwm_res = 64000000 / 2 / PWM_FREQ; // = 2000
static uint16_t offsetcount = 0; static uint16_t offsetcount = 0;
static int16_t offsetrl1 = 2000; static int16_t offsetrlA = 2000;
static int16_t offsetrl2 = 2000; static int16_t offsetrlB = 2000;
static int16_t offsetrr1 = 2000; static int16_t offsetrrB = 2000;
static int16_t offsetrr2 = 2000; static int16_t offsetrrC = 2000;
static int16_t offsetdcl = 2000; static int16_t offsetdcl = 2000;
static int16_t offsetdcr = 2000; static int16_t offsetdcr = 2000;
@ -91,10 +90,10 @@ void DMA1_Channel1_IRQHandler(void) {
if(offsetcount < 2000) { // calibrate ADC offsets if(offsetcount < 2000) { // calibrate ADC offsets
offsetcount++; offsetcount++;
offsetrl1 = (adc_buffer.rl1 + offsetrl1) / 2; offsetrlA = (adc_buffer.rlA + offsetrlA) / 2;
offsetrl2 = (adc_buffer.rl2 + offsetrl2) / 2; offsetrlB = (adc_buffer.rlB + offsetrlB) / 2;
offsetrr1 = (adc_buffer.rr1 + offsetrr1) / 2; offsetrrB = (adc_buffer.rrB + offsetrrB) / 2;
offsetrr2 = (adc_buffer.rr2 + offsetrr2) / 2; offsetrrC = (adc_buffer.rrC + offsetrrC) / 2;
offsetdcl = (adc_buffer.dcl + offsetdcl) / 2; offsetdcl = (adc_buffer.dcl + offsetdcl) / 2;
offsetdcr = (adc_buffer.dcr + offsetdcr) / 2; offsetdcr = (adc_buffer.dcr + offsetdcr) / 2;
return; return;
@ -102,17 +101,17 @@ void DMA1_Channel1_IRQHandler(void) {
if (buzzerTimer % 1000 == 0) { // because you get float rounding errors if it would run every time -> not any more, everything converted to fixed-point if (buzzerTimer % 1000 == 0) { // because you get float rounding errors if it would run every time -> not any more, everything converted to fixed-point
filtLowPass32(adc_buffer.batt1, BAT_FILT_COEF, &batVoltageFixdt); filtLowPass32(adc_buffer.batt1, BAT_FILT_COEF, &batVoltageFixdt);
batVoltage = (int16_t)(batVoltageFixdt >> 20); // convert fixed-point to integer batVoltage = (int16_t)(batVoltageFixdt >> 16); // convert fixed-point to integer
} }
// Get Left motor currents // Get Left motor currents
curL_phaA = (int16_t)(offsetrl1 - adc_buffer.rl1); curL_phaA = (int16_t)(offsetrlA - adc_buffer.rlA);
curL_phaB = (int16_t)(offsetrl2 - adc_buffer.rl2); curL_phaB = (int16_t)(offsetrlB - adc_buffer.rlB);
curL_DC = (int16_t)(offsetdcl - adc_buffer.dcl); curL_DC = (int16_t)(offsetdcl - adc_buffer.dcl);
// Get Right motor currents // Get Right motor currents
curR_phaB = (int16_t)(offsetrr1 - adc_buffer.rr1); curR_phaB = (int16_t)(offsetrrB - adc_buffer.rrB);
curR_phaC = (int16_t)(offsetrr2 - adc_buffer.rr2); curR_phaC = (int16_t)(offsetrrC - adc_buffer.rrC);
curR_DC = (int16_t)(offsetdcr - adc_buffer.dcr); curR_DC = (int16_t)(offsetdcr - adc_buffer.dcr);
// Disable PWM when current limit is reached (current chopping) // Disable PWM when current limit is reached (current chopping)
@ -152,7 +151,7 @@ void DMA1_Channel1_IRQHandler(void) {
OverrunFlag = true; OverrunFlag = true;
/* Make sure to stop BOTH motors in case of an error */ /* Make sure to stop BOTH motors in case of an error */
enableFin = enable && !errCode_Left && !errCode_Right; enableFin = enable && !rtY_Left.z_errCode && !rtY_Right.z_errCode;
// ========================= LEFT MOTOR ============================ // ========================= LEFT MOTOR ============================
// Get hall sensors values // Get hall sensors values
@ -178,7 +177,7 @@ void DMA1_Channel1_IRQHandler(void) {
ul = rtY_Left.DC_phaA; ul = rtY_Left.DC_phaA;
vl = rtY_Left.DC_phaB; vl = rtY_Left.DC_phaB;
wl = rtY_Left.DC_phaC; wl = rtY_Left.DC_phaC;
errCode_Left = rtY_Left.z_errCode; // errCodeLeft = rtY_Left.z_errCode;
// motSpeedLeft = rtY_Left.n_mot; // motSpeedLeft = rtY_Left.n_mot;
// motAngleLeft = rtY_Left.a_elecAngle; // motAngleLeft = rtY_Left.a_elecAngle;
@ -213,7 +212,7 @@ void DMA1_Channel1_IRQHandler(void) {
ur = rtY_Right.DC_phaA; ur = rtY_Right.DC_phaA;
vr = rtY_Right.DC_phaB; vr = rtY_Right.DC_phaB;
wr = rtY_Right.DC_phaC; wr = rtY_Right.DC_phaC;
errCode_Right = rtY_Right.z_errCode; // errCodeRight = rtY_Right.z_errCode;
// motSpeedRight = rtY_Right.n_mot; // motSpeedRight = rtY_Right.n_mot;
// motAngleRight = rtY_Right.a_elecAngle; // motAngleRight = rtY_Right.a_elecAngle;

View File

@ -30,11 +30,11 @@ void consoleScope(void) {
uart_buf[8] = CLAMP(ch_buf[7]+127, 0, 255); uart_buf[8] = CLAMP(ch_buf[7]+127, 0, 255);
uart_buf[9] = '\n'; uart_buf[9] = '\n';
if(UART_DMA_CHANNEL->CNDTR == 0) { if(UART_DMA_CHANNEL_TX->CNDTR == 0) {
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN; UART_DMA_CHANNEL_TX->CCR &= ~DMA_CCR_EN;
UART_DMA_CHANNEL->CNDTR = 10; UART_DMA_CHANNEL_TX->CNDTR = 10;
UART_DMA_CHANNEL->CMAR = (uint32_t)uart_buf; UART_DMA_CHANNEL_TX->CMAR = (uint32_t)uart_buf;
UART_DMA_CHANNEL->CCR |= DMA_CCR_EN; UART_DMA_CHANNEL_TX->CCR |= DMA_CCR_EN;
} }
#endif #endif
@ -45,11 +45,11 @@ void consoleScope(void) {
"1:%i 2:%i 3:%i 4:%i 5:%i 6:%i 7:%i 8:%i\r\n", "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]); 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) { if(UART_DMA_CHANNEL_TX->CNDTR == 0) {
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN; UART_DMA_CHANNEL_TX->CCR &= ~DMA_CCR_EN;
UART_DMA_CHANNEL->CNDTR = strLength; UART_DMA_CHANNEL_TX->CNDTR = strLength;
UART_DMA_CHANNEL->CMAR = (uint32_t)uart_buf; UART_DMA_CHANNEL_TX->CMAR = (uint32_t)uart_buf;
UART_DMA_CHANNEL->CCR |= DMA_CCR_EN; UART_DMA_CHANNEL_TX->CCR |= DMA_CCR_EN;
} }
#endif #endif
} }
@ -57,11 +57,11 @@ void consoleScope(void) {
void consoleLog(char *message) void consoleLog(char *message)
{ {
#if defined DEBUG_SERIAL_ASCII && (defined DEBUG_SERIAL_USART2 || defined DEBUG_SERIAL_USART3) #if defined DEBUG_SERIAL_ASCII && (defined DEBUG_SERIAL_USART2 || defined DEBUG_SERIAL_USART3)
if(UART_DMA_CHANNEL->CNDTR == 0) { if(UART_DMA_CHANNEL_TX->CNDTR == 0) {
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN; UART_DMA_CHANNEL_TX->CCR &= ~DMA_CCR_EN;
UART_DMA_CHANNEL->CNDTR = strlen((char *)(uintptr_t)message); UART_DMA_CHANNEL_TX->CNDTR = strlen((char *)(uintptr_t)message);
UART_DMA_CHANNEL->CMAR = (uint32_t)message; UART_DMA_CHANNEL_TX->CMAR = (uint32_t)message;
UART_DMA_CHANNEL->CCR |= DMA_CCR_EN; UART_DMA_CHANNEL_TX->CCR |= DMA_CCR_EN;
} }
#endif #endif
} }

File diff suppressed because it is too large Load Diff

View File

@ -53,11 +53,12 @@ DMA_HandleTypeDef hdma_usart3_tx;
volatile adc_buf_t adc_buffer; volatile adc_buf_t adc_buffer;
#if defined(CONTROL_SERIAL_USART2) || defined(FEEDBACK_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) #if defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2) || \
defined(FEEDBACK_SERIAL_USAR2) || defined(DEBUG_SERIAL_USART2)
void UART2_Init(void) { void UART2_Init(void) {
/* The code below is commented out - otwerwise Serial Receive does not work */ /* The code below is commented out - otwerwise Serial Receive does not work */
// #ifdef CONTROL_SERIAL_USART2 // #if defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART3)
// /* DMA1_Channel6_IRQn interrupt configuration */ // /* DMA1_Channel6_IRQn interrupt configuration */
// HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 6); // HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 6);
// HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn); // HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
@ -81,7 +82,7 @@ void UART2_Init(void) {
huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16; huart2.Init.OverSampling = UART_OVERSAMPLING_16;
#if defined(CONTROL_SERIAL_USART2) #if defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2)
huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.Mode = UART_MODE_TX_RX;
#elif defined(DEBUG_SERIAL_USART2) #elif defined(DEBUG_SERIAL_USART2)
huart2.Init.Mode = UART_MODE_TX; huart2.Init.Mode = UART_MODE_TX;
@ -99,7 +100,7 @@ void UART2_Init(void) {
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
#ifdef CONTROL_SERIAL_USART2 #if defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2)
GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //GPIO_MODE_AF_PP; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //GPIO_MODE_AF_PP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
@ -127,7 +128,7 @@ void UART2_Init(void) {
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_tx); HAL_DMA_Init(&hdma_usart2_tx);
#ifdef CONTROL_SERIAL_USART2 #if defined(CONTROL_SERIAL_USART2) || defined(SIDEBOARD_SERIAL_USART2)
__HAL_LINKDMA(&huart2, hdmatx, hdma_usart2_tx); __HAL_LINKDMA(&huart2, hdmatx, hdma_usart2_tx);
#endif #endif
#if defined(FEEDBACK_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2) #if defined(FEEDBACK_SERIAL_USART2) || defined(DEBUG_SERIAL_USART2)
@ -139,11 +140,12 @@ void UART2_Init(void) {
} }
#endif #endif
#if defined(CONTROL_SERIAL_USART3) || defined(FEEDBACK_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3) #if defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3) || \
defined(FEEDBACK_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3)
void UART3_Init(void) { void UART3_Init(void) {
/* The code below is commented out - otwerwise Serial Receive does not work */ /* The code below is commented out - otwerwise Serial Receive does not work */
// #ifdef CONTROL_SERIAL_USART3 // #if defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3)
// /* DMA1_Channel3_IRQn interrupt configuration */ // /* DMA1_Channel3_IRQn interrupt configuration */
// HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 5, 3); // HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 5, 3);
// HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn); // HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
@ -167,7 +169,7 @@ void UART3_Init(void) {
huart3.Init.Parity = UART_PARITY_NONE; huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16; huart3.Init.OverSampling = UART_OVERSAMPLING_16;
#if defined(CONTROL_SERIAL_USART3) #if defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3)
huart3.Init.Mode = UART_MODE_TX_RX; huart3.Init.Mode = UART_MODE_TX_RX;
#elif defined(DEBUG_SERIAL_USART3) #elif defined(DEBUG_SERIAL_USART3)
huart3.Init.Mode = UART_MODE_TX; huart3.Init.Mode = UART_MODE_TX;
@ -185,7 +187,7 @@ void UART3_Init(void) {
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
#ifdef CONTROL_SERIAL_USART3 #if defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3)
GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
@ -213,7 +215,7 @@ void UART3_Init(void) {
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart3_tx); HAL_DMA_Init(&hdma_usart3_tx);
#ifdef CONTROL_SERIAL_USART3 #if defined(CONTROL_SERIAL_USART3) || defined(SIDEBOARD_SERIAL_USART3)
__HAL_LINKDMA(&huart3, hdmatx, hdma_usart3_tx); __HAL_LINKDMA(&huart3, hdmatx, hdma_usart3_tx);
#endif #endif
#if defined(FEEDBACK_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3) #if defined(FEEDBACK_SERIAL_USART3) || defined(DEBUG_SERIAL_USART3)

1109
Src/util.c Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -33,7 +33,6 @@ monitor_port = COM5
monitor_speed = 38400 monitor_speed = 38400
build_flags = build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER -DUSE_HAL_DRIVER
-DSTM32F103xE -DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld -Wl,-T./STM32F103RCTx_FLASH.ld
@ -57,7 +56,6 @@ monitor_port = COM5
monitor_speed = 38400 monitor_speed = 38400
build_flags = build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER -DUSE_HAL_DRIVER
-DSTM32F103xE -DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld -Wl,-T./STM32F103RCTx_FLASH.ld
@ -77,7 +75,6 @@ debug_tool = stlink
upload_protocol = stlink upload_protocol = stlink
build_flags = build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER -DUSE_HAL_DRIVER
-DSTM32F103xE -DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld -Wl,-T./STM32F103RCTx_FLASH.ld
@ -97,7 +94,6 @@ debug_tool = stlink
upload_protocol = stlink upload_protocol = stlink
build_flags = build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER -DUSE_HAL_DRIVER
-DSTM32F103xE -DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld -Wl,-T./STM32F103RCTx_FLASH.ld
@ -117,7 +113,6 @@ debug_tool = stlink
upload_protocol = stlink upload_protocol = stlink
build_flags = build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER -DUSE_HAL_DRIVER
-DSTM32F103xE -DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld -Wl,-T./STM32F103RCTx_FLASH.ld
@ -141,7 +136,6 @@ monitor_port = COM5
monitor_speed = 38400 monitor_speed = 38400
build_flags = build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER -DUSE_HAL_DRIVER
-DSTM32F103xE -DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld -Wl,-T./STM32F103RCTx_FLASH.ld
@ -165,7 +159,6 @@ monitor_port = COM5
monitor_speed = 38400 monitor_speed = 38400
build_flags = build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER -DUSE_HAL_DRIVER
-DSTM32F103xE -DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld -Wl,-T./STM32F103RCTx_FLASH.ld
@ -185,7 +178,6 @@ debug_tool = stlink
upload_protocol = stlink upload_protocol = stlink
build_flags = build_flags =
-I${PROJECT_DIR}/inc/
-DUSE_HAL_DRIVER -DUSE_HAL_DRIVER
-DSTM32F103xE -DSTM32F103xE
-Wl,-T./STM32F103RCTx_FLASH.ld -Wl,-T./STM32F103RCTx_FLASH.ld