Austin Brown
/
ESCmk2_Inductance
Inductance Testing Code
Fork of CurrentModeSine by
Embed:
(wiki syntax)
Show/hide line numbers
Inverter.cpp
00001 #include "Inverter.h" 00002 00003 00004 00005 //Condensing all hardware related variables into just this file. 00006 //This includes all the register diddling, assigning duty cycles, etc. 00007 //should probably have a class called "inverter" but thats a lot of effort 00008 00009 Inverter::Inverter(){ 00010 00011 00012 } 00013 00014 void Inverter::Init_PWM(void){ 00015 00016 printf("\nStarting Hardware PWM\n\r"); 00017 00018 RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // enable the clock to GPIOA 00019 //RCC->AHBENR |= RCC_AHBENR_IOPAEN; // the above line is supposed to be this but mbed is borked 00020 RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable TIM1 clock 00021 00022 00023 //PWM Setup 00024 TIM1->CCMR1 |= 0x7070; // Enable output compare 1 and 2 in PWM mode 2 (inverted for low side shunts) 00025 TIM1->CCMR2 |= 0x70; // Enable output compare 3 in PWM mode 2 (inverted for low side shunts) 00026 TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E; // enable outputs 1, 2, 3 00027 //no inverting outputs. PWM mode opposite of Jaredtroller because CH1N is on high side, effectively inverts input 00028 //no dead time needed! 00029 TIM1->BDTR |= TIM_BDTR_MOE; //main output enable = 1 00030 TIM1->PSC = 0x0; // no prescaler 00031 TIM1->ARR = PWM_ARR; // set auto reload, 20 khz 00032 TIM1->CR1 |= TIM_CR1_ARPE; // autoreload on, 00033 RCC->CFGR3 |= RCC_CFGR3_TIM1SW; // bump tim1 up to 144MHz 00034 00035 //hardware pin setup 00036 GPIOA->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1; 00037 GPIOA->AFR[1] |= 0x00000666; // PA8,9,10 to alternate function 6 00038 00039 //interrupt generation 00040 NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); //Enable TIM1 IRQ //dafuq is this TIM16 BS? 00041 TIM1->DIER |= TIM_DIER_UIE; // enable update interrupt 00042 TIM1->CR1 |= 0x40; //CMS = 10, interrupt only when counting up 00043 TIM1->RCR |= 0x001; // update event once per up/down count of tim1 00044 TIM1->EGR |= TIM_EGR_UG; 00045 00046 TIM1->CR1 |= TIM_CR1_CEN; //go! 00047 00048 //sync with ADCs 00049 00050 //nvm changed to Update as trgo2 00051 //TIM1->CR2 |= 0x200000; 00052 00053 00054 } 00055 00056 void Inverter::Init_ADC(void){ 00057 // ADC Setup 00058 RCC->AHBENR |= RCC_AHBENR_GPIOAEN; 00059 RCC->AHBENR |= RCC_AHBENR_GPIOBEN; 00060 RCC->AHBENR |= RCC_AHBENR_ADC12EN; // clock for ADC1 and 2 enable 00061 //RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //page 149 on the ref manual 00062 00063 ADC12_COMMON->CCR |= 0x20006; // Regular simultaneous mode only, sync clock? 00064 00065 00066 /* 00067 //for board 1 00068 //PA_0 is horrendously noisy! 00069 ADC1->SQR1 = 0x80; // use PA_1 as input, ADC1 in2 00070 ADC2->SQR1 = 0x40; // use PA_4 as input, ADC2 in1 00071 GPIOA->MODER |= 0x0000030C; // Alternate function, PA_1, PA_4 are analog inputs 00072 00073 ADC1->SMPR1 = 256; //19.5 adc cock cycles for sample 00074 ADC2->SMPR1 = 32; //19.5 adc cock cycles for sample. Found it works better without this 00075 00076 ADC2->CR |= ADC_CR_ADEN; 00077 ADC1->CR |= ADC_CR_ADEN; 00078 */ 00079 00080 //for board 3 00081 ADC1->SQR1 = 0x40; // use PA_0 as input, ADC1 in1 00082 ADC2->SQR1 = 0x40; // use PA_4 as input, ADC2 in1 00083 GPIOA->MODER |= 0x00000303; // Alternate function, PA_0, PA_4 are analog inputs 00084 00085 ADC1->SMPR1 = 32; //19.5 adc cock cycles for sample 00086 ADC2->SMPR1 = 32; //19.5 adc cock cycles for sample. Found it works better without this 00087 00088 ADC2->CR |= ADC_CR_ADEN; 00089 ADC1->CR |= ADC_CR_ADEN; 00090 00091 //may try the sync clock later 00092 00093 } 00094 00095 00096 00097 00098 void Inverter::Init(){ 00099 wait_ms(100); 00100 Init_ADC(); 00101 wait(0.1); 00102 Init_PWM(); 00103 00104 } 00105 00106 void Inverter::zero_current(){ 00107 int adc1_offset_s = 0; 00108 int adc2_offset_s = 0; 00109 int n = 1024; 00110 for (int i = 0; i<n; i++){ 00111 ADC1->CR |= ADC_CR_ADSTART; 00112 //wait_us(5); 00113 for (volatile int t = 0; t < 16; t++) {} 00114 adc2_offset_s += ADC2->DR; 00115 adc1_offset_s += ADC1->DR; 00116 } 00117 adc1_offset = adc1_offset_s/n; 00118 adc2_offset = adc2_offset_s/n; 00119 00120 } 00121 00122 void Inverter::ADCsync() { 00123 //EXTEN[1:0] = 01 00124 //EXTSEL[3:0] = 1010 00125 00126 //this code works to slave to center of TIM1 update 00127 ADC1->CFGR |= ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTEN_1; 00128 ADC1->CFGR |= ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_1; 00129 TIM1->CR2 |= TIM_CR2_MMS2_1; 00130 ADC1->CR |= ADC_CR_ADSTART; 00131 } 00132 00133 //below is inverter- specific. May have to rearrange i_a and stuff depending on board 00134 /* 00135 void Inverter::GetCurrents(FocStruct *focc){ 00136 00137 if (!INVERT_MOTOR_DIR) { 00138 focc->i_b = I_SCALE*(float)(adc1_raw - adc1_offset); 00139 focc->i_a = I_SCALE*(float)(adc2_raw - adc2_offset); 00140 focc->i_c = -focc->i_a - focc->i_b; 00141 } 00142 else { 00143 focc->i_c = I_SCALE*(float)(adc1_raw - adc1_offset); 00144 focc->i_a = I_SCALE*(float)(adc2_raw - adc2_offset); 00145 focc->i_b = -focc->i_a - focc->i_c; 00146 } 00147 00148 } 00149 00150 void Inverter::SetDutyCycles (FocStruct *focc) { 00151 00152 if (!INVERT_MOTOR_DIR) { 00153 TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_u); 00154 TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); 00155 TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_w); 00156 } 00157 else { 00158 TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_u); 00159 TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); 00160 TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_w); 00161 } 00162 00163 00164 }*/ 00165 00166 00167 00168 void Inverter::GetCurrents(FocStruct *focc){ 00169 00170 if (!INVERT_MOTOR_DIR) { 00171 focc->i_a = I_SCALE*(float)(adc1_raw - adc1_offset); 00172 focc->i_b = I_SCALE*(float)(adc2_raw - adc2_offset); 00173 focc->i_c = -focc->i_a - focc->i_b; 00174 } 00175 else { 00176 focc->i_c = I_SCALE*(float)(adc1_raw - adc1_offset); 00177 focc->i_b = I_SCALE*(float)(adc2_raw - adc2_offset); 00178 focc->i_a = -focc->i_b - focc->i_c; 00179 } 00180 00181 } 00182 00183 void Inverter::SetDutyCycles (FocStruct *focc) { 00184 00185 if (!INVERT_MOTOR_DIR) { 00186 TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_u); 00187 TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); 00188 TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_w); 00189 } 00190 else { 00191 TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_u); 00192 TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); 00193 TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_w); 00194 } 00195 00196 00197 } 00198 00199 00200 /*for board 3: 00201 00202 CCR3 -> phase C 00203 so if non inverted, U in FW is A on gd. 00204 V is CCR2 00205 so A is ADC1 00206 00207 00208 00209 00210 00211 */ 00212 00213 00214 00215 00216 00217 00218
Generated on Wed Jul 13 2022 19:52:22 by 1.7.2