Struggling to get fast GPIO working on i.mxrt1176

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Struggling to get fast GPIO working on i.mxrt1176

2,569 Views
simongornall
Contributor I

I'm looking to figure out whether I can get use an i.MX1176 to solve a tight-timing problem in software when reading a bus rather than resorting to an FPGA. Here's the bus timing

CPU -External Device Timing.GIF

It's a 6502, so there's also the voltage-level-changing delays to concern me, but the main problem is the bottom trace (/MPD). I have to read the address lines, do a lookup in a 256-long table of A[15:8] and if the entry in that table is '1' rather than 0, assert /MPD, else ignore it and let it keep floating high.

The timing budget for this is ~45ns, given that A being active at 177ns from the clock-cycle probably translates to 180ns from the clock falling. 

My plan was to use the M4 to poll the bus, dedicating it to the task of handling the bus signals, then M4 writes to shared memory, pings a semaphore, and lets the M7 actually process stuff. That is predicated on the delay to assert a GPIO being sufficiently rapid, but looking at this gave me some hope that would be possible - 10ns to toggle a GPIO is awesome.

Sadly, I'm not seeing that using my board. I've set the build to 'Release' and set it so that GPIO9(io 6) is the GPIO being toggled, set the slew rate to be fast...

Screen Shot 2023-06-18 at 4.30.30 PM.png

and I'm calling:

        PRINTF("Toggling.\r\n");
        GPIO_PortToggle(GPIO9, 1<<6);
        GPIO_PortToggle(GPIO9, 1<<6);

 

From looking at the library code, it seems to be doing the correct thing, assuming the inline is honored for a release build (in fact I checked this, and replaced the function calls to the direct register-set operations)...

Screen Shot 2023-06-18 at 4.34.26 PM.png

But I'm only getting a 68ns period not a 10ns period like in the linked article...

Screen Shot 2023-06-18 at 4.40.07 PM.png

I'm totally new to the i.mx series, I'm presumably doing something stupid, so if anyone has words of wisdom, I'm all ears...

One thing I'll say is that I don't seem to be able to get the 'play' button at the top of the window to actually run the code on the device - it seems to compile then hang. I'm actually running this using the 'Debug' operation (yes, on a release build) from the Quickstart panel, so possibly there's some overhead in that being the case ?

 

0 Kudos
Reply
9 Replies

2,317 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @simongornall ,

  Please test my project on the MIMXRT1170-EVK board, the test GPIO pin is the  GPIO_AD_04, J9_8pin.

  Use the fast GPIO, it should can upto 248.87MHz, sine wave. normal GPIO also can upto 17.12Mhz, pulse wave.

  My oscilloscope sample rate is not enough, so to the fast GPIO, the wave is not good.I just get 81Mhz, as my testing tool is not enough, sample rate just 1GS/s.

  But our AE can get 248.87Mhz sine wave, you also can test it on your side.

  We suggest you use the oscilloscope with 2GHz bandwidth, sample rate to 10Gs/s, then I think you can get the AE related data.

I attach my project, you can test it directly, as it is calling the fast GPIO directly, testing pin is the J9_8.

 

You can see my wave:

Normal GPIO 17.22Mhz, I can get it correct:

kerryzhou_0-1688034887650.png

But to the fast GPIO, my oscillator is not enough, just up to 81M

kerryzhou_2-1688035137031.png

 

But, I can make sure, if the oscillator is 10Gs/s sample rate, you can get 248.87Mhz sine wave.amplitude is 1/4 sine wave.

 

void io_test_init(bool useNormalGpio)
{
    gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
    CLOCK_EnableClock(kCLOCK_Iomuxc);
    IOMUXC_SetPinMux(IOMUXC_GPIO_AD_04_GPIO_MUX3_IO03, 0U);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_04_GPIO_MUX3_IO03, 0x000eU);
    if (useNormalGpio)
    {
        // GPIO3
        IOMUXC_GPR->GPR42 &= ~(1u << 3);
        GPIO_PinInit(GPIO3, 3, &led_config);
    }
    else
    {
        // CM7_GPIO3
        IOMUXC_GPR->GPR42 |= (1u << 3);
        GPIO_PinInit(CM7_GPIO3, 3, &led_config);
    }
}

