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

TSボードに書き込むと動作はしますが実機との差分で以下の不具合があります。 (ベースが10.10であり、E3実機専用版と言うことで) ・加速度センサが使用できません ・音量Volが上下反転しています git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@162 013db118-44a6-b54f-8bf7-843cb86687b1
403 lines
12 KiB
C
403 lines
12 KiB
C
/* ========================================================
|
||
自己アップデータ
|
||
======================================================== */
|
||
#pragma SFR
|
||
#pragma di
|
||
#pragma ei
|
||
#pragma nop
|
||
#pragma stop
|
||
#pragma halt
|
||
|
||
|
||
#include "incs_loader.h"
|
||
|
||
#include <fsl.h>
|
||
#include "fsl_user.h"
|
||
#include "i2c_ctr.h"
|
||
|
||
|
||
|
||
// ========================================================
|
||
const u8 fsl_fx_MHz_u08 = 8;
|
||
const u8 fsl_low_voltage_u08 = 1;
|
||
|
||
|
||
// 自己フラッシュパラメータ
|
||
#define SAM_BLOCK_SIZE 1024
|
||
#define SELF_UPDATE_BUFF_SIZE 256
|
||
#define SELF_UPDATE_SPLIT_WRITE_NUM ( SAM_BLOCK_SIZE / SELF_UPDATE_BUFF_SIZE )
|
||
#define SAM_WORD_SIZE 4
|
||
|
||
// ↓ブロック番号(1ブロック=1kB)
|
||
#define INACTIVE_BOOTSECT_TOP 4
|
||
#define FIRM_TOP 8
|
||
#define FIRM_SIZE 12
|
||
#define UPDATE_BLOCK_LAST ( FIRM_TOP + FIRM_SIZE - 1 )
|
||
|
||
|
||
#ifdef _MCU_BSR_
|
||
|
||
|
||
#define ACKD ACKD1
|
||
#define ACKE ACKE1
|
||
#define COI COI1
|
||
#define IICAEN IICA1EN
|
||
#define IICAPR0 IICAPR10
|
||
#define IICRSV IICRSV1
|
||
#define IICA IICA1
|
||
#define IICAIF IICAIF1
|
||
#define IICAMK IICAMK1
|
||
#define IICAPR1 IICAPR11
|
||
#define IICCTL0 IICCTL01
|
||
#define IICE IICE1
|
||
#define IICF IICF1
|
||
#define IICS IICS1
|
||
#define IICWH IICWH1
|
||
#define IICWL IICWL1
|
||
#define LREL LREL1
|
||
#define SPD SPD1
|
||
#define SPIE SPIE1
|
||
#define STCEN STCEN1
|
||
#define STD STD1
|
||
#define SVA SVA1
|
||
#define WREL WREL1
|
||
#define WTIM WTIM1
|
||
#endif
|
||
|
||
|
||
|
||
// ========================================================
|
||
static void FSL_Open( void );
|
||
static void FSL_Close( void );
|
||
err firm_restore( );
|
||
|
||
static err my_FSL_Init();
|
||
static err firm_duplicate( __far u8 * p_rom, u8 block_dest );
|
||
|
||
|
||
|
||
// ========================================================
|
||
extern u16 pool[];
|
||
|
||
|
||
// 0.D以降 新アップデータ向け
|
||
#define N_MGC_L 0x1FF6
|
||
#define N_MGC_T 0x4FF6
|
||
|
||
|
||
|
||
/* ========================================================
|
||
I2Cで受信して、
|
||
書き込み、
|
||
チェックOK → 新ファームに切り替えて再起動
|
||
NG → 旧(現)ファームに戻して再起動
|
||
(この関数からは戻りません)
|
||
======================================================== */
|
||
err firm_update( )
|
||
{
|
||
u8 target_block;
|
||
u8 split_write_count; // ブロックへちまちま書き込むカウンタ
|
||
|
||
// 書き替え前準備 /////////////////////////////////////
|
||
my_FSL_Init();
|
||
|
||
/* ファームのバックアップ
|
||
0x2000 - 0x4FFF を
|
||
0x5000 - 0x7FFF (ブロック 20 - 31) にコピー
|
||
*/
|
||
firm_duplicate( ( __far u8 * ) 0x2000,
|
||
( 0x5000 / 0x0400 ) );
|
||
|
||
// 全ブロック削除 /////////////////////////////////////
|
||
// 電源断を判定するため、最初に全クラスタ消去する
|
||
//(新ファームが書かれるところに残ってる、以前のファームのフッタを消したい)
|
||
for( target_block = INACTIVE_BOOTSECT_TOP;
|
||
target_block <= UPDATE_BLOCK_LAST;
|
||
target_block += 1 )
|
||
{
|
||
FSL_Erase( target_block );
|
||
}
|
||
|
||
// 書き替え ///////////////////////////////////////////
|
||
// ●ストップコンディションが来るまで続ける
|
||
// ●終わったら、スタートアップルーチンに飛ぶ
|
||
for( target_block = INACTIVE_BOOTSECT_TOP;
|
||
target_block <= UPDATE_BLOCK_LAST;
|
||
target_block += 1 )
|
||
{
|
||
// 新ファーム領域削除
|
||
FSL_Erase( target_block );
|
||
|
||
// 分割書き込み
|
||
for( split_write_count = 0;
|
||
( ( split_write_count < SELF_UPDATE_SPLIT_WRITE_NUM )
|
||
&& ( !SPD ) );
|
||
split_write_count += 1 )
|
||
{
|
||
u8* p_buffer = pool;
|
||
u8 buffer_fill = 0;
|
||
|
||
WDT_Restart( );
|
||
|
||
// I2Cから書き込みデータをバッファにためる
|
||
do
|
||
{
|
||
while( !IICAIF && !SPD ){;}
|
||
IICAIF = 0;
|
||
*p_buffer = IICA;
|
||
WREL = 1;
|
||
p_buffer += 1;
|
||
buffer_fill += 1;
|
||
}
|
||
while( ( buffer_fill != ( u8 ) SELF_UPDATE_BUFF_SIZE ) && !SPD );
|
||
|
||
// 書き込み
|
||
// 最後だと、ゴミをパディングするが別にかまわない
|
||
if( FSL_Write( ( fsl_u32 ) ( target_block * SAM_BLOCK_SIZE
|
||
+
|
||
split_write_count *
|
||
SELF_UPDATE_BUFF_SIZE ),
|
||
( fsl_u08 ) ( SELF_UPDATE_BUFF_SIZE / SAM_WORD_SIZE ) )
|
||
|
||
!= FSL_OK )
|
||
{
|
||
// 書き込み後のチェックエラー
|
||
// リブートののち、リストア
|
||
// FSL_ForceReset(); // リセット
|
||
FSL_SwapBootCluster( );
|
||
// FSL_Close( );
|
||
return ( ERR_ERR );
|
||
}
|
||
|
||
}
|
||
// 1ブロック書き込み完了。内部ベリファイを行う
|
||
if( FSL_IVerify( target_block ) != FSL_OK ){
|
||
// todo 再度消去→書き込み ベリファイを繰り返すだけじゃダメでした...
|
||
NOP();
|
||
}
|
||
|
||
if( SPD )
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
LREL = 1;
|
||
|
||
// 書き込んだファームのチェック //
|
||
{
|
||
u8 i;
|
||
u8 comp = 0;
|
||
|
||
// ローダーのマジックと、本文の末尾のマジックは同じか確認
|
||
for( i = 0; i < sizeof( __TIME__ ); i++ )
|
||
{
|
||
comp += ( *( u8 * ) ( N_MGC_L + i ) == *( u8 * ) ( N_MGC_T + i ) ) ? 0 : 1;
|
||
}
|
||
if( comp == 0 )
|
||
{
|
||
FSL_InvertBootFlag( );
|
||
FSL_SwapBootCluster( ); // リセットせずに頭から。FSL_Closeは不要
|
||
// FSL_ForceReset(); // リセット
|
||
// FSL_SwapActiveBootCluster(); // ←スワップされてしまうので、続けられず暴走!
|
||
// 戻ってこない //
|
||
}
|
||
else
|
||
{
|
||
// データエラー
|
||
// リブートののち、リストア
|
||
// FSL_ForceReset(); // リセット
|
||
FSL_SwapBootCluster( );
|
||
// FSL_Close( );
|
||
// 戻ってこない //
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/* ========================================================
|
||
■ファームをバックアップ領域からリストアします。
|
||
チェック後、最後の最後でブートスワップするので、
|
||
ここではブートスワップは不要です。
|
||
|
||
======================================================== */
|
||
err firm_restore( )
|
||
{
|
||
my_FSL_Init();
|
||
|
||
/* ファームのリストア
|
||
0x4800 - 0x7FFF (ブロック 18 - 27) から
|
||
0x2000 - 0x47FF (ブロック 8 - 17) へコピー
|
||
*/
|
||
firm_duplicate( ( __far u8 * ) 0x5000,
|
||
FIRM_TOP );
|
||
|
||
// todo
|
||
// リストア失敗したら、LEDちかちかとかさせて、サービス送りにしてもらう
|
||
|
||
// リブート
|
||
// スワップは不要です!
|
||
FSL_SwapBootCluster();
|
||
// FSL_ForceReset( );
|
||
return ( ERR_SUCCESS );
|
||
}
|
||
|
||
|
||
|
||
|
||
// ========================================================
|
||
static void FSL_Open( void )
|
||
{
|
||
/* save the configuration of the interrupt controller and set */
|
||
#ifdef FSL_INT_BACKUP
|
||
fsl_MK0L_bak_u08 = MK0L; /* if (interrupt backup required) */
|
||
fsl_MK0H_bak_u08 = MK0H; /* { */
|
||
fsl_MK1L_bak_u08 = MK1L; /* */
|
||
fsl_MK1H_bak_u08 = MK1H; /* save interrupt controller */
|
||
fsl_MK2L_bak_u08 = MK2L; /* configuration */
|
||
fsl_MK2H_bak_u08 = MK2H; /* */
|
||
MK0L = FSL_MK0L_MASK; /* */
|
||
MK0H = FSL_MK0H_MASK; /* */
|
||
MK1L = FSL_MK1L_MASK; /* prepare interrupt controller */
|
||
MK1H = FSL_MK1H_MASK; /* for selfprogramming */
|
||
MK2L = FSL_MK2L_MASK; /* */
|
||
MK2H = FSL_MK2H_MASK; /* } */
|
||
#endif
|
||
|
||
// 何か前準備?
|
||
// todo DMAを止める
|
||
while( DST1 ){;}
|
||
DEN1 = 0;
|
||
|
||
MK0 = 0xFFFF;
|
||
MK1 = 0xFFFF;
|
||
MK2 = 0xFFFF;
|
||
|
||
FSL_FLMD0_HIGH; // フラッシュ書き替え許可
|
||
}
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------------------------*/
|
||
/* leave the "user room" and restore previous conditions */
|
||
/*----------------------------------------------------------------------------------------------*/
|
||
static void FSL_Close( void )
|
||
{
|
||
// 何か後始末?
|
||
|
||
FSL_FLMD0_LOW; // フラッシュライトプロテクト
|
||
|
||
#ifdef FSL_INT_BACKUP
|
||
MK0L = fsl_MK0L_bak_u08; /* do{ */
|
||
MK0H = fsl_MK0H_bak_u08; /* restore interrupt controller */
|
||
MK1L = fsl_MK1L_bak_u08; /* configuration */
|
||
MK1H = fsl_MK1H_bak_u08; /* */
|
||
MK2L = fsl_MK2L_bak_u08; /* */
|
||
MK2H = fsl_MK2H_bak_u08; /* } */
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
マイコン内でファームをコピーします。
|
||
__far u8 * p_rom コピー元の先頭アドレス
|
||
block_dest コピー先の先頭ブロック
|
||
|
||
コピー先に書けるようにmy_FSL_Initをあらかじめ実行する必要があります。
|
||
======================================================== */
|
||
static err firm_duplicate( __far u8 * p_rom,
|
||
u8 block_dest )
|
||
{
|
||
u8 target_block;
|
||
u8 split_write_count; // ブロックへちまちま書き込むカウンタ
|
||
|
||
// 書き込み先ブロックの数だけ繰り返す
|
||
for( target_block = block_dest;
|
||
target_block < block_dest + FIRM_SIZE;
|
||
target_block += 1 )
|
||
{
|
||
WDT_Restart( );
|
||
// ブロック消去
|
||
while( FSL_BlankCheck( target_block ) != FSL_OK )
|
||
{
|
||
FSL_Erase( target_block );
|
||
}
|
||
|
||
// 分割書き込み分繰り返す
|
||
for( split_write_count = 0;
|
||
split_write_count < SELF_UPDATE_SPLIT_WRITE_NUM;
|
||
split_write_count += 1 )
|
||
{
|
||
u8 buffer_fill;
|
||
u8* p_buff;
|
||
|
||
// 書き込みデータをバッファにためる
|
||
buffer_fill = 0;
|
||
p_buff = pool;
|
||
do
|
||
{
|
||
*p_buff = *p_rom;
|
||
p_rom += 1;
|
||
p_buff += 1;
|
||
buffer_fill +=1;
|
||
}
|
||
while( buffer_fill != ( u8 ) SELF_UPDATE_BUFF_SIZE );
|
||
|
||
// 書き込み
|
||
if( FSL_Write( ( fsl_u32 ) ( target_block * SAM_BLOCK_SIZE
|
||
+
|
||
split_write_count *
|
||
SELF_UPDATE_BUFF_SIZE ),
|
||
( fsl_u08 ) ( SELF_UPDATE_BUFF_SIZE / SAM_WORD_SIZE ) )
|
||
!= FSL_OK )
|
||
{
|
||
FSL_Close( );
|
||
return ( ERR_ERR );
|
||
}
|
||
}
|
||
|
||
// 1ブロック書き込み完了。内部電圧チェックを行う
|
||
while( FSL_IVerify( target_block ) != FSL_OK ){
|
||
// todo
|
||
;
|
||
}
|
||
}
|
||
return( ERR_SUCCESS );
|
||
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
======================================================== */
|
||
static err my_FSL_Init()
|
||
{
|
||
RTCE = 0;
|
||
|
||
// 書き替え前準備 //
|
||
DI( );
|
||
FSL_Open( ); // 割り込み禁止など
|
||
|
||
FSL_Init( pool ); // ライブラリ初期化。割り込み中断考慮せず
|
||
FSL_ModeCheck( ); // ライトプロテクトチェック。失敗することを考慮せず
|
||
|
||
return( ERR_SUCCESS );
|
||
}
|
||
|
||
|
||
task_status_immed tski_mcu_reset()
|
||
{
|
||
// 普通に再起動
|
||
my_FSL_Init();
|
||
FSL_Close( );
|
||
// FSL_SwapBootCluster();
|
||
FSL_ForceReset(); // リセット
|
||
|
||
// 保険? //
|
||
WDTE = 0xAA; // WDTで再起動(テスト向け)
|
||
return( ERR_SUCCESS ); // no reach
|
||
}
|