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

This commit is contained in:
fujita_ryohei 2009-07-06 06:27:40 +00:00
parent 96796eccec
commit 938ea96c94
18 changed files with 3347 additions and 0 deletions

8
trunk/WDT.c Normal file
View File

@ -0,0 +1,8 @@
#pragma sfr
#include "incs_loader.h"
void WDT_Restart( void ){
WDTE = 0xAC; // restart watch dog timer
}

133
trunk/accero.c Normal file
View File

@ -0,0 +1,133 @@
/*****************************************************************************
 
CPUに割り込み
I2Cの競合回避などがあるので
*****************************************************************************/
#pragma SFR
#pragma NOP
#pragma HALT
#pragma STOP
#include "incs.h"
// レジスタ名
#define ACC_REG_WHOAMI 0x0F
#define ACC_REG_CTRL1 0x20
#define ACC_REG_CTRL5 0x24
#define ACC_REG_X 0x28
// ビット位置
#define ACC_bP_PM0 5
#define ACC_bP_DR0 3
// ビット設定値
#define ACC_BITS_PM_PDN 0
#define ACC_BITS_PM_NORM 1
#define ACC_BITS_PM_LP0R5 2
#define ACC_BITS_PM_LP1 3
#define ACC_BITS_PM_LP2 4
#define ACC_BITS_PM_LP5 5
#define ACC_BITS_PM_LP10 6
#define ACC_BITS_DR_50Hz 0
#define ACC_BITS_DR_100Hz 1
#define ACC_BITS_DR_400Hz 2
#define ACC_BITS_DR_1000Hz 3
#define ACC_BITS_ALL_AXIS_ON 7
//*************************************
u8 hosu_mode = 0;
/*
0: power down
1:
*/
/*****************************************************************************
 
I2Cが使用中だったら
*****************************************************************************/
task_status_immed tsk_cbk_accero(){
static u8 sequence;
u8* dest_adrs;
if( system_status.pwr_state == ON ){
// if( 自動歩数計? )
// todo
sequence += 1;
vreg_ctr[VREG_C_ACC_0SEQ + 7 * ( sequence & 0x03 )] = sequence;
dest_adrs = &vreg_ctr[VREG_C_ACC_0XH] + 7 * ( sequence & 0x03 );
iic_mcu_read( IIC_SLA_ACCEL, ( ACC_REG_X | 0x80 ), 6, dest_adrs );
#if 0
switch( system_status.pwr_state ){
case OFF:
case ON_TRIG:
case ON:
case SLEEP_TRIG:
case SLEEP:
case OFF_TRIG:
default:
break;
}
#endif
}
return( ERR_SUCCESS );
}
/*****************************************************************************
 
todo
*****************************************************************************/
err accero_hosu_start(){
u8 temp;
u8 err;
u8 str_send_buf[4];
if( system_status.pwr_state == ON ){
err = iic_mcu_read( IIC_SLA_ACCEL, ACC_REG_WHOAMI, 1, &temp );
if( err == ERR_NAK ){
vreg_ctr[ VREG_C_ACC_STATUS ] |= 0x80;
return( ERR_ERR );
}
str_send_buf[0] = ( ACC_BITS_PM_NORM << ACC_bP_PM0 | ACC_BITS_DR_100Hz << ACC_bP_DR0 | ACC_BITS_ALL_AXIS_ON ); // cont1
str_send_buf[1] = 0x00; // 泣ける...
str_send_buf[2] = 0x02;
str_send_buf[3] = 0x80;
err = iic_mcu_write( IIC_SLA_ACCEL, ( ACC_REG_CTRL1 | 0x80 ), 4, str_send_buf );
// str_send_buf[0] = 0x00;
// err |= iic_mcu_write( IIC_SLA_ACCEL, ACC_REG_CTRL5, 1, str_send_buf );
return( err );
}
}
err accero_hosu_stop(){
u8 err;
u8 str_send_buf[4];
str_send_buf[0] = ( ACC_BITS_PM_PDN << ACC_bP_PM0 | 0 << ACC_bP_DR0 | ACC_BITS_ALL_AXIS_ON );
str_send_buf[1] = 0x00; // 泣ける...
str_send_buf[2] = 0x02;
str_send_buf[3] = 0x80;
err = iic_mcu_write( IIC_SLA_ACCEL, ( ACC_REG_CTRL1 | 0x80 ) , 4, str_send_buf );
return( err );
}

105
trunk/adc.c Normal file
View File

@ -0,0 +1,105 @@
/******************************************************************************
PMIC_TWL2 I2C通信
de JHL
nintendo
'09 Apr
*******************************************************************************/
#include "incs_loader.h"
#include "adc.h"
#include "pm.h"
/******************************************************************************
ADC設定と
BT_TEMP,_P
ADIN1
VOL
PM_BT_DET,_P PM_init
******************************************************************************/
task_status tsk_adc(){
if(( system_status.pwr_state == ON )
|| ( system_status.pwr_state == SLEEP )){
ADCEN = 1;
ADM = 0b00011011; // セレクトモード、章圧、fCLK/6 ///ここから
ADPC = 0x07; // ADCポートのセレクト
ADS = ADC_SEL_3D;
ADCS = 1; // AD開始。 /// ここまでに、1us以上開ける
ADIF = 0;
ADMK = 0;
return( 8 );
}
}
/******************************************************************************
 
  
*******************************************************************************/
__interrupt void int_adc(){
switch( ADS ){
case( ADC_SEL_3D ):
vreg_ctr[ VREG_C_3D_DEPTH ] = ADCRH;
break;
case( ADC_SEL_VOL ):
vreg_ctr[ VREG_C_VOL ] = ADCRH;
// todo: テーブル引きなど
break;
case( ADC_SEL_BATT_TEMP ):
raw_adc_temperature = ADCR;
break;
case( ADC_SEL_BATT_DET ):
// vreg_ctr[ VREG_C_DBG_BATT_DET ] = ADCRH;
break;
}
// if( ADS == ADC_SEL_BATT_DET ){
// もっとまともな書き方がありそうだ
if( ADS == ADC_SEL_BATT_TEMP ){ // 電池判別は電源投入の一回で良いよね
ADCEN = 0; // いっそのこと、止めてしまう
}else{
ADS += 1; // 次のチャンネル
}
}
/******************************************************************************
tsk_adcと競合することを考慮していません
*******************************************************************************/
u16 get_adc( u8 ch ){
u16 temp;
ADMK = 1;
ADIF = 0;
ADCEN = 1;
ADM = 0b00011011; // セレクトモード、章圧、fCLK/6 ///ここから
ADPC = 0x07; // ADCポートのセレクト
ADS = ch;
ADCS = 1; // AD開始。 /// ここまでに、1us以上開ける
ADMK = 0;
while( ADIF == 0 ){;}
temp = ADCR;
ADCEN = 0;
return( temp );
}

230
trunk/i2c_ctr.c Normal file
View File

@ -0,0 +1,230 @@
/******************************************************************************
SoC I2C通信
de JHL .nintendo
'09 Apr
*******************************************************************************/
#include "incs_loader.h"
u8 vreg_adrs;
u8 pre_dat;
u16 tot;
/*****************************************************************************
*****************************************************************************/
enum{
IIC_IDLE = 0,
IIC_RCV_REG_ADRS,
IIC_TX_OR_RX,
IIC_TX,
IIC_RX
};
#if 0
// 1バイト送受の度に割り込みが発生するバージョン
__interrupt void int_iica(){
static u8 state = 0;
static u8 reg_adrs;
static u8 reg_adrs_internal;
static u8 temp;
if( SPD ){
state = IIC_IDLE;
SPIE = 0;
return;
}
if( ACKD == 0 ){
LREL = 1;
state = IIC_IDLE;
return;
}
DBG_P_n = 1;
switch( state ){
case( IIC_IDLE ):
// 自局呼び出しに応答。
// 初期化など
WREL = 1; // ウェイト解除
SPIE = 1;
state = IIC_RCV_REG_ADRS;
break;
case( IIC_RCV_REG_ADRS ):
// レジスタアドレス受信
reg_adrs = IICA & 0x1F;
WREL = 1;
reg_adrs_internal = adrs_table_ctr_ext2int( reg_adrs );
temp = vreg_ctr_read( reg_adrs_internal );
// temp = vreg_ctr[ reg_adrs ];
state = IIC_TX_OR_RX;
break;
case( IIC_TX_OR_RX ):
if( STD ){
// リードされる
if( !COI ){
// リスタートで違うデバイスが呼ばれた!
WREL = 1; // ウェイト解除?
state = IIC_IDLE; // 終了処理
SPIE = 0;
}else{
state = IIC_TX;
}
}else{
state = IIC_RX;
}
// no break;
default:
if( state == IIC_TX ){
IICA = temp;
}else{
temp = IICA;
WREL = 1;
vreg_ctr_write( reg_adrs_internal, temp );
// vreg_ctr[ reg_adrs ] = temp;
}
reg_adrs = ( reg_adrs + 1 ) & 0x1F;
reg_adrs_internal = adrs_table_ctr_ext2int( reg_adrs );
if( state == IIC_TX ){
temp = vreg_ctr_read( reg_adrs_internal );
// temp = vreg_ctr[ reg_adrs ];
}
break;
}
DBG_P_n = 0;
}
#endif
//#if 0
//一度通信が始まったら終わるまで戻らないバージョン
__interrupt void int_iica(){
static u8 state = 0;
static u8 reg_adrs;
static u8 reg_adrs_internal;
static u8 trx_buf;
DBG_P_n = 1;
// 自局呼び出しに応答。
// 初期化など
WREL = 1; // ウェイト解除
DBG_P_n = 0;
while( !IICAIF ){;}
IICAIF = 0;
DBG_P_n = 1;
// レジスタアドレス受信
reg_adrs = IICA;
WREL = 1;
trx_buf = vreg_ctr_read( reg_adrs ); // データの準備をしておく
DBG_P_n = 0;
while( !IICAIF ){;}
IICAIF = 0;
if( STD ){ // リスタートコンディション
// リードされる
if( !COI ){
// リスタートで違うデバイスが呼ばれた!
WREL = 1; // ウェイト解除?
state = IIC_IDLE; // 終了処理
SPIE = 0;
return;
}else{
state = IIC_TX;
}
}else{ // ライト続行
state = IIC_RX;
}
DBG_P_n = 0;
if( state == IIC_TX ){ // 送信 //
do{
DBG_P_n = 1;
IICA = trx_buf;
reg_adrs += 1;
trx_buf = vreg_ctr_read( reg_adrs );
DBG_P_n = 0;
while( !IICAIF ){;}
IICAIF = 0;
}while( ACKD );
LREL = 1;
}else{ // 受信 //
SPIE = 1;
do{
DBG_P_n = 1;
trx_buf = IICA;
WREL = 1;
vreg_ctr_write( reg_adrs, trx_buf );
reg_adrs += 1;
DBG_P_n = 0;
while( !IICAIF ){;}
IICAIF = 0;
}while( !SPD );
SPIE = 0;
}
vreg_c_iic_release();
state = IIC_IDLE;
}
//#endif
/*****************************************************************************
API
*****************************************************************************/
void IICA_Init( void ){
IICAEN = 1;
IICE = 0; /* IICA disable */
IICAMK = 1; /* INTIICA disable */
IICAIF = 0; /* clear INTIICA interrupt flag */
IICAPR0 = 0; /* set INTIICA high priority */
IICAPR1 = 0; /* set INTIICA high priority */
P6 &= ~0x3;
SVA = IIC_C_SLAVEADDRESS;
IICF = 0x01;
STCEN = 1; // リスタートの許可
IICRSV = 1; // 通信予約をさせない:スレーブに徹する
SPIE = 0; // ストップコンディションでの割り込みを禁止
WTIM = 1; // 自動でACKを返した後clkをLに固定する
ACKE = 1; // ダメCPUは無視して次の通信をはじめるかもしれないんで早くclkを開放しないといけない
IICWL = 6; // L期間の長さ
IICWH = 5;
IICAMK = 0; // 割り込みを許可
IICE = 1;
PM6 &= ~0x3; /* set clock pin for IICA */
}
//****************************************************************************
void IICA_Stop( void ){
IICE = 0; /* IICA disable */
IICAEN = 0;
}

