ctr_mcu/trunk/loader.c
n2232 0473a08f39 注意事項、OSMCのセットの後3clk待つのを忘れていた。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@377 013db118-44a6-b54f-8bf7-843cb86687b1
2011-08-24 12:34:18 +00:00

382 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ========================================================
MCU CTR BSR
2009/03/30
開発技術部 藤田
ブートローダー部
ホストの通信と、自己書き換え、ファームのチェックを行う。
======================================================== */
#ifndef _WIN32
#pragma SFR
#pragma di
#pragma ei
#pragma nop
#pragma stop
#pragma halt
#pragma opc
#endif
#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 hdwinit();
static void hdwinit2();
static void chk_platform_type();
static void chk_firm_broke();
extern void main_loop();
// ========================================================
void main( )
{
while( 1 )
{
WDT_Restart( );
if( RTCEN ) // これはTRAP(自己update)にしか使えない。WDT等では立たない
{
system_status.reboot = true;
}
{
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 = true;
}
else if( ( my_resf & REG_BIT_RESF_TRAP ) != 0 ) // ( FSL_ForceReset, 'r' )
{
system_status.reboot = true;
}
/* LVI使用せず
else if(( my_resf & REG_BIT_RESF_LVI ) != 0 )
{
vreg_ctr[ VREG_C_MCU_STATUS ] |= ( 1 << 2 );
}
*/
}
//* ROMがどうにも足りなくなったら、評価の上コメントアウト
if( !system_status.reboot )
{
// 通常の電源投入
// 電池接続時、ちょっと待ってみる(チャタリング対策)
u16 pwup_delay0;
for( pwup_delay0 = 0xFFFF; pwup_delay0 != 0; pwup_delay0 -- ){;};
}
//*/
hdwinit2( );
#ifndef _WIN32
// ファームの整合性チェック //
chk_firm_broke(); // 壊れていたら帰ってこない
#endif
// 試遊台判定
chk_platform_type();
// 通常運転
main_loop( );
}
}
void chk_firm_broke()
{
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 +2 ) != ':' ) // 消去済のまま
{
comp ++;
}
if( comp != 0 )
{
// ファームリストアを試みる
firm_restore( );
// 帰ってこない。リセットをかける。
}
}
/* ========================================================
デバッガつないでると上手に判定できないことがあります。
●CTRファミリ
DEV_DET(P12.[2:1])
●CTRその開発機材
P40,41 !注意! デバッグ有効でP40がLだとMCUが起動しません
HH 実機
HL NBD試遊台
LH スタンドアロン試遊台
LL ISデバッガ
======================================================== */
void chk_platform_type()
{
// ●CTRファミリ //
system_status.family = (enum _family)( DEV_DET >> 1 ); /// あぁ...
if( system_status.family == FAMILY_SPFL )
{
pm_reg_bit_vddlcd = PM_REG_BIT_VDDLCD_AMO;
}
else
{
pm_reg_bit_vddlcd = PM_REG_BIT_VDDLCD_CGS;
}
// ●CTRその開発機材 //
// 一応初期化
system_status.is_dev = false;
system_status.taikendai = false;
system_status.taikendai_nbd = false;
switch( DIPSW )
{
case DIPSW_TAIKENDAI:
system_status.taikendai = true;
break;
case DIPSW_TAIKENDAI_NBD:
system_status.taikendai_nbd = true;
break;
case DIPSW_ISDEV:
system_status.is_dev = true;
break;
}
#ifdef _FORCE_TAIKENDAI_
system_status.taikendai = true;
#endif
#ifdef _FORCE_TAIKENDAI_NBD_
system_status.taikendai_nbd = true;
#endif
}
// ========================================================
void hdwinit( void )
{ // スタートアップルーチンが勝手に呼びます
DI( ); /* マスタ割り込み禁止 */
CMC = bits8(0,0,0,1, 0,0,0,0); /* X1発振せず(入力ポート)、XT1使用、超低電力発振は不安定に付き通常で */
CSC = bits8(1,0,0,0, 0,0,0,0); /* X1発振なし、XT1発振あり、高速内蔵発振動作 */
OSMC = 0x01; /* 隠しレジスタ */
NOP();NOP();NOP(); // 3clk開ける
CKC = bits8(0,0,0,0, 1,0,0,0); /* CPU/周辺クロック=fMAIN、fMAIN=fMX、fCLK=fMX */
/*--- 低電圧検出回路の設定 ---*/
/* リセット解除時のデフォルトは、オプション・バイトにて指定される */
LVIS = 0x00; /* VLVI = 4.22±0.1V */
// LVIM = 0x00; /* LVI動作禁止 */
/* 電源電圧(VDD)<検出電圧(VLVI)時に割込発生 */
/* 電源電圧(VDD)≧検出電圧<VLVI)、または動作禁止時に低電圧検出 */
}
/* ********************************************************
リブート時とで動きが違うもの
********************************************************** */
static void hdwinit2( )
{
// リセット後の初期値が保証されているのは省略
// ポート設定 //
if( system_status.reboot ) // リセットピンだけはすぐにセットする
{
P0 = bits8(0,0,0,0, 0,0,1,1);
P3 = bits8(0,0,0,0, 0,1,1,1); // 簡易I2Cは出力ラッチを1にする
}
else
{
// P0 = bits8(0,0,0,0, 0,0,0,0); // -,-,-,-, -,-,/reset2,/reset1
P3 = bits8(0,0,0,0, 1,1,1,0); // -,-,-,-, i2c_pu,scl_m,sda_m,/fcr_rst // 簡易I2Cは出力ラッチを1にする
}
// PM0 = bits8(1,1,1,1, 1,1,1,1); // BSRマイコンでは、reset1は監視のみになる。
PM3 = bits8(1,1,1,1, 1,0,0,0); // P31,32は簡易I2C
if( !system_status.reboot )
{
// リセット後の初期値0が保証されているのは省略
// P1 = bits8(0,0,0,0, 0,0,0,0); // bt_temp_p,bt_det_p,led_info_r,led_pow_b led_info_g,32khz_o,led_wifi,led_info_b
// P2 = bits8(0,0,0,0, 0,0,0,0); // ad_vol,ad_3d,acc_int1,led_chg, (sw_sel),(rbr_flight),(/rbr_rst),(ext_vdd33)
P4 = bits8(0,0,0,0, 1,0,0,0); // -,-,-,-, /chg_en, led_pow_r, dipsw[1,0]
P5 = bits8(0,0,0,0, 1,0,0,0); // -,-,-,-, i2c_pu,led_3d,/chg,/gyro_cs
// P6 = bits8(0,0,0,0, 0,0,0,0); // -,-,-,-, -,-,sda2,scl2
// P7 = bits8(0,0,0,0, 0,0,0,0); // slp_o,/irq,led_cam,sw_wifi, sw_pow,pm_irw,shell_close,/extdc
// P12 = bits8(0,0,0,0, 0,0,0,0); // -,-,-,xtal, xtal,dip(機種判定)[1,0],slp_i
// P14 = bits8(0,0,0,0, 0,0,0,0); // -,-,-,-, -,-,i2c_pu,i2c_pu // i2c_puのポート設定はちゃんと専用関数を使って順番に。
// P15 = bits8(0,0,0,0, 0,0,0,0); // -,-,-,-, -,-,ad_bt_det,ad_bt_temp // ADはどっちでも
// P20 = bits8(0,0,0,0, 0,0,0,0); // -,-,accel2,sw_home, wl_tx,amoled_hv,sda1,sda2。 // spfl reboot時の液晶電源のケアは後ほど
/*--- タイマ・アレイ・ユニットの動作停止 ---*/
// TAU0EN = 0; /* タイマ・アレイ・ユニットへのクロック供給停止 */
TT0 = 0x00ff; /* 全タイマ・チャネルの動作停止 */
/*--- RTCの動作停止 ---*/
// 別途初期化関数
}
/*--- 割り込み設定 ---------*/
// IF0 = 0x0000; /* 割り込み要求フラグクリア */
// IF1 = 0x0000;
// IF2 = 0x0000;
// MK0 = 0xFFFF; /* 割り込み禁止 */
// MK1 = 0xFFFF;
// MK2 = 0xFFFF;
PM20 = bits8(1,1,1,1, 1,0,0,0); // p20.2はこれよりも前にLにしておくこと
PM1 = bits8(0,0,0,0, 0,0,0,0);
PM2 = bits8(1,1,1,0, 1,0,0,1);
PM4 = bits8(1,1,1,1, 0,0,1,1);
PM5 = bits8(1,1,1,1, 1,0,1,0);
PM6 = bits8(1,1,1,1, 1,1,0,0); // I2CのラインがL出力になってしまうが、システムがOFFなのでかまわない
PM7 = bits8(0,1,0,1, 1,1,1,1);
// PM12 = bits8(1,1,1,1, 1,1,1,1); // 32kHzクロックのピン設定はどっちでもよい
PM14 = bits8(1,1,1,1, 1,1,0,0);
// PM15 = bits8(1,1,1,1, 1,1,1,1);
PU20 = bits8(0,0,0,1, 0,0,0,1);
// PU0 = bits8(0,0,0,0, 0,0,0,0); // バッテリ認証後にそれぞれセット
// PU1 = bits8(0,0,0,0, 0,0,0,0);
// PU3 = bits8(0,0,0,0, 0,0,0,0); // 外部でプルアップしないと具合が悪い。CPUがプルアップする
// PU4 = bits8(0,0,0,0, 0,0,0,0); // 外部でプルアップしてほしいtool0,1)
PU5 = bits8(0,0,0,0, 0,0,1,0);
PU7 = bits8(0,0,0,1, 1,0,0,1); // irq(7.6)cpuがpu
// PU12 = bits8(0,0,0,0, 0,0,0,0);
// PU14 = bits8(0,0,0,0, 0,0,0,0);
// ポート入力モード・レジスタ設定 /////////////////////
// [0:通常入力バッファ 1:TTL入力バッファ]
// PIM3 = bits8(0,0,0,0, 0,0,0,0);
// PIM7 = bits8(0,0,0,0, 0,0,0,0);
// ポート出力モード・レジスタ設定
// [0:通常出力モード 1:N-chオープン・ドレーン出力]
POM3 = bits8(0,0,0,0, 0,1,1,0);
// POM7 = bits8(0,0,0,0, 0,0,0,0);
/* 割り込み優先順位、全て低位(LV3) */
// PR00 = 0xFFFF;
// PR01 = 0xFFFF;
// PR10 = 0xFFFF;
PR11 = 0xFFFE;
// PR02 = 0xFFFF;
// PR12 = 0xFFFF;
/*--- 外部割込の有効エッジ設定 ---*/
EGP0 = bits8(0,0,1,1, 0,0,0,1);
EGN0 = bits8(0,1,1,1, 0,0,0,0);
EGP2 = bits8(0,0,0,0, 1,0,1,0);
// EGN2 = bits8(0,0,0,0, 0,0,0,0);
/*--- キー割り込み設定 ---*/
// KRM = bits8(0,0,0,0, 0,0,0,0); /* 全キー割り込み信号を検出しない */
/*--- ADCの動作停止 ---*/
// ADCEN = 0; /* ADCへのクロック供給停止 */
// ADM = bits8(0,0,0,0, 0,0,0,0); /* 変換動作停止 */
/*--- シリアル・アレイ・ユニットの動作停止 ---*/
// 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 = bits8(0,0,0,0, 0,0,0,0); /* DMAチャネル0の動作禁止 */
// DRC1 = bits8(0,0,0,0, 0,0,0,0); /* DMAチャネル1の動作禁止 */
/*--- クロック出力/ブザー出力停止 ---*/
// CKS0 = bits8(0,0,0,0, 0,0,0,0);
// CKS1 = bits8(0,0,0,0, 0,0,0,0);
}
/******************************************************************************
単位は ms
NOPを回すだけ、指定時間CPUを *占有します* 。
割り込みとか入るとその分遅れます。
少し誤差あります。
*****************************************************************************/
void wait_ms( u8 ms ){
u16 fine;
WDT_Restart();
while( ms != 0 ){
ms--;
fine = 860;
while( fine != 0 ){
fine --;
}
}
}