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.

ISR Fault during PWM and QEI operation on TM4C123GH6PM

Other Parts Discussed in Thread: TM4C123GH6PM, DRV8870, L293D

Hi guys,

I am using a custom board with the TM4C123GH6PM as the microcontroller. I am building an application related to motor movement and speed control, using a DRV8870 IC. I'm using an incremental encoder for the closed loop.

I had written a code on CCS and it was working fine till a week back. The code would rotate the motor up to a specific count of the encoder, and would stop there. I have enabled the QEI registers, as well as the PWM. But I am getting an ISR fault every time I run the code. If I run the code with breakpoints in the debugging mode, the code works fine, but in other cases, it just leads to an ISR fault. 

These are the QEI and PWM functions.

void ENCODER_INIT()
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI1);


  HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
  HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= 0x80;
  HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0;

  HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; 
  HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
  HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;


  GPIOPinConfigure(GPIO_PF0_PHA0);
  GPIOPinConfigure(GPIO_PF1_PHB0);
  GPIOPinConfigure(GPIO_PC5_PHA1);
  GPIOPinConfigure(GPIO_PC6_PHB1);


  GPIOPinTypeQEI(GPIO_PORTF_BASE,GPIO_PIN_0 | GPIO_PIN_1);
  GPIOPinTypeQEI(GPIO_PORTC_BASE,GPIO_PIN_5 | GPIO_PIN_6);

//DISable peripheral and int before configuration
  QEIDisable(QEI0_BASE);
  QEIDisable(QEI1_BASE);
  QEIIntDisable(QEI0_BASE,QEI_INTERROR | QEI_INTDIR | QEI_INTTIMER | QEI_INTINDEX);
  QEIIntDisable(QEI1_BASE,QEI_INTERROR | QEI_INTDIR | QEI_INTTIMER | QEI_INTINDEX); 

  QEIConfigure(QEI0_BASE, (QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_NO_RESET | QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), 1686110209);//1686110209
  QEIConfigure(QEI1_BASE, (QEI_CONFIG_CAPTURE_A_B | QEI_CONFIG_NO_RESET | QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), 1686110209);
  QEIVelocityConfigure(QEI0_BASE, QEI_VELDIV_1, SysCtlClockGet()); // Divide by clock speed to get counts/sec
  QEIVelocityConfigure(QEI1_BASE, QEI_VELDIV_1, SysCtlClockGet()); // Divide by clock speed to get counts/sec
  QEIEnable(QEI0_BASE);
  QEIEnable(QEI1_BASE);
  QEIVelocityEnable(QEI0_BASE);
  QEIVelocityEnable(QEI1_BASE);
}

void PWM_Init(void)
{

  SysCtlPWMClockSet(SYSCTL_PWMDIV_32);

  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);


  HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; //In Tiva include this is the same as "_DD" in older versions (0x4C4F434B)
  HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
  HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;

  GPIOPinConfigure(GPIO_PF2_M1PWM6);
  GPIOPinConfigure(GPIO_PF3_M1PWM7);
  GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3);


  PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC | PWM_GEN_MODE_DBG_RUN);

  unsigned long period = 5000;
  unsigned long pwmNow = 1000;

  PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, period);

  PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,pwmNow);
  PWMPulseWidthSet(PWM1_BASE, PWM_OUT_7,pwmNow);

}

void PWM_FORWARD(void)
{
// Enable the PWM generator
PWMGenEnable(PWM1_BASE, PWM_GEN_3);

PWMOutputState(PWM1_BASE, PWM_OUT_6_BIT, false);
PWMOutputState(PWM1_BASE, PWM_OUT_7_BIT, true);
}

void PWM_REVERSE(void)
{
// Enable the PWM generator
PWMGenEnable(PWM1_BASE, PWM_GEN_3);

PWMOutputState(PWM1_BASE, PWM_OUT_7_BIT, false);
PWMOutputState(PWM1_BASE, PWM_OUT_6_BIT, true);
}

The part of the code where these functions are called is given below

while(ulENCODER_val1<Forward_Rotation)  //ulENCODER_val1 - Encoder reading, Forward_Rotation - end limit
{

  PWM_FORWARD();
  if(((ulENCODER_val1-Forward_Rotation)<10 || (Forward_Rotation-ulENCODER_val1)<10))
  break;

  ulENCODER_val1=QEIPositionGet(QEI0_BASE);
}

I am using pins PF0 and PF1 as the encoder pins and PF2 and PF3 as the PWM pins connected to the DRV8870. The ISR fault does not appear when either the encoder function call, or the PWM function call are removed, but reappears when they are both called by the code.

Looking forward to your help,

Aditya

  • Hello Aditya,

    Did you analyze at what location the fault occurs? If not please try to figure out the fault location. This document should help in figuring out the fault location:

    Also while pasting code please use "Use rich formatting" and then click on Syntaxhighlghter (with the icon Insert code using Syntaxhighlighter).

    Thanks,

    Sai

  • Hello Sai,

    I have tried the same code with a different motor driver IC, the L293D, and it's working fine. Seems to me that the DRV8870 is the problem. I have connected the ISEN pin directly to ground, and the VREF to +3.3V. The DRV8870 seems to be interfering and driving it to an ISR fault. 

    Could you please let me know what could be the mistake in the design? 

    Thanks, 

    Aditya

  • Hello Aditya

    Is there any interrupt from the IC to the TM4C?

    Also please reset the peripheral before configuring it and always use System reset to start the program instead of CPU reset

    Regards
    Amit