476
trunk/i2c_mcu.c Normal file
View File

@ -0,0 +1,476 @@
/******************************************************************************
I2C使
de JHL
'09 Feb -
*******************************************************************************/
#pragma sfr
#pragma di
#pragma ei
#pragma nop
#pragma inline // memcpy()をインライン展開する
#include "incs_loader.h"
#include "i2c_mcu.h"
//#include <string.h>
bit iic_mcu_wo_dma;
volatile bit iic_mcu_busy;
volatile bit iic_mcu_initialized;
// SSR0n
#define bit_TSF0 6
// SIR0n
#define PECT0 ( 1 << 1 )
// SSR0n
#define PEF0 ( 1 << 1 )
#define TXE0 ( 1 << 15 )
#define RXE0 ( 1 << 14 )
#define SLC02 4
#define DLS02 0
#define TSF0 ( 1 << 6 )
#define DRS ( 1 << 6 )
#define TAUS_MASK 0b0000101100001011;
static void iic_mcu_send_st();
static void iic_mcu_send_re_st();
static void iic_mcu_send_sp();
static err iic_mcu_send_a_byte( u8 );
static err iic_mcu_call_slave( u8 slave );
u8 iic_send_work[4];
u8* p_iic_send_wo_dma_dat;
u8 iic_send_wo_dma_len;
volatile u8 interrupted;
u8 dma_state;
/*****
1
******************************************************************************/
u8 iic_mcu_read_a_byte( u8 SLA, u8 adrs ){
u8 dat;
iic_mcu_read( SLA, adrs, 1, &dat );
return( dat );
}
/******************************************************************************
0
1
2
3
******************************************************************************/
err iic_mcu_read( u8 slave, u8 adrs, u8 len, u8* dest ){
//*
// 使用中なら待つ
if( iic_mcu_initialized == 0 ){
#ifdef _debug_
iic_mcu_start();
#else
while(1){};
#endif
}
while( iic_mcu_busy ){
DBG_M_n = 1;
NOP();
}
DBG_M_n = 0;
/*/
// 使用中なら帰る
if( iic_mcu_initialized == 0 ){
return(0x80);
}
if( iic_mcu_busy != 0 ){
return( 3 );
}
//*/
// スタートコンディションとスレーブの呼び出し、レジスタアドレスの送信
if( iic_mcu_call_slave( slave ) != 0 ){
return( ERR_NAK );
}
// レジスタアドレスの送信
iic_mcu_send_a_byte( adrs ); // 終わるまで帰ってこない
// if( err != ERR_SUCCESS )
// データ受信 //
iic_mcu_send_re_st(); // リスタートコンディション
iic_mcu_send_a_byte( slave | 0x01 ); // 送信完了まで戻ってきません。
// データ受信
ST0 = 0x0004; // 受信モードに設定を変えるのでロジック停止
SCR02 = RXE0 | 1 << SLC02 | 7 << DLS02; // 受信設定
SS0 = 0x0004; // 通信待機
while( len != 0 ){
if( len == 1 ){
SOE0 &= ~0x0004;
}
IICIF10 = 0;
SIO10 = 0xFF; // ダミーデータを書くと受信開始
while( IICIF10 == 0 ){;}
*dest = SIO10;
dest++;
len--;
}
iic_mcu_send_sp();
IICIF10 = 0;
iic_mcu_busy = 0;
return( ERR_SUCCESS );
}
/*****
 iic_mcu_write 
使
******************************************************************************/
err iic_mcu_write_a_byte( u8 SLA, u8 adrs, u8 dat ){
volatile static u8 temp;
while( iic_mcu_busy ){
DBG_M_n = 1;
NOP();
}
DBG_M_n = 0;
temp = dat;
return( iic_mcu_write( SLA, adrs, 1, &temp ) );
}
u8* p_src_work; // DMA送信バッファ
u8 len_work;
/******************************************************************************
adrs
*strから
len文字書きます
0
1
2
3
DMA1を使用します
******************************************************************************/
err iic_mcu_write( u8 slave, u8 adrs, u8 len, u8* src ){
//*
// 使用中なら待つ
if( iic_mcu_initialized == 0 ){
#ifdef _debug_
iic_mcu_start();
#else
while(1){};
#endif
}
while( iic_mcu_busy ){
DBG_M_n = 1;
NOP();
}
DBG_M_n = 0;
/*/
// 使用中なら帰る
if( iic_mcu_initialized == 0 ){
return(0x80);
}
if( iic_mcu_busy != 0 ){
return( 3 );
}
//*/
// スタートコンディションとスレーブの呼び出し...
IICMK10 = 1;
if( iic_mcu_call_slave( slave ) != 0 ){
return( ERR_NAK );
}
iic_mcu_busy = 1;
dma_state = 0;
if( !iic_mcu_wo_dma ){
// DMAを使用する通常
// レジスタアドレスの送信
memcpy( iic_send_work, src, 4 ); //バッファとして4バイトしか用意して無いため。
// DMAセット
while( DST1 ){;};
DEN1 = 1;
DSA1 = (u8)( &SIO10 );
DRA1 = (u16)iic_send_work;
DBC1 = len;
DMC1 = DRS | 8; // RAM -> SFR, 8bit, IRQ, IIC10
DMAIF1 = 0;
DMAMK1 = 0;
DST1 = 1;
IICIF10 = 0;
SIO10 = adrs; // 書きっぱなし! 割り込みが発生してDMAスタート
}else{
// DMAを使用しない //
// レジスタアドレスの送信
IICIF10 = 0;
SIO10 = adrs;
IICMK10 = 0;
iic_send_wo_dma_len = len;
p_iic_send_wo_dma_dat = src;
// 残りは割り込みルーチン内で
}
dma_state = 1;
return( ERR_SUCCESS );
}
/******************************************************************************
DMA転送終了割り込み
IIC_mcu
DMA転送が終わっただけでI2Cの転送は終わってません
******************************************************************************/
__interrupt void int_dma1(){
dma_state = 2;
DMAMK1 = 1;
DEN1 = 0;
IICMK10 = 0;
// 最後のバイト転送後、I2C割り込みが発生する
}
/**
IIC MCUのバイト送出完了割り込み
******************************************************************************/
__interrupt void int_iic10(){
dma_state = 3;
if( iic_mcu_wo_dma ){
// DMA使用せず、転送途中
if( iic_send_wo_dma_len != 0 ){
SIO10 = *p_iic_send_wo_dma_dat;
p_iic_send_wo_dma_dat++;
iic_send_wo_dma_len--;
return;
}
}
// 共通(最終バイト送信完了)
IICMK10 = 1;
iic_mcu_send_sp();
iic_mcu_wo_dma = 0;
iic_mcu_busy = 0;
}
/******************************************************************************
 ACKの確認
ACK                  0
 NACK   1
******************************************************************************/
static err iic_mcu_call_slave( u8 slave ){
// スレーブの呼び出し //
iic_mcu_send_st();
// SIR02 = SSR02; // NAKエラーのフラグクリア
#if 0
if( iic_mcu_send_a_byte( slave ) != 0 ){
iic_mcu_send_sp();
return( 1 ); // 指定のスレーブがいない / busy
}
#else
IICIF10 = 0;
SIO10 = slave;
while( IICIF10 == 0 ){
NOP();
} // 通信中
if( SSR02 != 0 ){
SIR02 = SSR02;
iic_mcu_send_sp();
return( ERR_NAK );
}
#endif
return( ERR_SUCCESS );
}
/**
******************************************************************************/
static err iic_mcu_send_a_byte( u8 dat ){
IICIF10 = 0;
SIO10 = dat;
while( IICIF10 == 0 ){
NOP();
} // 通信中
if( SSR02 != 0 ){
SIR02 = SSR02;
return( 1 ); // NAK
}
return( 0 );
}
/**
*******************************************************************************/
static void iic_mcu_send_st(){
SO0 &= ~0x0004; // SDA
NOP();
NOP();
NOP();
NOP();
SO0 &= ~0x0400; // SCL
SOE0 = 0x0004; // ハード制御へ
SCR02 = TXE0 | 1 << SLC02 | 7 << DLS02; // 送信許可、データは8ビット単位
SS0 = 0x0004; // 通信待機
}
/**
*******************************************************************************/
static void iic_mcu_send_re_st(){
ST0 |= 0x0004;
SO0 |= 0x0400 | TAUS_MASK; // ( SDA = H ), SCL -> H
NOP();
NOP();
NOP();
NOP();
SOE0 &= ~0x0004; // ( SCL = H ), SDA -> L
NOP();
NOP();
NOP();
NOP();
iic_mcu_send_st();
}
/**
*******************************************************************************/
static void iic_mcu_send_sp(){
ST0 |= 0x0004;
SOE0 = 0; // 受信の時はもっと前に「も」設定してる。(NACK出力)
SO0 = 0x0000 | TAUS_MASK; // SCL
NOP();
NOP();
NOP();
NOP();
SO0 = 0x0400 | TAUS_MASK; // SCL
NOP();
NOP();
NOP();
NOP();
SO0 = 0x0404 | TAUS_MASK;
}
/**
(
******************************************************************************/
void iic2m_bus_reset(){
u8 count;
/*
for( count = 19; count != 0; count-- ){
iics_sda_H;
iics_scl_H;
PM1.1 = 1; // SDA
if( iics_sda != 0 ){
PM1.1 = 0;
iic_mcu_send_sp;
return;
}
PM1.1 = 0;
iics_scl_L;
}
return;
*/
}
/**
*
*****************************************************************************/
void iic_mcu_start(){
I2C_PU = 1;
SAU0EN = 1;
NOP(); // 4clkあける
NOP();
NOP();
NOP();
SPS0 = 0x0000; // シリアルユニットのクロック0。(8M/2)/1
SMR02 = 0 << 15 | 0 << 14 | 0 << 7 | 0 << 5 | 1 << 4 | 1 << 2; // I2Cとそのクロックなど設定
SDR02 = 5 << 9; // ボーレート設定 (8M/2)/1/(x+1)/2
SO0 = 0x0404 | TAUS_MASK; // 最初はHH
iic_mcu_busy = 0;
iic_mcu_wo_dma = 0;
iic_mcu_initialized = 1;
}
/**
*
* 使
*****************************************************************************/
void iic_mcu_stop(){
while( iic_mcu_busy ){;} // DMA動作中はもう少し待つ
iic_mcu_send_re_st(); // SCL,SDAをLLにする
I2C_PU = 0;
SAU0EN = 0;
iic_mcu_initialized = 0;
}

