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_DEVICE_CTRL 0x81 /*LED control command*/
13
14 #define LED_NUM 4
15 struct led_ctrl
16 {
17 uint32_t num;
18 LPC_GPIO_TypeDef *port;
19 };
20
21 struct lpc_led
22 {
23 /* inherit from rt_device */
24 struct rt_device parent;
25
26 struct led_ctrl ctrl[LED_NUM];
27 };
28
29 static struct lpc_led led;
30
rt_led_init(rt_device_t dev)31 static rt_err_t rt_led_init(rt_device_t dev)
32 {
33 /* led0 : P4.27,led1:P4.15 ,led2:P4.16 ,led3:P4.17*/
34 /* set P4.14,P4.15,P4.16,P4.17 as GPIO. */
35 LPC_IOCON->P4_27 = 0x00;
36 LPC_IOCON->P4_15 = 0x00;
37 LPC_IOCON->P4_16 = 0x00;
38 LPC_IOCON->P4_17 = 0x00;
39 /* set P4.27,P4.15,P4.16,P4.17 output. */
40 LPC_GPIO4->DIR |= (0x07 << 15) | (0x01 << 27);
41 /* turn off all the led */
42 LPC_GPIO4->SET = (0x07 << 15) | (0x01 << 27);
43 led.ctrl[3].num = 27;
44 led.ctrl[3].port = LPC_GPIO4;
45 led.ctrl[2].num = 15;
46 led.ctrl[2].port = LPC_GPIO4;
47 led.ctrl[1].num = 16;
48 led.ctrl[1].port = LPC_GPIO4;
49 led.ctrl[0].num = 17;
50 led.ctrl[0].port = LPC_GPIO4;
51 return RT_EOK;
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 ((led.ctrl[pos + index].port->PIN) & 1 << 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
99 for (index = 0; index < nw; index++)
100 {
101 if (*value++)
102 {
103 led.ctrl[pos + index].port->CLR |= (1 << led.ctrl[pos + index].num);
104 }
105 else
106 {
107 led.ctrl[pos + index].port->SET |= (1 << led.ctrl[pos + index].num);
108 }
109 }
110 return index;
111 }
112
rt_led_control(rt_device_t dev,int cmd,void * args)113 static rt_err_t rt_led_control(rt_device_t dev, int cmd, void *args)
114 {
115 RT_ASSERT(dev == &led.parent);
116
117 if (cmd == LED_DEVICE_CTRL)
118 {
119 rt_uint32_t *led_num = args;
120 *led_num = LED_NUM;
121 }
122 return RT_EOK;
123 }
124
rt_hw_led_init(void)125 int rt_hw_led_init(void)
126 {
127 led.parent.type = RT_Device_Class_Char;
128 led.parent.rx_indicate = RT_NULL;
129 led.parent.tx_complete = RT_NULL;
130 led.parent.init = rt_led_init;
131 led.parent.open = rt_led_open;
132 led.parent.close = rt_led_close;
133 led.parent.read = rt_led_read;
134 led.parent.write = rt_led_write;
135 led.parent.control = rt_led_control;
136 led.parent.user_data = RT_NULL;
137
138 /* register a character device */
139 rt_device_register(&led.parent, "led", RT_DEVICE_FLAG_RDWR);
140 /* init led device */
141 rt_led_init(&led.parent);
142 return 0;
143 }
144 INIT_DEVICE_EXPORT(rt_hw_led_init);
145
146 #ifdef RT_USING_FINSH
147 #include <finsh.h>
led_test(rt_uint32_t led_num,rt_uint32_t value)148 void led_test(rt_uint32_t led_num, rt_uint32_t value)
149 {
150 rt_uint8_t led_value = value;
151 rt_led_write(&led.parent, led_num, &led_value, 1);
152 }
153 FINSH_FUNCTION_EXPORT(led_test, e.g: led_test(0, 100).)
154 #endif
155