void io_test_run(bool mode)//1 FSGPIO, 0 NORMAL GPIO
{
  if(mode)
  {
    io_test_init(false );//FSGPIO
    while (1)
    {
        CM7_GPIO3->DR_TOGGLE = 0x8;
    }
  }
  else
  {

    io_test_init(true );//GPIO
    while (1)
    {
        GPIO3->DR_TOGGLE = 0x8;
    }

   }

}

 

Wish it helps you!

Best Regards,

Kerry

 

 

 

 

0 Kudos
Reply

2,505 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @simongornall ,

   Thanks for your updated information.

    Can you reproduce the issues on the NXP MIMXRT1170-EVK board? If yes, please tell me, and send me your tested project, I will find time to help you do the testing on my side.

  When you test the wave, I recommend you use the oscillatescope instead of the logic analyzer, as that will check the very original wave.

Best Regards,

Kerry

0 Kudos
Reply

2,488 Views
simongornall
Contributor I

Hi @kerryzhou 

 

Thank you for the help - I have put a sample project on GitHub that works on the EVK  

The Logic analyzer is a pretty good one, and it's a bit awkward to get to the scope at the moment, but I had the LA sample the analogue signal (@50MHz) at the same time as sampling the digital signal (@500MHz) as you can see below...

samples.png

 

Thanks again  

0 Kudos
Reply

2,424 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @simongornall ,

   Thanks for your information.

   These days(6.22 to 6.24), we are in the Dragon Boat Festival, and I lack the testing tool at my home during the holiday, we will be back to work from 6.25.

   I will help you do the testing on my side after I back to work.

   So, please keep patient, I will help you do the testing on my MIMXRT1070-EVK board, thanks a lot for your understanding.

Best Regards,

Kerry

 

0 Kudos
Reply

2,351 Views
simongornall
Contributor I

/thank you Kerry - I hope you had a good festival. Do you have any advice on what I've done wrong in the project ?

0 Kudos
Reply

2,334 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @simongornall ,

  I am really so sorry for my later reply, as really overwhelming in the case testing.

  I checked your situation, your low speed 54ns should from the normal GPIO, not the HSGPIO.

   If you use the HSGPIO, then you will get the higher gpio frequency, The HSGPIO even can get the 248.87Mhz when M7_CLK=996Mhz, BUS_CLK=240Mhz, I/O PAD is fast slew, use the GPIO->DR_TOGGLE.

  I will test it today, and give you my project and the wave pictures, wait me a moment.

 

Best Regards,

Kerry

0 Kudos
Reply

2,526 Views
simongornall
Contributor I

Hi Kerry, thanks for getting back to me

So the code I'm using is very similar, though I was using GPIO9 bit 6 instead. There are a couple of differences....

The auto-generated code from MCUExpresso creates:

  IOMUXC_SetPinConfig(
      IOMUXC_GPIO_AD_07_GPIO9_IO06,           /* GPIO_AD_07 PAD functional properties : */
      0x07U);                                 /* Slew Rate Field: Fast Slew Rate
                                                 Drive Strength Field: high drive strength
                                                 Pull / Keep Select Field: Pull Enable
                                                 Pull Up / Down Config. Field: Weak pull down
                                                 Open Drain Field: Disabled
                                                 Domain write protection: Both cores are allowed
                                                 Domain write protection lock: Neither of DWP bits is locked */

 

Looking in the 1170 reference manual, page 1096, 0x07U would correspond to:

  • Slew rate slow (at odds with the comment)
  • Drive strength high
  • Pull enabled
  • Weak pull down
  • Open drain disabled
  • Both cores allowed
  • Neither DWP bit locked