157
trunk/i2c_twl.c Normal file
View File

@ -0,0 +1,157 @@
#pragma sfr /* 特殊機能レジスタ使用 */
#ifndef _TEG_
// KE3Lの間はプレースホルダ
void IICB_Init( void ){}
void IICB_Stop( void ){}
void IICB_SlaveReceiveStart(){}
#else
/*============================================================================*/
#include "incs.h"
#include "i2c_twl_defs.h"
extern u8 vreg_twl[];
/*============================================================================*/
u8 vreg_adrs;
u8 pre_dat;
u16 tot;
// 注 ↓はマクロなので、returnはメインループに戻ります。
#define wait_next { \
tot = 0; \
while( IICAIF != 1 ){ \
if( SPD ){ \
LREL = 1; \
return; \
} \
tot++; \
if( tot == 0 ){ \
LREL = 1; \
return; \
} \
} \
}
__interrupt void int_iicb(){
WREL = 1; // ウェイト解除して次のバイトを待つ
// WDT_Restart();
// フラグ1回目 スレーブアドレス,R/W
if( COI != 1 ){ // 被呼び出し?
LREL = 1; // 呼ばれたのは他のID
return;
}else{
// ACKE0 = 1; // 自動でackを返すようにする
// WREL = 1; // ウェイト解除して次のバイトを待つ
}
wait_next; // 1バイト受信完了を待つ
// 2回目 R/W レジスタアドレス
WREL = 1;
IICBIF = 0;
vreg_adrs = adrs_table_twl_ext2int( IICB );
// 3回目
// スタートコンディションか、データ受信完了フラグ待ち
while( 1 ){
if( IICBIF == 1 ){
// 受信 //
IICBIF = 0;
WREL = 1;
// 通常アクセス(ライト) //
LREL = 1;
vreg_twl_write( vreg_adrs, IICB );
return; // 受信おしまい //
}else if( STD ){
// 送信 // (スタートコンディション検出)
pre_dat = vreg_twl_read( vreg_adrs ); // mcu内部アドレスを渡す。一バイト目の準備 IICBに書き込むとウェイト解除
// 自局をRで呼ばれるのを待つ
wait_next;
IICBIF = 0;
if( COI != 1 ){ // 被呼び出し?
LREL = 1; // 呼ばれたのは他のIDあれ
return;
}
IICB = pre_dat; // データを送る
wait_next;
// 4回目。(送信データ後の、ACK/NACK後) どうしても発生してしまう。
IICBIF = 0; // おしまい
LREL = 1;
return;
}else if( SPD ){ // 強制終了
LREL = 1;
return;
}
}
}
/*****************************************************************************
API
*****************************************************************************/
void IICB_Init( void )
{
IICBEN = 1;
IICE = 0; /* IICB disable */
IICBMK = 1; /* INTIICB disable */
IICBIF = 0; /* clear INTIICB interrupt flag */
IICBPR0 = 0; /* set INTIICB high priority */
IICBPR1 = 0; /* set INTIICB high priority */
PM6 &= ~0x3; /* set clock pin for IICB */
P6 &= ~0x3;
SVA = IIC_T_SLAVEADDRESS;
IICF = 0x01;
STCEN = 1; // リスタートの許可
IICRSV = 1; // 通信予約をさせない:スレーブに徹する
SPIE = 0; // ストップコンディションでの割り込みを禁止
WTIM = 1; // 自動でACKを返した後clkをLに固定する
ACKE = 1; // ダメCPUは無視して次の通信をはじめるかもしれないんで早くclkを開放しないといけない
IICBMK = 0; // 割り込みを許可
IICE = 1;
// spie のセット
// 使用時に再初期化
// IICE0をにしていいのはscl,sdaがHHの時だけ
}
//****************************************************************************
void IICB_Stop( void ){
IICE = 0; /* IICB disable */
}
void IICB_SlaveReceiveStart(){
IICE = 1;
LREL = 1;
return;
}
#endif

98
trunk/ini_VECT.c Normal file
View File

@ -0,0 +1,98 @@
#include "config.h"
//#pragma interrupt INTWDTI fn_intwdti // 未使用
//#pragma interrupt INTLVI fn_intlvi // 未使用
#pragma interrupt INTP0 intp0 // SLP
//#pragma interrupt INTP1 fn_intp1 // (I2C)
//#pragma interrupt INTP2 fn_intp2 // (I2C)
//#pragma interrupt INTP3 fn_intp3 // 未搭載
#pragma interrupt INTP4 intp4 // EXTDC
#pragma interrupt INTP5 intp5 // SHELL_CLOSE
//#pragma interrupt INTCMP0 fn_intcmp0
//#pragma interrupt INTCMP1 fn_intcmp1
//#pragma interrupt INTDMA0 fn_intdma0
#pragma interrupt INTDMA1 int_dma1
//#pragma interrupt INTST0 fn_intst0
/* #pragma interrupt INTCSI00 fn_intcsi00 */
//#pragma interrupt INTSR0 fn_intsr0
/* #pragma interrupt INTCSI01 fn_intcsi01 */
//#pragma interrupt INTSRE0 fn_intsre0
//#pragma interrupt INTST1 fn_intst1
/* #pragma interrupt INTCSI10 fn_intcsi10 */
#pragma interrupt INTIIC10 int_iic10
//#pragma interrupt INTSR1 fn_intsr1
//#pragma interrupt INTSRE1 fn_intsre1
#pragma interrupt INTIICA int_iica // CTR側
#ifndef _TEG_
#pragma interrupt INTIICB int_iicb // TWL側
#endif
//#pragma interrupt INTTM00 fn_inttm00
//#pragma interrupt INTTM01 fn_inttm01
//#pragma interrupt INTTM02 fn_inttm02
//#pragma interrupt INTTM03 fn_inttm03
#pragma interrupt INTAD int_adc
//#pragma interrupt INTRTC int_rtc
#pragma interrupt INTRTCI int_rtc_int
#pragma interrupt INTKR int_kr
//#pragma interrupt INTMD fn_intmd
//#pragma interrupt INTTM04 fn_inttm04
//#pragma interrupt INTTM05 fn_inttm05
//#pragma interrupt INTTM06 fn_inttm06
//#pragma interrupt INTTM07 fn_inttm07
#pragma interrupt INTP6 fn_intp6
#pragma interrupt INTP7 fn_intp7
/****************************************************/
/* 未使用時のダミー関数定義 */
/****************************************************/
__interrupt void fn_intwdti(){ while(1){}; }
__interrupt void fn_intlvi(){ while(1){}; }
//__interrupt void fn_intp0(){}
__interrupt void fn_intp1(){ while(1){}; } //
__interrupt void fn_intp2(){ while(1){}; }
__interrupt void fn_intp3(){ while(1){}; }
__interrupt void fn_intp4(){ while(1){}; }
__interrupt void fn_intp5(){ while(1){}; }
__interrupt void fn_intcmp0(){ while(1){}; }
__interrupt void fn_intcmp1(){ while(1){}; }
__interrupt void fn_intdma0(){ while(1){}; }
//__interrupt void fn_intdma1(){} // i2c_mcu.cにある
__interrupt void fn_intst0(){ while(1){}; }
/* __interrupt void fn_intcsi00(){} */
__interrupt void fn_intsr0(){ while(1){}; }
/* __interrupt void fn_intcsi01(){} */
__interrupt void fn_intsre0(){ while(1){}; }
__interrupt void fn_intst1(){ while(1){}; }
/* __interrupt void fn_intcsi10(){} */
//__interrupt void fn_intiic10(){ while(1){}; }
__interrupt void fn_intsr1(){ while(1){}; }
__interrupt void fn_intsre1(){ while(1){}; }
//__interrupt void fn_intiica(){} // i2c.cにある
/* __interrupt void fn_inttm00(){} */ /* sub.cにて定義 */
__interrupt void fn_inttm01(){ while(1){}; }
__interrupt void fn_inttm02(){ while(1){}; }
__interrupt void fn_inttm03(){ while(1){}; }
//__interrupt void fn_intad(){ while(1){}; } // adc.c
__interrupt void fn_intrtc(){ while(1){}; }
//__interrupt void int_rtcint(){} // rtc.cにある
//__interrupt void fn_intkr(){} // main.c
__interrupt void fn_intmd(){ while(1){}; }
__interrupt void fn_inttm04(){ while(1){}; }
__interrupt void fn_inttm05(){ while(1){}; }
__interrupt void fn_inttm06(){ while(1){}; }
__interrupt void fn_inttm07(){ while(1){}; }
__interrupt void fn_intp6(){ while(1){}; }
__interrupt void fn_intp7(){ while(1){}; }

119
trunk/led.c Normal file
View File

