twl_mcu/LEDs.c
2024-12-17 04:24:29 -05:00

419 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "incs.h"
#define led_pwr_G_duty CMP11
#define led_pwr_R_duty CMP10
#define led_wifi_duty CMP50
extern u8 vregs[];
extern u8 tsk_interval_power_led;
extern u8 tsk_interval_sw_vol;
extern u8 tsk_interval_wifi_led;
extern u8 tsk_interval_cnt_cam_led;
u8 wifi_tx;
extern u8 battLvl;
u8 batt_rest;
u8 led_G_brightness_to;
u8 led_R_brightness_to;
extern bit flg_BLChanged;
// 0 1 3 7 B F
const u8 LED_G_BRIGHTNESS[] = { 0, 0, 0, 255, 255, 255 };
const u8 LED_R_BRIGHTNESS[] = { 255, 255, 255, 0, 0, 0 };
static u8 slp_state; // 変数のスコープに泣く
#ifdef debug_codes
extern bit pwon_wt_sel;
extern bit pwon_wt_vol_p;
extern bit pwon_wt_vol_n;
#endif
/******************************************************************************
電源LED管理
この辺の明るさの変化とかは tsk_interval_power_led による
 何かみにくい(醜い/見にくい)コードだ
******************************************************************************/
void tsk_power_led(){
// PM_OFFで0にグラデしようかと思ったけど、PM_OFFが短すぎた(約100ms)
if( PM_OFF ){
TMHE1 = 0; /* stop TimerH0 */
TOEN1 = 0; /* disable output */
led_G_pwm;
TMHE0 = 0; /* stop TimerH0 */
TOEN0 = 0; /* disable output */
led_R_pwm;
}else{
// 通常運転
if( PM_SLP == 0 ){
tsk_interval_power_led = 30;
power_led_status_watch_awake();
}else{
// スリープ
tsk_interval_power_led = 160;
power_led_status_watch_sleep();
}
}
}
/******************************************************************************
電源LEDの明るさを目標値にグラデーションしてく
帰り値3 : ともにゼロ
******************************************************************************/
void led_pwm_GR_grad(){
static u8 delay = 0;
if( PM_SLP && ( delay < 1 ) ){ // クラデの速度調節ウェイト。やりたくなかった...。
delay++;
return;
}
delay = 0;
if( led_pwr_G_duty != led_G_brightness_to ){
led_pwr_G_duty += ( led_pwr_G_duty < led_G_brightness_to )? 1: -1;
}
if( led_pwr_G_duty == 0 ){
TMHE1 = 0; /* stop TimerH0 */
TOEN1 = 0; /* disable output */
led_G_pwm;
}else if( led_pwr_G_duty == 255 ){
led_G_on;
TMHE1 = 0; /* stop TimerH0 */
TOEN1 = 0; /* disable output */
}else{
led_G_pwm;
TOEN1 = 1; /* enable output */
TMHE1 = 1; /* start TimerH0 */
}
if( led_pwr_R_duty != led_R_brightness_to ){
led_pwr_R_duty += ( led_pwr_R_duty < led_R_brightness_to )? 1: -1;
}
if( led_pwr_R_duty == 0 ){
TMHE0 = 0; /* stop TimerH0 */
TOEN0 = 0; /* disable output */
led_R_pwm;
}else if( led_pwr_R_duty == 255 ){
led_R_on;
TMHE0 = 0; /* stop TimerH0 */
TOEN0 = 0; /* disable output */
}else{
led_R_pwm;
TOEN0 = 1; /* enable output */
TMHE0 = 1; /* start TimerH0 */
}
}
/******************************************************************************
 通常運転時。
電源LEDの明るさ変更をもうちょっと賢くやらせる
******************************************************************************/
static void power_led_status_watch_awake(){
static u8 state; // 明滅用カウンタ
u8 led_dim;
slp_state = 0;
if( battLvl >= 2 ){
// レベル 3,7,B,F
// BLに合わせて電源LED減光
led_G_brightness_to = ( LED_G_BRIGHTNESS[ battLvl ] >> ( 4 - vregs[ REG_INT_ADRS_BL ] ) );
led_R_brightness_to = ( LED_R_BRIGHTNESS[ battLvl ] >> ( 4 - vregs[ REG_INT_ADRS_BL ] ) );
if( flg_BLChanged == 1 ){
flg_BLChanged = 0;
led_pwr_G_duty = led_G_brightness_to;
led_pwr_R_duty = led_R_brightness_to;
}
state = 0;
}else{
// 点滅
led_pwr_G_duty = led_G_brightness_to = 0;
if( state == 0 ){
led_pwr_R_duty = ( LED_R_BRIGHTNESS[0] >> ( 4 - vregs[ REG_INT_ADRS_BL ] ) ); // 点
led_R_brightness_to = led_pwr_R_duty;
}else if( state == 2 ){
led_pwr_R_duty = 0; // 滅
led_R_brightness_to = 0;
}
state++;
if( state == 4 ){
state = 0;
}
}
return;
}
/******************************************************************************
sleep時の電源蛍
******************************************************************************/
static void power_led_status_watch_sleep(){
switch( slp_state ){
// 上げていく
case( 2 ):
case( 6 ):
case( 10 ):
case( 14 ):
if( battLvl > 2 ){
led_G_brightness_to = 40;
led_R_brightness_to = 0;
}else{
led_G_brightness_to = 0;
led_R_brightness_to = 40;
}
break;
// 下げていく
case( 0 ):
case( 4 ):
case( 8 ):
case( 12 ):
case( 16 ):
if( battLvl > 2 ){
led_G_brightness_to = 5;
led_R_brightness_to = 0;
}else{
led_G_brightness_to = 0;
led_R_brightness_to = 5;
}
break;
default:
// 現状を保持 何もしない
break;
}
slp_state++;
if( slp_state == 18 ){
slp_state = 0;
}
}
/******************************************************************************
カメラLED。
******************************************************************************/
void set_camled(){
static camLed_mode reg_cam_old;
if( reg_cam_old != camLed_blink ){
tsk_cam_led();
tsk_interval_cnt_cam_led = 0;
}
reg_cam_old = ( vregs[REG_INT_ADRS_CAM] & 0x03 );
}
void set_camled_stop(){
if( vregs[ REG_INT_ADRS_BATT_INFO ] != BATT_IS ){
#ifdef after_x6
led_cam = 0;
#else
IS_led_cam = 0;
#endif
}else{
IS_led_cam = 0;
}
}
// bit型のポインタ というのはやっぱりないらしい。
void tsk_cam_led(){
if( PM_SLP ){
return;
}
#ifdef after_x6
if( vregs[ REG_INT_ADRS_BATT_INFO ] != BATT_IS ){
switch( vregs[REG_INT_ADRS_CAM] & 0x03 ){
case ( 1 ): // 点灯
led_cam = 1;
break;
case( 2 ): // 点滅
led_cam = ~led_cam;
break;
default: // 消灯
led_cam = 0;
break;
}
// 赤箱対応 //
}
else
#endif // 赤箱と、X6より古いボード
{
switch( vregs[REG_INT_ADRS_CAM] & 0x03 ){
case ( 1 ): // 点灯
IS_led_cam = 1;
break;
case( 2 ): // 点滅
IS_led_cam = ~IS_led_cam;
break;
default: // 消灯
IS_led_cam = 0;
break;
}
}
}
/******************************************************************************
WiFiLED
起きるとき、寝るとき
******************************************************************************/
void trig_to_sleep_wifiLed(){
if( reg_wifi_led != 0 ){
led_wifi = 0;
CR50 = 5;
TM50_Start();
}
}
void trig_to_wake_wifiLed(){
if( reg_wifi_led != 0 ){
TM50_Stop();
led_wifi = 0;
}
}
/******************************************************************************
WiFiLED。
 動きがあるとうっとおしいよね...ほぼ常時点灯にするよね...。
→ 送信するときは点滅だって...。
■ 割り込みそのものは使っていません!
  条件さえそろえば割り込み待機フラグは立ち、マスクが解除されない限り、割り込み
  ルーチンには飛びません。
  短いパルスをポーリングで捕まえるのがつらいので、ラッチとして使ってます。
  また、割り込みを使いたくないのでこんな実装になっています。
******************************************************************************/
void tsk_wifi_led(){ // 10Hzで呼ばれます
static u8 state;
// フライトモードではNTRパルスが出ても電波でない→
// フライトレジスタ見なくてはならない
if( reg_wifi_led == 0 ){
TM50_Stop();
led_wifi = 0;
wifi_tx = 0;
return;
}
// スリープ時
if( PM_SLP == 1 ){
// タスクで回すことはない trig_to_sleep_wifiLed() で減光状態にしてる
return;
}
// 短いパルスを捕まえるために、割り込みフラグを見る
if( ( PIF2 == 1 ) || ( PIF3 == 1 ) ){
wifi_tx = 2;
PIF2 = 0; // アセンブル結果はビット操作になってるので問題なし
PIF3 = 0;
}
#ifdef debug_codes
#ifdef wifi_led_on_func
if( pwon_wt_sel ){
if( n_key_func == 0 ){
wifi_tx = 2;
}
}
#endif
#endif
if( reg_wifi_led_blink != 0 ){
if( wifi_tx != 0 ){ // TX active
switch( state ){
case( 1 ):
case( 3 ):
case( 5 ):
led_wifi = 0;
TM50_Stop();
break;
default:
if( vregs[ REG_INT_ADRS_BL ] >= 4 ){
led_wifi = 1;
TM50_Stop();
}else{
CR50 = ( 255 >> ( 4 - ( vregs[ REG_INT_ADRS_BL ] ) ) );
TM50_Start();
led_wifi = 0;
}
} // switch
state++;
if( state == 32 ){
state = 0;
wifi_tx--;
}
return;
} // if
}else{
wifi_tx = 0;
}
///// 点滅パターンここまで /////
state = 0;
// psy-no break //
if( reg_wifi_led != 0 ){ // 無線有効
if( vregs[ REG_INT_ADRS_BL ] >= 4 ){
led_wifi = 1;
TM50_Stop();
}else{
CR50 = ( 255 >> ( 4 - vregs[ REG_INT_ADRS_BL ] ) );
TM50_Start();
led_wifi = 0;
}
}
}
void set_powLED_mode(){
if( ( vregs[ REG_INT_ADRS_POWER_LED ] & 0x03 ) == 0x00 ){ // テストモード終了
led_G_brightness_to = LED_G_BRIGHTNESS[ battLvl ];
led_R_brightness_to = LED_R_BRIGHTNESS[ battLvl ];
led_pwr_G_duty = 127;
led_pwr_R_duty = 127;
return;
}else{
if( ( vregs[ REG_INT_ADRS_POWER_LED ] & 0x01 ) != 0 ){ // R
led_R_on;
TMHE0 = 0; /* stop TimerH0 */
TOEN0 = 0; /* disable output */
}else{
TMHE0 = 0; /* stop TimerH0 */
TOEN0 = 0; /* disable output */
led_R_pwm;
}
if( ( vregs[ REG_INT_ADRS_POWER_LED ] & 0x02 ) != 0 ){ // B
led_G_on;
TMHE1 = 0; /* stop TimerH0 */
TOEN1 = 0; /* disable output */
}else{
TMHE1 = 0; /* stop TimerH0 */
TOEN1 = 0; /* disable output */
led_G_pwm;
}
}
}