mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-18 16:45:33 -04:00

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@539 013db118-44a6-b54f-8bf7-843cb86687b1
247 lines
7.2 KiB
C
247 lines
7.2 KiB
C
/* ========================================================
|
|
スイッチ
|
|
・HOME
|
|
・POWER
|
|
・WiFi
|
|
の監視タスク
|
|
|
|
$Id$
|
|
======================================================== */
|
|
#ifndef _WIN32
|
|
|
|
#pragma SFR
|
|
#pragma NOP
|
|
#pragma HALT
|
|
#pragma STOP
|
|
|
|
#endif
|
|
|
|
#include "incs.h"
|
|
|
|
#include "i2c_twl.h"
|
|
#include "i2c_ctr.h"
|
|
#include "led.h"
|
|
#include "pm.h"
|
|
#include "rtc.h"
|
|
#include "sw.h"
|
|
|
|
|
|
//=========================================================
|
|
/*
|
|
vreg_ctrから読みたいのでヘッダへ
|
|
#define INTERVAL_TSK_SW
|
|
#define CLICK_THRESHOLD
|
|
|
|
#define HOLD_THREASHOLD
|
|
#define FORCEOFF_THREASHOLD
|
|
*/
|
|
#define TIME_MUKAN ( u8)( 300 / INTERVAL_TSK_SW )
|
|
#define TIME_MUKAN_PWSW_RED_TRIAL (u16)( 15000 / INTERVAL_TSK_SW ) // 試遊台、homeマスク時間
|
|
|
|
//=========================================================
|
|
u16 SW_pow_count;
|
|
bit SW_pow_mask;
|
|
|
|
static u8 SW_home_count, SW_wifi_count, SW_home_count_rel;
|
|
static u8 sw_wifi_mukan_time;
|
|
|
|
u16 off_timeout_timer;
|
|
|
|
static u16 sw_pwsw_mukan_time;
|
|
|
|
|
|
//=========================================================
|
|
static void chk_pow_sw();
|
|
static void chk_wifi_sw();
|
|
|
|
|
|
|
|
/********************************************//**
|
|
押した時間を数える。押しっぱなしでも0に戻らない
|
|
|
|
maskが非0の時は、一度離すまで無視する
|
|
***********************************************/
|
|
#define count_sw_n( sw, counter, mask ) \
|
|
{ \
|
|
if( sw ){ \
|
|
mask = 0; \
|
|
counter = 0; \
|
|
}else{ \
|
|
if( mask != 0 ){ \
|
|
counter = 0; \
|
|
}else{ \
|
|
counter ++; \
|
|
if( counter == 0 ) counter = -1; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
/********************************************//**
|
|
クリックしたか(チャタリング除去)。必要に応じて割り込み
|
|
***********************************************/
|
|
#define chk_clicked( button, count, irq_bit_name ) \
|
|
if( !button ) \
|
|
{ \
|
|
if( count < CLICK_THRESHOLD ) \
|
|
{ \
|
|
count ++; \
|
|
if( count == CLICK_THRESHOLD ) \
|
|
{ \
|
|
count ++; \
|
|
set_irq( VREG_C_IRQ0, irq_bit_name ); \
|
|
} \
|
|
} \
|
|
} \
|
|
else \
|
|
{ \
|
|
count = 0; \
|
|
}
|
|
|
|
|
|
|
|
/********************************************//**
|
|
スイッチの監視
|
|
|
|
チャタリングをはねたり、長押しや、押したトリガなどの検出を行う
|
|
***********************************************/
|
|
void tsk_sw( )
|
|
{
|
|
static u8 task_interval;
|
|
|
|
if( system_status.pwr_state == OFF_TRIG )
|
|
{
|
|
SW_pow_count = 0; // 電源投入に備えてクリア
|
|
// task_interval = 0;
|
|
}
|
|
|
|
if( system_status.pwr_state != ON_CHECK ) // 測定時間(PWSW_POWON_TIME)が短いのでプリスケーラ無し でないとチャタ除去があまりきかない
|
|
{
|
|
if( task_interval != 0 )
|
|
{
|
|
task_interval--;
|
|
return;
|
|
// おしまい
|
|
}
|
|
|
|
task_interval = (u8)( INTERVAL_TSK_SW / SYS_INTERVAL_TICK ) -1; // プリスケーラ代わりに使ってますね…
|
|
// -1はポストデクリメントのための調整
|
|
}
|
|
|
|
// 8ms 毎にきます
|
|
switch( system_status.pwr_state )
|
|
{
|
|
case( ON ):
|
|
case( SLEEP ):
|
|
chk_wifi_sw();
|
|
if( !SHELL_OPEN )
|
|
{
|
|
break;
|
|
}
|
|
// else 節の時は fall through (蓋閉じならpwswチェックをスキップ)。
|
|
// 実装が良くない気もするが...
|
|
|
|
// HOME sw //
|
|
chk_clicked( SW_HOME_n, SW_home_count, REG_BIT_SW_HOME_CLICK );
|
|
chk_clicked( !SW_HOME_n, SW_home_count_rel, REG_BIT_SW_HOME_RELEASE );
|
|
/* fall through */
|
|
|
|
case( OFF ):
|
|
case( ON_CHECK ):
|
|
chk_pow_sw();
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/********************************************//**
|
|
電源スイッチの監視
|
|
試遊台、ホームメニューには入れないようにしたくて、自動起動にしてあるそうだが
|
|
mmen の不具合でホームメニューにいけてしまう事がある(市場クレーム有り)
|
|
なのでマイコンでその操作をマスクする。
|
|
***********************************************/
|
|
static void chk_pow_sw()
|
|
{
|
|
// 実機の場合
|
|
if( ! system_status.taikendai )
|
|
{
|
|
if( SW_pow_count == ( TIME_PWSW_CLICK ) ) // クリック時間に到達
|
|
{
|
|
if( is_wifi_calib_resets_ast ) // wifi キャリブレーション時なら、SoCに通知せずにoffに遷移
|
|
{
|
|
system_status.pwr_state = OFF_TRIG;
|
|
}
|
|
set_irq( VREG_C_IRQ0, REG_BIT_SW_POW_CLICK );
|
|
}
|
|
else if( SW_pow_count == ( HOLD_THREASHOLD ) ) // 長押しに到達
|
|
{
|
|
set_irq( VREG_C_IRQ0, REG_BIT_SW_POW_HOLD );
|
|
if( off_timeout_timer == 0 ) // 強制電源断カウントダウン開始、何度も発動しないように。
|
|
{
|
|
off_timeout_timer = vreg_ctr[ VREG_C_OFF_DELAY ] * 16;
|
|
}
|
|
}
|
|
|
|
if( off_timeout_timer != 0 ) // 長押し割り込み後、タイムアウトで強制オフ。
|
|
{
|
|
off_timeout_timer --;
|
|
if( off_timeout_timer == 0 )
|
|
{
|
|
force_off = true;
|
|
}
|
|
}
|
|
|
|
}else{
|
|
// スタンドアロン試遊台
|
|
if( SW_pow_count == ( TIME_PWSW_CLICK ) )
|
|
{
|
|
if( sw_pwsw_mukan_time == 0 )
|
|
{
|
|
set_irq( VREG_C_IRQ0, REG_BIT_SW_POW_CLICK );
|
|
// いやなタイミングでPWSWを押すとHOMEメニューに入れてしまうのを回避するためのマスクタイマー
|
|
sw_pwsw_mukan_time = TIME_MUKAN_PWSW_RED_TRIAL;
|
|
}
|
|
}
|
|
else if( SW_pow_count == ( HOLD_THREASHOLD ) )
|
|
{
|
|
force_off = true;
|
|
}
|
|
|
|
if( sw_pwsw_mukan_time != 0 )
|
|
{
|
|
sw_pwsw_mukan_time--;
|
|
}
|
|
}
|
|
count_sw_n( SW_POW_n, SW_pow_count, SW_pow_mask ); // ボタン押し時間のカウント
|
|
}
|
|
|
|
|
|
|
|
/********************************************//**
|
|
wifi スイッチの監視
|
|
最悪な実装なのはわかっているが、市場に出てしまった不良スイッチを救うため
|
|
…そもそも他のスイッチも全部こうするのがいいんだろうけど
|
|
***********************************************/
|
|
static void chk_wifi_sw()
|
|
{
|
|
// wifi sw //
|
|
if( sw_wifi_mukan_time != 0 )
|
|
{
|
|
sw_wifi_mukan_time--;
|
|
}
|
|
else
|
|
{
|
|
chk_clicked( SW_WIFI_n, SW_wifi_count, REG_BIT_SW_WIFI_CLICK );
|
|
if( SW_wifi_count == CLICK_THRESHOLD +1 ) // 押した判定発生!
|
|
{
|
|
sw_wifi_mukan_time = TIME_MUKAN;
|
|
}
|
|
}
|
|
}
|
|
|