Inductance Testing Code

Dependencies:   mbed

Fork of CurrentModeSine by Austin Brown

Inverter/Inverter.cpp

Committer:
austinbrown124
Date:
2018-10-11
Revision:
1:64b881306f6f
Parent:
0:9edd6ec0f56a

File content as of revision 1:64b881306f6f:

#include "Inverter.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 Inverter::Init_PWM(void){
    
    printf("\nStarting Hardware PWM\n\r");
    
    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

    
    //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
    
    //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
    
    //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;  
    
    
    }

void Inverter::Init_ADC(void){
        // ADC Setup
    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 

    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 Inverter::Init(){
    wait_ms(100);
    Init_ADC();
    wait(0.1);         
    Init_PWM();
    
    }
    
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) {
    
    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) {
    
    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





*/