Merge pull request #5968 from pattheaux/leds

Leds
This commit is contained in:
Twinaphex 2017-12-27 18:01:33 +01:00 committed by GitHub
commit 61b7b2e590
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 300 additions and 7 deletions

View File

@ -201,6 +201,8 @@ OBJ += frontend/frontend.o \
audio/audio_driver.o \ audio/audio_driver.o \
$(LIBRETRO_COMM_DIR)/audio/audio_mixer.o \ $(LIBRETRO_COMM_DIR)/audio/audio_mixer.o \
input/input_driver.o \ input/input_driver.o \
led/led_driver.o \
led/null_led_driver.o \
gfx/video_coord_array.o \ gfx/video_coord_array.o \
gfx/video_display_server.o \ gfx/video_display_server.o \
gfx/video_driver.o \ gfx/video_driver.o \
@ -1648,3 +1650,7 @@ OBJ += libretro-common/audio/dsp_filters/echo.o \
libretro-common/audio/dsp_filters/reverb.o \ libretro-common/audio/dsp_filters/reverb.o \
libretro-common/audio/dsp_filters/wahwah.o libretro-common/audio/dsp_filters/wahwah.o
endif endif
ifeq ($(HAVE_RPILED), 1)
OBJ += led/rpi_led_driver.o
endif

View File

