ctr_mcu/trunk/self_flash.c

210 lines
6.7 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*****************************************************************************
自己アプデータ
*****************************************************************************/
#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
}