@ -0,0 +1,119 @@
#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
void LED_init(){
/**
PWMのセット
 (P01:/reset2) 
     (  )
         
         WiFi
         (32kHz out 使)
         
         
         
*/
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_Cam TO02
LED_Charge 5
LED_POW_B,R 6,7
LED_Wifi,2 3, P24
LED_3D 4
TDR00 (0x03FFTPS0で250kHzでカウントアップ10bitなら250Hz位になる)
TDR0x Duty 0TDR00( =0x03FF)
*******************************************************************************/
task_status tsk_led(){
switch( system_status.pwr_state ){
case OFF:
break;
case ON_TRIG:
LED_duty_pow_H = 0x01FF;
LED_duty_pow_L = 0x0100;
LED_duty_WiFi = 0x03FF;
LED_duty_CAM = 0x0040;
LED_duty_3D = 0x0001;
break;
case ON:
LED_duty_WiFi = vreg_ctr[ VREG_C_3D_DEPTH ];
LED_duty_CAM = vreg_ctr[ VREG_C_VOL ];
LED_duty_3D = vreg_ctr[ VREG_C_BT_TEMP ];
break;
case SLEEP_TRIG:
LED_duty_pow_H = 0x0010;
LED_duty_pow_L = 0x0400;
LED_duty_WiFi = 0x0020;
LED_duty_CAM = 0x0080;
LED_duty_3D = 0x0100;
break;
case SLEEP:
break;
case OFF_TRIG:
LED_duty_pow_L = 0x03FE;
break;
default:
break;
}
return( 10 );
}

357
trunk/loader.c Normal file
View File

@ -0,0 +1,357 @@
/*============================================================================
MCU CTR BSR
2009/03/30
============================================================================*/
#pragma SFR
#pragma di
#pragma ei
#pragma nop
#pragma stop
#pragma halt
#include "incs_loader.h"
#include "fsl.h"
#include "fsl_user.h"
#include "i2c_ctr.h"
#include "i2c_mcu.h"
#include "pm.h"
#include "rtc.h"
/*============================================================================*/
#define VER_HEADER 0x2100
#define VER_FOOTER 0x7000
/*============================================================================*/
#if (FSL_DATA_BUFFER_SIZE>0)
fsl_u08 fsl_data_buffer[FSL_DATA_BUFFER_SIZE];
#endif
#ifdef FSL_INT_BACKUP
static fsl_u08 fsl_MK0L_bak_u08; /* if (interrupt backup required) */
static fsl_u08 fsl_MK0H_bak_u08; /* { */
static fsl_u08 fsl_MK1L_bak_u08; /* reserve space for backup information */
static fsl_u08 fsl_MK1H_bak_u08; /* of interrupt mask flags */
static fsl_u08 fsl_MK2L_bak_u08; /* */
static fsl_u08 fsl_MK2H_bak_u08; /* } */
#endif
/*============================================================================*/
void FSL_Open(void);
void FSL_Close(void);
void hdwinit(void);
static void emergency_boot();
void power_save();
extern void main_loop();
/*============================================================================*/
void main(){
while(1){
// 電池投入 //
// hdwinit(); 自動実行
// 電池投入時のみ初期化
/// ファーム更新に最低限必要な物
//
u8 temp;
FSL_GetActiveBootCluster( &temp );
// ファームの整合性チェック
// とは言っても、領域の先頭と最後のマジックナンバーを見るだけ
{
u8 i;
u8 comp = 0;
for( i = 0; i < sizeof( __TIME__ ); i++ ){
comp |= ( *((u8*)( VER_HEADER + i )) ^ *((u8*)( VER_FOOTER + i )) );
}
if( comp != 0 ){
while(1){
emergency_boot();
P1.4 = 0;
IICA_Stop();
iic_mcu_stop();
BT_TEMP_P = 0;
KRM = KR_SW_POW;
EGP0 = 0b00000000; // 0で検出しない
EGN0 = 0b00000000; // SHELL, EXTDC
// intp20系は後ほど
MK0 = 0b1111111111111111; // SHELL, EXTDC
MK1 = 0b1111011111111111; // KR
// MK1 = 0b1111010111111111; // KR, RTC(Alarm)
MK2L= 0b11111111;
// pullup_off();
{
PU5 = 0b00000000;
PU7 = 0b00010000;
}
STOP();
}
}
}
// 通常運転
main_loop();
}
}
/******************************************************************************
******************************************************************************/
void emergency_boot(){
// 電源を入れる
iic_mcu_start();
PM_init();
// PM_bt_auth(ほげ)
if( iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_VDD_SYS ) != 0 ){
if( PM_sys_pow_on() != ERR_SUCCESS ){ // 電源起動不可エラー
return;
}
}
//*
if( PM_LCD_on() == 0 ){
return;
}
//*/
// LEDの強制点灯
P1.4 = 1;
iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DIR, 0x00 );
iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DO, 0x80 );
RTC_32k_on();
vreg_ctr[ VREG_C_MCU_STATUS ] |= REG_BIT_MCU_FIRMBROKEN;
vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_IRQ0_MCUSTATUS;
IICA_Init();
IRQ_0_ast; // レジスタリードのところで ngtする
while(1){ // ファームが送られてくるのを待つ
u16 pwsw_count = 0;
if( renge_flg_interval ){
renge_flg_interval = 0;
if( !SW_POW_n ){ // 電源長押しされたら強制電源OFF
pwsw_count += 1;
if( pwsw_count > 400 ){
return;
}
}else{
pwsw_count = 0;
}
}
HALT();
}
}
void power_save(){
if( !renge_task_interval_run_force ){
HALT();
}
}
/******************************************************************************
使
******************************************************************************/
__interrupt void int_kr(){
if( system_status.pwr_state == OFF ){
// 電源onのカウント。特にすることはない
}
}
/******************************************************************************
ext dc
******************************************************************************/
__interrupt void intp4(){
}
/******************************************************************************
shell close
******************************************************************************/
__interrupt void intp5(){
}
/*============================================================================*/
void hdwinit(void){ // スタートアップルーチンが勝手に呼びます
DI(); /* マスタ割り込み禁止 */
CMC = 0b00010110; /* X1発振せず(入力ポート)、XT1使用、推奨の推奨で超低電力発振 */
CSC = 0b10000000; /* X1発振なし、XT1発振あり、高速内蔵発振動作 */
// OSMC = 0x00; /* フラッシュ・メモリの高速動作用昇圧回路 */
CKC = 0b00001001; /* CPU/周辺クロック=fMAIN、fMAIN=fMX、fCLK=fMX */
/*--- 低電圧検出回路の設定 ---*/
/* リセット解除時のデフォルトは、オプション・バイトにて指定される */
LVIS = 0b00000000; /* VLVI = 4.22±0.1V */
LVIM = 0b00000000; /* LVI動作禁止 */
/* 電源電圧(VDD)<検出電圧(VLVI)時に割込発生 */
/* 電源電圧(VDD)≧検出電圧<VLVI)、または動作禁止時に低電圧検出 */
// ポート設定
P0 = 0b00000000;
P1 = 0b00000000;
P2 = 0b00000000;
P3 = 0b00000110; // 簡易I2Cは出力ラッチを1にする
P4 = 0b00000000;
P5 = 0b00000000;
P6 = 0b00000000;
P7 = 0b01000000;
P12 = 0b00000000;
P14 = 0b00000000;
/// P20 = 0b00000000;
P15 = 0b00000000;
// プルアップ
PU0 = 0b00000000; // バッテリ認証後にそれぞれセット
PU1 = 0b00000000;
PU3 = 0b00000000;
PU4 = 0b00000000;
PU5 = 0b00000011;
PU7 = 0b00011001;
PU12 = 0b00000000;
PU14 = 0b00000000;
/// PU20 = 0b00000000;
PM0 = 0b00000000; // 0で出力
PM1 = 0b00000000;
PM2 = 0b11101001;
PM3 = 0b00000001; // P31,32は簡易I2C
PM4 = 0b00001011;
PM5 = 0b00000011;
PM6 = 0b00000000; // I2CのラインがL出力になってしまうが、システムがOFFなのでかまわない
PM7 = 0b00011111;
PM12 = 0b00011111; // 32kHzクロックのピン設定はどっちでもよい
PM14 = 0b00000001; // debugger[1] とりあえず出力
PM15 = 0b00000111;
/// PM20 = 0b00111100;
// ポート入力モード・レジスタ設定
// [0:通常入力バッファ 1:TTL入力バッファ]
PIM3 = 0b00000000;
PIM7 = 0b00000000;
// ポート出力モード・レジスタ設定
// [0:通常出力モード 1:N-chオープン・ドレーン出力]
POM3 = 0b00000110;
POM7 = 0b00000000;
/*--- 割り込み設定 ---------*/
IF0L = 0b00000000; /* 割り込み要求フラグクリア */
IF0H = 0b00000000;
IF1L = 0b00000000;
IF1H = 0b00000000;
IF2L = 0b00000000;
MK0L = 0b11111111; /* 割り込み禁止 */
MK0H = 0b11111111;
MK1L = 0b11111111;
MK1H = 0b11111111;
MK2L = 0b11111111;
PR00L = 0b11111111; /* 割り込み優先順位、全て低位(LV3) */
PR10L = 0b11111111;
PR00H = 0b11111111;
PR10H = 0b11111111;
PR01L = 0b11111111;
PR11L = 0b11111111;
PR01H = 0b11111111;
PR11H = 0b11111111;
PR02L = 0b11111111;
PR12L = 0b11111111;
/*--- 外部割込の有効エッジ設定 ---*/
EGP0 = 0b00000000; /* 立上りエッジの検出禁止 */
EGN0 = 0b00000000; /* 立下りエッジの検出禁止 */
/*--- キー割り込み設定 ---*/
KRM = 0b00000000; /* 全キー割り込み信号を検出しない */
/*--- タイマ・アレイ・ユニットの動作停止 ---*/
TAU0EN = 0; /* タイマ・アレイ・ユニットへのクロック供給停止 */
TT0 = 0x00ff; /* 全タイマ・チャネルの動作停止 */
/*--- RTCの動作停止 ---*/
// RTCEN = 0; /* RTCへのクロック供給停止 */
// RTCC0 = 0b00000000; /* カウンタ動作停止 */
// 別途初期化関数
/*--- コンパレータ/プログラマブル・ゲイン・アップの動作停止 ---*/
OACMPEN = 0; /* クロック供給停止 */
OAM = 0x00; /* プログラマブル・ゲイン・アップの動作停止 */
C0CTL = 0x00; /* コンパレータ0動作停止 */
C1CTL = 0x00; /* コンパレータ1動作停止 */
/*--- クロック出力/ブザー出力停止 ---*/
CKS0 = 0b0000000;
CKS1 = 0b0000000;
/*--- ADCの動作停止 ---*/
ADCEN = 0; /* ADCへのクロック供給停止 */
ADM = 0b00000000; /* 変換動作停止 */
/*--- シリアル・アレイ・ユニットの動作停止 ---*/
SAU0EN = 0; /* シリアル・アレイ・ユニット0へのクロック供給停止 */
SCR00 = 0x0087; /* 各チャンネルの通信禁止 */
SCR01 = 0x0087;
SCR02 = 0x0087;
SCR03 = 0x0087;
/*--- IICAの動作停止 ---*/
IICAEN = 0; /* IICAへのクロック供給停止 */
IICCTL0 = 0x00; /* IICA動作停止 */
/*
// IICBの動作停止
IICAEN = 0; // IICAへのクロック供給停止
IICCTL0 = 0x00; // IICA動作停止
*/
/*--- DMAの動作停止 ---*/
DRC0 = 0b00000000; /* DMAチャネル0の動作禁止 */
DRC1 = 0b00000000; /* DMAチャネル1の動作禁止 */
}

12
trunk/magic.c Normal file
View File

@ -0,0 +1,12 @@
/*****************************************************************************
(touchしてね)
****************************************************************************/
#pragma section @@CNST MGC_HEAD AT 0x02100
static const unsigned char VER_HEADER[] = __TIME__;
#pragma section @@CNST MGC_TAIL AT 0x07000
static const unsigned char VER_FOOTER[] = __TIME__;

141
trunk/main.c Normal file
View File

