From 783987ca5d69c72b6cb1d7f057821637c3366d10 Mon Sep 17 00:00:00 2001 From: lsj119 Date: Tue, 16 Apr 2019 15:48:36 +0900 Subject: [PATCH] output: add HL_UI_LED Change-Id: Idf06aa4dbe39ec69d66535dd568168ed8468d2cb --- configure.ac | 2 +- packaging/pepper.spec | 4 + src/bin/headless/Makefile.am | 3 +- src/bin/headless/headless_server.c | 5 +- src/bin/headless/output/HL_UI_LED.h | 119 +++++++++++++ src/bin/headless/output/HL_UI_LED_APA102.c | 186 +++++++++++++++++++++ src/bin/headless/output/output_led.c | 24 ++- 7 files changed, 336 insertions(+), 7 deletions(-) create mode 100644 src/bin/headless/output/HL_UI_LED.h create mode 100644 src/bin/headless/output/HL_UI_LED_APA102.c diff --git a/configure.ac b/configure.ac index f83c362..20f1b68 100644 --- a/configure.ac +++ b/configure.ac @@ -307,7 +307,7 @@ AC_SUBST(SAMPLES_CFLAGS) AC_SUBST(SAMPLES_LIBS) # headless server -HEADLESS_SERVER_REQUIRES="wayland-server" +HEADLESS_SERVER_REQUIRES="wayland-server capi-system-peripheral-io" PKG_CHECK_MODULES(HEADLESS_SERVER, $[HEADLESS_SERVER_REQUIRES]) HEADLESS_SERVER_CFLAGS="$PEPPER_DIR $HEADLESS_SERVER_CFLAGS" HEADLESS_SERVER_LIBS="$PEPPER_LIB $PEPPER_LIBS $HEADLESS_SERVER_LIBS" diff --git a/packaging/pepper.spec b/packaging/pepper.spec index d6aa548..5973111 100644 --- a/packaging/pepper.spec +++ b/packaging/pepper.spec @@ -9,6 +9,7 @@ Source: %{name}-%{version}.tar.xz source1001: %name.manifest %define ENABLE_TDM 1 +%define HEADLESS_SERVER 1 BuildRequires: autoconf > 2.64 BuildRequires: automake >= 1.11 @@ -33,6 +34,9 @@ BuildRequires: pkgconfig(tizen-extension-client) BuildRequires: pkgconfig(libtdm) %endif BuildRequires: pkgconfig(dlog) +%if "%{HEADLESS_SERVER}" == "1" +BuildRequires: pkgconfig(capi-system-peripheral-io) +%endif %description Pepper is a lightweight and flexible library for developing various types of wayland compositors. diff --git a/src/bin/headless/Makefile.am b/src/bin/headless/Makefile.am index 7e95a66..cb7d14a 100644 --- a/src/bin/headless/Makefile.am +++ b/src/bin/headless/Makefile.am @@ -6,4 +6,5 @@ headless_server_CFLAGS = $(HEADLESS_SERVER_CFLAGS) headless_server_LDADD = $(HEADLESS_SERVER_LIBS) headless_server_SOURCES = headless_server.c \ - output/output_led.c + output/output_led.c \ + output/HL_UI_LED_APA102.c diff --git a/src/bin/headless/headless_server.c b/src/bin/headless/headless_server.c index 59d7b76..10a6d86 100644 --- a/src/bin/headless/headless_server.c +++ b/src/bin/headless/headless_server.c @@ -34,6 +34,7 @@ int main(int argc, char *argv[]) { const char *socket_name = NULL; pepper_compositor_t *compositor = NULL; + pepper_bool_t ret; socket_name = getenv("WAYLAND_DISPLAY"); @@ -45,7 +46,8 @@ int main(int argc, char *argv[]) PEPPER_CHECK(compositor, return EXIT_FAILURE, "Failed to create compositor !"); /* Init Output */ - pepper_output_led_init(compositor); + ret = pepper_output_led_init(compositor); + PEPPER_CHECK(ret, goto end, "pepper_output_led_init() failed.\n"); /* Init Signal for SIGINT */ init_signal(compositor); @@ -53,6 +55,7 @@ int main(int argc, char *argv[]) /* run event loop */ wl_display_run(pepper_compositor_get_display(compositor)); +end: /* Deinit Process */ pepper_output_led_deinit(compositor); pepper_compositor_destroy(compositor); diff --git a/src/bin/headless/output/HL_UI_LED.h b/src/bin/headless/output/HL_UI_LED.h new file mode 100644 index 0000000..9dd0c94 --- /dev/null +++ b/src/bin/headless/output/HL_UI_LED.h @@ -0,0 +1,119 @@ +#ifndef __HL_UI_LED_H__ +#define __HL_UI_LED_H__ +#include +#include +#include +#include +#include + +#define B_OFF_SET 1 +#define G_OFF_SET 2 +#define R_OFF_SET 3 + +#define BITRATE 8000000 + +typedef struct{ + uint32_t number; + peripheral_spi_h hnd_spi; + uint8_t *pixels; + uint8_t brightness; +}HL_UI_LED; + +/** + * @brief: Initialise a set of apa102 LEDs + * + * @param[in] led_num: Number of leds (0-255) + * + * @returns: pointer of handler\ Success + * NULL\ Error + */ +HL_UI_LED *HL_UI_LED_Init(uint32_t led_num); + +/** + * @brief: Change the global brightness and fresh + * + * @param[in] handle: handler of HL_UI_LED + * @param[in] brightness: New brightness value + */ +void HL_UI_LED_Change_Brightness(HL_UI_LED *handle, uint8_t brightness); + +/** + * @brief: Get the brightness + * + * @param[in] handle: handler of HL_UI_LED + * @return current brightness value (0-31) + */ +int HL_UI_LED_Get_Brightness(HL_UI_LED *handle); + +/** + * @brief: Set color for a specific pixel by giving R, G and B value separately + * + * @param[in] handle: handler of HL_UI_LED + * @param[in] index: Index of the target led (0-255) + * @param[in] red: Intensity of red colour (0-255) + * @param[in] green: Intensity of green colour (0-255) + * @param[in] blue: Intensity of blue colour (0-255) + */ +void HL_UI_LED_Set_Pixel_RGB(HL_UI_LED *handle, uint32_t index, uint8_t red, uint8_t green, uint8_t blue); + +/** + * @brief: Get colour form a specific pixel for R, G and B separately + * + * @param[in] handle: handler of HL_UI_LED + * @param[in] index: Index of the target led (0-255) + * @param[out] red: Intensity of red colour (0-255) + * @param[out] green: Intensity of green colour (0-255) + * @param[out] blue: Intensity of blue colour (0-255) + */ +void HL_UI_LED_Get_Pixel_RGB(HL_UI_LED *handle, uint32_t index, uint8_t *red, uint8_t *green, uint8_t *blue); + +/** + * @brief: Set color for a specific pixel by using 4byte date + * + * @param[in] handle: handler of HL_UI_LED + * @param[in] index: Index of the target led (0-255) + * @param[in] red: Intensity of red colour (0-255) + * @param[in] green: Intensity of green colour (0-255) + * @param[in] blue: Intensity of blue colour (0-255) + * + * @example: HL_UI_LED_Get_Pixel_RGB(1, 0xFF0000) sets the 1st LED to red colour + */ +void HL_UI_LED_Set_Pixel_4byte(HL_UI_LED *handle, uint32_t index, uint32_t colour); + +/** + * @brief: Get colour form a specific pixel + * + * @param[in] handle: handler of HL_UI_LED + * @param[in] index: Index of the target led (0-255) + * + * @returns: 32 bits colour data + */ +uint32_t HL_UI_LED_Get_Pixel_4byte(HL_UI_LED *handle, uint32_t index); + +/** + * @brief: Clear all the pixels + * + * @param[in] handle: handler of HL_UI_LED + */ +void HL_UI_LED_Clear_All(HL_UI_LED *handle); + +/** + * @brief: Refresh display (After modifing pixel colour) + */ +int HL_UI_LED_Refresh(HL_UI_LED *handle); + +/** + * @brief: Show display (After modifing pixel colour) + * + * @param[in] handle: handler of HL_UI_LED + */ +int HL_UI_LED_Show(HL_UI_LED *handle); + + +/** + * @brief: Close SPI file, release memory + * + * @param[in] handle: handler of HL_UI_LED + */ +void HL_UI_LED_Close(HL_UI_LED *handle); +#endif diff --git a/src/bin/headless/output/HL_UI_LED_APA102.c b/src/bin/headless/output/HL_UI_LED_APA102.c new file mode 100644 index 0000000..39072b8 --- /dev/null +++ b/src/bin/headless/output/HL_UI_LED_APA102.c @@ -0,0 +1,186 @@ +#include "HL_UI_LED.h" + +#define SUCCESS_FLAG 760302 +#define RETRY_TIMES 3 + +#define SPI_BUS 0 +#define SPI_DEV 1 + +HL_UI_LED *HL_UI_LED_Init(uint32_t led_num){ + HL_UI_LED *handle; + int count = 0; + int ret; + + handle = (HL_UI_LED*)malloc(sizeof(HL_UI_LED)); + if(handle == NULL) + { + return NULL; + } + handle->number = led_num; + handle->brightness = 0xFF; + handle->pixels = (uint8_t *)malloc(handle->number * 4); + if(handle->pixels == NULL) + { + free(handle); + return NULL; + } + + while(count < RETRY_TIMES) + { + if(peripheral_spi_open(SPI_BUS, SPI_DEV, &(handle->hnd_spi)) == 0) + { + printf("spi open success!\n"); + count = SUCCESS_FLAG; + if((ret = peripheral_spi_set_frequency(handle->hnd_spi, BITRATE)) != 0) + { + printf("Frequency Failed : 0x%x\n", ret); + } + if((ret = peripheral_spi_set_bits_per_word(handle->hnd_spi, 8)) != 0) + { + printf("BIT_WORD Failed : 0x%x\n", ret); + } + if((ret = peripheral_spi_set_bit_order(handle->hnd_spi,PERIPHERAL_SPI_BIT_ORDER_MSB)) != 0) + { + printf("BIT_ORDER Failed : 0x%x\n", ret); + } + if((ret = peripheral_spi_set_mode(handle->hnd_spi,PERIPHERAL_SPI_MODE_1)) != 0) + { + printf("SPI Mode Failed : 0x%x\n", ret); + } + break; + } + else + { + count++; + continue; + } + } + if(count == SUCCESS_FLAG) + { + HL_UI_LED_Clear_All(handle); + return handle; + } + else + { + free(handle->pixels); + free(handle); + return NULL; + } +} + +void HL_UI_LED_Change_Brightness(HL_UI_LED *handle, uint8_t brightness){ + if (brightness > 31) + handle->brightness = 0xFF; + else + handle->brightness = 0xE0 | (0x1F & brightness); + HL_UI_LED_Refresh(handle); +} + +int HL_UI_LED_Get_Brightness(HL_UI_LED *handle){ + return handle->brightness & 0x1F; +} + +void HL_UI_LED_Set_Pixel_RGB(HL_UI_LED *handle, uint32_t index, uint8_t red, uint8_t green, uint8_t blue){ + if (index < handle->number) { + uint8_t *ptr = &(handle->pixels[index * 4]); + ptr[R_OFF_SET] = red; + ptr[G_OFF_SET] = green; + ptr[B_OFF_SET] = blue; + } +} + +void HL_UI_LED_Get_Pixel_RGB(HL_UI_LED *handle, uint32_t index, uint8_t *red, uint8_t *green, uint8_t *blue){ + if (index < handle->number) { + uint8_t *ptr = &(handle->pixels[index * 4]); + red = ptr + R_OFF_SET; + green = ptr + G_OFF_SET; + blue = ptr + B_OFF_SET; + } +} + +void HL_UI_LED_Set_Pixel_4byte(HL_UI_LED *handle, uint32_t index, uint32_t colour){ + uint8_t r, g, b; + r = colour >> 16; + g = colour >> 8; + b = colour; + HL_UI_LED_Set_Pixel_RGB(handle, index, r, g, b); +} + +uint32_t HL_UI_LED_Get_Pixel_4byte(HL_UI_LED *handle, uint32_t index){ + uint8_t r=0, g=0, b=0; + uint32_t colour = 0; + HL_UI_LED_Get_Pixel_RGB(handle, index, &r, &g, &b); + r <<= 16; + g <<= 8; + colour = r | g | b; + return colour; +} + +void HL_UI_LED_Clear_All(HL_UI_LED *handle){ + uint8_t *ptr; + uint32_t i; + for(ptr = handle->pixels, i=0; inumber; i++, ptr += 4) { + ptr[1] = 0x00; + ptr[2] = 0x00; + ptr[3] = 0x00; + } + HL_UI_LED_Refresh(handle); +} + +int HL_UI_LED_Refresh(HL_UI_LED *handle){ + int ret; + uint32_t i; + uint32_t buf_len = 4 + 4 * handle->number + (handle->number + 15) / 16 + 1; + uint8_t *ptr, *qtr; + uint8_t *tx = (uint8_t *)malloc(buf_len); + + if( tx == NULL ) + { + return -1; + } + // start frame + for (i = 0; i < 4; i++) + *(tx + i) = 0x00; + + // LED data + qtr = tx + 4; + + for(ptr = handle->pixels, i=0; inumber; i++, ptr += 4, qtr += 4) { + qtr[0] = handle->brightness; + qtr[1] = ptr[1]; + qtr[2] = ptr[2]; + qtr[3] = ptr[3]; + } + + // end frame + for (i = handle->number * 4 + 4; i < buf_len; i++) + { + *(tx + i) = 0x00; + } + + ret = peripheral_spi_write(handle->hnd_spi, tx, buf_len); + free(tx); + if (ret != 0) + { + fprintf(stdout, "[Error] can't send spi message\n"); + return -2; + } + + return 0; +} + +int HL_UI_LED_Show(HL_UI_LED *handle) +{ + return HL_UI_LED_Refresh(handle); +} + +void HL_UI_LED_Close(HL_UI_LED *handle){ + HL_UI_LED_Clear_All(handle); + peripheral_spi_close(handle->hnd_spi); + + if (handle->pixels) { + free(handle->pixels); + } + + free(handle); +} diff --git a/src/bin/headless/output/output_led.c b/src/bin/headless/output/output_led.c index f767b1e..d01d23f 100644 --- a/src/bin/headless/output/output_led.c +++ b/src/bin/headless/output/output_led.c @@ -26,6 +26,9 @@ #include #include +#include "HL_UI_LED.h" + +#define NUM_LED 12 typedef struct { pepper_compositor_t *compositor; @@ -33,6 +36,7 @@ typedef struct { pepper_plane_t *plane; int num_led; + HL_UI_LED *ui_led; }led_output_t; static const int KEY_OUTPUT; @@ -42,6 +46,10 @@ led_output_destroy(void *o) { led_output_t *output = (led_output_t *)o; PEPPER_TRACE("Output Destroy %p base %p\n", output, output->output); + + if (output->ui_led) + HL_UI_LED_Close(output->ui_led); + free(output); } @@ -75,7 +83,7 @@ led_output_get_mode(void *o, int index, pepper_output_mode_t *mode) led_output_t *output = (led_output_t *)o; if (index != 0) - return; + return; mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED; mode->w = output->num_led; @@ -146,10 +154,15 @@ pepper_output_led_init(pepper_compositor_t *compositor) PEPPER_TRACE("Output Init\n"); if (!output) { - PEPPER_ERROR("Failed to allocate memory in %s\n", __FUNCTION__); - goto error; + PEPPER_ERROR("Failed to allocate memory in %s\n", __FUNCTION__); + goto error; } + output->num_led = NUM_LED; + output->ui_led = HL_UI_LED_Init(output->num_led); + if (!output->ui_led) + PEPPER_ERROR("HL_UI_LED_Init() failed.\n"); + output->compositor = compositor; output->output = pepper_compositor_add_output(compositor, &led_output_backend, "led_output", @@ -163,10 +176,13 @@ pepper_output_led_init(pepper_compositor_t *compositor) &KEY_OUTPUT, output, led_output_destroy); PEPPER_TRACE("\t Add Output %p, base %p\n", output, output->output); PEPPER_TRACE("\t Add Output %p, plane %p\n", output, output->plane); - PEPPER_TRACE("\t Userdata %p\n", pepper_object_get_user_data(compositor,&KEY_OUTPUT)); + PEPPER_TRACE("\t Userdata %p\n", pepper_object_get_user_data((pepper_object_t *)compositor,&KEY_OUTPUT)); return PEPPER_TRUE; error: + if (output->ui_led) + HL_UI_LED_Close(output->ui_led); + if (output->output) pepper_output_destroy(output->output); -- 2.34.1