Whereas the blog code uses 0x0EU which sets a weak pull-up (instead of pull-down) and sets the slew rate correctly. I ought to be using 0x06 to set the slew rate, which would seem to be a bug in the IDE (since I set slew rate to fast in the "pins" tool of the IDE, and the comment makes it look like it's supposed to have bit 0 set to 0.

Setting the slew rate correctly gives me pulses approximately 44 -> 54ns in duration, so that's helped, but it's still a long way short of 10ns. 

Screen Shot 2023-06-19 at 2.42.06 PM.png

Next step

I suspected the slowness might be because of the line in the blog: "the project build with the highest code execution performance is selected here (that is, the code segment is in ITCM and the data segment is in DTCM)." - which was not working for me - all my code was in flash, but after looking at another of your posts I got everything compiling into ITCM...

Memory region         Used Size  Region Size  %age Used
     BOARD_FLASH:          0 GB        16 MB      0.00%
    SRAM_ITC_cm7:       40572 B       256 KB     15.48%
    SRAM_DTC_cm7:          0 GB       256 KB      0.00%
        SRAM_OC1:          0 GB       512 KB      0.00%
        SRAM_OC2:          0 GB       256 KB      0.00%
   NCACHE_REGION:          0 GB       256 KB      0.00%
    SRAM_OC_ECC1:          0 GB        64 KB      0.00%
    SRAM_OC_ECC2:          0 GB        64 KB      0.00%
     BOARD_SDRAM:          0 GB        64 MB      0.00%

 

However, I'm still seeing 52 -> 54ns pulses on the logic analyzer:

Screen Shot 2023-06-19 at 3.02.22 PM.png

 

I am running using the 'Debug' operation of the Quickstart panel (with a release build).

Screen Shot 2023-06-19 at 3.04.10 PM.png

Could the "debug" facility be slowing things down ? Is there a better way to run the application ? The green 'play' icon at the top doesn't seem to have anything that will let me configure a download-to-the-board-and-run operation, and nothing happens when I press it anyway ... 

Screen Shot 2023-06-19 at 3.06.23 PM.png

Cheers

 

0 Kudos
Reply

2,551 Views
simongornall
Contributor I

Replying to myself because it looks as though I can't edit - maybe it's too old. 

While walking the dog, it did occur to me that the code might not be in the fastest-fetch location - and looking at the output of the build, it's going to flash...

Memory region         Used Size  Region Size  %age Used
     BOARD_FLASH:       29612 B        16 MB      0.18%
    SRAM_DTC_cm7:       19276 B       256 KB      7.35%
    SRAM_ITC_cm7:          0 GB       256 KB      0.00%
        SRAM_OC1:          0 GB       512 KB      0.00%
        SRAM_OC2:          0 GB       256 KB      0.00%
   NCACHE_REGION:          0 GB       256 KB      0.00%
    SRAM_OC_ECC1:          0 GB        64 KB      0.00%
    SRAM_OC_ECC2:          0 GB        64 KB      0.00%
     BOARD_SDRAM:          0 GB        64 MB      0.00%
Finished building target: evkmimxrt1170_freertos_hello_cm7.axf

 

but telling the linker to use SRAM_ITC_cm7 didn't seem to make any difference - I get exactly the same report above when I remake with the function looking like:

__RAM_FUNC_EXT("SRAM_ITC_cm7") static void toggleIt()

 Of course this just means I'm doing this wrong too More reading, it seems...

0 Kudos
Reply

2,541 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @simongornall ,

   Thanks you for your interest in the NXP MIMXRT product, I would like to provide service for you.

  For the RT1170 fast GPIO, our Expert have a blog about it, just it is in Chinese, you can read it with the translation tool at first, that is really very useful:

https://www.cnblogs.com/henjay724/p/15581290.html

  When you test the toggle which want to get the faster speed, don't call the API, use the register control directly, eg:

    while (1)
    {
        GPIO6->DR_TOGGLE = 0x800;
    }

 Please check my mentioned blog at first!

If you still have issue about it, please kindly let me know.

Best Regards,

Kerry

0 Kudos
Reply