mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-10-31 13:51:10 -04:00
CTRコーデックに対応? IRQ_0を確実にかける I2C(TWL/CTR)の割り込み優先度修正(レジスタ名が悪いと思う) カメラLED、TWLからの操作を追加 loader、文法ミス修正 自己アップデート後、自己リセットをかける。メーカーの回答待ちのため暫定。(セットは電源が切れ、RTCも初期化される) RTCの初期値を変更(暫定) バッテリ残量ICとのやりとりを修正。メーカーの推奨の手順が更新されたため。また、不正になりがちなのでリセットをかけるようにしてみた。I2C_mの2バイト書き込みがひどかったので修正 互換側I2Cれじすたの整理。エンバグ心配 git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@13 013db118-44a6-b54f-8bf7-843cb86687b1
563 lines
13 KiB
C
563 lines
13 KiB
C
/* ========================================================
|
||
LED.c
|
||
|
||
======================================================== */
|
||
#pragma sfr
|
||
|
||
|
||
#include "incs.h"
|
||
#include "led.h"
|
||
|
||
|
||
|
||
// ========================================================
|
||
// TPS0
|
||
#define BIT_PRS01 4
|
||
#define BIT_PRS00 0
|
||
|
||
// 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( );
|
||
|
||
|
||
|
||
// ========================================================
|
||
u8 wifi_TX;
|
||
|
||
|
||
// ========================================================
|
||
static const char MSG_MAIL[] = { 0b11110110, 0b11011010, 0b01101110, 0b10010100 };
|
||
#define MSG_SPD 60
|
||
|
||
// ========================================================
|
||
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 = 1 << BIT_PRS01 | 1 << BIT_PRS00; // マスタークロックは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以降にクロックが届かない
|
||
TOL0 = 0b0000000000000000; // 出力を反転させるかフラグ
|
||
|
||
TO0 = 0; // タイマー動作中で、タイマー出力にしてないときのピンのラッチ。タイマー出力を使わないなら0
|
||
TOE0 = 0b0000000011101110; // TOxをタイマーモジュールが制御?
|
||
TS0 = 0b0000000011101111; // 動作開始
|
||
|
||
TDR00 = LED_BRIGHT_MAX - 1; // 10bit, 周期
|
||
}
|
||
|
||
|
||
|
||
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] < ( 255 * 0.05 ) )
|
||
{
|
||
// 赤点滅
|
||
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] < ( 255 * 0.2 ) )
|
||
{
|
||
// 赤点灯
|
||
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 = 3;
|
||
}
|
||
|
||
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] < ( 255 * 0.2 ) )
|
||
{
|
||
// 赤いとき
|
||
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] < ( 255 * 0.2 ) )
|
||
{
|
||
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
|
||
2 P24 (未)
|
||
======================================================== */
|
||
void tsk_led_wifi( )
|
||
{
|
||
static u8 task_interval;
|
||
static u8 remain_wifi_tx;
|
||
static u8 state_wifi_tx;
|
||
|
||
if( task_interval != 0 )
|
||
{
|
||
task_interval -= 1;
|
||
return;
|
||
}
|
||
|
||
switch ( vreg_ctr[VREG_C_LED_WIFI] )
|
||
{
|
||
case ( WIFI_LED_OFF ):
|
||
LED_duty_WiFi = 0;
|
||
wifi_TX = 0;
|
||
state_wifi_tx = 0;
|
||
remain_wifi_tx = 0;
|
||
LED_WIFI_2 = 0;
|
||
break;
|
||
|
||
case ( WIFI_LED_ON ):
|
||
default:
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
wifi_TX = 0;
|
||
state_wifi_tx = 0;
|
||
remain_wifi_tx = 0;
|
||
LED_WIFI_2 = 1;
|
||
break;
|
||
|
||
case ( WIFI_LED_TXAUTO ):
|
||
// 短いパルスを捕まえるために、割り込みフラグを見る
|
||
if( wifi_TX != 0 )
|
||
{
|
||
wifi_TX = 0;
|
||
remain_wifi_tx = 2;
|
||
}
|
||
|
||
// 送信パターン
|
||
if( remain_wifi_tx != 0 )
|
||
{ // TX active
|
||
switch ( state_wifi_tx )
|
||
{
|
||
case ( 1 ):
|
||
case ( 3 ):
|
||
case ( 5 ):
|
||
LED_duty_WiFi = 0;
|
||
LED_WIFI_2 = 0;
|
||
break;
|
||
default:
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
LED_WIFI_2 = 1;
|
||
}
|
||
state_wifi_tx++;
|
||
if( state_wifi_tx == 32 )
|
||
{
|
||
state_wifi_tx = 0;
|
||
remain_wifi_tx--;
|
||
}
|
||
task_interval = 22;
|
||
return;
|
||
|
||
}
|
||
else
|
||
{
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
LED_WIFI_2 = 1;
|
||
task_interval = 200;
|
||
return;
|
||
}
|
||
break;
|
||
|
||
case ( WIFI_LED_PTN0 ):
|
||
LED_WIFI_2 = 1;
|
||
switch ( state_wifi_tx )
|
||
{
|
||
case ( 1 ):
|
||
case ( 3 ):
|
||
case ( 5 ):
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
break;
|
||
default:
|
||
LED_duty_WiFi = 0;
|
||
}
|
||
state_wifi_tx++;
|
||
if( state_wifi_tx == 16 )
|
||
{
|
||
state_wifi_tx = 0;
|
||
}
|
||
task_interval = 50;
|
||
return;
|
||
break;
|
||
|
||
case ( WIFI_LED_PTN1 ):
|
||
LED_WIFI_2 = 1;
|
||
{
|
||
u8 dat;
|
||
|
||
if( remain_wifi_tx != 0 )
|
||
{
|
||
LED_duty_WiFi = 0;
|
||
remain_wifi_tx = 0;
|
||
task_interval = MSG_SPD;
|
||
return;
|
||
}
|
||
|
||
dat = ( MSG_MAIL[state_wifi_tx / 4] << ( ( state_wifi_tx % 4 ) * 2 ) ) & 0xC0;
|
||
state_wifi_tx = ( dat == 0 ) ? 0 : ( state_wifi_tx + 1 );
|
||
|
||
switch ( dat )
|
||
{
|
||
case ( 0b00000000 ):
|
||
LED_duty_WiFi = 0;
|
||
remain_wifi_tx = 0;
|
||
task_interval = ( MSG_SPD * 3 );
|
||
break;
|
||
|
||
case ( 0b01000000 ):
|
||
default:
|
||
LED_duty_WiFi = 0;
|
||
remain_wifi_tx = 1;
|
||
task_interval = ( MSG_SPD );
|
||
break;
|
||
|
||
case ( 0b10000000 ):
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
remain_wifi_tx = 1;
|
||
task_interval = ( MSG_SPD );
|
||
break;
|
||
|
||
case ( 0b11000000 ):
|
||
LED_duty_WiFi = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
remain_wifi_tx = 1;
|
||
task_interval = ( MSG_SPD * 3 );
|
||
break;
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/******************************************************//**
|
||
wifi_TXピン割り込み
|
||
\n LED点滅のフラグ操作のみ
|
||
\n 実際の点滅などは tsk_led_wifi で行う
|
||
*********************************************************/
|
||
__interrupt void intp21_RFTx( )
|
||
{
|
||
wifi_TX = 1;
|
||
}
|
||
|
||
|
||
|
||
/******************************************************//**
|
||
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;
|
||
|
||
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 ] ){
|
||
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 = 0;
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|