This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

FaultISR happens in response to driverlib function

Other Parts Discussed in Thread: EK-TM4C1294XL

I created this code from the timers example for ek-tm4c1294xl board. My program, running on the EK-TM4C1294 Launchpad, faults out almost immediately, at the same place whether running or single-stepping. I am using CCS 6.1.3 on a 64-bit Win 7 SP1 system. Here is the code:

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "driverlib/pwm.h"
#include "driverlib/adc.h"
#include "utils/uartstdio.h"

	uint32_t ADC_data[4];
	volatile uint32_t load_velocity;
    volatile uint32_t CIM_velocity;
    volatile uint32_t frequency_input;
    volatile uint32_t acceleration_input;
    uint32_t dead_band_value;

//*****************************************************************************
//
// Configure the PWM0 block with dead-band generation.  The example configures
// the PWM0 block to generate a 25% duty cycle signal on PD0 with dead-band
// generation.  This will produce a complement of PD0 on PD1 (75% duty cycle).
// The dead-band generator is set to have a 10us or 160 cycle delay
// (160cycles / 16Mhz = 10us) on the rising and falling edges of the PD0 PWM
// signal.
//
//*****************************************************************************
void main(void)
{

	//SysCtlClockFreqSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    //               SYSCTL_XTAL_25MHZ);
	uint32_t g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |// Set the clocking to run directly from the crystal at 120MHz.
	                                             SYSCTL_OSC_MAIN |
	                                             SYSCTL_USE_PLL |
	                                             SYSCTL_CFG_VCO_480), 120000000);
    // Set the PWM clock to the system clock.
    PWMClockSet(PWM_GEN_0, PWM_SYSCLK_DIV_1);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);	// for the PWM outputs
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);	// for the ADC inputs

    GPIOPinConfigure(GPIO_PK4_M0PWM6);
    GPIOPinConfigure(GPIO_PK5_M0PWM7);

    // Configure the GPIO pad for PWM function on pins PK4 and PK5.
    GPIOPinTypePWM(GPIO_PORTK_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

    ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);

    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH0);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH1);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH2);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 3, ADC_CTL_CH3|ADC_CTL_IE|ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, 1);

    // Configure the PWM Generator 0 to count up/down without synchronization.
    // Note: Enabling the dead-band generator automatically couples the 2
    // outputs from the PWM block so we don't use the PWM synchronization.
    PWMGenConfigure(PWM0_BASE, PWM_GEN_3, 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 - 1.
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, 64000);
    //PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, 1985);

    // Set PWM1 PD0 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 cycles (64000 / 4).

    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,
                     PWMGenPeriodGet(PWM0_BASE, PWM_GEN_3) / 2);

    // Enable the dead-band generation on the PWM0 output signal.  PWM bit 0
    // (PD0), will have a duty cycle of 25% (set above) and PWM bit 1 will have
    // a duty cycle of 75%.  These signals will have a 10us gap between the
    // rising and falling edges.
    PWMDeadBandEnable(PWM0_BASE, PWM_GEN_3, 160, 160);


    // Enable the PWM0 Bit 0 (PD0) and Bit 1 (PD1) output signals.
    PWMOutputState(PWM0_BASE, PWM_OUT_6_BIT | PWM_OUT_7_BIT, true);

    // Enables the counter for a PWM generator block.
    PWMGenEnable(PWM0_BASE, PWM_GEN_3);

    // Loop forever while the PWM signals are generated.
    while(1)
    {
        ADCIntClear(ADC0_BASE, 1);
        ADCSequenceDataGet(ADC0_BASE, 1, ADC_data);
        ADCProcessorTrigger(ADC0_BASE, 1);
        load_velocity = ADC_data[0];
        CIM_velocity = ADC_data[1];
        frequency_input = ADC_data[2];
        acceleration_input = ADC_data[3];
        dead_band_value =
        		acceleration_input * PWMGenPeriodGet(PWM0_BASE, PWM_GEN_0) / 8192 + 80;
        while(!ADCIntStatus(ADC0_BASE, 1, false))
        {
            PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, frequency_input);
            PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,
                                 PWMGenPeriodGet(PWM1_BASE, PWM_GEN_0) / 2);
            PWMDeadBandEnable(PWM0_BASE, PWM_GEN_0, dead_band_value, dead_band_value);
        }
    }
}