@ -41,6 +41,7 @@
#include "config.features.h" #include "config.features.h"
#include "input/input_keymaps.h" #include "input/input_keymaps.h"
#include "input/input_remapping.h" #include "input/input_remapping.h"
#include "led/led_defines.h"
#include "defaults.h" #include "defaults.h"
#include "core.h" #include "core.h"
#include "dirs.h" #include "dirs.h"
@ -885,6 +886,18 @@ const char *config_get_default_wifi(void)
return "null"; return "null";
} }
/**
* config_get_default_led:
*
* Gets default led driver.
*
* Returns: Default led driver.
**/
const char *config_get_default_led(void)
{
return "null";
}
/** /**
* config_get_default_location: * config_get_default_location:
* *
@ -982,7 +995,7 @@ static struct config_array_setting *populate_settings_array(settings_t *settings
SETTING_ARRAY("bundle_assets_src_path", settings->arrays.bundle_assets_src, false, NULL, true); SETTING_ARRAY("bundle_assets_src_path", settings->arrays.bundle_assets_src, false, NULL, true);
SETTING_ARRAY("bundle_assets_dst_path", settings->arrays.bundle_assets_dst, false, NULL, true); SETTING_ARRAY("bundle_assets_dst_path", settings->arrays.bundle_assets_dst, false, NULL, true);
SETTING_ARRAY("bundle_assets_dst_path_subdir", settings->arrays.bundle_assets_dst_subdir, false, NULL, true); SETTING_ARRAY("bundle_assets_dst_path_subdir", settings->arrays.bundle_assets_dst_subdir, false, NULL, true);
SETTING_ARRAY("led_driver", settings->arrays.led_driver, false, NULL, true);
*size = count; *size = count;
return tmp; return tmp;
@ -1479,6 +1492,7 @@ static void config_set_defaults(void)
#endif #endif
const char *def_camera = config_get_default_camera(); const char *def_camera = config_get_default_camera();
const char *def_wifi = config_get_default_wifi(); const char *def_wifi = config_get_default_wifi();
const char *def_led = config_get_default_led();
const char *def_location = config_get_default_location(); const char *def_location = config_get_default_location();
const char *def_record = config_get_default_record(); const char *def_record = config_get_default_record();
struct config_float_setting *float_settings = populate_settings_float (settings, &float_settings_size); struct config_float_setting *float_settings = populate_settings_float (settings, &float_settings_size);
@ -1536,6 +1550,9 @@ static void config_set_defaults(void)
if (def_wifi) if (def_wifi)
strlcpy(settings->arrays.wifi_driver, strlcpy(settings->arrays.wifi_driver,
def_wifi, sizeof(settings->arrays.wifi_driver)); def_wifi, sizeof(settings->arrays.wifi_driver));
if (def_led)
strlcpy(settings->arrays.led_driver,
def_led, sizeof(settings->arrays.led_driver));
if (def_location) if (def_location)
strlcpy(settings->arrays.location_driver, strlcpy(settings->arrays.location_driver,
def_location, sizeof(settings->arrays.location_driver)); def_location, sizeof(settings->arrays.location_driver));
@ -2455,6 +2472,18 @@ static bool config_load_file(const char *path, bool set_defaults,
CONFIG_GET_INT_BASE(conf, settings, uints.input_libretro_device[i], buf); CONFIG_GET_INT_BASE(conf, settings, uints.input_libretro_device[i], buf);
} }
} }
/* LED map for use by the led driver */
for (i = 0; i < MAX_LEDS; i++)
{
char buf[64];
buf[0] = '\0';
snprintf(buf, sizeof(buf), "led%u_map", i + 1);
CONFIG_GET_INT_BASE(conf, settings, uints.led_map[i], buf);
}
{ {
/* ugly hack around C89 not allowing mixing declarations and code */ /* ugly hack around C89 not allowing mixing declarations and code */
int buffer_size = 0; int buffer_size = 0;

View File

@ -27,6 +27,7 @@
#include "gfx/video_driver.h" #include "gfx/video_driver.h"
#include "input/input_defines.h" #include "input/input_defines.h"
#include "led/led_defines.h"
#define configuration_set_float(settings, var, newvar) \ #define configuration_set_float(settings, var, newvar) \
{ \ { \
@ -368,6 +369,8 @@ typedef struct settings
unsigned input_keymapper_ids[RARCH_CUSTOM_BIND_LIST_END]; unsigned input_keymapper_ids[RARCH_CUSTOM_BIND_LIST_END];
unsigned input_remap_ids[MAX_USERS][RARCH_CUSTOM_BIND_LIST_END]; unsigned input_remap_ids[MAX_USERS][RARCH_CUSTOM_BIND_LIST_END];
unsigned led_map[MAX_LEDS];
} uints; } uints;
struct struct
@ -378,6 +381,7 @@ typedef struct settings
char record_driver[32]; char record_driver[32];
char camera_driver[32]; char camera_driver[32];
char wifi_driver[32]; char wifi_driver[32];
char led_driver[32];
char location_driver[32]; char location_driver[32];
char menu_driver[32]; char menu_driver[32];
char cheevos_username[32]; char cheevos_username[32];

View File

@ -37,6 +37,7 @@
#include "record/record_driver.h" #include "record/record_driver.h"
#include "location/location_driver.h" #include "location/location_driver.h"
#include "wifi/wifi_driver.h" #include "wifi/wifi_driver.h"
#include "led/led_driver.h"
#include "configuration.h" #include "configuration.h"
#include "core.h" #include "core.h"
#include "core_info.h" #include "core_info.h"
@ -316,6 +317,7 @@ static bool driver_update_system_av_info(const struct retro_system_av_info *info
void drivers_init(int flags) void drivers_init(int flags)
{ {
bool video_is_threaded = false; bool video_is_threaded = false;
if (flags & DRIVER_VIDEO_MASK) if (flags & DRIVER_VIDEO_MASK)
video_driver_unset_own_driver(); video_driver_unset_own_driver();
if (flags & DRIVER_AUDIO_MASK) if (flags & DRIVER_AUDIO_MASK)
@ -383,6 +385,11 @@ void drivers_init(int flags)
if (input_driver_is_nonblock_state()) if (input_driver_is_nonblock_state())
driver_set_nonblock_state(); driver_set_nonblock_state();
} }
if (flags & DRIVER_LED_MASK)
{
led_driver_init();
}
} }
@ -429,6 +436,9 @@ void driver_uninit(int flags)
if ((flags & DRIVER_WIFI_MASK) && !wifi_driver_ctl(RARCH_WIFI_CTL_OWNS_DRIVER, NULL)) if ((flags & DRIVER_WIFI_MASK) && !wifi_driver_ctl(RARCH_WIFI_CTL_OWNS_DRIVER, NULL))
wifi_driver_ctl(RARCH_WIFI_CTL_DEINIT, NULL); wifi_driver_ctl(RARCH_WIFI_CTL_DEINIT, NULL);
if (flags & DRIVER_LED)
led_driver_free();
if (flags & DRIVERS_VIDEO_INPUT) if (flags & DRIVERS_VIDEO_INPUT)
video_driver_free(); video_driver_free();

View File

@ -34,7 +34,8 @@ RETRO_BEGIN_DECLS
| DRIVER_LOCATION_MASK \ | DRIVER_LOCATION_MASK \
| DRIVER_MENU_MASK \ | DRIVER_MENU_MASK \
| DRIVERS_VIDEO_INPUT_MASK \ | DRIVERS_VIDEO_INPUT_MASK \
| DRIVER_WIFI_MASK ) | DRIVER_WIFI_MASK \
| DRIVER_LED_MASK )
#define DRIVERS_CMD_ALL_BUT_MENU \ #define DRIVERS_CMD_ALL_BUT_MENU \
( DRIVER_AUDIO_MASK \ ( DRIVER_AUDIO_MASK \
@ -43,7 +44,8 @@ RETRO_BEGIN_DECLS
| DRIVER_CAMERA_MASK \ | DRIVER_CAMERA_MASK \
| DRIVER_LOCATION_MASK \ | DRIVER_LOCATION_MASK \
| DRIVERS_VIDEO_INPUT_MASK \ | DRIVERS_VIDEO_INPUT_MASK \
| DRIVER_WIFI_MASK ) | DRIVER_WIFI_MASK \
| DRIVER_LED_MASK )
enum enum
{ {
@ -54,7 +56,8 @@ enum
DRIVER_LOCATION, DRIVER_LOCATION,
DRIVER_MENU, DRIVER_MENU,
DRIVERS_VIDEO_INPUT, DRIVERS_VIDEO_INPUT,
DRIVER_WIFI DRIVER_WIFI,
DRIVER_LED
}; };
enum enum
@ -66,7 +69,8 @@ enum
DRIVER_LOCATION_MASK = 1 << DRIVER_LOCATION, DRIVER_LOCATION_MASK = 1 << DRIVER_LOCATION,
DRIVER_MENU_MASK = 1 << DRIVER_MENU, DRIVER_MENU_MASK = 1 << DRIVER_MENU,
DRIVERS_VIDEO_INPUT_MASK = 1 << DRIVERS_VIDEO_INPUT, DRIVERS_VIDEO_INPUT_MASK = 1 << DRIVERS_VIDEO_INPUT,
DRIVER_WIFI_MASK = 1 << DRIVER_WIFI DRIVER_WIFI_MASK = 1 << DRIVER_WIFI,
DRIVER_LED_MASK = 1 << DRIVER_LED
}; };
enum driver_ctl_state enum driver_ctl_state

