Example #1
0
//*****************************************************************************
//
//! Sets the motor to be driven at the requested duty cycle.
//!
//! \param ucMotor determines which motor's duty cycle is to be set. Valid
//! values are \e LEFT_SIDE or \e RIGHT_SIDE.
//! \param usPercent Percent of the maximum speed to drive the motor in
//! 8.8 fixed point format.  This value must be less than (100 << 8).
//!
//! This function can be called to set the duty cycle of one or other of the
//! motors.
//!
//! \return None.
//!
//! \note The duty cycle and motor speed are not the same thing, although there
//! is a relation.
//
//*****************************************************************************
void
MotorSpeed(tSide ucMotor, unsigned short usPercent)
{
    unsigned long ulPWMOut, ulPWMOutBit;

    //
    // Check for invalid parameters.
    //
    ASSERT((ucMotor == LEFT_SIDE) || (ucMotor == RIGHT_SIDE));
    ASSERT(usPercent < (100 << 8));

    //
    // Which PWM output are we controlling?
    //
    if(ucMotor == LEFT_SIDE)
    {
        ulPWMOut = PWM_OUT_2;
        ulPWMOutBit = PWM_OUT_2_BIT;
    }
    else
    {
        ulPWMOut = PWM_OUT_0;
        ulPWMOutBit = PWM_OUT_0_BIT;
    }

    //
    // First, enable the PWM output in case it was disabled by the
    // previously requested speed being greater than 95%
    //
    PWMOutputState(PWM0_BASE, ulPWMOutBit, true);

    //
    // Make sure that output is not inverted.
    //
    PWMOutputInvert(PWM0_BASE, ulPWMOutBit, false);

    //
    // Set the pulse width to the requested value. Divide by two since
    // we are using 6V motors with 12V power rail.
    //
    PWMPulseWidthSet(PWM0_BASE, ulPWMOut, ((PWM_PERIOD * usPercent) /
                         (100 << 8)));
}
Example #2
0
//*****************************************************************************
//
// Configure PWM0 for a 25% duty cycle signal running at 250Hz.  This example
// also shows how to invert the PWM signal every 5 seconds for 5 seconds.
//
//*****************************************************************************
int
main(void)
{
    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal on your board.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_16MHZ);

    //
    // Set the PWM clock to the system clock.
    //
    SysCtlPWMClockSet(SYSCTL_PWMDIV_1);

    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for Timer operation.
    //
    InitConsole();

    //
    // Display the setup on the console.
    //
    UARTprintf("PWM ->\n");
    UARTprintf("  Module: PWM0\n");
    UARTprintf("  Pin: PD0\n");
    UARTprintf("  Configured Duty Cycle: 25%%\n");
    UARTprintf("  Inverted Duty Cycle: 75%%\n");
    UARTprintf("  Features: PWM output inversion every 5 seconds.\n\n");
    UARTprintf("Generating PWM on PWM0 (PD0) -> State = ");

    //
    // The PWM peripheral must be enabled for use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);

    //
    // For this example PWM0 is used with PortB Pin6.  The actual port and
    // pins used may be different on your part, consult the data sheet for
    // more information.
    // GPIO port B needs to be enabled so these pins can be used.
    // TODO: change this to whichever GPIO port you are using.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //
    // Configure the GPIO pin muxing to select PWM00 functions for these pins.
    // This step selects which alternate function is available for these pins.
    // This is necessary if your part supports GPIO pin function muxing.
    // Consult the data sheet to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinConfigure(GPIO_PB6_M0PWM0);

    //
    // Configure the PWM function for this pin.
    // Consult the data sheet to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6);

    //
    // Configure the PWM0 to count up/down without synchronization.
    //
    PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN |
                    PWM_GEN_MODE_NO_SYNC);

    //
    // Set the PWM period to 250Hz.  To calculate the appropriate parameter
    // use the following equation: N = (1 / f) * SysClk.  Where N is the
    // function parameter, f is the desired frequency, and SysClk is the
    // system clock frequency.
    // In this case you get: (1 / 250Hz) * 16MHz = 64000 cycles.  Note that
    // the maximum period you can set is 2^16.
    // TODO: modify this calculation to use the clock frequency that you are
    // using.
    //
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 64000);

    //
    // Set PWM0 to a duty cycle of 25%.  You set the duty cycle as a function
    // of the period.  Since the period was set above, you can use the
    // PWMGenPeriodGet() function.  For this example the PWM will be high for
    // 25% of the time or 16000 clock ticks (64000 / 4).
    //
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,
                     PWMGenPeriodGet(PWM0_BASE, PWM_OUT_0) / 4);

    //
    // Enable the PWM0 Bit0 (PD0) output signal.
    //
    PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);

    //
    // Enable the PWM generator block.
    //
    PWMGenEnable(PWM0_BASE, PWM_GEN_0);

    //
    // Loop forever while the PWM signals are generated.
    //
    while(1)
    {
        //
        // Print out that the level of PWM is normal.
        //
        UARTprintf("Normal  \b\b\b\b\b\b\b\b");

        //
        // This function provides a means of generating a constant length
        // delay.  The function delay (in cycles) = 3 * parameter.  Delay
        // 5 seconds arbitrarily.
        //
        SysCtlDelay((SysCtlClockGet() * 5) / 3);

        //
        // Invert PWM0 signal.
        //
        PWMOutputInvert(PWM0_BASE, PWM_OUT_0_BIT, true);

        //
        // Print out that the level of PWM is inverted.
        //
        UARTprintf("Inverted\b\b\b\b\b\b\b\b");

        //
        // This function provides a means of generating a constant length
        // delay.  The function delay (in cycles) = 3 * parameter.  Delay
        // 5 seconds arbitrarily.
        //
        SysCtlDelay((SysCtlClockGet() * 5) / 3);

        //
        // Switch PWM0 signal back to regular operation.
        //
        PWMOutputInvert(PWM0_BASE, PWM_OUT_0_BIT, false);
    }
}
Example #3
0
/* ---- Private Function Prototypes -------------------------------------- */
void A3906Init()
{
    SysCtlPWMClockSet(SYSCTL_PWMDIV_1);	
	
    //
    // Enable the peripherals used by this device. (PWM0,1,2,3)
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);	
	
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);  	// PWM 0,1 ROLL_MOTOR 
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);     	// PWM 2,3 PITCH_MOTOR
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);  	// FL1 + FL2

	GPIOPinConfigure(GPIO_PB6_M0PWM0);    
	GPIOPinConfigure(GPIO_PB7_M0PWM1);   	
	
	GPIOPinConfigure(GPIO_PA6_M1PWM2);    
	GPIOPinConfigure(GPIO_PA7_M1PWM3);    
	
    //
    // Set GPIO PWM pins.  They are used to output the PWM0-3 signals
    //
    GPIOPinTypePWM(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7); //pwm1 2-3
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6 | GPIO_PIN_7); //pwm0 2-3
    
    // Set the PWM period to 20KHz.
    // N = (1 / F) * SysClk. 
    // Where N is the function parameter
    // F is the desired frequency
    // SysClk is the system clock frequency.
    // In this case you get: (1 / 20KHz) * 80MHz = 4000 cycles.  Note that
    ulPeriod = 4000;// SysCtlClockGet() / PWMRATE;

    //ulPeriod = SysCtlClockGet() / 50000;//PWMRATE;
	//
	// Set the PWM period to chosen rate.
	//
	PWMGenConfigure(PWM_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
	PWMGenPeriodSet(PWM_BASE, PWM_GEN_0, ulPeriod);
		
	//PWMGenConfigure(PWM_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
	//PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, ulPeriod);

	PWMOutputInvert(PWM_BASE,PWM_OUT_0_BIT | PWM_OUT_1_BIT, true);
	//
	// Enable the PWM0 and PWM1 output signals.
	//
	PWMOutputState(PWM_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT, true);
	//
	// Enable the PWM generators.
	//
	PWMGenEnable(PWM_BASE, PWM_GEN_0);
	//PWMGenEnable(PWM_BASE, PWM_GEN_1);

	//
	// Set the PWM period to chosen rate.
	//
	//PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
	//PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, ulPeriod);
		
	PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
	PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, ulPeriod);

	PWMOutputInvert(PWM1_BASE,PWM_OUT_2_BIT | PWM_OUT_3_BIT, true);
	//
	// Enable the PWM0 and PWM1 output signals.
	//
	PWMOutputState(PWM1_BASE, PWM_OUT_2_BIT | PWM_OUT_3_BIT, true);
	//
	// Enable the PWM generators.
	//
	//PWMGenEnable(PWM1_BASE, PWM_GEN_0);
	PWMGenEnable(PWM1_BASE, PWM_GEN_1);

	
