Exemple #1
0
//*****************************************************************************
//
//! 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;
}