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.
I'm just starting to testing a new board with a TMS320F28335 on it. I have some basic test code running and one of the first tests I've run is to flash a couple LEDs. After an intial issue I decided ti try a couple of different ways to do this and I got two to work just fine and the third to work only with a double write to the port. (See below)
Method A
I write all 32 bits of data to port B to set the state of both the LEDs. This works as expected.
// GpioDataRegs.GPBDAT.all = 0x03; // - Method A
Method B
I use the GPBSET and GPBCLEAR registers to set the specific LED in turn. This works as expected.
// GpioDataRegs.GPBSET.bit.GPIO32 = 1; // Green LED - Method B
// GpioDataRegs.GPBSET.bit.GPIO33 = 1; // Red LED
Methiod C
I use the GPBDAT register to set the appropriate Bit on or off. This is were things don't work as expected. If I set one than the other only the second value is set. I can reverse the command and still only the second write works.
GpioDataRegs.GPBDAT.bit.GPIO32 = 1; // Green LED - Method C
GpioDataRegs.GPBDAT.bit.GPIO33 = 1; // Red LED
(Only Red LED will work.)
OR
GpioDataRegs.GPBDAT.bit.GPIO33 = 1; // Red LED
GpioDataRegs.GPBDAT.bit.GPIO32 = 1; // Green LED - Method C
(Only Green LED will work.)
If I set a breakpoint and then signle step over the commands they will work as exected.
Also if I double write the first LED command it will also work
GpioDataRegs.GPBDAT.bit.GPIO32 = 0; // Green LED - Method C
GpioDataRegs.GPBDAT.bit.GPIO32 = 0; // Green LED
GpioDataRegs.GPBDAT.bit.GPIO33 = 0; // Red LED
Can someone explain this?
Ed Hildebrandt
Ed,
This happens because of the read modify write instructions that these lines of code generate. Remember this is a pipelined architecture. Let me explain more:
When the first line of code is executed it reads the contents of the GPxDAT register modifies the bit requested and then write it back into memory (remember these are discrete steps that occur at different times in the pipeline). While the CPU is doing this, the next instruction is being read and executed ...specifically the read of the GPxDAT register again. Now the first modify to lets say GPIO32 is done, but the CPU is now modifying the bit for GPIO33 WITH THE OLD REGISTER VALUE!!! Now when this gets written back to memory it overwrites the first write so that it is effectively lost.
I actually ran into this same problem in some code I was working on this morning. For this reason and a few others, it is not good practice to use bitfields. In our newer software we still provide bit fields for learning purposes, but we recommend users use drivers or other methods of accessing the peripheral register. For more info on why bitfields are problematic take a look at this.
Regards,
Trey
Trey, Is this behavior observed regardless of the sub-register (DAT, SET, or CLEAR) being used ?
I.e., can it be avoided by using only SET or CLEAR to update/write state, and using only DAT to read state ?
I, too, have a "rogue-write" to a GPIO, but it's happening on only 1 of 12-15 GPIOs all of which are coded to undergo identical operations (when called upon individually to be operated on).
Greg
Yes, this behavior will be present on all the accesses made like this. HOWEVER, you will not see in correct behavior in the case of the set and clear bits because of how they work. In the scenario I outlined above, both lines are causing a write to the DAT register, but what if this was a set/clear/toggle register? The write still occurs for both lines of code, its just the second one overwrite the first. In the case of the set/clear/toggle registers there is nothing to overwrite, so the first write causes the appropriate action to be taken on the GPIO and then the second write goes through and modifies the second GPIO.
Trey
Trey,
Thanks for the help that makes sense. This is the first time I've worked with a pipelined processor. I know the basic concept, but I'd like to read up on the details. Can you recommend a good resource?
Thanks
Ed
Ed,
If you're looking for specifics of how the C28x works I would recommend the CPU and Instruction Set Reference Guide (spru430). If you're looking for more general CPU architecture information I would recommend you just get one of the many computer architecture text books out there (I don't have any specific recommendations, though).
Trey
One more question on this subject. Why does this issue not appear when writting the configuration registers?
For example the following code seems to work just fine:
SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 0; // I2C
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 0; // SCI-A
SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1; // SCI-B
SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 0; // SCI-C
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 0; // SPI-A
SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 0; // McBSP-A
SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 0; // McBSP-B
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 0; // eCAN-A
SysCtrlRegs.PCLKCR0.bit.ECANBENCLK = 0; // eCAN-B
Ed
Ithink both of you are a little bit on a false path.
The C2000 has a "protected" pipeline, means theat a read, following a write to the same memory location will not lead to a read of the old value. Instead, the hardware of the CPU - pipeline will include 1(or 2) waitstates to delay the read access until the earlier write has finished (see our workshop files regarding pipeline). What happen's with the GPIO's is that the pins are just not fast enough to execute two switch- instructions in such a short time. I believe the max. GPIO - switching speed is in the region of 20 MHz, whereas the CPU runs at 150 MHz. (see datasheet). The situation is different with other registers, such as PCLKCR0, which has not speed limitations.
Regards
Frank,
Thanks for your response, that makes a lot of sense.
Can you post a link to the pipeline workshop?
Thanks
Ed
Ed,
it's here: http://processors.wiki.ti.com/index.php/C2000_Piccolo_Multi-Day_Workshop ; Page 1-7 of the Student Guide (pdf document at the bottom of the wiki page).
The GPIO speed is defined in the data sheet.
Regards
BTW: The next face to face workshops will be held in Dallas, US (Oct 23-25) and Regensburg, Germany (Sept. 18-21).