#if 0
    // setup interrupt handlers for overcurrent
    GPIOPinInit(A3906_OC1_INTERRUPT_PORT,A3906_OC1_INTERRUPT_PIN,true,true);
    GPIOPinInit(A3906_OC2_INTERRUPT_PORT,A3906_OC2_INTERRUPT_PIN,true,true);
#endif
    desiredencoder[0] = -1;  // means not active
    desiredencoder[1] = -1;
    dcycle[0] = PITCH_MINIMUM_DUTYCYCLE; // recommended initial values
    dcycle[1] = ROLL_MINIMUM_DUTYCYCLE;
    brakeOnChange = true;
}
/*
 *  ======== PWMTiva_open ========
 *  @pre    Function assumes that the handle is not NULL
 */
PWM_Handle PWMTiva_open(PWM_Handle handle, PWM_Params *params)
{
    unsigned int           key;
    uint8_t                cyclesPerMicroSec;
    uint8_t                prescalar;
    uint16_t               pwmGenerator;
    uint16_t              *pwmGenPeriod;
    uint32_t               pwmGenOptions;
    uint32_t               prescalarRegVal;
    uint32_t               tempPeriod;
    Types_FreqHz           freq;
    PWMTiva_Object        *object = handle->object;
    PWMTiva_HWAttrs const *hwAttrs = handle->hwAttrs;

    BIOS_getCpuFreq(&freq);
    cyclesPerMicroSec = freq.lo / 1000000;

    if(params == NULL) {
        params = (PWM_Params *) &PWM_defaultParams;
    }

    /* Assert if period is too large for peripheral */
    tempPeriod = params->period * cyclesPerMicroSec;
    Assert_isTrue(tempPeriod <= (PWMTiva_MAX_MATCH_VALUE * PWMTiva_MAX_PRESCALAR),
                  NULL);

    PWMTiva_calculatePrescalar(tempPeriod, &prescalarRegVal, &prescalar);

    /* Get the PWM generator and it's period */
    pwmGenerator = hwAttrs->pwmOutput & PWM_GEN_MASK;
    pwmGenPeriod = (object->pwmStatus)->genPeriods +
                   ((hwAttrs->pwmOutput / PWM_OUT_0) - 1);

    key = Hwi_disable();

    /* Verify if PWM peripheral has been initialized by another PWM instance */
    if ((object->pwmStatus)->cyclesPerMicroSec) {
        /*
         * The PWM peripheral has already been initialized.
         *
         * Ensure the instance has not been opened and the peripheral prescalar
         * is >= the prescalar required for new instance.
         */
        if (((object->pwmStatus)->activeOutputs & object->pwmOutputBit) ||
            ((object->pwmStatus)->prescalar < prescalar)) {
            Hwi_restore(key);
            return (NULL);
        }

        /* Check if the other output on the generator is active */
        if (*pwmGenPeriod) {
            /* Ensure period are the same */
            if (params->period != *pwmGenPeriod) {
                Hwi_restore(key);
                return (NULL);
            }

            /* Get PWM generator options & ensure options are the same */
            pwmGenOptions = (HWREG(hwAttrs->baseAddr + pwmGenerator) &
                             ~PWM_X_CTL_ENABLE);
            if (hwAttrs->pwmGenOpts != pwmGenOptions) {
                Hwi_restore(key);
                return (NULL);
            }
        }
    }
    else {
        /* PWM has not been initialized by another instance */

        (object->pwmStatus)->prescalar = prescalar;
        (object->pwmStatus)->cyclesPerMicroSec = cyclesPerMicroSec;
        PWMTiva_setPrescalar(hwAttrs->baseAddr, prescalarRegVal);
    }

    /* PWM can be opened safely, mark as being used */
    (object->pwmStatus)->activeOutputs |= object->pwmOutputBit;

    if (!(*pwmGenPeriod)) {
        /* Initialize PWM signal generator */
        *pwmGenPeriod = params->period;
        PWMGenConfigure(hwAttrs->baseAddr, pwmGenerator, hwAttrs->pwmGenOpts);
        PWMGenPeriodSet(hwAttrs->baseAddr, pwmGenerator, (tempPeriod / prescalar));
    }
    Hwi_restore(key);

    /*
     * Set PWM duty to initial value (not 0 or period) - required when
     * inverting output polarity to generate a duty equal to 0 or
     * period.  See comments in PWMTiva_setDuty for more information.
     */
    object->pwmDuty = 1;
    object->dutyMode = params->dutyMode;

    /* Set PWM generator outputs to 0 initially */
    PWMOutputInvert(hwAttrs->baseAddr, object->pwmOutputBit, params->polarity);
    PWMTiva_setDuty(handle, 0);
    PWMOutputState(hwAttrs->baseAddr, object->pwmOutputBit, true);
    PWMGenEnable(hwAttrs->baseAddr, pwmGenerator);

    Log_print2(Diags_USER1,
               "PWM:(%p) opened; period set to: %d",
               (UArg) handle,
               params->period);

    return (handle);
}
//*****************************************************************************
//
//! Initializes the PWM control routines.
//!
//! This function initializes the PWM module and the control routines,
//! preparing them to produce PWM waveforms to drive the power module.
//!
//! \return None.
//
//*****************************************************************************
void
PWMInit(void)
{
    //
    // Make the PWM pins be peripheral function.
    //
    GPIOPinTypePWM(PIN_PHASEA_LOW_PORT,
                   PIN_PHASEA_LOW_PIN | PIN_PHASEA_HIGH_PIN);
    GPIOPinTypePWM(PIN_PHASEB_LOW_PORT,
                   PIN_PHASEB_LOW_PIN | PIN_PHASEB_HIGH_PIN);
    GPIOPinTypePWM(PIN_PHASEC_LOW_PORT,
                   PIN_PHASEC_LOW_PIN | PIN_PHASEC_HIGH_PIN);

    //
    // Configure the three PWM generators for up/down counting mode,
    // synchronous updates, and to stop at zero on debug events.
    //
    PWMGenConfigure(PWM0_BASE, PWM_GEN_0, (PWM_GEN_MODE_UP_DOWN |
                                           PWM_GEN_MODE_SYNC |
                                           PWM_GEN_MODE_DBG_STOP));
    PWMGenConfigure(PWM0_BASE, PWM_GEN_1, (PWM_GEN_MODE_UP_DOWN |
                                           PWM_GEN_MODE_SYNC |
                                           PWM_GEN_MODE_DBG_STOP));
    PWMGenConfigure(PWM0_BASE, PWM_GEN_2, (PWM_GEN_MODE_UP_DOWN |
                                           PWM_GEN_MODE_SYNC |
                                           PWM_GEN_MODE_DBG_STOP));

    //
    // Set the initial duty cycles to 50%.
    //
    g_ulPWMDutyCycleA = 32768;
    g_ulPWMDutyCycleB = 32768;
    g_ulPWMDutyCycleC = 32768;

    //
    // Configure the PWM period, duty cycle, and dead band.  The initial period
    // is 1 KHz (for triggering the ADC), which will be increased when the
    // motor starts running.
    //
    PWMClearDeadBand();
    PWMSetFrequency();
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, PWM_CLOCK / 1000);
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, PWM_CLOCK / 1000);
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, PWM_CLOCK / 1000);
    PWMUpdateDutyCycle();

    //
    // Enable the PWM generators.
    //
    PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    PWMGenEnable(PWM0_BASE, PWM_GEN_1);
    PWMGenEnable(PWM0_BASE, PWM_GEN_2);

    //
    // Synchronize the time base of the generators.
    //
    PWMSyncTimeBase(PWM0_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT);

    //
    // Configure an interrupt on the zero event of the first generator, and an
    // ADC trigger on the load event of the first generator.
    //
    PWMGenIntClear(PWM0_BASE, PWM_GEN_0, PWM_INT_CNT_ZERO);
    PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_0,
                        PWM_INT_CNT_ZERO | PWM_TR_CNT_LOAD);
    PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_1, 0);
    PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_2, 0);
    PWMIntEnable(PWM0_BASE, PWM_INT_GEN_0);
    IntEnable(INT_PWM0_0);
    IntEnable(INT_PWM0_1);
    IntEnable(INT_PWM0_2);

    //
    // Set all six PWM outputs to go to the inactive state when a fault event
    // occurs (which includes debug events).
    //
    PWMOutputFault(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),
                   true);

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

    //
    // Ensure that all outputs are not-inverted.
    //
    PWMOutputInvert(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);
}