mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-10-31 13:51:10 -04:00
210 lines
6.7 KiB
C
210 lines
6.7 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 = 4;
|
||
const u8 fsl_low_voltage_u08 = 0;
|
||
|
||
|
||
#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
|
||
#define UPDATEABLE_BLOCK_LAST 7
|
||
//*****************************************************************************
|
||
static void FSL_Open(void);
|
||
static void FSL_Close(void);
|
||
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
*****************************************************************************/
|
||
void firm_update(){
|
||
u8 flg_rcv_end = 0;
|
||
u8 buffer_fill;
|
||
u8 target_block;
|
||
u8 data_buffer[ SELF_UPDATE_BUFF_SIZE ];
|
||
u8 *p_data_buffer;
|
||
u8 split_write_count; // ブロックへちまちま書き込むカウンタ
|
||
fsl_u08 err;
|
||
|
||
// debug
|
||
__far u8* p_rom = (u8*)0x0000;
|
||
|
||
// 書き替え前準備 //
|
||
FSL_Open(); // 割り込み禁止など
|
||
DI();
|
||
|
||
err = FSL_Init( data_buffer ); // ライブラリ初期化。割り込み中断考慮せず
|
||
err += FSL_ModeCheck(); // ライトプロテクトチェック。失敗することを考慮せず
|
||
|
||
// 書き替え //
|
||
/*
|
||
●アクティブでない方のブートクラスタ (0x1000 =ブロック3) から、ストップコンディションが来るまで
|
||
消しては書き、消しては書きする。
|
||
●各ブロック、内部ベリファイをして、だめだったら1回リトライする。
|
||
それでもだなら、LEDちかちかとかさせて、サービス送りにしてもらう
|
||
●ベリファイがOKだったところで、それがブロック7だったら、スワップを行う。
|
||
後はひたすら終わるまで続けるか、
|
||
書き替えては行けない領域に行きそうなら止める(無いと思うが)
|
||
●終わったら、リセットベクタに飛ばす。
|
||
*/
|
||
|
||
|
||
// ブロック分繰り返す
|
||
for( target_block = 4;
|
||
target_block <= UPDATEABLE_BLOCK_LAST ;
|
||
target_block += 1 ){
|
||
|
||
// 分割書き込み分繰り返す
|
||
for( split_write_count = 0;
|
||
split_write_count < SELF_UPDATE_SPLIT_WRITE_NUM;
|
||
split_write_count += 1 ){
|
||
|
||
// 初めて見るブロックなら消去
|
||
if( split_write_count == 0 ){
|
||
while( FSL_BlankCheck( target_block ) != FSL_OK ){
|
||
err = FSL_Erase( target_block );
|
||
}
|
||
}
|
||
|
||
// 書き込みデータをバッファにためる
|
||
p_data_buffer = data_buffer;
|
||
|
||
|
||
/* I2Cから受信
|
||
for( buffer_fill = 0;
|
||
buffer_fill != SELF_UPDATE_BUFF_SIZE - 1;
|
||
buffer_fill++ ){
|
||
while( !IICAIF ){;}
|
||
IICAIF = 0;
|
||
if( SPD ){
|
||
flg_rcv_end = 1;
|
||
break;
|
||
}else{
|
||
*p_data_buffer = IICA;
|
||
WREL = 1;
|
||
p_data_buffer += 1;
|
||
}
|
||
}
|
||
|
||
/*/
|
||
// 動作確認 自分をコピー
|
||
buffer_fill = 0;
|
||
do{
|
||
*p_data_buffer = *p_rom;
|
||
p_data_buffer += 1;
|
||
p_rom += 1;
|
||
buffer_fill++;
|
||
}while( buffer_fill != ( SELF_UPDATE_BUFF_SIZE & 0xFF ));
|
||
//*/
|
||
|
||
// 書き込み
|
||
// 最後だと、ゴミをパディングするが別にかまわない
|
||
err = 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 ) );
|
||
|
||
if( err != FSL_OK ){
|
||
FSL_Close();
|
||
while(1){
|
||
NOP();
|
||
}
|
||
}
|
||
|
||
// 1ブロック書き込み完了だったら内部ベリファイを行う
|
||
if(( split_write_count == SELF_UPDATE_SPLIT_WRITE_NUM - 1 ) ||
|
||
flg_rcv_end ){
|
||
while( FSL_IVerify( target_block ) != FSL_OK ){;}
|
||
|
||
// ブートクラスタの書き込み完了か?
|
||
if( target_block == 7 ){
|
||
err = FSL_InvertBootFlag();
|
||
}
|
||
}
|
||
|
||
if( flg_rcv_end ){
|
||
goto UPDATE_END;
|
||
}
|
||
}
|
||
}
|
||
UPDATE_END:
|
||
|
||
// todo ちゃんと終わらせる
|
||
WREL = 1;
|
||
|
||
FSL_SwapBootCluster();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//****************************************************************************
|
||
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を止める
|
||
|
||
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
|
||
}
|
||
|
||
|
||
|
||
|