mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-10-31 13:51:10 -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@4 013db118-44a6-b54f-8bf7-843cb86687b1
349 lines
8.0 KiB
C
349 lines
8.0 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 task_interval led_pow_normal();
|
||
static task_interval led_pow_hotaru();
|
||
|
||
|
||
|
||
// ========================================================
|
||
u8 wifi_TX;
|
||
|
||
|
||
// ========================================================
|
||
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 = 0;
|
||
TO0 = 0; // タイマー動作中で、タイマー出力にしてないときのピンのラッチ。タイマー出力を使わないなら0
|
||
TOE0 = 0b0000000011101110; // TOxをタイマーモジュールが制御?
|
||
TS0 = 0b0000000011101111; // 動作開始
|
||
|
||
TDR00 = 0x03FE; // 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
|
||
};
|
||
======================================================== */
|
||
task_interval tsk_led_pow(){
|
||
|
||
switch( vreg_ctr[ VREG_C_LED_POW_ILUMI ] ){
|
||
case( LED_POW_ILM_AUTO ):
|
||
switch( system_status.pwr_state ){
|
||
case( SLEEP ):
|
||
return( led_pow_hotaru() );
|
||
break;
|
||
|
||
case( ON ):
|
||
default:
|
||
return( led_pow_normal() );
|
||
break;
|
||
|
||
case( ON_TRIG ):
|
||
case( SLEEP_TRIG ):
|
||
case( OFF_TRIG ):
|
||
case( OFF ):
|
||
return( 250 );
|
||
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;
|
||
return( 0 );
|
||
break;
|
||
|
||
case( LED_POW_ILM_HOTARU ):
|
||
return( led_pow_hotaru() );
|
||
break;
|
||
|
||
case( LED_POW_ILM_ON ):
|
||
default:
|
||
return( led_pow_normal() );
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
電池残量で、 青→赤→赤点滅
|
||
!! タスクシステムから直接呼ばれるわけではないです!!
|
||
======================================================== */
|
||
static task_interval led_pow_normal(){
|
||
static u8 state;
|
||
u8 dirty;
|
||
|
||
dirty = 0;
|
||
if( vreg_ctr[ VREG_C_BT_REMAIN ] < ( 255 * 0.05 ) ){
|
||
// 赤点滅
|
||
if( state == 0 ){
|
||
LED_duty_pow_H = 0x0000;
|
||
LED_duty_pow_L = 0x0000;
|
||
state = 1;
|
||
}else{
|
||
LED_duty_pow_L = vreg_ctr[ VREG_C_LED_BRIGHT ];
|
||
state = 0;
|
||
}
|
||
return( 250 );
|
||
|
||
}else if( vreg_ctr[ VREG_C_BT_REMAIN ] < ( 255 * 0.2 ) ){
|
||
// 赤点灯
|
||
if( LED_duty_pow_H != 0x0000 ){
|
||
LED_duty_pow_H -= 1;
|
||
dirty = 1;
|
||
}
|
||
if( LED_duty_pow_L != vreg_ctr[ VREG_C_LED_BRIGHT ] ){
|
||
dirty = 1;
|
||
LED_duty_pow_L += ( LED_duty_pow_L < vreg_ctr[ VREG_C_LED_BRIGHT ] )? 1 : -1;
|
||
}
|
||
|
||
}else{
|
||
// 青点灯
|
||
if( LED_duty_pow_H != vreg_ctr[ VREG_C_LED_BRIGHT ] ){
|
||
dirty = 1;
|
||
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;
|
||
dirty = 1;
|
||
}
|
||
}
|
||
|
||
if( dirty == 0 ){
|
||
return( 250 );
|
||
}else{
|
||
return( 0 );
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
ホタルパターン
|
||
!! タスクシステムから直接呼ばれるわけではないです!!
|
||
======================================================== */
|
||
static task_interval led_pow_hotaru(){
|
||
static u8 state;
|
||
static u8 delay;
|
||
static u16 blue_to;
|
||
static u16 red_to;
|
||
u8 dirty;
|
||
|
||
|
||
// LED 調光?
|
||
dirty = 0;
|
||
if( LED_duty_pow_H != blue_to ){
|
||
dirty = 1;
|
||
if( LED_duty_pow_H > blue_to ){
|
||
LED_duty_pow_H -= 1;
|
||
}else{
|
||
LED_duty_pow_H += 2;
|
||
}
|
||
}
|
||
|
||
if( LED_duty_pow_L != red_to ){
|
||
dirty = 1;
|
||
if( LED_duty_pow_L > red_to ){
|
||
LED_duty_pow_L -= 1;
|
||
}else{
|
||
LED_duty_pow_L += 2;
|
||
}
|
||
}
|
||
|
||
|
||
if( dirty == 0 ){
|
||
switch( state ){
|
||
// フェードイン
|
||
case( 0 ):
|
||
case( 2 ):
|
||
case( 4 ):
|
||
if( vreg_ctr[ VREG_C_BT_REMAIN ] < ( 255 * 0.2 ) ){
|
||
red_to = 0x03FF / 8;
|
||
blue_to = 0;
|
||
}else{
|
||
red_to = 0;
|
||
blue_to = 0x03FF / 8;
|
||
}
|
||
break;
|
||
default:
|
||
// フェードアウト
|
||
red_to = 0;
|
||
blue_to = 0;
|
||
break;
|
||
}
|
||
|
||
state += 1;
|
||
|
||
}
|
||
return( 5 );
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
======================================================== */
|
||
void set_LED_cam(){
|
||
if(( vreg_ctr[ VREG_C_CAM_LED ] & 0x01 ) != 0 ){
|
||
LED_duty_CAM = vreg_ctr[ VREG_C_LED_BRIGHT ];
|
||
}else{
|
||
LED_duty_CAM = 0;
|
||
}
|
||
if(( vreg_ctr[ VREG_C_CAM_LED ] & 0x02 ) != 0 ){
|
||
EGP0 |= 0x80;
|
||
}else{
|
||
EGP0 &= ~0x80;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/* ========================================================
|
||
// LED_Cam TO02 未
|
||
// LED_Charge 5 →PM
|
||
LED_Wifi,2 3, P24
|
||
LED_3D 4
|
||
======================================================== */
|
||
task_interval tsk_led_wifi(){
|
||
// WiFi LED //
|
||
static u8 remain_wifi_tx;
|
||
static u8 state_wifi_tx;
|
||
|
||
// フライトモードではNTRパルスが出ても電波でない→
|
||
// フライトレジスタ見なくてはならない
|
||
if(( vreg_ctr[ VREG_C_WIFI_LED ] & REG_BIT_WIFI_ON ) == 0 ){
|
||
return( 250 );
|
||
}
|
||
|
||
/*
|
||
// スリープ時
|
||
if( PM_SLP == 1 ){
|
||
// タスクで回すことはない trig_to_sleep_wifiLed() で減光状態にしてる
|
||
return;
|
||
}
|
||
*/
|
||
|
||
// 短いパルスを捕まえるために、割り込みフラグを見る
|
||
if( wifi_TX != 0 ){
|
||
wifi_TX = 0;
|
||
if(( vreg_ctr[ VREG_C_WIFI_LED ] & REG_BIT_WIFI_BLINK_ENA ) != 0 ){
|
||
remain_wifi_tx = 2;
|
||
}else{
|
||
remain_wifi_tx = 0;
|
||
}
|
||
return( 250 );
|
||
}
|
||
|
||
// 点滅パターン
|
||
if( remain_wifi_tx != 0 ){ // TX active
|
||
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;
|
||
remain_wifi_tx--;
|
||
}
|
||
}else{
|
||
set_led_wifi;
|
||
}
|
||
return( 28 );
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
wifi_TXピン割り込み
|
||
LED点滅のフラグ操作のみ
|
||
実際の点滅などは tsk_led_wifi で行う
|
||
======================================================== */
|
||
__interrupt void intp21_RFTx(){
|
||
wifi_TX = 1;
|
||
}
|