1 /*
2 * Copyright (c) 2017 Linaro Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/sys/printk.h>
11 #include <zephyr/sys/__assert.h>
12 #include <string.h>
13
14 /* size of stack area used by each thread */
15 #define STACKSIZE 1024
16
17 /* scheduling priority used by each thread */
18 #define PRIORITY 7
19
20 #define LED0_NODE DT_ALIAS(led0)
21 #define LED1_NODE DT_ALIAS(led1)
22
23 #if !DT_NODE_HAS_STATUS(LED0_NODE, okay)
24 #error "Unsupported board: led0 devicetree alias is not defined"
25 #endif
26
27 #if !DT_NODE_HAS_STATUS(LED1_NODE, okay)
28 #error "Unsupported board: led1 devicetree alias is not defined"
29 #endif
30
31 struct printk_data_t {
32 void *fifo_reserved; /* 1st word reserved for use by fifo */
33 uint32_t led;
34 uint32_t cnt;
35 };
36
37 K_FIFO_DEFINE(printk_fifo);
38
39 struct led {
40 struct gpio_dt_spec spec;
41 uint8_t num;
42 };
43
44 static const struct led led0 = {
45 .spec = GPIO_DT_SPEC_GET_OR(LED0_NODE, gpios, {0}),
46 .num = 0,
47 };
48
49 static const struct led led1 = {
50 .spec = GPIO_DT_SPEC_GET_OR(LED1_NODE, gpios, {0}),
51 .num = 1,
52 };
53
blink(const struct led * led,uint32_t sleep_ms,uint32_t id)54 void blink(const struct led *led, uint32_t sleep_ms, uint32_t id)
55 {
56 const struct gpio_dt_spec *spec = &led->spec;
57 int cnt = 0;
58 int ret;
59
60 if (!device_is_ready(spec->port)) {
61 printk("Error: %s device is not ready\n", spec->port->name);
62 return;
63 }
64
65 ret = gpio_pin_configure_dt(spec, GPIO_OUTPUT);
66 if (ret != 0) {
67 printk("Error %d: failed to configure pin %d (LED '%d')\n",
68 ret, spec->pin, led->num);
69 return;
70 }
71
72 while (1) {
73 gpio_pin_set(spec->port, spec->pin, cnt % 2);
74
75 struct printk_data_t tx_data = { .led = id, .cnt = cnt };
76
77 size_t size = sizeof(struct printk_data_t);
78 char *mem_ptr = k_malloc(size);
79 __ASSERT_NO_MSG(mem_ptr != 0);
80
81 memcpy(mem_ptr, &tx_data, size);
82
83 k_fifo_put(&printk_fifo, mem_ptr);
84
85 k_msleep(sleep_ms);
86 cnt++;
87 }
88 }
89
blink0(void)90 void blink0(void)
91 {
92 blink(&led0, 100, 0);
93 }
94
blink1(void)95 void blink1(void)
96 {
97 blink(&led1, 1000, 1);
98 }
99
uart_out(void)100 void uart_out(void)
101 {
102 while (1) {
103 struct printk_data_t *rx_data = k_fifo_get(&printk_fifo,
104 K_FOREVER);
105 printk("Toggled led%d; counter=%d\n",
106 rx_data->led, rx_data->cnt);
107 k_free(rx_data);
108 }
109 }
110
111 K_THREAD_DEFINE(blink0_id, STACKSIZE, blink0, NULL, NULL, NULL,
112 PRIORITY, 0, 0);
113 K_THREAD_DEFINE(blink1_id, STACKSIZE, blink1, NULL, NULL, NULL,
114 PRIORITY, 0, 0);
115 K_THREAD_DEFINE(uart_out_id, STACKSIZE, uart_out, NULL, NULL, NULL,
116 PRIORITY, 0, 0);
117