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.

OMAP-L138 GPIO CLR_DATA problem

I'm trying to set up some GPIO pins as outputs and am having issues when I write to the CLR_DATA register.

Desired pins:
GP6[0-4], GP6[6], GP6[12-13] - all configured as output pins.

Pinmux:
reg: 13, mask: 0x0000FF00, val: 0x00008800
reg: 14, mask: 0x000000F0, val: 0x00000080
reg: 19, mask: 0x0FFFFF00, val: 0x08888800

From the GPIO User's guide (http://focus.ti.com/lit/ug/sprufl8b/sprufl8b.pdf), it says for a GPIO output signal that one should "write a logic 1 to the bit in SET_DATA... to be driven high" and "write a logic 1 to the bit in CLR_DATA... to be driven low." It also states that the OUT_DATA register "contains the current state of the output signals" and that reading IN_DATA "returns the output value being driven by the device."

When I configure the pins above as outputs pins and drive them all to high (by setting the appropriate bit in SET_DATA), I see the following values:
OUT_DATA: 0x0000305F
SET_DATA: 0x0000305F
CLR_DATA: 0x0000305F
IN_DATA: some value, such as 0x0000FFDF, where 0x0000305F is a subset.

However, when I change pin 12 to drive low (by writing 1 to the appropriate bit in CLR_DATA), I see the following values:
OUT_DATA: 0x00000000
SET_DATA: 0x00000000
CLR_DATA: 0x00000000
IN_DATA: 0xFFFFC780

Note that 0xC780 is not a super set of 0x205F. In fact, instead of just pin 12 being driven low, all of my configured pins are now being driven low. Subsequent reads of IN_DATA shows that these pins are constantly changing, i.e. neither driven high or low.

When I use the same logic, except that I am writing or clearing the bit in OUT_DATA only, then the above steps work appropriately.

The second "feature" in the GPIO User's Guide states "Output set/clear functionality through separate data set and clear registers allows multiple software processes to control GPIO signals without critical section protection." I would prefer to use this feature. Is there a problem with writing to CLR_DATA or am I doing something wrong?

Thanks,
Wes

  • Wesley Denlinger said:
    The second "feature" in the GPIO User's Guide states "Output set/clear functionality through separate data set and clear registers allows multiple software processes to control GPIO signals without critical section protection." I would prefer to use this feature. Is there a problem with writing to CLR_DATA or am I doing something wrong?

     

    Wes,

       There is some example code for using GPIO in this link. If I were you, I would take advantage of the CSLr macros instead of programming all the registers at the bit level. There are 5 simple macros that you can use to set/clear bits.

  • Hi Drew,

    Thank you for your reponse. I followed the link you provided and perused the code in project GPIO_multi_led_interrup_dspL137. I added in the necessary macros and performed the steps I described above. However, I received the same results. As soon as I write to the CLR_DATA using the following macro:

    CSL_FINS(gpioRegs->BANK[GP6].CLR_DATA, GPIO_CLR_DATA_CLR12, CSL_GPIO_CLR_DATA_CLR_CLR);

     

    all of the pins go to 0. I also noticed that the macros aren't always used, but the registers are programed at the bit level. For instance, on line 150 of main.c SET_DATA is written to in the following manner:

    gpioRegs->BANK[GP0].SET_DATA = (GP0P12 | GP0P13 | GP0P14 | GP0P15);

    Writing to SET_DATA has worked fine for me though. Later on, on line 191, CLR_DATA is directly written to as well.

    gpioRegs->BANK[GP0].CLR_DATA = GP0P12;

    Have you been able to change a bit to 1 in the CLR_DATA registers without it affecting the non-related bits in SET_DATA or OUT_DATA?

    Thanks,
    Wes

  • Hi Wes,

    I was unable to replicate your issue. Would you mind using the attached source and header files to verify that you are still not able to clear just one bit?

    You will need to add the "quickStartOMAPL1x_rCSL/OMAPL1x/support/includes" folder to your "#include search path options" in the "C/C++ Build Settings".

    Hope this helps!

    Thanks,
    Kevin

    1145.test_gpio_l138.zip

  • Hi Kevin,

    Thank you for your response and sample code. When I was writing to CLR_DATA and SET_DATA, I was using |= (OR EQUALS) instead of just writing the bit. I thought I needed to preserve the state of those registers. Clearly, I was wrong.

    Thank you for your help,
    Wes

  • Hi Wes,

    Glad to hear everything is working and thanks for sharing the result!

    You are correct, the state of "CLR_DATA" and "SET_DATA" do not need to be preserved (writes of 0 have no effect, regardless of I/O direction).
    You could also write directly to the "OUT_DATA" register; however, the state of "OUT_DATA" should be preserved.

    Unfortunately, this presents one of the rare occurences where using the CSL "field insert" macros (CSL_FINS, CSL_FINST) can get you in trouble, as you observed. The CSL "field insert" macros also perform a read/modify/write and thus produce undesirable results when writing to those registers. Setting a bit in "SET_DATA" also sets the corresponding bit in "CLR_DATA". Thus when the state of the register is preserved, the user writes a "1" to every "set" bit, which clears all the bits. You could use the CSL "field make" macro (CSL_FMK) to obtain the value to write to the register; using the "GPxPx" defines as demonstrated in the example will also work.

    Sorry for any confusion; I hope this helps!

    Regards,
    Kevin