View File

@ -54,6 +54,7 @@
#include "driver.h" #include "driver.h"
#include "performance_counters.h" #include "performance_counters.h"
#include "gfx/video_driver.h" #include "gfx/video_driver.h"
#include "led/led_driver.h"
#include "cores/internal_cores.h" #include "cores/internal_cores.h"
#include "frontend/frontend_driver.h" #include "frontend/frontend_driver.h"
@ -1680,6 +1681,13 @@ bool rarch_environment_cb(unsigned cmd, void *data)
break; break;
} }
case RETRO_ENVIRONMENT_GET_LED_INTERFACE:
{
struct retro_led_interface *ledintf =
(struct retro_led_interface *)data;
ledintf->set_led_state = led_driver_set_led;
}
default: default:
RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd); RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
return false; return false;

6
led/led_defines.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __OUTPUT_DEFINES__H
#define __OUTPUT_DEFINES__H
#define MAX_LEDS 32
#endif

56
led/led_driver.c Normal file
View File

@ -0,0 +1,56 @@
#include <stdio.h>
#include "led_driver.h"
#include "configuration.h"
#include "verbosity.h"
extern led_driver_t *null_led_driver;
#if HAVE_RPILED
extern led_driver_t *rpi_led_driver;
#endif
led_driver_t *current_led_driver = NULL;
bool led_driver_init(void)
{
char *drivername = NULL;
settings_t *settings = config_get_ptr();
drivername = settings->arrays.led_driver;
if(drivername == NULL)
drivername = "null";
#if HAVE_RPILED
if(!strcmp("rpi",drivername))
{
current_led_driver = rpi_led_driver;
}
else
#endif
{
current_led_driver = null_led_driver;
}
RARCH_LOG("[LED]: LED driver = '%s' %p\n",drivername,current_led_driver);
if(current_led_driver != NULL)
{
(*current_led_driver->init)();
}
return true;
}
void led_driver_free(void)
{
if(current_led_driver != NULL)
{
(*current_led_driver->free)();
}
}
void led_driver_set_led(int led,int value)
{
if(current_led_driver != NULL)
{
(*current_led_driver->set_led)(led,value);
}
}

35
led/led_driver.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef __LED_DRIVER__H
#define __LED_DRIVER__H
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <boolean.h>
#include <retro_common_api.h>
#include <retro_inline.h>
#include <libretro.h>
#include "../msg_hash.h"
RETRO_BEGIN_DECLS
typedef struct led_driver
{
void (*init)(void);
void (*free)(void);
void (*set_led)(int led,int value);
} led_driver_t;
bool led_driver_init(void);
void led_driver_free(void);
void led_driver_set_led(int led,int value);
#endif

12
led/null_led_driver.c Normal file
View File

@ -0,0 +1,12 @@
#include "led_driver.h"
#include "verbosity.h"
static void null_init(void)
{
RARCH_LOG("[LED]: using null LED driver\n");
}
static void null_free(void) {}
static void null_set(int led,int state) {}
static led_driver_t null_led_driver_ins = { null_init, null_free, null_set };
led_driver_t *null_led_driver = &null_led_driver_ins;

