]> the.earth.li Git - esp8266-clock.git/blob - user_main.c
Add initial OTA upgrade support
[esp8266-clock.git] / user_main.c
1 /*
2  * Copyright 2017 Jonathan McDowell <noodles@earth.li>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 #include <ets_sys.h>
18 #include <osapi.h>
19 #include <os_type.h>
20 #include <user_interface.h>
21
22 #include "project_config.h"
23
24 #include "clock.h"
25 #include "max7219.h"
26 #include "ota.h"
27 #include "spi.h"
28
29 struct station_config wificfg;
30 static os_timer_t update_timer;
31
32 static const struct fontchar clocknums[] = {
33         { .width = 5,
34           .bitmap = { 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e } },
35         { .width = 3,
36           .bitmap = { 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x07 } },
37         { .width = 5,
38           .bitmap = { 0x0e, 0x11, 0x10, 0x10, 0x08, 0x04, 0x02, 0x1f } },
39         { .width = 5,
40           .bitmap = { 0x0e, 0x11, 0x10, 0x0c, 0x10, 0x10, 0x11, 0x0e } },
41         { .width = 6,
42           .bitmap = { 0x10, 0x18, 0x14, 0x12, 0x11, 0x3f, 0x10, 0x10 } },
43         { .width = 5,
44           .bitmap = { 0x1f, 0x01, 0x01, 0x0f, 0x10, 0x10, 0x11, 0x0e } },
45         { .width = 5,
46           .bitmap = { 0x0e, 0x11, 0x01, 0x0f, 0x11, 0x11, 0x11, 0x0e } },
47         { .width = 5,
48           .bitmap = { 0x1f, 0x10, 0x10, 0x08, 0x04, 0x02, 0x02, 0x02 } },
49         { .width = 5,
50           .bitmap = { 0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x11, 0x0e } },
51         { .width = 5,
52           .bitmap = { 0x0e, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x11, 0x0e } }
53 };
54
55 void ICACHE_FLASH_ATTR update_func(void *arg)
56 {
57         static bool ind = false;
58         uint8_t hour, mins;
59         uint8_t digits[4], position[4];
60         struct tm curtime;
61
62         max7219_clear();
63         ind = !ind;
64
65         /* Draw the middle : */
66         if (ind) {
67                 max7219_set_pixel(15, 1, true);
68                 max7219_set_pixel(15, 2, true);
69                 max7219_set_pixel(15, 5, true);
70                 max7219_set_pixel(15, 6, true);
71                 max7219_set_pixel(16, 1, true);
72                 max7219_set_pixel(16, 2, true);
73                 max7219_set_pixel(16, 5, true);
74                 max7219_set_pixel(16, 6, true);
75         }
76
77         breakdown_time(get_time(), &curtime);
78         mins = curtime.tm_min;
79         hour = curtime.tm_hour;
80
81         digits[0] = hour / 10;
82         digits[1] = hour % 10;
83         digits[2] = mins / 10;
84         digits[3] = mins % 10;
85
86         /*
87          * We want our numbers to use as much of the LED matrix as possible,
88          * and the displayed time to be centred on the display, so we do our
89          * own positioning and blitting instead of using max7219_print.
90          */
91         position[1] = 14 - clocknums[digits[1]].width;
92         position[0] = position[1] - clocknums[digits[0]].width - 1;
93         position[2] = 18;
94         position[3] = position[2] + clocknums[digits[2]].width + 1;
95
96         max7219_blit(position[0], 0, clocknums[digits[0]].bitmap,
97                 clocknums[digits[0]].width, 8);
98         max7219_blit(position[1], 0, clocknums[digits[1]].bitmap,
99                 clocknums[digits[1]].width, 8);
100         max7219_blit(position[2], 0, clocknums[digits[2]].bitmap,
101                 clocknums[digits[2]].width, 8);
102         max7219_blit(position[3], 0, clocknums[digits[3]].bitmap,
103                 clocknums[digits[3]].width, 8);
104
105         max7219_show();
106 }
107
108 void ICACHE_FLASH_ATTR wifi_callback(System_Event_t *evt)
109 {
110         switch (evt->event) {
111         case EVENT_STAMODE_CONNECTED:
112         case EVENT_STAMODE_DISCONNECTED:
113                 break;
114         case EVENT_STAMODE_GOT_IP:
115                 ntp_get_time();
116                 ota_check();
117         default:
118                 break;
119         }
120 }
121
122 void ICACHE_FLASH_ATTR wifi_init(void)
123 {
124         wificfg.bssid_set = 0;
125         os_memcpy(&wificfg.ssid, CFG_WIFI_SSID,
126                 os_strlen(CFG_WIFI_SSID));
127         os_memcpy(&wificfg.password, CFG_WIFI_PASSWORD,
128                 os_strlen(CFG_WIFI_PASSWORD));
129
130         wifi_station_set_hostname("esp8266-clock");
131         wifi_set_opmode(STATION_MODE);
132         wifi_station_set_config(&wificfg);
133
134         wifi_set_event_handler_cb(wifi_callback);
135 }
136
137 void user_init(void)
138 {
139         /* Fix up UART0 baud rate */
140         uart_div_modify(0, UART_CLK_FREQ / 115200);
141         os_printf("Starting up.");
142
143         rtc_init();
144         gpio_init();
145
146         spi_init();
147         max7219_init(BIT12);            /* GPIO12 is CS */
148         max7219_print("Booting");
149         max7219_show();
150
151         wifi_init();
152
153         os_timer_setfn(&update_timer, update_func, NULL);
154         os_timer_arm(&update_timer, 10000 /* 10s */, 1);
155 }