This program faults to the FaultISR at the second driverlib command:

SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);

Any suggestions?


  • Hi Otto,

       Try this below. I moved the Port K and Port E Peripheral Enable code above SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);

    // Set the PWM clock to the system clock.
    PWMClockSet(PWM_GEN_0, PWM_SYSCLK_DIV_1);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); // for the PWM outputs
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // for the ADC inputs

    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    GPIOPinConfigure(GPIO_PK4_M0PWM6);
    GPIOPinConfigure(GPIO_PK5_M0PWM7);

    - kel

  • And - of (some) interest - after you reordered the appearance of those functions - did your program (then) run?

    And - if you (returned) to poster's order - did the program vector to, "Fault ISR."

    Such would strengthen your post - would it not?

  • That was a good suggestion, Markel. It makes sense to enable the peripheral port prior to enabling the peripheral. I recall being bit by that once before (I never learn!) Also, moving things around does often help in understanding the source of a fault such as this. My code still goes off the track, stuck in the fault ISR, when SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); is reached, which is now a bit further into the code. Again, the fault ISR happens during running and single-stepping in exactly the same way. Here is the redone code section:

    	uint32_t g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |// Set the clocking to run directly from the crystal at 120MHz.
    	                                             SYSCTL_OSC_MAIN |
    	                                             SYSCTL_USE_PLL |
    	                                             SYSCTL_CFG_VCO_480), 120000000);
        // Set the PWM clock to the system clock.
        PWMClockSet(PWM_GEN_0, PWM_SYSCLK_DIV_1);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);	// for the PWM outputs
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);	// for the ADC inputs
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    
        GPIOPinConfigure(GPIO_PK4_M0PWM6);
        GPIOPinConfigure(GPIO_PK5_M0PWM7);

  • cb1 and Otto,

        Just now that I have run my earlier suggestions and it did not solve the Fault ISR. But, I have debugged the Fault ISR just now and here is the recommended code changes. 

          There are 2 FaultISR causes:

    1. First one is the wrong PWM base define "PWM_GEN_0", the correct one is "PWM0_BASE".
    2. Second one is not enabling clock to  PWM0 before calling PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1);

    Code Changes:

      // Set the PWM clock to the system clock.

       //PWMClockSet(PWM_GEN_0, PWM_SYSCLK_DIV_1);

       SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);

       PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1);

       //SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);

       SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

       SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);    // for the PWM outputs

       SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);    // for the ADC inputs

       GPIOPinConfigure(GPIO_PK4_M0PWM6);

       GPIOPinConfigure(GPIO_PK5_M0PWM7);

    - kel

    Link to Diagnosing FaultISR()

  • Way cool, Markel, this code no longer gets stuck at SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0) :) It zooms right past that point to get stuck further down, but that is another separate problem and possible separate post if, again, I need help. Here is the working code snippet:

    void main(void)
    {
    
    	//SysCtlClockFreqSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
        //               SYSCTL_XTAL_25MHZ);
    	uint32_t g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |// Set the clocking to run directly from the crystal at 120MHz.
    	                                             SYSCTL_OSC_MAIN |
    	                                             SYSCTL_USE_PLL |
    	                                             SYSCTL_CFG_VCO_480), 120000000);
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);	// for the PWM outputs
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);	// for the ADC inputs
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);		// enable the clock to the PWM0 peripheral
        PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1);		// Set the PWM clock to the system clock.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    
        GPIOPinConfigure(GPIO_PK4_M0PWM6);
        GPIOPinConfigure(GPIO_PK5_M0PWM7);

    The rest of the code is unchanged from my first post. Thanks, again, Markel!