1/* 2 * devices for ESP32 Heltec WB32 3 * 4 * Written in 2010-2020 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 * Hook up bitbang i2c, display driver and display 29 */ 30 31static void 32esp32_i2c_delay(void) 33{ 34 volatile int n = 0; 35 36 while (n < 20) 37 n++; 38} 39 40static const lws_bb_i2c_t li2c = { 41 .bb_ops = lws_bb_i2c_ops, 42 .scl = GPIO_NUM_15, 43 .sda = GPIO_NUM_4, 44 .gpio = &lws_gpio_plat, 45 .delay = esp32_i2c_delay 46}; 47 48/* 49 * Button controller 50 */ 51 52static const lws_button_map_t bcm[] = { 53 { 54 .gpio = GPIO_NUM_0, 55 .smd_interaction_name = "user" 56 }, 57}; 58 59static const lws_button_controller_t bc = { 60 .smd_bc_name = "bc", 61 .gpio_ops = &lws_gpio_plat, 62 .button_map = &bcm[0], 63 .active_state_bitmap = 0, 64 .count_buttons = LWS_ARRAY_SIZE(bcm), 65}; 66 67/* 68 * pwm controller 69 */ 70 71static const lws_pwm_map_t pwm_map[] = { 72 { .gpio = GPIO_NUM_25, .index = 0, .active_level = 1 } 73}; 74 75static const lws_pwm_ops_t pwm_ops = { 76 lws_pwm_plat_ops, 77 .pwm_map = &pwm_map[0], 78 .count_pwm_map = LWS_ARRAY_SIZE(pwm_map) 79}; 80 81static const lws_display_ssd1306_t disp = { 82 .disp = { 83 lws_display_ssd1306_ops, 84 .w = 128, 85 .h = 64 86 }, 87 .i2c = (lws_i2c_ops_t *)&li2c, 88 .gpio = &lws_gpio_plat, 89 .reset_gpio = GPIO_NUM_16, 90 .i2c7_address = SSD1306_I2C7_ADS1 91}; 92 93/* 94 * led controller 95 */ 96 97static const lws_led_gpio_map_t lgm[] = { 98 { 99 .name = "alert", 100 .gpio = GPIO_NUM_25, 101 .pwm_ops = &pwm_ops, /* managed by pwm */ 102 .active_level = 1, 103 }, 104}; 105 106static const lws_led_gpio_controller_t lgc = { 107 .led_ops = lws_led_gpio_ops, 108 .gpio_ops = &lws_gpio_plat, 109 .led_map = &lgm[0], 110 .count_leds = LWS_ARRAY_SIZE(lgm) 111}; 112 113/* 114 * Settings stored in platform nv 115 */ 116 117static const lws_settings_ops_t sett = { 118 lws_settings_ops_plat 119}; 120 121/* 122 * Wifi 123 */ 124 125static const lws_netdev_ops_t wifi_ops = { 126 lws_netdev_wifi_plat_ops 127}; 128 129int 130init_plat_devices(struct lws_context *ctx) 131{ 132 lws_settings_instance_t *si; 133 lws_netdevs_t *netdevs = lws_netdevs_from_ctx(ctx); 134 135 si = lws_settings_init(&sett, (void *)"nvs"); 136 if (!si) { 137 lwsl_err("%s: failed to create settings instance\n", __func__); 138 return 1; 139 } 140 netdevs->si = si; 141 142#if 0 143 /* 144 * This is a temp hack to bootstrap the settings to contain the test 145 * AP ssid and passphrase for one time, so the settings can be stored 146 * while there's no UI atm 147 */ 148 { 149 lws_wifi_creds_t creds; 150 151 memset(&creds, 0, sizeof(creds)); 152 153 lws_strncpy(creds.ssid, "xxx", sizeof(creds.ssid)); 154 lws_strncpy(creds.passphrase, "yyy", sizeof(creds.passphrase)); 155 lws_dll2_add_tail(&creds.list, &netdevs->owner_creds); 156 157 if (lws_netdev_credentials_settings_set(netdevs)) { 158 lwsl_err("%s: failed to write bootstrap creds\n", 159 __func__); 160 return 1; 161 } 162 } 163#endif 164 165 /* create the wifi network device and configure it */ 166 167 wnd = (lws_netdev_instance_wifi_t *) 168 wifi_ops.create(ctx, &wifi_ops, "wl0", NULL); 169 if (!wnd) { 170 lwsl_err("%s: failed to create wifi object\n", __func__); 171 return 1; 172 } 173 174 wnd->flags |= LNDIW_MODE_STA; 175 176 if (wifi_ops.configure(&wnd->inst, NULL)) { 177 lwsl_err("%s: failed to configure wifi object\n", __func__); 178 return 1; 179 } 180 181 wifi_ops.up(&wnd->inst); 182 183 lls = lgc.led_ops.create(&lgc.led_ops); 184 if (!lls) { 185 lwsl_err("%s: could not create led\n", __func__); 186 return 1; 187 } 188 189 /* pwm init must go after the led controller init */ 190 191 pwm_ops.init(&pwm_ops); 192 193 bcs = lws_button_controller_create(ctx, &bc); 194 if (!bcs) { 195 lwsl_err("%s: could not create buttons\n", __func__); 196 return 1; 197 } 198 199 /* 200 * Show the lws logo on the display 201 */ 202 203 lws_display_state_init(&lds, ctx, 10000, 20000, lls, &disp.disp); 204 205 lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user")); 206 lws_led_transition(lls, "alert", &lws_pwmseq_static_off, 207 &lws_pwmseq_static_on); 208 209 return 0; 210} 211