ctr_mcu/branches/1.05(sdk_0_12)/loader.c

337 lines
9.4 KiB
C

/* ========================================================
MCU CTR BSR
2009/03/30
開発技術部 藤田
ブートローダー部
ホストの通信と、自己書き換え、ファームのチェックを行う。
======================================================== */
#pragma SFR
#pragma di
#pragma ei
#pragma nop
#pragma stop
#pragma halt
#pragma opc
#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"
#include "reboot.h"
#include "magic.h"
#define REG_BIT_RESF_WDT 0x10
#define REG_BIT_RESF_TRAP 0x80
#define REG_BIT_RESF_LVI 0x01
// ========================================================
#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 hdwinit2( );
extern void main_loop( );
// ========================================================
void main( )
{
while( 1 )
{
WDT_Restart( );
if( !RTCEN ) // これは書き替えたときにしか使えない
{
// 通常の電源投入
u8 pwup_delay0 = 0;
u8 pwup_delay1 = 0;
do
{ // 電池接続時、16ms待ってみる(チャタリング対策)
pwup_delay0 += 1;
do
{
pwup_delay1 += 1;
}
while( pwup_delay1 != 0 ); // u16にするとコンパイラが怒るんだが…。
}
while( pwup_delay0 != 0 );
}
// ファームの整合性チェック //
{
u8 i;
u8 comp = 0;
// ローダーと本体は同じバージョンか?
/// 次へのアップデートの途中で終わってないか?
for( i = 0; i < sizeof( __TIME__ ); i++ ) // sizeof( __TIME__ ) = 8 らし
{
comp += ( *( __far u8 * )( MGC_LOAD + i ) == *( u8 * )( MGC_FOOT + i ) ) ? 0 : 1;
comp += ( *( u8 * )( MGC_HEAD + i ) == *( u8 * )( MGC_FOOT + i ) ) ? 0 : 1;
}
if( *( u8 * )( MGC_FOOT ) == 0xFF ) // 消去済のまま
{
comp += 1;
}
if( comp != 0 )
{
hdwinit2( );
// ファームリストアを試みる
firm_restore( );
// 帰ってこない。リセットをかける。
}
}
WDT_Restart( );
if( RTCEN ) // これは書き替えたときにしか使えない
{
system_status.reboot = 1;
}
else
{
volatile u8 my_resf = RESF; // ←読むと消え、生存区間の関係
if( ( my_resf & REG_BIT_RESF_WDT ) != 0 )
{
vreg_ctr[ VREG_C_MCU_STATUS ] |= REG_BIT_STATUS_WDT_RESET;
// set_irq( VREG_C_IRQ0, REG_BIT_IRQ_WDT_RESET );
// ↑I2Cの初期化後に行う
system_status.reboot = 1;
}
else if( ( my_resf & REG_BIT_RESF_TRAP ) != 0 ) // ( FSL_ForceReset, 'r' )
{
system_status.reboot = 1;
}
/*
else if(( my_resf & REG_BIT_RESF_LVI ) != 0 )
{
vreg_ctr[ VREG_C_MCU_STATUS ] |= ( 1 << 2 );
}
*/
hdwinit2( );
}
// 通常運転
main_loop( );
}
}
// ========================================================
void hdwinit( void )
{ // スタートアップルーチンが勝手に呼びます
DI( ); /* マスタ割り込み禁止 */
CMC = 0b00010000; /* X1発振せず(入力ポート)、XT1使用、超低電力発振は不安定に付き通常で */
// CMC = 0b00010100; /* ↑超低電力発振(不安定に付き使うな)*/
CSC = 0b10000000; /* X1発振なし、XT1発振あり、高速内蔵発振動作 */
OSMC = 0x01; /* 隠しレジスタ */
CKC = 0b00001000; /* CPU/周辺クロック=fMAIN、fMAIN=fMX、fCLK=fMX */
/*--- 低電圧検出回路の設定 ---*/
/* リセット解除時のデフォルトは、オプション・バイトにて指定される */
LVIS = 0b00000000; /* VLVI = 4.22±0.1V */
LVIM = 0b00000000; /* LVI動作禁止 */
/* 電源電圧(VDD)<検出電圧(VLVI)時に割込発生 */
/* 電源電圧(VDD)≧検出電圧<VLVI)、または動作禁止時に低電圧検出 */
}
void hdwinit2( )
{
// ポート設定 /////////////////////////////////////////
if( system_status.reboot ) // リセットピンだけはすぐにセットする
{
P0 = 0b00000011;
P3 = 0b00000111; // 簡易I2Cは出力ラッチを1にする
P14 = 0b00000000;
}
else
{
P0 = 0b00000000;
P3 = 0b00000110; // 簡易I2Cは出力ラッチを1にする
P14 = 0b00000000;
}
PM20 = 0b11111100;
P20 = 0b00000000;
PU20 = 0b00010001;
PM0 = 0b11111111; // BSRマイコンでは、reset1は監視のみになる。
PM3 = 0b11110000; // P31,32は簡易I2C
PM14 = 0b11111100; // debugger[1] とりあえず出力
P1 = 0b11000000;
P2 = 0b00000000;
P4 = 0b00001000;
P5 = 0b00000000;
P6 = 0b00000000;
P7 = 0b01000000;
P12 = 0b00000000;
P15 = 0b00000000;
PM1 = 0b00000000;
PM2 = 0b11101001;
PM4 = 0b11110011;
PM5 = 0b11110010;
PM6 = 0b11111100; // I2CのラインがL出力になってしまうが、システムがOFFなのでかまわない
PM7 = 0b01011111;
PM12 = 0b11111111; // 32kHzクロックのピン設定はどっちでもよい
PM15 = 0b11111111;
// プルアップ /////////////////////////////////////////
PU0 = 0b00000000; // バッテリ認証後にそれぞれセット
PU1 = 0b00000000;
PU3 = 0b00000000; // 外部でプルアップしないと具合が悪い。CPUがプルアップする
PU4 = 0b00000000; // 外部でプルアップしてほしいtool0,1)
PU5 = 0b00000010;
PU7 = 0b00011001;
PU12 = 0b00000000;
PU14 = 0b00000000;
// ポート入力モード・レジスタ設定 /////////////////////
// [0:通常入力バッファ 1:TTL入力バッファ]
#if 0
// デフォルト値
PIM3 = 0b00000000;
PIM7 = 0b00000000;
#endif
// ポート出力モード・レジスタ設定
// [0:通常出力モード 1:N-chオープン・ドレーン出力]
POM3 = 0b00000110;
POM7 = 0b00000000;
/*--- 割り込み設定 ---------*/
IF0 = 0x0000; /* 割り込み要求フラグクリア */
IF1 = 0x0000;
IF2 = 0x0000;
MK0 = 0xFFFF; /* 割り込み禁止 */
MK1 = 0xFFFF;
MK2 = 0xFFFF;
#if 0
// デフォルト値
PR00 = 0xFFFF; /* 割り込み優先順位、全て低位(LV3) */
PR01 = 0xFFFF;
PR10 = 0xFFFF;
PR11 = 0xFFFE;
// PR11H = 0b11111111;
// PR11L = 0b11111110;
PR02L = 0xFF;
PR12L = 0xFF;
#endif
/*--- 外部割込の有効エッジ設定 ---*/
EGP0 = 0b00110001;
EGN0 = 0b01110000;
EGP2 = 0b00001010;
EGN2 = 0b00000000;
/*--- キー割り込み設定 ---*/
KRM = 0b00000000; /* 全キー割り込み信号を検出しない */
/*--- タイマ・アレイ・ユニットの動作停止 ---*/
TAU0EN = 0; /* タイマ・アレイ・ユニットへのクロック供給停止 */
TT0 = 0x00ff; /* 全タイマ・チャネルの動作停止 */
/*--- RTCの動作停止 ---*/
// RTCEN = 0; /* RTCへのクロック供給停止 */
// RTCC0 = 0b00000000; /* カウンタ動作停止 */
// 別途初期化関数
/*--- クロック出力/ブザー出力停止 ---*/
CKS0 = 0b00000000;
CKS1 = 0b00000000;
/*--- ADCの動作停止 ---*/
ADCEN = 0; /* ADCへのクロック供給停止 */
ADM = 0b00000000; /* 変換動作停止 */
/*--- シリアル・アレイ・ユニットの動作停止 ---*/
SAU0EN = 0; /* シリアル・アレイ・ユニット0へのクロック供給停止 */
SCR00 = 0x0087; /* 各チャンネルの通信禁止 */
SCR01 = 0x0087;
SCR02 = 0x0087;
SCR03 = 0x0087;
// IICの動作停止
IICA0EN = 0; /* IICA0(CTR)へのクロック供給停止 */
IICCTL00 = 0x00; /* IICA1動作停止 */
IICA1EN = 0; // IICA1(TWL)へのクロック供給停止
IICCTL01 = 0x00; // IICA1動作停止
/*--- DMAの動作停止 ---*/
DRC0 = 0b00000000; /* DMAチャネル0の動作禁止 */
DRC1 = 0b00000000; /* DMAチャネル1の動作禁止 */
}
/******************************************************************************
単位は ms
NOPを回すだけ、指定時間CPUを *占有します* 。
割り込みとか入るとその分遅れます。
少し誤差あります。
*****************************************************************************/
void wait_ms( u8 ms ){
u16 fine;
WDT_Restart();
// まだ適当です!
while( ms != 0 ){
ms--;
fine = 860;
while( fine != 0 ){
fine -= 1;
}
}
}