1 | /*
|
---|
2 | * TOPPERS ECHONET Lite Communication Middleware
|
---|
3 | *
|
---|
4 | * Copyright (C) 2014-2018 Cores Co., Ltd. Japan
|
---|
5 | *
|
---|
6 | * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
|
---|
7 | * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
|
---|
8 | * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
|
---|
9 | * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
|
---|
10 | * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
|
---|
11 | * スコード中に含まれていること.
|
---|
12 | * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
|
---|
13 | * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
|
---|
14 | * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
|
---|
15 | * の無保証規定を掲載すること.
|
---|
16 | * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
|
---|
17 | * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
|
---|
18 | * と.
|
---|
19 | * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
|
---|
20 | * 作権表示,この利用条件および下記の無保証規定を掲載すること.
|
---|
21 | * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
|
---|
22 | * 報告すること.
|
---|
23 | * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
|
---|
24 | * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
|
---|
25 | * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
|
---|
26 | * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
|
---|
27 | * 免責すること.
|
---|
28 | *
|
---|
29 | * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
|
---|
30 | * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
|
---|
31 | * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
|
---|
32 | * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
|
---|
33 | * の責任を負わない.
|
---|
34 | *
|
---|
35 | * @(#) $Id$
|
---|
36 | */
|
---|
37 |
|
---|
38 | /*
|
---|
39 | * サンプルプログラム(1)の本体
|
---|
40 | */
|
---|
41 |
|
---|
42 | #include <kernel.h>
|
---|
43 | #include <t_syslog.h>
|
---|
44 | #include <t_stdlib.h>
|
---|
45 | #include <sil.h>
|
---|
46 | #include <string.h>
|
---|
47 | #include "syssvc/serial.h"
|
---|
48 | #include "syssvc/syslog.h"
|
---|
49 | #include "kernel_cfg.h"
|
---|
50 | #include "echonet_main.h"
|
---|
51 | #include "echonet_cfg.h"
|
---|
52 | #include "target_kernel_impl.h"
|
---|
53 | #include "gpio_api.h"
|
---|
54 | #include "analogin_api.h"
|
---|
55 | #include "adafruit_st7735.h"
|
---|
56 | #include "draw_font.h"
|
---|
57 | #include <tinet_defs.h>
|
---|
58 | #include <tinet_config.h>
|
---|
59 | #include <netinet/in.h>
|
---|
60 | #include <netinet/in_var.h>
|
---|
61 | #include <net/ethernet.h>
|
---|
62 | #include <net/if_var.h>
|
---|
63 |
|
---|
64 | extern uint8_t mac_addr[6];
|
---|
65 |
|
---|
66 | /* TODO: メーカーコードを設定 */
|
---|
67 | #define MAKER_CODE { 0x00, 0x00, 0xB3 } /* TOPPERSプロジェクト */
|
---|
68 |
|
---|
69 | /* ノードプロファイルオブジェクト */
|
---|
70 | struct ecn_cls0EF0_t node_profile_data = {
|
---|
71 | 0x30, /* 動作状態 */
|
---|
72 | { 0x01, 0x0A, { 0x01, 0x00 } }, /* Version情報 */
|
---|
73 | {
|
---|
74 | 0xFE, /* 下位通信層IDフィールド */
|
---|
75 | { MAKER_CODE }, /* メーカーコード */
|
---|
76 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* ユニークID部(メーカー独自) */
|
---|
77 | },
|
---|
78 | 0x0000, /* 異常内容 */
|
---|
79 | { MAKER_CODE }, /* メーカーコード */
|
---|
80 | };
|
---|
81 |
|
---|
82 | /* 温度センサクラス */
|
---|
83 | struct ecn_cls0011_t temperature_sensor1_data = {
|
---|
84 | 0x30, /* 動作状態 */
|
---|
85 | 0xF554, /* 温度計測値 */
|
---|
86 | 0x00, /* 設置場所 */
|
---|
87 | { 0x00, 0x00, 'C', 0x00 }, /* 規格Version情報 */
|
---|
88 | 0x42, /* 異常発生状態 */
|
---|
89 | { MAKER_CODE }, /* メーカーコード */
|
---|
90 | };
|
---|
91 |
|
---|
92 | /* 温度センサクラス */
|
---|
93 | struct ecn_cls0011_t temperature_sensor2_data = {
|
---|
94 | 0x30, /* 動作状態 */
|
---|
95 | 0xF554, /* 温度計測値 */
|
---|
96 | 0x00, /* 設置場所 */
|
---|
97 | { 0x00, 0x00, 'C', 0x00 }, /* 規格Version情報 */
|
---|
98 | 0x42, /* 異常発生状態 */
|
---|
99 | { MAKER_CODE }, /* メーカーコード */
|
---|
100 | };
|
---|
101 |
|
---|
102 | /* 湿度センサクラス */
|
---|
103 | struct ecn_cls0012_t humidity_sensor_data = {
|
---|
104 | 0x30, /* 動作状態 */
|
---|
105 | 0x00, /* 相対湿度計測値 */
|
---|
106 | 0x00, /* 設置場所 */
|
---|
107 | { 0x00, 0x00, 'C', 0x00 }, /* 規格Version情報 */
|
---|
108 | 0x42, /* 異常発生状態 */
|
---|
109 | { MAKER_CODE }, /* メーカーコード */
|
---|
110 | };
|
---|
111 |
|
---|
112 | /*
|
---|
113 | * 動作状態ON/OFF設定関数(0x30, 0x31のみ受け付け)
|
---|
114 | */
|
---|
115 | int onoff_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
|
---|
116 | {
|
---|
117 | ER ret;
|
---|
118 | uint8_t data[2];
|
---|
119 |
|
---|
120 | /* サイズが1以外は受け付けない */
|
---|
121 | if (size != 1)
|
---|
122 | return 0;
|
---|
123 |
|
---|
124 | *anno = *((uint8_t *)item->exinf) != *((uint8_t *)src);
|
---|
125 |
|
---|
126 | switch (*(uint8_t *)src) {
|
---|
127 | /* ONの場合 */
|
---|
128 | case 0x30:
|
---|
129 | /* OFFの場合 */
|
---|
130 | case 0x31:
|
---|
131 | *((uint8_t *)item->exinf) = *((uint8_t *)src);
|
---|
132 | /* メインタスクに通知 */
|
---|
133 | data[0] = 0x80;
|
---|
134 | data[1] = *(uint8_t *)src;
|
---|
135 | ret = ecn_brk_wai(data, sizeof(data));
|
---|
136 | if (ret != E_OK) {
|
---|
137 | syslog(LOG_ERROR, "ecn_brk_wai");
|
---|
138 | return 1;
|
---|
139 | }
|
---|
140 | break;
|
---|
141 | /* 0x30か0x31以外は受け付けない */
|
---|
142 | default:
|
---|
143 | return 0;
|
---|
144 | }
|
---|
145 |
|
---|
146 | return 1;
|
---|
147 | }
|
---|
148 |
|
---|
149 | /*
|
---|
150 | * 異常発生状態設定関数(0x41, 0x42のみ受け付け)
|
---|
151 | */
|
---|
152 | int alarm_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
|
---|
153 | {
|
---|
154 | /* サイズが1以外は受け付けない */
|
---|
155 | if (size != 1)
|
---|
156 | return 0;
|
---|
157 |
|
---|
158 | *anno = *((uint8_t *)item->exinf) != *((uint8_t *)src);
|
---|
159 |
|
---|
160 | switch (*(uint8_t *)src) {
|
---|
161 | /* 異常発生ありの場合 */
|
---|
162 | case 0x41:
|
---|
163 | /* 異常発生なしの場合 */
|
---|
164 | case 0x42:
|
---|
165 | *((uint8_t *)item->exinf) = *((uint8_t *)src);
|
---|
166 | break;
|
---|
167 | /* 0x41か0x42以外は受け付けない */
|
---|
168 | default:
|
---|
169 | return 0;
|
---|
170 | }
|
---|
171 |
|
---|
172 | return 1;
|
---|
173 | }
|
---|
174 |
|
---|
175 | /*
|
---|
176 | * 温度測定値設定関数
|
---|
177 | */
|
---|
178 | int temperature_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
|
---|
179 | {
|
---|
180 | struct ecn_cls0011_t *eobj = (struct ecn_cls0011_t *)item->exinf;
|
---|
181 | int16_t value;
|
---|
182 | ER ret;
|
---|
183 | uint8_t data[1];
|
---|
184 |
|
---|
185 | /* サイズが2以外は受け付けない */
|
---|
186 | if (size != 2)
|
---|
187 | return 0;
|
---|
188 |
|
---|
189 | value = (((uint8_t *)src)[0] << 8) | (((uint8_t *)src)[1] & 0xFF);
|
---|
190 |
|
---|
191 | if ((value >= -2732) && (value <= 32766)) {
|
---|
192 | eobj->propertyE0 = value;
|
---|
193 | /* メインタスクに通知 */
|
---|
194 | data[0] = 0xE0;
|
---|
195 | ret = ecn_brk_wai(data, sizeof(data));
|
---|
196 | if (ret != E_OK) {
|
---|
197 | syslog(LOG_ERROR, "ecn_brk_wai");
|
---|
198 | return 2;
|
---|
199 | }
|
---|
200 | }
|
---|
201 | /* 上記以外は受け付けない */
|
---|
202 | else {
|
---|
203 | return 0;
|
---|
204 | }
|
---|
205 |
|
---|
206 | return 2;
|
---|
207 | }
|
---|
208 |
|
---|
209 | /*
|
---|
210 | * 温度計測値取得関数
|
---|
211 | */
|
---|
212 | int temperature_get(const EPRPINIB *item, void *dst, int size)
|
---|
213 | {
|
---|
214 | struct ecn_cls0011_t *eobj = (struct ecn_cls0011_t *)item->exinf;
|
---|
215 | int16_t value = eobj->propertyE0;
|
---|
216 |
|
---|
217 | /* サイズが2以外は受け付けない */
|
---|
218 | if (size != 2)
|
---|
219 | return 0;
|
---|
220 |
|
---|
221 | ((uint8_t *)dst)[0] = value >> 8;
|
---|
222 | ((uint8_t *)dst)[1] = value & 0xFF;
|
---|
223 |
|
---|
224 | return 2;
|
---|
225 | }
|
---|
226 |
|
---|
227 | static void main_initialize();
|
---|
228 | static int main_get_timer();
|
---|
229 | static void main_progress(int interval);
|
---|
230 | static void main_recv_esv(T_EDATA *esv);
|
---|
231 | static void main_break_wait(uint8_t *brkdat, int32_t len);
|
---|
232 | static void main_timeout();
|
---|
233 |
|
---|
234 | /*
|
---|
235 | * メインタスク
|
---|
236 | */
|
---|
237 | void echonet_main_task(intptr_t exinf)
|
---|
238 | {
|
---|
239 | ER ret, ret2;
|
---|
240 | SYSTIM prev, now;
|
---|
241 | int timer;
|
---|
242 | T_EDATA *esv;
|
---|
243 | uint8_t brkdat[64];
|
---|
244 | int32_t len;
|
---|
245 |
|
---|
246 | /* アプリケーションの初期化 */
|
---|
247 | main_initialize();
|
---|
248 |
|
---|
249 | ret2 = get_tim(&now);
|
---|
250 | if (ret2 != E_OK) {
|
---|
251 | syslog(LOG_ERROR, "get_tim");
|
---|
252 | return;
|
---|
253 | }
|
---|
254 |
|
---|
255 | for (;;) {
|
---|
256 | prev = now;
|
---|
257 |
|
---|
258 | /* タイマー取得 */
|
---|
259 | timer = main_get_timer();
|
---|
260 |
|
---|
261 | /* 応答電文待ち */
|
---|
262 | ret = ecn_trcv_esv(&esv, timer);
|
---|
263 | if ((ret != E_OK) && (ret != E_BRK) && (ret != E_TMOUT)) {
|
---|
264 | syslog(LOG_ERROR, "ecn_trcv_esv");
|
---|
265 | break;
|
---|
266 | }
|
---|
267 |
|
---|
268 | ret2 = get_tim(&now);
|
---|
269 | if (ret2 != E_OK) {
|
---|
270 | syslog(LOG_ERROR, "get_tim");
|
---|
271 | break;
|
---|
272 | }
|
---|
273 |
|
---|
274 | /* 時間経過 */
|
---|
275 | main_progress(now - prev);
|
---|
276 |
|
---|
277 | /* Echonet電文受信の場合 */
|
---|
278 | if (ret == E_OK) {
|
---|
279 | /* Echonet電文受信処理 */
|
---|
280 | main_recv_esv(esv);
|
---|
281 |
|
---|
282 | /* 領域解放 */
|
---|
283 | ret = ecn_rel_esv(esv);
|
---|
284 | if (ret != E_OK) {
|
---|
285 | syslog(LOG_ERROR, "ecn_rel_esv");
|
---|
286 | break;
|
---|
287 | }
|
---|
288 | }
|
---|
289 | /* 応答電文待ちの割り込みの場合 */
|
---|
290 | else if (ret == E_BRK) {
|
---|
291 | /* 応答電文待ちの割り込みデータ取得 */
|
---|
292 | ret = ecn_get_brk_dat(esv, brkdat, sizeof(brkdat), &len);
|
---|
293 | if (ret != E_OK) {
|
---|
294 | syslog(LOG_ERROR, "ecn_get_brk_dat");
|
---|
295 | break;
|
---|
296 | }
|
---|
297 |
|
---|
298 | /* 応答電文待ちの割り込み処理 */
|
---|
299 | main_break_wait(brkdat, len);
|
---|
300 |
|
---|
301 | /* 領域解放 */
|
---|
302 | ret = ecn_rel_esv(esv);
|
---|
303 | if (ret != E_OK) {
|
---|
304 | syslog(LOG_ERROR, "ecn_rel_esv");
|
---|
305 | break;
|
---|
306 | }
|
---|
307 | }
|
---|
308 |
|
---|
309 | /* タイムアウト処理 */
|
---|
310 | main_timeout();
|
---|
311 | }
|
---|
312 | }
|
---|
313 |
|
---|
314 | void echonet_change_netif_link(uint8_t link_up, uint8_t up)
|
---|
315 | {
|
---|
316 | ER ret;
|
---|
317 |
|
---|
318 | if (link_up == 0)
|
---|
319 | return;
|
---|
320 |
|
---|
321 | if (up) {
|
---|
322 | /* インスタンスリスト通知の送信 */
|
---|
323 | ret = ecn_ntf_inl();
|
---|
324 | if (ret != E_OK) {
|
---|
325 | syslog(LOG_ERROR, "ecn_ntf_inl");
|
---|
326 | }
|
---|
327 | }
|
---|
328 |
|
---|
329 | /* メインタスクに通知 */
|
---|
330 | uint8_t data[2];
|
---|
331 | data[0] = 0x01;
|
---|
332 | data[1] = (up ? 0x01 : 0x02) | (link_up ? 0x10 : 0x20);
|
---|
333 | ret = ecn_brk_wai(data, sizeof(data));
|
---|
334 | if (ret != E_OK) {
|
---|
335 | syslog(LOG_ERROR, "ecn_brk_wai");
|
---|
336 | return;
|
---|
337 | }
|
---|
338 | }
|
---|
339 |
|
---|
340 | enum main_state_t {
|
---|
341 | main_state_start,
|
---|
342 | main_state_idle,
|
---|
343 | };
|
---|
344 |
|
---|
345 | int main_timer = TMO_FEVR;
|
---|
346 | enum main_state_t main_state = main_state_start;
|
---|
347 |
|
---|
348 | int main_lcd_timer = TMO_FEVR;
|
---|
349 | int main_lcd_state = 0;
|
---|
350 |
|
---|
351 | gpio_t pow_led;
|
---|
352 | analogin_t analogin[3];
|
---|
353 |
|
---|
354 | /* ジョイスティック種別 */
|
---|
355 | #define BUTTON_NONE 0
|
---|
356 | #define BUTTON_DOWN 1
|
---|
357 | #define BUTTON_LEFT 2
|
---|
358 | #define BUTTON_SELECT 3
|
---|
359 | #define BUTTON_UP 4
|
---|
360 | #define BUTTON_RIGHT 5
|
---|
361 |
|
---|
362 | analogin_t joystick;
|
---|
363 | static uint8_t main_read_button(analogin_t *obj);
|
---|
364 |
|
---|
365 | bool_t main_btn1_state;
|
---|
366 | int main_btn1_count = 0;
|
---|
367 | bool_t main_btn2_state;
|
---|
368 | int main_btn2_count = 0;
|
---|
369 |
|
---|
370 | LCD_Handler_t lcd;
|
---|
371 | LCD_DrawProp_t drawProp;
|
---|
372 |
|
---|
373 | /*
|
---|
374 | * 初期化
|
---|
375 | */
|
---|
376 | static void main_initialize()
|
---|
377 | {
|
---|
378 | uint8_t btn;
|
---|
379 |
|
---|
380 | /* LEDの初期化 */
|
---|
381 | gpio_init_out(&pow_led, LED_USER);
|
---|
382 |
|
---|
383 | /* アナログ入力の初期化 */
|
---|
384 | analogin_init(&analogin[0], A0);
|
---|
385 | analogin_init(&analogin[1], A1);
|
---|
386 | analogin_init(&analogin[2], A2);
|
---|
387 |
|
---|
388 | /* ジョイスティックの初期化 */
|
---|
389 | analogin_init(&joystick, P1_12);
|
---|
390 |
|
---|
391 | /* ECHONETミドルウェアを起動するのを待つ */
|
---|
392 | main_state = main_state_start;
|
---|
393 | main_timer = 1000 * 1000;
|
---|
394 |
|
---|
395 | /* ボタン状態読み込み */
|
---|
396 | btn = main_read_button(&joystick);
|
---|
397 | main_btn1_state = btn == BUTTON_LEFT;
|
---|
398 | main_btn2_state = btn == BUTTON_RIGHT;
|
---|
399 |
|
---|
400 | // 1.8" TFTの初期化
|
---|
401 | spi_init(&lcd.hspi, P10_14, P10_15, P10_12, NC);
|
---|
402 | spi_format(&lcd.hspi, 8, 0, 0);
|
---|
403 | spi_frequency(&lcd.hspi, 4000000);
|
---|
404 |
|
---|
405 | gpio_init_out(&lcd.cs_pin, P10_13);
|
---|
406 | gpio_init_out(&lcd.rs_pin, P8_15);
|
---|
407 | gpio_init_out(&lcd.rst_pin, P8_14);
|
---|
408 | gpio_init_out(&lcd.cs2_pin, NC);
|
---|
409 |
|
---|
410 | lcd_initR(&lcd, /*INITR_REDTAB?*/INITR_18BLACKTAB);
|
---|
411 |
|
---|
412 | drawProp.hlcd = &lcd;
|
---|
413 | drawProp.TextColor = ST7735_BLACK;
|
---|
414 | drawProp.BackColor = ST7735_WHITE;
|
---|
415 | drawProp.pFont = NULL;
|
---|
416 | lcd_fillScreen(&drawProp);
|
---|
417 |
|
---|
418 | /* 1秒後にLCD表示を更新 */
|
---|
419 | main_lcd_state = 10;
|
---|
420 | main_lcd_timer = 1000 * 1000;
|
---|
421 |
|
---|
422 | /* メインタスクを起動 */
|
---|
423 | ER ret = act_tsk(MAIN_TASK);
|
---|
424 | if (ret != E_OK) {
|
---|
425 | syslog(LOG_ERROR, "act_tsk");
|
---|
426 | }
|
---|
427 | }
|
---|
428 |
|
---|
429 | /*
|
---|
430 | * タイマー取得
|
---|
431 | */
|
---|
432 | static int main_get_timer()
|
---|
433 | {
|
---|
434 | int result = main_timer;
|
---|
435 |
|
---|
436 | if ((result == TMO_FEVR)
|
---|
437 | || ((main_lcd_timer != TMO_FEVR) && (main_lcd_timer < result))) {
|
---|
438 | result = main_lcd_timer;
|
---|
439 | }
|
---|
440 |
|
---|
441 | return result;
|
---|
442 | }
|
---|
443 |
|
---|
444 | /*
|
---|
445 | * 時間経過
|
---|
446 | */
|
---|
447 | static void main_progress(int interval)
|
---|
448 | {
|
---|
449 | if (main_timer != TMO_FEVR) {
|
---|
450 | main_timer -= interval;
|
---|
451 | if (main_timer < 0) {
|
---|
452 | main_timer = 0;
|
---|
453 | }
|
---|
454 | }
|
---|
455 |
|
---|
456 | if (main_lcd_timer != TMO_FEVR) {
|
---|
457 | main_lcd_timer -= interval;
|
---|
458 | if (main_lcd_timer < 0) {
|
---|
459 | main_lcd_timer = 0;
|
---|
460 | }
|
---|
461 | }
|
---|
462 | }
|
---|
463 |
|
---|
464 | static bool_t check_response(uint8_t pdc, uint8_t *p_edt);
|
---|
465 |
|
---|
466 | /*
|
---|
467 | * Echonet電文受信処理
|
---|
468 | */
|
---|
469 | static void main_recv_esv(T_EDATA *esv)
|
---|
470 | {
|
---|
471 | ER ret;
|
---|
472 | uint8_t epc;
|
---|
473 | uint8_t pdc;
|
---|
474 | uint8_t p_edt[256];
|
---|
475 | T_ENUM_EPC enm;
|
---|
476 | bool_t in_get = false;
|
---|
477 |
|
---|
478 | ret = ecn_itr_ini(&enm, esv);
|
---|
479 | if (ret != E_OK) {
|
---|
480 | syslog(LOG_ERROR, "ecn_itr_ini");
|
---|
481 | return;
|
---|
482 | }
|
---|
483 |
|
---|
484 | for (;;) {
|
---|
485 | while ((ret = ecn_itr_nxt(&enm, &epc, &pdc, p_edt)) == E_OK) {
|
---|
486 | switch (epc) {
|
---|
487 | case 0xE0:
|
---|
488 | if (in_get && (esv->hdr.edata.esv == ESV_SET_GET_RES)) {
|
---|
489 | check_response(pdc, p_edt);
|
---|
490 | }
|
---|
491 | break;
|
---|
492 | }
|
---|
493 | }
|
---|
494 | if (ret != E_BOVR) {
|
---|
495 | syslog(LOG_ERROR, "ecn_itr_nxt");
|
---|
496 | break;
|
---|
497 | }
|
---|
498 | if (enm.is_eof)
|
---|
499 | break;
|
---|
500 |
|
---|
501 | /* GET_SETのGETへ */
|
---|
502 | in_get = true;
|
---|
503 | }
|
---|
504 | }
|
---|
505 |
|
---|
506 | /*
|
---|
507 | * 応答電文待ちの割り込み処理
|
---|
508 | */
|
---|
509 | static void main_break_wait(uint8_t *brkdat, int32_t len)
|
---|
510 | {
|
---|
511 | char mac_text[30] = "mac: ";
|
---|
512 | char ipaddr_text[30] = "ipadr: ";
|
---|
513 | const T_IN4_ADDR *ip4_addr;
|
---|
514 | int pos;
|
---|
515 |
|
---|
516 | if (brkdat[0] == 0x01) {
|
---|
517 | pos = str_macaddr(&mac_text[4], sizeof(mac_text) - 4, mac_addr, 0);
|
---|
518 | mac_text[pos + 4] = '\0';
|
---|
519 | lcd_drawString(&lcd, mac_text, X_LINE_TO_PIX(&lcd, 0), Y_ROW_TO_PIX(&lcd, 11), ST7735_BLACK, ST7735_WHITE);
|
---|
520 |
|
---|
521 | ip4_addr = in4_get_ifaddr(0);
|
---|
522 | pos = str_ipv4addr(&ipaddr_text[6], sizeof(ipaddr_text) - 6, ip4_addr, 0);
|
---|
523 | ipaddr_text[pos + 6] = '\0';
|
---|
524 | lcd_drawString(&lcd, ipaddr_text, X_LINE_TO_PIX(&lcd, 0), Y_ROW_TO_PIX(&lcd, 12), ST7735_BLACK, ST7735_WHITE);
|
---|
525 | return;
|
---|
526 | }
|
---|
527 |
|
---|
528 | if ((len == 2) && (brkdat[0] == 0x80)) {
|
---|
529 | switch (brkdat[1]) {
|
---|
530 | /* ONの場合 */
|
---|
531 | case 0x30:
|
---|
532 | /* LEDをON */
|
---|
533 | gpio_write(&pow_led, 1);
|
---|
534 | break;
|
---|
535 | /* OFFの場合 */
|
---|
536 | case 0x31:
|
---|
537 | /* LEDをOFF */
|
---|
538 | gpio_write(&pow_led, 0);
|
---|
539 | break;
|
---|
540 | }
|
---|
541 | }
|
---|
542 | }
|
---|
543 |
|
---|
544 | static void main_ontimer();
|
---|
545 | static void main_lcd_ontimer();
|
---|
546 |
|
---|
547 | /*
|
---|
548 | * タイムアウト処理
|
---|
549 | */
|
---|
550 | static void main_timeout()
|
---|
551 | {
|
---|
552 | if (main_timer == 0) {
|
---|
553 | main_ontimer();
|
---|
554 | }
|
---|
555 |
|
---|
556 | if (main_lcd_timer == 0) {
|
---|
557 | main_lcd_ontimer();
|
---|
558 | }
|
---|
559 | }
|
---|
560 |
|
---|
561 | #define main_ad_count 3
|
---|
562 | #define main_ad_table_count 64
|
---|
563 | static int16_t main_ad_tempr[main_ad_count] = { 200, 200, 200 };
|
---|
564 | static uint16_t main_ad_table[main_ad_count][main_ad_table_count];
|
---|
565 | static int main_ad_pos = 0;
|
---|
566 | static uint32_t main_ad_avelage[main_ad_count];
|
---|
567 | static int main_count[main_ad_count];
|
---|
568 |
|
---|
569 | static void main_ad_change(int no, int adv);
|
---|
570 | static void main_btn1_change(bool_t push);
|
---|
571 | static void main_btn2_change(bool_t push);
|
---|
572 |
|
---|
573 | static void main_ontimer()
|
---|
574 | {
|
---|
575 | ER ret;
|
---|
576 | uint8_t btn;
|
---|
577 | uint16_t ad_value;
|
---|
578 | int16_t ad_tempr;
|
---|
579 |
|
---|
580 | switch (main_state) {
|
---|
581 | case main_state_start:
|
---|
582 | /* ECHONETミドルウェアを起動 */
|
---|
583 | ret = ecn_sta_svc();
|
---|
584 | if (ret != E_OK) {
|
---|
585 | syslog(LOG_ERROR, "ecn_sta_svc");
|
---|
586 | }
|
---|
587 |
|
---|
588 | /* 10ms後にボタン状態を確認 */
|
---|
589 | main_state = main_state_idle;
|
---|
590 | main_timer = 10 * 1000;
|
---|
591 | break;
|
---|
592 | case main_state_idle:
|
---|
593 | /* 10ms後にボタン状態を確認 */
|
---|
594 | main_timer = 10 * 1000;
|
---|
595 |
|
---|
596 | /* ADCの変換結果取得 */
|
---|
597 | for (int i = 0; i < main_ad_count; i++) {
|
---|
598 | main_ad_avelage[i] -= main_ad_table[i][main_ad_pos];
|
---|
599 | ad_value = analogin_read_u16(&analogin[i]) >> 4; // 16bit値取得->12bit
|
---|
600 | main_ad_table[i][main_ad_pos] = ad_value;
|
---|
601 | main_ad_avelage[i] += ad_value;
|
---|
602 | }
|
---|
603 |
|
---|
604 | main_ad_pos++;
|
---|
605 | if (main_ad_pos >= main_ad_table_count) {
|
---|
606 | main_ad_pos = 0;
|
---|
607 | }
|
---|
608 |
|
---|
609 | for (int i = 0; i < main_ad_count; i++) {
|
---|
610 | ad_tempr = ((int16_t)(((main_ad_avelage[i] / main_ad_table_count) >> 3) & 0x1FF)) - 100;
|
---|
611 | if (main_ad_tempr[i] != ad_tempr) {
|
---|
612 | /* 1秒変化が続いたら */
|
---|
613 | if (main_count[i] < 100) {
|
---|
614 | main_count[i]++;
|
---|
615 | }
|
---|
616 | else {
|
---|
617 | main_count[i] = 0;
|
---|
618 | main_ad_tempr[i] = ad_tempr;
|
---|
619 |
|
---|
620 | /* ADC状態変化処理 */
|
---|
621 | main_ad_change(i + 1, ad_tempr);
|
---|
622 | }
|
---|
623 | }
|
---|
624 | else {
|
---|
625 | main_count[i] = 0;
|
---|
626 | }
|
---|
627 | }
|
---|
628 |
|
---|
629 | /* ボタン状態読み込み */
|
---|
630 | btn = main_read_button(&joystick);
|
---|
631 |
|
---|
632 | /* ボタン1の処理 */
|
---|
633 | if ((btn == BUTTON_LEFT) && !main_btn1_state) {
|
---|
634 | main_btn1_count++;
|
---|
635 | if (main_btn1_count > 10) {
|
---|
636 | main_btn1_count = 0;
|
---|
637 | main_btn1_state = true;
|
---|
638 |
|
---|
639 | main_btn1_change(true);
|
---|
640 | }
|
---|
641 | }
|
---|
642 | else if ((btn != BUTTON_LEFT) && main_btn1_state) {
|
---|
643 | main_btn1_count++;
|
---|
644 | if (main_btn1_count > 10) {
|
---|
645 | main_btn1_count = 0;
|
---|
646 | main_btn1_state = false;
|
---|
647 |
|
---|
648 | main_btn1_change(false);
|
---|
649 | }
|
---|
650 | }
|
---|
651 |
|
---|
652 | /* ボタン2の処理 */
|
---|
653 | if ((btn == BUTTON_RIGHT) && !main_btn2_state) {
|
---|
654 | main_btn2_count++;
|
---|
655 | if (main_btn2_count > 10) {
|
---|
656 | main_btn2_count = 0;
|
---|
657 | main_btn2_state = true;
|
---|
658 |
|
---|
659 | main_btn2_change(true);
|
---|
660 | }
|
---|
661 | }
|
---|
662 | else if ((btn != BUTTON_RIGHT) && main_btn2_state) {
|
---|
663 | main_btn2_count++;
|
---|
664 | if (main_btn2_count > 10) {
|
---|
665 | main_btn2_count = 0;
|
---|
666 | main_btn2_state = false;
|
---|
667 |
|
---|
668 | main_btn2_change(false);
|
---|
669 | }
|
---|
670 | }
|
---|
671 | break;
|
---|
672 | }
|
---|
673 | }
|
---|
674 |
|
---|
675 | static void main_lcd_ontimer()
|
---|
676 | {
|
---|
677 | char temp1[] = "温度1:+000.0℃";
|
---|
678 | char temp2[] = "温度2:+000.0℃";
|
---|
679 | char humid[] = "湿度 :+000.0%";
|
---|
680 | char *btn_texts[] = { "none ", "down ", "left ", "select", "up ", "right " };
|
---|
681 | int temp, btn;
|
---|
682 |
|
---|
683 | switch (main_lcd_state) {
|
---|
684 | case 0:
|
---|
685 | temp1[10] = (temperature_sensor1_data.propertyE0 >= 0) ? ' ' : '-';
|
---|
686 | temp = (temperature_sensor1_data.propertyE0 / 1000) % 10;
|
---|
687 | if (temp < 0)
|
---|
688 | temp = -temp;
|
---|
689 | temp1[11] = '0' + temp;
|
---|
690 | temp = (temperature_sensor1_data.propertyE0 / 100) % 10;
|
---|
691 | if (temp < 0)
|
---|
692 | temp = -temp;
|
---|
693 | temp1[12] = '0' + temp;
|
---|
694 | temp = (temperature_sensor1_data.propertyE0 / 10) % 10;
|
---|
695 | if (temp < 0)
|
---|
696 | temp = -temp;
|
---|
697 | temp1[13] = '0' + temp;
|
---|
698 | temp = (temperature_sensor1_data.propertyE0 / 1) % 10;
|
---|
699 | if (temp < 0)
|
---|
700 | temp = -temp;
|
---|
701 | temp1[15] = '0' + temp;
|
---|
702 | lcd_drawString(&lcd, &temp1[10], X_LINE_HALF_TO_PIX(&lcd, 7), Y_ROW_TO_PIX(&lcd, main_lcd_state + 2), ST7735_BLACK, ST7735_WHITE);
|
---|
703 | main_lcd_state++;
|
---|
704 | break;
|
---|
705 | case 1:
|
---|
706 | temp2[10] = (temperature_sensor2_data.propertyE0 >= 0) ? ' ' : '-';
|
---|
707 | temp = (temperature_sensor2_data.propertyE0 / 1000) % 10;
|
---|
708 | if (temp < 0)
|
---|
709 | temp = -temp;
|
---|
710 | temp2[11] = '0' + temp;
|
---|
711 | temp = (temperature_sensor2_data.propertyE0 / 100) % 10;
|
---|
712 | if (temp < 0)
|
---|
713 | temp = -temp;
|
---|
714 | temp2[12] = '0' + temp;
|
---|
715 | temp = (temperature_sensor2_data.propertyE0 / 10) % 10;
|
---|
716 | if (temp < 0)
|
---|
717 | temp = -temp;
|
---|
718 | temp2[13] = '0' + temp;
|
---|
719 | temp = (temperature_sensor2_data.propertyE0 / 1) % 10;
|
---|
720 | if (temp < 0)
|
---|
721 | temp = -temp;
|
---|
722 | temp2[15] = '0' + temp;
|
---|
723 | lcd_drawString(&lcd, &temp2[10], X_LINE_HALF_TO_PIX(&lcd, 7), Y_ROW_TO_PIX(&lcd, main_lcd_state + 2), ST7735_BLACK, ST7735_WHITE);
|
---|
724 | main_lcd_state++;
|
---|
725 | break;
|
---|
726 | case 2:
|
---|
727 | humid[10] = ' ';
|
---|
728 | humid[11] = ' ';
|
---|
729 | temp = (humidity_sensor_data.propertyE0 / 100) % 10;
|
---|
730 | humid[12] = '0' + temp;
|
---|
731 | temp = (humidity_sensor_data.propertyE0 / 10) % 10;
|
---|
732 | humid[13] = '0' + temp;
|
---|
733 | temp = (humidity_sensor_data.propertyE0 / 1) % 10;
|
---|
734 | humid[15] = '0' + temp;
|
---|
735 | lcd_drawString(&lcd, &humid[10], X_LINE_HALF_TO_PIX(&lcd, 7), Y_ROW_TO_PIX(&lcd, main_lcd_state + 2), ST7735_BLACK, ST7735_WHITE);
|
---|
736 | main_lcd_state++;
|
---|
737 | break;
|
---|
738 | case 3:
|
---|
739 | case 4:
|
---|
740 | case 5:
|
---|
741 | main_lcd_state++;
|
---|
742 | break;
|
---|
743 | case 6:
|
---|
744 | btn = main_read_button(&joystick);
|
---|
745 | lcd_drawString(&lcd, btn_texts[btn], X_LINE_TO_PIX(&lcd, 0), Y_ROW_TO_PIX(&lcd, 9), ST7735_BLACK, ST7735_WHITE);
|
---|
746 | main_lcd_state++;
|
---|
747 | break;
|
---|
748 | case 9:
|
---|
749 | main_lcd_state = 0;
|
---|
750 | break;
|
---|
751 | case 10:
|
---|
752 | lcd_drawString(&lcd, "温度湿度計", X_LINE_TO_PIX(&lcd, 5), Y_ROW_TO_PIX(&lcd, 0), ST7735_BLACK, ST7735_WHITE);
|
---|
753 | lcd_drawString(&lcd, temp1, X_LINE_TO_PIX(&lcd, 0), Y_ROW_TO_PIX(&lcd, 0 + 2), ST7735_BLACK, ST7735_WHITE);
|
---|
754 | lcd_drawString(&lcd, temp2, X_LINE_TO_PIX(&lcd, 0), Y_ROW_TO_PIX(&lcd, 1 + 2), ST7735_BLACK, ST7735_WHITE);
|
---|
755 | lcd_drawString(&lcd, humid, X_LINE_TO_PIX(&lcd, 0), Y_ROW_TO_PIX(&lcd, 2 + 2), ST7735_BLACK, ST7735_WHITE);
|
---|
756 | main_lcd_state = 0;
|
---|
757 | break;
|
---|
758 | default:
|
---|
759 | main_lcd_state++;
|
---|
760 | break;
|
---|
761 | }
|
---|
762 |
|
---|
763 | /* 100ms後にLCD表示を更新 */
|
---|
764 | main_lcd_timer = 100 * 1000;
|
---|
765 | }
|
---|
766 |
|
---|
767 | /*
|
---|
768 | * ADC状態変化処理
|
---|
769 | */
|
---|
770 | static void main_ad_change(int no, int adv)
|
---|
771 | {
|
---|
772 | ER ret;
|
---|
773 | T_EDATA *esv;
|
---|
774 | uint8_t p_edt[2];
|
---|
775 | uint8_t eobj;
|
---|
776 |
|
---|
777 | switch (no) {
|
---|
778 | case 1:
|
---|
779 | eobj = TEMP_SENSOR_01_EOBJ;
|
---|
780 | break;
|
---|
781 | case 2:
|
---|
782 | eobj = TEMP_SENSOR_02_EOBJ;
|
---|
783 | break;
|
---|
784 | case 3:
|
---|
785 | eobj = HUMIDITY_SENSOR_EOBJ;
|
---|
786 | break;
|
---|
787 | default:
|
---|
788 | return;
|
---|
789 | }
|
---|
790 |
|
---|
791 | p_edt[0] = ((uint16_t)adv) >> 8;
|
---|
792 | p_edt[1] = ((uint16_t)adv) & 0xFF;
|
---|
793 |
|
---|
794 | /* プロパティ設定電文作成 */
|
---|
795 | ret = ecn_esv_setc(&esv, eobj, 0xE0, 2, p_edt);
|
---|
796 | if (ret != E_OK) {
|
---|
797 | syslog(LOG_ERROR, "ecn_esv_setc");
|
---|
798 | return;
|
---|
799 | }
|
---|
800 |
|
---|
801 | /* 電文送信 */
|
---|
802 | ret = ecn_snd_esv(esv);
|
---|
803 | if (ret != E_OK) {
|
---|
804 | syslog(LOG_ERROR, "ecn_snd_esv");
|
---|
805 | }
|
---|
806 | }
|
---|
807 |
|
---|
808 | static uint8_t main_read_button(analogin_t *obj)
|
---|
809 | {
|
---|
810 | float a = analogin_read(obj);
|
---|
811 |
|
---|
812 | a *= 5.0;
|
---|
813 |
|
---|
814 | //printf("Button read analog = %f\r\n",a);
|
---|
815 | if (a < 0.2)
|
---|
816 | return BUTTON_DOWN;
|
---|
817 | if (a < 1.0)
|
---|
818 | return BUTTON_RIGHT;
|
---|
819 | if (a < 1.7)
|
---|
820 | return BUTTON_SELECT;
|
---|
821 | if (a < 2.6)
|
---|
822 | return BUTTON_UP;
|
---|
823 | if (a < 4.6)
|
---|
824 | return BUTTON_LEFT;
|
---|
825 | else
|
---|
826 | return BUTTON_NONE;
|
---|
827 | }
|
---|
828 |
|
---|
829 | int16_t main_tmpr = 200; /* 20.0℃ */
|
---|
830 |
|
---|
831 | /*
|
---|
832 | * ボタン1状態変化処理
|
---|
833 | */
|
---|
834 | static void main_btn1_change(bool_t push)
|
---|
835 | {
|
---|
836 | ER ret;
|
---|
837 | T_EDATA *esv;
|
---|
838 | uint8_t p_edt[2];
|
---|
839 | int trn_pos;
|
---|
840 |
|
---|
841 | /* 押されて戻った時に処理する */
|
---|
842 | if (push)
|
---|
843 | return;
|
---|
844 |
|
---|
845 | /* 温度計測値 */
|
---|
846 | main_tmpr -= 10; /* - 1.0℃ */
|
---|
847 | if (main_tmpr < -100) /* -10.0℃までとする */
|
---|
848 | main_tmpr = -100;
|
---|
849 |
|
---|
850 | p_edt[0] = ((uint16_t)main_tmpr) >> 8;
|
---|
851 | p_edt[1] = ((uint16_t)main_tmpr) & 0xFF;
|
---|
852 |
|
---|
853 | /* プロパティ値書き込み・読み出し要求電文作成 */
|
---|
854 | ret = ecn_esv_set_get(&esv, TEMP_SENSOR_02_EOBJ, 0xE0, 2, p_edt);
|
---|
855 | if (ret != E_OK) {
|
---|
856 | syslog(LOG_ERROR, "ecn_esv_setc");
|
---|
857 | return;
|
---|
858 | }
|
---|
859 |
|
---|
860 | p_edt[0] = 0x30;
|
---|
861 |
|
---|
862 | /* 書き込みプロパティ追加 */
|
---|
863 | ret = ecn_add_edt(esv, 0x80, 1, p_edt);
|
---|
864 | if (ret) {
|
---|
865 | syslog(LOG_ERROR, "ecn_add_edt");
|
---|
866 | goto error;
|
---|
867 | }
|
---|
868 |
|
---|
869 | /* プロパティ値書き込み・読み出し要求電文作成:折り返し指定 */
|
---|
870 | ret = ecn_trn_set_get(esv, &trn_pos);
|
---|
871 | if (ret) {
|
---|
872 | syslog(LOG_ERROR, "ecn_trn_set_get");
|
---|
873 | goto error;
|
---|
874 | }
|
---|
875 |
|
---|
876 | /* 読み出しプロパティ追加 */
|
---|
877 | ret = ecn_add_epc(esv, 0xE0);
|
---|
878 | if (ret) {
|
---|
879 | syslog(LOG_ERROR, "ecn_add_epc");
|
---|
880 | goto error;
|
---|
881 | }
|
---|
882 |
|
---|
883 | /* プロパティ値書き込み・読み出し要求電文作成:終了指定 */
|
---|
884 | ret = ecn_end_set_get(esv, trn_pos);
|
---|
885 | if (ret) {
|
---|
886 | syslog(LOG_ERROR, "ecn_end_set_get");
|
---|
887 | goto error;
|
---|
888 | }
|
---|
889 |
|
---|
890 | /* 電文送信 */
|
---|
891 | ret = ecn_snd_esv(esv);
|
---|
892 | if (ret != E_OK) {
|
---|
893 | syslog(LOG_ERROR, "ecn_snd_esv");
|
---|
894 | }
|
---|
895 | return;
|
---|
896 | error:
|
---|
897 | /* 領域解放 */
|
---|
898 | ret = ecn_rel_esv(esv);
|
---|
899 | if (ret != E_OK) {
|
---|
900 | syslog(LOG_ERROR, "ecn_rel_esv");
|
---|
901 | }
|
---|
902 | }
|
---|
903 |
|
---|
904 | /*
|
---|
905 | * ボタン2状態変化処理
|
---|
906 | */
|
---|
907 | static void main_btn2_change(bool_t push)
|
---|
908 | {
|
---|
909 | ER ret;
|
---|
910 | T_EDATA *esv;
|
---|
911 | uint8_t p_edt[2];
|
---|
912 | int trn_pos;
|
---|
913 |
|
---|
914 | /* 押されて戻った時に処理する */
|
---|
915 | if (push)
|
---|
916 | return;
|
---|
917 |
|
---|
918 | /* 温度計測値 */
|
---|
919 | main_tmpr += 10; /* + 1.0℃ */
|
---|
920 | if (main_tmpr > 400) /* +40.0℃までとする */
|
---|
921 | main_tmpr = 400;
|
---|
922 |
|
---|
923 | p_edt[0] = ((uint16_t)main_tmpr) >> 8;
|
---|
924 | p_edt[1] = ((uint16_t)main_tmpr) & 0xFF;
|
---|
925 |
|
---|
926 | /* プロパティ値書き込み・読み出し要求電文作成 */
|
---|
927 | ret = ecn_esv_set_get(&esv, TEMP_SENSOR_02_EOBJ, 0xE0, 2, p_edt);
|
---|
928 | if (ret != E_OK) {
|
---|
929 | syslog(LOG_ERROR, "ecn_esv_setc");
|
---|
930 | return;
|
---|
931 | }
|
---|
932 |
|
---|
933 | p_edt[0] = 0x30;
|
---|
934 |
|
---|
935 | /* 書き込みプロパティ追加 */
|
---|
936 | ret = ecn_add_edt(esv, 0x80, 1, p_edt);
|
---|
937 | if (ret) {
|
---|
938 | syslog(LOG_ERROR, "ecn_add_edt");
|
---|
939 | goto error;
|
---|
940 | }
|
---|
941 |
|
---|
942 | /* プロパティ値書き込み・読み出し要求電文作成:折り返し指定 */
|
---|
943 | ret = ecn_trn_set_get(esv, &trn_pos);
|
---|
944 | if (ret) {
|
---|
945 | syslog(LOG_ERROR, "ecn_trn_set_get");
|
---|
946 | goto error;
|
---|
947 | }
|
---|
948 |
|
---|
949 | /* 読み出しプロパティ追加 */
|
---|
950 | ret = ecn_add_epc(esv, 0xE0);
|
---|
951 | if (ret) {
|
---|
952 | syslog(LOG_ERROR, "ecn_add_epc");
|
---|
953 | goto error;
|
---|
954 | }
|
---|
955 |
|
---|
956 | /* プロパティ値書き込み・読み出し要求電文作成:終了指定 */
|
---|
957 | ret = ecn_end_set_get(esv, trn_pos);
|
---|
958 | if (ret) {
|
---|
959 | syslog(LOG_ERROR, "ecn_end_set_get");
|
---|
960 | goto error;
|
---|
961 | }
|
---|
962 |
|
---|
963 | /* 電文送信 */
|
---|
964 | ret = ecn_snd_esv(esv);
|
---|
965 | if (ret != E_OK) {
|
---|
966 | syslog(LOG_ERROR, "ecn_snd_esv");
|
---|
967 | }
|
---|
968 | return;
|
---|
969 | error:
|
---|
970 | /* 領域解放 */
|
---|
971 | ret = ecn_rel_esv(esv);
|
---|
972 | if (ret != E_OK) {
|
---|
973 | syslog(LOG_ERROR, "ecn_rel_esv");
|
---|
974 | }
|
---|
975 | }
|
---|
976 |
|
---|
977 | /*
|
---|
978 | * ボタンによる温度設定結果確認
|
---|
979 | */
|
---|
980 | static bool_t check_response(uint8_t pdc, uint8_t *p_edt)
|
---|
981 | {
|
---|
982 | if ((pdc != 2)
|
---|
983 | || (p_edt[0] != ((uint16_t)main_tmpr) >> 8)
|
---|
984 | || (p_edt[1] != ((uint16_t)main_tmpr) & 0xFF)) {
|
---|
985 | syslog(LOG_WARNING, "epc_set_get response NG");
|
---|
986 | return false;
|
---|
987 | }
|
---|
988 | return true;
|
---|
989 | }
|
---|