mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-19 00:55:37 -04:00

拡張レジスタ・色テーブルをもらう部分を書く前に一度コミット 一部の割り込みをレジスタバンク使用するように変更。 効果あるか? コンパイラのワーニング対応 バッテリ残量で割り込み(暫定3%、8% 有用か?) git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@128 013db118-44a6-b54f-8bf7-843cb86687b1
564 lines
12 KiB
C
564 lines
12 KiB
C
/* ========================================================
|
||
LED.c
|
||
|
||
======================================================== */
|
||
#pragma sfr
|
||
|
||
|
||
#include "incs.h"
|
||
#include "led.h"
|
||
|
||
|
||
|
||
// ========================================================
|
||
// TPS0
|
||
#define BIT_PRS012 ( 1 << 2 )
|
||
#define BIT_PRS002 ( 1 << 6 )
|
||
|
||
// TMR0
|
||
#define BIT_CKS0 15
|
||
#define BIT_CCS0 12
|
||
#define BIT_MASTER0 11
|
||
#define BIT_STS0 8
|
||
#define BIT_CIS0 6
|
||
#define BIT_MD123 1
|
||
#define BIT_MD0 0
|
||
|
||
// ========================================================
|
||
static void led_pow_normal( );
|
||
static void led_pow_hotaru( );
|
||
|
||
|
||
|
||
// ========================================================
|
||
// お知らせLEDのパターンを流し込んでもらう
|
||
typedef struct{
|
||
u8 red;
|
||
u8 grn;
|
||
u8 blu;
|
||
}st_info_LED_ptn;
|
||
|
||
typedef struct{
|
||
st_info_LED_ptn ptn[32];
|
||
u8 option1;
|
||
u8 option2;
|
||
u8 option3;
|
||
u8 option4;
|
||
}st_info_LED;
|
||
|
||
st_info_LED info_LED;
|
||
|
||
|
||
|
||
#define led_fade_to( now, goal ) now = fade_to( now, goal )
|
||
|
||
|
||
|
||
/* ========================================================
|
||
reg_ledをgoalになるまでグラデーションする
|
||
とりあえず、ステップ固定
|
||
====================================================== */
|
||
u8 fade_to( u8 now, u8 goal )
|
||
{
|
||
if( now != goal )
|
||
{
|
||
if( now > goal )
|
||
{
|
||
now -= 1;
|
||
}
|
||
else
|
||
{
|
||
now += 1;
|
||
}
|
||
}
|
||
return( now );
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
// ========================================================
|
||
|
||
|
||
// ========================================================
|
||
void LED_init( )
|
||
{
|
||
/**
|
||
PWMのセット、とりあえず全部消灯
|
||
|
||
マスタチャネル:0 (P01:/reset2) マスターは偶数チャネルしかできない
|
||
スレーブ 1 SLTO。(3D LED?)
|
||
2 カメラ
|
||
3 WiFi
|
||
4 (ピンはRTC32kHz out に使用)
|
||
5 充電
|
||
6 電源 L
|
||
7 電源 H
|
||
*/
|
||
TAU0EN = 1;
|
||
TPS0 = BIT_PRS012 | BIT_PRS002; // マスタークロックはCK01,8M/2 /2^4 = 250kHz
|
||
|
||
TMR00 =
|
||
1 << BIT_CKS0 | 0 << BIT_CCS0 | 1 << BIT_MASTER0 | 0 << BIT_STS0 | 0
|
||
<< BIT_CIS0 | 0 << BIT_MD123 | 1 << BIT_MD0;
|
||
TMR01 = TMR02 = TMR03 = TMR04 = TMR05 = TMR06 = TMR07 =
|
||
1 << BIT_CKS0 | 0 << BIT_CCS0 | 0 << BIT_MASTER0 | 4 << BIT_STS0 | 0
|
||
<< BIT_CIS0 | 4 << BIT_MD123 | 1 << BIT_MD0;
|
||
ISC = 0;
|
||
TOM0 = 0b0000000011111110; // 出力モード。4はPWM出力しないが1にしないとTO5以降にクロックが届かない
|
||
|
||
#ifdef _MCU_BSR_
|
||
TOL0 = 0b0000000000000000; // 出力を反転させるかフラグ
|
||
#else
|
||
TOL0 = 0b0000000000000100; // 出力を反転させるかフラグ
|
||
#endif
|
||
|
||
TO0 = 0; // タイマー動作中で、タイマー出力にしてないときのピンのラッチ。タイマー出力を使わないなら0
|
||
TOE0 = 0b0000000011101110; // TOxをタイマーモジュールが制御?
|
||
TS0 = 0b0000000011101111; // 動作開始
|
||
|
||
TDR00 = LED_BRIGHT_MAX - 1; // 10bit, 周期
|
||
|
||
if( system_status.reboot )
|
||
{
|
||
vreg_ctr[VREG_C_LED_POW] = LED_POW_ILM_AUTO;
|
||
LED_duty_pow_blu = LED_BRIGHT_MAX;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void LED_stop( )
|
||
{
|
||
TT0 = 0b0000000011101111; // 一斉停止(しないとだめ)
|
||
TOE0 = 0b0000000000000000; // TOxをタイマーモジュールが制御?(GPIOになる)
|
||
TAU0EN = 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
/* ========================================================
|
||
// 電源LED
|
||
LED_POW_B,R 6,7
|
||
|
||
TDR00 周期(0x03FF。TPS0で250kHzでカウントアップ。10bitなら250Hz位になる)
|
||
TDR0x Duty 0で消灯、TDR00(より大 =0x03FF以上)で点灯です。
|
||
|
||
enum pwr_state_{
|
||
OFF_TRIG = 0,
|
||
OFF,
|
||
ON_TRIG,
|
||
ON,
|
||
SLEEP_TRIG,
|
||
SLEEP
|
||
};
|
||
|
||
enum LED_ILUM_MODE{
|
||
LED_POW_ILM_AUTO,
|
||
LED_POW_ILM_ON,
|
||
LED_POW_ILM_HOTARU,
|
||
LED_POW_ILM_CEOFF
|
||
};
|
||
======================================================== */
|
||
void tsk_led_pow( )
|
||
{
|
||
switch ( vreg_ctr[VREG_C_LED_POW] )
|
||
{
|
||
// 自動切り替え
|
||
case ( LED_POW_ILM_AUTO ):
|
||
switch ( system_status.pwr_state )
|
||
{
|
||
case SLEEP:
|
||
led_pow_hotaru( );
|
||
break;
|
||
|
||
case ON:
|
||
led_pow_normal( );
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
|
||
// 強制
|
||
case ( LED_POW_ILM_OFF ):
|
||
LED_pow_red = 0;
|
||
break;
|
||
|
||
case ( LED_POW_ILM_HOTARU ):
|
||
led_pow_hotaru( );
|
||
break;
|
||
|
||
case ( LED_POW_ILM_ON ):
|
||
default:
|
||
led_pow_normal( );
|
||
break;
|
||
|
||
case ( LED_POW_ILM_ONLY_RED ):
|
||
led_fade_to( LED_duty_pow_blu, 0 );
|
||
LED_pow_red = 1;
|
||
break;
|
||
|
||
case ( LED_POW_ILM_ONLY_BLUE ):
|
||
led_fade_to( LED_duty_pow_blu, LED_BRIGHT_MAX );
|
||
LED_pow_red = 0;
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
電池残量で、 青→赤→赤点滅
|
||
======================================================== */
|
||
static void led_pow_normal( )
|
||
{
|
||
static u8 state;
|
||
|
||
if( vreg_ctr[VREG_C_BT_REMAIN] <= BATT_TH_EMPTY )
|
||
{
|
||
led_fade_to( LED_duty_pow_blu, 0 );
|
||
// 赤点滅
|
||
state++;
|
||
if( state < 127 )
|
||
{
|
||
LED_pow_red = 0;
|
||
}
|
||
else
|
||
{
|
||
LED_pow_red = 1;
|
||
}
|
||
return;
|
||
|
||
}
|
||
else if( vreg_ctr[VREG_C_BT_REMAIN] <= BATT_TH_LO )
|
||
{
|
||
// 赤点灯
|
||
led_fade_to( LED_duty_pow_blu, 0 );
|
||
LED_pow_red = 1;
|
||
return;
|
||
|
||
}
|
||
else
|
||
{
|
||
// 青点灯
|
||
led_fade_to( LED_duty_pow_blu, vreg_ctr[VREG_C_LED_BRIGHT] );
|
||
LED_pow_red = 0;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
ホタルパターン
|
||
======================================================== */
|
||
static void led_pow_hotaru( )
|
||
{
|
||
static u8 delay;
|
||
static u8 state;
|
||
static u16 blue_to;
|
||
|
||
if( delay != 0 )
|
||
{
|
||
delay -= 1;
|
||
return;
|
||
}
|
||
|
||
delay = 10;
|
||
|
||
switch ( state )
|
||
{
|
||
// フェードイン
|
||
case ( 0 ):
|
||
case ( 2 ):
|
||
case ( 4 ):
|
||
if( vreg_ctr[VREG_C_BT_REMAIN] <= BATT_TH_LO )
|
||
{
|
||
blue_to = 0;
|
||
LED_pow_red = 1;
|
||
}
|
||
else
|
||
{
|
||
blue_to = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
LED_pow_red = 0;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
// フェードアウト
|
||
if( vreg_ctr[VREG_C_BT_REMAIN] <= BATT_TH_LO )
|
||
{
|
||
LED_pow_red = 0;
|
||
}
|
||
else
|
||
{
|
||
blue_to = 2;
|
||
}
|
||
break;
|
||
}
|
||
|
||
// LED更新
|
||
if( LED_duty_pow_blu != blue_to )
|
||
{
|
||
if( LED_duty_pow_blu > blue_to )
|
||
{
|
||
LED_duty_pow_blu -= 1;
|
||
}
|
||
else
|
||
{
|
||
LED_duty_pow_blu += 2;
|
||
}
|
||
}
|
||
|
||
if( LED_duty_pow_blu == blue_to )
|
||
{
|
||
state += 1;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
* 割り込みそのものは使いません *
|
||
LED_Wifi 3
|
||
todo 直書きの点滅間隔など
|
||
======================================================== */
|
||
void tsk_led_wifi( )
|
||
{
|
||
static u8 task_interval;
|
||
static u8 remain_wifi_tx;
|
||
static u8 state_wifi_tx;
|
||
static u8 flag_wifi_TX;
|
||
|
||
|
||
if( task_interval-- != 0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 送信パルスのラッチ
|
||
if( vreg_ctr[VREG_C_LED_WIFI] == WIFI_LED_TXAUTO )
|
||
{
|
||
if( WIFI_txLatch )
|
||
{
|
||
WIFI_txLatch = 0;
|
||
flag_wifi_TX = 2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
flag_wifi_TX = 0;
|
||
}
|
||
|
||
|
||
switch ( vreg_ctr[VREG_C_LED_WIFI] )
|
||
{
|
||
case ( WIFI_LED_OFF ):
|
||
default:
|
||
LED_duty_WiFi = 0;
|
||
state_wifi_tx = 0;
|
||
remain_wifi_tx = 0;
|
||
break;
|
||
|
||
case ( WIFI_LED_ON ):
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
state_wifi_tx = 0;
|
||
remain_wifi_tx = 0;
|
||
break;
|
||
|
||
case ( WIFI_LED_TXAUTO ):
|
||
if( flag_wifi_TX != 0 ) // 短いパルスを捕まえるために、割り込みフラグを見る
|
||
{
|
||
// 送信パターン
|
||
switch ( state_wifi_tx )
|
||
{
|
||
case ( 1 ):
|
||
case ( 3 ):
|
||
case ( 5 ):
|
||
LED_duty_WiFi = 0;
|
||
break;
|
||
default:
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
}
|
||
state_wifi_tx++;
|
||
if( state_wifi_tx == 32 )
|
||
{
|
||
state_wifi_tx = 0;
|
||
flag_wifi_TX -= 1;
|
||
}
|
||
task_interval = 22;
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
// 送信フラグ待ち
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
task_interval = 200;
|
||
return;
|
||
}
|
||
break;
|
||
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/* ========================================================
|
||
お知らせLED
|
||
======================================================== */
|
||
void tsk_led_notify( )
|
||
{
|
||
// static u8 task_interval;
|
||
static u16 time_to_next;
|
||
static u8 pos;
|
||
st_info_LED_ptn temp;
|
||
|
||
temp = info_LED.ptn[ pos ];
|
||
/*
|
||
led_fade_to( LED_duty_notify_red, (u8)temp.red );
|
||
led_fade_to( LED_duty_notify_grn, (u8)temp.grn );
|
||
led_fade_to( LED_duty_notify_blu, (u8)temp.blu );
|
||
/*/
|
||
LED_duty_notify_red = (u8)temp.red;
|
||
LED_duty_notify_grn = (u8)temp.grn;
|
||
LED_duty_notify_blu = (u8)temp.blu;
|
||
//*/
|
||
/*
|
||
if( task_interval != 0 )
|
||
{
|
||
task_interval -= 1;
|
||
return;
|
||
}
|
||
task_interval -= 1;
|
||
*/
|
||
|
||
if( time_to_next-- != 0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
time_to_next = 32;
|
||
pos += 1;
|
||
pos &= 0x1F;
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/******************************************************//**
|
||
LED_Cam TO02
|
||
\n BLINK,*_PLUSE の時は、1周期分は必ずその状態になります。
|
||
\n その間に OFF→BLINK などされると、OFFが無視されます。
|
||
*********************************************************/
|
||
void tsk_led_cam( )
|
||
{
|
||
static u8 state_led_cam = 0;
|
||
static u8 task_interval;
|
||
static u8 state_led_cam_twl;
|
||
|
||
if( task_interval != 0 )
|
||
{
|
||
task_interval -= 1;
|
||
return;
|
||
}
|
||
|
||
// ブリンクのように待たせたいとき以外は毎週起動する
|
||
// (レジスタの変更にすぐに反応する)
|
||
|
||
switch ( vreg_ctr[VREG_C_LED_CAM] )
|
||
{
|
||
case ( CAM_LED_OFF ):
|
||
default:
|
||
LED_CAM = 0;
|
||
state_led_cam = 0;
|
||
break;
|
||
|
||
case ( CAM_LED_ON ):
|
||
LED_CAM = 1;
|
||
state_led_cam = 0;
|
||
break;
|
||
|
||
case ( CAM_LED_BLINK ):
|
||
if( state_led_cam == 0 )
|
||
{
|
||
LED_CAM = 1;
|
||
state_led_cam = 1;
|
||
}
|
||
else
|
||
{
|
||
LED_CAM = 0;
|
||
state_led_cam = 0;
|
||
}
|
||
task_interval = 250;
|
||
break;
|
||
|
||
case ( CAM_LED_ON_PLUSE ):
|
||
if( state_led_cam == 0 )
|
||
{
|
||
LED_CAM = 1;
|
||
state_led_cam = 1;
|
||
task_interval = 250;
|
||
}
|
||
else
|
||
{
|
||
vreg_ctr[VREG_C_LED_CAM] = CAM_LED_OFF;
|
||
}
|
||
break;
|
||
|
||
case ( CAM_LED_OFF_PLUSE ):
|
||
if( state_led_cam == 0 )
|
||
{
|
||
LED_CAM = 0;
|
||
state_led_cam = 1;
|
||
task_interval = 250;
|
||
}
|
||
else
|
||
{
|
||
vreg_ctr[VREG_C_LED_CAM] = CAM_LED_ON;
|
||
}
|
||
break;
|
||
|
||
case ( CAM_LED_BY_TWL ):
|
||
switch ( vreg_twl[ REG_TWL_INT_ADRS_CAM ] ){ // switchのネストとか…
|
||
case( TWL_CAMLED_OFF ):
|
||
LED_CAM = 0;
|
||
state_led_cam = 0;
|
||
break;
|
||
|
||
case( TWL_CAMLED_BLINK ):
|
||
if( state_led_cam == 0 )
|
||
{
|
||
LED_CAM = 1;
|
||
state_led_cam = 1;
|
||
}
|
||
else
|
||
{
|
||
LED_CAM = 0;
|
||
state_led_cam = 0;
|
||
}
|
||
task_interval = 250;
|
||
break;
|
||
|
||
case( TWL_CAMLED_ON ):
|
||
case( TWL_CAMLED_DEF_ON ):
|
||
default:
|
||
LED_CAM = 1;
|
||
state_led_cam = 1;
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|