diff --git a/Inc/BLDC_controller.h b/Inc/BLDC_controller.h new file mode 100644 index 0000000..38c3dc3 --- /dev/null +++ b/Inc/BLDC_controller.h @@ -0,0 +1,444 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: BLDC_controller.h + * + * Code generated for Simulink model 'BLDC_controller'. + * + * Model version : 1.800 + * Simulink Coder version : 8.13 (R2017b) 24-Jul-2017 + * C/C++ source code generated on : Sat May 25 21:42:39 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_BLDC_controller_h_ +#define RTW_HEADER_BLDC_controller_h_ +#include "rtwtypes.h" +#include "zero_crossing_types.h" +#ifndef BLDC_controller_COMMON_INCLUDES_ +# define BLDC_controller_COMMON_INCLUDES_ +#include "rtwtypes.h" +#include "zero_crossing_types.h" +#endif /* BLDC_controller_COMMON_INCLUDES_ */ + +/* Macros for accessing real-time model data structure */ + +/* Block signals and states (auto storage) for system '/F01_03_Direction_Detection' */ +typedef struct { + int8_T UnitDelay1_DSTATE; /* '/UnitDelay1' */ +} DW_F01_03_Direction_Detection; + +/* Block signals and states (auto storage) for system '/Edge_counter' */ +typedef struct { + uint8_T UnitDelay1_DSTATE; /* '/UnitDelay1' */ + boolean_T Edge_counter_MODE; /* '/Edge_counter' */ +} DW_Edge_counter; + +/* Block signals and states (auto storage) for system '/Moving_Average_Filter' */ +typedef struct { + int32_T UnitDelay5_DSTATE; /* '/UnitDelay5' */ + int32_T UnitDelay1_DSTATE; /* '/UnitDelay1' */ +} DW_Moving_Average_Filter; + +/* Zero-crossing (trigger) state for system '/Moving_Average_Filter' */ +typedef struct { + ZCSigState Moving_Average_Filter_Trig_ZCE;/* '/Moving_Average_Filter' */ +} ZCE_Moving_Average_Filter; + +/* Zero-crossing (trigger) state for system '/Raw_ Speed_calculation' */ +typedef struct { + ZCSigState Raw_Speed_calculation_Trig_ZCE;/* '/Raw_ Speed_calculation' */ +} ZCE_Raw_Speed_calculation; + +/* Block signals and states (auto storage) for system '' */ +typedef struct { + DW_Moving_Average_Filter Moving_Average_Filter_n;/* '/Moving_Average_Filter' */ + DW_Edge_counter Edge_counter_l; /* '/Edge_counter' */ + DW_F01_03_Direction_Detection F01_03_Direction_Detection_j;/* '/F01_03_Direction_Detection' */ + DW_Moving_Average_Filter Moving_Average_Filter_l;/* '/Moving_Average_Filter' */ + DW_Edge_counter Edge_counter_f; /* '/Edge_counter' */ + DW_F01_03_Direction_Detection F01_03_Direction_Detection_o;/* '/F01_03_Direction_Detection' */ + int32_T Switch_PhaAdv; /* '/Switch_PhaAdv' */ + int32_T rpm_signed; /* '/Product2' */ + int32_T Switch_PhaAdv_a; /* '/Switch_PhaAdv' */ + int32_T rpm_signed_c; /* '/Product2' */ + int16_T Merge; /* '/Merge' */ + int16_T Merge1; /* '/Merge1' */ + int16_T Merge2; /* '/Merge2' */ + int16_T Merge_j; /* '/Merge' */ + int16_T Merge1_m; /* '/Merge1' */ + int16_T Merge2_d; /* '/Merge2' */ + int16_T z_counterRawPrev_DSTATE; /* '/z_counterRawPrev' */ + int16_T z_counter2_DSTATE; /* '/z_counter2' */ + int16_T UnitDelay1_DSTATE; /* '/UnitDelay1' */ + int16_T z_counterRawPrev_DSTATE_p; /* '/z_counterRawPrev' */ + int16_T z_counter2_DSTATE_h; /* '/z_counter2' */ + int16_T UnitDelay1_DSTATE_k; /* '/UnitDelay1' */ + int8_T UnitDelay1; /* '/UnitDelay1' */ + int8_T Switch2; /* '/Switch2' */ + int8_T UnitDelay1_k; /* '/UnitDelay1' */ + int8_T Switch2_e; /* '/Switch2' */ + int8_T If1_ActiveSubsystem; /* '/If1' */ + int8_T If1_ActiveSubsystem_j; /* '/If1' */ + uint8_T Sum2_i; /* '/Sum2' */ + uint8_T Sum2_l; /* '/Sum2' */ + uint8_T UnitDelay_DSTATE; /* '/UnitDelay' */ + uint8_T UnitDelay1_DSTATE_p; /* '/UnitDelay1' */ + uint8_T UnitDelay2_DSTATE; /* '/UnitDelay2' */ + uint8_T UnitDelay1_DSTATE_g; /* '/UnitDelay1' */ + uint8_T UnitDelay_DSTATE_j; /* '/UnitDelay' */ + uint8_T UnitDelay1_DSTATE_f; /* '/UnitDelay1' */ + uint8_T UnitDelay2_DSTATE_b; /* '/UnitDelay2' */ + uint8_T UnitDelay1_DSTATE_j; /* '/UnitDelay1' */ + boolean_T RelationalOperator4; /* '/Relational Operator4' */ + boolean_T LogicalOperator; /* '/Logical Operator' */ + boolean_T UnitDelay8_DSTATE; /* '/UnitDelay8' */ + boolean_T UnitDelay8_DSTATE_p; /* '/UnitDelay8' */ + boolean_T UnitDelay_DSTATE_k; /* '/UnitDelay' */ + boolean_T UnitDelay_DSTATE_l; /* '/UnitDelay' */ + boolean_T Memory_PreviousInput; /* '/Memory' */ + boolean_T Relay_Mode; /* '/Relay' */ + boolean_T Memory_PreviousInput_i; /* '/Memory' */ + boolean_T Relay_Mode_m; /* '/Relay' */ +} DW; + +/* Zero-crossing (trigger) state */ +typedef struct { + ZCE_Raw_Speed_calculation Raw_Speed_calculation_k;/* '/Raw_ Speed_calculation' */ + ZCE_Moving_Average_Filter Moving_Average_Filter_n;/* '/Moving_Average_Filter' */ + ZCE_Raw_Speed_calculation Raw_Speed_calculation_m;/* '/Raw_ Speed_calculation' */ + ZCE_Moving_Average_Filter Moving_Average_Filter_l;/* '/Moving_Average_Filter' */ +} PrevZCX; + +/* Constant parameters (auto storage) */ +typedef struct { + /* Pooled Parameter (Expression: r_trapPhaA_M1) + * Referenced by: + * '/r_trapPhaA_M1' + * '/r_trapPhaA_M1' + */ + int16_T pooled8[7]; + + /* Pooled Parameter (Expression: r_trapPhaB_M1) + * Referenced by: + * '/r_trapPhaB_M1' + * '/r_trapPhaB_M1' + */ + int16_T pooled9[7]; + + /* Pooled Parameter (Expression: r_trapPhaC_M1) + * Referenced by: + * '/r_trapPhaC_M1' + * '/r_trapPhaC_M1' + */ + int16_T pooled10[7]; + + /* Pooled Parameter (Expression: r_sinPhaA_M1) + * Referenced by: + * '/r_sinPhaA_M1' + * '/r_sinPhaA_M1' + */ + int16_T pooled11[37]; + + /* Pooled Parameter (Expression: r_sinPhaB_M1) + * Referenced by: + * '/r_sinPhaB_M1' + * '/r_sinPhaB_M1' + */ + int16_T pooled12[37]; + + /* Pooled Parameter (Expression: r_sinPhaC_M1) + * Referenced by: + * '/r_sinPhaC_M1' + * '/r_sinPhaC_M1' + */ + int16_T pooled13[37]; + + /* Pooled Parameter (Expression: r_sin3PhaA_M1) + * Referenced by: + * '/r_sin3PhaA_M1' + * '/r_sin3PhaA_M1' + */ + int16_T pooled14[37]; + + /* Pooled Parameter (Expression: r_sin3PhaB_M1) + * Referenced by: + * '/r_sin3PhaB_M1' + * '/r_sin3PhaB_M1' + */ + int16_T pooled15[37]; + + /* Pooled Parameter (Expression: r_sin3PhaC_M1) + * Referenced by: + * '/r_sin3PhaC_M1' + * '/r_sin3PhaC_M1' + */ + int16_T pooled16[37]; + + /* Pooled Parameter (Expression: z_commutMap_M1) + * Referenced by: + * '/z_commutMap_M1' + * '/z_commutMap_M1' + */ + int16_T pooled17[18]; + + /* Pooled Parameter (Expression: vec_hallToPos) + * Referenced by: + * '/vec_hallToPos' + * '/vec_hallToPos' + */ + uint8_T pooled27[8]; + + /* Pooled Parameter (Expression: [0 1;1 0;0 1;0 1;1 0;1 0;0 0;0 0]) + * Referenced by: + * '/Logic' + * '/Logic' + */ + boolean_T pooled31[16]; +} ConstP; + +/* External inputs (root inport signals with auto storage) */ +typedef struct { + uint8_T b_hallALeft; /* '/b_hallALeft ' */ + uint8_T b_hallBLeft; /* '/b_hallBLeft' */ + uint8_T b_hallCLeft; /* '/b_hallCLeft' */ + int32_T r_DCLeft; /* '/r_DCLeft' */ + uint8_T b_hallARight; /* '/b_hallARight' */ + uint8_T b_hallBRight; /* '/b_hallBRight' */ + uint8_T b_hallCRight; /* '/b_hallCRight' */ + int32_T r_DCRight; /* '/r_DCRight' */ +} ExtU; + +/* External outputs (root outports fed by signals with auto storage) */ +typedef struct { + int32_T DC_phaALeft; /* '/DC_phaALeft' */ + int32_T DC_phaBLeft; /* '/DC_phaBLeft' */ + int32_T DC_phaCLeft; /* '/DC_phaCLeft' */ + int32_T n_motLeft; /* '/n_motLeft' */ + int32_T a_elecAngleLeft; /* '/a_elecAngleLeft' */ + int32_T DC_phaARight; /* '/DC_phaARight' */ + int32_T DC_phaBRight; /* '/DC_phaBRight' */ + int32_T DC_phaCRight; /* '/DC_phaCRight' */ + int32_T n_motRight; /* '/n_motRight' */ + int32_T a_elecAngleRight; /* '/a_elecAngleRight' */ +} ExtY; + +/* Parameters (auto storage) */ +struct P_ { + int32_T cf_spdCoef; /* Variable: cf_spdCoef + * Referenced by: + * '/cf_spdCoef' + * '/cf_spdCoef' + */ + int32_T n_commAcvLo; /* Variable: n_commAcvLo + * Referenced by: + * '/Relay' + * '/Relay' + */ + int32_T n_commDeacvHi; /* Variable: n_commDeacvHi + * Referenced by: + * '/Relay' + * '/Relay' + */ + int32_T n_thresSpdDeacv; /* Variable: n_thresSpdDeacv + * Referenced by: + * '/n_thresSpdDeacv' + * '/n_thresSpdDeacv' + */ + int32_T r_commDCDeacv; /* Variable: r_commDCDeacv + * Referenced by: + * '/r_commDCDeacv' + * '/r_commDCDeacv' + */ + int32_T r_phaAdvDC_XA[11]; /* Variable: r_phaAdvDC_XA + * Referenced by: + * '/r_phaAdvDC_XA' + * '/r_phaAdvDC_XA' + */ + int16_T a_phaAdv_M1[11]; /* Variable: a_phaAdv_M1 + * Referenced by: + * '/a_phaAdv_M2' + * '/a_phaAdv_M2' + */ + int16_T z_maxCntRst; /* Variable: z_maxCntRst + * Referenced by: + * '/z_maxCntRst' + * '/z_maxCntRst' + * '/z_maxCntRst' + * '/z_maxCntRst' + */ + uint8_T z_ctrlTypSel; /* Variable: z_ctrlTypSel + * Referenced by: + * '/z_ctrlTypSel1' + * '/z_ctrlTypSel1' + */ + uint8_T z_nrEdgeSpdAcv; /* Variable: z_nrEdgeSpdAcv + * Referenced by: + * '/z_nrEdgeSpdAcv' + * '/z_nrEdgeSpdAcv' + */ + boolean_T b_phaAdvEna; /* Variable: b_phaAdvEna + * Referenced by: + * '/a_elecPeriod1' + * '/a_elecPeriod1' + */ +}; + +/* Parameters (auto storage) */ +typedef struct P_ P; + +/* Block parameters (auto storage) */ +extern P rtP; + +/* Block signals and states (auto storage) */ +extern DW rtDW; + +/* External inputs (root inport signals with auto storage) */ +extern ExtU rtU; + +/* External outputs (root outports fed by signals with auto storage) */ +extern ExtY rtY; + +/* Constant parameters (auto storage) */ +extern const ConstP rtConstP; + +/* Model entry point functions */ +extern void BLDC_controller_initialize(void); +extern void BLDC_controller_step(void); + +/*- + * These blocks were eliminated from the model due to optimizations: + * + * Block '/Scope2' : Unused code path elimination + * Block '/Scope' : Unused code path elimination + * Block '/Scope2' : Unused code path elimination + * Block '/Scope' : Unused code path elimination + */ + +/*- + * The generated code includes comments that allow you to trace directly + * back to the appropriate location in the model. The basic format + * is /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_R2017b/BLDC_controller') - opens subsystem BLDCmotorControl_R2017b/BLDC_controller + * hilite_system('BLDCmotorControl_R2017b/BLDC_controller/Kp') - opens and selects block Kp + * + * Here is the system hierarchy for this model + * + * '' : 'BLDCmotorControl_R2017b' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log3' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log4' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log5' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log7' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/signal_log8' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F04_Control_Type_Management' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/signal_log3' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_01_Edge_Detector' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_02_Position_Calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_03_Direction_Detection' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_01_Edge_Detector/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_02_Position_Calculation/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_03_Direction_Detection/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Edge_counter' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Moving_Average_Filter' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Raw_ Speed_calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/S-R Flip-Flop' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/rising_edge' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/rst_Delay' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log3' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log4' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Edge_counter/rst_Delay' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation/Modulo_Calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F02_Electrical_Angle_Calculation/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/F03_01_Pure_Trapezoidal_Method' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/F03_02_Sinusoidal3rd_Method' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/F03_02_Sinusoidal_Method' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F03_Control_Method_Selection/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F04_Control_Type_Management/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F04_Control_Type_Management/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Left/F04_Control_Type_Management/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F04_Control_Type_Management' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/signal_log3' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_01_Edge_Detector' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_02_Position_Calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_03_Direction_Detection' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_01_Edge_Detector/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_02_Position_Calculation/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_03_Direction_Detection/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Edge_counter' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Moving_Average_Filter' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Raw_ Speed_calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/S-R Flip-Flop' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/rising_edge' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/rst_Delay' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log3' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log4' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F01_Preliminary_Calculations/F01_04_Speed_Calculation/Edge_counter/rst_Delay' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation/Modulo_Calculation' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F02_Electrical_Angle_Calculation/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/F03_01_Pure_Trapezoidal_Method' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/F03_02_Sinusoidal3rd_Method' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/F03_02_Sinusoidal_Method' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F03_Control_Method_Selection/signal_log6' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F04_Control_Type_Management/signal_log1' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F04_Control_Type_Management/signal_log2' + * '' : 'BLDCmotorControl_R2017b/BLDC_controller/BLDC_controller_Right/F04_Control_Type_Management/signal_log6' + */ +#endif /* RTW_HEADER_BLDC_controller_h_ */ + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/Inc/config.h b/Inc/config.h index 2ecac25..4f3d590 100644 --- a/Inc/config.h +++ b/Inc/config.h @@ -6,16 +6,16 @@ #define PWM_FREQ 16000 // PWM frequency in Hz #define DEAD_TIME 32 // PWM deadtime -#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 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 TIMEOUT 5 // number of wrong / missing input commands before emergency off // ############################### 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. // Battery voltage calibration: connect power source. see . 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 +#define BAT_CALIB_REAL_VOLTAGE 43.0 // input voltage measured by multimeter #define BAT_CALIB_ADC 1704 // adc-value measured by mainboard (value nr 5 on UART debug output) #define BAT_NUMBER_OF_CELLS 10 // normal Hoverboard battery: 10s @@ -64,16 +64,35 @@ // ###### 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 . 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 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) -#define ADC2_MAX 4095 // max ADC2-value while poti at maximum-position (0 - 4095) +#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) +#define ADC2_MAX 4095 // max ADC2-value while poti at maximum-position (0 - 4095) // ###### CONTROL VIA NINTENDO NUNCHUCK ###### // 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 CONTROL (overwrite) ######################### +#define CTRL_TYP_SEL 3 // [-] Control method selection: 0 = Commutation , 1 = Pure Trapezoidal , 2 = Sinusoidal, 3 = Sinusoidal 3rd armonic (default) +#define PHASE_ADV_ENA 1 // [-] Phase advance enable parameter: 0 = disabled, 1 = enabled (default) +#define COMM_DEACV_HI 180 // [rpm] Commutation method deactivation speed high (above this value the control switches from Commutation method to Selected method above) +#define COMM_ACV_LO 100 // [rpm] Commutation method activation speed low + +// GENERAL NOTES: +// 1. All the available motor parameters can be found in the BLDC_controller_data.c +// 2. For more details regarding the parameters and the working principle of the controller please consult the Simulink model +// 3. A webview was created, so Matlab/Simulink installation is not needed, unless you want to regenerate the code + +// NOTES Phase Advance / Field weakening: +// 1. In BLDC_controller_data.c you can find the Phase advance Map as a function of Duty Cycle: MAP = a_phaAdv_M1, XAXIS = r_phaAdvDC_XA +// 2. The default calibration was experimentaly obtained on the real motor based on the minimum noise and minimum torque ripple +// 3. If you re-calibrate the Phase advance map please take all the safety measures! +// 4. I do not recommend more than 40 deg MAX Phase advance. The motors can spin VERY VERY FAST!!! Please use it with care!! + + // ############################### DRIVING BEHAVIOR ############################### // inputs: @@ -82,23 +101,13 @@ // - adc_buffer.l_tx2 and adc_buffer.l_rx2: unfiltered ADC values (you do not need them). 0 to 4095 // outputs: // - speedR and speedL: normal driving -1000 to 1000 -// - weakr and weakl: field weakening for extra boost at high speed (speedR > 700 and speedL > 700). 0 to ~400 #define FILTER 0.1 // lower value == softer filter. do not use values <0.01, you will get float precision issues. -#define SPEED_COEFFICIENT 0.5 // higher value == stronger. 0.0 to ~2.0? -#define STEER_COEFFICIENT 0.5 // higher value == stronger. if you do not want any steering, set it to 0.0; 0.0 to 1.0 +#define SPEED_COEFFICIENT 1.0 //0.5 // higher value == stronger. 0.0 to ~2.0? +#define STEER_COEFFICIENT 0.5//0.5 // higher value == stronger. if you do not want any steering, set it to 0.0; 0.0 to 1.0 #define INVERT_R_DIRECTION #define INVERT_L_DIRECTION -#define BEEPS_BACKWARD 1 // 0 or 1 - -//Turbo boost at high speeds while button1 is pressed: -//#define ADDITIONAL_CODE \ -if (button1 && speedR > 700) { /* field weakening at high speeds */ \ - weakl = cmd1 - 700; /* weak should never exceed 400 or 450 MAX!! */ \ - weakr = cmd1 - 700; } \ -else { \ - weakl = 0; \ - weakr = 0; } +#define BEEPS_BACKWARD 0 // 0 or 1 // ###### SIMPLE BOBBYCAR ###### // for better bobbycar code see: https://github.com/larsmm/hoverboard-firmware-hack-bbcar @@ -106,30 +115,10 @@ else { \ // #define SPEED_COEFFICIENT -1 // #define STEER_COEFFICIENT 0 -// #define ADDITIONAL_CODE \ -if (button1 && speedR < 300) { /* drive backwards */ \ - speedR = speedR * -0.2f; \ - speedL = speedL * -0.2f; } \ -else { \ - direction = 1; } \ -if (button1 && speedR > 700) { /* field weakening at high speeds */ \ - weakl = speedR - 600; /* weak should never exceed 400 or 450 MAX!! */ \ - weakr = speedR - 600; } \ -else { \ - weakl = 0; \ - weakr = 0; } - // ###### ARMCHAIR ###### // #define FILTER 0.05 // #define SPEED_COEFFICIENT 0.5 -// #define STEER_COEFFICIENT -0.2 - -// #define ADDITIONAL_CODE if (button1 && scale > 0.8) { /* field weakening at high speeds */ \ - weakl = speedL - 600; /* weak should never exceed 400 or 450 MAX!! */ \ - weakr = speedR - 600; } \ -else {\ - weakl = 0;\ - weakr = 0; +// #define STEER_COEFFICIENT -0.2 // ############################### VALIDATE SETTINGS ############################### diff --git a/Inc/ert_main.c b/Inc/ert_main.c new file mode 100644 index 0000000..ba38846 --- /dev/null +++ b/Inc/ert_main.c @@ -0,0 +1,116 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: ert_main.c + * + * Code generated for Simulink model 'BLDC_controller'. + * + * Model version : 1.790 + * Simulink Coder version : 8.13 (R2017b) 24-Jul-2017 + * C/C++ source code generated on : Wed May 22 23:49:19 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 +#include /* This ert_main.c example uses printf/fflush */ +#include "BLDC_controller.h" /* Model's header file */ +#include "rtwtypes.h" +#include "zero_crossing_types.h" + +/* + * Associating rt_OneStep with a real-time clock or interrupt service routine + * is what makes the generated code "real-time". The function rt_OneStep is + * always associated with the base rate of the model. Subrates are managed + * by the base rate from inside the generated code. Enabling/disabling + * interrupts and floating point context switches are target specific. This + * example code indicates where these should take place relative to executing + * the generated code step function. Overrun behavior should be tailored to + * your application needs. This example simply sets an error status in the + * real-time model and returns from rt_OneStep. + */ +void rt_OneStep(void); +void rt_OneStep(void) +{ + static boolean_T OverrunFlag = false; + + /* Disable interrupts here */ + + /* Check for overrun */ + if (OverrunFlag) { + return; + } + + OverrunFlag = true; + + /* Save FPU context here (if necessary) */ + /* Re-enable timer or interrupt here */ + /* Set model inputs here */ + + /* Step the model */ + BLDC_controller_step(); + + /* Get model outputs here */ + + /* Indicate task complete */ + OverrunFlag = false; + + /* Disable interrupts here */ + /* Restore FPU context here (if necessary) */ + /* Enable interrupts here */ +} + +/* + * The example "main" function illustrates what is required by your + * application code to initialize, execute, and terminate the generated code. + * Attaching rt_OneStep to a real-time clock is target specific. This example + * illustrates how you do this relative to initializing the model. + */ +int_T main(int_T argc, const char *argv[]) +{ + /* Unused arguments */ + (void)(argc); + (void)(argv); + + /* Initialize model */ + BLDC_controller_initialize(); + + /* Attach rt_OneStep to a timer or interrupt service routine with + * period 1.0E-5 seconds (the model's base sample time) here. The + * call syntax for rt_OneStep is + * + * rt_OneStep(); + */ + printf("Warning: The simulation will run forever. " + "Generated ERT main won't simulate model step behavior. " + "To change this behavior select the 'MAT-file logging' option.\n"); + fflush((NULL)); + while (1) { + /* Perform other application tasks here */ + } + + /* The option 'Remove error status field in real-time model data structure' + * is selected, therefore the following code does not need to execute. + */ +#if 0 + + /* Disable rt_OneStep() here */ +#endif + + return 0; +} + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/Inc/rtwtypes.h b/Inc/rtwtypes.h new file mode 100644 index 0000000..80e8117 --- /dev/null +++ b/Inc/rtwtypes.h @@ -0,0 +1,108 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: rtwtypes.h + * + * Code generated for Simulink model 'BLDC_controller'. + * + * Model version : 1.800 + * Simulink Coder version : 8.13 (R2017b) 24-Jul-2017 + * C/C++ source code generated on : Sat May 25 21:42:39 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 RTWTYPES_H +#define RTWTYPES_H + +/* Logical type definitions */ +#if (!defined(__cplusplus)) +# ifndef false +# define false (0U) +# endif + +# ifndef true +# define true (1U) +# endif +#endif + +/*=======================================================================* + * Target hardware information + * Device type: MATLAB Host + * Number of bits: char: 8 short: 16 int: 32 + * long: 32 long long: 64 + * native word size: 64 + * Byte ordering: LittleEndian + * Signed integer division rounds to: Zero + * Shift right on a signed integer as arithmetic shift: on + *=======================================================================*/ + +/*=======================================================================* + * Fixed width word size data types: * + * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * + * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * + * real32_T, real64_T - 32 and 64 bit floating point numbers * + *=======================================================================*/ +typedef signed char int8_T; +typedef unsigned char uint8_T; +typedef short int16_T; +typedef unsigned short uint16_T; +typedef int int32_T; +typedef unsigned int uint32_T; +typedef long long int64_T; +typedef unsigned long long uint64_T; +typedef float real32_T; +typedef double real64_T; + +/*===========================================================================* + * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * + * real_T, time_T, ulong_T, ulonglong_T. * + *===========================================================================*/ +typedef double real_T; +typedef double time_T; +typedef unsigned char boolean_T; +typedef int int_T; +typedef unsigned int uint_T; +typedef unsigned long ulong_T; +typedef unsigned long long ulonglong_T; +typedef char char_T; +typedef unsigned char uchar_T; +typedef char_T byte_T; + +/*=======================================================================* + * Min and Max: * + * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * + * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * + *=======================================================================*/ +#define MAX_int8_T ((int8_T)(127)) +#define MIN_int8_T ((int8_T)(-128)) +#define MAX_uint8_T ((uint8_T)(255U)) +#define MAX_int16_T ((int16_T)(32767)) +#define MIN_int16_T ((int16_T)(-32768)) +#define MAX_uint16_T ((uint16_T)(65535U)) +#define MAX_int32_T ((int32_T)(2147483647)) +#define MIN_int32_T ((int32_T)(-2147483647-1)) +#define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) +#define MAX_int64_T ((int64_T)(9223372036854775807LL)) +#define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) +#define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) + +/* Block D-Work pointer type */ +typedef void * pointer_T; + +#endif /* RTWTYPES_H */ + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/Inc/zero_crossing_types.h b/Inc/zero_crossing_types.h new file mode 100644 index 0000000..c402c64 --- /dev/null +++ b/Inc/zero_crossing_types.h @@ -0,0 +1,57 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: zero_crossing_types.h + * + * Code generated for Simulink model 'BLDC_controller'. + * + * Model version : 1.800 + * Simulink Coder version : 8.13 (R2017b) 24-Jul-2017 + * C/C++ source code generated on : Sat May 25 21:42:39 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 ZERO_CROSSING_TYPES_H +#define ZERO_CROSSING_TYPES_H +#include "rtwtypes.h" + +/* Trigger directions: falling, either, and rising */ +typedef enum { + FALLING_ZERO_CROSSING = -1, + ANY_ZERO_CROSSING = 0, + RISING_ZERO_CROSSING = 1 +} ZCDirection; + +/* Previous state of a trigger signal */ +typedef uint8_T ZCSigState; + +/* Initial value of a trigger zero crossing signal */ +#define UNINITIALIZED_ZCSIG 0x03U +#define NEG_ZCSIG 0x02U +#define POS_ZCSIG 0x01U +#define ZERO_ZCSIG 0x00U + +/* Current state of a trigger signal */ +typedef enum { + FALLING_ZCEVENT = -1, + NO_ZCEVENT = 0, + RISING_ZCEVENT = 1 +} ZCEventType; + +#endif /* ZERO_CROSSING_TYPES_H */ + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/Src/BLDC_controller.c b/Src/BLDC_controller.c new file mode 100644 index 0000000..9111d29 --- /dev/null +++ b/Src/BLDC_controller.c @@ -0,0 +1,1313 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: BLDC_controller.c + * + * Code generated for Simulink model 'BLDC_controller'. + * + * Model version : 1.800 + * Simulink Coder version : 8.13 (R2017b) 24-Jul-2017 + * C/C++ source code generated on : Sat May 25 21:42:39 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 "BLDC_controller.h" +#ifndef UCHAR_MAX +#include +#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 + +/* Block signals and states (auto storage) */ +DW rtDW; + +/* Previous zero-crossings (trigger) states */ +PrevZCX rtPrevZCX; + +/* External inputs (root inport signals with auto storage) */ +ExtU rtU; + +/* External outputs (root outports fed by signals with auto storage) */ +ExtY rtY; +static uint8_T plook_u8s32u32n31_evenc_s(int32_T u, int32_T bp0, uint32_T + bpSpace, uint32_T maxIndex, uint32_T *fraction); +static int16_T intrp1d_s16s32s32u8u32n31l_s(uint8_T bpIndex, uint32_T frac, + const int16_T table[]); +static int32_T div_nde_s32_floor(int32_T numerator, int32_T denominator); +static void F01_03_Direction_Detection(boolean_T rtu_Enable, uint8_T rtu_z_pos, + uint8_T rtu_z_posPrev, int8_T *rty_z_dir, int8_T *rty_z_dirPrev, + DW_F01_03_Direction_Detection *localDW); +static void Edge_counter_Reset(DW_Edge_counter *localDW); +static void Edge_counter_Disable(uint8_T *rty_cnt, DW_Edge_counter *localDW); +static void Edge_counter(boolean_T rtu_Enable, boolean_T rtu_b_edge, int8_T + rtu_z_dir, int8_T rtu_z_dirPrev, uint8_T *rty_cnt, DW_Edge_counter *localDW); +static void Moving_Average_Filter(boolean_T rtu_Trigger, int32_T rtu_n_motRaw, + int32_T *rty_n_mot, DW_Moving_Average_Filter *localDW, + ZCE_Moving_Average_Filter *localZCE); +static void Raw_Speed_calculation(boolean_T rtu_Trigger, int16_T rtu_z_counter, + int8_T rtu_z_dir, int32_T *rty_n_motRaw, ZCE_Raw_Speed_calculation *localZCE); +static void F03_01_Pure_Trapezoidal_Method(int32_T rtu_a_elecAngleAdv, int16_T + *rty_r_phaA_Trap, int16_T *rty_r_phaB_Trap, int16_T *rty_r_phaC_Trap); +static void F03_02_Sinusoidal_Method(int32_T rtu_a_elecAngleAdv, int16_T + *rty_r_phaA_Sin, int16_T *rty_r_phaB_Sin, int16_T *rty_r_phaC_Sin); +static void F03_02_Sinusoidal3rd_Method(int32_T rtu_a_elecAngleAdv, int16_T + *rty_r_phaA_Sin3, int16_T *rty_r_phaB_Sin3, int16_T *rty_r_phaC_Sin3); +static void F02_Electrical_Angle_Ca_Disable(int32_T *rty_a_elecAngleAdv, int32_T + *rty_a_elecAngle); +static void F02_Electrical_Angle_Calculatio(int32_T rtu_r_DC, uint8_T rtu_z_pos, + int8_T rtu_z_dir, int16_T rtu_z_counter, int16_T rtu_z_counterRaw, int32_T + *rty_a_elecAngleAdv, int32_T *rty_a_elecAngle); +static void rising_edge(void); +static void rising_edge_f(void); +static uint8_T plook_u8s32u32n31_evenc_s(int32_T u, int32_T bp0, uint32_T + bpSpace, uint32_T maxIndex, uint32_T *fraction) +{ + uint8_T bpIndex; + uint32_T uAdjust; + uint32_T fbpIndex; + + /* Prelookup - Index and Fraction + Index Search method: 'even' + Extrapolation method: 'Clip' + Use previous index: 'off' + Use last breakpoint for index at or above upper limit: 'off' + Remove protection against out-of-range input in generated code: 'off' + Rounding mode: 'simplest' + */ + if (u <= bp0) { + bpIndex = 0U; + *fraction = 0U; + } else { + uAdjust = (uint32_T)u - bp0; + fbpIndex = uAdjust / bpSpace; + if (fbpIndex < maxIndex) { + bpIndex = (uint8_T)fbpIndex; + *fraction = (uint32_T)(((uint64_T)(uAdjust - bpIndex * bpSpace) << 31) / + bpSpace); + } else { + bpIndex = (uint8_T)(maxIndex - 1U); + *fraction = 2147483648U; + } + } + + return bpIndex; +} + +static int16_T intrp1d_s16s32s32u8u32n31l_s(uint8_T bpIndex, uint32_T frac, + const int16_T table[]) +{ + uint32_T offset_0d; + + /* Interpolation 1-D + Interpolation method: 'Linear' + Use last breakpoint for index at or above upper limit: 'off' + Rounding mode: 'simplest' + Overflow mode: 'wrapping' + */ + offset_0d = bpIndex; + return (int16_T)((int16_T)(((int64_T)(table[offset_0d + 1U] - table[offset_0d]) + * frac) >> 31) + table[offset_0d]); +} + +static int32_T div_nde_s32_floor(int32_T numerator, int32_T denominator) +{ + return (((numerator < 0) != (denominator < 0)) && (numerator % denominator != + 0) ? -1 : 0) + numerator / denominator; +} + +/* + * Output and update for enable system: + * '/F01_03_Direction_Detection' + * '/F01_03_Direction_Detection' + */ +static void F01_03_Direction_Detection(boolean_T rtu_Enable, uint8_T rtu_z_pos, + uint8_T rtu_z_posPrev, int8_T *rty_z_dir, int8_T *rty_z_dirPrev, + DW_F01_03_Direction_Detection *localDW) +{ + int8_T rtb_Sum2; + + /* Outputs for Enabled SubSystem: '/F01_03_Direction_Detection' incorporates: + * EnablePort: '/Enable' + */ + if (rtu_Enable) { + /* UnitDelay: '/UnitDelay1' */ + *rty_z_dirPrev = localDW->UnitDelay1_DSTATE; + + /* Sum: '/Sum2' incorporates: + * DataTypeConversion: '/Data Type Conversion1' + * DataTypeConversion: '/Data Type Conversion10' + */ + rtb_Sum2 = (int8_T)((int8_T)rtu_z_pos - (int8_T)rtu_z_posPrev); + + /* Switch: '/Switch2' incorporates: + * Constant: '/Constant20' + * Constant: '/Constant23' + * Constant: '/Constant24' + * Constant: '/Constant8' + * Logic: '/Logical Operator3' + * RelationalOperator: '/Relational Operator1' + * RelationalOperator: '/Relational Operator6' + */ + if ((rtb_Sum2 == 1) || (rtb_Sum2 == -5)) { + *rty_z_dir = 1; + } else { + *rty_z_dir = -1; + } + + /* End of Switch: '/Switch2' */ + + /* Update for UnitDelay: '/UnitDelay1' */ + localDW->UnitDelay1_DSTATE = *rty_z_dir; + } + + /* End of Outputs for SubSystem: '/F01_03_Direction_Detection' */ +} + +/* + * System reset for enable system: + * '/Edge_counter' + * '/Edge_counter' + */ +static void Edge_counter_Reset(DW_Edge_counter *localDW) +{ + /* InitializeConditions for UnitDelay: '/UnitDelay1' */ + localDW->UnitDelay1_DSTATE = 0U; +} + +/* + * Disable for enable system: + * '/Edge_counter' + * '/Edge_counter' + */ +static void Edge_counter_Disable(uint8_T *rty_cnt, DW_Edge_counter *localDW) +{ + /* Outputs for Enabled SubSystem: '/Edge_counter' incorporates: + * EnablePort: '/Enable' + */ + /* Disable for Outport: '/cnt' */ + *rty_cnt = 0U; + + /* End of Outputs for SubSystem: '/Edge_counter' */ + localDW->Edge_counter_MODE = false; +} + +/* + * Output and update for enable system: + * '/Edge_counter' + * '/Edge_counter' + */ +static void Edge_counter(boolean_T rtu_Enable, boolean_T rtu_b_edge, int8_T + rtu_z_dir, int8_T rtu_z_dirPrev, uint8_T *rty_cnt, DW_Edge_counter *localDW) +{ + boolean_T rtb_RelationalOperator1_i; + uint8_T rtb_RelationalOperator1_m1; + + /* Outputs for Enabled SubSystem: '/Edge_counter' incorporates: + * EnablePort: '/Enable' + */ + if (rtu_Enable) { + if (!localDW->Edge_counter_MODE) { + Edge_counter_Reset(localDW); + localDW->Edge_counter_MODE = true; + } + + /* RelationalOperator: '/Relational Operator1' */ + rtb_RelationalOperator1_i = (rtu_z_dir == rtu_z_dirPrev); + + /* Switch: '/Switch1' incorporates: + * Constant: '/Constant23' + * Logic: '/Logical Operator2' + * UnitDelay: '/UnitDelay1' + */ + if (!rtb_RelationalOperator1_i) { + rtb_RelationalOperator1_m1 = 0U; + } else { + rtb_RelationalOperator1_m1 = localDW->UnitDelay1_DSTATE; + } + + /* End of Switch: '/Switch1' */ + + /* Sum: '/Sum2' incorporates: + * Logic: '/Logical Operator1' + */ + *rty_cnt = (uint8_T)((uint32_T)(rtu_b_edge && rtb_RelationalOperator1_i) + + rtb_RelationalOperator1_m1); + + /* Update for UnitDelay: '/UnitDelay1' */ + localDW->UnitDelay1_DSTATE = *rty_cnt; + } else { + if (localDW->Edge_counter_MODE) { + Edge_counter_Disable(rty_cnt, localDW); + } + } + + /* End of Outputs for SubSystem: '/Edge_counter' */ +} + +/* + * Output and update for trigger system: + * '/Moving_Average_Filter' + * '/Moving_Average_Filter' + */ +static void Moving_Average_Filter(boolean_T rtu_Trigger, int32_T rtu_n_motRaw, + int32_T *rty_n_mot, DW_Moving_Average_Filter *localDW, + ZCE_Moving_Average_Filter *localZCE) +{ + int32_T rtb_UnitDelay1_f; + + /* Outputs for Triggered SubSystem: '/Moving_Average_Filter' incorporates: + * TriggerPort: '/Trigger' + */ + if (rtu_Trigger && (localZCE->Moving_Average_Filter_Trig_ZCE != POS_ZCSIG)) { + /* UnitDelay: '/UnitDelay1' */ + rtb_UnitDelay1_f = localDW->UnitDelay1_DSTATE; + + /* Product: '/Divide4' incorporates: + * Constant: '/Constant1' + * Sum: '/Sum2' + * UnitDelay: '/UnitDelay5' + */ + *rty_n_mot = ((localDW->UnitDelay5_DSTATE + rtb_UnitDelay1_f) + rtu_n_motRaw) + / 3; + + /* Update for UnitDelay: '/UnitDelay5' */ + localDW->UnitDelay5_DSTATE = rtb_UnitDelay1_f; + + /* Update for UnitDelay: '/UnitDelay1' */ + localDW->UnitDelay1_DSTATE = rtu_n_motRaw; + } + + localZCE->Moving_Average_Filter_Trig_ZCE = rtu_Trigger; + + /* End of Outputs for SubSystem: '/Moving_Average_Filter' */ +} + +/* + * Output and update for trigger system: + * '/Raw_ Speed_calculation' + * '/Raw_ Speed_calculation' + */ +static void Raw_Speed_calculation(boolean_T rtu_Trigger, int16_T rtu_z_counter, + int8_T rtu_z_dir, int32_T *rty_n_motRaw, ZCE_Raw_Speed_calculation *localZCE) +{ + int32_T rtb_Switch_p; + + /* Outputs for Triggered SubSystem: '/Raw_ Speed_calculation' incorporates: + * TriggerPort: '/Trigger' + */ + if (rtu_Trigger && (localZCE->Raw_Speed_calculation_Trig_ZCE != POS_ZCSIG)) { + /* Switch: '/Switch' incorporates: + * Constant: '/Constant1' + * Constant: '/cf_spdCoef' + * Constant: '/z_maxCntRst' + * Product: '/Divide4' + * RelationalOperator: '/Relational Operator1' + */ + if (rtu_z_counter > rtP.z_maxCntRst) { + rtb_Switch_p = 0; + } else { + rtb_Switch_p = rtP.cf_spdCoef / rtu_z_counter; + } + + /* End of Switch: '/Switch' */ + + /* Product: '/Product2' */ + *rty_n_motRaw = rtb_Switch_p * rtu_z_dir; + } + + localZCE->Raw_Speed_calculation_Trig_ZCE = rtu_Trigger; + + /* End of Outputs for SubSystem: '/Raw_ Speed_calculation' */ +} + +/* Output and update for atomic system: '/rising_edge' */ +static void rising_edge(void) +{ + /* Logic: '/Logical Operator' incorporates: + * Logic: '/Logical Operator1' + * UnitDelay: '/UnitDelay' + */ + rtDW.LogicalOperator = (rtDW.RelationalOperator4 && (!rtDW.UnitDelay_DSTATE_l)); + + /* Update for UnitDelay: '/UnitDelay' */ + rtDW.UnitDelay_DSTATE_l = rtDW.RelationalOperator4; +} + +/* + * Output and update for action system: + * '/F03_01_Pure_Trapezoidal_Method' + * '/F03_01_Pure_Trapezoidal_Method' + */ +static void F03_01_Pure_Trapezoidal_Method(int32_T rtu_a_elecAngleAdv, int16_T + *rty_r_phaA_Trap, int16_T *rty_r_phaB_Trap, int16_T *rty_r_phaC_Trap) +{ + uint8_T rtb_a_trapElecAngle_XA_o1; + uint32_T rtb_a_trapElecAngle_XA_o2; + + /* PreLookup: '/a_trapElecAngle_XA' */ + rtb_a_trapElecAngle_XA_o1 = plook_u8s32u32n31_evenc_s(rtu_a_elecAngleAdv, 0, + 60U, 6U, &rtb_a_trapElecAngle_XA_o2); + + /* Interpolation_n-D: '/r_trapPhaA_M1' */ + *rty_r_phaA_Trap = intrp1d_s16s32s32u8u32n31l_s(rtb_a_trapElecAngle_XA_o1, + rtb_a_trapElecAngle_XA_o2, rtConstP.pooled8); + + /* Interpolation_n-D: '/r_trapPhaB_M1' */ + *rty_r_phaB_Trap = intrp1d_s16s32s32u8u32n31l_s(rtb_a_trapElecAngle_XA_o1, + rtb_a_trapElecAngle_XA_o2, rtConstP.pooled9); + + /* Interpolation_n-D: '/r_trapPhaC_M1' */ + *rty_r_phaC_Trap = intrp1d_s16s32s32u8u32n31l_s(rtb_a_trapElecAngle_XA_o1, + rtb_a_trapElecAngle_XA_o2, rtConstP.pooled10); +} + +/* + * Output and update for action system: + * '/F03_02_Sinusoidal_Method' + * '/F03_02_Sinusoidal_Method' + */ +static void F03_02_Sinusoidal_Method(int32_T rtu_a_elecAngleAdv, int16_T + *rty_r_phaA_Sin, int16_T *rty_r_phaB_Sin, int16_T *rty_r_phaC_Sin) +{ + uint8_T rtb_a_sinElecAngle_XA_o1; + uint32_T rtb_a_sinElecAngle_XA_o2; + + /* PreLookup: '/a_sinElecAngle_XA' */ + rtb_a_sinElecAngle_XA_o1 = plook_u8s32u32n31_evenc_s(rtu_a_elecAngleAdv, 0, + 10U, 36U, &rtb_a_sinElecAngle_XA_o2); + + /* Interpolation_n-D: '/r_sinPhaA_M1' */ + *rty_r_phaA_Sin = intrp1d_s16s32s32u8u32n31l_s(rtb_a_sinElecAngle_XA_o1, + rtb_a_sinElecAngle_XA_o2, rtConstP.pooled11); + + /* Interpolation_n-D: '/r_sinPhaB_M1' */ + *rty_r_phaB_Sin = intrp1d_s16s32s32u8u32n31l_s(rtb_a_sinElecAngle_XA_o1, + rtb_a_sinElecAngle_XA_o2, rtConstP.pooled12); + + /* Interpolation_n-D: '/r_sinPhaC_M1' */ + *rty_r_phaC_Sin = intrp1d_s16s32s32u8u32n31l_s(rtb_a_sinElecAngle_XA_o1, + rtb_a_sinElecAngle_XA_o2, rtConstP.pooled13); +} + +/* + * Output and update for action system: + * '/F03_02_Sinusoidal3rd_Method' + * '/F03_02_Sinusoidal3rd_Method' + */ +static void F03_02_Sinusoidal3rd_Method(int32_T rtu_a_elecAngleAdv, int16_T + *rty_r_phaA_Sin3, int16_T *rty_r_phaB_Sin3, int16_T *rty_r_phaC_Sin3) +{ + uint8_T rtb_a_sinElecAngle_XA_o1; + uint32_T rtb_a_sinElecAngle_XA_o2; + + /* PreLookup: '/a_sinElecAngle_XA' */ + rtb_a_sinElecAngle_XA_o1 = plook_u8s32u32n31_evenc_s(rtu_a_elecAngleAdv, 0, + 10U, 36U, &rtb_a_sinElecAngle_XA_o2); + + /* Interpolation_n-D: '/r_sin3PhaA_M1' */ + *rty_r_phaA_Sin3 = intrp1d_s16s32s32u8u32n31l_s(rtb_a_sinElecAngle_XA_o1, + rtb_a_sinElecAngle_XA_o2, rtConstP.pooled14); + + /* Interpolation_n-D: '/r_sin3PhaB_M1' */ + *rty_r_phaB_Sin3 = intrp1d_s16s32s32u8u32n31l_s(rtb_a_sinElecAngle_XA_o1, + rtb_a_sinElecAngle_XA_o2, rtConstP.pooled15); + + /* Interpolation_n-D: '/r_sin3PhaC_M1' */ + *rty_r_phaC_Sin3 = intrp1d_s16s32s32u8u32n31l_s(rtb_a_sinElecAngle_XA_o1, + rtb_a_sinElecAngle_XA_o2, rtConstP.pooled16); +} + +/* + * Disable for action system: + * '/F02_Electrical_Angle_Calculation' + * '/F02_Electrical_Angle_Calculation' + */ +static void F02_Electrical_Angle_Ca_Disable(int32_T *rty_a_elecAngleAdv, int32_T + *rty_a_elecAngle) +{ + /* Disable for Outport: '/a_elecAngleAdv' */ + *rty_a_elecAngleAdv = 0; + + /* Disable for Outport: '/a_elecAngle' */ + *rty_a_elecAngle = 0; +} + +/* + * Output and update for action system: + * '/F02_Electrical_Angle_Calculation' + * '/F02_Electrical_Angle_Calculation' + */ +static void F02_Electrical_Angle_Calculatio(int32_T rtu_r_DC, uint8_T rtu_z_pos, + int8_T rtu_z_dir, int16_T rtu_z_counter, int16_T rtu_z_counterRaw, int32_T + *rty_a_elecAngleAdv, int32_T *rty_a_elecAngle) +{ + uint8_T rtb_Switch3; + int32_T rtb_Sum3_e; + int16_T rtb_a_phaAdv_M2; + uint32_T rtb_r_phaAdvDC_XA_o2; + + /* Switch: '/Switch3' incorporates: + * Constant: '/Constant16' + * RelationalOperator: '/Relational Operator7' + * Sum: '/Sum1' + */ + if (rtu_z_dir == 1) { + rtb_Switch3 = rtu_z_pos; + } else { + rtb_Switch3 = (uint8_T)(rtu_z_pos + 1U); + } + + /* End of Switch: '/Switch3' */ + + /* Sum: '/Sum2' incorporates: + * Product: '/Divide4' + * Product: '/Divide5' + * Product: '/Product6' + */ + *rty_a_elecAngle = 60 * rtu_z_counterRaw / rtu_z_counter * rtu_z_dir + + rtb_Switch3 * 60; + + /* Switch: '/Switch_PhaAdv' incorporates: + * Constant: '/a_elecPeriod1' + * Constant: '/a_elecPeriod2' + * Product: '/Divide2' + * Product: '/Divide3' + * Sum: '/Sum3' + */ + if (rtP.b_phaAdvEna) { + /* Abs: '/Abs2' */ + if (rtu_r_DC < 0) { + rtb_Sum3_e = -rtu_r_DC; + } else { + rtb_Sum3_e = rtu_r_DC; + } + + /* End of Abs: '/Abs2' */ + + /* PreLookup: '/r_phaAdvDC_XA' */ + rtb_Switch3 = plook_u8s32u32n31_evenc_s(rtb_Sum3_e, rtP.r_phaAdvDC_XA[0], + (uint32_T)rtP.r_phaAdvDC_XA[1] - rtP.r_phaAdvDC_XA[0], 10U, + &rtb_r_phaAdvDC_XA_o2); + + /* Interpolation_n-D: '/a_phaAdv_M2' */ + rtb_a_phaAdv_M2 = intrp1d_s16s32s32u8u32n31l_s(rtb_Switch3, + rtb_r_phaAdvDC_XA_o2, rtP.a_phaAdv_M1); + + /* Sum: '/Sum3' incorporates: + * Product: '/Product2' + */ + rtb_Sum3_e = rtu_z_dir * rtb_a_phaAdv_M2 + *rty_a_elecAngle; + *rty_a_elecAngleAdv = rtb_Sum3_e - div_nde_s32_floor(rtb_Sum3_e, 360) * 360; + } else { + *rty_a_elecAngleAdv = *rty_a_elecAngle; + } + + /* End of Switch: '/Switch_PhaAdv' */ +} + +/* Output and update for atomic system: '/rising_edge' */ +static void rising_edge_f(void) +{ + /* Logic: '/Logical Operator' incorporates: + * Logic: '/Logical Operator1' + * UnitDelay: '/UnitDelay' + */ + rtDW.LogicalOperator = (rtDW.RelationalOperator4 && (!rtDW.UnitDelay_DSTATE_k)); + + /* Update for UnitDelay: '/UnitDelay' */ + rtDW.UnitDelay_DSTATE_k = rtDW.RelationalOperator4; +} + +/* Model step function */ +void BLDC_controller_step(void) +{ + int32_T rowIdx; + uint8_T rtb_Sum; + boolean_T rtb_LogicalOperator; + boolean_T rtb_LogicalOperator3; + int32_T rtb_Abs1; + int8_T rtPrevAction; + int8_T rtAction; + uint8_T rtb_Sum_a; + int16_T rtb_Switch; + int16_T rtb_Switch_b; + int16_T rtb_Sum1; + int16_T rtb_Sum1_c; + int32_T rtb_Switch1_idx_0; + int32_T rtb_Switch1_idx_1; + boolean_T rtb_Logic_idx_0; + uint8_T tmp; + + /* Outputs for Atomic SubSystem: '/BLDC_controller' */ + /* Sum: '/Sum' incorporates: + * Gain: '/g_Ha' + * Gain: '/g_Hb' + * Inport: '/b_hallALeft ' + * Inport: '/b_hallBLeft' + * Inport: '/b_hallCLeft' + */ + rtb_Sum = (uint8_T)((uint32_T)(uint8_T)((uint32_T)(uint8_T)(rtU.b_hallALeft << + 2) + (uint8_T)(rtU.b_hallBLeft << 1)) + rtU.b_hallCLeft); + + /* Logic: '/Logical Operator' incorporates: + * Inport: '/b_hallALeft ' + * Inport: '/b_hallBLeft' + * Inport: '/b_hallCLeft' + * UnitDelay: '/UnitDelay' + * UnitDelay: '/UnitDelay1' + * UnitDelay: '/UnitDelay2' + */ + rtb_LogicalOperator = (boolean_T)((rtU.b_hallALeft != 0) ^ (rtU.b_hallBLeft != + 0) ^ (rtU.b_hallCLeft != 0) ^ (rtDW.UnitDelay_DSTATE != 0) ^ + (rtDW.UnitDelay1_DSTATE_p != 0)) ^ (rtDW.UnitDelay2_DSTATE != 0); + + /* Logic: '/Logical Operator3' incorporates: + * Constant: '/z_maxCntRst' + * RelationalOperator: '/Relational Operator1' + * UnitDelay: '/z_counterRawPrev' + */ + rtb_LogicalOperator3 = (rtb_LogicalOperator || (rtDW.z_counterRawPrev_DSTATE > + rtP.z_maxCntRst)); + + /* Outputs for Enabled SubSystem: '/F01_03_Direction_Detection' */ + + /* Selector: '/Selector' incorporates: + * Constant: '/vec_hallToPos' + * UnitDelay: '/UnitDelay1' + */ + F01_03_Direction_Detection(rtb_LogicalOperator, rtConstP.pooled27[rtb_Sum], + rtDW.UnitDelay1_DSTATE_g, &rtDW.Switch2_e, &rtDW.UnitDelay1_k, + &rtDW.F01_03_Direction_Detection_o); + + /* End of Outputs for SubSystem: '/F01_03_Direction_Detection' */ + + /* Outputs for Enabled SubSystem: '/Edge_counter' */ + + /* Logic: '/Logical Operator2' incorporates: + * UnitDelay: '/UnitDelay8' + */ + Edge_counter(!rtDW.UnitDelay8_DSTATE, rtb_LogicalOperator, rtDW.Switch2_e, + rtDW.UnitDelay1_k, &rtDW.Sum2_l, &rtDW.Edge_counter_f); + + /* End of Outputs for SubSystem: '/Edge_counter' */ + + /* Abs: '/Abs4' incorporates: + * UnitDelay: '/UnitDelay10' + */ + if (rtDW.rpm_signed_c < 0) { + rtb_Switch1_idx_0 = -rtDW.rpm_signed_c; + } else { + rtb_Switch1_idx_0 = rtDW.rpm_signed_c; + } + + /* End of Abs: '/Abs4' */ + + /* RelationalOperator: '/Relational Operator4' incorporates: + * Constant: '/n_thresSpdDeacv' + */ + rtDW.RelationalOperator4 = (rtb_Switch1_idx_0 < rtP.n_thresSpdDeacv); + + /* Outputs for Atomic SubSystem: '/rising_edge' */ + rising_edge(); + + /* End of Outputs for SubSystem: '/rising_edge' */ + + /* CombinatorialLogic: '/Logic' incorporates: + * Constant: '/z_nrEdgeSpdAcv' + * Memory: '/Memory' + * RelationalOperator: '/Relational Operator5' + */ + rowIdx = (int32_T)(((((uint32_T)(rtDW.Sum2_l >= rtP.z_nrEdgeSpdAcv) << 1) + + rtDW.LogicalOperator) << 1) + rtDW.Memory_PreviousInput); + rtb_Logic_idx_0 = rtConstP.pooled31[(uint32_T)rowIdx]; + + /* Switch: '/Switch' incorporates: + * CombinatorialLogic: '/Logic' + * Logic: '/Logical Operator1' + * UnitDelay: '/z_counter2' + * UnitDelay: '/z_counterRawPrev' + */ + if (rtb_LogicalOperator3 && rtConstP.pooled31[(uint32_T)rowIdx]) { + rtb_Switch = rtDW.z_counterRawPrev_DSTATE; + } else { + rtb_Switch = rtDW.z_counter2_DSTATE; + } + + /* End of Switch: '/Switch' */ + + /* Outputs for Triggered SubSystem: '/Raw_ Speed_calculation' */ + Raw_Speed_calculation(rtb_LogicalOperator3, rtb_Switch, rtDW.Switch2_e, + &rtDW.rpm_signed_c, &rtPrevZCX.Raw_Speed_calculation_m); + + /* End of Outputs for SubSystem: '/Raw_ Speed_calculation' */ + + /* Outputs for Triggered SubSystem: '/Moving_Average_Filter' */ + + /* Outport: '/n_motLeft' */ + Moving_Average_Filter(rtb_LogicalOperator3, rtDW.rpm_signed_c, &rtY.n_motLeft, + &rtDW.Moving_Average_Filter_l, + &rtPrevZCX.Moving_Average_Filter_l); + + /* End of Outputs for SubSystem: '/Moving_Average_Filter' */ + + /* Abs: '/Abs5' incorporates: + * Outport: '/n_motLeft' + */ + if (rtY.n_motLeft < 0) { + rtb_Abs1 = -rtY.n_motLeft; + } else { + rtb_Abs1 = rtY.n_motLeft; + } + + /* End of Abs: '/Abs5' */ + + /* Relay: '/Relay' */ + if (rtb_Abs1 >= rtP.n_commDeacvHi) { + rtDW.Relay_Mode = true; + } else { + if (rtb_Abs1 <= rtP.n_commAcvLo) { + rtDW.Relay_Mode = false; + } + } + + /* Switch: '/Switch1' incorporates: + * Constant: '/Constant23' + * UnitDelay: '/UnitDelay1' + */ + if (rtb_LogicalOperator3) { + rtb_Sum1_c = 0; + } else { + rtb_Sum1_c = rtDW.UnitDelay1_DSTATE; + } + + /* End of Switch: '/Switch1' */ + + /* Sum: '/Sum1' */ + rtb_Sum1 = (int16_T)(1 + rtb_Sum1_c); + + /* If: '/If1' incorporates: + * Constant: '/z_ctrlTypSel1' + * Constant: '/vec_hallToPos' + * Inport: '/r_DCLeft' + * Outport: '/a_elecAngleLeft' + * Selector: '/Selector' + */ + rtPrevAction = rtDW.If1_ActiveSubsystem; + rtAction = -1; + if (rtP.z_ctrlTypSel != 0) { + rtAction = 0; + } + + rtDW.If1_ActiveSubsystem = rtAction; + if ((rtPrevAction != rtAction) && (rtPrevAction == 0)) { + F02_Electrical_Angle_Ca_Disable(&rtDW.Switch_PhaAdv_a, &rtY.a_elecAngleLeft); + } + + if (rtAction == 0) { + /* Outputs for IfAction SubSystem: '/F02_Electrical_Angle_Calculation' incorporates: + * ActionPort: '/Action Port' + */ + F02_Electrical_Angle_Calculatio(rtU.r_DCLeft, rtConstP.pooled27[rtb_Sum], + rtDW.Switch2_e, rtb_Switch, rtb_Sum1, &rtDW.Switch_PhaAdv_a, + &rtY.a_elecAngleLeft); + + /* End of Outputs for SubSystem: '/F02_Electrical_Angle_Calculation' */ + } + + /* End of If: '/If1' */ + + /* SwitchCase: '/Switch Case' incorporates: + * Constant: '/z_ctrlTypSel1' + */ + switch (rtP.z_ctrlTypSel) { + case 1: + /* Outputs for IfAction SubSystem: '/F03_01_Pure_Trapezoidal_Method' incorporates: + * ActionPort: '/Action Port' + */ + F03_01_Pure_Trapezoidal_Method(rtDW.Switch_PhaAdv_a, &rtDW.Merge, + &rtDW.Merge1, &rtDW.Merge2); + + /* End of Outputs for SubSystem: '/F03_01_Pure_Trapezoidal_Method' */ + break; + + case 2: + /* Outputs for IfAction SubSystem: '/F03_02_Sinusoidal_Method' incorporates: + * ActionPort: '/Action Port' + */ + F03_02_Sinusoidal_Method(rtDW.Switch_PhaAdv_a, &rtDW.Merge, &rtDW.Merge1, + &rtDW.Merge2); + + /* End of Outputs for SubSystem: '/F03_02_Sinusoidal_Method' */ + break; + + case 3: + /* Outputs for IfAction SubSystem: '/F03_02_Sinusoidal3rd_Method' incorporates: + * ActionPort: '/Action Port' + */ + F03_02_Sinusoidal3rd_Method(rtDW.Switch_PhaAdv_a, &rtDW.Merge, &rtDW.Merge1, + &rtDW.Merge2); + + /* End of Outputs for SubSystem: '/F03_02_Sinusoidal3rd_Method' */ + break; + } + + /* End of SwitchCase: '/Switch Case' */ + + /* Abs: '/Abs1' incorporates: + * Inport: '/r_DCLeft' + */ + if (rtU.r_DCLeft < 0) { + rtb_Switch1_idx_0 = -rtU.r_DCLeft; + } else { + rtb_Switch1_idx_0 = rtU.r_DCLeft; + } + + /* End of Abs: '/Abs1' */ + + /* Switch: '/Switch1' incorporates: + * Constant: '/z_ctrlTypSel1' + * Constant: '/CTRL_COMM' + * Constant: '/r_commDCDeacv' + * Constant: '/vec_hallToPos' + * Inport: '/r_DCLeft' + * Logic: '/Logical Operator3' + * LookupNDDirect: '/z_commutMap_M1' + * Product: '/Divide2' + * Product: '/Divide4' + * RelationalOperator: '/Relational Operator1' + * RelationalOperator: '/Relational Operator2' + * Relay: '/Relay' + * Selector: '/Selector' + * + * About '/z_commutMap_M1': + * 2-dimensional Direct Look-Up returning a Column + */ + if (rtDW.Relay_Mode && (rtb_Switch1_idx_0 > rtP.r_commDCDeacv) && + (rtP.z_ctrlTypSel != 0)) { + rtb_Switch1_idx_0 = rtU.r_DCLeft * rtDW.Merge; + rtb_Switch1_idx_1 = rtU.r_DCLeft * rtDW.Merge1; + rtb_Abs1 = rtU.r_DCLeft * rtDW.Merge2; + } else { + if (rtConstP.pooled27[rtb_Sum] < 5) { + /* LookupNDDirect: '/z_commutMap_M1' incorporates: + * Constant: '/vec_hallToPos' + * Selector: '/Selector' + * + * About '/z_commutMap_M1': + * 2-dimensional Direct Look-Up returning a Column + */ + tmp = rtConstP.pooled27[rtb_Sum]; + } else { + /* LookupNDDirect: '/z_commutMap_M1' + * + * About '/z_commutMap_M1': + * 2-dimensional Direct Look-Up returning a Column + */ + tmp = 5U; + } + + /* LookupNDDirect: '/z_commutMap_M1' + * + * About '/z_commutMap_M1': + * 2-dimensional Direct Look-Up returning a Column + */ + rtb_Abs1 = tmp * 3; + rtb_Switch1_idx_0 = rtU.r_DCLeft * rtConstP.pooled17[rtb_Abs1]; + rtb_Switch1_idx_1 = rtConstP.pooled17[1 + rtb_Abs1] * rtU.r_DCLeft; + rtb_Abs1 = rtConstP.pooled17[2 + rtb_Abs1] * rtU.r_DCLeft; + } + + /* End of Switch: '/Switch1' */ + + /* Outport: '/DC_phaALeft' incorporates: + * Constant: '/Constant1' + * Product: '/Divide1' + */ + rtY.DC_phaALeft = rtb_Switch1_idx_0 / 1000; + + /* Outport: '/DC_phaBLeft' incorporates: + * Constant: '/Constant1' + * Product: '/Divide1' + */ + rtY.DC_phaBLeft = rtb_Switch1_idx_1 / 1000; + + /* Outport: '/DC_phaCLeft' incorporates: + * Constant: '/Constant1' + * Product: '/Divide1' + */ + rtY.DC_phaCLeft = rtb_Abs1 / 1000; + + /* Sum: '/Sum' incorporates: + * Gain: '/g_Ha' + * Gain: '/g_Hb' + * Inport: '/b_hallARight' + * Inport: '/b_hallBRight' + * Inport: '/b_hallCRight' + */ + rtb_Sum_a = (uint8_T)((uint32_T)(uint8_T)((uint32_T)(uint8_T)(rtU.b_hallARight + << 2) + (uint8_T)(rtU.b_hallBRight << 1)) + rtU.b_hallCRight); + + /* Logic: '/Logical Operator' incorporates: + * Inport: '/b_hallARight' + * Inport: '/b_hallBRight' + * Inport: '/b_hallCRight' + * UnitDelay: '/UnitDelay' + * UnitDelay: '/UnitDelay1' + * UnitDelay: '/UnitDelay2' + */ + rtb_LogicalOperator = (boolean_T)((rtU.b_hallARight != 0) ^ (rtU.b_hallBRight + != 0) ^ (rtU.b_hallCRight != 0) ^ (rtDW.UnitDelay_DSTATE_j != 0) ^ + (rtDW.UnitDelay1_DSTATE_f != 0)) ^ (rtDW.UnitDelay2_DSTATE_b != 0); + + /* Logic: '/Logical Operator3' incorporates: + * Constant: '/z_maxCntRst' + * RelationalOperator: '/Relational Operator1' + * UnitDelay: '/z_counterRawPrev' + */ + rtb_LogicalOperator3 = (rtb_LogicalOperator || (rtDW.z_counterRawPrev_DSTATE_p + > rtP.z_maxCntRst)); + + /* Outputs for Enabled SubSystem: '/F01_03_Direction_Detection' */ + + /* Selector: '/Selector' incorporates: + * Constant: '/vec_hallToPos' + * UnitDelay: '/UnitDelay1' + */ + F01_03_Direction_Detection(rtb_LogicalOperator, rtConstP.pooled27[rtb_Sum_a], + rtDW.UnitDelay1_DSTATE_j, &rtDW.Switch2, &rtDW.UnitDelay1, + &rtDW.F01_03_Direction_Detection_j); + + /* End of Outputs for SubSystem: '/F01_03_Direction_Detection' */ + + /* Outputs for Enabled SubSystem: '/Edge_counter' */ + + /* Logic: '/Logical Operator2' incorporates: + * UnitDelay: '/UnitDelay8' + */ + Edge_counter(!rtDW.UnitDelay8_DSTATE_p, rtb_LogicalOperator, rtDW.Switch2, + rtDW.UnitDelay1, &rtDW.Sum2_i, &rtDW.Edge_counter_l); + + /* End of Outputs for SubSystem: '/Edge_counter' */ + + /* Abs: '/Abs4' incorporates: + * UnitDelay: '/UnitDelay10' + */ + if (rtDW.rpm_signed < 0) { + rtb_Switch1_idx_0 = -rtDW.rpm_signed; + } else { + rtb_Switch1_idx_0 = rtDW.rpm_signed; + } + + /* End of Abs: '/Abs4' */ + + /* RelationalOperator: '/Relational Operator4' incorporates: + * Constant: '/n_thresSpdDeacv' + */ + rtDW.RelationalOperator4 = (rtb_Switch1_idx_0 < rtP.n_thresSpdDeacv); + + /* Outputs for Atomic SubSystem: '/rising_edge' */ + rising_edge_f(); + + /* End of Outputs for SubSystem: '/rising_edge' */ + + /* CombinatorialLogic: '/Logic' incorporates: + * Constant: '/z_nrEdgeSpdAcv' + * Memory: '/Memory' + * RelationalOperator: '/Relational Operator5' + */ + rowIdx = (int32_T)(((((uint32_T)(rtDW.Sum2_i >= rtP.z_nrEdgeSpdAcv) << 1) + + rtDW.LogicalOperator) << 1) + rtDW.Memory_PreviousInput_i); + + /* Switch: '/Switch' incorporates: + * CombinatorialLogic: '/Logic' + * Logic: '/Logical Operator1' + * UnitDelay: '/z_counter2' + * UnitDelay: '/z_counterRawPrev' + */ + if (rtb_LogicalOperator3 && rtConstP.pooled31[(uint32_T)rowIdx]) { + rtb_Switch_b = rtDW.z_counterRawPrev_DSTATE_p; + } else { + rtb_Switch_b = rtDW.z_counter2_DSTATE_h; + } + + /* End of Switch: '/Switch' */ + + /* Outputs for Triggered SubSystem: '/Raw_ Speed_calculation' */ + Raw_Speed_calculation(rtb_LogicalOperator3, rtb_Switch_b, rtDW.Switch2, + &rtDW.rpm_signed, &rtPrevZCX.Raw_Speed_calculation_k); + + /* End of Outputs for SubSystem: '/Raw_ Speed_calculation' */ + + /* Outputs for Triggered SubSystem: '/Moving_Average_Filter' */ + + /* Outport: '/n_motRight' */ + Moving_Average_Filter(rtb_LogicalOperator3, rtDW.rpm_signed, &rtY.n_motRight, + &rtDW.Moving_Average_Filter_n, + &rtPrevZCX.Moving_Average_Filter_n); + + /* End of Outputs for SubSystem: '/Moving_Average_Filter' */ + + /* Abs: '/Abs5' incorporates: + * Outport: '/n_motRight' + */ + if (rtY.n_motRight < 0) { + rtb_Abs1 = -rtY.n_motRight; + } else { + rtb_Abs1 = rtY.n_motRight; + } + + /* End of Abs: '/Abs5' */ + + /* Relay: '/Relay' */ + if (rtb_Abs1 >= rtP.n_commDeacvHi) { + rtDW.Relay_Mode_m = true; + } else { + if (rtb_Abs1 <= rtP.n_commAcvLo) { + rtDW.Relay_Mode_m = false; + } + } + + /* Switch: '/Switch1' incorporates: + * Constant: '/Constant23' + * UnitDelay: '/UnitDelay1' + */ + if (rtb_LogicalOperator3) { + rtb_Sum1_c = 0; + } else { + rtb_Sum1_c = rtDW.UnitDelay1_DSTATE_k; + } + + /* End of Switch: '/Switch1' */ + + /* Sum: '/Sum1' */ + rtb_Sum1_c++; + + /* If: '/If1' incorporates: + * Constant: '/z_ctrlTypSel1' + * Constant: '/vec_hallToPos' + * Inport: '/r_DCRight' + * Outport: '/a_elecAngleRight' + * Selector: '/Selector' + */ + rtPrevAction = rtDW.If1_ActiveSubsystem_j; + rtAction = -1; + if (rtP.z_ctrlTypSel != 0) { + rtAction = 0; + } + + rtDW.If1_ActiveSubsystem_j = rtAction; + if ((rtPrevAction != rtAction) && (rtPrevAction == 0)) { + F02_Electrical_Angle_Ca_Disable(&rtDW.Switch_PhaAdv, &rtY.a_elecAngleRight); + } + + if (rtAction == 0) { + /* Outputs for IfAction SubSystem: '/F02_Electrical_Angle_Calculation' incorporates: + * ActionPort: '/Action Port' + */ + F02_Electrical_Angle_Calculatio(rtU.r_DCRight, rtConstP.pooled27[rtb_Sum_a], + rtDW.Switch2, rtb_Switch_b, rtb_Sum1_c, &rtDW.Switch_PhaAdv, + &rtY.a_elecAngleRight); + + /* End of Outputs for SubSystem: '/F02_Electrical_Angle_Calculation' */ + } + + /* End of If: '/If1' */ + + /* SwitchCase: '/Switch Case' incorporates: + * Constant: '/z_ctrlTypSel1' + */ + switch (rtP.z_ctrlTypSel) { + case 1: + /* Outputs for IfAction SubSystem: '/F03_01_Pure_Trapezoidal_Method' incorporates: + * ActionPort: '/Action Port' + */ + F03_01_Pure_Trapezoidal_Method(rtDW.Switch_PhaAdv, &rtDW.Merge_j, + &rtDW.Merge1_m, &rtDW.Merge2_d); + + /* End of Outputs for SubSystem: '/F03_01_Pure_Trapezoidal_Method' */ + break; + + case 2: + /* Outputs for IfAction SubSystem: '/F03_02_Sinusoidal_Method' incorporates: + * ActionPort: '/Action Port' + */ + F03_02_Sinusoidal_Method(rtDW.Switch_PhaAdv, &rtDW.Merge_j, &rtDW.Merge1_m, + &rtDW.Merge2_d); + + /* End of Outputs for SubSystem: '/F03_02_Sinusoidal_Method' */ + break; + + case 3: + /* Outputs for IfAction SubSystem: '/F03_02_Sinusoidal3rd_Method' incorporates: + * ActionPort: '/Action Port' + */ + F03_02_Sinusoidal3rd_Method(rtDW.Switch_PhaAdv, &rtDW.Merge_j, + &rtDW.Merge1_m, &rtDW.Merge2_d); + + /* End of Outputs for SubSystem: '/F03_02_Sinusoidal3rd_Method' */ + break; + } + + /* End of SwitchCase: '/Switch Case' */ + + /* Abs: '/Abs1' incorporates: + * Inport: '/r_DCRight' + */ + if (rtU.r_DCRight < 0) { + rtb_Switch1_idx_0 = -rtU.r_DCRight; + } else { + rtb_Switch1_idx_0 = rtU.r_DCRight; + } + + /* End of Abs: '/Abs1' */ + + /* Switch: '/Switch1' incorporates: + * Constant: '/z_ctrlTypSel1' + * Constant: '/CTRL_COMM' + * Constant: '/r_commDCDeacv' + * Constant: '/vec_hallToPos' + * Inport: '/r_DCRight' + * Logic: '/Logical Operator3' + * LookupNDDirect: '/z_commutMap_M1' + * Product: '/Divide2' + * Product: '/Divide4' + * RelationalOperator: '/Relational Operator1' + * RelationalOperator: '/Relational Operator2' + * Relay: '/Relay' + * Selector: '/Selector' + * + * About '/z_commutMap_M1': + * 2-dimensional Direct Look-Up returning a Column + */ + if (rtDW.Relay_Mode_m && (rtb_Switch1_idx_0 > rtP.r_commDCDeacv) && + (rtP.z_ctrlTypSel != 0)) { + rtb_Switch1_idx_0 = rtU.r_DCRight * rtDW.Merge_j; + rtb_Switch1_idx_1 = rtU.r_DCRight * rtDW.Merge1_m; + rtb_Abs1 = rtU.r_DCRight * rtDW.Merge2_d; + } else { + if (rtConstP.pooled27[rtb_Sum_a] < 5) { + /* LookupNDDirect: '/z_commutMap_M1' incorporates: + * Constant: '/vec_hallToPos' + * Selector: '/Selector' + * + * About '/z_commutMap_M1': + * 2-dimensional Direct Look-Up returning a Column + */ + tmp = rtConstP.pooled27[rtb_Sum_a]; + } else { + /* LookupNDDirect: '/z_commutMap_M1' + * + * About '/z_commutMap_M1': + * 2-dimensional Direct Look-Up returning a Column + */ + tmp = 5U; + } + + /* LookupNDDirect: '/z_commutMap_M1' + * + * About '/z_commutMap_M1': + * 2-dimensional Direct Look-Up returning a Column + */ + rtb_Abs1 = tmp * 3; + rtb_Switch1_idx_0 = rtU.r_DCRight * rtConstP.pooled17[rtb_Abs1]; + rtb_Switch1_idx_1 = rtConstP.pooled17[1 + rtb_Abs1] * rtU.r_DCRight; + rtb_Abs1 = rtConstP.pooled17[2 + rtb_Abs1] * rtU.r_DCRight; + } + + /* End of Switch: '/Switch1' */ + + /* Outport: '/DC_phaARight' incorporates: + * Constant: '/Constant1' + * Product: '/Divide1' + */ + rtY.DC_phaARight = rtb_Switch1_idx_0 / 1000; + + /* Outport: '/DC_phaBRight' incorporates: + * Constant: '/Constant1' + * Product: '/Divide1' + */ + rtY.DC_phaBRight = rtb_Switch1_idx_1 / 1000; + + /* Update for UnitDelay: '/UnitDelay' incorporates: + * Inport: '/b_hallALeft ' + */ + rtDW.UnitDelay_DSTATE = rtU.b_hallALeft; + + /* Update for UnitDelay: '/UnitDelay1' incorporates: + * Inport: '/b_hallBLeft' + */ + rtDW.UnitDelay1_DSTATE_p = rtU.b_hallBLeft; + + /* Update for UnitDelay: '/UnitDelay2' incorporates: + * Inport: '/b_hallCLeft' + */ + rtDW.UnitDelay2_DSTATE = rtU.b_hallCLeft; + + /* Update for UnitDelay: '/z_counterRawPrev' */ + rtDW.z_counterRawPrev_DSTATE = rtb_Sum1; + + /* Update for UnitDelay: '/UnitDelay1' incorporates: + * Constant: '/vec_hallToPos' + * Selector: '/Selector' + */ + rtDW.UnitDelay1_DSTATE_g = rtConstP.pooled27[rtb_Sum]; + + /* Update for UnitDelay: '/UnitDelay8' */ + rtDW.UnitDelay8_DSTATE = rtb_Logic_idx_0; + + /* Update for Memory: '/Memory' */ + rtDW.Memory_PreviousInput = rtb_Logic_idx_0; + + /* Update for UnitDelay: '/z_counter2' */ + rtDW.z_counter2_DSTATE = rtb_Switch; + + /* Update for UnitDelay: '/UnitDelay1' */ + rtDW.UnitDelay1_DSTATE = rtb_Sum1; + + /* Update for UnitDelay: '/UnitDelay' incorporates: + * Inport: '/b_hallARight' + */ + rtDW.UnitDelay_DSTATE_j = rtU.b_hallARight; + + /* Update for UnitDelay: '/UnitDelay1' incorporates: + * Inport: '/b_hallBRight' + */ + rtDW.UnitDelay1_DSTATE_f = rtU.b_hallBRight; + + /* Update for UnitDelay: '/UnitDelay2' incorporates: + * Inport: '/b_hallCRight' + */ + rtDW.UnitDelay2_DSTATE_b = rtU.b_hallCRight; + + /* Update for UnitDelay: '/z_counterRawPrev' */ + rtDW.z_counterRawPrev_DSTATE_p = rtb_Sum1_c; + + /* Update for UnitDelay: '/UnitDelay1' incorporates: + * Constant: '/vec_hallToPos' + * Selector: '/Selector' + */ + rtDW.UnitDelay1_DSTATE_j = rtConstP.pooled27[rtb_Sum_a]; + + /* Update for UnitDelay: '/UnitDelay8' incorporates: + * CombinatorialLogic: '/Logic' + */ + rtDW.UnitDelay8_DSTATE_p = rtConstP.pooled31[(uint32_T)rowIdx]; + + /* Update for Memory: '/Memory' incorporates: + * CombinatorialLogic: '/Logic' + */ + rtDW.Memory_PreviousInput_i = rtConstP.pooled31[(uint32_T)rowIdx]; + + /* Update for UnitDelay: '/z_counter2' */ + rtDW.z_counter2_DSTATE_h = rtb_Switch_b; + + /* Update for UnitDelay: '/UnitDelay1' */ + rtDW.UnitDelay1_DSTATE_k = rtb_Sum1_c; + + /* Outport: '/DC_phaCRight' incorporates: + * Constant: '/Constant1' + * Product: '/Divide1' + */ + rtY.DC_phaCRight = rtb_Abs1 / 1000; + + /* End of Outputs for SubSystem: '/BLDC_controller' */ +} + +/* Model initialize function */ +void BLDC_controller_initialize(void) +{ + /* Start for Atomic SubSystem: '/BLDC_controller' */ + /* Start for If: '/If1' */ + rtDW.If1_ActiveSubsystem = -1; + + /* Start for If: '/If1' */ + rtDW.If1_ActiveSubsystem_j = -1; + + /* End of Start for SubSystem: '/BLDC_controller' */ + rtPrevZCX.Raw_Speed_calculation_k.Raw_Speed_calculation_Trig_ZCE = POS_ZCSIG; + rtPrevZCX.Moving_Average_Filter_n.Moving_Average_Filter_Trig_ZCE = POS_ZCSIG; + rtPrevZCX.Raw_Speed_calculation_m.Raw_Speed_calculation_Trig_ZCE = POS_ZCSIG; + rtPrevZCX.Moving_Average_Filter_l.Moving_Average_Filter_Trig_ZCE = POS_ZCSIG; + + /* SystemInitialize for Atomic SubSystem: '/BLDC_controller' */ + /* InitializeConditions for UnitDelay: '/z_counter2' */ + rtDW.z_counter2_DSTATE = 5000; + + /* InitializeConditions for UnitDelay: '/z_counter2' */ + rtDW.z_counter2_DSTATE_h = 5000; + + /* End of SystemInitialize for SubSystem: '/BLDC_controller' */ +} + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/Src/BLDC_controller_data.c b/Src/BLDC_controller_data.c new file mode 100644 index 0000000..299e57f --- /dev/null +++ b/Src/BLDC_controller_data.c @@ -0,0 +1,212 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: BLDC_controller_data.c + * + * Code generated for Simulink model 'BLDC_controller'. + * + * Model version : 1.800 + * Simulink Coder version : 8.13 (R2017b) 24-Jul-2017 + * C/C++ source code generated on : Sat May 25 21:42:39 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 "BLDC_controller.h" + +/* Block parameters (auto storage) */ +P rtP = { + /* Variable: cf_spdCoef + * Referenced by: + * '/cf_spdCoef' + * '/cf_spdCoef' + */ + 66667, + + /* Variable: n_commAcvLo + * Referenced by: + * '/Relay' + * '/Relay' + */ + 100, + + /* Variable: n_commDeacvHi + * Referenced by: + * '/Relay' + * '/Relay' + */ + 180, + + /* Variable: n_thresSpdDeacv + * Referenced by: + * '/n_thresSpdDeacv' + * '/n_thresSpdDeacv' + */ + 5, + + /* Variable: r_commDCDeacv + * Referenced by: + * '/r_commDCDeacv' + * '/r_commDCDeacv' + */ + 70, + + /* Variable: r_phaAdvDC_XA + * Referenced by: + * '/r_phaAdvDC_XA' + * '/r_phaAdvDC_XA' + */ + { 0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }, + + /* Variable: a_phaAdv_M1 + * Referenced by: + * '/a_phaAdv_M2' + * '/a_phaAdv_M2' + */ + { 0, 0, 7, 2, 2, 2, 4, 5, 9, 16, 25 }, + + /* Variable: z_maxCntRst + * Referenced by: + * '/z_maxCntRst' + * '/z_maxCntRst' + * '/z_maxCntRst' + * '/z_maxCntRst' + */ + 2000, + + /* Variable: z_ctrlTypSel + * Referenced by: + * '/z_ctrlTypSel1' + * '/z_ctrlTypSel1' + */ + 3U, + + /* Variable: z_nrEdgeSpdAcv + * Referenced by: + * '/z_nrEdgeSpdAcv' + * '/z_nrEdgeSpdAcv' + */ + 5U, + + /* Variable: b_phaAdvEna + * Referenced by: + * '/a_elecPeriod1' + * '/a_elecPeriod1' + */ + 1 +}; + +/* Constant parameters (auto storage) */ +const ConstP rtConstP = { + /* Pooled Parameter (Expression: r_trapPhaA_M1) + * Referenced by: + * '/r_trapPhaA_M1' + * '/r_trapPhaA_M1' + */ + { 1000, 1000, 1000, -1000, -1000, -1000, 1000 }, + + /* Pooled Parameter (Expression: r_trapPhaB_M1) + * Referenced by: + * '/r_trapPhaB_M1' + * '/r_trapPhaB_M1' + */ + { -1000, -1000, 1000, 1000, 1000, -1000, -1000 }, + + /* Pooled Parameter (Expression: r_trapPhaC_M1) + * Referenced by: + * '/r_trapPhaC_M1' + * '/r_trapPhaC_M1' + */ + { 1000, -1000, -1000, -1000, 1000, 1000, 1000 }, + + /* Pooled Parameter (Expression: r_sinPhaA_M1) + * Referenced by: + * '/r_sinPhaA_M1' + * '/r_sinPhaA_M1' + */ + { 500, 643, 766, 866, 940, 985, 1000, 985, 940, 866, 766, 643, 500, 342, 174, + 0, -174, -342, -500, -643, -766, -866, -940, -985, -1000, -985, -940, -866, + -766, -643, -500, -342, -174, 0, 174, 342, 500 }, + + /* Pooled Parameter (Expression: r_sinPhaB_M1) + * Referenced by: + * '/r_sinPhaB_M1' + * '/r_sinPhaB_M1' + */ + { -1000, -985, -940, -866, -766, -643, -500, -342, -174, 0, 174, 342, 500, 643, + 766, 866, 940, 985, 1000, 985, 940, 866, 766, 643, 500, 342, 174, 0, -174, + -342, -500, -643, -766, -866, -940, -985, -1000 }, + + /* Pooled Parameter (Expression: r_sinPhaC_M1) + * Referenced by: + * '/r_sinPhaC_M1' + * '/r_sinPhaC_M1' + */ + { 500, 342, 174, 0, -174, -342, -500, -643, -766, -866, -940, -985, -1000, + -985, -940, -866, -766, -643, -500, -342, -174, 0, 174, 342, 500, 643, 766, + 866, 940, 985, 1000, 985, 940, 866, 766, 643, 500 }, + + /* Pooled Parameter (Expression: r_sin3PhaA_M1) + * Referenced by: + * '/r_sin3PhaA_M1' + * '/r_sin3PhaA_M1' + */ + { 795, 930, 991, 996, 971, 942, 930, 942, 971, 996, 991, 930, 795, 584, 310, 0, + -310, -584, -795, -930, -991, -996, -971, -942, -930, -942, -971, -996, -991, + -930, -795, -584, -310, 0, 310, 584, 795 }, + + /* Pooled Parameter (Expression: r_sin3PhaB_M1) + * Referenced by: + * '/r_sin3PhaB_M1' + * '/r_sin3PhaB_M1' + */ + { -930, -942, -971, -996, -991, -930, -795, -584, -310, 0, 310, 584, 795, 930, + 991, 996, 971, 942, 930, 942, 971, 996, 991, 930, 795, 584, 310, 0, -310, + -584, -795, -930, -991, -996, -971, -942, -930 }, + + /* Pooled Parameter (Expression: r_sin3PhaC_M1) + * Referenced by: + * '/r_sin3PhaC_M1' + * '/r_sin3PhaC_M1' + */ + { 795, 584, 310, 0, -310, -584, -795, -930, -991, -996, -971, -942, -930, -942, + -971, -996, -991, -930, -795, -584, -310, 0, 310, 584, 795, 930, 991, 996, + 971, 942, 930, 942, 971, 996, 991, 930, 795 }, + + /* Pooled Parameter (Expression: z_commutMap_M1) + * Referenced by: + * '/z_commutMap_M1' + * '/z_commutMap_M1' + */ + { 1000, -1000, 0, 1000, 0, -1000, 0, 1000, -1000, -1000, 1000, 0, -1000, 0, + 1000, 0, -1000, 1000 }, + + /* Pooled Parameter (Expression: vec_hallToPos) + * Referenced by: + * '/vec_hallToPos' + * '/vec_hallToPos' + */ + { 0U, 5U, 3U, 4U, 1U, 0U, 2U, 0U }, + + /* Pooled Parameter (Expression: [0 1;1 0;0 1;0 1;1 0;1 0;0 0;0 0]) + * Referenced by: + * '/Logic' + * '/Logic' + */ + { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0 } +}; + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/Src/bldc.c b/Src/bldc.c index e5c609c..560aefe 100644 --- a/Src/bldc.c +++ b/Src/bldc.c @@ -1,16 +1,38 @@ +/* +* This file has been re-implemented with 4 new selectable motor control methods. +* Recommended control method: 3 = Sinusoidal 3rd order. This control method offers superior performanace +* compared to previous method. The new method features: +* â–º reduced noise and vibrations +* â–º smooth torque output +* â–º improved motor efficiency -> lower energy consumption +* +* Copyright (C) 2019 Emanuel FERU +* +* 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 . +*/ #include "stm32f1xx_hal.h" #include "defines.h" #include "setup.h" #include "config.h" +// Matlab includes +#include "BLDC_controller.h" /* Model's header file */ +#include "rtwtypes.h" -volatile int posl = 0; -volatile int posr = 0; volatile int pwml = 0; volatile int pwmr = 0; -volatile int weakl = 0; -volatile int weakr = 0; extern volatile int speed; @@ -18,110 +40,13 @@ extern volatile adc_buf_t adc_buffer; extern volatile uint32_t timeout; -uint32_t buzzerFreq = 0; -uint32_t buzzerPattern = 0; +uint32_t buzzerFreq = 0; +uint32_t buzzerPattern = 0; +uint32_t buzzerTimer = 0; -uint8_t enable = 0; +uint8_t enable = 0; -const int pwm_res = 64000000 / 2 / PWM_FREQ; // = 2000 - -const uint8_t hall_to_pos[8] = { - 0, - 0, - 2, - 1, - 4, - 5, - 3, - 0, -}; - -inline void blockPWM(int pwm, int pos, int *u, int *v, int *w) { - switch(pos) { - case 0: - *u = 0; - *v = pwm; - *w = -pwm; - break; - case 1: - *u = -pwm; - *v = pwm; - *w = 0; - break; - case 2: - *u = -pwm; - *v = 0; - *w = pwm; - break; - case 3: - *u = 0; - *v = -pwm; - *w = pwm; - break; - case 4: - *u = pwm; - *v = -pwm; - *w = 0; - break; - case 5: - *u = pwm; - *v = 0; - *w = -pwm; - break; - default: - *u = 0; - *v = 0; - *w = 0; - } -} - -inline void blockPhaseCurrent(int pos, int u, int v, int *q) { - switch(pos) { - case 0: - *q = u - v; - // *u = 0; - // *v = pwm; - // *w = -pwm; - break; - case 1: - *q = u; - // *u = -pwm; - // *v = pwm; - // *w = 0; - break; - case 2: - *q = u; - // *u = -pwm; - // *v = 0; - // *w = pwm; - break; - case 3: - *q = v; - // *u = 0; - // *v = -pwm; - // *w = pwm; - break; - case 4: - *q = v; - // *u = pwm; - // *v = -pwm; - // *w = 0; - break; - case 5: - *q = -(u - v); - // *u = pwm; - // *v = 0; - // *w = -pwm; - break; - default: - *q = 0; - // *u = 0; - // *v = 0; - // *w = 0; - } -} - -uint32_t buzzerTimer = 0; +const int pwm_res = 64000000 / 2 / PWM_FREQ; // = 2000 int offsetcount = 0; int offsetrl1 = 2000; @@ -133,20 +58,11 @@ int offsetdcr = 2000; float batteryVoltage = BAT_NUMBER_OF_CELLS * 4.0; -int curl = 0; -// int errorl = 0; -// int kp = 5; -// volatile int cmdl = 0; - -int last_pos = 0; -int timer = 0; -const int max_time = PWM_FREQ / 10; -volatile int vel = 0; - //scan 8 channels with 2ADCs @ 20 clk cycles per sample //meaning ~80 ADC clock cycles @ 8MHz until new DMA interrupt =~ 100KHz //=640 cpu cycles void DMA1_Channel1_IRQHandler() { + DMA1->IFCR = DMA_IFCR_CTCIF1; // HAL_GPIO_WritePin(LED_PORT, LED_PIN, 1); @@ -180,61 +96,6 @@ void DMA1_Channel1_IRQHandler() { RIGHT_TIM->BDTR |= TIM_BDTR_MOE; } - int ul, vl, wl; - int ur, vr, wr; - - //determine next position based on hall sensors - uint8_t hall_ul = !(LEFT_HALL_U_PORT->IDR & LEFT_HALL_U_PIN); - uint8_t hall_vl = !(LEFT_HALL_V_PORT->IDR & LEFT_HALL_V_PIN); - uint8_t hall_wl = !(LEFT_HALL_W_PORT->IDR & LEFT_HALL_W_PIN); - - uint8_t hall_ur = !(RIGHT_HALL_U_PORT->IDR & RIGHT_HALL_U_PIN); - uint8_t hall_vr = !(RIGHT_HALL_V_PORT->IDR & RIGHT_HALL_V_PIN); - uint8_t hall_wr = !(RIGHT_HALL_W_PORT->IDR & RIGHT_HALL_W_PIN); - - uint8_t halll = hall_ul * 1 + hall_vl * 2 + hall_wl * 4; - posl = hall_to_pos[halll]; - posl += 2; - posl %= 6; - - uint8_t hallr = hall_ur * 1 + hall_vr * 2 + hall_wr * 4; - posr = hall_to_pos[hallr]; - posr += 2; - posr %= 6; - - blockPhaseCurrent(posl, adc_buffer.rl1 - offsetrl1, adc_buffer.rl2 - offsetrl2, &curl); - - //setScopeChannel(2, (adc_buffer.rl1 - offsetrl1) / 8); - //setScopeChannel(3, (adc_buffer.rl2 - offsetrl2) / 8); - - - // uint8_t buzz(uint16_t *notes, uint32_t len){ - // static uint32_t counter = 0; - // static uint32_t timer = 0; - // if(len == 0){ - // return(0); - // } - - // struct { - // uint16_t freq : 4; - // uint16_t volume : 4; - // uint16_t time : 8; - // } note = notes[counter]; - - // if(timer / 500 == note.time){ - // timer = 0; - // counter++; - // } - - // if(counter == len){ - // counter = 0; - // } - - // timer++; - // return(note.freq); - // } - - //create square wave for buzzer buzzerTimer++; if (buzzerFreq != 0 && (buzzerTimer / 5000) % (buzzerPattern + 1) == 0) { @@ -245,35 +106,64 @@ void DMA1_Channel1_IRQHandler() { HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, 0); } - //update PWM channels based on position - blockPWM(pwml, posl, &ul, &vl, &wl); - blockPWM(pwmr, posr, &ur, &vr, &wr); + // ############################### MOTOR CONTROL ############################### + int ul, vl, wl; + int ur, vr, wr; - int weakul, weakvl, weakwl; - if (pwml > 0) { - blockPWM(weakl, (posl+5) % 6, &weakul, &weakvl, &weakwl); - } else { - blockPWM(-weakl, (posl+1) % 6, &weakul, &weakvl, &weakwl); + // Get hall sensors values + uint8_t hall_ul = !(LEFT_HALL_U_PORT->IDR & LEFT_HALL_U_PIN); + uint8_t hall_vl = !(LEFT_HALL_V_PORT->IDR & LEFT_HALL_V_PIN); + uint8_t hall_wl = !(LEFT_HALL_W_PORT->IDR & LEFT_HALL_W_PIN); + + uint8_t hall_ur = !(RIGHT_HALL_U_PORT->IDR & RIGHT_HALL_U_PIN); + uint8_t hall_vr = !(RIGHT_HALL_V_PORT->IDR & RIGHT_HALL_V_PIN); + uint8_t hall_wr = !(RIGHT_HALL_W_PORT->IDR & RIGHT_HALL_W_PIN); + + static boolean_T OverrunFlag = false; + /* Check for overrun */ + if (OverrunFlag) { + return; } - ul += weakul; - vl += weakvl; - wl += weakwl; + OverrunFlag = true; + + /* Set motor inputs here */ + rtU.b_hallALeft = hall_ul; + rtU.b_hallBLeft = hall_vl; + rtU.b_hallCLeft = hall_wl; + rtU.r_DCLeft = pwml; - int weakur, weakvr, weakwr; - if (pwmr > 0) { - blockPWM(weakr, (posr+5) % 6, &weakur, &weakvr, &weakwr); - } else { - blockPWM(-weakr, (posr+1) % 6, &weakur, &weakvr, &weakwr); - } - ur += weakur; - vr += weakvr; - wr += weakwr; + rtU.b_hallARight = hall_ur; + rtU.b_hallBRight = hall_vr; + rtU.b_hallCRight = hall_wr; + rtU.r_DCRight = pwmr; + + /* Step the controller */ + BLDC_controller_step(); + + /* Get motor outputs here */ + ul = rtY.DC_phaALeft; + vl = rtY.DC_phaBLeft; + wl = rtY.DC_phaCLeft; + // motSpeedLeft = rtY.n_motLeft; + // motAngleLeft = rtY.a_elecAngleLeft; + + ur = rtY.DC_phaARight; + vr = rtY.DC_phaBRight; + wr = rtY.DC_phaCRight; + // motSpeedRight = rtY.n_motRight; + // motAngleRight = rtY.a_elecAngleRight; + + /* Indicate task complete */ + OverrunFlag = false; + // ############################################################################### + + LEFT_TIM->LEFT_TIM_U = CLAMP(ul + pwm_res / 2, 10, pwm_res-10); + LEFT_TIM->LEFT_TIM_V = CLAMP(vl + pwm_res / 2, 10, pwm_res-10); + LEFT_TIM->LEFT_TIM_W = CLAMP(wl + pwm_res / 2, 10, pwm_res-10); + + RIGHT_TIM->RIGHT_TIM_U = CLAMP(ur + pwm_res / 2, 10, pwm_res-10); + RIGHT_TIM->RIGHT_TIM_V = CLAMP(vr + pwm_res / 2, 10, pwm_res-10); + RIGHT_TIM->RIGHT_TIM_W = CLAMP(wr + pwm_res / 2, 10, pwm_res-10); - LEFT_TIM->LEFT_TIM_U = CLAMP(ul + pwm_res / 2, 10, pwm_res-10); - LEFT_TIM->LEFT_TIM_V = CLAMP(vl + pwm_res / 2, 10, pwm_res-10); - LEFT_TIM->LEFT_TIM_W = CLAMP(wl + pwm_res / 2, 10, pwm_res-10); - RIGHT_TIM->RIGHT_TIM_U = CLAMP(ur + pwm_res / 2, 10, pwm_res-10); - RIGHT_TIM->RIGHT_TIM_V = CLAMP(vr + pwm_res / 2, 10, pwm_res-10); - RIGHT_TIM->RIGHT_TIM_W = CLAMP(wr + pwm_res / 2, 10, pwm_res-10); } diff --git a/Src/main.c b/Src/main.c index b737a77..ddbd350 100644 --- a/Src/main.c +++ b/Src/main.c @@ -23,8 +23,13 @@ #include "defines.h" #include "setup.h" #include "config.h" +#include //#include "hd44780.h" +// Matlab includes - from auto-code generation +#include "BLDC_controller.h" /* Model's header file */ +#include "rtwtypes.h" + void SystemClock_Config(void); extern TIM_HandleTypeDef htim_left; @@ -38,7 +43,6 @@ extern UART_HandleTypeDef huart2; int cmd1; // normalized input values. -1000 to 1000 int cmd2; -int cmd3; typedef struct{ int16_t steer; @@ -55,8 +59,6 @@ int speed; // global variable for speed. -1000 to 1000 extern volatile int pwml; // global variable for pwm left. -1000 to 1000 extern volatile int pwmr; // global variable for pwm right. -1000 to 1000 -extern volatile int weakl; // global variable for field weakening left. -1000 to 1000 -extern volatile int weakr; // global variable for field weakening right. -1000 to 1000 extern uint8_t buzzerFreq; // global variable for the buzzer pitch. can be 1, 2, 3, 4, 5, 6, 7... extern uint8_t buzzerPattern; // global variable for the buzzer pattern. can be 1, 2, 3, 4, 5, 6, 7... @@ -77,7 +79,7 @@ int milli_vel_error_sum = 0; void poweroff() { - if (abs(speed) < 20) { + // if (abs(speed) < 20) { // wait for the speed to drop, then shut down -> this is commented out for SAFETY reasons buzzerPattern = 0; enable = 0; for (int i = 0; i < 8; i++) { @@ -86,11 +88,12 @@ void poweroff() { } HAL_GPIO_WritePin(OFF_PORT, OFF_PIN, 0); while(1) {} - } + // } } int main(void) { + HAL_Init(); __HAL_RCC_AFIO_CLK_ENABLE(); HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); @@ -127,6 +130,19 @@ int main(void) { HAL_ADC_Start(&hadc1); HAL_ADC_Start(&hadc2); +////////////////////////////////////// + + /* Set BLDC controller parameters */ + rtP.z_ctrlTypSel = CTRL_TYP_SEL; + rtP.b_phaAdvEna = PHASE_ADV_ENA; + rtP.n_commDeacvHi = COMM_DEACV_HI; + rtP.n_commAcvLo = COMM_ACV_LO; + +/* Initialize BLDC controller */ + BLDC_controller_initialize(); + +///////////////////////////////////// + for (int i = 8; i >= 0; i--) { buzzerFreq = i; HAL_Delay(100); @@ -137,7 +153,6 @@ int main(void) { int lastSpeedL = 0, lastSpeedR = 0; int speedL = 0, speedR = 0; - float direction = 1; #ifdef CONTROL_PPM PPM_Init(); @@ -180,6 +195,7 @@ int main(void) { enable = 1; // enable motors + while(1) { HAL_Delay(DELAY_IN_MAIN_LOOP); //delay in ms @@ -201,8 +217,8 @@ int main(void) { #ifdef CONTROL_ADC // ADC values range: 0-4095, see ADC-calibration in config.h - cmd1 = CLAMP(adc_buffer.l_tx2 - ADC1_MIN, 0, ADC1_MAX) / (ADC1_MAX / 1000.0f); // ADC1 - cmd2 = CLAMP(adc_buffer.l_rx2 - ADC2_MIN, 0, ADC2_MAX) / (ADC2_MAX / 1000.0f); // ADC2 + cmd1 = CLAMP(adc_buffer.l_tx2 - ADC1_MIN, 0, ADC1_MAX) / (ADC1_MAX / 1000.0f); // ADC1 + cmd2 = CLAMP(adc_buffer.l_rx2 - ADC2_MIN, 0, ADC2_MAX) / (ADC2_MAX / 1000.0f); // ADC2 // use ADCs as button inputs: button1 = (uint8_t)(adc_buffer.l_tx2 > 2000); // ADC1 @@ -218,7 +234,6 @@ int main(void) { timeout = 0; #endif - // ####### LOW-PASS FILTER ####### steer = steer * (1.0 - FILTER) + cmd1 * FILTER; speed = speed * (1.0 - FILTER) + cmd2 * FILTER; @@ -234,7 +249,7 @@ int main(void) { #endif - // ####### SET OUTPUTS ####### + // ####### SET OUTPUTS (if the target change less than +/- 50) ####### if ((speedL < lastSpeedL + 50 && speedL > lastSpeedL - 50) && (speedR < lastSpeedR + 50 && speedR > lastSpeedR - 50) && timeout < TIMEOUT) { #ifdef INVERT_R_DIRECTION pwmr = speedR; @@ -256,24 +271,27 @@ int main(void) { // ####### 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; - + // ####### DEBUG SERIAL OUT ####### #ifdef CONTROL_ADC - setScopeChannel(0, (int)adc_buffer.l_tx2); // 1: ADC1 - setScopeChannel(1, (int)adc_buffer.l_rx2); // 2: ADC2 + // setScopeChannel(0, (int)adc_buffer.l_tx2); // 1: ADC1 + // setScopeChannel(1, (int)adc_buffer.l_rx2); // 2: ADC2 #endif - setScopeChannel(2, (int)speedR); // 3: output speed: 0-1000 - setScopeChannel(3, (int)speedL); // 4: output speed: 0-1000 - setScopeChannel(4, (int)adc_buffer.batt1); // 5: for battery voltage calibration - setScopeChannel(5, (int)(batteryVoltage * 100.0f)); // 6: for verifying battery voltage calibration - setScopeChannel(6, (int)board_temp_adc_filtered); // 7: for board temperature calibration - setScopeChannel(7, (int)board_temp_deg_c); // 8: for verifying board temperature calibration + setScopeChannel(0, (int)speedR); // 1: output command: [-1000, 1000] + setScopeChannel(1, (int)speedL); // 2: output command: [-1000, 1000] + setScopeChannel(2, (int)rtY.n_motRight); // 3: Real motor speed [rpm] + setScopeChannel(3, (int)rtY.n_motLeft); // 4: Real motor speed [rpm] + setScopeChannel(4, (int)adc_buffer.batt1); // 5: for battery voltage calibration + setScopeChannel(5, (int)(batteryVoltage * 100.0f)); // 6: for verifying battery voltage calibration + setScopeChannel(6, (int)board_temp_adc_filtered); // 7: for board temperature calibration + setScopeChannel(7, (int)board_temp_deg_c); // 8: for verifying board temperature calibration + consoleScope(); } // ####### POWEROFF BY POWER-BUTTON ####### - if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) && weakr == 0 && weakl == 0) { + if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) { enable = 0; while (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) {} poweroff(); diff --git a/build/hover.hex b/build/hover.hex deleted file mode 100644 index 20d6a41..0000000 --- a/build/hover.hex +++ /dev/null @@ -1,1153 +0,0 @@ -:020000040800F2 -:1000000000C00020913D0008753D0008773D0008C4 -:10001000793D00087B3D00087D3D000800000000A0 -:100020000000000000000000000000007F3D00080C -:10003000813D000800000000833D0008853D000868 -:10004000D93D0008D93D0008D93D0008D93D000838 -:10005000D93D0008D93D0008D93D0008D93D000828 -:10006000D93D0008D93D0008D93D0008A135000858 -:10007000D93D0008D93D0008D93D0008D93D000808 -:10008000D93D0008D93D0008D93D0008D93D0008F8 -:10009000D93D0008D93D0008D93D0008D93D0008E8 -:1000A000D93D0008D93D0008D93D0008D93D0008D8 -:1000B000D93D0008D93D0008D93D0008D93D0008C8 -:1000C000D93D0008D93D0008D93D0008D93D0008B8 -:1000D000D93D0008D93D0008D93D0008D93D0008A8 -:1000E000D93D0008D93D0008D93D0008D93D000898 -:1000F000D93D0008D93D0008D93D0008D93D000888 -:10010000D93D0008D93D0008D93D0008D93D000877 -:10011000D93D0008D93D0008D93D0008D93D000867 -:10012000D93D0008D93D0008D93D0008D93D000857 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000000000000000000000000000008F -:10017000000000000000000000000000000000007F -:10018000000000000000000000000000000000006F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:0401E0005FF8E0F1F3 -:1001E80010B5054C237833B9044B13B10448AFF369 -:1001F80000800123237010BD88000020000000004B -:100208007046000808B5034B1BB103490348AFF318 -:10021800008008BD000000008C0000207046000827 -:10022800034613F8012B002AFBD1181A013870472E -:1002380081F0004102E000BF83F0004330B54FEA8F -:1002480041044FEA430594EA050F08BF90EA020FFC -:100258001FBF54EA000C55EA020C7FEA645C7FEA8F -:10026800655C00F0E2804FEA5454D4EB5555B8BFB2 -:100278006D420CDD2C4480EA020281EA030382EA23 -:10028800000083EA010180EA020281EA0303362DB5 -:1002980088BF30BD11F0004F4FEA01314FF4801C88 -:1002A8004CEA113102D0404261EB410113F0004F9A -:1002B8004FEA03334CEA133302D0524263EB430351 -:1002C80094EA050F00F0A780A4F10104D5F1200EEF -:1002D8000DDB02FA0EFC22FA05F2801841F100014A -:1002E80003FA0EF2801843FA05F359410EE0A5F11E -:1002F80020050EF1200E012A03FA0EFC28BF4CF04F -:10030800020C43FA05F3C01851EBE37101F0004504 -:1003180007D54FF0000EDCF1000C7EEB00006EEB11 -:100328000101B1F5801F1BD3B1F5001F0CD349089B -:100338005FEA30004FEA3C0C04F101044FEA4452F2 -:1003480012F5800F80F09A80BCF1004F08BF5FEA79 -:10035800500C50F1000041EB045141EA050130BD59 -:100368005FEA4C0C404141EB010111F4801FA4F1FC -:100378000104E9D191F0000F04BF01460020B1FA51 -:1003880081F308BF2033A3F10B03B3F120020CDA89 -:100398000C3208DD02F1140CC2F10C0201FA0CF067 -:1003A80021FA02F10CE002F11402D8BFC2F1200CCC -:1003B80001FA02F120FA0CFCDCBF41EA0C01904082 -:1003C800E41AA2BF01EB0451294330BD6FEA0404CB -:1003D8001F3C1CDA0C340EDC04F11404C4F12002B6 -:1003E80020FA04F001FA02F340EA030021FA04F3C8 -:1003F80045EA030130BDC4F10C04C4F1200220FA1F -:1004080002F001FA04F340EA0300294630BD21FA5C -:1004180004F0294630BD94F0000F83F4801306BF22 -:1004280081F480110134013D4EE77FEA645C18BF16 -:100438007FEA655C29D094EA050F08BF90EA020FAD -:1004480005D054EA000C04BF1946104630BD91EAA5 -:10045800030F1EBF0021002030BD5FEA545C05D1A8 -:100468004000494128BF41F0004130BD14F58004E7 -:100478003CBF01F5801130BD01F0004545F0FE415B -:1004880041F470014FF0000030BD7FEA645C1ABF90 -:10049800194610467FEA655C1CBF0B46024650EAC7 -:1004A800013406BF52EA033591EA030F41F40021F3 -:1004B80030BD00BF90F0000F04BF0021704730B579 -:1004C8004FF4806404F132044FF000054FF000014E -:1004D80050E700BF90F0000F04BF0021704730B50F -:1004E8004FF4806404F1320410F0004548BF4042E4 -:1004F8004FF000013EE700BF42004FEAE2014FEA39 -:1005080031014FEA02701FBF12F07F4393F07F4F13 -:1005180081F06051704732F07F4208BF704793F016 -:100528007F4F04BF41F40021704730B54FF4607429 -:1005380001F0004521F000411CE700BF50EA01022C -:1005480008BF704730B54FF000050AE050EA0102D5 -:1005580008BF704730B511F0004502D5404261EB45 -:1005680041014FF4806404F132045FEA915C3FF486 -:10057800D8AE4FF003025FEADC0C18BF03325FEA23 -:10058800DC0C18BF033202EBDC02C2F1200300FAD4 -:1005980003FC20FA02F001FA03FE40EA0E0021FAF9 -:1005A80002F11444BDE600BF70B54FF0FF0C4CF4E7 -:1005B800E06C1CEA11541DBF1CEA135594EA0C0F99 -:1005C80095EA0C0F00F0DEF82C4481EA030621EAD4 -:1005D8004C5123EA4C5350EA013518BF52EA03350F -:1005E80041F4801143F4801338D0A0FB02CE4FF0C1 -:1005F8000005E1FB02E506F00042E0FB03E54FF0F1 -:100608000006E1FB03569CF0000F18BF4EF0010EE8 -:10061800A4F1FF04B6F5007F64F5407404D25FEAE4 -:100628004E0E6D4146EB060642EAC62141EA555197 -:100638004FEAC52040EA5E504FEACE2EB4F1FD0CD9 -:1006480088BFBCF5E06F1ED8BEF1004F08BF5FEA57 -:10065800500E50F1000041EB045170BD06F0004609 -:1006680046EA010140EA020081EA0301B4EB5C04B6 -:10067800C2BFD4EB0C0541EA045170BD41F48011AE -:100688004FF0000E013C00F3AB8014F1360FDEBFD3 -:10069800002001F0004170BDC4F10004203C35DAAF -:1006A8000C341BDC04F11404C4F1200500FA05F332 -:1006B80020FA04F001FA05F240EA020001F00042D3 -:1006C80021F0004110EBD37021FA04F642EB060149 -:1006D8005EEA430E08BF20EAD37070BDC4F10C0473 -:1006E800C4F1200500FA04F320FA05F001FA04F237 -:1006F80040EA020001F0004110EBD37041F1000123 -:100708005EEA430E08BF20EAD37070BDC4F120052D -:1007180000FA05F24EEA020E20FA04F301FA05F295 -:1007280043EA020321FA04F001F0004121FA04F23D -:1007380020EA020000EBD3705EEA430E08BF20EA0D -:10074800D37070BD94F0000F0FD101F00046400047 -:1007580041EB010111F4801F08BF013CF7D041EAC9 -:10076800060195F0000F18BF704703F000465200CD -:1007780043EB030313F4801F08BF013DF7D043EA9E -:100788000603704794EA0C0F0CEA135518BF95EA54 -:100798000C0F0CD050EA410618BF52EA4306D1D1DB -:1007A80081EA030101F000414FF0000070BD50EAFA -:1007B800410606BF1046194652EA430619D094EA84 -:1007C8000C0F02D150EA013613D195EA0C0F05D16E -:1007D80052EA03361CBF104619460AD181EA0301C2 -:1007E80001F0004141F0FE4141F470014FF000007A -:1007F80070BD41F0FE4141F4780170BD70B54FF015 -:10080800FF0C4CF4E06C1CEA11541DBF1CEA135594 -:1008180094EA0C0F95EA0C0F00F0A7F8A4EB050476 -:1008280081EA030E52EA03354FEA013100F088806D -:100838004FEA03334FF0805545EA131343EA126336 -:100848004FEA022245EA111545EA10654FEA0026EB -:100858000EF000419D4208BF964244F1FD0404F5A4 -:10086800407402D25B084FEA3202B61A65EB030500 -:100878005B084FEA32024FF480104FF4002CB6EBBD -:10088800020E75EB030E22BFB61A754640EA0C003D -:100898005B084FEA3202B6EB020E75EB030E22BF7D -:1008A800B61A754640EA5C005B084FEA3202B6EBBE -:1008B800020E75EB030E22BFB61A754640EA9C007D -:1008C8005B084FEA3202B6EB020E75EB030E22BF4D -:1008D800B61A754640EADC0055EA060E18D04FEA0B -:1008E800051545EA16754FEA06164FEAC30343EAAB -:1008F80052734FEAC2025FEA1C1CC0D111F4801F78 -:100908000BD141EA00014FF000004FF0004CB6E770 -:1009180011F4801F04BF01430020B4F1FD0C88BF0F -:10092800BCF5E06F3FF6AFAEB5EB030C04BFB6EB1A -:10093800020C5FEA500C50F1000041EB045170BD0D -:100948000EF0004E4EEA113114EB5C04C2BFD4EB3A -:100958000C0541EA045170BD41F480114FF0000EBE -:10096800013C90E645EA060E8DE60CEA135594EA3A -:100978000C0F08BF95EA0C0F3FF43BAF94EA0C0F3D -:100988000AD150EA01347FF434AF95EA0C0F7FF4B2 -:1009980025AF104619462CE795EA0C0F06D152EA06 -:1009A80003353FF4FDAE1046194622E750EA4106EA -:1009B80018BF52EA43067FF4C5AE50EA41047FF4FB -:1009C8000DAF52EA43057FF4EBAE12E74FF0FF3C60 -:1009D80006E000BF4FF0010C02E000BF4FF0010C31 -:1009E8004DF804CD4FEA410C7FEA6C5C4FEA430CAA -:1009F80018BF7FEA6C5C1BD001B050EA410C0CBFF9 -:100A080052EA430C91EA030F02BF90EA020F00205A -:100A1800704710F1000F91EA030F58BF994208BFC1 -:100A280090422CBFD8176FEAE37040F0010070477E -:100A38004FEA410C7FEA6C5C02D150EA013C07D1D5 -:100A48004FEA430C7FEA6C5CD6D152EA033CD3D020 -:100A58005DF8040B704700BF8446104662468C461A -:100A68001946634600E000BF01B5FFF7B7FF00284D -:100A780048BF10F1000F01BD4DF808EDFFF7F4FF76 -:100A88000CBF012000205DF808FB00BF4DF808ED01 -:100A9800FFF7EAFF34BF012000205DF808FB00BF24 -:100AA8004DF808EDFFF7E0FF94BF012000205DF846 -:100AB80008FB00BF4DF808EDFFF7CEFF94BF0120FB -:100AC80000205DF808FB00BF4DF808EDFFF7C4FFF4 -:100AD80034BF012000205DF808FB00BF4FEA410247 -:100AE80012F5001215D211D56FF47873B3EB625278 -:100AF80012D94FEAC12343F0004343EA505311F09F -:100B0800004F23FA02F018BF404270474FF0000030 -:100B1800704750EA013005D111F0004008BF6FF06E -:100B2800004070474FF00000704700BF4FEA410295 -:100B3800B2F1E04324BFB3F5001CDCF1FE5C0DD933 -:100B480001F0004C4FEAC0024CEA5070B2F1004F7D -:100B580040EB830008BF20F00100704711F0804F80 -:100B680021D113F13872BCBF01F00040704741F445 -:100B780080114FEA5252C2F11802C2F1200C10FA49 -:100B88000CF320FA02F018BF40F001004FEAC1232D -:100B98004FEAD32303FA0CFC40EA0C0023FA02F3D1 -:100BA8004FEA4303CCE77FEA625307D150EA0133A7 -:100BB8001EBF4FF0FE4040F44000704701F0004077 -:100BC80040F0FE4040F40000704700BF80F0004055 -:100BD80002E000BF81F0004142001FBF5FEA41030D -:100BE80092EA030F7FEA226C7FEA236C6AD04FEA0D -:100BF8001262D2EB1363C1BFD21841404840414052 -:100C0800B8BF5B42192B88BF704710F0004F40F403 -:100C1800000020F07F4018BF404211F0004F41F41F -:100C2800000121F07F4118BF494292EA030F3FD0EB -:100C3800A2F1010241FA03FC10EB0C00C3F12003FE -:100C480001FA03F100F0004302D5494260EB40008D -:100C5800B0F5000F13D3B0F1807F06D340084FEAF8 -:100C6800310102F10102FE2A51D2B1F1004F40EBED -:100C7800C25008BF20F0010040EA03007047490055 -:100C880040EB000010F4000FA2F10102EDD1B0FA20 -:100C980080FCACF1080CB2EB0C0200FA0CF0AABF15 -:100CA80000EBC25052421843BCBFD04018437047B3 -:100CB80092F0000F81F4000106BF80F400000132B9 -:100CC800013BB5E74FEA41037FEA226C18BF7FEA90 -:100CD800236C21D092EA030F04D092F0000F08BFD2 -:100CE8000846704790EA010F1CBF0020704712F0B9 -:100CF8007F4F04D1400028BF40F00040704712F1F8 -:100D080000723CBF00F50000704700F0004343F05C -:100D1800FE4040F4000070477FEA226216BF084692 -:100D28007FEA23630146420206BF5FEA412390EA55 -:100D3800010F40F4800070474FF0000304E000BF4B -:100D480010F0004348BF40425FEA000C08BF7047FC -:100D580043F0964301464FF000001CE050EA0102C0 -:100D680008BF70474FF000030AE000BF50EA0102D5 -:100D780008BF704711F0004302D5404261EB4101C2 -:100D88005FEA010C02BF84460146002043F0B643E7 -:100D980008BFA3F18053A3F50003BCFA8CF2083A0C -:100DA800A3EBC25310DB01FA02FC634400FA02FC15 -:100DB800C2F12002BCF1004F20FA02F243EB02001C -:100DC80008BF20F00100704702F1200201FA02FC7E -:100DD800C2F1200250EA4C0021FA02F243EB020071 -:100DE80008BF20EADC7070474FF0FF0C1CEAD052B5 -:100DF8001EBF1CEAD15392EA0C0F93EA0C0F6FD076 -:100E08001A4480EA010C400218BF5FEA41211ED053 -:100E18004FF0006343EA501043EA5111A0FB01313F -:100E28000CF00040B1F5000F3EBF490041EAD37114 -:100E38005B0040EA010062F17F02FD2A1DD8B3F190 -:100E4800004F40EBC25008BF20F00100704790F0FF -:100E5800000F0CF0004C08BF49024CEA502040EA51 -:100E680051207F3AC2BFD2F1FF0340EAC250704717 -:100E780040F400004FF00003013A5DDC12F1190F55 -:100E8800DCBF00F000407047C2F10002410021FAC7 -:100E980002F1C2F1200200FA02FC5FEA310040F1DF -:100EA800000053EA4C0308BF20EADC70704792F058 -:100EB800000F00F0004C02BF400010F4000F013A90 -:100EC800F9D040EA0C0093F0000F01F0004C02BF8B -:100ED800490011F4000F013BF9D041EA0C018FE7FA -:100EE8000CEAD15392EA0C0F18BF93EA0C0F0AD000 -:100EF80030F0004C18BF31F0004CD8D180EA010026 -:100F080000F00040704790F0000F17BF90F0004FBE -:100F1800084691F0000F91F0004F14D092EA0C0FA0 -:100F280001D142020FD193EA0C0F03D14B0218BF33 -:100F3800084608D180EA010000F0004040F0FE4079 -:100F480040F40000704740F0FE4040F44000704715 -:100F58004FF0FF0C1CEAD0521EBF1CEAD15392EA94 -:100F68000C0F93EA0C0F69D0A2EB030280EA010C84 -:100F780049024FEA402037D04FF0805343EA11111D -:100F880043EA10130CF000408B4238BF5B0042F17B -:100F98007D024FF4000C8B4224BF5B1A40EA0C0020 -:100FA800B3EB510F24BFA3EB510340EA5C00B3EB52 -:100FB800910F24BFA3EB910340EA9C00B3EBD10F40 -:100FC80024BFA3EBD10340EADC001B0118BF5FEA92 -:100FD8001C1CE0D1FD2A3FF650AF8B4240EBC250BB -:100FE80008BF20F0010070470CF0004C4CEA50207C -:100FF8007F32C2BFD2F1FF0340EAC250704740F4CB -:1010080000004FF00003013A37E792F0000F00F0BC -:10101800004C02BF400010F4000F013AF9D040EA3A -:101028000C0093F0000F01F0004C02BF490011F4CE -:10103800000F013BF9D041EA0C0195E70CEAD153C6 -:1010480092EA0C0F08D142027FF47DAF93EA0C0FAD -:101058007FF470AF084676E793EA0C0F04D14B0291 -:101068003FF44CAF08466EE730F0004C18BF31F043 -:10107800004CCAD130F000427FF45CAF31F000433D -:101088007FF43CAF5FE700BF4FF0FF3C06E000BFD6 -:101098004FF0010C02E000BF4FF0010C4DF804CDF9 -:1010A8004FEA40024FEA41037FEA226C18BF7FEA09 -:1010B800236C11D001B052EA530C18BF90EA010F0B -:1010C80058BFB2EB030088BFC81738BF6FEAE1709A -:1010D80018BF40F0010070477FEA226C02D15FEA36 -:1010E800402C05D17FEA236CE4D15FEA412CE1D0A2 -:1010F8005DF8040B704700BF844608466146FFE769 -:101108000FB5FFF7C9FF002848BF10F1000F0FBD4A -:101118004DF808EDFFF7F4FF0CBF012000205DF843 -:1011280008FB00BF4DF808EDFFF7EAFF34BF0120C8 -:1011380000205DF808FB00BF4DF808EDFFF7E0FF61 -:1011480094BF012000205DF808FB00BF4DF808EDB2 -:10115800FFF7D2FF94BF012000205DF808FB00BF15 -:101168004DF808EDFFF7C8FF34BF012000205DF8F7 -:1011780008FB00BF4FEA4002B2F1FE4F0FD34FF019 -:101188009E03B3EB12620DD94FEA002343F00043EC -:1011980010F0004F23FA02F018BF404270474FF09A -:1011A8000000704712F1610F01D1420205D110F021 -:1011B800004008BF6FF0004070474FF000007047D4 -:1011C80082B0084B1B68084AA2FB03235B0A00FB9A -:1011D80003F0019000BF019B5A1E0192002BF9D128 -:1011E80002B0704700000020D34D621070B582B085 -:1011F8000446036813F0010F2CD0AB4B5B6803F077 -:101208000C03042B1DD0A84B5B6803F00C03082BC0 -:1012180012D06368B3F5803F41D0002B55D103F15C -:10122800804303F504331A6822F480321A601A687E -:1012380022F480221A6037E09B4B5B6813F4803FEE -:10124800E7D0994B1B6813F4003F03D06368002B69 -:1012580000F0AE81236813F0020F76D0924B5B68E2 -:1012680013F00C0F5FD0904B5B6803F00C03082B56 -:1012780054D02369002B00F08A808C4B01221A601D -:1012880000F0F8FF0546884B1B6813F0020F75D174 -:1012980000F0F0FF401B0228F5D903208BE1824AB9 -:1012A800136843F480331360636843B300F0E2FFCC -:1012B80005467D4B1B6813F4003FCBD100F0DAFFE5 -:1012C800401B6428F5D9032075E1B3F5A02F09D098 -:1012D800754B1A6822F480321A601A6822F4802248 -:1012E8001A60E1E703F18043A3F53C331A6842F43E -:1012F80080221A601A6842F480321A60D4E700F03B -:10130800B9FF0546684B1B6813F4003FA2D000F0F4 -:10131800B1FF401B6428F5D903204CE1624B5B68A0 -:1013280013F4803FA5D1604B1B6813F0020F04D063 -:101338002369012B01D001203DE15B4A136823F0AA -:10134800F803616943EAC1031360236813F0080FC7 -:1013580032D0A369002B5BD0554B01221A6000F0F4 -:1013680089FF0546504B5B6A13F0020F21D100F04C -:1013780081FF401B0228F5D903201CE14A4A136863 -:1013880023F0F803616943EAC1031360DDE7474BC3 -:1013980000221A6000F06EFF0546434B1B6813F0ED -:1013A800020FD2D000F066FF401B0228F5D90320B7 -:1013B80001E10120FFF704FF236813F0040F00F098 -:1013C8009780394BDB6913F0805F33D1364BDA698C -:1013D80042F08052DA61DB6903F080530193019B8C -:1013E8000125344B1B6813F4807F25D0E368012B5B -:1013F80036D0002B4CD103F1804303F504331A6A2D -:1014080022F001021A621A6A22F004021A622CE01F -:10141800274B00221A6000F02DFF0546224B5B6A1D -:1014280013F0020FC8D000F025FF401B0228F5D9A1 -:101438000320C0E00025D4E71E4A136843F48073F4 -:10144800136000F017FF06461A4B1B6813F4807FE1 -:10145800CCD100F00FFF801B6428F5D90320AAE047 -:10146800114A136A43F001031362E36873B300F08F -:1014780001FF06460C4B1B6A13F0020F37D100F030 -:10148800F9FE801B41F288339842F3D9032092E099 -:10149800052B11D0044B1A6A22F001021A621A6A4B -:1014A80022F004021A62E0E7001002400000424203 -:1014B8008004424200700040414B1A6A42F0040224 -:1014C8001A621A6A42F001021A62CEE700F0D2FEEE -:1014D80006463B4B1B6A13F0020F08D000F0CAFE09 -:1014E800801B41F288339842F3D9032063E0E5B9C1 -:1014F800E369002B5ED0324A526802F00C02082AD7 -:101508005BD0022B17D02F4B00221A6000F0B2FEDE -:1015180004462B4B1B6813F0007F47D000F0AAFE4F -:10152800001B0228F5D9032045E0254AD36923F09A -:101538008053D361DCE7234B00221A6000F09AFE47 -:1015480005461F4B1B6813F0007F06D000F092FE83 -:10155800401B0228F5D903202DE0236AB3F5803F0C -:101568001AD017494B6823F47413226A606A02433D -:1015780013434B60134B01221A6000F07BFE0446B4 -:101588000F4B1B6813F0007F0ED100F073FE001B99 -:101598000228F5D903200EE0094A536823F40033E2 -:1015A800A1680B435360DCE7002004E0002002E060 -:1015B800012000E0002002B070BD0120FBE700BF61 -:1015C800001002406000424210B487B0164C94E804 -:1015D8000F000DF1180C0CE90F00238AADF8043048 -:1015E800124B5B6803F00C02082A1AD1C3F383423A -:1015F800624412F8100C13F4803F05D10C4B03FB26 -:1016080000F007B010BC7047084B5B68C3F3404359 -:10161800634413F8142C074BB3FBF2F300FB03F0FD -:10162800EFE70448EDE700BF8846000800100240D5 -:1016380000093D0000127A00594B1B6803F00703AC -:101648008B420CD2564A136823F007030B431360EE -:10165800136803F007038B4201D00120704770B56F -:10166800036813F0020F06D04E4A536823F0F003C4 -:101678008468234353600C460546036813F0010F42 -:1016880052D04368012B23D0022B28D0454A126838 -:1016980012F0020F00F0828042494A6822F00302E9 -:1016A80013434B6000F0E6FD06466B68012B1DD026 -:1016B800022B2AD03B4B5B6813F00C0F34D000F0A0 -:1016C800D9FD801B41F288339842F3D9032064E0A6 -:1016D800344A126812F4003FDED101205DE0314A3D -:1016E800126812F0007FD7D1012056E02D4B5B68BD -:1016F80003F00C03042B17D000F0BCFD801B41F253 -:1017080088339842F2D9032047E0264B5B6803F000 -:101718000C03082B08D000F0ADFD801B41F2883384 -:101728009842F2D9032038E01D4B1B6803F00703E9 -:10173800A3420CD91A4A136823F007032343136002 -:10174800136803F00703A34201D0012025E02B68AA -:1017580013F0040F06D0134A536823F4E063E968D2 -:101768000B4353602B6813F0080F07D00D4A5368DA -:1017780023F46053296943EAC1035360FFF724FF48 -:10178800084B5B68C3F30313074AD35CD840074B85 -:101798001860002000F03EFD002070BD0120FCE72D -:1017A80000200240001002409C4600080000002073 -:1017B800014B1868704700BF0000002008B5FFF70C -:1017C800F7FF044B5B68C3F30223034AD35CD8409A -:1017D80008BD00BF00100240AC46000808B5FFF77E -:1017E800E7FF044B5B68C3F3C223034AD35CD840CA -:1017F80008BD00BF00100240AC46000830B4036AC0 -:1018080023F001030362056A4268846924F07304C3 -:101818000B681C4325F002058B682B43104DA8422A -:1018280003D005F50065A84205D123F00803CD686B -:101838002B4323F004030A4DA84203D005F50065A5 -:10184800A84205D122F440724D6915438A692A439A -:10185800426084614A684263036230BC704700BFDB -:10186800002C014030B4036A23F480730362036AD6 -:101878004268C46924F073040D682C4323F4007390 -:101888008D6843EA0523124DA84203D005F500658B -:10189800A84206D123F40063CD6843EA052323F464 -:1018A80080630B4DA84203D005F50065A84207D117 -:1018B80022F440524D6942EA05128D6942EA051246 -:1018C8004260C4614A68C263036230BC704700BFAB -:1018D800002C014030B4036A23F480530362036A86 -:1018E8004468C26922F4E6420D6842EA052223F4FC -:1018F80000538D6843EA0533094DA84203D005F526 -:101908000065A84204D124F480444D6944EA851452 -:101918004460C2614A680264036230BC704700BF19 -:10192800002C014010B4036A046A24F00104046224 -:10193800846924F0F00444EA021223F00A030B43FA -:101948008261036210BC704710B4036A23F010036D -:1019580003628469036A24F4704444EA023223F07F -:10196800A00343EA01138261036210BC704710B4FC -:10197800846824F47F4442EA03230B4323438360AF -:1019880010BC704710B50468A26822F070024B685A -:10199800134323F007030A681343A3604B68502BD3 -:1019A8001ED00AD9602B21D0702B05D10B698A680B -:1019B800C9680068FFF7DBFF10BD402BFCD1036846 -:1019C8001C6A1A6A22F001021A620268936923F0FB -:1019D800F003096943EA0113936103681C62EBE7AA -:1019E8000A6989680068FFF79DFFE5E70A69896861 -:1019F8000068FFF7A9FFDFE7704738B590F83C307B -:101A0800012B18D00446012580F83C50022380F8A9 -:101A18003D30FFF7B7FF2268D36823F04003D36057 -:101A28002268D36823F48043D36084F83D500020B3 -:101A380084F83C0038BD0220FCE700000368244A13 -:101A4800904212D002F5006290420ED0B0F1804F61 -:101A58000BD0A2F59832904207D002F580629042EE -:101A680003D002F58062904203D123F070034A68E4 -:101A78001343174A904212D002F5006290420ED0EA -:101A8800B0F1804F0BD0A2F59832904207D002F502 -:101A98008062904203D002F58062904203D123F421 -:101AA8004073CA68134323F080034A6913430360F1 -:101AB8008B68C3620B688362054B984203D003F5B9 -:101AC8000063984201D10B690363012343617047A6 -:101AD800002C0140A8B110B5044690F83D305BB128 -:101AE800022384F83D30211D2068FFF7A7FF01235A -:101AF80084F83D30002010BD80F83C30FFF77CFFB3 -:101B0800EEE701207047000030B4036A23F01003A9 -:101B18000362036A4468826922F4E6420D6842EA75 -:101B2800052223F020038D6843EA0513114DA842CE -:101B380003D005F50065A84206D123F08003CD68DF -:101B480043EA051323F040030A4DA84203D005F5E4 -:101B58000065A84207D124F440644D6944EA85042D -:101B68008D6944EA8504446082614A68826303623D -:101B780030BC7047002C014038B590F83C30012B40 -:101B880066D00D460446012380F83C30022380F8D5 -:101B98003D300C2A1AD8DFE802F007191919201964 -:101BA80019193419191947000068FFF727FE226828 -:101BB800936943F0080393612268936923F004034F -:101BC80093612268936929690B439361012384F81F -:101BD8003D30002084F83C0038BD0068FFF794FFD2 -:101BE8002268936943F4006393612268936923F43C -:101BF8008063936122689369296943EA01239361A9 -:101C0800E4E70068FFF72EFE2268D36943F0080373 -:101C1800D3612268D36923F00403D3612268D369AE -:101C280029690B43D361D1E70068FFF753FE2268A7 -:101C3800D36943F40063D3612268D36923F48063D2 -:101C4800D3612268D369296943EA0123D361BDE7D7 -:101C58000220C1E710B4012303FA01F4036A23EA5E -:101C680004030362036A8A401343036210BC70478B -:101C780010B5044601220068FFF7ECFF2368094A03 -:101C8800934203D002F50062934203D15A6C42F4A6 -:101C980000425A642268136843F00103136000206D -:101CA80010BD00BF002C014010B4042303FA01F456 -:101CB800036A23EA04030362036A8A401343036244 -:101CC80010BC704710B5044604220068FFF7ECFF0B -:101CD8002268536C43F4004353642268136843F04A -:101CE80001031360002010BD90F83C30012B25D073 -:101CF800012380F83C30CB6823F440738A6813438F -:101D080023F480634A68134323F400630A68134387 -:101D180023F480530A69134323F400534A69134395 -:101D280023F480438A69134323F40043134302686E -:101D38005364002380F83C301846704702207047EF -:101D480090F83C30012B22D030B4012280F83C209E -:101D5800022380F83D300468636823F070036360F1 -:101D6800046863680D682B4363600468A36823F004 -:101D78008003A3600468A36849680B43A36080F8E4 -:101D88003D20002380F83C30184630BC70470220C4 -:101D980070470000034690F82420012A20D0012231 -:101DA80080F824200268906810F0010F07D10D48D0 -:101DB800806810F0010F02D10B48824208D09A6A5D -:101DC80042F020029A620120002283F82420704702 -:101DD800506820F470200968014351600020F3E73F -:101DE800022070470028014000240140074AD368B8 -:101DF80023F4E0631B041B0C000200F4E0601843AA -:101E080040F0BF6040F40030D060704700ED00E063 -:101E180030B4174BDB68C3F30223C3F10704042C67 -:101E280028BF04241D1D062D18D9033B4FF0FF358C -:101E380005FA04F421EA0401994005FA03F322EAB9 -:101E48000303194300280BDB0901C9B200F1604004 -:101E580000F5614080F8001330BC70470023E5E7C7 -:101E680000F00F000901C9B2024B1954F4E700BF92 -:101E780000ED00E014ED00E000F01F02400901232E -:101E88009340024A42F82030704700BF00E100E06A -:101E98000138B0F1807F0AD2064B5860064AF0211B -:101EA80082F823100020986007221A6070470120EA -:101EB800704700BF10E000E000ED00E0042805D006 -:101EC800054A136823F0040313607047024A136835 -:101ED80043F004031360704710E000E0704708B552 -:101EE800FFF7FCFF08BD0000F0B482B000263546BD -:101EF800ABE0002C63D0012C00D1CE68FF2B72D848 -:101F08008446FF2B72D8AC00DCF800200F27A740CE -:101F180022EA070206FA04F42243CCF800204A68B1 -:101F280012F0805F00F09080654A946944F00104E3 -:101F38009461926902F001020192019AAC08A71C0F -:101F4800604A52F827C005F0030297000F22BA40F2 -:101F58002CEA020C5C4A90424ED002F58062904214 -:101F680000F08B8002F58062904200F0888002F5D4 -:101F78008062904200F0858002F58062904200F015 -:101F8800828002F58062904234D0062235E04F4FBD -:101F9800BC4214D00BD94E4FBC4210D007F5803745 -:101FA800BC420CD0A7F58017BC42A7D107E0A7F523 -:101FB8008017BC4203D007F58037BC429ED18C689D -:101FC8007CB1012C08D04261082697E7CE68083614 -:101FD80094E7CE680C3691E7026108268EE7002662 -:101FE8008CE704268AE700F1040C8AE7A5F10804C7 -:101FF800A40089E7052200E00022BA4042EA0C0268 -:102008000234304F47F824204A6812F4803F3CD00D -:10201800304C22681A4322604A6812F4003F3AD0D2 -:102028002C4C62681A4362604A6812F4801F38D0E8 -:10203800284CA2681A43A2604A6812F4001F36D0DE -:10204800244CE2681343E36001350F2D35D8012293 -:10205800AA400B6813409A42F6D14C68122CB8D0AB -:1020680095D8022CB2D07FF644AF032CB7D0112CF0 -:102078007FF444AFCE68043640E70122BDE7022270 -:10208800BBE70322B9E70422B7E7124C226822EA29 -:1020980003022260C0E70F4C626822EA0302626012 -:1020A800C2E70C4CA26822EA0302A260C4E7094C0A -:1020B800E26822EA0303E360C6E702B0F0BC7047B7 -:1020C80000100240000001400008014000002110FB -:1020D80000003110000401408368194201D100203A -:1020E80070470120704712B9090401617047016106 -:1020F8007047C3685940C1607047000070B582B02E -:102108000446036813F0010F34D03E4BDB6913F02B -:10211800805F48D13B4BDA6942F08052DA61DB6973 -:1021280003F080530193019B0125374B1B6813F47F -:10213800807F3AD0334B1B6A13F4407311D0626826 -:1021480002F440729A420CD02E4A136A23F440706B -:102158002E4901260E6000260E60106213F0010F52 -:1021680037D1284A136A23F4407361680B4313621A -:10217800002D3FD1236813F0020F06D0214A53687F -:1021880023F44043A1680B435360236813F0100FF6 -:1021980035D01C4A536823F4800361690B435360AC -:1021A800002002B070BD0025BFE7174A136843F44A -:1021B8008073136000F05EF80646134B1B6813F437 -:1021C800807FB7D100F056F8801B6428F5D903202A -:1021D800E7E700F04FF806460A4B1B6A13F0020FB8 -:1021E800BFD100F047F8801B41F288339842F3D9F9 -:1021F8000320D6E7D36923F08053D361BAE70020E0 -:10220800CFE700BF00100240007000404004424287 -:102218007047000010B50446074B1868074BA3FB2E -:1022280000308009FFF734FE002221464FF0FF30CE -:10223800FFF7EEFD002010BD00000020D34D621016 -:1022480008B5074A136843F0100313600320FFF72B -:10225800CDFD0020FFF7DEFFFFF7DAFF002008BD05 -:1022680000200240024A136801331360704700BF20 -:10227800E0000020014B1868704700BFE000002014 -:1022880030B583B00190FFF7F5FF0546019CB4F126 -:10229800FF3F00D00134FFF7EDFF401BA042FAD307 -:1022A80003B030BD7047000030B482B00023019302 -:1022B80090F82430012B00F08B800246012380F82F -:1022C80024304B68062B29D80568686B03EB830319 -:1022D800053B1F249C4020EA04000C6804FA03F321 -:1022E80003436B630B68092B38D91568E86803EB5F -:1022F80043031E3B07249C4020EA04008C6804FA30 -:1023080003F30343EB600B68103B012B34D9002027 -:10231800002382F8243002B030BC70470C2B0ED852 -:102328000568286B03EB8303233B1F249C4020EAAA -:1023380004000C6804FA03F303432B63D2E705682F -:10234800E86A03EB8303413B1F249C4020EA040016 -:102358000C6804FA03F30343EB62C3E715682869C2 -:1023680003EB430307249C4020EA04008C6804FA2A -:1023780003F303432B61C6E713681648834205D06D -:10238800936A43F0200393620120C1E7986810F430 -:10239800000F1BD1986840F4000098600B68102B60 -:1023A80001D00020B4E70C4B1B680C49A1FB0313B8 -:1023B8009B0C03EB83035900019102E0019B013B55 -:1023C8000193019B002BF9D10020A1E700209FE792 -:1023D8000220A0E7002401400000002083DE1B4308 -:1023E80030B583B00023019303689A6812F0010F97 -:1023F8002ED19A6842F001029A60174B1B68174A5F -:10240800A2FB03239B0C019302E0019B013B019378 -:10241800019B002BF9D10446FFF72CFF05462368E2 -:102428009B6813F0010F11D1FFF724FF401B02280E -:10243800F5D9A36A43F01003A362E36A43F00103EA -:10244800E362002384F82430012002E0002000E049 -:10245800002003B030BD00BF0000002083DE1B4316 -:1024680090F82430012B6AD010B50446012380F877 -:102478002430FFF7B5FF024600285BD1A36A23F496 -:10248800407323F0010343F48073A36223682D494A -:102498008B4227D0A16A21F48011A162596811F4F6 -:1024A800806F05D0A16A21F4405141F48051A162A6 -:1024B800A16A11F4805F2BD0E16A21F00601E16284 -:1024C800002184F824106FF00201196023689968CC -:1024D80001F46021B1F5602F1DD0996841F4801195 -:1024E80099602AE0A1F58061496811F4702FD1D074 -:1024F800A16A41F48011A1621349496811F4806FFF -:10250800D6D0A16A21F4405141F48051A162CFE7AD -:102518000021E162D4E70B498B4204D0996841F469 -:10252800A001996009E0A1F58061496811F4702F54 -:10253800D3D1F3E7002384F82430104610BD0222DB -:1025480010467047002801400024014038B5036850 -:102558009A6812F0010F01D1002038BD04469A682C -:1025680022F001029A60FFF785FE054623689B6802 -:1025780013F0010F0ED0FFF77DFE401B0228F5D99E -:10258800A36A43F01003A362E36A43F00103E36222 -:102598000120E2E70020E0E7002800F08A8070B51B -:1025A8000446836A002B36D02046FFF7CFFFA36A84 -:1025B80013F0100377D1002875D1A26A22F488524B -:1025C80022F0020242F00202A262626825683A49D9 -:1025D8008D4226D0E1690A43E66842EA4602A168CC -:1025E800B1F5807F27D0012922D06169012925D042 -:1025F800696821F469410B436B6021688D682F4B32 -:102608002B4013438B60A368B3F5807F27D0012B41 -:1026180025D0002126E0C36280F82430FFF742FE6F -:10262800C2E7E169B1F5402FD5D14FF40021D2E7D7 -:102638004FF48073D9E74FF48073D6E736B9A169B0 -:10264800013943EA413343F40063D1E7A16A41F019 -:102658002001A162E16A41F00101E162C8E7236952 -:10266800013B19052568EB6A23F470030B43EB6201 -:1026780023689968124B0B409A420BD0A36A23F047 -:10268800120343F01003A362E36A43F00103E36219 -:1026980001200DE00023E362A36A23F0030343F063 -:1026A8000103A36204E0A36A43F01003A3620120BC -:1026B80070BD0120704700BF003C0140FDF7E1FFFD -:1026C800FE0E1FFF2DE9F84305460268136923F43F -:1026D8004053C1680B43136183680269134342691D -:1026E80013430168CA6822F4B05222F00C02134363 -:1026F800CB600268536923F4407381690B435361CB -:102708000268594B9A4257D0FFF758F800EB8000FF -:1027180000EB80006C68A400B0FBF4F4534FA7FBF7 -:10272800043464092601FFF749F800EB800000EB48 -:1027380080006C68A400B0FBF4F9FFF73FF800EBE9 -:10274800800000EB80006C68A400B0FBF4F4A7FBE9 -:10275800043464094FF0640808FB149424013234EB -:10276800A7FB0434640904F0F0043444FFF726F8A6 -:1027780000EB800000EB80006E68B600B0FBF6F658 -:10278800FFF71CF800EB800000EB80006B689B00F3 -:10279800B0FBF3F0A7FB0030400908FB10684FEAD4 -:1027A800081808F13208A7FB0837C7F343172B6846 -:1027B80027449F60BDE8F883FFF710F800EB80001E -:1027C80000EB80006C68A400B0FBF4F4274FA7FB73 -:1027D800043464092601FFF701F800EB800000EBE0 -:1027E80080006C68A400B0FBF4F9FEF7F7FF00EB7B -:1027F800800000EB80006C68A400B0FBF4F4A7FB39 -:10280800043464094FF0640808FB1494240132343A -:10281800A7FB0434640904F0F0043444FEF7DEFF37 -:1028280000EB800000EB80006E68B600B0FBF6F6A7 -:10283800FEF7D4FF00EB800000EB80006B689B0084 -:10284800B0FBF3F0A7FB0030400908FB10684FEA23 -:10285800081808F13208A7FB0837C7F343172B6895 -:1028680027449F60A6E700BF003801401F85EB5151 -:10287800704758B310B5044690F839300BB3242389 -:1028880084F839302268D36823F40053D360204693 -:10289800FFF718FF2268136923F490431361226835 -:1028A800536923F02A0353612268D36843F4005321 -:1028B800D3600020E063202384F8393084F83A306C -:1028C80010BD80F83830FFF7D3FFD8E701207047F4 -:1028D8000F4B1A6842F001021A6059680D4A0A4003 -:1028E8005A601A6822F0847222F480321A601A68D8 -:1028F80022F480221A605A6822F4FE025A604FF4C9 -:102908001F029A60044B4FF000629A60704700BF44 -:10291800001002400000FFF800ED00E030B597B06D -:102928001F4BDA6942F48022DA61DA6902F4802204 -:102938000092009A5A6942F001025A615B6903F0F9 -:1029480001030193019B174D06954FF4E13307935B -:102958000024089409940A9408230B930C940D946A -:1029680006A8FFF786FF6B6943F080036B614FF49D -:1029780080630293012304930223039303230593A3 -:1029880002A90948FFF7B0FA084B1C60084A9A6088 -:102998005C6090221A601C3B70225A6017B030BDF0 -:1029A8000010024000480040000C01401C0002409A -:1029B800044800402DE9F04F89B07B4B9A6942F0FA -:1029C80004029A619A6902F004020192019A9A69D2 -:1029D80042F008029A619A6902F008020292029A89 -:1029E8009A6942F010029A619B6903F010030393FD -:1029F800039B002305930693022707974FF0200AAD -:102A08000DEB0A0444F810AD21466848FFF76CFA4C -:102A18004023049321466548FFF766FA802504950C -:102A280021466248FFF760FA4FF480630493214619 -:102A38005F48FFF759FA4FF40063049321465C4856 -:102A4800FFF752FA4FF48056049621465848FFF78C -:102A58004BFA049621465748FFF746FA0497214651 -:102A68005448FFF741FA4FF00108CDF814804FF0B1 -:102A78000409CDF8109021464C48FFF735FA102686 -:102A8800049621464B48FFF72FFACDF810A02146AF -:102A98004848FFF729FA03230593CDF8108021460B -:102AA8004348FFF721FACDF8108021464148FFF747 -:102AB8001BFA4FF0080BCDF810B021463C48FFF741 -:102AC80013FA049721463A48FFF70EFA049621466E -:102AD8003748FFF709FACDF810A021463448FFF728 -:102AE80003FACDF8109021463148FFF7FDF9CDF8EB -:102AF80010B021462F48FFF7F7F9CDF8109021467E -:102B08002C48FFF7F1F905974023049321462848FC -:102B1800FFF7EAF9049521462548FFF7E5F94FF450 -:102B28008079CDF8109021462148FFF7DDF904950A -:102B380021462048FFF7D8F9CDF8108021461B48D8 -:102B4800FFF7D2F9049721461848FFF7CDF9CDF8D9 -:102B5800109021461748FFF7C7F94FF40073049304 -:102B680021461448FFF7C0F94FF4806304932146C7 -:102B78001048FFF7B9F94FF40053049321460B4866 -:102B8800FFF7B2F94FF48043049321460748FFF753 -:102B9800ABF94FF40043049321460448FFF7A4F926 -:102BA80009B0BDE8F08F00BF00100240000C0140E2 -:102BB80000100140000801402DE9F04F99B0754B15 -:102BC8009A6942F400629A619A6902F40062019279 -:102BD800019A9A6942F400529A619B6903F400537E -:102BE8000293029B6C4EDFF8B891C6F8009000245F -:102BF80074604FF02008C6F808804FF4FA6BC6F8E6 -:102C08000CB034617461B4613046FEF763FF102381 -:102C18001693179416A93046FFF792F860230F937E -:102C28001094119408271297139414944FF4007376 -:102C3800159322460FA93046FEF79EFF04220FA9DE -:102C48003046FEF799FF3A460FA93046FEF794FF43 -:102C58004FF4006308934FF4806309930A94CDF806 -:102C68002C800C940D940E940DEB08013046FFF760 -:102C78003BF84A4DDFF82CA1C5F800A06C60C5F8F8 -:102C88000880C5F80CB02C616C61AC612846FEF771 -:102C980021FFCDF858808023179316A92846FFF7FF -:102CA8004FF8049418A9052341F8543D2846FEF727 -:102CB800A4FE60230F931094119412971394149404 -:102CC8004FF40073159322460FA92846FEF754FFC8 -:102CD80004220FA92846FEF74FFF3A460FA92846B7 -:102CE800FEF74AFF4FF4006308934FF4806309939B -:102CF8000A94CDF82C800C940D940E940DEB0801D9 -:102D08002846FEF7F1FFDAF8443023F40043CAF806 -:102D18004430D9F8443023F40043C9F844302146FC -:102D28002846FEF7A5FF04212846FEF7A1FF3946ED -:102D38002846FEF79DFF21462846FEF7C3FF0421DB -:102D48002846FEF7BFFF39462846FEF7BBFF214657 -:102D58003046FEF78DFF04213046FEF789FF3946DD -:102D68003046FEF785FF21463046FEF7ABFF0421CB -:102D78003046FEF7A7FF39463046FEF7A3FF2B681B -:102D880001221A633268136843F00103136019B013 -:102D9800BDE8F08F00100240AC0100203C03002089 -:102DA800002C0140003401402DE9F04186B0424E2C -:102DB800B36943F40073B361B36903F40073009318 -:102DC800009B3E4C3E4B23604FF48073A36000256C -:102DD800E56065614FF44023E36165604FF00508E5 -:102DE800C4F810802046FFF7D7FB364A536843F4EF -:102DF8008023536006A94FF4C02341F8043D2046C0 -:102E0800FEF7C8FF012304930E220292039302A93E -:102E18002046FFF749FA02950227039702A92046A0 -:102E2800FFF742FA04970B2702970323039302A99B -:102E38002046FFF739FA0C2302930423039302A9CF -:102E48002046FFF731FA0723049310230293CDF8A5 -:102E58000C8002A92046FFF727FA2268936843F4FA -:102E6800000343F480739360936843F00103936015 -:102E7800736943F001037361736903F001030193FC -:102E8800019B114B1D60C3F80480104A9A60104AD8 -:102E9800DA6040F6A2221A601A6842F001021A604B -:102EA8002A4629463846FEF7B3FF3846FEF7E4FFC0 -:102EB80006B0BDE8F08100BF001002407402002097 -:102EC8000024014000000140080002404C24014059 -:102ED800E8020020F0B585B0284B9A6942F4806278 -:102EE8009A619B6903F480630093009B244C254BF3 -:102EF80023604FF48073A3600023E36063614FF4A1 -:102F08006022E2616360052626612046FFF744FBE4 -:102F1800012303930F220192029301A92046FFF790 -:102F2800C3F90D2301930225029501A92046FFF755 -:102F3800BBF903950A2301930327029701A92046A9 -:102F4800FFF7B2F90195042302930DEB0301204624 -: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 -:00000001FF diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..b68b3e0 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,22 @@ +; PlatformIO Project Configuration File2 +; http://docs.platformio.org/page/projectconf.html + +[platformio] +include_dir = Inc + +[env:genericSTM32F103RC] +platform = ststm32 +framework = stm32cube +board = genericSTM32F103RC +debug_tool = stlink +upload_protocol = stlink + +build_flags = + -I${PROJECT_DIR}/inc/ + -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