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.

Linux/PROCESSOR-SDK-AM335X: GPIO Test

Part Number: PROCESSOR-SDK-AM335X
Other Parts Discussed in Thread: AM3359

Tool/software: Linux

We've a custom board based on AM335x-EVM-Starter Kit.

SDK we're using is ti-processor-sdk-linux-am335x-evm-05.00.00.15.

In the above schematic, the following 3 lines are connected to the FPGA.

1. UART1_CTSn,

2. UART1_RTSn &

3. GPMC_BEn0_CLE


Our requirement is to prove the clock rate as 10 MHz on all the above 3 lines.

1. We want to send some buffer from processor (ex:- an array of 1024 bytes) to FPGA and capture the data. How to do it?

2. If any thing to be set in the kernel, where and all I should modify?

Please find below my dts file & the program that I am using to send data to FPGA, Please suggest me changes required, if any.

DTS:

    gpio1_pins:gpio1_pins{
        pinctrl-single,pins = <
            AM33XX_IOPAD(0x978, PIN_OUTPUT | MUX_MODE7)    /*UART1_CTSn.GPIO0_12*/
            AM33XX_IOPAD(0x97c, PIN_OUTPUT | MUX_MODE7)    /*UART1_RTSn.GPIO0_13*/
            AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE7)    /*GPMC_BEn0_CLE.GPIO2_5*/
        >;
    };

&gpio1 {
    pinctrl-names = "default";
    pinctrl-0 = <&gpio1_pins>;
    status = "okay";
};

Program to send data to FPGA:


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <time.h>

#include <getopt.h>
//#include "gpiolib.h"

int gpio_export(int gpio)
{
    int efd;
    char buf[50];
    int gpiofd, ret;

    /* Quick test if it has already been exported */
    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    efd = open(buf, O_WRONLY);
    if(efd != -1) {
        close(efd);
        return 0;
    }

    efd = open("/sys/class/gpio/export", O_WRONLY);

    if(efd != -1) {
        sprintf(buf, "%d", gpio);
        ret = write(efd, buf, strlen(buf));
        if(ret < 0) {
            perror("Export failed");
            return -2;
        }
        close(efd);
    } else {
        // If we can't open the export file, we probably
        // dont have any gpio permissions
        return -1;
    }
    return 0;
}

void gpio_unexport(int gpio)
{
    int gpiofd, ret;
    char buf[50];
    gpiofd = open("/sys/class/gpio/unexport", O_WRONLY);
    sprintf(buf, "%d", gpio);
    ret = write(gpiofd, buf, strlen(buf));
    close(gpiofd);
}

int gpio_read(int gpio)
{
    char in[3] = {0, 0, 0};
    char buf[50];
    int nread, gpiofd;
    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    gpiofd = open(buf, O_RDWR);
    if(gpiofd < 0) {
        fprintf(stderr, "Failed to open gpio %d value\n", gpio);
        perror("gpio failed");
    }

    do {
        nread = read(gpiofd, in, 1);
    } while (nread == 0);
    if(nread == -1){
        perror("GPIO Read failed");
        return -1;
    }
    
    close(gpiofd);
    return atoi(in);
}

int gpio_write(int gpio, unsigned char val)
{    
    char buf[50];
    int nread, ret, gpiofd;
    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    gpiofd = open(buf, O_RDWR);
    if(gpiofd > 0) {
        snprintf(buf, 2, "%d", val);
        ret = write(gpiofd, buf, 2);
        if(ret < 0) {
            perror("failed to set gpio");
            return 1;
        }

        close(gpiofd);
        if(ret == 2) return 0;
    }
    return 1;
}

