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

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

syscallが関数呼びになるよう変更
他更新

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