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.

AM335x Starter Kit User LEDs



Hi all,

I would like to know how to toggle the User LEDs in Sitara AM335x starter kit using the GPIO.

What are the ways in which it can be done, For eg., using the board console or through C programming.

Best Regards,

Harsha J K

  • Harsha J K,

    The simplest C interface would be through Starterware, which is a low level C library for programming the 335x. You can find more information on it here. The demo application for the SK in <install dir>\examples\evmSKAM335x\demo has some LED examples in it.

    From Linux, you can use a few options that are detailed here. Note that you will have to change how the SDK uses the pins to make them available to you to use as you wish.

    I hope this helps.

  • RonB,

        Thank you for your response. I would like to know how to compile the demo files so that I can run it in Linux.

    Thanks

  • By simple Linux command line via sysfs, for gpio bank 1, 18:

    echo 50 > /sys/class/gpio/export

    echo "out" > /sys/class/gpio/gpio50/direction

    echo 1 > /sys/class/gpio/gpio50/value

    echo 0 > /sys/class/gpio/gpio50/value

    Equivalent in a C program:

       system("echo 50 > /sys/class/gpio/export");
       system("echo \"out\" > /sys/class/gpio/gpio50/direction");
       while (1)
       {  
         system("echo 1 > /sys/class/gpio/gpio50/value");
         sleep(1);
         system("echo 0 > /sys/class/gpio/gpio50/value");
         sleep(1);
       }

    Assuming you have your crosscompiler already installed in your linux development PC, crosscompile for the starterkit:

    arm-none-linux-gnueabi-gcc my_gpio.c -o my_gpio

    Copy the binary to the starterkit and execute:

    ./my_gpio

  • Hi,


    I have written using the GPIOs memory mapped to userspace.

    /*
     * This program enables the user to fiddle with GPIO pins.
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #include <errno.h>
    #include <string.h>
    #include <fcntl.h>
    
    // See page 155 of SPRUH73H (AM335X) October 2011
    // Base address of GPIO0
    #define AM335X_GPIO0_BASE		    0x44E07000
    // Base address of GPIO1
    #define AM335X_GPIO1_BASE		    0x4804C000
    // Base address of GPIO2
    #define AM335X_GPIO2_BASE		    0x481AC000
    // Base address of GPIO3
    #define AM335X_GPIO3_BASE		    0x481AE000
    // GPIO register size
    #define AM335X_GPIO_SIZE		    0x1000
    // This register is used to enable the pins output capabilities.
    #define AM335X_GPIO_OE		    	0x134
    //This register is used to register the data that is read from the GPIO pins.
    #define AM335X_GPIO_DATAIN			0x138
    // This register is used for setting the value of the GPIO output pins
    #define AM335X_GPIO_DATAOUT			0x13C
    // This register is used to register the data that is read from the GPIO pins.
    #define AM335X_GPIO_SETDATAOUT		0x190
    // This register is used for setting the value of the GPIO output pins
    #define AM335X_GPIO_CLEARDATAOUT	0x194
    
    #define MAX_NO_OF_GPIO_BANKS        (4)
    #define GPIO_MODULE0                (0)
    #define GPIO_MODULE1                (1)
    #define GPIO_MODULE2                (2)
    #define GPIO_MODULE3                (3)
    
    #define USR0_LED_D1 (4)
    #define USR1_LED_D2 (5)
    #define USR2_LED_D3 (7)
    #define USR3_LED_D4 (6)
    
    
    #define USR0_KEY_SW1 (3)
    #define USR1_KEY_SW2 (2)
    #define USR2_KEY_SW3 (30)
    #define USR3_KEY_SW4 (5)
    
    #define OUT          (0)
    #define IN           (1)
    
    uint32_t gpio_base[] = {
    	AM335X_GPIO0_BASE,
    	AM335X_GPIO1_BASE,
    	AM335X_GPIO2_BASE,
    	AM335X_GPIO3_BASE,
    	0/*NULL*/
    };
    
    void *gpio_addr[MAX_NO_OF_GPIO_BANKS] = { NULL };
    unsigned int *gpio_oe_addr = NULL;
    unsigned int *gpio_dataout_addr = NULL;
    unsigned int *gpio_datain_addr = NULL;
    unsigned int *gpio_setdataout_addr = NULL;
    unsigned int *gpio_cleardataout_addr = NULL;
    
    void *pinmux_addr = NULL;
    unsigned int *used_pinmux_addr = NULL;
    
    int  mem_fd;
    int gpio_module = -1;
    
    void gpio_set(int gpio_module_no, int pin)
    {
    	unsigned int reg;
    	gpio_dataout_addr = gpio_addr[gpio_module_no] + AM335X_GPIO_DATAOUT;
    	reg = *gpio_dataout_addr;
    	reg = reg | (1 << pin);
    	*gpio_dataout_addr = reg;
    	printf("gpio_set: pin value = %d\treg value = 0x%X\n",pin, reg);
    }
    
    void gpio_reset(int gpio_module_no, int pin)
    {
    	unsigned int reg;
    	gpio_dataout_addr = gpio_addr[gpio_module_no] + AM335X_GPIO_DATAOUT;
    	reg = *gpio_dataout_addr;
    	reg = reg & ~(1 << pin);
    	*gpio_dataout_addr = reg;
    	//printf("gpio_reset: pin value = %d\treg value = 0x%X\n",pin, reg);	
    }
    
    int gpio_read(int gpio_module_no, int direction, int pin)
    {
    	int pin_value = 0;
    	unsigned int reg;
    	if (direction == 0) {
    		gpio_dataout_addr = gpio_addr[gpio_module_no] + AM335X_GPIO_DATAOUT;
    		reg = *gpio_dataout_addr;
    		if (reg & (1 << pin)) {
    			pin_value = 1;
    		}
    	}
    	else if (direction == 1) {
    		gpio_datain_addr = gpio_addr[gpio_module_no] + AM335X_GPIO_DATAIN;
    		reg = *gpio_datain_addr;
    		if (reg & (1 << pin)) {
    			pin_value = 1;
    		}
    	}
    	else{
    		pin_value = -1;
    	}
    	if (pin_value == 1)
    		printf("gpio_read: pin value = %d\n",pin_value);
    	return pin_value;
    }
    
    void gpio_set_direction(int gpio_module_no, int direction, int pin)
    {
    	unsigned int reg;
    	gpio_oe_addr = gpio_addr[gpio_module_no] + AM335X_GPIO_OE;
    	reg = *gpio_oe_addr;
    	printf("gpio_set_direction: reg initial = 0x%X\n",reg);
    	if (direction == 0) {
    		reg = reg & ~(1 << pin);
    		*gpio_oe_addr = reg;
    	} else {
    		reg = reg | (1 << pin);
    		*gpio_oe_addr = reg;
    	}
    	printf("gpio_set_direction: reg after setting dir = 0x%X\n",reg);
    }
    
    /*
     * Set up a memory regions to access GPIO
     */
    void setup_io()
    {
    	int i = 0;
    	/* open /dev/mem */
    	if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
    		printf("main: can't open /dev/mem \n");
    		exit(-1);
    	}
    	printf("main: mem_fd = %d\n",mem_fd);
    	/* mmap GPIO Bank1 */
    	gpio_addr[GPIO_MODULE0]
    		= mmap(
    				NULL,                   //Any adddress in our space will do
    				AM335X_GPIO_SIZE,       //Map length
    				PROT_READ|PROT_WRITE,   // Enable reading & writting to mapped memory
    				MAP_SHARED,             //Shared with other processes
    				mem_fd,                 //File to map
    				gpio_base[GPIO_MODULE0] //Offset to GPIO peripheral
    		      );
    	/* mmap GPIO Bank2*/
    	gpio_addr[GPIO_MODULE1]
    		= mmap(
    				NULL,                   //Any adddress in our space will do
    				AM335X_GPIO_SIZE,       //Map length
    				PROT_READ|PROT_WRITE,   // Enable reading & writting to mapped memory
    				MAP_SHARED,             //Shared with other processes
    				mem_fd,                 //File to map
    				gpio_base[GPIO_MODULE1] //Offset to GPIO peripheral
    		      );
    	/* mmap GPIO Bank3*/
    	gpio_addr[GPIO_MODULE2]
    		= mmap(
    				NULL,                   //Any adddress in our space will do
    				AM335X_GPIO_SIZE,       //Map length
    				PROT_READ|PROT_WRITE,   // Enable reading & writting to mapped memory
    				MAP_SHARED,             //Shared with other processes
    				mem_fd,                 //File to map
    				gpio_base[GPIO_MODULE2] //Offset to GPIO peripheral
    		      );
    	/* mmap GPIO Bank4*/
    	gpio_addr[GPIO_MODULE3]
    		= mmap(
    				NULL,                   //Any adddress in our space will do
    				AM335X_GPIO_SIZE,       //Map length
    				PROT_READ|PROT_WRITE,   // Enable reading & writting to mapped memory
    				MAP_SHARED,             //Shared with other processes
    				mem_fd,                 //File to map
    				gpio_base[GPIO_MODULE3] //Offset to GPIO peripheral
    		      );				
    	//printf("main: gpio_base[%d] = 0x%X\n", gpio_module, gpio_base[gpio_module]); 
    	close(mem_fd); //No need to keep mem_fd open after mmap
    	for ( i = 0; i < MAX_NO_OF_GPIO_BANKS; i++ ) {
    		if (gpio_addr[i] == MAP_FAILED) {
    			printf("mmap error %d\n", (int)gpio_addr[i]);//errno also set!
    			exit(-1);
    		}
    	}    
    } // setup_io
    
    int set_trigger (void) {
    	FILE *fp = NULL;
    	/* create a variable to store what we are sending */
    	char set_value[20]; 
    
    	/* Using sysfs we need to write "none" to /sys/class/leds/am335x:EVM_SK:heartbeat
    	   /trigger */  
    	if ((fp = fopen("/sys/class/leds/am335x:EVM_SK:heartbeat/trigger",
    					"ab")) == NULL) {
    		printf("Cannot open trigger file.\n");
    		exit(1);
    	}
    	/* Set pointer to begining of the file */
    	rewind(fp);
    	/* Write our value of "heartbeat" to the file */
    	strcpy(set_value,"none");
    	fwrite(&set_value, sizeof(char), 4, fp);
    	fclose(fp);
    
    	/* Using sysfs we need to write "none" to /sys/class/leds/am335x:EVM_SK:mmc0
    	   /trigger */  
    	if ((fp = fopen("/sys/class/leds/am335x:EVM_SK:mmc0/trigger",
    					"ab")) == NULL) {
    		printf("Cannot open trigger file.\n");
    		exit(1);
    	}
    	/* Set pointer to begining of the file */
    	rewind(fp);
    	/* Write our value of "heartbeat" to the file */
    	strcpy(set_value,"none");
    	fwrite(&set_value, sizeof(char), 4, fp);
    	fclose(fp);
    
    	return 0;
    }
    
    int main (int argc, char *argv[])
    {
    	int i = 0;
    	set_trigger();  
    	setup_io();
    
    	/* Unbind LEDs D3 & D4 */
    
    	/* Set LEDs as output */
    	gpio_set_direction(GPIO_MODULE1, USR0_LED_D1, OUT);
    	gpio_set_direction(GPIO_MODULE1, USR1_LED_D2, OUT);
    	gpio_set_direction(GPIO_MODULE1, USR2_LED_D3, OUT);
    	gpio_set_direction(GPIO_MODULE1, USR3_LED_D4, OUT);
    
    	printf("main: LEDs set as outputs successfully\n");
    
    	/* Set Keys as inputs */
    	gpio_set_direction(GPIO_MODULE2, USR0_KEY_SW1, IN);
    	gpio_set_direction(GPIO_MODULE2, USR1_KEY_SW2, IN);	
    	gpio_set_direction(GPIO_MODULE0, USR2_KEY_SW3, IN);	
    	gpio_set_direction(GPIO_MODULE2, USR3_KEY_SW4, IN);				
    
    	printf("main: Keys set as inputs successfully\n");
    	while (1) {
    		if (1 == gpio_read(GPIO_MODULE2, IN, USR0_KEY_SW1) ) 
    			gpio_set(GPIO_MODULE1, USR0_LED_D1);
    		else gpio_reset(GPIO_MODULE1, USR0_LED_D1);
    
    		if (1 == gpio_read(GPIO_MODULE2, IN, USR1_KEY_SW2) )
    			gpio_set(GPIO_MODULE1, USR1_LED_D2);
    		else gpio_reset(GPIO_MODULE1, USR1_LED_D2);
    
    		if (1 == gpio_read(GPIO_MODULE0, IN, USR2_KEY_SW3) )
    		{	        gpio_set(GPIO_MODULE1, USR2_LED_D3);printf("Hello Boss!!\n");}
    		else gpio_reset(GPIO_MODULE1, USR2_LED_D3);
    
    		if (1 == gpio_read(GPIO_MODULE2, IN, USR3_KEY_SW4) )
    			gpio_set(GPIO_MODULE1, USR3_LED_D4);
    		else gpio_reset(GPIO_MODULE1, USR3_LED_D4);
    	}
    	for ( i = 0; i < MAX_NO_OF_GPIO_BANKS; i++ ) {
    		munmap((void *)gpio_addr[i], AM335X_GPIO_SIZE);
    	}
    	return 0;
    }
    

    Just cross-compile it and execute it.

    I have written code for switching LED D1 on the press on KEY SW1, and so on.

  • Hi,

    I try to use your file but when I compile I have:

    Description    Resource    Path    Location    Type
    #1965 cannot open source file "unistd.h"    main.c    /ESSAI1    line 8    C/C++ Problem

    Best regards

  • Hi,

    I downloaded, compiled and tried your code with success, that you for your work.
    I read and try to understand your code, and I have only one point that I didn't understand.
    How did you find the pins numbers which correspond to the leds and switches on the AM335X sitara starter kit ?
    How/Where you find that D1=4, D2=5, D3=7, D4=6 _ SW1=3, SW2=2, SW3=30, SW4=5 ?
    I search on the technical reference manual, but I don't found...

    -stan-
  • Hello Stan,

    These are the numbers of gpios, where the diodes and the switches are wired.

    Here you can find the starter kit design files:
    processors.wiki.ti.com/.../AM335x_StarterKit_Board_Design_Files

    Here you can see these bindings in the device tree.
    <kernel>/arch/arm/boot/dts/am335x-evmsk.dts

    	leds {
    		pinctrl-names = "default";
    		pinctrl-0 = <&user_leds_s0>;
    
    		compatible = "gpio-leds";
    
    		led@1 {
    			label = "evmsk:green:usr0";
    			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
    			default-state = "off";
    		};
    
    		led@2 {
    			label = "evmsk:green:usr1";
    			gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
    			default-state = "off";
    		};
    
    		led@3 {
    			label = "evmsk:green:mmc0";
    			gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
    			linux,default-trigger = "mmc0";
    			default-state = "off";
    		};
    
    		led@4 {
    			label = "evmsk:green:heartbeat";
    			gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
    			linux,default-trigger = "heartbeat";
    			default-state = "off";
    		};
    	};
    
    	gpio_buttons: gpio_buttons@0 {
    		compatible = "gpio-keys";
    		#address-cells = <1>;
    		#size-cells = <0>;
    
    		switch@1 {
    			label = "button0";
    			linux,code = <0x100>;
    			gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
    		};
    
    		switch@2 {
    			label = "button1";
    			linux,code = <0x101>;
    			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
    		};
    
    		switch@3 {
    			label = "button2";
    			linux,code = <0x102>;
    			gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
    			gpio-key,wakeup;
    		};
    
    		switch@4 {
    			label = "button3";
    			linux,code = <0x103>;
    			gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
    		};
    	};

    Best regards,
    Kemal

  • Thank you Kemal.

    Best Regards,
    Stan