Initial version of headless-server
[platform/core/uifw/headless-server.git] / src / output / HL_UI_LED_APA102.c
1 /*
2  * Copyright © 2019 Samsung Electronics co., Ltd. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25
26 #include "HL_UI_LED.h"
27
28 #define SUCCESS_FLAG 760302
29 #define RETRY_TIMES 3
30
31 #define SPI_BUS 0
32 #define SPI_DEV 1
33
34 HL_UI_LED *
35 HL_UI_LED_Init(uint32_t led_num)
36 {
37         HL_UI_LED *handle;
38         int count = 0;
39         int ret;
40
41         handle = (HL_UI_LED*)malloc(sizeof(HL_UI_LED));
42         if(handle == NULL)
43         {
44                 return NULL;
45         }
46         handle->number = led_num;
47         handle->brightness = 0xFF;
48         handle->pixels = (uint8_t *)malloc(handle->number * 4);
49         if(handle->pixels == NULL)
50         {
51                 free(handle);
52                 return NULL;
53         }
54
55         while(count < RETRY_TIMES)
56         {
57                 if(peripheral_spi_open(SPI_BUS, SPI_DEV, &(handle->hnd_spi)) == 0)
58                 {
59                         printf("spi open success!\n");
60                         count = SUCCESS_FLAG;
61                         if((ret = peripheral_spi_set_frequency(handle->hnd_spi, BITRATE)) != 0)
62                         {
63                                 printf("Frequency Failed : 0x%x\n", ret);
64                         }
65                         if((ret = peripheral_spi_set_bits_per_word(handle->hnd_spi, 8)) != 0)
66                         {
67                                 printf("BIT_WORD Failed : 0x%x\n", ret);
68                         }
69                         if((ret = peripheral_spi_set_bit_order(handle->hnd_spi,PERIPHERAL_SPI_BIT_ORDER_MSB)) != 0)
70                         {
71                                 printf("BIT_ORDER Failed : 0x%x\n", ret);
72                         }
73                         if((ret = peripheral_spi_set_mode(handle->hnd_spi,PERIPHERAL_SPI_MODE_1)) != 0)
74                         {
75                                 printf("SPI Mode Failed : 0x%x\n", ret);
76                         }
77                         break;
78                 }
79                 else
80                 {
81                         count++;
82                         continue;
83                 }
84         }
85         if(count == SUCCESS_FLAG)
86         {
87                 HL_UI_LED_Clear_All(handle);
88                 return handle;
89         }
90         else
91         {
92                 free(handle->pixels);
93                 free(handle);
94                 return NULL;
95         }
96 }
97
98 void
99 HL_UI_LED_Change_Brightness(HL_UI_LED *handle, uint8_t brightness)
100 {
101         if (brightness > 31)
102                 handle->brightness = 0xFF;
103         else
104                 handle->brightness = 0xE0 | (0x1F & brightness);
105         HL_UI_LED_Refresh(handle);
106 }
107
108 int
109 HL_UI_LED_Get_Brightness(HL_UI_LED *handle)
110 {
111         return handle->brightness & 0x1F;
112 }
113
114 void
115 HL_UI_LED_Set_Pixel_RGB(HL_UI_LED *handle, uint32_t index, uint8_t red, uint8_t green, uint8_t blue)
116 {
117         if (index < handle->number) {
118                 uint8_t *ptr = &(handle->pixels[index * 4]);
119                 ptr[R_OFF_SET] = red;
120                 ptr[G_OFF_SET] = green;
121                 ptr[B_OFF_SET] = blue;
122         }
123 }
124
125 void
126 HL_UI_LED_Get_Pixel_RGB(HL_UI_LED *handle, uint32_t index, uint8_t *red, uint8_t *green, uint8_t *blue)
127 {
128         if (index < handle->number) {
129                 uint8_t *ptr = &(handle->pixels[index * 4]);
130                 *red = ptr[R_OFF_SET];
131                 *green = ptr[G_OFF_SET];
132                 *blue = ptr[B_OFF_SET];
133         }
134 }
135
136 void
137 HL_UI_LED_Set_Pixel_4byte(HL_UI_LED *handle, uint32_t index, uint32_t colour)
138 {
139         uint8_t  r, g, b;
140         uint8_t *ptr = (uint8_t *)&colour;
141         r = ptr[R_OFF_SET];
142         g = ptr[G_OFF_SET];
143         b = ptr[B_OFF_SET];
144         HL_UI_LED_Set_Pixel_RGB(handle, index, r, g, b);
145 }
146
147 uint32_t
148 HL_UI_LED_Get_Pixel_4byte(HL_UI_LED *handle, uint32_t index)
149 {
150         uint8_t r=0, g=0, b=0;
151         uint32_t colour = 0;
152         uint8_t *ptr = (uint8_t *)&colour;
153         HL_UI_LED_Get_Pixel_RGB(handle, index, &r, &g, &b);
154         ptr[R_OFF_SET] = r;
155         ptr[G_OFF_SET] = g;
156         ptr[B_OFF_SET] = b;
157         return colour;
158 }
159
160 void
161 HL_UI_LED_Clear_All(HL_UI_LED *handle)
162 {
163         uint8_t *ptr;
164         uint32_t i;
165         for(ptr = handle->pixels, i=0; i<handle->number; i++, ptr += 4) {
166                 ptr[1] = 0x00;
167                 ptr[2] = 0x00;
168                 ptr[3] = 0x00;
169         }
170         HL_UI_LED_Refresh(handle);
171 }
172
173 int
174 HL_UI_LED_Refresh(HL_UI_LED *handle)
175 {
176         int ret;
177         uint32_t i;
178         uint32_t buf_len = 4 + 4 * handle->number + (handle->number + 15) / 16 + 1;
179         uint8_t *ptr, *qtr;
180         uint8_t *tx = (uint8_t *)malloc(buf_len);
181
182         if( tx == NULL )
183         {
184                 return -1;
185         }
186         // start frame
187         for (i = 0; i < 4; i++)
188                 *(tx + i) = 0x00;
189
190         // LED data
191         qtr = tx + 4;
192
193         for(ptr = handle->pixels, i=0; i<handle->number; i++, ptr += 4, qtr += 4) {
194                 qtr[0] = handle->brightness;
195                 qtr[1] = ptr[1];
196                 qtr[2] = ptr[2];
197                 qtr[3] = ptr[3];
198         }
199
200         // end frame
201         for (i = handle->number * 4 + 4; i < buf_len; i++)
202         {
203                 *(tx + i) = 0x00;
204         }
205
206         ret = peripheral_spi_write(handle->hnd_spi, tx, buf_len);
207         free(tx);
208         if (ret != 0)
209         {
210                 fprintf(stdout, "[Error] can't send spi message\n");
211                 return -2;
212         }
213
214         return 0;
215 }
216
217 int
218 HL_UI_LED_Show(HL_UI_LED *handle)
219 {
220         return HL_UI_LED_Refresh(handle);
221 }
222
223 void
224 HL_UI_LED_Close(HL_UI_LED *handle)
225 {
226         HL_UI_LED_Clear_All(handle);
227         peripheral_spi_close(handle->hnd_spi);
228
229         if (handle->pixels) {
230                 free(handle->pixels);
231         }
232
233         free(handle);
234 }