int gpio_direction(int gpio, int dir)
{
    int ret = 0;
    char buf[50];
    sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
    int gpiofd = open(buf, O_WRONLY);
    if(gpiofd < 0) {
        perror("Couldn't open IRQ file");
        ret = -1;
    }

    if(dir == 2 && gpiofd){
        if (3 != write(gpiofd, "high", 3)) {
            perror("Couldn't set GPIO direction to out");
            ret = -2;
        }
    }

    if(dir == 1 && gpiofd){
        if (3 != write(gpiofd, "out", 3)) {
            perror("Couldn't set GPIO direction to out");
            ret = -3;
        }
    }
    else if(gpiofd) {
        if(2 != write(gpiofd, "in", 2)) {
            perror("Couldn't set GPIO directio to in");
            ret= -4;
        }
    }

    close(gpiofd);
    return ret;
}

int main(int argc, char **argv)  {
   int gpio_pin1 = 12,gpio_pin2=13,gpio_pin3=69,i;
   struct timespec tim, tim2;
   tim.tv_sec = 0;
   tim.tv_nsec = 50;

    gpio_export(gpio_pin1);    
    gpio_direction(gpio_pin1, 1);

    gpio_export(gpio_pin2);    
    gpio_direction(gpio_pin2, 1);

    gpio_export(gpio_pin3);    
    gpio_direction(gpio_pin3, 1);

    unsigned char value=12;
    while(1)
    {
        gpio_write(gpio_pin1,value);
        gpio_write(gpio_pin2,value);
        gpio_write(gpio_pin3,value);
        usleep(10);
        //nanosleep(&tim, NULL);
        //value = value ? 0:1;
        //printf("val: %d\n",value);
    }
    gpio_unexport(gpio_pin1);
    gpio_unexport(gpio_pin2);
    gpio_unexport(gpio_pin3);
    
    return 0;
}

Thanks & Regards