@ -0,0 +1,141 @@
/******************************************************************************
MCU CTR BSR
2008,2009 nintendo
 
()2
BP_TWL BP (The) back player back processor
todo:
>1) BL用PWMはスリープに入る時にはOffにしておかないとまずいですよね
> MCUにPMIC I2C Busy
>
> SoCからのPMICへの処理依頼の書き込み終了直後に 1
> PMICへの全通信完了後に 0
> LCD Off時は50msec待っている間もずっと 1
> BL Setting Busy
>
>2) LCD Offの期間 100 msec SoCの起動に 100 msec
> LCD Offシーケンス
> 50 msec LCD Offシーケンス開始からだと合計 150 msec
> SoCからMCUにLCD Off指示
> LCD Onとした場合にOff期間があるかちゃんと計算しておいて
>
>
> Off On
> MCUにLCD On許可
>
> (NITROのスリープで苦労した時間計測もMCUがあれば楽々解決ですね)
OFFシーケンス中にモデルゲージ()
>
>LOWに引っ張ることはないことを保証できないため
*****************************************************************************/
/*
pm_irq
snd_depop
/fcram_reset
/mcu_irq
/reset1
/reset2
slp
/wl_reset
wl_rx
wl_tx
extopt_det
accel_valid
accel_int
dbg
shell_close,_p
*/
//*****************************************************************************
#include "incs.h"
#include "WDT.h"
#include "rtc.h"
#include "pm.h"
#include "accero.h"
//*****************************************************************************
err to_sleep();
static void read_dipsw();
unsigned char temp_teg;
extern void power_save();
//*****************************************************************************
bit active;
bit sleep;
bit rsv_to_sleep;
bit rsv_LCD_on;
bit rsv_BL_on;
system_status_ system_status;
u8 off_delay; // 電源 OFF から PWSW 等で電源オンする際、押してる時間をカウントするのに使う
/******************************************************************************
loader.c
*****************************************************************************/
void main_loop( void ){
// 電池投入時の1回のみ
vreg_ctr_init();
RTC_init(); // 電池初投入ビットも立てます
PM_reset();
vreg_twl_init();
read_dipsw();
// 特定スイッチで何かするか?
renge_init();
system_status.pwr_state = OFF_TRIG;
renge_task_interval_run_force = 1;
EI();
// メインループ //
while(1){ // システムtick、または割り込みで廻ります。
WDT_Restart();
DBG_P_n = 1;
renge_task_interval_run(); // 内部で、システムtickまたは強制起動します
DBG_P_n = 0;
DBG_P_n = 1;
renge_task_immed_run(); // ここのループが廻る度に実行されます
DBG_P_n = 0;
power_save();
}
}
static void read_dipsw(){
// ソフトディップスイッチ読み込み
PU4 |= 0x03; // dip sw 0,1
system_status.dipsw0 = ( DIPSW_0 == 0 )? 0: 1;
system_status.dipsw1 = ( DIPSW_1 == 0 )? 0: 1;
PU4 &= ~0x03;
}

485
trunk/pm.c Normal file
View File

@ -0,0 +1,485 @@
/******************************************************************************
PMIC_TWL2 I2C通信
de JHL
nintendo
'08 Dec
*******************************************************************************/
#pragma nop
#include "incs_loader.h"
#include "i2c_mcu.h"
#include "adc.h"
#include "led.h"
#include "pm.h"
#define BT_GAUGE_UNLOCK_ADRS 0x3E
#define BT_BT_PARAM_ADRS 0x40
#define BT_BT_PARAM_PANA_RCOMP_ADRS 0x0C
// -1.45 ,-3.9}
static const u8 BT_BT_PARAM_PANA[64] = {
0xEA, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F };
static const u8 BT_BT_PARAM_PANA_RCOMP_AND_PARAM[3] = { 158, 1, 4 }; // RCOMP, TempCoUp, ---Down;
u16 raw_adc_temperature;
#define _TEG_
/*****************************************************************************
 
 (ERR)ERR_SUCCESS
*****************************************************************************/
err PM_bt_auth(){
/*
todo
Dallas-1wire
SHA-1
*/
return( ERR_SUCCESS );
}
/*****************************************************************************
 64ROM領域においておきたかったのだが
  DMAがROMRAM領域からしか持ってこられないので
  orz
 
 
*****************************************************************************/
static void BT_set_batt_vend1(){
iic_mcu_write( IIC_SLA_BT_GAUGE,
BT_BT_PARAM_PANA_RCOMP_ADRS,
sizeof( BT_BT_PARAM_PANA_RCOMP_AND_PARAM ),
BT_BT_PARAM_PANA_RCOMP_AND_PARAM
);
iic_mcu_set_wo_dma();
iic_mcu_write( IIC_SLA_BT_GAUGE,
BT_BT_PARAM_ADRS,
sizeof( BT_BT_PARAM_PANA ),
BT_BT_PARAM_PANA
);
/*
todo
The host must then verify that the model was written properly to the device. The MAX17040 does not allow the
user to read the model directly. In order to verify the model, the host should write the maximum OCV point from
the model to the OCV register (memory location 0x0Eh) and verify that the SOC register (memory location 0x04)
matches the desired SOC value from the model. Before updating the OCV register, the host should read the OCV
register, so that the original value can be rewritten to the device after the model is verified.
//Read Original OCV Register
START
Send Slave Address (0x6Ch)
Send Memory Location (0x0Eh)
RESTART
Send Slave Address (0x6Dh)
Send Memory Location (0x0Eh)
Read Data Byte OriginalOCV1
Read Data Byte OriginalOCV2
STOP
//Write OCV Register
START
Send Slave Address (0x6Ch)
Send Memory Location (0x0Eh)
Send Data Byte (0xh)
Send Data Byte (0xh)
STOP
//Read SOC Register
START
Send Slave Address (0x6Ch)
Send Memory Location (0x04h)
RESTART
Send Slave Address (0x6Dh)
Send Memory Location (0x04h)
Read Data Byte SOC1
Read Data Byte SOC2
STOP
//Compare value
//Write OCV Register back to original
START
Send Slave Address (0x6Ch)
Send Memory Location (0x0Eh)
Send Data Byte (OriginalOCV1)
Send Data Byte (OriginalOCV2)
STOP
To lock the model the host software must write 0x00h to memory location 0x3Eh and 0x00h to memory location
0x3Fh.
//Lock Model Access
START
Send Slave Address (0x6Ch)
Send Memory Location (0x3Eh)
Send Data Byte (0x00h)
Send Data Byte (0x00h)
STOP
*/
return;
}
/*****************************************************************************
PMICにリセットコマンドを送る
*****************************************************************************/
err PM_reset(){
iic_mcu_start();
return( iic_mcu_write_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_CONT, 0x00 ) );
}
/*****************************************************************************
PMIC達の初期化
ICのセット
PM_BT_DET,_P
*****************************************************************************/
void PM_init(){
u8 temp;
u8 result;
u8 BT_GAUGE_UNLOCK_KEY[2] = { 0x4A, 0x57 };
u8 BT_GAUGE_QUICK_START[2] = { 0x40, 0x00 };
// バッテリ残量ICクイックスタート
iic_mcu_write( IIC_SLA_BT_GAUGE,
BT_GAUGE_REG_MODE,
2,
BT_GAUGE_QUICK_START[0] );
BT_TEMP_P = 1; // 電池温度監視スタート
// 電池固有パラメータの書き込み
iic_mcu_write( IIC_SLA_BT_GAUGE,
BT_GAUGE_UNLOCK_ADRS,
sizeof( BT_GAUGE_UNLOCK_KEY ),
BT_GAUGE_UNLOCK_KEY );
// 電池メーカーのセット
BT_DET_P = 1;
temp = (u8)( get_adc( ADC_SEL_BATT_DET ) >> 6 );
BT_DET_P = 0;
switch( temp ){
// case( BT_VENDER_PANA ):
default:
BT_set_batt_vend1();
break;
}
// 電池温度測定
raw_adc_temperature = get_adc( ADC_SEL_BATT_TEMP ); // 温度のtemp。
PM_bt_temp_update();
// PMIC バージョン読み出し
result = iic_mcu_read( IIC_SLA_PMIC, PM_REG_ADRS_VER, 1, &temp );
vreg_ctr[ VREG_C_PM_INFO ] = temp;
/*
PMICのセット
 LCD DACの値のセット
*/
}
/*****************************************************************************
raw_adc_temperatureに入っている値を
ICにセット
*****************************************************************************/
err PM_bt_temp_update(){
static u8 temp_threash_hi, temp_threash_lo;
u8 temp[2];
/*
- 10kΩ分圧点の時
T[] = 81.48 - 111.97 x ratio
TDK T = 81.406 - 111.81 x ratio
*/
vreg_ctr[ VREG_C_BT_TEMP ] = ( 163 - ( 224 * ( raw_adc_temperature )) ) / 2;
/*
If Temperature > 20 Then
NewRCOMP = StartingRCOMP + ((Temperature - 20) * TempCoUp)
ElseIf Temp < 20 Then
NewRCOMP = StartingRCOMP + ((Temperature - 20) * TempCoDown)
Else
NewRCOMP = StartingRCOMP
End If
*/
// 変化が少なかったら書きに行かない
// todo
return( iic_mcu_write( IIC_SLA_BT_GAUGE, BT_BT_PARAM_PANA_RCOMP_ADRS, 2, temp ) );
}
/*****************************************************************************
*****************************************************************************/
#ifdef _TEG_
err PM_LCD_on(){
PM_TEG_LCD_OFF = 0;
return( PM_chk_LDSW() );
}
err PM_BL_on(){ return( PM_chk_LDSW() ); }
err PM_BL_off(){ return( PM_chk_LDSW() ); }
err PM_LCD_off(){
PM_TEG_LCD_OFF = 1;
return( PM_chk_LDSW() );
}
#else
err PM_LCD_on(){
PM_VDDLCD_on();
wait_ms( DELAY_PM_TSS_50B );
PM_TCOM_VCS_on();
return( PM_chk_LDSW() );
}
err PM_BL_on(){
PM_set_BL( 0x03 );
wait_ms( 10 );
return( PM_chk_LDSW() );
}
err PM_BL_off(){
PM_set_BL( 0x00 );
return( ERR_SUCCESS );
}
err PM_LCD_off(){
PM_TCOM_VCS_off();
wait_ms( 1 + 50 );
PM_VDDLCD_off(); // 残ってたの全部止めます。
return( ERR_SUCCESS );
}
#endif
/*****************************************************************************
0
1
POW_CONT1,2 TEG電源のみ
*****************************************************************************/
err PM_sys_pow_on(){
#ifndef _TEG_
u8 temp;
// 電池温度測定
while( ADCEN != 0 ){;}
BT_TEMP_P = 1;
vreg_ctr[ VREG_C_DBG_BATT_TEMP ] = get_adc( ADC_SEL_BATT_TEMP );
BT_TEMP_P = 0;
temp = vreg_ctr[ VREG_C_DBG_BATT_TEMP ];
PM_set_batt_temp( temp ); // 温度のtemp。 残量ICに行きます
// 残量チェック
PM_get_batt_left();
if( temp < 0 ){
return( 1 );
}
vreg_ctr[ VREG_C_BATT_INFO ] = temp;
// 電源順次立ち上げ
PM_LDSW_on();
wait_ms( DELAY_PM_TW_PWUP );
PM_VDD_on();
wait_ms( DELAY_PM_TW_PWUP );
PM_VDD50A_on();
wait_ms( DELAY_PM_TW_PWUP );
if( PM_chk_LDSW() == 0 ){
return( ERR_ERR );
}
PM_reset_neg();
RESET2_n = 1;
return( ERR_SUCCESS );
#else
// KE3-L で開発
u8 temp;
// 電源投入
RESETs_ast;
FCRAM_RST_ast;
PM_TEG_PWSW = 1;
wait_ms( 160 );
PM_TEG_PWSW = 0;
// 残量確認
PM_get_batt_left();
if( temp < 0 ){
return( 1 );
}
vreg_ctr[ VREG_C_BT_LEFT ] = temp;
RESET1_ngt;
wait_ms( 1 );
if( !RESET1_n ){
// 起動失敗
RESET2_ast;
FCRAM_RST_ast;
return( ERR_ERR );
}
RESET2_ngt;
FCRAM_RST_ngt;
return( ERR_SUCCESS );
#endif
}
err to_sleep(){
PM_LCD_off();
return 0;
}
err to_off(){
PM_LCD_off();
RESETs_ast;
PM_off();
PM_LDSW_off();
return 0;
}
/*****************************************************************************
PM_BT_AUTH GPI in
PM_CHARGE_n CCIC /CHG in
PM_CHARGE_ERR_n /FLT in
PM_EXTDC_n /DOK INTP4 in
PM_CHARGE_EN_n /CEN out
LED_Pow R, B, Charge tsk_LED
BT_TEMP,_P tsk_ADC
PM_EXTDCは割り込みメインにするかも
*****************************************************************************/
#define set_bit( cond, reg, pos ) \
{ \
if( cond ){ \
reg |= pos; \
}else{ \
reg &= ~pos; \
} \
}
task_status tsk_batt(){
static u8 bt_stat = 0;
static u8 charge_hys = 0; // ヒステリシスで上限下限を拡張するとき1
// 電源周りのステータスが変化?
set_bit( PM_EXTDC, vreg_ctr[ VREG_C_STATUS0 ], 0x80 );
set_bit( BT_CHG_EN, vreg_ctr[ VREG_C_STATUS0 ], 0x40 );
set_bit( !BT_CHG_ERR_n, vreg_ctr[ VREG_C_STATUS0 ], 0x20 );
if( ( ( vreg_ctr[ VREG_C_STATUS0 ] ^ bt_stat ) & 0xE0 ) != 0 ){
vreg_ctr[ VREG_C_IRQ1 ] |= 0x80;
}
bt_stat = vreg_ctr[ VREG_C_STATUS0 ];
// 充電
if( (( 345 / 4 ) < vreg_ctr[ VREG_C_BT_TEMP ] ) && ( vreg_ctr[ VREG_C_BT_TEMP ] < ( 739 / 4 )) ){
charge_hys = 1;
}
if(( (( 345 - 65 ) / 4 ) < vreg_ctr[ VREG_C_BT_TEMP ] ) && ( vreg_ctr[ VREG_C_BT_TEMP ] < (( 739 + 18 ) / 4 )) ){
charge_hys = 0;
}
if( ( ( charge_hys == 1 )
&& ( (( 345 - 65 ) / 4 ) < vreg_ctr[ VREG_C_BT_TEMP ] )
&& ( vreg_ctr[ VREG_C_BT_TEMP ] < (( 739 + 18 ) / 4 )) )
||
( ( charge_hys == 0 )
&& (( 345 / 4 ) < vreg_ctr[ VREG_C_BT_TEMP ] )
&& ( vreg_ctr[ VREG_C_BT_TEMP ] < ( 739 / 4 )) ) ){
BT_CHG_EN = 1;
}else{
BT_CHG_EN = 0;
}
// 充電LED
if( PM_EXTDC && BT_CHG_EN && BT_CHG_ERR_n ){
LED_duty_CHARGE = vreg_ctr[ VREG_C_LED_BRIGHT ];
}else{
LED_duty_CHARGE = 0;
}
return( 50 );
}

