source: asp3_tinet_ecnl_rx/trunk/app4_aircon/src/echonet_main.c@ 351

Last change on this file since 351 was 351, checked in by coas-nagasima, 6 years ago

ECHONETミドルウェアを起動後、少し待つよう変更。

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 28.5 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014 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
54/* TODO: メーカーコードを設定 */
55#define MAKER_CODE { 0x00, 0x00, 0xB3 } /* TOPPERSプロジェクト */
56
57/* ノードプロファイルオブジェクト */
58struct ecn_cls0EF0_t node_profile_data = {
59 0x30, /* 動作状態 */
60 { 0x01, 0x0A, { 0x01, 0x00 } }, /* Version情報 */
61 {
62 0xFE, /* 下位通信層IDフィールド */
63 { MAKER_CODE }, /* メーカーコード */
64 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* ユニークID部(メーカー独自) */
65 },
66 0x0000, /* 異常内容 */
67 { MAKER_CODE }, /* メーカーコード */
68};
69
70/* 家庭用エアコンクラス */
71struct ecn_cls0130_t home_air_conditioner_data = {
72 0x30, /* 動作状態 */
73 0x41, /* 運転モード設定 */
74 0x14, /* 温度設定値 */
75 0x00, /* 設置場所 */
76 { 0x00, 0x00, 'C', 0x00 }, /* 規格Version情報 */
77 0x42, /* 異常発生状態 */
78 { MAKER_CODE }, /* メーカーコード */
79};
80
81/* ノードプロファイルオブジェクト */
82struct ecn_cls0EF0_t temp_sensor_01_node_data = {
83 0x30, /* 動作状態 */
84 { 0x01, 0x0A, { 0x01, 0x00 } }, /* Version情報 */
85 {
86 0xFE, /* 下位通信層IDフィールド */
87 { MAKER_CODE }, /* メーカーコード */
88 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* ユニークID部(メーカー独自) */
89 },
90 0x0000, /* 異常内容 */
91 { MAKER_CODE }, /* メーカーコード */
92};
93
94/* 温度センサクラス */
95struct ecn_cls0011_t temp_sensor_01_data = {
96 0x31, /* 動作状態 */
97 0xF554, /* 温度計測値 */
98 0x00, /* 設置場所 */
99 { 0x00, 0x00, 'C', 0x00 }, /* 規格Version情報 */
100 0x42, /* 異常発生状態 */
101 { MAKER_CODE }, /* メーカーコード */
102};
103
104/* ノードプロファイルオブジェクト */
105struct ecn_cls0EF0_t temp_sensor_02_node_data = {
106 0x30, /* 動作状態 */
107 { 0x01, 0x0A, { 0x01, 0x00 } }, /* Version情報 */
108 {
109 0xFE, /* 下位通信層IDフィールド */
110 { MAKER_CODE }, /* メーカーコード */
111 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* ユニークID部(メーカー独自) */
112 },
113 0x0000, /* 異常内容 */
114 { MAKER_CODE }, /* メーカーコード */
115};
116
117/* 温度センサクラス */
118struct ecn_cls0011_t temp_sensor_02_data = {
119 0x31, /* 動作状態 */
120 0xF554, /* 温度計測値 */
121 0x00, /* 設置場所 */
122 { 0x00, 0x00, 'C', 0x00 }, /* 規格Version情報 */
123 0x42, /* 異常発生状態 */
124 { MAKER_CODE }, /* メーカーコード */
125};
126
127/* ノードプロファイルオブジェクト */
128struct ecn_cls0EF0_t temp_sensor_03_node_data = {
129 0x30, /* 動作状態 */
130 { 0x01, 0x0A, { 0x01, 0x00 } }, /* Version情報 */
131 {
132 0xFE, /* 下位通信層IDフィールド */
133 { MAKER_CODE }, /* メーカーコード */
134 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* ユニークID部(メーカー独自) */
135 },
136 0x0000, /* 異常内容 */
137 { MAKER_CODE }, /* メーカーコード */
138};
139
140/* 温度センサクラス */
141struct ecn_cls0011_t temp_sensor_03_data = {
142 0x31, /* 動作状態 */
143 0xF554, /* 温度計測値 */
144 0x00, /* 設置場所 */
145 { 0x00, 0x00, 'C', 0x00 }, /* 規格Version情報 */
146 0x42, /* 異常発生状態 */
147 { MAKER_CODE }, /* メーカーコード */
148};
149
150/* ノードプロファイルオブジェクト */
151struct ecn_cls0EF0_t temp_sensor_04_node_data = {
152 0x30, /* 動作状態 */
153 { 0x01, 0x0A, { 0x01, 0x00 } }, /* Version情報 */
154 {
155 0xFE, /* 下位通信層IDフィールド */
156 { MAKER_CODE }, /* メーカーコード */
157 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* ユニークID部(メーカー独自) */
158 },
159 0x0000, /* 異常内容 */
160 { MAKER_CODE }, /* メーカーコード */
161};
162
163/* 温度センサクラス */
164struct ecn_cls0011_t temp_sensor_04_data = {
165 0x31, /* 動作状態 */
166 0xF554, /* 温度計測値 */
167 0x00, /* 設置場所 */
168 { 0x00, 0x00, 'C', 0x00 }, /* 規格Version情報 */
169 0x42, /* 異常発生状態 */
170 { MAKER_CODE }, /* メーカーコード */
171};
172
173/*
174 * 動作状態ON/OFF設定関数(0x30, 0x31のみ受け付け)
175 */
176int onoff_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
177{
178 ER ret;
179 uint8_t data[1];
180
181 /* サイズが1以外は受け付けない */
182 if(size != 1)
183 return 0;
184
185 *anno = *((uint8_t *)item->exinf) != *((uint8_t *)src);
186
187 switch(*(uint8_t *)src){
188 /* ONの場合 */
189 case 0x30:
190 /* OFFの場合 */
191 case 0x31:
192 *((uint8_t *)item->exinf) = *((uint8_t *)src);
193 /* メインタスクに通知 */
194 data[0] = 0x80;
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 break;
201 /* 0x30か0x31以外は受け付けない */
202 default:
203 return 0;
204 }
205
206 return 1;
207}
208
209/*
210 * 異常発生状態設定関数(0x41, 0x42のみ受け付け)
211 */
212int alarm_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
213{
214 /* サイズが1以外は受け付けない */
215 if(size != 1)
216 return 0;
217
218 *anno = *((uint8_t *)item->exinf) != *((uint8_t *)src);
219
220 switch(*(uint8_t *)src){
221 /* 異常発生ありの場合 */
222 case 0x41:
223 /* 異常発生なしの場合 */
224 case 0x42:
225 *((uint8_t *)item->exinf) = *((uint8_t *)src);
226 break;
227 /* 0x41か0x42以外は受け付けない */
228 default:
229 return 0;
230 }
231
232 return 1;
233}
234
235/*
236 * 運転モード設定設定関数
237 */
238int ecn_cls0130_propertyB0_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
239{
240 ER ret;
241 uint8_t data[1];
242
243 /* サイズが1以外は受け付けない */
244 if(size != 1)
245 return 0;
246
247 switch(*(uint8_t *)src){
248 /* 自動の場合 */
249 case 0x41:
250 /* 冷房の場合 */
251 case 0x42:
252 /* 暖房の場合 */
253 case 0x43:
254 /* 除湿の場合 */
255 case 0x44:
256 /* 送風の場合 */
257 case 0x45:
258 /* その他の場合 */
259 case 0x40:
260 *((uint8_t *)item->exinf) = *((uint8_t *)src);
261 /* メインタスクに通知 */
262 data[0] = 0xB0;
263 ret = ecn_brk_wai(data, sizeof(data));
264 if(ret != E_OK){
265 syslog(LOG_ERROR, "ecn_brk_wai");
266 return 2;
267 }
268 break;
269 default:
270 /* 上記以外は受け付けない */
271 return 0;
272 }
273
274 return 1;
275}
276
277/*
278 * 温度設定値設定関数
279 */
280int ecn_cls0130_propertyB3_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
281{
282 ER ret;
283 uint8_t data[1];
284
285 /* サイズが1以外は受け付けない */
286 if(size != 1)
287 return 0;
288
289 /* 0℃~50℃ */
290 if((*(uint8_t *)src >= 0x00) && (*(uint8_t *)src <= 0x32)){
291 *((uint8_t *)item->exinf) = *((uint8_t *)src);
292 /* メインタスクに通知 */
293 data[0] = 0xB3;
294 ret = ecn_brk_wai(data, sizeof(data));
295 if(ret != E_OK){
296 syslog(LOG_ERROR, "ecn_brk_wai");
297 return 2;
298 }
299 }
300 /* 上記以外は受け付けない */
301 else{
302 return 0;
303 }
304
305 return 1;
306}
307
308static void main_initialize();
309static int main_get_timer();
310static void main_progress(int interval);
311static void main_recv_esv(T_EDATA *esv);
312static void main_break_wait(uint8_t *brkdat, int32_t len);
313static void main_timeout();
314
315/*
316 * メインタスク
317 */
318void echonet_main_task(intptr_t exinf)
319{
320 ER ret, ret2;
321 SYSTIM prev, now;
322 int timer;
323 T_EDATA *esv;
324 uint8_t brkdat[64];
325 int32_t len;
326
327 /* アプリケーションの初期化 */
328 main_initialize();
329
330 ret2 = get_tim(&now);
331 if (ret2 != E_OK){
332 syslog(LOG_ERROR, "get_tim");
333 return;
334 }
335
336 for(;;){
337 prev = now;
338
339 /* タイマー取得 */
340 timer = main_get_timer();
341
342 /* 応答電文待ち */
343 ret = ecn_trcv_esv(&esv, timer);
344 if ((ret != E_OK) && (ret != E_BRK) && (ret != E_TMOUT)){
345 syslog(LOG_ERROR, "ecn_trcv_esv");
346 break;
347 }
348
349 ret2 = get_tim(&now);
350 if (ret2 != E_OK){
351 syslog(LOG_ERROR, "get_tim");
352 break;
353 }
354
355 /* 時間経過 */
356 main_progress(now - prev);
357
358 /* Echonet電文受信の場合 */
359 if (ret == E_OK) {
360 /* Echonet電文受信処理 */
361 main_recv_esv(esv);
362
363 /* 領域解放 */
364 ret = ecn_rel_esv(esv);
365 if (ret != E_OK){
366 syslog(LOG_ERROR, "ecn_rel_esv");
367 break;
368 }
369 }
370 /* 応答電文待ちの割り込みの場合 */
371 else if (ret == E_BRK) {
372 /* 応答電文待ちの割り込みデータ取得 */
373 ret = ecn_get_brk_dat(esv, brkdat, sizeof(brkdat), &len);
374 if (ret != E_OK){
375 syslog(LOG_ERROR, "ecn_get_brk_dat");
376 break;
377 }
378
379 /* 応答電文待ちの割り込み処理 */
380 main_break_wait(brkdat, len);
381
382 /* 領域解放 */
383 ret = ecn_rel_esv(esv);
384 if (ret != E_OK){
385 syslog(LOG_ERROR, "ecn_rel_esv");
386 break;
387 }
388 }
389
390 /* タイムアウト処理 */
391 main_timeout();
392 }
393}
394
395bool_t started = false;
396
397void echonet_change_netif_link(uint8_t link_up, uint8_t up)
398{
399 ER ret;
400
401 if (link_up == 0)
402 return;
403
404 if (up && !started) {
405 started = true;
406
407 /* ECHONETミドルウェアを起動 */
408 ret = ecn_sta_svc();
409 if (ret != E_OK)
410 return;
411
412 /* ECHONETミドルウェアを起動するのを待つ */
413 dly_tsk(100);
414 }
415
416 /* メインタスクに通知 */
417 uint8_t data[2];
418 data[0] = 0x01;
419 data[1] = up ? 0x01 : 0x02;
420 ret = ecn_brk_wai(data, sizeof(data));
421 if (ret != E_OK) {
422 syslog(LOG_ERROR, "ecn_brk_wai");
423 return;
424 }
425}
426
427enum main_state_t{
428 main_state_idle,
429 main_state_search,
430 main_state_survey_01,
431 main_state_survey_02,
432 main_state_survey_03,
433 main_state_survey_04,
434 main_state_interval,
435};
436
437int main_timer = TMO_FEVR;
438enum main_state_t main_state = main_state_idle;
439int16_t main_ave_templ;
440bool_t main_tmp_fan_on;
441bool_t main_ctl_fan_on;
442
443int main_btn_timer = TMO_FEVR;
444
445enum main_led_state_t{
446 main_led_state_idle,
447 main_led_state_on_o,
448 main_led_state_on_n,
449 main_led_state_off_o,
450 main_led_state_off_f1,
451 main_led_state_off_f2,
452 main_led_state_space1,
453 main_led_state_templ_10,
454 main_led_state_templ_1,
455 main_led_state_space2,
456 main_led_state_ave_templ_10,
457 main_led_state_ave_templ_1,
458 main_led_state_space3,
459 main_led_state_mode,
460 main_led_state_space4,
461};
462
463int main_led_timer = TMO_FEVR;
464enum main_led_state_t main_led_state = main_led_state_idle;
465bool_t main_led_update;
466
467bool_t main_btn1_state;
468int main_btn1_count = 0;
469bool_t main_btn2_state;
470int main_btn2_count = 0;
471
472enum main_rly_state_t{
473 main_rly_state_off,
474 main_rly_state_on
475};
476
477int main_rly_timer = TMO_FEVR;
478enum main_rly_state_t main_rly_state = main_rly_state_off;
479static void main_rly_onoff(bool_t onoff);
480
481/*
482 * 初期化
483 */
484static void main_initialize()
485{
486 uint8_t btn1, btn2;
487
488 /* 7segを"0"と表示 */
489 sil_wrb_mem((uint8_t *)0x0008C02D, 0xC0);
490
491 /* 1秒後に温度センサーを探す */
492 main_timer = 1000 * 1000;
493
494 /* 10ms後にボタン状態を確認 */
495 main_btn_timer = 10 * 1000;
496
497 if(home_air_conditioner_data.property80 == 0x30)
498 main_led_state = main_led_state_on_o;
499 else
500 main_led_state = main_led_state_off_o;
501 main_led_timer = 0;
502
503 /* ボタン状態読み込み */
504 btn1 = sil_reb_mem((uint8_t *)0x0008C040);
505 btn2 = sil_reb_mem((uint8_t *)0x0008C040);
506 main_btn1_state = (btn1 & 0x20) != 0;
507 main_btn2_state = (btn2 & 0x80) != 0;
508
509 ER ret = act_tsk(MAIN_TASK);
510 if (ret != E_OK) {
511 syslog(LOG_ERROR, "act_tsk");
512 }
513}
514
515/*
516 * タイマー取得
517 */
518static int main_get_timer()
519{
520 int result = main_timer;
521
522 if((result == TMO_FEVR)
523 || ((main_btn_timer != TMO_FEVR) && (main_btn_timer < result))){
524 result = main_btn_timer;
525 }
526
527 if((result == TMO_FEVR)
528 || ((main_led_timer != TMO_FEVR) && (main_led_timer < result))){
529 result = main_led_timer;
530 }
531
532 if((result == TMO_FEVR)
533 || ((main_rly_timer != TMO_FEVR) && (main_rly_timer < result))){
534 result = main_rly_timer;
535 }
536
537 return result;
538}
539
540/*
541 * 時間経過
542 */
543static void main_progress(int interval)
544{
545 if(main_timer != TMO_FEVR){
546 main_timer -= interval;
547 if(main_timer < 0){
548 main_timer = 0;
549 }
550 }
551
552 if(main_btn_timer != TMO_FEVR){
553 main_btn_timer -= interval;
554 if(main_btn_timer < 0){
555 main_btn_timer = 0;
556 }
557 }
558
559 if(main_led_timer != TMO_FEVR){
560 main_led_timer -= interval;
561 if(main_led_timer < 0){
562 main_led_timer = 0;
563 }
564 }
565
566 if(main_rly_timer != TMO_FEVR){
567 main_rly_timer -= interval;
568 if(main_rly_timer < 0){
569 main_rly_timer = 0;
570 }
571 }
572}
573
574static void main_survey_templ(int no);
575static void main_calc_ave_templ();
576
577/*
578 * Echonet電文受信処理
579 */
580static void main_recv_esv(T_EDATA *esv)
581{
582 ER ret;
583 ID eobjid;
584 uint8_t epc;
585 uint8_t pdc;
586 uint8_t p_edt[256];
587 T_ENUM_EPC enm;
588
589 eobjid = ecn_get_eobj(esv);
590 if(eobjid == EOBJ_NULL){
591 syslog(LOG_ERROR, "ecn_get_eobj");
592 }
593
594 ret = ecn_itr_ini(&enm, esv);
595 if(ret != E_OK){
596 syslog(LOG_ERROR, "ecn_itr_ini");
597 return;
598 }
599
600 for(;;) {
601 while((ret = ecn_itr_nxt(&enm, &epc, &pdc, p_edt)) == E_OK) {
602 switch (epc) {
603 case 0xD6:
604 switch(main_state){
605 case main_state_idle:
606 case main_state_search:
607 /* 温度センサー1温度監視 */
608 main_survey_templ(1);
609 main_state = main_state_survey_01;
610 main_timer = 1000 * 1000;
611 break;
612 }
613 break;
614 case 0xE0:
615 switch(main_state){
616 case main_state_survey_01:
617 /* 温度センサー2温度監視 */
618 main_survey_templ(2);
619 main_state = main_state_survey_02;
620 main_timer = 1000 * 1000;
621 break;
622 case main_state_survey_02:
623 /* 温度センサー3温度監視 */
624 main_survey_templ(3);
625 main_state = main_state_survey_03;
626 main_timer = 1000 * 1000;
627 break;
628 case main_state_survey_03:
629 /* 温度センサー4温度監視 */
630 main_survey_templ(4);
631 main_state = main_state_survey_04;
632 main_timer = 1000 * 1000;
633 break;
634 case main_state_survey_04:
635 /* 温度センサー1~4平均値計算 */
636 main_calc_ave_templ();
637 /* 温度監視休止10秒 */
638 main_state = main_state_interval;
639 main_timer = 10000 * 1000;
640 break;
641 }
642 break;
643 }
644 }
645 if(ret != E_BOVR){
646 syslog(LOG_ERROR, "ecn_itr_nxt");
647 break;
648 }
649 if(enm.is_eof)
650 break;
651 }
652}
653
654/*
655 * 温度センサー温度監視
656 */
657static void main_survey_templ(int no)
658{
659 const ID senserids[] = {
660 TEMP_SENSOR_01_EOBJ,
661 TEMP_SENSOR_02_EOBJ,
662 TEMP_SENSOR_03_EOBJ,
663 TEMP_SENSOR_04_EOBJ
664 };
665 ER ret;
666 T_EDATA *esv;
667
668 /* 温度センサー動作状態取得電文作成 */
669 ret = ecn_esv_get(&esv, senserids[no - 1], 0x80);
670 if(ret != E_OK){
671 syslog(LOG_ERROR, "ecn_esv_get");
672 return;
673 }
674
675 /* 温度計測値取得追加 */
676 ret = ecn_add_epc(esv, 0xE0);
677 if(ret != E_OK){
678 syslog(LOG_ERROR, "ecn_add_epc");
679
680 ret = ecn_rel_esv(esv);
681 if(ret != E_OK){
682 syslog(LOG_ERROR, "ecn_rel_esv");
683 }
684 return;
685 }
686
687 /* 電文送信 */
688 ret = ecn_snd_esv(esv);
689 if(ret != E_OK){
690 syslog(LOG_ERROR, "ecn_snd_esv");
691 }
692}
693
694/*
695 * 温度センサー1~4平均値計算
696 */
697static void main_calc_ave_templ()
698{
699 int count = 0;
700 int templ = 0;
701
702 if(temp_sensor_01_data.property80 == 0x30){
703 templ += ((((uint16_t)temp_sensor_01_data.propertyE0) & 0xFF) << 8)
704 | ((((uint16_t)temp_sensor_01_data.propertyE0) & 0xFF00) >> 8);
705 count++;
706 }
707 if(temp_sensor_02_data.property80 == 0x30){
708 templ += ((((uint16_t)temp_sensor_02_data.propertyE0) & 0xFF) << 8)
709 | ((((uint16_t)temp_sensor_02_data.propertyE0) & 0xFF00) >> 8);
710 count++;
711 }
712 if(temp_sensor_03_data.property80 == 0x30){
713 templ += ((((uint16_t)temp_sensor_03_data.propertyE0) & 0xFF) << 8)
714 | ((((uint16_t)temp_sensor_03_data.propertyE0) & 0xFF00) >> 8);
715 count++;
716 }
717 if(temp_sensor_04_data.property80 == 0x30){
718 templ += ((((uint16_t)temp_sensor_04_data.propertyE0) & 0xFF) << 8)
719 | ((((uint16_t)temp_sensor_04_data.propertyE0) & 0xFF00) >> 8);
720 count++;
721 }
722
723 if(count > 0){
724 templ = templ / count;
725 if(templ < -2732)
726 main_ave_templ = 0x8000;
727 else if(templ > 32766)
728 main_ave_templ = 0x7FFF;
729 else
730 main_ave_templ = (int16_t)templ;
731
732 /* FANが停止中の場合 */
733 if(!main_tmp_fan_on){
734 if(main_ave_templ > (10 * home_air_conditioner_data.propertyB3 + 5)){
735 main_tmp_fan_on = true;
736
737 /* リレー出力をON */
738 if (!main_ctl_fan_on)
739 main_rly_onoff(true);
740 }
741 }
742 /* FANが稼働中の場合 */
743 else{
744 if(main_ave_templ < (10 * home_air_conditioner_data.propertyB3 - 5)){
745 main_tmp_fan_on = false;
746
747 /* リレー出力をOFF */
748 if (!main_ctl_fan_on)
749 main_rly_onoff(false);
750 }
751 }
752 }
753 else
754 main_ave_templ = 0x7FFF;
755}
756
757/*
758 * 応答電文待ちの割り込み処理
759 */
760static void main_break_wait(uint8_t *brkdat, int32_t len)
761{
762 switch(main_led_state){
763 case main_led_state_idle:
764 switch (brkdat[0]) {
765 case 0x01:
766 // Link up/down
767 break;
768 case 0x80:
769 case 0xB0:
770 case 0xB3:
771 if(home_air_conditioner_data.property80 == 0x30)
772 main_led_state = main_led_state_on_o;
773 else
774 main_led_state = main_led_state_off_o;
775 main_led_timer = 0;
776 break;
777 }
778 break;
779 default:
780 main_led_update = true;
781 break;
782 }
783
784 /* 運転モードが送風の場合、温度によらずFANをON */
785 if (*brkdat == 0xB0) {
786 bool_t prev = main_ctl_fan_on;
787 main_ctl_fan_on = home_air_conditioner_data.propertyB0 == 0x45;
788
789 if (prev != main_ctl_fan_on) {
790 if (main_ctl_fan_on) {
791 /* リレー出力をON */
792 if (!main_tmp_fan_on)
793 main_rly_onoff(true);
794 }
795 else {
796 /* リレー出力をOFF */
797 if (!main_tmp_fan_on)
798 main_rly_onoff(false);
799 }
800 }
801 }
802}
803
804static void main_ontimer();
805static void main_btn_ontimer();
806static void main_led_ontimer();
807static void main_rly_ontimer();
808
809/*
810 * タイムアウト処理
811 */
812static void main_timeout()
813{
814 if(main_timer == 0){
815 main_ontimer();
816 }
817
818 if(main_btn_timer == 0){
819 main_btn_ontimer();
820 }
821
822 if(main_led_timer == 0){
823 main_led_ontimer();
824 }
825
826 if(main_rly_timer == 0){
827 main_rly_ontimer();
828 }
829}
830
831static void main_search();
832
833static void main_ontimer()
834{
835 switch(main_state){
836 case main_state_idle:
837 case main_state_search:
838 /* 温度センサー再検索 */
839 main_search();
840 main_state = main_state_search;
841 main_timer = 5000 * 1000;
842 break;
843 case main_state_survey_01:
844 /* 応答がない場合動作状態OFFとする */
845 temp_sensor_01_data.property80 = 0x31;
846 /* 温度センサー2温度監視 */
847 main_survey_templ(2);
848 main_state = main_state_survey_02;
849 main_timer = 1000 * 1000;
850 break;
851 case main_state_survey_02:
852 /* 応答がない場合動作状態OFFとする */
853 temp_sensor_02_data.property80 = 0x31;
854 /* 温度センサー3温度監視 */
855 main_survey_templ(3);
856 main_state = main_state_survey_03;
857 main_timer = 1000 * 1000;
858 break;
859 case main_state_survey_03:
860 /* 応答がない場合動作状態OFFとする */
861 temp_sensor_03_data.property80 = 0x31;
862 /* 温度センサー4温度監視 */
863 main_survey_templ(4);
864 main_state = main_state_survey_04;
865 main_timer = 1000 * 1000;
866 break;
867 case main_state_survey_04:
868 /* 応答がない場合動作状態OFFとする */
869 temp_sensor_04_data.property80 = 0x31;
870 /* 温度センサー1~4平均値計算 */
871 main_calc_ave_templ();
872 /* 温度監視休止10秒 */
873 main_state = main_state_interval;
874 main_timer = 10000 * 1000;
875 break;
876 case main_state_interval:
877 /* 温度センサー1温度監視 */
878 main_survey_templ(1);
879 main_state = main_state_survey_01;
880 main_timer = 1000 * 1000;
881 break;
882 }
883}
884
885static void main_search()
886{
887 ER ret;
888 T_EDATA *esv;
889
890 /* 温度センサー検索 */
891 ret = ecn_esv_inf_req(&esv, EOBJ_NULL, 0xD6);
892 if(ret != E_OK){
893 syslog(LOG_ERROR, "ecn_esv_inf_req");
894 return;
895 }
896
897 /* 電文送信 */
898 ret = ecn_snd_esv(esv);
899 if(ret != E_OK){
900 syslog(LOG_ERROR, "ecn_snd_esv");
901 }
902}
903
904static void main_btn1_change(bool_t push);
905static void main_btn2_change(bool_t push);
906
907static void main_btn_ontimer()
908{
909 uint8_t btn1, btn2;
910
911 /* 10ms後にボタン状態を確認 */
912 main_btn_timer = 10 * 1000;
913
914 /* ボタン状態読み込み */
915 btn1 = sil_reb_mem((uint8_t *)0x0008C040);
916 btn2 = sil_reb_mem((uint8_t *)0x0008C040);
917
918 /* ボタン1の処理 */
919 if(((btn1 & 0x20) != 0) && !main_btn1_state){
920 main_btn1_count++;
921 if(main_btn1_count > 10){
922 main_btn1_count = 0;
923 main_btn1_state = true;
924
925 main_btn1_change(true);
926 }
927 }
928 else if(((btn1 & 0x20) == 0) && main_btn1_state){
929 main_btn1_count++;
930 if(main_btn1_count > 10){
931 main_btn1_count = 0;
932 main_btn1_state = false;
933
934 main_btn1_change(false);
935 }
936 }
937
938 /* ボタン2の処理 */
939 if(((btn2 & 0x80) != 0) && !main_btn2_state){
940 main_btn2_count++;
941 if(main_btn2_count > 10){
942 main_btn2_count = 0;
943 main_btn2_state = true;
944
945 main_btn2_change(true);
946 }
947 }
948 else if(((btn2 & 0x80) == 0) && main_btn2_state){
949 main_btn2_count++;
950 if(main_btn2_count > 10){
951 main_btn2_count = 0;
952 main_btn2_state = false;
953
954 main_btn2_change(false);
955 }
956 }
957}
958
959uint8_t led_num[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };
960uint8_t led_onf[] = { 0xA3, 0xAB, 0x8E };
961uint8_t led_abcdef[] = { 0xF7, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E };
962
963static void main_led_ontimer()
964{
965 int temp;
966
967 switch(main_led_state){
968 case main_led_state_idle:
969 /* 7segに' 'を表示 */
970 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
971 main_led_timer = TMO_FEVR;
972 return;
973 case main_led_state_on_o:
974 /* 7segに'o'を表示 */
975 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[0]);
976 main_led_state = main_led_state_on_n;
977 break;
978 case main_led_state_on_n:
979 /* 7segに'n'を表示 */
980 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[1]);
981 main_led_state = main_led_state_space1;
982 break;
983 case main_led_state_off_o:
984 /* 7segに'o'を表示 */
985 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[0]);
986 main_led_state = main_led_state_off_f1;
987 break;
988 case main_led_state_off_f1:
989 /* 7segに'f'を表示 */
990 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[2]);
991 main_led_state = main_led_state_off_f2;
992 break;
993 case main_led_state_off_f2:
994 /* 7segに'f'を表示 */
995 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[2]);
996 main_led_state = main_led_state_space1;
997 break;
998 case main_led_state_space1:
999 /* 7segに' 'を表示 */
1000 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1001 main_led_state = main_led_state_templ_10;
1002 break;
1003 case main_led_state_templ_10:
1004 temp = (home_air_conditioner_data.propertyB3 / 10) % 10;
1005 if(temp < 0)
1006 temp = -temp;
1007 /* 7segに温度設定10の位を表示 */
1008 sil_wrb_mem((uint8_t *)0x0008C02D, led_num[temp]);
1009 main_led_state = main_led_state_templ_1;
1010 break;
1011 case main_led_state_templ_1:
1012 temp = (home_air_conditioner_data.propertyB3 / 1) % 10;
1013 if(temp < 0)
1014 temp = -temp;
1015 /* 7segに温度設定1の位を表示 */
1016 sil_wrb_mem((uint8_t *)0x0008C02D, led_num[temp] & (~0x80));
1017 main_led_state = main_led_state_space2;
1018 break;
1019 case main_led_state_space2:
1020 /* 7segに' 'を表示 */
1021 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1022 main_led_state = main_led_state_ave_templ_10;
1023 break;
1024 case main_led_state_ave_templ_10:
1025 temp = (main_ave_templ / 100) % 10;
1026 if(temp < 0)
1027 temp = -temp;
1028 /* 7segに温度計測値10の位を表示 */
1029 sil_wrb_mem((uint8_t *)0x0008C02D, led_num[temp]);
1030 main_led_state = main_led_state_ave_templ_1;
1031 break;
1032 case main_led_state_ave_templ_1:
1033 temp = (main_ave_templ / 10) % 10;
1034 if(temp < 0)
1035 temp = -temp;
1036 /* 7segに温度計測値1の位を表示 */
1037 sil_wrb_mem((uint8_t *)0x0008C02D, led_num[temp] & (~0x80));
1038 main_led_state = main_led_state_space3;
1039 break;
1040 case main_led_state_space3:
1041 /* 7segに' 'を表示 */
1042 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1043 main_led_state = main_led_state_mode;
1044 break;
1045 case main_led_state_mode:
1046 temp = home_air_conditioner_data.propertyB0 - 0x40;
1047 /* 7segに運転モードを表示 */
1048 sil_wrb_mem((uint8_t *)0x0008C02D, led_abcdef[temp]);
1049 main_led_state = main_led_state_space4;
1050 break;
1051 case main_led_state_space4:
1052 if(home_air_conditioner_data.property80 == 0x30)
1053 /* 7segに'.'を表示 */
1054 sil_wrb_mem((uint8_t *)0x0008C02D, 0x7F);
1055 else
1056 /* 7segに' 'を表示 */
1057 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1058
1059 if(main_led_update){
1060 main_led_update = false;
1061
1062 if(home_air_conditioner_data.property80 == 0x30)
1063 main_led_state = main_led_state_on_o;
1064 else
1065 main_led_state = main_led_state_off_o;
1066 }
1067 else{
1068 main_led_state = main_led_state_idle;
1069 main_led_timer = TMO_FEVR;
1070 return;
1071 }
1072 break;
1073 default:
1074 /* 7segに' 'を表示 */
1075 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1076 main_led_state = main_led_state_idle;
1077 main_led_timer = TMO_FEVR;
1078 return;
1079 }
1080
1081 main_led_timer = 500 * 1000;
1082}
1083
1084uint8_t main_templ = 20; /* 20℃ */
1085
1086/*
1087 * ボタン1状態変化処理
1088 */
1089static void main_btn1_change(bool_t push)
1090{
1091 ER ret;
1092 T_EDATA *esv;
1093 uint8_t p_edt[1];
1094
1095 /* 押されて戻った時に処理する */
1096 if(push)
1097 return;
1098
1099 /* 設定温度 */
1100 if(main_templ > 0)
1101 main_templ--; /* - 1℃ */
1102
1103 p_edt[0] = main_templ;
1104
1105 /* プロパティ設定電文作成 */
1106 ret = ecn_esv_seti(&esv, HOME_AIR_CONDITIONER_EOBJ, 0xB3, 1, p_edt);
1107 if(ret != E_OK){
1108 syslog(LOG_ERROR, "ecn_esv_seti");
1109 return;
1110 }
1111
1112 /* 電文送信 */
1113 ecn_snd_esv(esv);
1114 if(ret != E_OK){
1115 syslog(LOG_ERROR, "ecn_snd_esv");
1116 }
1117}
1118
1119/*
1120 * ボタン2状態変化処理
1121 */
1122static void main_btn2_change(bool_t push)
1123{
1124 ER ret;
1125 T_EDATA *esv;
1126 uint8_t p_edt[1];
1127
1128 /* 押されて戻った時に処理する */
1129 if(push)
1130 return;
1131
1132 /* 設定温度 */
1133 if(main_templ < 50)
1134 main_templ++; /* + 1.0℃ */
1135
1136 p_edt[0] = main_templ;
1137
1138 /* プロパティ設定電文作成 */
1139 ret = ecn_esv_seti(&esv, HOME_AIR_CONDITIONER_EOBJ, 0xB3, 1, p_edt);
1140 if(ret != E_OK){
1141 syslog(LOG_ERROR, "ecn_esv_seti");
1142 return;
1143 }
1144
1145 /* 電文送信 */
1146 ecn_snd_esv(esv);
1147 if(ret != E_OK){
1148 syslog(LOG_ERROR, "ecn_snd_esv");
1149 }
1150}
1151#if 1
1152static void main_rly_onoff(bool_t onoff)
1153{
1154 if(onoff){
1155 /* リレー出力をON */
1156 sil_wrb_mem((uint8_t *)0x0008C022, sil_reb_mem((uint8_t *)0x0008C022) | 0x20);
1157 }
1158 else{
1159 /* リレー出力をOFF */
1160 sil_wrb_mem((uint8_t *)0x0008C022, sil_reb_mem((uint8_t *)0x0008C022) & ~0x20);
1161 }
1162}
1163
1164static void main_rly_ontimer()
1165{
1166 main_rly_timer = TMO_FEVR;
1167}
1168#else
1169static void main_rly_onoff(bool_t onoff)
1170{
1171 /* リレー出力をON */
1172 sil_wrb_mem((uint8_t *)0x0008C022, sil_reb_mem((uint8_t *)0x0008C022) | 0x20);
1173
1174 /* 500msパルス出力 */
1175 main_rly_state = main_rly_state_on;
1176 main_rly_timer = 500 * 1000;
1177}
1178
1179/*
1180 * リレーパルス出力処理
1181 */
1182static void main_rly_ontimer()
1183{
1184 switch(main_rly_state)
1185 {
1186 case main_rly_state_off:
1187 main_rly_timer = TMO_FEVR;
1188 break;
1189 case main_rly_state_on:
1190 /* リレー出力をOFF */
1191 sil_wrb_mem((uint8_t *)0x0008C022, sil_reb_mem((uint8_t *)0x0008C022) & ~0x20);
1192
1193 main_rly_state = main_rly_state_off;
1194 main_rly_timer = TMO_FEVR;
1195 break;
1196 }
1197}
1198#endif
Note: See TracBrowser for help on using the repository browser.