1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  */
9 #include <rtthread.h>
10 #include "board.h"
11 
12 #define LED_NUM 3
13 
14 struct led_ctrl
15 {
16     uint32_t num;
17     uint32_t port;
18 };
19 
20 struct lpc_led
21 {
22     /* inherit from rt_device */
23     struct rt_device parent;
24     struct led_ctrl ctrl[LED_NUM];
25 };
26 
27 static struct lpc_led led;
28 
rt_led_init(rt_device_t dev)29 static rt_err_t rt_led_init(rt_device_t dev)
30 {
31     /*led2 Blue:P0.31 ,led1 Green:P0.30 ,led0 Red:P0_29  P38,P32*/
32     LPC_SYSCON->AHBCLKCTRLSET[0] = (1UL << 14);       /* enable GPIO0 clock*/
33 
34     LPC_SYSCON->PRESETCTRLSET[0] = (1UL << 14);             /* Resets a GPIO0 peripheral */
35     LPC_SYSCON->PRESETCTRLCLR[0] = (1UL << 14);
36 
37     /* set P0.31, P0.30, P0.29  output. */
38     LPC_GPIO->DIR[0] |= 0x07UL << 29;
39 
40     /* turn off all the led */
41     LPC_GPIO->SET[0] = 0x07UL << 29;
42 
43     led.ctrl[0].num = 29;
44     led.ctrl[0].port = 0;
45     led.ctrl[1].num = 30;
46     led.ctrl[1].port = 0;
47     led.ctrl[2].num = 31;
48     led.ctrl[2].port = 0;
49 
50     return RT_EOK;
51 
52 }
53 
rt_led_open(rt_device_t dev,rt_uint16_t oflag)54 static rt_err_t rt_led_open(rt_device_t dev, rt_uint16_t oflag)
55 {
56     return RT_EOK;
57 }
58 
rt_led_close(rt_device_t dev)59 static rt_err_t rt_led_close(rt_device_t dev)
60 {
61     return RT_EOK;
62 }
63 
rt_led_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)64 static rt_ssize_t rt_led_read(rt_device_t dev, rt_off_t pos, void *buffer,
65                              rt_size_t size)
66 {
67     rt_ubase_t index = 0;
68     rt_ubase_t nr = size;
69     rt_uint8_t *value = buffer;
70 
71     RT_ASSERT(dev == &led.parent);
72     RT_ASSERT((pos + size) <= LED_NUM);
73 
74     for (index = 0; index < nr; index++)
75     {
76         if ((LPC_GPIO->B[0][led.ctrl[pos + index].num]))
77         {
78             *value = 0;
79         }
80         else
81         {
82             *value = 1;
83         }
84         value++;
85     }
86     return index;
87 }
88 
rt_led_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)89 static rt_ssize_t rt_led_write(rt_device_t dev, rt_off_t pos,
90                               const void *buffer, rt_size_t size)
91 {
92     rt_ubase_t index = 0;
93     rt_ubase_t nw = size;
94     const rt_uint8_t *value = buffer;
95 
96     RT_ASSERT(dev == &led.parent);
97     RT_ASSERT((pos + size) <= LED_NUM);
98     for (index = 0; index < nw; index++)
99     {
100         if (*value > 0)
101         {
102              //LPC_GPIO->CLR[led.ctrl[pos + index].port] |= (1 << led.ctrl[pos + index].num);
103              LPC_GPIO->CLR[0] |= (1 << led.ctrl[pos + index].num);
104         }
105         else
106         {
107             //LPC_GPIO->SET[led.ctrl[pos + index].port] |= (1 << led.ctrl[pos + index].num);
108             LPC_GPIO->SET[0] |= (1 << led.ctrl[pos + index].num);
109         }
110     }
111 
112         return index;
113 }
114 
rt_led_control(rt_device_t dev,int cmd,void * args)115 static rt_err_t rt_led_control(rt_device_t dev, int cmd, void *args)
116 {
117     return RT_EOK;
118 }
119 
rt_led_hw_init(void)120 int rt_led_hw_init(void)
121 {
122     led.parent.type         = RT_Device_Class_Char;
123     led.parent.rx_indicate  = RT_NULL;
124     led.parent.tx_complete  = RT_NULL;
125     led.parent.init         = rt_led_init;
126     led.parent.open         = rt_led_open;
127     led.parent.close        = rt_led_close;
128     led.parent.read         = rt_led_read;
129     led.parent.write        = rt_led_write;
130     led.parent.control      = rt_led_control;
131     led.parent.user_data    = RT_NULL;
132 
133     /* register a character device */
134     rt_device_register(&led.parent, "led", RT_DEVICE_FLAG_RDWR);
135     /* init led device */
136     rt_led_init(&led.parent);
137     return 0;
138 }
139 
Led_Control(rt_uint32_t Set_led,rt_uint32_t value)140 void Led_Control(rt_uint32_t Set_led, rt_uint32_t value)
141 {
142     if ( Set_led == 0 )
143     {
144         /* set led status */
145         switch (value)
146         {
147         case 0:
148             /* Light off */
149             LPC_GPIO->B[0][led.ctrl[Set_led].num] = 1UL;
150             break;
151         case 1:
152             /* Lights on */
153             LPC_GPIO->B[0][led.ctrl[Set_led].num] = 0UL;
154             break;
155         default:
156             break;
157         }
158     }
159 
160     if ( Set_led == 1 )
161     {
162         /* set led status */
163         switch (value)
164         {
165         case 0:
166             /* Light off */
167             LPC_GPIO->B[0][led.ctrl[Set_led].num] = 1UL;
168             break;
169         case 1:
170             /* Lights on */
171             LPC_GPIO->B[0][led.ctrl[Set_led].num] = 0UL;
172             break;
173         default:
174             break;
175         }
176     }
177         if ( Set_led == 2 )
178     {
179         /* set led status */
180         switch (value)
181         {
182         case 0:
183             /* Lights off */
184             LPC_GPIO->B[0][led.ctrl[Set_led].num] = 1UL;
185             break;
186         case 1:
187             /* Lights on */
188             LPC_GPIO->B[0][led.ctrl[Set_led].num] = 0UL;
189             break;
190         default:
191             break;
192         }
193     }
194 }
195 INIT_DEVICE_EXPORT(rt_led_hw_init);
196 
197 #ifdef RT_USING_FINSH
198 #include <finsh.h>
led_test(rt_uint32_t led_num,rt_uint32_t value)199 void led_test(rt_uint32_t led_num, rt_uint32_t value)
200 {
201     rt_uint8_t led_value = value;
202     rt_led_write(&led.parent, led_num, &led_value, 1);
203 }
204 FINSH_FUNCTION_EXPORT(led_test, e.g: led_test(0, 100).)
205 #endif
206