1/*
2 * devices for ESP32 C3 dev board
3 *
4 * Written in 2010-2021 by Andy Green <andy@warmcat.com>
5 *
6 * This file is made available under the Creative Commons CC0 1.0
7 * Universal Public Domain Dedication.
8 */
9
10#define LWIP_PROVIDE_ERRNO 1
11#define _ESP_PLATFORM_ERRNO_H_
12
13#include <stdio.h>
14#include "sdkconfig.h"
15#include "freertos/FreeRTOS.h"
16#include "freertos/task.h"
17
18#include <driver/gpio.h>
19
20#include <libwebsockets.h>
21
22struct lws_led_state *lls;
23lws_display_state_t lds;
24struct lws_button_state *bcs;
25lws_netdev_instance_wifi_t *wnd;
26
27/*
28 * Button controller
29 */
30
31static const lws_button_map_t bcm[] = {
32	{
33		.gpio			= GPIO_NUM_0,
34		.smd_interaction_name	= "user"
35	},
36};
37
38static const lws_button_controller_t bc = {
39	.smd_bc_name			= "bc",
40	.gpio_ops			= &lws_gpio_plat,
41	.button_map			= &bcm[0],
42	.active_state_bitmap		= 0,
43	.count_buttons			= LWS_ARRAY_SIZE(bcm),
44};
45
46/*
47 * pwm controller
48 */
49
50static const lws_pwm_map_t pwm_map[] = {
51	{ .gpio = GPIO_NUM_8, .index = 0, .active_level = 1 }
52};
53
54static const lws_pwm_ops_t pwm_ops = {
55	lws_pwm_plat_ops,
56	.pwm_map			= &pwm_map[0],
57	.count_pwm_map			= LWS_ARRAY_SIZE(pwm_map)
58};
59
60#if 0
61static const lws_display_ssd1306_t disp = {
62	.disp = {
63		lws_display_ssd1306_ops,
64		.w			= 128,
65		.h			= 64
66	},
67	.i2c				= (lws_i2c_ops_t *)&li2c,
68	.gpio				= &lws_gpio_plat,
69	.reset_gpio			= GPIO_NUM_16,
70	.i2c7_address			= SSD1306_I2C7_ADS1
71};
72#endif
73
74/*
75 * led controller
76 */
77
78static const lws_led_gpio_map_t lgm[] = {
79	{
80		.name			= "alert",
81		.gpio			= GPIO_NUM_8,
82		.pwm_ops		= &pwm_ops, /* managed by pwm */
83		.active_level		= 1,
84	},
85};
86
87static const lws_led_gpio_controller_t lgc = {
88	.led_ops			= lws_led_gpio_ops,
89	.gpio_ops			= &lws_gpio_plat,
90	.led_map			= &lgm[0],
91	.count_leds			= LWS_ARRAY_SIZE(lgm)
92};
93
94/*
95 * Settings stored in platform nv
96 */
97
98static const lws_settings_ops_t sett = {
99	lws_settings_ops_plat
100};
101
102/*
103 * Wifi
104 */
105
106static const lws_netdev_ops_t wifi_ops = {
107	lws_netdev_wifi_plat_ops
108};
109
110int
111init_plat_devices(struct lws_context *ctx)
112{
113	lws_settings_instance_t *si;
114	lws_netdevs_t *netdevs = lws_netdevs_from_ctx(ctx);
115
116	si = lws_settings_init(&sett, (void *)"nvs");
117	if (!si) {
118		lwsl_err("%s: failed to create settings instance\n", __func__);
119		return 1;
120	}
121	netdevs->si = si;
122
123#if 0
124	/*
125	 * This is a temp hack to bootstrap the settings to contain the test
126	 * AP ssid and passphrase for one time, so the settings can be stored
127	 * while there's no UI atm
128	 */
129	{
130		lws_wifi_creds_t creds;
131
132		memset(&creds, 0, sizeof(creds));
133
134		lws_strncpy(creds.ssid, "xxx", sizeof(creds.ssid));
135		lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
136		lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
137
138		if (lws_netdev_credentials_settings_set(netdevs)) {
139			lwsl_err("%s: failed to write bootstrap creds\n",
140					__func__);
141			return 1;
142		}
143	}
144#endif
145
146	/* create the wifi network device and configure it */
147
148	wnd = (lws_netdev_instance_wifi_t *)
149			wifi_ops.create(ctx, &wifi_ops, "wl0", NULL);
150	if (!wnd) {
151		lwsl_err("%s: failed to create wifi object\n", __func__);
152		return 1;
153	}
154
155	wnd->flags |= LNDIW_MODE_STA;
156
157	if (wifi_ops.configure(&wnd->inst, NULL)) {
158		lwsl_err("%s: failed to configure wifi object\n", __func__);
159		return 1;
160	}
161
162	wifi_ops.up(&wnd->inst);
163	esp_wifi_set_mode(WIFI_MODE_STA);
164lws_netdev_wifi_scan_plat(&wnd->inst);
165	lls = lgc.led_ops.create(&lgc.led_ops);
166	if (!lls) {
167		lwsl_err("%s: could not create led\n", __func__);
168		return 1;
169	}
170
171	/* pwm init must go after the led controller init */
172
173//	pwm_ops.init(&pwm_ops);
174
175	bcs = lws_button_controller_create(ctx, &bc);
176	if (!bcs) {
177		lwsl_err("%s: could not create buttons\n", __func__);
178		return 1;
179	}
180
181	lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
182//	lws_led_transition(lls, "alert", &lws_pwmseq_static_off,
183//					 &lws_pwmseq_static_on);
184
185	lwsl_notice("%s: exiting device init\n", __func__);
186	return 0;
187}
188