Vamsi

  • Hi,

    Application programming is beyond the scope of support on this forum. We support only the Processor SDK as provided by TI.
  • Thanks Biser for the information,
    Can you tell me how fast GPIO can toggle?

    Regards
    Vamsi
  • Part Number: PROCESSOR-SDK-AM335X

    Tool/software: Linux

    We have a custom board based on AM3359.

    SDK we are using is ti-processor-sdk-linux-am335x-evm-05.00.00.15.

    We are working on GPIO & I2C interface tests.

    1. In our custom board, 3 GPIO lines - UART1_CTSn, UART1_RTSn & GPMC_BEn0_CLE are connected to FPGA.

    We've to prove that the above 3 lines are working at 10 MHz clock rate by capturing chipscope pro images during communication.

    Right now, I am sending data using the below user level program. But it is observed that the clock rate is very low. (~2KHz)

    Please suggest us something.


    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/select.h>
    #include <sys/stat.h>
    #include <time.h>

    #include <getopt.h>
    //#include "gpiolib.h"

    int gpio_export(int gpio)
    {
    int efd;
    char buf[50];
    int gpiofd, ret;

    /* Quick test if it has already been exported */
    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    efd = open(buf, O_WRONLY);
    if(efd != -1) {
    close(efd);
    return 0;
    }

    efd = open("/sys/class/gpio/export", O_WRONLY);

    if(efd != -1) {
    sprintf(buf, "%d", gpio);
    ret = write(efd, buf, strlen(buf));
    if(ret < 0) {
    perror("Export failed");
    return -2;
    }
    close(efd);
    } else {
    // If we can't open the export file, we probably
    // dont have any gpio permissions
    return -1;
    }
    return 0;
    }

    void gpio_unexport(int gpio)
    {
    int gpiofd, ret;
    char buf[50];
    gpiofd = open("/sys/class/gpio/unexport", O_WRONLY);
    sprintf(buf, "%d", gpio);
    ret = write(gpiofd, buf, strlen(buf));
    close(gpiofd);
    }

    int gpio_read(int gpio)
    {
    char in[3] = {0, 0, 0};
    char buf[50];
    int nread, gpiofd;
    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    gpiofd = open(buf, O_RDWR);
    if(gpiofd < 0) {
    fprintf(stderr, "Failed to open gpio %d value\n", gpio);
    perror("gpio failed");
    }

    do {
    nread = read(gpiofd, in, 1);
    } while (nread == 0);
    if(nread == -1){
    perror("GPIO Read failed");
    return -1;
    }

    close(gpiofd);
    return atoi(in);
    }

    int gpio_write(int gpio, unsigned char val)
    {
    char buf[50];
    int nread, ret, gpiofd;
    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    gpiofd = open(buf, O_RDWR);
    if(gpiofd > 0) {
    snprintf(buf, 2, "%d", val);
    ret = write(gpiofd, buf, 2);
    if(ret < 0) {
    perror("failed to set gpio");
    return 1;
    }

    close(gpiofd);
    if(ret == 2) return 0;
    }
    return 1;
    }

    int gpio_direction(int gpio, int dir)
    {
    int ret = 0;
    char buf[50];
    sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
    int gpiofd = open(buf, O_WRONLY);
    if(gpiofd < 0) {
    perror("Couldn't open IRQ file");
    ret = -1;
    }

    if(dir == 2 && gpiofd){
    if (3 != write(gpiofd, "high", 3)) {
    perror("Couldn't set GPIO direction to out");
    ret = -2;
    }
    }

    if(dir == 1 && gpiofd){
    if (3 != write(gpiofd, "out", 3)) {
    perror("Couldn't set GPIO direction to out");
    ret = -3;
    }
    }
    else if(gpiofd) {
    if(2 != write(gpiofd, "in", 2)) {
    perror("Couldn't set GPIO directio to in");
    ret= -4;
    }
    }

    close(gpiofd);
    return ret;
    }

    int main(int argc, char **argv) {
    int gpio_pin1 = 12,gpio_pin2=13,gpio_pin3=69,i;
    struct timespec tim, tim2;
    tim.tv_sec = 0;
    tim.tv_nsec = 50;

    gpio_export(gpio_pin1);
    gpio_direction(gpio_pin1, 1);

    //gpio_export(gpio_pin2);
    //gpio_direction(gpio_pin2, 1);

    //gpio_export(gpio_pin3);
    //gpio_direction(gpio_pin3, 1);

    unsigned char value=12;
    while(1)
    {
    gpio_write(gpio_pin1,value);
    //gpio_write(gpio_pin2,value);
    //gpio_write(gpio_pin3,value);
    usleep(10);
    //nanosleep(&tim, NULL);
    //value = value ? 0:1;
    //printf("val: %d\n",value);
    }
    gpio_unexport(gpio_pin1);
    //gpio_unexport(gpio_pin2);
    //gpio_unexport(gpio_pin3);

    return 0;
    }

     

    2. For I2C interface test,

    I2C lines - AM335X_I2C0_SCL, AM335X_I2C0_SDA are connected to FPGA, PMIC & ASIC.

    We've to prove that the above 2 lines are working at 400KHz clock rate by capturing chipscope pro images during communication.

    Whenever, we program FPGA for receiving I2C data, it is generating the following error.

    [  730.003617] omap_i2c@44e0b000.i2c: controller timed out
    [  731.023643] omap_i2c@44e0b000.i2c: controller timed out

    Please clear the following doubt.
    In the initial stages of booting, processor is getting some signals from PMIC. And also both SDA & SLC lines are defined as INPUT_PULLUP.
    In this scenario after booting, we cannot output data on that SDA line as it is now INPUT_PULLUP.
    Is there any way to make it as OUTPUT after booting is completed? (Please correct me if I am wrong.)


    Please help us how to proceed further with these two interfaces.


    Regards
    Vamsi
  • Hi,

    Q1: I already explained above that application programming is beyond the scope of support on this forum.
    Q2: INPUT_PULLUP does not mean that you cannot output data on the SDA line. This definition means only that the input receiver is enabled, with internal pullup. The I2C output is always available and cannot be disabled.