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.

AM5748: GPIO toggling latency is high

Part Number: AM5748

Hi,
we are trying to implement the I2C communication to communicate with slave device without I2C engine (via bit banging). Currently we could able to achieve it, but the GPIO toggling latency is high. As we could able to achieve upto 32kHz frequency, but we are expecting to achieve at least  2 MHz frequency.  

The ARM core is booted with Linux and using below API's in user space to toggle the GPIO's,

int gpioValue = open(gpioPath, O_WRONLY);
write(gpioValue, state, 1);


Please kindly provide the proper guidelines to achieve the GPIO toggling speed till 2MHz  

Thanks,
Srinidhi H

  • Hi,

    Need some time to look into this. Will get back to you on this by tomorrow.

    Regards,
    Parth

  • Hi Srinidhi,

    As we could able to achieve upto 32kHz frequency, but we are expecting to achieve at least  2 MHz frequency.  

    We have not tried anything like this. Can you please share the code how you are achieving this? I am not sure, if it is even possible or not to achieve 2MHz.

    we are trying to implement the I2C communication to communicate with slave device without I2C engine (via bit banging).

    Also, what is the intent here? Why are you not using the i2c controller available directly?

    Regards,
    Parth

  • Hi Parth,

    Thanks for the quick response. The main purpose of this interface is used to flash one of the PIC microcontroller from AM5748 ARM core. 
    Due to design constraints we wanted to use these GPIO pins instead of I2C. Already custom PCB and all done, for that we wanted to achieve this GPIO speed from software. The AM5748 GPIO pins used here are mentioned below, 
                                                                                    1. gpio7_31 --> as I2C SDA
                                                                                     2. gpio7_32 --> as I2C SCL




    Thanks,
    Srinidhi H 

  • Hi Srindhi,

    Can you please share the code how you are achieving this?

    Can you please share the code?

    Regards,
    Parth

  • Hi Parth,

    Below piece of code which can toggle the GPIO at the speed of 32kHz at Linux user space.

    setPin(ICSPMode, FALSE); //ICSPMode = low --> bootup stage
    setPin(ICSPMode, TRUE); //ICSPMode = high

    inside setPin() function,

    int gpioValue = open(gpioPath, O_WRONLY);

    write(gpioValue, state, 1);


    Thanks & Regards,

    Srinidhi H

  • Looping in more experts to comment on this

    Regadrs,
    Parth

  • Hello,

    Can you dig into the assembly code - Are there any read-modify-write sequences happening?  If you issue reads to the GPIO module it will significantly slow down compared to only issuing writes.

    There are three registers that can set the output:

    GPIO_DATAOUT can be programmed to set the corresponding outputs to a 1 or 0.  So writing say 0x5 will set bits[2:0] to 1, 0, 1.  If you wanted to modify one bit SW may try to read the value of the register and mask the value for the 1 bit you care about and write it back to the register.

    GPIO_CLEARDATAOUT ... you write a 1 to bits that you want to clear (drive low).  No read modify write is required and you will only affect the bits you want to.

    GPIO_SETDATAOUT is similar ... write a 1 to bits that you want to set (drive high).  

    You want to make sure software is using the CLEAR and SET registers.

    Regards,
    Kyle

  • Can you also summarize:

    - Is this a 1 time programming in your factory, or does this "flash one of the PIC microcontroller" happen in the real system/application?  How often?

    - Is 2 MHz a hard requirement or you are just trying to improve from 32kHz that you are achieving now?

    Thanks,

    Kyle

  • Hi Kyle,

    Thanks for the reply.

    Sorry, we cannot able to dig into the assembly level as of now. Can you please recommend some other way.

    As we are still in development phase (not one time) and also required for production(maybe one time) in the future.

    In current senecio, to flash the 75kb file from AM5748 to Pic controller, it consumes 13 min and which is not acceptable. The main agenda is to reduce the flashing time from 13 min to 2/3 min as the end result. The entire process is again depend on GPIO toggling on AM5748.  

    The slave can respond up to 8MHz of speed. 



    Thanks,
    Srinidhi H

  • Srinidhi,

    Are you (or colleague) writing the "bit banging" code?  Can you trace what's going on with JTAG debugger (CCS or Lauterbach?) to see if read transactions are mixed in with the writes?

    Thanks,

    Kyle 

  • Hi Kyle,

    We are not using the JTAG debugger, as we are developing this utility on Linux platform. It is purely a bit banging code which is replicating the I2C interface. I feel there should not be any shuffling or mixing between reads or write cycles because we could able to get the output results with delay process.

    Also we are able to achieve the expected results with least delay, where further reduction is impacting the output results. 

    To glance the agenda: Currently AM5748 consuming 13 to 14 min of time to transfer the data to PIC Microcontroller. Target is to reduce the flashing time to 2 to 3 min.



    Thanks,
    Srinidhi H

  • Hello Srinidhi,

    Can you share more information as to how you the code/driver uses the GPIO from userspace?

    What SDK/Kernel is being used?

    -Josue

  • Hi Josue,


    PFA for piece of code used to write and read GPIO Pin on AM5748 ARM core. 
    SDK version:ti-processor-sdk-linux-rt-am57xx-evm-08_02_01_00-Linux.

    /**********************************************************************************************************************************
      Function: Setpin
      Description: Write state of gpio
      Inputs: pin - pin number
      		  state - HIGH or LOW
      Output: None
    **********************************************************************************************************************************/
    int setPin(int pin, char * state){
    
    	snprintf(gpioPath, sizeof(gpioPath), "/sys/class/gpio/gpio%d/value", pin);
        
        int gpioValue = open(gpioPath, O_WRONLY);
        if (gpioValue == -1) {
            perror("Failed to open GPIO value file");
            return 1;
        }
        
    /**********************************************************************************************************************************
      Function: GetPin
      Descriptio: Gets the GPIO value/state 
      Inputs: pin - gpio
      Output: state - Low(0)/High(1).
    **********************************************************************************************************************************/
    int getPin(int pin)
    {
    int a;
    snprintf(gpioPath, sizeof(gpioPath), "/sys/class/gpio/gpio%d/value", pin);
        
        int gpioValue = open(gpioPath, O_RDONLY);
        if (gpioValue == -1) {
            perror("Failed to open GPIO value file");
            return -1;
        }
        
        char value;
        read(gpioValue, &value, 1);
       //printf("GPIO value: %c\n", value);
       a=atoi(&value);
        close(gpioValue);
        return a;
    }
        
        // Write '1' or '0' to the value file to set the GPIO high or low
        write(gpioValue, state, 1);
        close(gpioValue);
        return 0;
    }



    By any chance can we toggle the GPIO at 1MHz (For time being).


    Thanks,
    Srinidhi H

  • Hello Srinidhi,

    I am passing the message to Kyle. Need some more time to look into this. Keep in mind this is not a feature from our SDK therefore it falls out of our standard support.

    What are the GPIOs set up as in pin-mux?

    Is this a user-space program?

    -Josue

  • Hi Josue,

    Thanks for the quick reply. 
    As from the Application perspective need GPIO to be operated or toggled at the frequency of 2MHz.

    The particular pins are mux as GPIO's.
    Yes, it is a user-space program. 

    what is the maximum operating frequency of GPIO8 and GPIO7 bank in AM5748 SoC?

    Thanks,
    Srinidhi H

  • Hello Srinidhi, 

    what is the maximum operating frequency of GPIO8 and GPIO7 bank in AM5748 SoC?

    You can find this information within the TRM, please feel free to consult the following section 28.4.3 General-Purpose Interface Clock Configuration.

    Based on the feedback from my team, the user space sysfs GPIO access will be slow by definition. Every bit-toggle of data or clock (in the code shown) will incur a ton of overhead going through Linux read() and write() system calls. Each bit toggle will have setup code, trap-handling code, dispatch decode code, and finally a toggle. Since this is unbuffered and only 1 bit at a time, getting out of the KHz range is probably not possible in this approach.

    Alternate options: 

    • Still want to utilize user space: One could try to memory-map the GPIO range back to user space and do direct accesses on that range. This will get into the MHz range (assuming one doesn’t have 32KHz debounce clocks activated).  Note:  User space scheduling realities will mean this can have huge jitter.  Maybe it peaks in the many MHz, but if something else runs on the system it can drop to KHz also while time slices go elsewhere.

    • The “proper” and safe way to do this would be to create a kernel driver which could consume a buffer stream so they could pass big buffered sequences to a kernel driver which would decompose and do direct access to the GPIOs. Working this way allows proper sharing of GPIO blocks.  The danger in direct IO from user space is they can upset other GPIO states which exist in the shared bank and cause other unwanted board side effects.   With careful GPIO programming they could reduce the risk by using bit-set/clear register interfaces, but any kind of user space (non-priv) mistake could take down their board in theory.

    • Lastly, another path could be to offload this task to an IPU core. It would be less complex than writing a full fledge Linux driver. You could use IPC to trigger the event. 

    In conclusion, this is all outside of our standard support offering, therefore TI will have very limited support in this endeavor.

    I hope this helps you move forward.

    Best,

    Josue