//***************************************************************************** // //! Updates the duty cycle in the PWM module. //! //! This function programs the duty cycle of the PWM waveforms into the PWM //! module. The changes will be written to the hardware and the hardware //! instructed to start using the new values the next time its counters reach //! zero. //! //! \return None. // //***************************************************************************** static void PWMUpdateDutyCycle(void) { unsigned long ulWidth; // // Get the pulse width of the U phase of the motor. If the width of the // positive portion of the pulse is less than the minimum pulse width, then // force the signal low continuously. If the width of the negative portion // of the pulse is less than the minimum pulse width, then force the signal // high continuously. // ulWidth = (g_ulPWMDutyCycleRoll * ulPeriod) / 65536; //if(ulWidth < g_ulMinPulseWidth) //{ // ulWidth = g_ulMinPulseWidth; //} //if((g_ulPWMClock - ulWidth) < g_ulMinPulseWidth) //{ // ulWidth = g_ulPWMClock - g_ulMinPulseWidth; //} // // Set the pulse width of the ROLL phase of the motor. // PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, ulWidth); PWMPulseWidthSet(PWM_BASE, PWM_OUT_1, ulWidth); // // Get the pulse width of the Pitch phase of the motor. // ulWidth = (g_ulPWMDutyCyclePitch * ulPeriod) / 65536; //if(ulWidth < g_ulMinPulseWidth) //{ // ulWidth = g_ulMinPulseWidth; //} //if((g_ulPWMClock - ulWidth) < g_ulMinPulseWidth) //{ // ulWidth = g_ulPWMClock - g_ulMinPulseWidth; //} // // Set the pulse width of the Pitch phase of the motor. // PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, ulWidth); PWMPulseWidthSet(PWM1_BASE, PWM_OUT_1, ulWidth); // // Perform a synchronous update of all three PWM generators. // PWMSyncUpdate(PWM_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT); PWMSyncUpdate(PWM1_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT); }
//***************************************************************************** // //! Sets the PWM outputs to precharge the high side gate drives. //! //! This function configures the PWM outputs such that they will start charging //! the bootstrap capacitor on the high side gate drives. Without this step, //! the high side gates will not turn on properly for the first several PWM //! cycles when starting the motor drive. //! //! \return None. // //***************************************************************************** void PWMOutputPrecharge(void) { unsigned long ulTemp; // // If the motor drive is in a faulted state, don't do anything else. // if(MainIsFaulted()) { return; } // // Ensure that the deadband is disabled. // PWMClearDeadBand(); // // Disable all six PWM outputs. // PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT | PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT), false); // // Set the PWM period based on the configured PWM frequency. // PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, g_ulPWMClock); PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, g_ulPWMClock); PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, g_ulPWMClock); // // Set the PWM duty cycles to 1%. // ulTemp = (g_ulPWMClock / 100) + 1; if(ulTemp < (g_sParameters.ucDeadTime + 1)) { ulTemp = (g_sParameters.ucDeadTime + 1); } // // Update global parameters (for Trapezoid, A=B=C, for Sinusoid, don't // matter). // g_ulPWMWidth = ulTemp; g_ulTrapDutyCycle = (g_ulPWMWidth * 10000) / g_ulPWMClock; // // Set A, B, and C PWM output duty cycles (all generator outputs). // PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, ulTemp); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, ulTemp); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, ulTemp); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_3, ulTemp); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_4, ulTemp); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5, ulTemp); // // Perform a synchronous update of all three PWM generators. // PWMSyncUpdate(PWM0_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT); // // Indicate that a precharge has been started. // HWREGBITW(&g_ulPWMFlags, PWM_FLAG_NEW_PRECHARGE) = 1; }
void hardware_init(void) { //Set PWM clock at the same frequency as system clock SysCtlPWMClockSet(SYSCTL_PWMDIV_1); /* * Inverter system setup * period : Switching Frequency : 20Khz * cycle : Duty Cycle SPWM * deadband : Deadband */ inv.period = SysCtlClockGet()/20000; inv.deadband = 25*inv.period/100; inv.cycle = inv.period*500/1000; /* * Boost converter system setup * period: Switching frequency: 20kHz * cycle: Duty cycle * deadband: Deadband */ conv.period = inv.period; conv.deadband = inv.deadband; conv.cycle = conv.period*500/1000; /* * Setup SPWM on PWM0 GEN0 and GEN1 * PB6 : PWM0 GEN0 * PB7: PWM0 GEN1 */ SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralReset(SYSCTL_PERIPH_PWM0); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOB); GPIOPinConfigure(GPIO_PB6_M0PWM0); GPIOPinConfigure(GPIO_PB7_M0PWM1); GPIOPinTypePWM(GPIO_PORTB_BASE, (GPIO_PIN_6 | GPIO_PIN_7)); PWMGenConfigure(PWM0_BASE, PWM_GEN_0, (PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_GEN_SYNC_LOCAL | PWM_GEN_MODE_FAULT_UNLATCHED | PWM_GEN_MODE_DB_NO_SYNC)); PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, inv.period-1); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, inv.cycle); PWMDeadBandEnable(PWM0_BASE, PWM_GEN_0, 13, 0); PWMGenEnable(PWM0_BASE, PWM_GEN_0); PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT|PWM_OUT_1_BIT, true); PWMSyncUpdate(PWM0_BASE, PWM_OUT_0_BIT|PWM_OUT_1_BIT); /* * Setup boost converter pwm on PWM1 * PA6: PWM1 GEN1 */ SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralReset(SYSCTL_PERIPH_PWM1); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOA); GPIOPinConfigure(GPIO_PA6_M1PWM2); //Map PWM1, P1 OP2 to PA6 GPIOPinTypePWM(GPIO_PORTA_BASE, GPIO_PIN_6); //Configure PA6 as PWM PWMGenConfigure(PWM1_BASE, PWM_GEN_1, (PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_GEN_NO_SYNC| PWM_GEN_MODE_DB_NO_SYNC)); //Configure PWM1, G1 as Down counter with no sync of updates PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, conv.period-1); //Set Period of PWM1, G1 PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, conv.cycle); //Set phase shift PWMIntEnable(PWM1_BASE, PWM_INT_GEN_1); PWMGenIntTrigEnable(PWM1_BASE, PWM_GEN_1, PWM_TR_CNT_LOAD|PWM_INT_CNT_LOAD); IntPrioritySet(INT_PWM1_1, 0x02); PWMOutputState(PWM1_BASE, PWM_OUT_2_BIT, true); PWMGenEnable(PWM1_BASE, PWM_GEN_1); /* * Setup ISR for updating SPWM duty cycle */ uint32_t ui32TimIntSine = SysCtlClockGet()/200000; SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2); SysCtlPeripheralReset(SYSCTL_PERIPH_TIMER2); TimerConfigure(TIMER2_BASE, TIMER_CFG_A_PERIODIC); TimerLoadSet(TIMER2_BASE, TIMER_A, ui32TimIntSine-1); TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT); IntPrioritySet(INT_TIMER2A, 0x03); TimerEnable(TIMER2_BASE, TIMER_A); uint32_t ui32TimIntIcontrol = SysCtlClockGet()/40000; SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1); SysCtlPeripheralReset(SYSCTL_PERIPH_TIMER1); TimerConfigure(TIMER1_BASE, TIMER_CFG_A_PERIODIC); TimerLoadSet(TIMER1_BASE, TIMER_A, ui32TimIntIcontrol-1); TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT); IntPrioritySet(INT_TIMER1A, 0x01); TimerEnable(TIMER1_BASE, TIMER_A); /* * Setup PF1 as debug pin */ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOF); HWREG(0x40005520) = 0x4C4F434B; HWREG(0x40005524) |= 0x01; HWREG(0x40005520) = 0x00; GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4); GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE); IntPrioritySet(INT_GPIOF,0x00); GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_4); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1); /* * Setup ADC * Configuration currently in discussion * Interrupt at end might not be necessary */ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOE); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0); SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0); ADCHardwareOversampleConfigure(ADC0_BASE, 2); ADCSequenceDisable(ADC0_BASE, 2); ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PWM1, 0x00); HWREG(0x4003801C) |= 0x1000; //Sec 13.4.2 Pt 3 ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH1); ADCSequenceStepConfigure(ADC0_BASE, 2, 1, ADC_CTL_CH2); ADCSequenceStepConfigure(ADC0_BASE, 2, 2, ADC_CTL_CH3|ADC_CTL_IE|ADC_CTL_END); ADCSequenceEnable(ADC0_BASE, 2); }
//***************************************************************************** // //! Updates the duty cycle in the PWM module. //! //! This function programs the duty cycle of the PWM waveforms into the PWM //! module. The changes will be written to the hardware and the hardware //! instructed to start using the new values the next time its counters reach //! zero. //! //! \return None. // //***************************************************************************** static void PWMUpdateDutyCycle(void) { unsigned long ulWidthA, ulWidthB, ulWidthC; // // Get the pulse width of the A phase of the motor. // ulWidthA = (g_ulPWMDutyCycleA * g_ulPWMClock) / 65536; if(ulWidthA > g_ulPWMClock) { ulWidthA = g_ulPWMClock; } if(ulWidthA < g_ulMinPulseWidth) { ulWidthA = g_ulMinPulseWidth; } if((g_ulPWMClock - ulWidthA) < g_ulMinPulseWidth) { ulWidthA = g_ulPWMClock - g_ulMinPulseWidth; } // // Get the pulse width of the B phase of the motor. // ulWidthB = (g_ulPWMDutyCycleB * g_ulPWMClock) / 65536; if(ulWidthB > g_ulPWMClock) { ulWidthB = g_ulPWMClock; } if(ulWidthB < g_ulMinPulseWidth) { ulWidthB = g_ulMinPulseWidth; } if((g_ulPWMClock - ulWidthB) < g_ulMinPulseWidth) { ulWidthB = g_ulPWMClock - g_ulMinPulseWidth; } // // Get the pulse width of the C phase of the motor. // ulWidthC = (g_ulPWMDutyCycleC * g_ulPWMClock) / 65536; if(ulWidthC > g_ulPWMClock) { ulWidthC = g_ulPWMClock; } if(ulWidthC < g_ulMinPulseWidth) { ulWidthC = g_ulMinPulseWidth; } if((g_ulPWMClock - ulWidthC) < g_ulMinPulseWidth) { ulWidthC = g_ulPWMClock - g_ulMinPulseWidth; } // // Update global parameters (for Trapezoid, A=B=C, for Sinusoid, don't // matter). // g_ulPWMWidth = (ulWidthA + ulWidthB + ulWidthC) / 3; g_ulTrapDutyCycle = (g_ulPWMWidth * 10000) / g_ulPWMClock; // // Set A, B, and C PWM output duty cycles (all generator outputs). // PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, ulWidthA); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, ulWidthA); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, ulWidthB); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_3, ulWidthB); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_4, ulWidthC); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5, ulWidthC); // // If trapezoid (not sine), and slow decay, set the odd PWM at near // 100% duty cycle. // if((g_sParameters.ucModulationType != MOD_TYPE_SINE) && (HWREGBITH(&(g_sParameters.usFlags), FLAG_DECAY_BIT) == FLAG_DECAY_SLOW)) { PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, (g_ulPWMClock - g_sParameters.ucDeadTime)); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_3, (g_ulPWMClock - g_sParameters.ucDeadTime)); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5, (g_ulPWMClock - g_sParameters.ucDeadTime)); } // // Perform a synchronous update of all three PWM generators. // PWMSyncUpdate(PWM0_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT); // // And we're done for now. // return; }