/* ======================================================== 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" // ======================================================== #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 // magic.c の記述と違わないように注意! #define MGC_LOAD 0x0FF6 #define MGC_HEAD 0x2100 #define MGC_FOOT 0x47F6 // ======================================================== void FSL_Open( void ); void FSL_Close( void ); void hdwinit( void ); void power_save( ); static void hdwinit2( ); extern void main_loop( ); // ======================================================== void main( ) { while( 1 ) { WDT_Restart( ); if( RTCEN ) { // 旧版対応 強制リセット WDTE = 0x00; /* { u8 temp; #asm mov A,PSW and A,#06h mov !_temp,A #endasm if( temp != 6 ){ // 新ファームにしてジャンプしてきた場合 while( SW_TUNE_n ){ WDT_Restart( ); DBG_LED_WIFI_on; DBG_LED_WIFI_off; } my_reboot(); }else{ // ↑で強制的にリセットベクタに"リターンした"場合 system_status.reboot = 1; while( SW_WIFI_n ){ WDT_Restart( ); DBG_LED_WIFI_2_on; DBG_LED_WIFI_2_off; } } } */ } else { 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 ); } hdwinit2( ); // ファームの整合性チェック // { u8 i; u8 comp = 0; // ローダーと本体は同じバージョンか? for( i = 0; i < sizeof( __TIME__ ); i++ ) { // sizeof( __TIME__ ) = 8 らし comp += ( *( u8 * ) ( MGC_HEAD + i ) == *( __far u8 * ) ( MGC_LOAD + i ) ) ? 0 : 1; } // 本体は壊れていないか? comp += ( *( u8 * ) ( MGC_HEAD ) == 0xFF ) ? 1 : 0; for( i = 0; i < sizeof( __TIME__ ); i++ ) { comp += ( *( u8 * ) ( MGC_HEAD + i ) == *( u8 * ) ( MGC_FOOT + i ) ) ? 0 : 1; } if( comp != 0 ) { // ファームリストアを試みる firm_restore( ); // 帰ってこない。リセットをかける。 } } // 通常運転 main_loop( ); } } /* ======================================================== キーリターン割り込み ======================================================== */ __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)≧検出電圧