Control a LED with BUTTON on SAMA5D27-SOM1-EK1 board

This forum is for users of Microchip MPUs and who are interested in using Linux OS.

Moderator: nferre

Gaston
Posts: 28
Joined: Fri May 10, 2019 12:21 pm

Control a LED with BUTTON on SAMA5D27-SOM1-EK1 board

Mon Aug 19, 2019 8:57 pm

Hello!

I think that my question is a little bit dumb but i am really stuck in this problem. I have an embedded SAMA5D27-SOM1-EK1 board which i build Linux OS image version 4.14 with YOCTO project. Now i want to control a RBG LED using a pushUSER BUTTON existing both on the board. I must make the LED Lights when I push the Button. For the moment i have only the PINS of the Led and the Button. I don't know what i must do now.

Thank you for your help!
blue_z
Location: USA
Posts: 1954
Joined: Thu Apr 19, 2007 10:15 pm

Re: Control a LED with BUTTON on SAMA5D27-SOM1-EK1 board

Tue Aug 20, 2019 12:05 am

Gaston wrote: Now i want to control a RBG LED using a pushUSER BUTTON existing both on the board. I must make the LED Lights when I push the Button.
FYI a RGB LED is actually three (3) LEDs. Check the board schematics if you are confused.

The existing Device Tree file for the SAMA5D27-SOM1-EK1 board in the Linux kernel configures the RGB LEDs as three "gpio-leds" output devices.
The LEDs can be controlled by userspace programs through the /sys/class/leds/ interface.
Study Documentation/leds/leds-class.txt.

The existing Device Tree file for the SAMA5D27-SOM1-EK1 board in the Linux kernel configures the PB4 user push-button as a "gpio-keys" input device.
However the input is configured as a "wakeup-source".
Study Documentation/devicetree/bindings/input/gpio-keys.txt for information on specifying the button as a simple event.
Study the user API for input devices and events as described in Documentation/input/input.rst. The salient items are the /dev/input/eventN device node(s), the struct input_event data, and the evtest program.

You will have to concoct your own scheme for how a single button will control three LEDs.
Perhaps you need a state machine?

Regards
Gaston
Posts: 28
Joined: Fri May 10, 2019 12:21 pm

Re: Control a LED with BUTTON on SAMA5D27-SOM1-EK1 board

Tue Aug 20, 2019 3:41 pm

Thank you blue_z for your interraction! I know that RGB led is constitued of 3 leds : PA10 for RED, PA31 for BLUE and PB1 for GREEN. And I read what you recommended me to read about gpio, leds and buttons. But your response is vague and i didn't find a solution for my problem. I really don't know what to do!
nferre
Site Admin
Posts: 205
Joined: Wed Feb 14, 2007 11:17 am

Re: Control a LED with BUTTON on SAMA5D27-SOM1-EK1 board

Wed Aug 21, 2019 10:44 am

Hi,

In python, you can use the mpio library to write your code. That'll ease your access to hardware:
https://github.com/linux4sam/mpio/

In C, you can use the part of pct_examples that we have here that deals with keys and leds. You'll have to replace the keycodes and LED definitions of course:
https://github.com/linux4sam/ptc_examples
for example like in C file here:
https://github.com/linux4sam/ptc_exampl ... /ptc_qt1.c
where leds are updated according to input events.

or this type of (far simpler/basic) code (here again, changing input definitions and LED spec.):

Code: Select all

/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support 
 * ----------------------------------------------------------------------------
 * Copyright (c) 2009, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ----------------------------------------------------------------------------
 */

/*
 * A simple application for Key scan and led on/off control using:
 * - input event interface for buttons 
 * - led sysfs class in /sys/class/leds for leds
 */


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

#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>

#include <linux/input.h>

#define BTN_FILE_PATH "/dev/input/event0"
#define LED_PATH "/sys/class/leds"
#define LLED "d6"
#define RLED "d7"

void change_led_state(char *led_path, int led_value)
{
	char 	lpath[64];
	FILE	*led_fd;

	strncpy(lpath, led_path, sizeof(lpath) - 1);
	lpath[sizeof(lpath) - 1] = '\0';

	led_fd = fopen(lpath, "w");

	if (led_fd == NULL) {
		fprintf(stderr, "simplekey: unable to access led\n");
		return;
	}

	fprintf(led_fd, "%d\n", led_value);
	
	fclose(led_fd);
}

void reset_leds(void)
{
	change_led_state(LED_PATH "/" LLED "/brightness", 0);
	change_led_state(LED_PATH "/" RLED "/brightness", 0);
}

int configure_leds(void)
{
	FILE	*l_fd;
	FILE	*r_fd;
	char	*none_str = "none";

	/* Configure leds for hand control */
	l_fd = fopen(LED_PATH "/" LLED "/trigger", "w");
	r_fd = fopen(LED_PATH "/" RLED "/trigger", "w");

	if (l_fd == NULL || r_fd == NULL) {
		perror("simplekey: unable to configure led");
		return -EACCES;
	}

	fprintf(r_fd, "%s\n", none_str);
	fprintf(l_fd, "%s\n", none_str);
	
	fclose(r_fd);
	fclose(l_fd);

	/* Switch off leds */
	reset_leds();

	return 0;
}

void eval_keycode(int code)
{
	static int d6_state = 0;
	static int d7_state = 0;

	switch (code) {
	case BTN_LEFT:
		printf("BTN left pressed\n");

		/* figure out d6 state */
		d6_state = d6_state ? 0 : 1;

		change_led_state(LED_PATH "/" LLED "/brightness", d6_state);
		break;

	case BTN_RIGHT:
		printf("BTN right pressed\n");

		/* figure out d7 state */
		d7_state = d7_state ? 0 : 1;

		change_led_state(LED_PATH "/" RLED "/brightness", d7_state);
		break;
	}
}


int main(void)
{
	int	file;
	/* how many bytes were read */
	size_t	rb;
	int	ret;
	int	yalv;
	/* the events (up to 64 at once) */
	struct input_event	ev[64];
	char	*str = BTN_FILE_PATH;

	printf("Starting simplekey app\n");

	ret = configure_leds();
	if (ret < 0)
		exit(1);

	printf("File Path: %s\n", str);

	if((file = open(str, O_RDONLY)) < 0) {
		perror("simplekey: File can not open");
		exit(1);
	}

	for (;;) {
		/* Blocking read */
		rb= read(file, &ev, sizeof(ev));

		if (rb < (int) sizeof(struct input_event)) {
			perror("simplekey: short read");
			exit(1);
		}

		for (yalv = 0;
			yalv < (int) (rb / sizeof(struct input_event));
			yalv++) {
			if (ev[yalv].type == EV_KEY) {
				printf("%ld.%06ld ",
					ev[yalv].time.tv_sec,
					ev[yalv].time.tv_usec);
				printf("type %d code %d value %d\n",
						ev[yalv].type,
						ev[yalv].code, ev[yalv].value);
				
				/* Change state on button pressed */
				if (ev[yalv].value == 0)
					eval_keycode(ev[yalv].code);
			}
		}
	}

	close(file);
	reset_leds();
	exit(0);
}
Gaston
Posts: 28
Joined: Fri May 10, 2019 12:21 pm

Re: Control a LED with BUTTON on SAMA5D27-SOM1-EK1 board

Wed Aug 21, 2019 3:45 pm

@nferre Thank you for your help :)

Return to “LINUX”

Who is online

Users browsing this forum: Google [Bot] and 3 guests