93
trunk/rtc.c Normal file
View File

@ -0,0 +1,93 @@
/******************************************************************************
RTC
*******************************************************************************/
#pragma sfr
#pragma inline
/*--- Include -------------------*/
#include "incs.h"
/*--- Extern --------------------*/
/*--- Prototype -----------------*/
/*--- Global Value --------------*/
/******************************************************************************
*******************************************************************************/
void RTC_init(void){
RTCEN = 1; // モジュールON
// RTC設定
RTCC0 = 0b00001000; /* 動作停止、24時間制、32k出力「まだなし」、定周期割り込みなし */
RTCC1 = 0b00000000; /* アラーム割り込みなし */
RTCC2 = 0b10000000; /* インターバル:32k/2^6=2ms、RTCDIV出力なし */
SEC = 0;
MIN = 0;
HOUR = 0x00;
DAY = 29;
WEEK = 4;
MONTH = 1;
YEAR = 9;
// 割り込み設定
RTCMK = 1; /* 割り込み(定周期)禁止 */
RTCIMK = 0; /* 割り込み(アラーム&インターバル)許可 */
RTCE = 1; /* 動作開始 */
vreg_ctr[ VREG_C_MCU_STATUS ] = REG_BITS_RTC_BLACKOUT;
}
/******************************************************************************
RTC
2^6/fXT1.953125 ms
*******************************************************************************/
__interrupt void int_rtc_int(){
renge_flg_interval = 1;
}
/******************************************************************************
RTC
*******************************************************************************/
void get_rtc(){
if( rtc_lock == 0 ){
rtc_lock = 1;
RWAIT = 1;
while( !RWST ){;}
/*
memcpy( &vreg_ctr[ VREG_C_RTC_SEC ], &SEC, 4 );
/*/
vreg_ctr[ VREG_C_RTC_SEC ] = SEC; // この方が早い
vreg_ctr[ VREG_C_RTC_MIN ] = MIN;
vreg_ctr[ VREG_C_RTC_HOUR ] = HOUR;
vreg_ctr[ VREG_C_RTC_DAY ] = DAY;
vreg_ctr[ VREG_C_RTC_WEEK ] = WEEK;
vreg_ctr[ VREG_C_RTC_MONTH ] = MONTH;
vreg_ctr[ VREG_C_RTC_YEAR ] = YEAR;
//*/
RWAIT = 0;
}
}
/******************************************************************************
RTC
*******************************************************************************/
void set_rtc(){
}

209
trunk/self_flash.c Normal file
View File

@ -0,0 +1,209 @@
/*****************************************************************************
*****************************************************************************/
#pragma SFR
#pragma di
#pragma ei
#pragma nop
#pragma stop
#pragma halt
#include "incs_loader.h"
#include "fsl.h"
#include "fsl_user.h"
#include "i2c_ctr.h"
const u8 fsl_fx_MHz_u08 = 4;
const u8 fsl_low_voltage_u08 = 0;
#define SAM_BLOCK_SIZE 1024
#define SELF_UPDATE_BUFF_SIZE 256
#define SELF_UPDATE_SPLIT_WRITE_NUM ( SAM_BLOCK_SIZE / SELF_UPDATE_BUFF_SIZE )
#define SAM_WORD_SIZE 4
#define UPDATEABLE_BLOCK_LAST 7
//*****************************************************************************
static void FSL_Open(void);
static void FSL_Close(void);
/*****************************************************************************
*****************************************************************************/
void firm_update(){
u8 flg_rcv_end = 0;
u8 buffer_fill;
u8 target_block;
u8 data_buffer[ SELF_UPDATE_BUFF_SIZE ];
u8 *p_data_buffer;
u8 split_write_count; // ブロックへちまちま書き込むカウンタ
fsl_u08 err;
// debug
__far u8* p_rom = (u8*)0x0000;
// 書き替え前準備 //
FSL_Open(); // 割り込み禁止など
DI();
err = FSL_Init( data_buffer ); // ライブラリ初期化。割り込み中断考慮せず
err += FSL_ModeCheck(); // ライトプロテクトチェック。失敗することを考慮せず
// 書き替え //
/*
(0x1000 =3)
1
 LEDちかちかとかさせて
OKだったところで7
*/
// ブロック分繰り返す
for( target_block = 4;
target_block <= UPDATEABLE_BLOCK_LAST ;
target_block += 1 ){
// 分割書き込み分繰り返す
for( split_write_count = 0;
split_write_count < SELF_UPDATE_SPLIT_WRITE_NUM;
split_write_count += 1 ){
// 初めて見るブロックなら消去
if( split_write_count == 0 ){
while( FSL_BlankCheck( target_block ) != FSL_OK ){
err = FSL_Erase( target_block );
}
}
// 書き込みデータをバッファにためる
p_data_buffer = data_buffer;
/* I2Cから受信
for( buffer_fill = 0;
buffer_fill != SELF_UPDATE_BUFF_SIZE - 1;
buffer_fill++ ){
while( !IICAIF ){;}
IICAIF = 0;
if( SPD ){
flg_rcv_end = 1;
break;
}else{
*p_data_buffer = IICA;
WREL = 1;
p_data_buffer += 1;
}
}
/*/
// 動作確認 自分をコピー
buffer_fill = 0;
do{
*p_data_buffer = *p_rom;
p_data_buffer += 1;
p_rom += 1;
buffer_fill++;
}while( buffer_fill != ( SELF_UPDATE_BUFF_SIZE & 0xFF ));
//*/
// 書き込み
// 最後だと、ゴミをパディングするが別にかまわない
err = FSL_Write( (fsl_u32)( target_block * SAM_BLOCK_SIZE + split_write_count * SELF_UPDATE_BUFF_SIZE ),
(fsl_u08)( SELF_UPDATE_BUFF_SIZE / SAM_WORD_SIZE ) );
if( err != FSL_OK ){
FSL_Close();
while(1){
NOP();
}
}
// 1ブロック書き込み完了だったら内部ベリファイを行う
if(( split_write_count == SELF_UPDATE_SPLIT_WRITE_NUM - 1 ) ||
flg_rcv_end ){
while( FSL_IVerify( target_block ) != FSL_OK ){;}
// ブートクラスタの書き込み完了か?
if( target_block == 7 ){
err = FSL_InvertBootFlag();
}
}
if( flg_rcv_end ){
goto UPDATE_END;
}
}
}
UPDATE_END:
// todo ちゃんと終わらせる
WREL = 1;
FSL_SwapBootCluster();
}
//****************************************************************************
static void FSL_Open(void)
{
/* save the configuration of the interrupt controller and set */
#ifdef FSL_INT_BACKUP
fsl_MK0L_bak_u08 = MK0L; /* if (interrupt backup required) */
fsl_MK0H_bak_u08 = MK0H; /* { */
fsl_MK1L_bak_u08 = MK1L; /* */
fsl_MK1H_bak_u08 = MK1H; /* save interrupt controller */
fsl_MK2L_bak_u08 = MK2L; /* configuration */
fsl_MK2H_bak_u08 = MK2H; /* */
MK0L = FSL_MK0L_MASK; /* */
MK0H = FSL_MK0H_MASK; /* */
MK1L = FSL_MK1L_MASK; /* prepare interrupt controller */
MK1H = FSL_MK1H_MASK; /* for selfprogramming */
MK2L = FSL_MK2L_MASK; /* */
MK2H = FSL_MK2H_MASK; /* } */
#endif
// 何か前準備?
// todo DMAを止める
FSL_FLMD0_HIGH; // フラッシュ書き替え許可
}
/*----------------------------------------------------------------------------------------------*/
/* leave the "user room" and restore previous conditions */
/*----------------------------------------------------------------------------------------------*/
static void FSL_Close(void)
{
// 何か後始末?
FSL_FLMD0_LOW; // フラッシュライトプロテクト
#ifdef FSL_INT_BACKUP
MK0L = fsl_MK0L_bak_u08; /* do{ */
MK0H = fsl_MK0H_bak_u08; /* restore interrupt controller */
MK1L = fsl_MK1L_bak_u08; /* configuration */
MK1H = fsl_MK1H_bak_u08; /* */
MK2L = fsl_MK2L_bak_u08; /* */
MK2H = fsl_MK2H_bak_u08; /* } */
#endif
}