107
led/rpi_led_driver.c Normal file
View File

@ -0,0 +1,107 @@
#include <stdio.h>
#include "led_driver.h"
#include "led_defines.h"
#include "configuration.h"
#include "verbosity.h"
typedef struct
{
int setup[MAX_LEDS];
int map[MAX_LEDS];
} rpiled_t;
static rpiled_t curins;
static rpiled_t *cur = &curins;
static void rpi_init(void)
{
int i;
settings_t *settings = config_get_ptr();
RARCH_LOG("[LED]: rpi LED driver init\n");
for(i=0;i<MAX_LEDS;i++) {
cur->setup[i] = 0;
cur->map[i] = settings->uints.led_map[i];
RARCH_LOG("[LED]: rpi map[%d]=%d\n",i,cur->map[i]);
}
}
static void rpi_free(void)
{
RARCH_LOG("[LED]: rpi LED driver free\n");
}
static int set_gpio(int gpio,int value)
{
FILE *fp;
char buf[256];
sprintf(buf,"/sys/class/gpio/%d/value",gpio);
fp = fopen(buf,"w");
if(fp == NULL)
{
RARCH_WARN("[LED]: failed to set GPIO %d\n",gpio);
return -1;
}
fprintf(fp,"%d\n",value?1:0);
fclose(fp);
return 1;
}
static int setup_gpio(int gpio) {
FILE *fp;
char buf[256];
sprintf(buf,"/sys/class/gpio/%d/direction",gpio);
fp = fopen(buf,"w");
if(fp == NULL) {
sprintf(buf,"/sys/class/gpio/export");
fp = fopen(buf,"w");
if(fp == NULL)
{
RARCH_WARN("[LED]: failed to export GPIO %d\n",gpio);
return -1;
}
fprintf(fp,"%d\n",gpio);
fclose(fp);
sprintf(buf,"/sys/class/gpio/%d/direction",gpio);
fp = fopen(buf,"w");
}
if(fp == NULL)
{
RARCH_WARN("[LED]: failed to set direction GPIO %d\n",gpio);
return -1;
}
fprintf(fp,"out\n");
fclose(fp);
return 1;
}
static void rpi_set(int led,int state)
{
int gpio = 0;
if((led < 0) || (led >= MAX_LEDS))
{
RARCH_WARN("[LED]: invalid led %d\n",led);
return;
}
gpio = cur->map[led];
if(gpio <= 0) return;
if(cur->setup[led]==0)
{
RARCH_LOG("[LED]: rpi setup led %d gpio %d\n",led,gpio,state);
cur->setup[led] = setup_gpio(gpio);
if(cur->setup[led] <= 0)
{
RARCH_WARN("[LED]: failed to setup led %d gpio %d\n",led,gpio);
}
}
if(cur->setup[led] > 0)
{
RARCH_LOG("[LED]: rpi LED driver set led %d gpio %d = %d\n",led,gpio,state);
set_gpio(gpio,state);
}
}
static led_driver_t rpi_led_driver_ins = { rpi_init, rpi_free, rpi_set };
led_driver_t *rpi_led_driver = &rpi_led_driver_ins;

View File

@ -1094,6 +1094,21 @@ struct retro_hw_render_interface
enum retro_hw_render_interface_type interface_type; enum retro_hw_render_interface_type interface_type;
unsigned interface_version; unsigned interface_version;
}; };
#define RETRO_ENVIRONMENT_GET_LED_INTERFACE (46 | RETRO_ENVIRONMENT_EXPERIMENTAL)
/* struct retro_led_interface * --
* Gets an interface which is used by a libretro core to set
* state of LEDs.
*/
typedef void (RETRO_CALLCONV *retro_set_led_state_t)(int led, int state);
struct retro_led_interface
{
retro_set_led_state_t set_led_state;
};
#define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL) #define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL)
/* const struct retro_hw_render_interface ** -- /* const struct retro_hw_render_interface ** --
* Returns an API specific rendering interface for accessing API specific data. * Returns an API specific rendering interface for accessing API specific data.

View File

@ -232,6 +232,7 @@ check_lib '' OSS_LIB -lossaudio
if [ "$OS" = 'Linux' ]; then if [ "$OS" = 'Linux' ]; then
HAVE_TINYALSA=yes HAVE_TINYALSA=yes
HAVE_RPILED=yes
fi fi
if [ "$OS" = 'Darwin' ]; then if [ "$OS" = 'Darwin' ]; then