ctr_mcu/branches/0.15(sdk0.9_E3_fix_vol)/led.c
N2232 898a08202c 0.15 for E3
TSボードに書き込むと動作はしますが実機との差分で以下の不具合があります。
 (ベースが10.10であり、E3実機専用版と言うことで)
 ・加速度センサが使用できません
 ・音量Volが上下反転しています


git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@162 013db118-44a6-b54f-8bf7-843cb86687b1
2010-05-18 00:37:45 +00:00

619 lines
15 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

/* ========================================================
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( );
// ========================================================
static const char MSG_MAIL[] = { 0b11110110, 0b11011010, 0b01101110, 0b10010100 };
#define MSG_SPD 60
// ↑255/3以下であること
// ========================================================
void LED_init( )
{
/**
PWMのセット、とりあえず全部消灯
マスタチャネル:0 (P01:/reset2) マスターは偶数チャネルしかできない
スレーブ    1 SLTO。( )
        2 カメラ
         WiFi
         (ピンは32kHz out に使用)
        5 充電
        6 電源
        7 電源
*/
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_H = 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_duty_pow_H -= ( LED_duty_pow_H == 0x0000 ) ? 0 : 1;
LED_duty_pow_L -= ( LED_duty_pow_L == 0x0000 ) ? 0 : 1;
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_duty_pow_H = 0x0000;
LED_duty_pow_L = LED_BRIGHT_MAX;
break;
case ( LED_POW_ILM_ONLY_BLUE ):
LED_duty_pow_H = LED_BRIGHT_MAX;
LED_duty_pow_L = 0x0000;
break;
}
}
/* ========================================================
電池残量で、 青→赤→赤点滅
======================================================== */
static void led_pow_normal( )
{
static u8 state;
if( vreg_ctr[VREG_C_BT_REMAIN] < 3 )
{
// 赤点滅
state++;
if( state < 127 )
{
LED_duty_pow_H = 0x0000;
LED_duty_pow_L = 0x0000;
}
else
{
LED_duty_pow_L = vreg_ctr[VREG_C_LED_BRIGHT];
}
return;
}
else if( vreg_ctr[VREG_C_BT_REMAIN] < 12 )
{
// 赤点灯
if( LED_duty_pow_H != 0x0000 )
{ // 青フェードアウト
LED_duty_pow_H -= 1;
}
if( LED_duty_pow_L != vreg_ctr[VREG_C_LED_BRIGHT] )
{ // 赤フェードイン
LED_duty_pow_L += ( LED_duty_pow_L < vreg_ctr[VREG_C_LED_BRIGHT] ) ? 1 : -1;
}
return;
}
else
{
// 青点灯
if( LED_duty_pow_H != vreg_ctr[VREG_C_LED_BRIGHT] )
{
LED_duty_pow_H += ( LED_duty_pow_H < vreg_ctr[VREG_C_LED_BRIGHT] ) ? 1 : -1;
}
if( LED_duty_pow_L != 0x0000 )
{
LED_duty_pow_L -= 1;
}
}
return;
}
/* ========================================================
ホタルパターン
======================================================== */
static void led_pow_hotaru( )
{
static u8 delay;
static u8 state;
static u16 blue_to;
static u16 red_to;
if( delay != 0 )
{
delay -= 1;
return;
}
else
{
delay = 10;
}
if( LED_duty_pow_L != red_to )
{
if( LED_duty_pow_L > red_to )
{
LED_duty_pow_L -= 1;
}
else
{
LED_duty_pow_L += 2;
}
}
if( LED_duty_pow_H != blue_to )
{
if( LED_duty_pow_H > blue_to )
{
LED_duty_pow_H -= 1;
}
else
{
LED_duty_pow_H += 2;
}
}
switch ( state )
{
// フェードイン
case ( 0 ):
case ( 2 ):
case ( 4 ):
if( vreg_ctr[VREG_C_BT_REMAIN] < 12 )
{
// 赤いとき
blue_to = 0;
red_to = vreg_ctr[VREG_C_LED_BRIGHT];
}
else
{
blue_to = vreg_ctr[VREG_C_LED_BRIGHT];
red_to = 0;
}
break;
default:
// フェードアウト
if( vreg_ctr[VREG_C_BT_REMAIN] < 12 )
{
red_to = 2;
}
else
{
blue_to = 2;
}
break;
}
if( ( LED_duty_pow_H == blue_to ) && ( LED_duty_pow_L == red_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_Wifi2 P24 (未)
======================================================== */
void tsk_led_notify( )
{
static u8 task_interval;
static u8 flg_char_space;
static u8 state_notify_led; // 点灯パターンの進行具合
static u8 flag_wifi_TX;
if( task_interval-- != 0 )
{
return;
}
switch ( vreg_ctr[VREG_C_LED_NOTIFY] )
{
case ( NOTIFY_LED_OFF ):
default:
LED_duty_NOTIFY = 0;
state_notify_led = 0;
flg_char_space = 0;
break;
case ( NOTIFY_LED_ON ):
LED_duty_NOTIFY = vreg_ctr[VREG_C_LED_BRIGHT];
state_notify_led = 0;
flg_char_space = 0;
break;
case ( NOTIFY_LED_PTN0 ):
// ゆっくりバースト
switch ( state_notify_led )
{
case ( 1 ):
case ( 3 ):
case ( 5 ):
LED_duty_NOTIFY = vreg_ctr[VREG_C_LED_BRIGHT];
break;
default:
LED_duty_NOTIFY = 0;
}
state_notify_led++;
if( state_notify_led == 16 )
{
state_notify_led = 0;
}
task_interval = 50;
return;
case ( NOTIFY_LED_PTN1 ):
// データテーブルに従って点滅
{
u8 dat;
task_interval = MSG_SPD; // 共通のため。場合によって上書き
if( flg_char_space != 0 )
{
LED_duty_NOTIFY = 0;
flg_char_space = 0;
return;
}
// データバッファの見る位置の更新
dat = ( MSG_MAIL[state_notify_led / 4] << ( ( state_notify_led % 4 ) * 2 ) ) & 0xC0;
if( dat == 0 )
{
state_notify_led = 0;
}
else
{
state_notify_led += 1;
}
flg_char_space = 1;
if(( dat & 0b10000000 ) != 0 )
{
// 点灯はさせる
LED_duty_NOTIFY = vreg_ctr[VREG_C_LED_BRIGHT];
if(( dat & 0b01000000 ) == 0 )
{
// 短
// nothing to do
}
else
{
// 長
task_interval = ( MSG_SPD * 3 );
}
// 次は単語間休み、とかの判定をさせたかったが
/// 1バイトに2ビットずつデータが並んでおり、次のバイトに
/// またがるようなときが面倒なのでやめる
return;
}
else
{
if(( dat & 0b01000000 ) == 0 )
{
// 一文終了
task_interval = ( MSG_SPD * 3 );
}
else
{
// 単語間
// nothing to do
}
return;
}
}
}
}
/******************************************************//**
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_duty_CAM = 0;
state_led_cam = 0;
break;
case ( CAM_LED_ON ):
LED_duty_CAM = vreg_ctr[VREG_C_LED_BRIGHT];
state_led_cam = 0;
break;
case ( CAM_LED_BLINK ):
if( state_led_cam == 0 )
{
LED_duty_CAM = vreg_ctr[VREG_C_LED_BRIGHT];
state_led_cam = 1;
}
else
{
LED_duty_CAM = 0;
state_led_cam = 0;
}
task_interval = 250;
break;
case ( CAM_LED_ON_PLUSE ):
if( state_led_cam == 0 )
{
LED_duty_CAM = vreg_ctr[VREG_C_LED_BRIGHT];
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_duty_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_duty_CAM = 0;
state_led_cam = 0;
break;
case( TWL_CAMLED_BLINK ):
if( state_led_cam == 0 )
{
LED_duty_CAM = vreg_ctr[VREG_C_LED_BRIGHT];
state_led_cam = 1;
}
else
{
LED_duty_CAM = 0;
state_led_cam = 0;
}
task_interval = 250;
break;
case( TWL_CAMLED_ON ):
case( TWL_CAMLED_DEF_ON ):
default:
LED_duty_CAM = vreg_ctr[VREG_C_LED_BRIGHT];
state_led_cam = 1;
break;
}
}
return;
}