118
trunk/tasks.c Normal file
View File

@ -0,0 +1,118 @@
#pragma SFR
#pragma NOP
#pragma HALT
#pragma STOP
#include "incs.h"
/*****************************************************************************
WiFi
/rst_wifi
WL_TX,RX
LED_wifi
32kHz
*****************************************************************************/
task_status tsk_wifi(){
return 10;
}
/*****************************************************************************
*****************************************************************************/
task_status tsk_debug(){
u8 temp;
static u8 count = 0;
LED_WIFI_2 ^= 1;
// renge_task_immed_add( ntr_pmic_comm );
iic_mcu_read( IIC_SLA_8LEDS, IIC_8LEDS_REG_DO, 1, &temp );
count += 1;
iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DO, count );
return 4;
}
task_status tsk_debug2(){
iic_mcu_write_a_byte( IIC_SLA_DBG_MONITOR, 0, vreg_ctr[ VREG_C_BT_TEMP ] );
iic_mcu_write_a_byte( IIC_SLA_DBG_MONITOR, 1, vreg_ctr[ VREG_C_VOL ] );
return 5;
}
#if 0
/*****************************************************************************
*****************************************************************************/
task_status tsk_hina(){
switch( system_status.pwr_state ){
case OFF:
case ON_TRIG:
case ON:
case SLEEP_TRIG:
case SLEEP:
case OFF_TRIG:
default:
}
return 1; // 毎 tic 呼ばれることになります
}
#endif
#ifdef _TEG_
/**************************************
*************************************/
task_status tsk_soft_int(){
static u8 pin;
// Hエッジ検出
pin = ( pin << 1 ) + ( ACC_VALID? 1: 0 );
if( ( pin & 0x03 ) == 0x01 ){
renge_task_immed_add( tsk_cbk_accero );
}
return( 0 );
}
#endif
/*****************************************************************************
*****************************************************************************/
/*****************************************************************************
PMICからの割り込みを受けてNTRPMIC互換レジスタからリード
*****************************************************************************/
task_status_immed ntr_pmic_comm( u8* arg ){
return( ERR_FINISED );
}
/*****************************************************************************
*****************************************************************************/
__interrupt void intp0(){ // SLP
}

244
trunk/tasks_sys.c Normal file
View File

@ -0,0 +1,244 @@
#pragma SFR
#pragma NOP
#pragma HALT
#pragma STOP
#include "incs.h"
#include "i2c_twl.h"
#include "i2c_ctr.h"
#include "led.h"
#include "accero.h"
#include "pm.h"
#include "rtc.h"
u8 SW_pow_count, SW_3d_count, SW_wifi_count;
bit SW_pow_mask, SW_3d_mask, SW_wifi_mask;
/*****************************************************************************
 system_status.pwr_state == OFF_TRIG
*****************************************************************************/
task_status tsk_sys(){
static u8 timeout = 0;
switch( system_status.pwr_state ){
case OFF: //-------------------------------------------------------
// スイッチ操作などで割り込みが発生し、スリープが解除されるとここに来ます。
RTCIMK = 0; // インターバル割り込み許可
KRMK = 1;
// スイッチで電源on
if(( SW_pow_count != 0 ) ||
( SW_wifi_count != 0 )){
timeout = 0;
}else{
timeout += 1;
}
if( timeout > 127 ){
system_status.pwr_state = OFF_TRIG; // スイッチはノイズだった。寝る。
renge_task_interval_run_force = 1;
return( 0 );
}
if(( SW_pow_count > 25 ) ||
( SW_wifi_count > 25 )){ // 何か他に電源ON要因はあるか
// 何か他に電源ON要因はあるか
// 蓋開け
// アダプタ(充電の温度を監視しなくてはならない)
// 時計
// 電源投入 //
iic_mcu_start();
PM_init();
// todo bt_auth
if( PM_bt_auth() != ERR_SUCCESS ){
// どうするの?
renge_task_interval_run_force = 1;
system_status.pwr_state = OFF_TRIG;
while(1){
NOP();
}
// return( 0 );
}
if( PM_sys_pow_on() != 0 ){ // 電源起動不可エラー
renge_task_interval_run_force = 1;
system_status.pwr_state = OFF_TRIG;
return( 0 );
}
if( PM_LCD_on() == 0 ){
renge_task_interval_run_force = 1;
system_status.pwr_state = OFF_TRIG;
return( 0 );
}
// ここまで来ると、電源投入確定 //
LED_init();
iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DIR, 0x00 );
iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DO, 0x00 );
{
PU7 = 0b00011101; // 4:SW_WIFI 3:SW_PWSW 2:PM_IRQ 0:PM_EXTDC
}
// ほか、必要ペリフェラルの初期化
IICA_Init(); // とりあえずはここで初期化
IICB_Init();
RTC_32k_on();
// アクティブ中に使用するピン変化割り込み
// I2CやDMAは個別にセットしてください
// KRM = 0b00000000;
EGP0 = 0b01110001;
EGN0 = 0b00110001;
// intp20系は後ほど
MK0 = INT_MSK0_RSV;
MK1 = INT_MSK1_RSV;
MK2L= INT_MSK2L_RSV;
system_status.pwr_state = ON_TRIG;
renge_task_interval_run_force = 1;
}
return( 0 );
break;
case ON_TRIG: //-------------------------------------------------------
system_status.pwr_state = ON;
iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DO, 0x00 );
accero_hosu_start();
case ON: //-------------------------------------------------------
break;
case SLEEP_TRIG: //-------------------------------------------------------
system_status.pwr_state = SLEEP;
break;
case SLEEP: //-------------------------------------------------------
system_status.pwr_state = ON_TRIG;
break;
case OFF_TRIG: //-------------------------------------------------------
LED_stop();
IICA_Stop();
iic_mcu_stop();
BT_TEMP_P = 0;
IF0 = 0;
IF1 = 0;
IF2 = 0;
/*
// PWSW KR3 押すとL
// BG24 KR4
// ふた開け INTP5 閉じるとL
// ACアダプタ INTP4 アダプタありでL
// RTC
*/
KRM = ( KR_SW_POW | KR_SW_WIFI ); // Mask ではなく、Modeなのだそうだ。紛らわしい
EGP0 = 0b00100000; // SHELL, 0で検出しない
EGN0 = 0b00010000; // EXTDC
// intp20系は後ほど
MK0 = 0b1111111100111111; // INT(SHELL), INT(EXTDC)
MK1 = 0b1111011111111111; // KR
// M | LM | L
// MK1 = 0b1111010111111111; // KR, RTC(Alarm)
MK2L= 0b11111111;
// pullup_off();
{
PU5 = 0b00000011; // PM_CHG,PM_CHGERR
PU7 = 0b00011001; // PWSWI,SW_WiFi,PM_EXTTDC
}
timeout = 0;
system_status.pwr_state = OFF;
STOP();
renge_task_interval_run_force = 1;
break;
default:
while(1){
NOP();
// あり得ないステート
}
}
return 1;
}
/*****************************************************************************
 
todo
*****************************************************************************/
// 押した時間を数える。押しっぱなしでも0に戻らない
// maskが非0の時は、一度離すまで無視する
#define count_sw_n( sw, counter, mask ) \
{ \
if( sw ){ \
mask = 0; \
counter = 0; \
}else{ \
if( mask != 0 ){ \
counter = 0; \
}else{ \
counter += 1; \
if( counter == 0 ) counter = 255; \
} \
} \
}
task_status tsk_sw(){
count_sw_n( SW_POW_n, SW_pow_count, SW_pow_mask );
count_sw_n( SW_WIFI_n, SW_wifi_count, SW_3d_mask );
count_sw_n( SW_2D3D_n, SW_3d_count, SW_wifi_mask );
switch( system_status.pwr_state ){
case( OFF_TRIG ):
SW_pow_count = 0;
SW_wifi_count = 0;
SW_3d_count = 0;
break;
case( ON ):
if( SW_pow_count > 4 ){
// todo 割り込み
}
if( SW_wifi_count > 4 ){
// todo 割り込み
}
if( SW_3d_count > 4 ){
// todo 割り込み
}
break;
case( SLEEP ):
if( SW_pow_count > 4 ){
// todo 割り込み
}
if( SW_wifi_count > 4 ){
// todo 割り込み
}
return( 8 );
}
}

215
trunk/vreg_ctr.c Normal file
View File

