Hi,
I'm using a TMS320F28335 on a custom board. There's a JTAG interface which I access using a Spectrum Digital XDS510PP. I'm running a big program out of RAM which runs just fine. The board features a self-made "8-GPIO-to-64-IO"-Circuit, which is controlled by GPIO54-GPIO61. Lately I came to realize that the necessary control-routine for those GPIOs seems to have an error. So I started troubleshooting it. Unfortunately I can't find any mistakes in the code and if the CCS 3.3 Watch-Window is right, the controller doesn't do what it's supposed to do. Instead it causes some outputs to be set/reset when they shouldn't.
The sourcecode:
void IOMux_Write_Bit(Uint16 u16_address, Uint16 u16_bit, Uint16 u16_value)
{
//u16_address: value between 0 and 7
//u16_bit: value between 0 and 7
//u16_value: value between 0 and 1
#ifndef HDR2_GPIO
#ifdef HDR3_GPIO //necessary defines for proper operation
//Variables for testing...
Uint32 ui32_address = 0;
Uint32 ui32_bit = 0;
Uint32 ui32_value = 0;
Uint32 Temp_Mask = 0;
ui32_address = (Uint32)u16_address; //cast here, so I can check whether the cast worked fine...
ui32_bit = (Uint32)u16_bit;
ui32_value = (Uint32)u16_value;
Joetest10 = u16_address; //save input variables to global variables for watchwindow
Joetest11 = u16_bit;
Joetest12 = u16_value;
Joetest323 = ui32_address; //save internal variables to global variables for watchwindow
Joetest324 = ui32_bit;
Joetest325 = ui32_value;
if((u16_address == 6) && (u16_bit == 7) && (u16_value==0))
{
Joetest3++; //count, how often the correct instruction (Address = 6, Bit = 7, Value = 0) is called
}
//Clear GPIO57 (--> disables Address-Enable-Slave)
GpioDataRegs.GPBCLEAR.bit.GPIO57 = 1;
asm(" RPT #7 || NOP"); //wait --> for timing purposes
//Clear all bits of Multiplexer-Control-Circuits (GPIO54-GPIO61)
GpioDataRegs.GPBCLEAR.all = 0x3FC00000;
asm(" RPT #5 || NOP");
//Calculate Mask for addressing of Output-Latch-Slave-IC via GPB
Temp_Mask = ui32_address << 26;
Joetest321 = Temp_Mask; //copy mask to global register to watch in watch window
GpioDataRegs.GPBSET.all = Temp_Mask; //Set corresponding bits to activate Output-Latch-Slave-Address (GPIO58 - GPIO60)
asm(" RPT #30 || NOP"); //wait --> for timing purposes
//Clear again the bits of the Bit-Address-Bus (redundant)
GpioDataRegs.GPBCLEAR.all = 0x01C00000;
asm(" RPT #2 || NOP");
//Calculate the mask of the corresponding bits for the Bit-Address-Bus
Temp_Mask = ui32_bit << 22;
asm(" RPT #30 || NOP"); //wait --> for timing purposes
Joetest322 = Temp_Mask; //copy mask to global register to watch in watch window
GpioDataRegs.GPBSET.all = Temp_Mask; //Set corresponding bits to activate the Bit-Address-Bus (GPIO54-GPIO56)
//Set the data-pin if it should be set (value != 0) or clear it, if value is 0
if(ui32_value != 0)
{
GpioDataRegs.GPBSET.bit.GPIO61 = 1;
}
else
{
GpioDataRegs.GPBCLEAR.bit.GPIO61 = 1;
}
asm(" RPT #7 || NOP");
// Set data-pin as output
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;
EDIS;
asm(" RPT #7 || NOP");
//activate latch-function of the addressed slave
GpioDataRegs.GPBSET.bit.GPIO57 = 1;
asm(" RPT #7 || NOP");
//####################################################
//Testing: check if address == 6, bit == 7 and value = 0
if((GpioDataRegs.GPBDAT.all & 0x3FC00000) == 0x1BC00000)
{
Joetest5 = u16_address; //copy input variables to another global variable for watch window to become amazed
Joetest6 = u16_bit;
Joetest7 = u16_value;
Joetest4++; //count, whenever this configuration occured --------> BREAKPOINT updating watch window
}
//#######################################################
// Deactivate latch-function of addressed slave
GpioDataRegs.GPBCLEAR.bit.GPIO57 = 1;
asm(" RPT #7 || NOP");
//Protect GPIO by putting it into input-state
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO61 = 0;
EDIS;
#endif
#endif
}
What the watch-window says at the breakpoint:
Address-variables:
Joetest10 = 6 and Joetest323 = 6 (both at start of the routine and correct) <------> Joetest 5 = 0 should be the same ( = 6)
Bit-variables
Joetest11 = 7 and Joetest323 = 7 (both at start of the routine and correct) <------->Joetest6 = 0..7 should also be the same ( = 7)
Value
Joetest12 = 1 and Joetest324 = 1 (both at start of the routine and correct) <-------> Joetest7 = 0 should be the same ( = 1)
I think I should mention that the condition: if((GpioDataRegs.GPBDAT.all & 0x3FC00000) == 0x1BC00000) means: address = 6, bit = 7, value = 0... This routine is repeatedly called with different configurations, but NEVER (except for 4 times on purpose at the start of the whole program) with address = 6, bit = 7 and value = 0 at the same time! In fact, it's called with address = 6, bit = 7 and value = 1 very often within a loop. It seems that this error randomly occurs while the program is running... every 3 seconds, sometimes two or three errors at once...
The masks for the addresses and bits (Temp_Mask shown via Joetest321 and Joetest 322): Most of the time correct (0b00011000... and 0b000000111000...), but sometimes just plain wrong (Joetest322 = 0 or something else...)
I double-checked whether any of those GPIOs (54-61) is used somewhere else (they aren't), whether my global variables are manipulated somewhere else (they aren't) and whether my GPIOs are initialized correctly (they are). And: the DSP doesn't seem to be damage, as I have the same problem on another board...
So, can anybody tell me, what this DSP is doing? Because it definitely should do something else...
I appreciate any help.