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

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

ASP3版ECNLを追加

  • 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 "rx630.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 /* TINETが起動するまで待つ */
328 ret = tslp_tsk(1000);
329 if(ret != E_TMOUT)
330 return;
331
332 /* ECHONETミドルウェアを起動 */
333 ret = ecn_sta_svc();
334 if(ret != E_OK)
335 return;
336
337 /* 初期化 */
338 main_initialize();
339
340 ret2 = get_tim(&now);
341 if (ret2 != E_OK){
342 syslog(LOG_ERROR, "get_tim");
343 return;
344 }
345
346 for(;;){
347 prev = now;
348
349 /* タイマー取得 */
350 timer = main_get_timer();
351
352 /* 応答電文待ち */
353 ret = ecn_trcv_esv(&esv, timer);
354 if ((ret != E_OK) && (ret != E_BRK) && (ret != E_TMOUT)){
355 syslog(LOG_ERROR, "ecn_trcv_esv");
356 break;
357 }
358
359 ret2 = get_tim(&now);
360 if (ret2 != E_OK){
361 syslog(LOG_ERROR, "get_tim");
362 break;
363 }
364
365 /* 時間経過 */
366 main_progress(now - prev);
367
368 /* Echonet電文受信の場合 */
369 if (ret == E_OK) {
370 /* Echonet電文受信処理 */
371 main_recv_esv(esv);
372
373 /* 領域解放 */
374 ret = ecn_rel_esv(esv);
375 if (ret != E_OK){
376 syslog(LOG_ERROR, "ecn_rel_esv");
377 break;
378 }
379 }
380 /* 応答電文待ちの割り込みの場合 */
381 else if (ret == E_BRK) {
382 /* 応答電文待ちの割り込みデータ取得 */
383 ret = ecn_get_brk_dat(esv, brkdat, sizeof(brkdat), &len);
384 if (ret != E_OK){
385 syslog(LOG_ERROR, "ecn_get_brk_dat");
386 break;
387 }
388
389 /* 応答電文待ちの割り込み処理 */
390 main_break_wait(brkdat, len);
391
392 /* 領域解放 */
393 ret = ecn_rel_esv(esv);
394 if (ret != E_OK){
395 syslog(LOG_ERROR, "ecn_rel_esv");
396 break;
397 }
398 }
399
400 /* タイムアウト処理 */
401 main_timeout();
402 }
403}
404
405bool_t started = false;
406
407void echonet_change_netif_link(uint8_t link_up, uint8_t up)
408{
409 ER ret;
410
411 if (link_up == 0)
412 return;
413
414 if (up && !started) {
415 started = true;
416
417 /* ECHONETミドルウェアを起動 */
418 ret = ecn_sta_svc();
419 if (ret != E_OK)
420 return;
421 }
422
423 /* メインタスクに通知 */
424 uint8_t data[2];
425 data[0] = 0x01;
426 data[1] = up ? 0x01 : 0x02;
427 ret = ecn_brk_wai(data, sizeof(data));
428 if (ret != E_OK) {
429 syslog(LOG_ERROR, "ecn_brk_wai");
430 return;
431 }
432}
433
434enum main_state_t{
435 main_state_idle,
436 main_state_search,
437 main_state_survey_01,
438 main_state_survey_02,
439 main_state_survey_03,
440 main_state_survey_04,
441 main_state_interval,
442};
443
444int main_timer = TMO_FEVR;
445enum main_state_t main_state = main_state_idle;
446int16_t main_ave_templ;
447bool_t main_tmp_fan_on;
448bool_t main_ctl_fan_on;
449
450int main_btn_timer = TMO_FEVR;
451
452enum main_led_state_t{
453 main_led_state_idle,
454 main_led_state_on_o,
455 main_led_state_on_n,
456 main_led_state_off_o,
457 main_led_state_off_f1,
458 main_led_state_off_f2,
459 main_led_state_space1,
460 main_led_state_templ_10,
461 main_led_state_templ_1,
462 main_led_state_space2,
463 main_led_state_ave_templ_10,
464 main_led_state_ave_templ_1,
465 main_led_state_space3,
466 main_led_state_mode,
467 main_led_state_space4,
468};
469
470int main_led_timer = TMO_FEVR;
471enum main_led_state_t main_led_state = main_led_state_idle;
472bool_t main_led_update;
473
474bool_t main_btn1_state;
475int main_btn1_count = 0;
476bool_t main_btn2_state;
477int main_btn2_count = 0;
478
479enum main_rly_state_t{
480 main_rly_state_off,
481 main_rly_state_on
482};
483
484int main_rly_timer = TMO_FEVR;
485enum main_rly_state_t main_rly_state = main_rly_state_off;
486static void main_rly_onoff(bool_t onoff);
487
488/*
489 * 初期化
490 */
491static void main_initialize()
492{
493 uint8_t btn1, btn2;
494
495 /* 7segを"0"と表示 */
496 sil_wrb_mem((uint8_t *)0x0008C02D, 0xC0);
497
498 /* 1秒後に温度センサーを探す */
499 main_timer = 1000 * 1000;
500
501 /* 10ms後にボタン状態を確認 */
502 main_btn_timer = 10 * 1000;
503
504 if(home_air_conditioner_data.property80 == 0x30)
505 main_led_state = main_led_state_on_o;
506 else
507 main_led_state = main_led_state_off_o;
508 main_led_timer = 0;
509
510 /* ボタン状態読み込み */
511 btn1 = sil_reb_mem((uint8_t *)0x0008C040);
512 btn2 = sil_reb_mem((uint8_t *)0x0008C040);
513 main_btn1_state = (btn1 & 0x20) != 0;
514 main_btn2_state = (btn2 & 0x80) != 0;
515}
516
517/*
518 * タイマー取得
519 */
520static int main_get_timer()
521{
522 int result = main_timer;
523
524 if((result == TMO_FEVR)
525 || ((main_btn_timer != TMO_FEVR) && (main_btn_timer < result))){
526 result = main_btn_timer;
527 }
528
529 if((result == TMO_FEVR)
530 || ((main_led_timer != TMO_FEVR) && (main_led_timer < result))){
531 result = main_led_timer;
532 }
533
534 if((result == TMO_FEVR)
535 || ((main_rly_timer != TMO_FEVR) && (main_rly_timer < result))){
536 result = main_rly_timer;
537 }
538
539 return result;
540}
541
542/*
543 * 時間経過
544 */
545static void main_progress(int interval)
546{
547 if(main_timer != TMO_FEVR){
548 main_timer -= interval;
549 if(main_timer < 0){
550 main_timer = 0;
551 }
552 }
553
554 if(main_btn_timer != TMO_FEVR){
555 main_btn_timer -= interval;
556 if(main_btn_timer < 0){
557 main_btn_timer = 0;
558 }
559 }
560
561 if(main_led_timer != TMO_FEVR){
562 main_led_timer -= interval;
563 if(main_led_timer < 0){
564 main_led_timer = 0;
565 }
566 }
567
568 if(main_rly_timer != TMO_FEVR){
569 main_rly_timer -= interval;
570 if(main_rly_timer < 0){
571 main_rly_timer = 0;
572 }
573 }
574}
575
576static void main_survey_templ(int no);
577static void main_calc_ave_templ();
578
579/*
580 * Echonet電文受信処理
581 */
582static void main_recv_esv(T_EDATA *esv)
583{
584 ER ret;
585 ID eobjid;
586 uint8_t epc;
587 uint8_t pdc;
588 uint8_t p_edt[256];
589 T_ENUM_EPC enm;
590
591 eobjid = ecn_get_eobj(esv);
592 if(eobjid == EOBJ_NULL){
593 syslog(LOG_ERROR, "ecn_get_eobj");
594 }
595
596 ret = ecn_itr_ini(&enm, esv);
597 if(ret != E_OK){
598 syslog(LOG_ERROR, "ecn_itr_ini");
599 return;
600 }
601
602 for(;;) {
603 while((ret = ecn_itr_nxt(&enm, &epc, &pdc, p_edt)) == E_OK) {
604 switch (epc) {
605 case 0xD6:
606 switch(main_state){
607 case main_state_idle:
608 case main_state_search:
609 /* 温度センサー1温度監視 */
610 main_survey_templ(1);
611 main_state = main_state_survey_01;
612 main_timer = 1000 * 1000;
613 break;
614 }
615 break;
616 case 0xE0:
617 switch(main_state){
618 case main_state_survey_01:
619 /* 温度センサー2温度監視 */
620 main_survey_templ(2);
621 main_state = main_state_survey_02;
622 main_timer = 1000 * 1000;
623 break;
624 case main_state_survey_02:
625 /* 温度センサー3温度監視 */
626 main_survey_templ(3);
627 main_state = main_state_survey_03;
628 main_timer = 1000 * 1000;
629 break;
630 case main_state_survey_03:
631 /* 温度センサー4温度監視 */
632 main_survey_templ(4);
633 main_state = main_state_survey_04;
634 main_timer = 1000 * 1000;
635 break;
636 case main_state_survey_04:
637 /* 温度センサー1~4平均値計算 */
638 main_calc_ave_templ();
639 /* 温度監視休止10秒 */
640 main_state = main_state_interval;
641 main_timer = 10000 * 1000;
642 break;
643 }
644 break;
645 }
646 }
647 if(ret != E_BOVR){
648 syslog(LOG_ERROR, "ecn_itr_nxt");
649 break;
650 }
651 if(enm.is_eof)
652 break;
653 }
654}
655
656/*
657 * 温度センサー温度監視
658 */
659static void main_survey_templ(int no)
660{
661 const ID senserids[] = {
662 TEMP_SENSOR_01_EOBJ,
663 TEMP_SENSOR_02_EOBJ,
664 TEMP_SENSOR_03_EOBJ,
665 TEMP_SENSOR_04_EOBJ
666 };
667 ER ret;
668 T_EDATA *esv;
669
670 /* 温度センサー動作状態取得電文作成 */
671 ret = ecn_esv_get(&esv, senserids[no - 1], 0x80);
672 if(ret != E_OK){
673 syslog(LOG_ERROR, "ecn_esv_get");
674 return;
675 }
676
677 /* 温度計測値取得追加 */
678 ret = ecn_add_epc(esv, 0xE0);
679 if(ret != E_OK){
680 syslog(LOG_ERROR, "ecn_add_epc");
681
682 ret = ecn_rel_esv(esv);
683 if(ret != E_OK){
684 syslog(LOG_ERROR, "ecn_rel_esv");
685 }
686 return;
687 }
688
689 /* 電文送信 */
690 ret = ecn_snd_esv(esv);
691 if(ret != E_OK){
692 syslog(LOG_ERROR, "ecn_snd_esv");
693 }
694}
695
696/*
697 * 温度センサー1~4平均値計算
698 */
699static void main_calc_ave_templ()
700{
701 int count = 0;
702 int templ = 0;
703
704 if(temp_sensor_01_data.property80 == 0x30){
705 templ += ((((uint16_t)temp_sensor_01_data.propertyE0) & 0xFF) << 8)
706 | ((((uint16_t)temp_sensor_01_data.propertyE0) & 0xFF00) >> 8);
707 count++;
708 }
709 if(temp_sensor_02_data.property80 == 0x30){
710 templ += ((((uint16_t)temp_sensor_02_data.propertyE0) & 0xFF) << 8)
711 | ((((uint16_t)temp_sensor_02_data.propertyE0) & 0xFF00) >> 8);
712 count++;
713 }
714 if(temp_sensor_03_data.property80 == 0x30){
715 templ += ((((uint16_t)temp_sensor_03_data.propertyE0) & 0xFF) << 8)
716 | ((((uint16_t)temp_sensor_03_data.propertyE0) & 0xFF00) >> 8);
717 count++;
718 }
719 if(temp_sensor_04_data.property80 == 0x30){
720 templ += ((((uint16_t)temp_sensor_04_data.propertyE0) & 0xFF) << 8)
721 | ((((uint16_t)temp_sensor_04_data.propertyE0) & 0xFF00) >> 8);
722 count++;
723 }
724
725 if(count > 0){
726 templ = templ / count;
727 if(templ < -2732)
728 main_ave_templ = 0x8000;
729 else if(templ > 32766)
730 main_ave_templ = 0x7FFF;
731 else
732 main_ave_templ = (int16_t)templ;
733
734 /* FANが停止中の場合 */
735 if(!main_tmp_fan_on){
736 if(main_ave_templ > (10 * home_air_conditioner_data.propertyB3 + 5)){
737 main_tmp_fan_on = true;
738
739 /* リレー出力をON */
740 if (!main_ctl_fan_on)
741 main_rly_onoff(true);
742 }
743 }
744 /* FANが稼働中の場合 */
745 else{
746 if(main_ave_templ < (10 * home_air_conditioner_data.propertyB3 - 5)){
747 main_tmp_fan_on = false;
748
749 /* リレー出力をOFF */
750 if (!main_ctl_fan_on)
751 main_rly_onoff(false);
752 }
753 }
754 }
755 else
756 main_ave_templ = 0x7FFF;
757}
758
759/*
760 * 応答電文待ちの割り込み処理
761 */
762static void main_break_wait(uint8_t *brkdat, int32_t len)
763{
764 switch(main_led_state){
765 case main_led_state_idle:
766 switch (brkdat[0]) {
767 case 0x01:
768 // Link up/down
769 break;
770 case 0x80:
771 case 0xB0:
772 case 0xB3:
773 if(home_air_conditioner_data.property80 == 0x30)
774 main_led_state = main_led_state_on_o;
775 else
776 main_led_state = main_led_state_off_o;
777 main_led_timer = 0;
778 break;
779 }
780 break;
781 default:
782 main_led_update = true;
783 break;
784 }
785
786 /* 運転モードが送風の場合、温度によらずFANをON */
787 if (*brkdat == 0xB0) {
788 bool_t prev = main_ctl_fan_on;
789 main_ctl_fan_on = home_air_conditioner_data.propertyB0 == 0x45;
790
791 if (prev != main_ctl_fan_on) {
792 if (main_ctl_fan_on) {
793 /* リレー出力をON */
794 if (!main_tmp_fan_on)
795 main_rly_onoff(true);
796 }
797 else {
798 /* リレー出力をOFF */
799 if (!main_tmp_fan_on)
800 main_rly_onoff(false);
801 }
802 }
803 }
804}
805
806static void main_ontimer();
807static void main_btn_ontimer();
808static void main_led_ontimer();
809static void main_rly_ontimer();
810
811/*
812 * タイムアウト処理
813 */
814static void main_timeout()
815{
816 if(main_timer == 0){
817 main_ontimer();
818 }
819
820 if(main_btn_timer == 0){
821 main_btn_ontimer();
822 }
823
824 if(main_led_timer == 0){
825 main_led_ontimer();
826 }
827
828 if(main_rly_timer == 0){
829 main_rly_ontimer();
830 }
831}
832
833static void main_search();
834
835static void main_ontimer()
836{
837 switch(main_state){
838 case main_state_idle:
839 case main_state_search:
840 /* 温度センサー再検索 */
841 main_search();
842 main_state = main_state_search;
843 main_timer = 5000 * 1000;
844 break;
845 case main_state_survey_01:
846 /* 応答がない場合動作状態OFFとする */
847 temp_sensor_01_data.property80 = 0x31;
848 /* 温度センサー2温度監視 */
849 main_survey_templ(2);
850 main_state = main_state_survey_02;
851 main_timer = 1000 * 1000;
852 break;
853 case main_state_survey_02:
854 /* 応答がない場合動作状態OFFとする */
855 temp_sensor_02_data.property80 = 0x31;
856 /* 温度センサー3温度監視 */
857 main_survey_templ(3);
858 main_state = main_state_survey_03;
859 main_timer = 1000 * 1000;
860 break;
861 case main_state_survey_03:
862 /* 応答がない場合動作状態OFFとする */
863 temp_sensor_03_data.property80 = 0x31;
864 /* 温度センサー4温度監視 */
865 main_survey_templ(4);
866 main_state = main_state_survey_04;
867 main_timer = 1000 * 1000;
868 break;
869 case main_state_survey_04:
870 /* 応答がない場合動作状態OFFとする */
871 temp_sensor_04_data.property80 = 0x31;
872 /* 温度センサー1~4平均値計算 */
873 main_calc_ave_templ();
874 /* 温度監視休止10秒 */
875 main_state = main_state_interval;
876 main_timer = 10000 * 1000;
877 break;
878 case main_state_interval:
879 /* 温度センサー1温度監視 */
880 main_survey_templ(1);
881 main_state = main_state_survey_01;
882 main_timer = 1000 * 1000;
883 break;
884 }
885}
886
887static void main_search()
888{
889 ER ret;
890 T_EDATA *esv;
891
892 /* 温度センサー検索 */
893 ret = ecn_esv_inf_req(&esv, EOBJ_NULL, 0xD6);
894 if(ret != E_OK){
895 syslog(LOG_ERROR, "ecn_esv_inf_req");
896 return;
897 }
898
899 /* 電文送信 */
900 ret = ecn_snd_esv(esv);
901 if(ret != E_OK){
902 syslog(LOG_ERROR, "ecn_snd_esv");
903 }
904}
905
906static void main_btn1_change(bool_t push);
907static void main_btn2_change(bool_t push);
908
909static void main_btn_ontimer()
910{
911 uint8_t btn1, btn2;
912
913 /* 10ms後にボタン状態を確認 */
914 main_btn_timer = 10 * 1000;
915
916 /* ボタン状態読み込み */
917 btn1 = sil_reb_mem((uint8_t *)0x0008C040);
918 btn2 = sil_reb_mem((uint8_t *)0x0008C040);
919
920 /* ボタン1の処理 */
921 if(((btn1 & 0x20) != 0) && !main_btn1_state){
922 main_btn1_count++;
923 if(main_btn1_count > 10){
924 main_btn1_count = 0;
925 main_btn1_state = true;
926
927 main_btn1_change(true);
928 }
929 }
930 else if(((btn1 & 0x20) == 0) && main_btn1_state){
931 main_btn1_count++;
932 if(main_btn1_count > 10){
933 main_btn1_count = 0;
934 main_btn1_state = false;
935
936 main_btn1_change(false);
937 }
938 }
939
940 /* ボタン2の処理 */
941 if(((btn2 & 0x80) != 0) && !main_btn2_state){
942 main_btn2_count++;
943 if(main_btn2_count > 10){
944 main_btn2_count = 0;
945 main_btn2_state = true;
946
947 main_btn2_change(true);
948 }
949 }
950 else if(((btn2 & 0x80) == 0) && main_btn2_state){
951 main_btn2_count++;
952 if(main_btn2_count > 10){
953 main_btn2_count = 0;
954 main_btn2_state = false;
955
956 main_btn2_change(false);
957 }
958 }
959}
960
961uint8_t led_num[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };
962uint8_t led_onf[] = { 0xA3, 0xAB, 0x8E };
963uint8_t led_abcdef[] = { 0xF7, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E };
964
965static void main_led_ontimer()
966{
967 int temp;
968
969 switch(main_led_state){
970 case main_led_state_idle:
971 /* 7segに' 'を表示 */
972 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
973 main_led_timer = TMO_FEVR;
974 return;
975 case main_led_state_on_o:
976 /* 7segに'o'を表示 */
977 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[0]);
978 main_led_state = main_led_state_on_n;
979 break;
980 case main_led_state_on_n:
981 /* 7segに'n'を表示 */
982 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[1]);
983 main_led_state = main_led_state_space1;
984 break;
985 case main_led_state_off_o:
986 /* 7segに'o'を表示 */
987 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[0]);
988 main_led_state = main_led_state_off_f1;
989 break;
990 case main_led_state_off_f1:
991 /* 7segに'f'を表示 */
992 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[2]);
993 main_led_state = main_led_state_off_f2;
994 break;
995 case main_led_state_off_f2:
996 /* 7segに'f'を表示 */
997 sil_wrb_mem((uint8_t *)0x0008C02D, led_onf[2]);
998 main_led_state = main_led_state_space1;
999 break;
1000 case main_led_state_space1:
1001 /* 7segに' 'を表示 */
1002 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1003 main_led_state = main_led_state_templ_10;
1004 break;
1005 case main_led_state_templ_10:
1006 temp = (home_air_conditioner_data.propertyB3 / 10) % 10;
1007 if(temp < 0)
1008 temp = -temp;
1009 /* 7segに温度設定10の位を表示 */
1010 sil_wrb_mem((uint8_t *)0x0008C02D, led_num[temp]);
1011 main_led_state = main_led_state_templ_1;
1012 break;
1013 case main_led_state_templ_1:
1014 temp = (home_air_conditioner_data.propertyB3 / 1) % 10;
1015 if(temp < 0)
1016 temp = -temp;
1017 /* 7segに温度設定1の位を表示 */
1018 sil_wrb_mem((uint8_t *)0x0008C02D, led_num[temp] & (~0x80));
1019 main_led_state = main_led_state_space2;
1020 break;
1021 case main_led_state_space2:
1022 /* 7segに' 'を表示 */
1023 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1024 main_led_state = main_led_state_ave_templ_10;
1025 break;
1026 case main_led_state_ave_templ_10:
1027 temp = (main_ave_templ / 100) % 10;
1028 if(temp < 0)
1029 temp = -temp;
1030 /* 7segに温度計測値10の位を表示 */
1031 sil_wrb_mem((uint8_t *)0x0008C02D, led_num[temp]);
1032 main_led_state = main_led_state_ave_templ_1;
1033 break;
1034 case main_led_state_ave_templ_1:
1035 temp = (main_ave_templ / 10) % 10;
1036 if(temp < 0)
1037 temp = -temp;
1038 /* 7segに温度計測値1の位を表示 */
1039 sil_wrb_mem((uint8_t *)0x0008C02D, led_num[temp] & (~0x80));
1040 main_led_state = main_led_state_space3;
1041 break;
1042 case main_led_state_space3:
1043 /* 7segに' 'を表示 */
1044 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1045 main_led_state = main_led_state_mode;
1046 break;
1047 case main_led_state_mode:
1048 temp = home_air_conditioner_data.propertyB0 - 0x40;
1049 /* 7segに運転モードを表示 */
1050 sil_wrb_mem((uint8_t *)0x0008C02D, led_abcdef[temp]);
1051 main_led_state = main_led_state_space4;
1052 break;
1053 case main_led_state_space4:
1054 if(home_air_conditioner_data.property80 == 0x30)
1055 /* 7segに'.'を表示 */
1056 sil_wrb_mem((uint8_t *)0x0008C02D, 0x7F);
1057 else
1058 /* 7segに' 'を表示 */
1059 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1060
1061 if(main_led_update){
1062 main_led_update = false;
1063
1064 if(home_air_conditioner_data.property80 == 0x30)
1065 main_led_state = main_led_state_on_o;
1066 else
1067 main_led_state = main_led_state_off_o;
1068 }
1069 else{
1070 main_led_state = main_led_state_idle;
1071 main_led_timer = TMO_FEVR;
1072 return;
1073 }
1074 break;
1075 default:
1076 /* 7segに' 'を表示 */
1077 sil_wrb_mem((uint8_t *)0x0008C02D, 0xFF);
1078 main_led_state = main_led_state_idle;
1079 main_led_timer = TMO_FEVR;
1080 return;
1081 }
1082
1083 main_led_timer = 500 * 1000;
1084}
1085
1086uint8_t main_templ = 20; /* 20℃ */
1087
1088/*
1089 * ボタン1状態変化処理
1090 */
1091static void main_btn1_change(bool_t push)
1092{
1093 ER ret;
1094 T_EDATA *esv;
1095 uint8_t p_edt[1];
1096
1097 /* 押されて戻った時に処理する */
1098 if(push)
1099 return;
1100
1101 /* 設定温度 */
1102 if(main_templ > 0)
1103 main_templ--; /* - 1℃ */
1104
1105 p_edt[0] = main_templ;
1106
1107 /* プロパティ設定電文作成 */
1108 ret = ecn_esv_seti(&esv, HOME_AIR_CONDITIONER_EOBJ, 0xB3, 1, p_edt);
1109 if(ret != E_OK){
1110 syslog(LOG_ERROR, "ecn_esv_seti");
1111 return;
1112 }
1113
1114 /* 電文送信 */
1115 ecn_snd_esv(esv);
1116 if(ret != E_OK){
1117 syslog(LOG_ERROR, "ecn_snd_esv");
1118 }
1119}
1120
1121/*
1122 * ボタン2状態変化処理
1123 */
1124static void main_btn2_change(bool_t push)
1125{
1126 ER ret;
1127 T_EDATA *esv;
1128 uint8_t p_edt[1];
1129
1130 /* 押されて戻った時に処理する */
1131 if(push)
1132 return;
1133
1134 /* 設定温度 */
1135 if(main_templ < 50)
1136 main_templ++; /* + 1.0℃ */
1137
1138 p_edt[0] = main_templ;
1139
1140 /* プロパティ設定電文作成 */
1141 ret = ecn_esv_seti(&esv, HOME_AIR_CONDITIONER_EOBJ, 0xB3, 1, p_edt);
1142 if(ret != E_OK){
1143 syslog(LOG_ERROR, "ecn_esv_seti");
1144 return;
1145 }
1146
1147 /* 電文送信 */
1148 ecn_snd_esv(esv);
1149 if(ret != E_OK){
1150 syslog(LOG_ERROR, "ecn_snd_esv");
1151 }
1152}
1153#if 1
1154static void main_rly_onoff(bool_t onoff)
1155{
1156 if(onoff){
1157 /* リレー出力をON */
1158 sil_wrb_mem((uint8_t *)0x0008C022, sil_reb_mem((uint8_t *)0x0008C022) | 0x20);
1159 }
1160 else{
1161 /* リレー出力をOFF */
1162 sil_wrb_mem((uint8_t *)0x0008C022, sil_reb_mem((uint8_t *)0x0008C022) & ~0x20);
1163 }
1164}
1165
1166static void main_rly_ontimer()
1167{
1168 main_rly_timer = TMO_FEVR;
1169}
1170#else
1171static void main_rly_onoff(bool_t onoff)
1172{
1173 /* リレー出力をON */
1174 sil_wrb_mem((uint8_t *)0x0008C022, sil_reb_mem((uint8_t *)0x0008C022) | 0x20);
1175
1176 /* 500msパルス出力 */
1177 main_rly_state = main_rly_state_on;
1178 main_rly_timer = 500;
1179}
1180
1181/*
1182 * リレーパルス出力処理
1183 */
1184static void main_rly_ontimer()
1185{
1186 switch(main_rly_state)
1187 {
1188 case main_rly_state_off:
1189 main_rly_timer = TMO_FEVR;
1190 break;
1191 case main_rly_state_on:
1192 /* リレー出力をOFF */
1193 sil_wrb_mem((uint8_t *)0x0008C022, sil_reb_mem((uint8_t *)0x0008C022) & ~0x20);
1194
1195 main_rly_state = main_rly_state_off;
1196 main_rly_timer = TMO_FEVR;
1197 break;
1198 }
1199}
1200#endif
Note: See TracBrowser for help on using the repository browser.