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.

TM4C123GH6PM: Accessing the AHB immediately after enabling it throws a fault

Part Number: TM4C123GH6PM

Hi Team, 

Good day. I am posting this inquiry on behalf of the customer.

"I am working with a program that attempts to access a GPIO port through the AHB. When compiled with -O0, everything works as expected and the disassembled pseudocode for this reads:

...STR instruction to enable the AHB for the GPIO portMOV instructions to prepare the GPIO port memory address needed nextLDR instruction to read the GPIO port through the AHB...

However, when compiled with -O1, a fault is thrown upon execution. I have narrowed down the cause of the fault to the above code section through debugging and found that the disassembled code this time is the same as above except that the MOV instructions are omitted (the memory address is instead prepared earlier in the code). So, it seems that enabling the AHB and then attempting to immediately access it in the very next instruction can cause issues.

My understanding is that this is due to one of two reasons:

1) there is an instruction synchronization issue occurring that requires an appropriate memory barrier to fix, or

2) there is a hardware latency issue occurring that requires an appropriate delay to transpire to fix.

If 1) is correct, then which barrier instruction should be inserted between the STR/LDR to resolve this? I wasn't able to identify an answer in the ARM CortexTm-M Programming Guide to Memory Barrier Instructions Application Note. If 2) is correct, then what is the recommended way to ensure that the bus is ready to use upon enabling it? There is no associated ready-bit register to check for the buses like there is for the GPIO (PRGPIO), for example.

I believe it is 2) that is correct since the problem only occurs when executing the program at full speed and not when single-stepping over these instructions with a debugger (please correct me if this assessment is wrong). I also was unable to find any mention of such a sync/latency characteristic of the buses in the TivaTm TM4C123GH6PM Microcontroller Data Sheet.

Any assistance is appreciated."

Please help to advise. Thank you for extending your support.

Kind regards, 

Marvin

  • Hello Marvin,

    2) there is a hardware latency issue occurring that requires an appropriate delay to transpire to fix.

    This is the answer. There is some time required after enabling a peripheral before it is ready to be used.

    In TivaWare the SysCtlPeripheralReady API is used to check for this. The DRM code would be as follows:

    HWREGBITW(SYSCTL_PRBASE + ((ui32Peripheral & 0xff00) >> 8), ui32Peripheral & 0xff));

    Where:

    • ui32Peripheral is based on the SYSCTL_PERIPH table in sysctl.h - so for GPIOA, it would be SYSCTL_PERIPH_GPIOA.
    • SYSCTL_PRBASE is defined in sysctl.c to be 0x400fea00

    Likely more relevant for them is that whole sequence is checking Register 108: General-Purpose Input/Output Peripheral Ready (PRGPIO), offset 0xA08 from the device datasheet.

    Best Regards,

    Ralph Jacobi

  • Hi Ralph, 

    Thank you for your response. Please see the feedback from our customer.

    Allow me to expand on my setup sequence for clarification and to show details I should have included the first time:

    ...
    1) Enabling the GPIO port via register **RCGCGPIO**
    2) Busy-waiting until the GPIO port is ready via register **PRGPIO**
    3) Enabling the AHB for the GPIO port via register **GPIOHBCTL**
    4) Setting the direction of the GPIO (AHB) port via register **GPIODIR**
    ...

    In other words, I confirm the readiness of the GPIO peripheral above at Line 2 yet the fault still occurs at Line 4 when running at full speed. The fact that it does not occur when single-stepping with a debugger is why I assumed it was, indeed, a latency issue as you say. However, it looked to me as though it was the AHB that was not ready upon enabling it in Line 3 and then attempting to access it in the very next instruction. So again, this looks to mean one of two things:

    1) enabling the AHB for a GPIO port clears the ready bit for that port which must then be checked for readiness, or
    2) the readiness of a GPIO port and the readiness of the bus used to access it are distinct and so some other action must be performed to ensure the bus is ready, as well.

    If 1) is true, then I assume the solution would be to switch Lines 2 and 3 above. If 2) is correct, then is there a way to check the readiness of the AHB upon enabling it that is guaranteed and does not involve some busy-wait or barrier/NOP delay of arbitrary length?

    Please help to advise. Thank you for extending your support.

    Kind regards, 

    Marvin

  • Hello Marvin,

    Thanks for the added detail here. I did some investigations regarding this.

    1) enabling the AHB for a GPIO port clears the ready bit for that port which must then be checked for readiness, or

    I see no indication this is the case, so I would not consider this to be the root cause nor would I expect the adjustment outlined would work correctly.

    2) the readiness of a GPIO port and the readiness of the bus used to access it are distinct and so some other action must be performed to ensure the bus is ready, as well.

    I believe this the root cause here, but documentation does not cover any specific wait times. Looking at how the GPIO module generally handles changes, I would expect it would take effect within a few clock cycles. For our usual TivaWare code, we have not run into any issues with this so the added overhead from that style of programming is sufficient.

    Unfortunately as I couldn't find any specific wait time to provide, and we don't have access to design simulations for this part to try and specify that duration,  the only option here would be an arbitrary NOP length.

    Best Regards,

    Ralph Jacobi