App uses TMS320F28062 in an application driving a 3 phase brushless DC motor.
App has been working great for a long time.
GPIO0 to GPIO5 are used as EPWM1 to EPWM3 to drive the motor FETs.
During boot, GPIO0-5 are set high and low and each state checked to verify they all are working.
This is performed by the following function, MotorTest().
Here is the problem.
During software validation must prove that if any of GPIO0-5 are shorted low or high that the MotorTest() will fail.
To do this, each of GPIO0-5 are loaded one at a time by a 100 ohm resistor to either GND or +3.3V. This makes a high on the GPIO only reach 0.3V or the low only reach 3.1V. So when any one of GPIO0-5 are set high and loaded by 100 ohms to GND the pin only reaches 0.3V but reading GPADAT returns a 1. And when any one of GPIO0-5 are set low and loaded by 100 ohms to +3.3V the pin only reaches 3.1V but reading GPADAT returns a 0.
The MotorTest() always passes.
So, it appears that the read of GPADAT is not reading the pin state, but instead reading the output latch. All documentation for this part clearly states that reading GPADAT will always return pin states, not the latch.
Can anyone tell me why this is happening?
Here is the function:
// This function tests that all of GPIO0 to GPIO5 can be set high and low
// GPIO0 to GPIO5 are tested one at a time by setting high, reading to verify,
// then setting low and reading to verify.
uint16_t MotorTest(void)
{
uint16_t error = 0;
uint32_t val32;
uint32_t mask32;
volatile uint16_t i;
EALLOW; // Enable EALLOW protected register access
GpioDataRegs.GPACLEAR.all = 0x3F; // output latch for GPIO0-5 all set to 0
GpioCtrlRegs.GPAMUX1.all = 0x0000; // GPIO functionality on GPIO0-GPIO15
GpioCtrlRegs.GPADIR.all = 0x003F; // GPIO0-5 are outputs, GPIO6-GPIO31 are inputs
GpioCtrlRegs.GPAQSEL1.all = 0x0000; // GPIO0-GPIO15 Synch to SYSCLKOUT
GpioCtrlRegs.GPAPUD.all = 0x003F; // Pullups disabled on GPIO0-5 and enabled on
// GPIO6-GPIO31
EDIS; // Disable EALLOW protected register access
for (i=0; i<10; i++); // short delay
// walks a bit through GPIO0 to GPIO5
for(mask32=1UL; mask32<0x040UL; mask32<<=1)
{
// set one of GPIO0-5 high, verify only it is high
GpioDataRegs.GPASET.all = mask32; // set one of GPIO0-5 high as specified by mask32
for (i=0; i<10; i++); // short delay
val32= GpioDataRegs.GPADAT.all & MOTOR_IO; // read GPADAT
if(val32 != mask32) // test that only the one bit set by mask32 is high
{
error= 1;
break;
}
// clear all of GPIO0-5, verify all are low
GpioDataRegs.GPACLEAR.all = mask32; // clear one of GPIO0-5 as specified by mask32
for (i=0; i<10; i++); // short delay
val32= GpioDataRegs.GPADAT.all & MOTOR_IO; // read GPADAT
if(val32 != 0) // test that all bits are low
{
error= 1;
break;
}
}
return error;
}