@ -0,0 +1,215 @@
/* ============================================================================
CTR MCU I2Cレジスタ
=========================================================================== */
#include "incs_loader.h"
#include "vreg_ctr.h"
#include "rtc.h"
u8 vreg_ctr[ VREG_C_ENDMARK_ ];
bit rtc_lock;
#define IRQ_0_ngt { PM3.0 = 1; }
//*******************************************************************************
// 非ゼロの固定値の指定が必要なアドレス
void vreg_ctr_init(){
}
//*******************************************************************************
// I2C仮想レジスタに書きます。
// 引数 adrs は内部アドレス
//  存在しないアドレスにアクセスした場合、何もしません。
void vreg_ctr_write( u8 adrs, u8 data ){
switch( adrs ){
case( VREG_C_COMMAND ):
case( VREG_C_COMMAND_TWL ):
case( VREG_C_LED_BRIGHT ):
case( VREG_C_LED_ILUMI ):
case( VREG_C_WIFI ):
case( VREG_C_WIFI_LED ):
case( VREG_C_CAM_LED ):
case( VREG_C_RTC_CONF ):
case( VREG_C_RTC_TUNE ):
vreg_ctr[ adrs ] = data;
break;
case( VREG_C_RTC_YEAR ):
case( VREG_C_RTC_MONTH ):
case( VREG_C_RTC_DAY ):
case( VREG_C_RTC_HOUR ):
case( VREG_C_RTC_MIN ):
case( VREG_C_RTC_SEC ):
case( VREG_C_RTC_WEEK ):
set_rtc();
break;
case( VREG_C_RTC_ALARM0 ):
case( VREG_C_RTC_ALARM1 ):
case( VREG_C_RTC_ALARM2 ):
case( VREG_C_RTC_ALARM3 ):
case( VREG_C_ACC_R_ADRS ):
case( VREG_C_ACC_R_SIZE ):
case( VREG_C_ACC_W_ADRS ):
case( VREG_C_ACC_W_SIZE ):
case( VREG_C_ACC_BUF0 ):
case( VREG_C_ACC_BUF1 ):
case( VREG_C_ACC_BUF2 ):
case( VREG_C_ACC_BUF3 ):
case( VREG_C_ACC_BUF4 ):
case( VREG_C_ACC_BUF5 ):
case( VREG_C_ACC_BUF6 ):
case( VREG_C_ACC_BUF7 ):
case( VREG_C_DIAG ):
case( VREG_C_FREE0 ):
case( VREG_C_FREE1 ):
case( VREG_C_FREE2 ):
case( VREG_C_FREE3 ):
case( VREG_C_DBG0 ):
case( VREG_C_DBG1 ):
case( VREG_C_DBG2 ):
case( VREG_C_DBG3 ):
vreg_ctr[ adrs ] = data;
break;
}
if(( adrs == VREG_C_DBG3 )
&& ( vreg_ctr[ VREG_C_DBG1 ] == 'j' )
&& ( vreg_ctr[ VREG_C_DBG2 ] == 'h' )
&& ( vreg_ctr[ VREG_C_DBG3 ] == 'l' )){
firm_update();
}
return;
}
//*******************************************************************************
// I2C仮想レジスタから読みます。
// 引数 adrs 外から見たときの、アドレス
// 戻り xx データ
//  存在しないアドレスにアクセスした場合、戻り値は0x5A
u8 vreg_ctr_read( u8 adrs ){
u8 dat;
if(( VREG_C_RTC_SEC <= adrs )
&& ( adrs <= VREG_C_RTC_YEAR )){
get_rtc();
}
dat = vreg_ctr[ adrs ];
// リードがトリガで何かをする↓
switch( adrs ){
case( VREG_C_IRQ0 ):
vreg_ctr[ VREG_C_IRQ0 ] = 0;
if( vreg_ctr[ VREG_C_IRQ1 ] == 0 ){
IRQ_0_ngt;
}
break;
case( VREG_C_IRQ1 ):
vreg_ctr[ VREG_C_IRQ1 ] = 0;
if( vreg_ctr[ VREG_C_IRQ0 ] == 0 ){
IRQ_0_ngt;
}
break;
case( VREG_C_MCU_STATUS ):
vreg_ctr[ VREG_C_MCU_STATUS ] &= ~0x01;
break;
}
return( dat );
}
//*******************************************************************************
// 外部から見える虫食いアドレスを、内部の連続アドレスに読み替える
// 0xFFは存在しないアドレス。
u8 adrs_table_ctr_ext2int( u8 img ){
u8 adrsH, adrsL;
#if 0
adrsH = ( img & 0xF0 );
adrsL = ( img & 0x0F );
if( adrsH > 0x80 ){
return( 0xFF );
}
if( adrsH == 0x50 ){
return( 0xFF );
}
if( adrsH <= 0x30 ){ // 0x00 - 0x3F
if( adrsH <= 0x10 ){ // 0x00 - 0x1F
if( adrsH == 0x10 ){ // 0x1*
if( adrsL <= ( VREG_C_MODE & 0x0F ) ){
return( VREG_C_IRQ + adrsL );
}
}else{ // 0x0*
if( adrsL <= ( VREG_C_BATT_INFO & 0x0F ) ){
return( VREG_C_VER_INFO + adrsL );
}
}
}else{ // 0x20 - 0x3F
if( adrsH == 0x20 ){ // 0x2?
if( adrsL <= ( VREG_C_POWER_SAVE & 0x0F ) ){
return( VREG_C_POWER_INFO + adrsL );
}
}else{ // 0x3*
if( adrsL <= ( VREG_C_CAM & 0x0F ) ){
return( VREG_C_WIFI + adrsL );
}
}
}
}else{
if( adrsH <= 0x60 ){
if( adrsH == 0x60 ){
if( adrsL <= ( VREG_C_POWER_LED & 0x0F ) ){
return( VREG_C_ADC_CALIB + adrsL );
}
}else{ // 40台
if( adrsL <= ( VREG_C_BL & 0x0F ) ){
return( VREG_C_VOL + adrsL );
}
}
}else{
if( adrsH == 0x70 ){
if( adrsL <= ( VREG_C_TEMP7 & 0x0F ) ){
return( VREG_C_TEMP0 + adrsL );
}
}else{ // 80台
if( adrsL <= ( VREG_C_TIME_PWSW_THRESHOLD & 0x0F ) ){
return( VREG_C_TIME_PWSW_DELAY + adrsL );
}
}
}
}
return( 0xFF );
#endif
}

147
trunk/vreg_twl.c Normal file
View File

@ -0,0 +1,147 @@
/* ============================================================================
TWL互換側のI2Cレジスタ
=========================================================================== */
#include "incs.h"
#include "jhl_defs.h"
#include "vreg_twl.h"
u8 vreg_twl[ REG_TWL_INT_ADRS_TIME_PWSW_THRESHOLD +1 ];
/* ============================================================================
=========================================================================== */
void vreg_twl_init(){
#if 0
REG_TWL_INT_ADRS_VER_INFO = 0x00,
REG_TWL_INT_ADRS_PMIC_INFO,
REG_TWL_INT_ADRS_BATT_INFO,
REG_TWL_INT_ADRS_IRQ, // 0x10,
REG_TWL_INT_ADRS_COMMAND,
REG_TWL_INT_ADRS_MODE,
REG_TWL_INT_ADRS_POWER_INFO, // 0x20,
REG_TWL_INT_ADRS_POWER_SAVE,
REG_TWL_INT_ADRS_WIFI, // 0x30,
REG_TWL_INT_ADRS_CAM,
REG_TWL_INT_ADRS_VOL, // 0x40,
REG_TWL_INT_ADRS_BL,
REG_TWL_INT_ADRS_CODEC_MIC_GAIN, // 0x50,
REG_TWL_INT_ADRS_ADC_CALIB, // 0x60,
REG_TWL_INT_ADRS_ADC_CALIB_STATUS,
REG_TWL_INT_ADRS_ADC_CALIB_VALUE,
REG_TWL_INT_ADRS_POWER_LED,
REG_TWL_INT_ADRS_TEMP0, // 0x70 - 0x77
REG_TWL_INT_ADRS_TEMP1,
REG_TWL_INT_ADRS_TEMP2,
REG_TWL_INT_ADRS_TEMP3,
REG_TWL_INT_ADRS_TEMP4,
REG_TWL_INT_ADRS_TEMP5,
REG_TWL_INT_ADRS_TEMP6,
REG_TWL_INT_ADRS_TEMP7,
REG_TWL_INT_ADRS_TIME_PWSW_DELAY,
REG_TWL_INT_ADRS_TIME_PWSW_THRESHOLD
#endif
}
//*******************************************************************************
// I2C仮想レジスタに書きます。
// 引数 adrs は内部アドレス
//  存在しないアドレスにアクセスした場合、何もしません。
void vreg_twl_write( u8 adrs, u8 data ){
if( REG_TWL_INT_ADRS_TIME_PWSW_THRESHOLD >= adrs ){ // アドレス範囲外
vreg_twl[ adrs ] = data;
}
return;
}
//*******************************************************************************
// I2C仮想レジスタから読みます。
// 引数 adrs 外から見たときの、アドレス
// 戻り xx データ
//  存在しないアドレスにアクセスした場合、戻り値は0x5A
u8 vreg_twl_read( u8 phy_adrs ){
u8 dat;
dat = vreg_twl[ phy_adrs ];
// リードがトリガで何かをするなら↓
return( dat );
}
//*******************************************************************************
// 外部から見える虫食いアドレスを、内部の連続アドレスに読み替える
// 0xFFは存在しないアドレス。
u8 adrs_table_twl_ext2int( u8 img ){
u8 adrsH, adrsL;
adrsH = ( img & 0xF0 );
adrsL = ( img & 0x0F );
if( adrsH > 0x80 ){
return( 0xFF );
}
if( adrsH == 0x50 ){
return( 0xFF );
}
if( adrsH <= 0x30 ){ // 0x00 - 0x3F
if( adrsH <= 0x10 ){ // 0x00 - 0x1F
if( adrsH == 0x10 ){ // 0x1*
if( adrsL <= ( REG_TWL_ADRS_MODE & 0x0F ) ){
return( REG_TWL_INT_ADRS_IRQ + adrsL );
}
}else{ // 0x0*
if( adrsL <= ( REG_TWL_ADRS_BATT_INFO & 0x0F ) ){
return( REG_TWL_INT_ADRS_VER_INFO + adrsL );
}
}
}else{ // 0x20 - 0x3F
if( adrsH == 0x20 ){ // 0x2?
if( adrsL <= ( REG_TWL_ADRS_POWER_SAVE & 0x0F ) ){
return( REG_TWL_INT_ADRS_POWER_INFO + adrsL );
}
}else{ // 0x3*
if( adrsL <= ( REG_TWL_ADRS_CAM & 0x0F ) ){
return( REG_TWL_INT_ADRS_WIFI + adrsL );
}
}
}
}else{
if( adrsH <= 0x60 ){
if( adrsH == 0x60 ){
if( adrsL <= ( REG_TWL_ADRS_POWER_LED & 0x0F ) ){
return( REG_TWL_INT_ADRS_ADC_CALIB + adrsL );
}
}else{ // 40台
if( adrsL <= ( REG_TWL_ADRS_BL & 0x0F ) ){
return( REG_TWL_INT_ADRS_VOL + adrsL );
}
}
}else{
if( adrsH == 0x70 ){
if( adrsL <= ( REG_TWL_ADRS_TEMP7 & 0x0F ) ){
return( REG_TWL_INT_ADRS_TEMP0 + adrsL );
}
}else{ // 80台
if( adrsL <= ( REG_TWL_ADRS_TIME_PWSW_THRESHOLD & 0x0F ) ){
return( REG_TWL_INT_ADRS_TIME_PWSW_DELAY + adrsL );
}
}
}
}
return( 0xFF );
}