Inductance Testing Code

Dependencies:   mbed

Fork of CurrentModeSine by Austin Brown

Committer:
austinbrown124
Date:
Thu Oct 11 04:13:45 2018 +0000
Revision:
1:64b881306f6f
Parent:
0:9edd6ec0f56a
DINGBAT

Who changed what in which revision?

UserRevisionLine numberNew 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