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