Austin Brown
/
ESCmk2_Inductance
Inductance Testing Code
Fork of CurrentModeSine by
Diff: Inverter/Inverter.cpp
- Revision:
- 1:64b881306f6f
- Parent:
- 0:9edd6ec0f56a
diff -r 9edd6ec0f56a -r 64b881306f6f Inverter/Inverter.cpp --- a/Inverter/Inverter.cpp Sat May 20 21:42:20 2017 +0000 +++ b/Inverter/Inverter.cpp Thu Oct 11 04:13:45 2018 +0000 @@ -1,96 +1,218 @@ +#include "Inverter.h" -#include "mbed.h" -#include "hw_pins.h" -//#include "hw_config.h" -#include "structs.h" -#include "FastPWM.h" + + +//Condensing all hardware related variables into just this file. +//This includes all the register diddling, assigning duty cycles, etc. +//should probably have a class called "inverter" but thats a lot of effort + +Inverter::Inverter(){ -void Init_PWM(GPIOStruct *gpio){ - printf("\nStarting Hardware Function\n\r"); + } + +void Inverter::Init_PWM(void){ - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // enable the clock to GPIOC - RCC->APB1ENR |= 0x00000001; // enable TIM2 clock - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable TIM1 clock + printf("\nStarting Hardware PWM\n\r"); - GPIOC->MODER |= (1 << 10); // set pin 5 to be general purpose output for LED + RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // enable the clock to GPIOA + //RCC->AHBENR |= RCC_AHBENR_IOPAEN; // the above line is supposed to be this but mbed is borked + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable TIM1 clock - //gpio->enable = new DigitalOut(ENABLE_PIN); - gpio->pwm_ul = new FastPWM(PIN_AL); - gpio->pwm_vl = new FastPWM(PIN_BL); - gpio->pwm_wl = new FastPWM(PIN_CL); - gpio->pwm_uh = new FastPWM(PIN_AH); - gpio->pwm_vh = new FastPWM(PIN_BH); - gpio->pwm_wh = new FastPWM(PIN_CH); - - gpio->phasing = 1; + //PWM Setup + TIM1->CCMR1 |= 0x7070; // Enable output compare 1 and 2 in PWM mode 2 (inverted for low side shunts) + TIM1->CCMR2 |= 0x70; // Enable output compare 3 in PWM mode 2 (inverted for low side shunts) + TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E; // enable outputs 1, 2, 3 + //no inverting outputs. PWM mode opposite of Jaredtroller because CH1N is on high side, effectively inverts input + //no dead time needed! + TIM1->BDTR |= TIM_BDTR_MOE; //main output enable = 1 + TIM1->PSC = 0x0; // no prescaler + TIM1->ARR = PWM_ARR; // set auto reload, 20 khz + TIM1->CR1 |= TIM_CR1_ARPE; // autoreload on, + RCC->CFGR3 |= RCC_CFGR3_TIM1SW; // bump tim1 up to 144MHz - //ISR Setup - - NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); //Enable TIM1 IRQ + //hardware pin setup + GPIOA->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1; + GPIOA->AFR[1] |= 0x00000666; // PA8,9,10 to alternate function 6 - TIM1->DIER |= TIM_DIER_UIE; // enable update interrupt - TIM1->CR1 = 0x40; // CMS = 10, interrupt only when counting up - TIM1->CR1 |= TIM_CR1_UDIS; - TIM1->CR1 |= TIM_CR1_ARPE; // autoreload on, - TIM1->RCR |= 0x001; // update event once per up/down count of tim1 + //interrupt generation + NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); //Enable TIM1 IRQ //dafuq is this TIM16 BS? + TIM1->DIER |= TIM_DIER_UIE; // enable update interrupt + TIM1->CR1 |= 0x40; //CMS = 10, interrupt only when counting up + TIM1->RCR |= 0x001; // update event once per up/down count of tim1 TIM1->EGR |= TIM_EGR_UG; + TIM1->CR1 |= TIM_CR1_CEN; //go! + + //sync with ADCs + + //nvm changed to Update as trgo2 + //TIM1->CR2 |= 0x200000; + - //PWM Setup - TIM1->DIER |= TIM_DIER_UIE; // enable update interrupt - TIM1->CR1 = 0x40;//CMS = 10, interrupt only when counting up - - TIM1->CR1 |= TIM_CR1_ARPE; // autoreload on, - TIM1->RCR |= 0x001; // update event once per up/down count of tim1 - TIM1->EGR |= TIM_EGR_UG; - - - //PWM Setup - TIM1->PSC = 0x0; // no prescaler, timer counts up in sync with the peripheral clock - TIM1->ARR = 0x1194; // 20 Khz - //TIM1->BDTR |= TIM_BDTR_MOE; - //TIM1->BDTR |= TIM_BDTR_OSSI; - //TIM1->BDTR |= TIM_BDTR_OSSR; - TIM1->BDTR |= 0xBF; - TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1NE | TIM_CCER_CC2E | TIM_CCER_CC2NE | TIM_CCER_CC3E | TIM_CCER_CC3NE; - //TIM1->CCER |= ~TIM_CCER_CC1NP; //Interupt when low side is on. - //TIM1->CCER |= TIM_CCER_CC1NP; - TIM1->CR1 |= TIM_CR1_CEN; - - } -void Init_ADC(void){ +void Inverter::Init_ADC(void){ // ADC Setup - RCC->APB2ENR |= RCC_APB2ENR_ADC2EN; // clock for ADC2 - RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // clock for ADC1 - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // Enable clock for GPIOC - - ADC->CCR = 0x00000006; // Regular simultaneous mode only - ADC1->CR2 |= ADC_CR2_ADON;//0x00000001; // ADC1 ON - ADC1->SQR3 = 0x000000A; // use PC_0 as input this is the V phase - ADC2->CR2 |= ADC_CR2_ADON;//0x00000001; // ADC1 ON - ADC2->SQR3 = 0x0000000B; // use PC_1 as input. This is the U phase - GPIOC->MODER |= 0x0000000f; // Alternate function, PC_0, PC_1 are analog inputs + RCC->AHBENR |= RCC_AHBENR_GPIOAEN; + RCC->AHBENR |= RCC_AHBENR_GPIOBEN; + RCC->AHBENR |= RCC_AHBENR_ADC12EN; // clock for ADC1 and 2 enable + //RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //page 149 on the ref manual + + ADC12_COMMON->CCR |= 0x20006; // Regular simultaneous mode only, sync clock? + + + /* + //for board 1 + //PA_0 is horrendously noisy! + ADC1->SQR1 = 0x80; // use PA_1 as input, ADC1 in2 + ADC2->SQR1 = 0x40; // use PA_4 as input, ADC2 in1 + GPIOA->MODER |= 0x0000030C; // Alternate function, PA_1, PA_4 are analog inputs - } + ADC1->SMPR1 = 256; //19.5 adc cock cycles for sample + ADC2->SMPR1 = 32; //19.5 adc cock cycles for sample. Found it works better without this + + ADC2->CR |= ADC_CR_ADEN; + ADC1->CR |= ADC_CR_ADEN; + */ + + //for board 3 + ADC1->SQR1 = 0x40; // use PA_0 as input, ADC1 in1 + ADC2->SQR1 = 0x40; // use PA_4 as input, ADC2 in1 + GPIOA->MODER |= 0x00000303; // Alternate function, PA_0, PA_4 are analog inputs -void Init_DAC(void){ - RCC->APB1ENR |= 0x20000000; // Enable clock for DAC - DAC->CR |= 0x00000001; // DAC control reg, both channels ON - GPIOA->MODER |= 0x00000300; // PA04 as analog output - } + ADC1->SMPR1 = 32; //19.5 adc cock cycles for sample + ADC2->SMPR1 = 32; //19.5 adc cock cycles for sample. Found it works better without this + + ADC2->CR |= ADC_CR_ADEN; + ADC1->CR |= ADC_CR_ADEN; + + //may try the sync clock later -void Init_All_HW(GPIOStruct *gpio){ +} + + + + +void Inverter::Init(){ wait_ms(100); Init_ADC(); wait(0.1); + Init_PWM(); - //Init_DAC(); - wait(0.1); + } + +void Inverter::zero_current(){ + int adc1_offset_s = 0; + int adc2_offset_s = 0; + int n = 1024; + for (int i = 0; i<n; i++){ + ADC1->CR |= ADC_CR_ADSTART; + //wait_us(5); + for (volatile int t = 0; t < 16; t++) {} + adc2_offset_s += ADC2->DR; + adc1_offset_s += ADC1->DR; + } + adc1_offset = adc1_offset_s/n; + adc2_offset = adc2_offset_s/n; + + } + +void Inverter::ADCsync() { + //EXTEN[1:0] = 01 + //EXTSEL[3:0] = 1010 + + //this code works to slave to center of TIM1 update + ADC1->CFGR |= ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTEN_1; + ADC1->CFGR |= ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_1; + TIM1->CR2 |= TIM_CR2_MMS2_1; + ADC1->CR |= ADC_CR_ADSTART; +} + +//below is inverter- specific. May have to rearrange i_a and stuff depending on board +/* +void Inverter::GetCurrents(FocStruct *focc){ + + if (!INVERT_MOTOR_DIR) { + focc->i_b = I_SCALE*(float)(adc1_raw - adc1_offset); + focc->i_a = I_SCALE*(float)(adc2_raw - adc2_offset); + focc->i_c = -focc->i_a - focc->i_b; + } + else { + focc->i_c = I_SCALE*(float)(adc1_raw - adc1_offset); + focc->i_a = I_SCALE*(float)(adc2_raw - adc2_offset); + focc->i_b = -focc->i_a - focc->i_c; + } + +} + +void Inverter::SetDutyCycles (FocStruct *focc) { - Init_PWM(gpio); + if (!INVERT_MOTOR_DIR) { + TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_u); + TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); + TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_w); + } + else { + TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_u); + TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); + TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_w); + } + + +}*/ + + + +void Inverter::GetCurrents(FocStruct *focc){ + + if (!INVERT_MOTOR_DIR) { + focc->i_a = I_SCALE*(float)(adc1_raw - adc1_offset); + focc->i_b = I_SCALE*(float)(adc2_raw - adc2_offset); + focc->i_c = -focc->i_a - focc->i_b; + } + else { + focc->i_c = I_SCALE*(float)(adc1_raw - adc1_offset); + focc->i_b = I_SCALE*(float)(adc2_raw - adc2_offset); + focc->i_a = -focc->i_b - focc->i_c; + } + +} + +void Inverter::SetDutyCycles (FocStruct *focc) { - } \ No newline at end of file + if (!INVERT_MOTOR_DIR) { + TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_u); + TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); + TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_w); + } + else { + TIM1->CCR1 = PWM_ARR*(1.0f - focc->dtc_u); + TIM1->CCR2 = PWM_ARR*(1.0f - focc->dtc_v); + TIM1->CCR3 = PWM_ARR*(1.0f - focc->dtc_w); + } + + +} + + +/*for board 3: + +CCR3 -> phase C +so if non inverted, U in FW is A on gd. +V is CCR2 +so A is ADC1 + + + + + +*/ + + + + + + + \ No newline at end of file