mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-18 16:45:33 -04:00

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@600 013db118-44a6-b54f-8bf7-843cb86687b1
421 lines
13 KiB
C
421 lines
13 KiB
C
/* ========================================================
|
||
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 (1<<4)
|
||
#define REG_BIT_RESF_TRAP (1<<7)
|
||
#define REG_BIT_RESF_LVI (1<<0)
|
||
|
||
|
||
|
||
// ========================================================
|
||
#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 には書かない方針です。
|
||
|
||
【備考】
|
||
ファームアップデートでここに来た場合、(system_status.reboot == 1)
|
||
レジスタの値は直前の値を維持しています。
|
||
***********************************************/
|
||
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);
|
||
}
|
||
|