ctr_mcu/trunk/loader.c
n2232 5d01c4f3f1 代入なのに == にしてしまった。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@559 013db118-44a6-b54f-8bf7-843cb86687b1
2013-09-06 04:46:19 +00:00

417 lines
13 KiB
C
Raw Permalink 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 -
開発技術部 藤田
ブートローダー部
ホストの通信と、自己書き換え、ファームのチェックを行う。
$Id: loader.c 418 2011-09-22 01:35:37Z n2232 $
======================================================== */
#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 "wdt.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 にするとcrt0から見えなくなります。注意
static void hdwinit2();
static void chk_platform_type();
static void chk_firm_broke();
extern void main_loop();
/********************************************//**
* - ファームアップデート、WDT等のリセット、
* - ファームの破壊、
* - 本体種類の識別、
* - ポート、
* - 低レベルなペリフェラルの初期化をし、
*
* 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();
// HALデバッグリセット
hal_reset();
hal_update();
// RTC 初期化
RTC_init( ); // 内部でリブートか判定して初期化するか判断します
// 通常運転
main_loop( );
}
}
/********************************************//**
* マジックナンバーをチェックして、動作させようとしているファームが破損していないかチェックします。
*
* 壊れていた場合はリストアを試み、MCUはリセットします。
***********************************************/
static 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( );
// 帰ってこない。リセットをかける。
}
}
/********************************************//**
プラットフォームの判定を行い、system_statusにセットします。
デバッガつないでると上手に判定できないことがあります。
●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 ); /// あぁ...
#ifdef _DBG_FORCE_FLOWER
// 強制的に機種設定をしてデバッグしたいとき
system_status.family = FAMILY_FLOWER;
#endif
#ifdef _MCU_ARR
if( system_status.family == FAMILY_SPFL )
{
system_status.family = FAMILY_CLOSER;
}
#endif
if( system_status.family == FAMILY_CTR )
{
system_status.LCD_is_CGS = true;
}
else
{
// FAMILY_SPFL or FAMILY_SNAKE or FAMILY_FLOWER // アモルファスしか生産しない
system_status.LCD_is_CGS = false;
}
if( system_status.LCD_is_CGS == true )
{
pm_reg_bit_vddlcd = PM_REG_BIT_VDDLCD_CGS;
}
else
{
pm_reg_bit_vddlcd = PM_REG_BIT_VDDLCD_AMO;
}
set_vdd_voltages( system_status.family );
// ●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 = bits8(0,0,0,0, 0,0,0,1); /* 隠しレジスタ */
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)、または動作禁止時に低電圧検出 */
}
/********************************************//**
追加のレジスタ初期化を行います。
出来るだけ hdwinit には書かない方針です。
***********************************************/
static void hdwinit2( )
{
// ポート設定 //
// リセット後の初期値が保証されているのは省略
if( system_status.reboot ) // リセットピンだけはすぐにセットする
{
P0 = bits8(0,0,0,0, 0,0,1,1); // -,-,-,-, -,-,/reset2,/reset1
P3 = bits8(0,0,0,0, 1,1,1,1); // -,-,-,-, i2c_pu,scl_m,sda_m,/fcr_rst // 簡易I2Cは出力ラッチを1にする
}
else
{
// リセット後の初期値0が保証されているのは省略
// P0 = bits8(0,0,0,0, 0,0,0,0); // -,-,-,-, -,-,/reset2,/reset1
// 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),(-),(-),(ext_vdd33)
P3 = bits8(0,0,0,0, 1,1,1,0); // -,-,-,-, i2c_pu,scl_m,sda_m,/fcr_rst // 簡易I2Cは出力ラッチを1にする
// 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の動作停止 ---*/
// 別途初期化関数
}
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
/*--- 割り込み設定 ---------*/
// IF0 = 0x0000; /* 割り込み要求フラグクリア */
// IF1 = 0x0000;
// IF2 = 0x0000;
// MK0 = 0xFFFF; /* 割り込み禁止 */
// MK1 = 0xFFFF;
// MK2 = 0xFFFF;
// PM0 = bits8(1,1,1,1, 1,1,1,1); // BSRマイコンでは、reset1は監視のみになる。
PM1 = bits8(0,0,0,0, 0,0,0,0);
PM2 = bits8(1,1,1,0, 1,0,0,1);
PM3 = bits8(1,1,1,1, 1,0,0,0); // P31,32は簡易I2C
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);
PM20 = bits8(1,1,1,1, 1,0,0,0); // p20.2はこれよりも前にLにしておくこと
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);
}