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