Austin Brown
/
ESCmk2_Inductance
Inductance Testing Code
Fork of CurrentModeSine by
Inverter/Inverter.cpp@1:64b881306f6f, 2018-10-11 (annotated)
- Committer:
- austinbrown124
- Date:
- Thu Oct 11 04:13:45 2018 +0000
- Revision:
- 1:64b881306f6f
- Parent:
- 0:9edd6ec0f56a
DINGBAT
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
austinbrown124 | 1:64b881306f6f | 1 | #include "Inverter.h" |
austinbrown124 | 0:9edd6ec0f56a | 2 | |
austinbrown124 | 1:64b881306f6f | 3 | |
austinbrown124 | 1:64b881306f6f | 4 | |
austinbrown124 | 1:64b881306f6f | 5 | //Condensing all hardware related variables into just this file. |
austinbrown124 | 1:64b881306f6f | 6 | //This includes all the register diddling, assigning duty cycles, etc. |
austinbrown124 | 1:64b881306f6f | 7 | //should probably have a class called "inverter" but thats a lot of effort |
austinbrown124 | 1:64b881306f6f | 8 | |
austinbrown124 | 1:64b881306f6f | 9 | Inverter::Inverter(){ |
austinbrown124 | 0:9edd6ec0f56a | 10 | |
austinbrown124 | 0:9edd6ec0f56a | 11 | |
austinbrown124 | 1:64b881306f6f | 12 | } |
austinbrown124 | 1:64b881306f6f | 13 | |
austinbrown124 | 1:64b881306f6f | 14 | void Inverter::Init_PWM(void){ |
austinbrown124 | 0:9edd6ec0f56a | 15 | |
austinbrown124 | 1:64b881306f6f | 16 | printf("\nStarting Hardware PWM\n\r"); |
austinbrown124 | 0:9edd6ec0f56a | 17 | |
austinbrown124 | 1:64b881306f6f | 18 | RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // enable the clock to GPIOA |
austinbrown124 | 1:64b881306f6f | 19 | //RCC->AHBENR |= RCC_AHBENR_IOPAEN; // the above line is supposed to be this but mbed is borked |
austinbrown124 | 1:64b881306f6f | 20 | RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable TIM1 clock |
austinbrown124 | 0:9edd6ec0f56a | 21 | |
austinbrown124 | 0:9edd6ec0f56a | 22 | |
austinbrown124 | 1:64b881306f6f | 23 | //PWM Setup |
austinbrown124 | 1:64b881306f6f | 24 | TIM1->CCMR1 |= 0x7070; // Enable output compare 1 and 2 in PWM mode 2 (inverted for low side shunts) |
austinbrown124 | 1:64b881306f6f | 25 | TIM1->CCMR2 |= 0x70; // Enable output compare 3 in PWM mode 2 (inverted for low side shunts) |
austinbrown124 | 1:64b881306f6f | 26 | TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E; // enable outputs 1, 2, 3 |
austinbrown124 | 1:64b881306f6f | 27 | //no inverting outputs. PWM mode opposite of Jaredtroller because CH1N is on high side, effectively inverts input |
austinbrown124 | 1:64b881306f6f | 28 | //no dead time needed! |
austinbrown124 | 1:64b881306f6f | 29 | TIM1->BDTR |= TIM_BDTR_MOE; //main output enable = 1 |
austinbrown124 | 1:64b881306f6f | 30 | TIM1->PSC = 0x0; // no prescaler |
austinbrown124 | 1:64b881306f6f | 31 | TIM1->ARR = PWM_ARR; // set auto reload, 20 khz |
austinbrown124 | 1:64b881306f6f | 32 | TIM1->CR1 |= TIM_CR1_ARPE; // autoreload on, |
austinbrown124 | 1:64b881306f6f | 33 | RCC->CFGR3 |= RCC_CFGR3_TIM1SW; // bump tim1 up to 144MHz |
austinbrown124 | 0:9edd6ec0f56a | 34 | |
austinbrown124 | 1:64b881306f6f | 35 | //hardware pin setup |
austinbrown124 | 1:64b881306f6f | 36 | GPIOA->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1; |
austinbrown124 | 1:64b881306f6f | 37 | GPIOA->AFR[1] |= 0x00000666; // PA8,9,10 to alternate function 6 |
austinbrown124 | 0:9edd6ec0f56a | 38 | |
austinbrown124 | 1:64b881306f6f | 39 | //interrupt generation |
austinbrown124 | 1:64b881306f6f | 40 | NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); //Enable TIM1 IRQ //dafuq is this TIM16 BS? |
austinbrown124 | 1:64b881306f6f | 41 | TIM1->DIER |= TIM_DIER_UIE; // enable update interrupt |
austinbrown124 | 1:64b881306f6f | 42 | TIM1->CR1 |= 0x40; //CMS = 10, interrupt only when counting up |
austinbrown124 | 1:64b881306f6f | 43 | TIM1->RCR |= 0x001; // update event once per up/down count of tim1 |
austinbrown124 | 0:9edd6ec0f56a | 44 | TIM1->EGR |= TIM_EGR_UG; |
austinbrown124 | 0:9edd6ec0f56a | 45 | |
austinbrown124 | 1:64b881306f6f | 46 | TIM1->CR1 |= TIM_CR1_CEN; //go! |
austinbrown124 | 1:64b881306f6f | 47 | |
austinbrown124 | 1:64b881306f6f | 48 | //sync with ADCs |
austinbrown124 | 1:64b881306f6f | 49 | |
austinbrown124 | 1:64b881306f6f | 50 | //nvm changed to Update as trgo2 |
austinbrown124 | 1:64b881306f6f | 51 | //TIM1->CR2 |= 0x200000; |
austinbrown124 | 1:64b881306f6f | 52 | |
austinbrown124 | 0:9edd6ec0f56a | 53 | |
austinbrown124 | 0:9edd6ec0f56a | 54 | } |
austinbrown124 | 0:9edd6ec0f56a | 55 | |
austinbrown124 | 1:64b881306f6f | 56 | void Inverter::Init_ADC(void){ |
austinbrown124 | 0:9edd6ec0f56a | 57 | // ADC Setup |
austinbrown124 | 1:64b881306f6f | 58 | RCC->AHBENR |= RCC_AHBENR_GPIOAEN; |
austinbrown124 | 1:64b881306f6f | 59 | RCC->AHBENR |= RCC_AHBENR_GPIOBEN; |
austinbrown124 | 1:64b881306f6f | 60 | RCC->AHBENR |= RCC_AHBENR_ADC12EN; // clock for ADC1 and 2 enable |
austinbrown124 | 1:64b881306f6f | 61 | //RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //page 149 on the ref manual |
austinbrown124 | 1:64b881306f6f | 62 | |
austinbrown124 | 1:64b881306f6f | 63 | ADC12_COMMON->CCR |= 0x20006; // Regular simultaneous mode only, sync clock? |
austinbrown124 | 1:64b881306f6f | 64 | |
austinbrown124 | 1:64b881306f6f | 65 | |
austinbrown124 | 1:64b881306f6f | 66 | /* |
austinbrown124 | 1:64b881306f6f | 67 | //for board 1 |
austinbrown124 | 1:64b881306f6f | 68 | //PA_0 is horrendously noisy! |
austinbrown124 | 1:64b881306f6f | 69 | ADC1->SQR1 = 0x80; // use PA_1 as input, ADC1 in2 |
austinbrown124 | 1:64b881306f6f | 70 | ADC2->SQR1 = 0x40; // use PA_4 as input, ADC2 in1 |
austinbrown124 | 1:64b881306f6f | 71 | GPIOA->MODER |= 0x0000030C; // Alternate function, PA_1, PA_4 are analog inputs |
austinbrown124 | 0:9edd6ec0f56a | 72 | |
austinbrown124 | 1:64b881306f6f | 73 | ADC1->SMPR1 = 256; //19.5 adc cock cycles for sample |
austinbrown124 | 1:64b881306f6f | 74 | ADC2->SMPR1 = 32; //19.5 adc cock cycles for sample. Found it works better without this |
austinbrown124 | 1:64b881306f6f | 75 | |
austinbrown124 | 1:64b881306f6f | 76 | ADC2->CR |= ADC_CR_ADEN; |
austinbrown124 | 1:64b881306f6f | 77 | ADC1->CR |= ADC_CR_ADEN; |
austinbrown124 | 1:64b881306f6f | 78 | */ |
austinbrown124 | 1:64b881306f6f | 79 | |
austinbrown124 | 1:64b881306f6f | 80 | //for board 3 |
austinbrown124 | 1:64b881306f6f | 81 | ADC1->SQR1 = 0x40; // use PA_0 as input, ADC1 in1 |
austinbrown124 | 1:64b881306f6f | 82 | ADC2->SQR1 = 0x40; // use PA_4 as input, ADC2 in1 |
austinbrown124 | 1:64b881306f6f | 83 | GPIOA->MODER |= 0x00000303; // Alternate function, PA_0, PA_4 are analog inputs |
austinbrown124 | 0:9edd6ec0f56a | 84 | |
austinbrown124 | 1:64b881306f6f | 85 | ADC1->SMPR1 = 32; //19.5 adc cock cycles for sample |
austinbrown124 | 1:64b881306f6f | 86 | ADC2->SMPR1 = 32; //19.5 adc cock cycles for sample. Found it works better without this |
austinbrown124 | 1:64b881306f6f | 87 | |
austinbrown124 | 1:64b881306f6f | 88 | ADC2->CR |= ADC_CR_ADEN; |
austinbrown124 | 1:64b881306f6f | 89 | ADC1->CR |= ADC_CR_ADEN; |
austinbrown124 | 1:64b881306f6f | 90 | |
austinbrown124 | 1:64b881306f6f | 91 | //may try the sync clock later |
austinbrown124 | 0:9edd6ec0f56a | 92 | |
austinbrown124 | 1:64b881306f6f | 93 | } |
austinbrown124 | 1:64b881306f6f | 94 | |
austinbrown124 | 1:64b881306f6f | 95 | |
austinbrown124 | 1:64b881306f6f | 96 | |
austinbrown124 | 1:64b881306f6f | 97 | |
austinbrown124 | 1:64b881306f6f | 98 | void Inverter::Init(){ |
austinbrown124 | 0:9edd6ec0f56a | 99 | wait_ms(100); |
austinbrown124 | 0:9edd6ec0f56a | 100 | Init_ADC(); |
austinbrown124 | 0:9edd6ec0f56a | 101 | wait(0.1); |
austinbrown124 | 1:64b881306f6f | 102 | Init_PWM(); |
austinbrown124 | 0:9edd6ec0f56a | 103 | |
austinbrown124 | 1:64b881306f6f | 104 | } |
austinbrown124 | 1:64b881306f6f | 105 | |
austinbrown124 | 1:64b881306f6f | 106 | void Inverter::zero_current(){ |
austinbrown124 | 1:64b881306f6f | 107 | int adc1_offset_s = 0; |
austinbrown124 | 1:64b881306f6f | 108 | int adc2_offset_s = 0; |
austinbrown124 | 1:64b881306f6f | 109 | int n = 1024; |
austinbrown124 | 1:64b881306f6f | 110 | for (int i = 0; i<n; i++){ |
austinbrown124 | 1:64b881306f6f | 111 | ADC1->CR |= ADC_CR_ADSTART; |
austinbrown124 | 1:64b881306f6f | 112 | //wait_us(5); |
austinbrown124 | 1:64b881306f6f | 113 | for (volatile int t = 0; t < 16; t++) {} |
austinbrown124 | 1:64b881306f6f | 114 | adc2_offset_s += ADC2->DR; |
austinbrown124 | 1:64b881306f6f | 115 | adc1_offset_s += ADC1->DR; |
austinbrown124 | 1:64b881306f6f | 116 | } |
austinbrown124 | 1:64b881306f6f | 117 | adc1_offset = adc1_offset_s/n; |
austinbrown124 | 1:64b881306f6f | 118 | adc2_offset = adc2_offset_s/n; |
austinbrown124 | 1:64b881306f6f | 119 | |
austinbrown124 | 1:64b881306f6f | 120 | } |
austinbrown124 | 1:64b881306f6f | 121 | |
austinbrown124 | 1:64b881306f6f | 122 | void Inverter::ADCsync() { |
austinbrown124 | 1:64b881306f6f | 123 | //EXTEN[1:0] = 01 |
austinbrown124 | 1:64b881306f6f | 124 | //EXTSEL[3:0] = 1010 |
austinbrown124 | 1:64b881306f6f | 125 | |
austinbrown124 | 1:64b881306f6f | 126 | //this code works to slave to center of TIM1 update |
austinbrown124 | 1:64b881306f6f | 127 | ADC1->CFGR |= ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTEN_1; |
austinbrown124 | 1:64b881306f6f | 128 | ADC1->CFGR |= ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_1; |
austinbrown124 | 1:64b881306f6f | 129 | TIM1->CR2 |= TIM_CR2_MMS2_1; |
austinbrown124 | 1:64b881306f6f | 130 | ADC1->CR |= ADC_CR_ADSTART; |
austinbrown124 | 1:64b881306f6f | 131 | } |
austinbrown124 | 1:64b881306f6f | 132 | |
austinbrown124 | 1:64b881306f6f | 133 | //below is inverter- specific. May have to rearrange i_a and stuff depending on board |
austinbrown124 | 1:64b881306f6f | 134 | /* |
austinbrown124 | 1:64b881306f6f | 135 | void Inverter::GetCurrents(FocStruct *focc){ |
austinbrown124 | 1:64b881306f6f | 136 | |
austinbrown124 | 1:64b881306f6f | 137 | if (!INVERT_MOTOR_DIR) { |
austinbrown124 | 1:64b881306f6f | 138 | focc->i_b = I_SCALE*(float)(adc1_raw - adc1_offset); |
austinbrown124 | 1:64b881306f6f | 139 | focc->i_a = I_SCALE*(float)(adc2_raw - adc2_offset); |
austinbrown124 | 1:64b881306f6f | 140 | focc->i_c = -focc->i_a - focc->i_b; |
austinbrown124 | 1:64b881306f6f | 141 | } |
austinbrown124 | 1:64b881306f6f | 142 | else { |
austinbrown124 | 1:64b881306f6f | 143 | focc->i_c = I_SCALE*(float)(adc1_raw - adc1_offset); |
austinbrown124 | 1:64b881306f6f | 144 | focc->i_a = I_SCALE*(float)(adc2_raw - adc2_offset); |
austinbrown124 | 1:64b881306f6f | 145 | focc->i_b = -focc->i_a - focc->i_c; |
austinbrown124 | 1:64b881306f6f | 146 | } |
austinbrown124 | 1:64b881306f6f | 147 | |
austinbrown124 | 1:64b881306f6f | 148 | } |
austinbrown124 | 1:64b881306f6f | 149 | |
austinbrown124 | 1:64b881306f6f | 150 | void Inverter::SetDutyCycles (FocStruct *focc) { |
austinbrown124 | 0:9edd6ec0f56a | 151 | |
austinbrown124 | 1:64b881306f6f | 152 | if (!INVERT_MOTOR_DIR) { |
austinbrown124 | 1:64b881306f6f | 153 | TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_u); |
austinbrown124 | 1:64b881306f6f | 154 | TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); |
austinbrown124 | 1:64b881306f6f | 155 | TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_w); |
austinbrown124 | 1:64b881306f6f | 156 | } |
austinbrown124 | 1:64b881306f6f | 157 | else { |
austinbrown124 | 1:64b881306f6f | 158 | TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_u); |
austinbrown124 | 1:64b881306f6f | 159 | TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); |
austinbrown124 | 1:64b881306f6f | 160 | TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_w); |
austinbrown124 | 1:64b881306f6f | 161 | } |
austinbrown124 | 1:64b881306f6f | 162 | |
austinbrown124 | 1:64b881306f6f | 163 | |
austinbrown124 | 1:64b881306f6f | 164 | }*/ |
austinbrown124 | 1:64b881306f6f | 165 | |
austinbrown124 | 1:64b881306f6f | 166 | |
austinbrown124 | 1:64b881306f6f | 167 | |
austinbrown124 | 1:64b881306f6f | 168 | void Inverter::GetCurrents(FocStruct *focc){ |
austinbrown124 | 1:64b881306f6f | 169 | |
austinbrown124 | 1:64b881306f6f | 170 | if (!INVERT_MOTOR_DIR) { |
austinbrown124 | 1:64b881306f6f | 171 | focc->i_a = I_SCALE*(float)(adc1_raw - adc1_offset); |
austinbrown124 | 1:64b881306f6f | 172 | focc->i_b = I_SCALE*(float)(adc2_raw - adc2_offset); |
austinbrown124 | 1:64b881306f6f | 173 | focc->i_c = -focc->i_a - focc->i_b; |
austinbrown124 | 1:64b881306f6f | 174 | } |
austinbrown124 | 1:64b881306f6f | 175 | else { |
austinbrown124 | 1:64b881306f6f | 176 | focc->i_c = I_SCALE*(float)(adc1_raw - adc1_offset); |
austinbrown124 | 1:64b881306f6f | 177 | focc->i_b = I_SCALE*(float)(adc2_raw - adc2_offset); |
austinbrown124 | 1:64b881306f6f | 178 | focc->i_a = -focc->i_b - focc->i_c; |
austinbrown124 | 1:64b881306f6f | 179 | } |
austinbrown124 | 1:64b881306f6f | 180 | |
austinbrown124 | 1:64b881306f6f | 181 | } |
austinbrown124 | 1:64b881306f6f | 182 | |
austinbrown124 | 1:64b881306f6f | 183 | void Inverter::SetDutyCycles (FocStruct *focc) { |
austinbrown124 | 0:9edd6ec0f56a | 184 | |
austinbrown124 | 1:64b881306f6f | 185 | if (!INVERT_MOTOR_DIR) { |
austinbrown124 | 1:64b881306f6f | 186 | TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_u); |
austinbrown124 | 1:64b881306f6f | 187 | TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); |
austinbrown124 | 1:64b881306f6f | 188 | TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_w); |
austinbrown124 | 1:64b881306f6f | 189 | } |
austinbrown124 | 1:64b881306f6f | 190 | else { |
austinbrown124 | 1:64b881306f6f | 191 | TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_u); |
austinbrown124 | 1:64b881306f6f | 192 | TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); |
austinbrown124 | 1:64b881306f6f | 193 | TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_w); |
austinbrown124 | 1:64b881306f6f | 194 | } |
austinbrown124 | 1:64b881306f6f | 195 | |
austinbrown124 | 1:64b881306f6f | 196 | |
austinbrown124 | 1:64b881306f6f | 197 | } |
austinbrown124 | 1:64b881306f6f | 198 | |
austinbrown124 | 1:64b881306f6f | 199 | |
austinbrown124 | 1:64b881306f6f | 200 | /*for board 3: |
austinbrown124 | 1:64b881306f6f | 201 | |
austinbrown124 | 1:64b881306f6f | 202 | CCR3 -> phase C |
austinbrown124 | 1:64b881306f6f | 203 | so if non inverted, U in FW is A on gd. |
austinbrown124 | 1:64b881306f6f | 204 | V is CCR2 |
austinbrown124 | 1:64b881306f6f | 205 | so A is ADC1 |
austinbrown124 | 1:64b881306f6f | 206 | |
austinbrown124 | 1:64b881306f6f | 207 | |
austinbrown124 | 1:64b881306f6f | 208 | |
austinbrown124 | 1:64b881306f6f | 209 | |
austinbrown124 | 1:64b881306f6f | 210 | |
austinbrown124 | 1:64b881306f6f | 211 | */ |
austinbrown124 | 1:64b881306f6f | 212 | |
austinbrown124 | 1:64b881306f6f | 213 | |
austinbrown124 | 1:64b881306f6f | 214 | |
austinbrown124 | 1:64b881306f6f | 215 | |
austinbrown124 | 1:64b881306f6f | 216 | |
austinbrown124 | 1:64b881306f6f | 217 | |
austinbrown124 | 1:64b881306f6f | 218 |