マイコンファームの書き換えに対応(NandInitializerRed)

書き換えに成功するためには、書き換え機能を有するマイコンファームに(別手段で)更新しておく必要があります。
マイコンファームデータはROM持ちしていますがSDカード持ちに変更するかもしれません。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1618 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
kamikawa 2008-06-12 06:09:29 +00:00
parent 3606ce018d
commit fbbb9cdc11
17 changed files with 1671 additions and 62 deletions

View File

@ -30,7 +30,8 @@ SRCS = crt0.SCFG_NOLOCK.c \
main.c \ main.c \
kami_pxi.c \ kami_pxi.c \
formatter.c \ formatter.c \
nvram_misc.c nvram_misc.c \
mcu_firm.c
TARGET_NAME = armadillo TARGET_NAME = armadillo

View File

@ -74,6 +74,7 @@ SRCS = main.c \
process_auto.c \ process_auto.c \
process_fade.c \ process_fade.c \
process_font.c \ process_font.c \
process_mcu.c \
process_wireless_setting.c \ process_wireless_setting.c \
sd_event.c \ sd_event.c \
hwi.c \ hwi.c \

View File

@ -30,7 +30,8 @@ SRCS = crt0.SCFG_NOLOCK.c \
main.c \ main.c \
kami_pxi.c \ kami_pxi.c \
formatter.c \ formatter.c \
nvram_misc.c nvram_misc.c \
mcu_firm.c
TARGET_NAME = armadillo TARGET_NAME = armadillo

View File

@ -42,6 +42,7 @@ Ltdautoload SCRWRAM
Object $(OBJDIR)/kami_pxi.o Object $(OBJDIR)/kami_pxi.o
Object $(OBJDIR)/formatter.o Object $(OBJDIR)/formatter.o
Object $(OBJDIR)/nvram_misc.o Object $(OBJDIR)/nvram_misc.o
Object $(OBJDIR)/mcu_firm.o
Library libsea_sp$(LIBSUFFIX).a Library libsea_sp$(LIBSUFFIX).a
Library libcrypto_sp$(LIBSUFFIX).a Library libcrypto_sp$(LIBSUFFIX).a

View File

@ -22,6 +22,7 @@
#include "twl/cdc.h" #include "twl/cdc.h"
#include "formatter.h" #include "formatter.h"
#include "nvram.h" #include "nvram.h"
#include "mcu_firm.h"
#include <twl/ltdmain_begin.h> #include <twl/ltdmain_begin.h>
#include <twl/mcu.h> #include <twl/mcu.h>
#include <twl/camera.h> #include <twl/camera.h>
@ -129,6 +130,7 @@ static void KamiPxiCallback(PXIFifoTag tag, u32 data, BOOL err)
case KAMI_EXE_FORMAT: case KAMI_EXE_FORMAT:
case KAMI_NAND_IO: case KAMI_NAND_IO:
case KAMI_NVRAM_IO: case KAMI_NVRAM_IO:
case KAMI_MCU_WRITE_FIRM:
case KAMI_MCU_IO: case KAMI_MCU_IO:
case KAMI_ARM7_IO: case KAMI_ARM7_IO:
case KAMI_CDC_GO_DSMODE: case KAMI_CDC_GO_DSMODE:
@ -249,6 +251,22 @@ static void KamiThread(void *arg)
} }
break; break;
case KAMI_MCU_WRITE_FIRM:
{
void* buffer;
KAMI_UNPACK_U32((u32 *)(&buffer), &kamiWork.data[1]);
if ( MCU_WriteFirm( buffer ) )
{
KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_SUCCESS);
}
else
{
KamiReturnResult(kamiWork.command, KAMI_PXI_RESULT_SUCCESS_FALSE);
}
}
break;
case KAMI_MCU_IO: case KAMI_MCU_IO:
{ {
BOOL is_read; BOOL is_read;

View File

@ -70,6 +70,7 @@ SRCS = main.c \
process_auto.c \ process_auto.c \
process_fade.c \ process_fade.c \
process_font.c \ process_font.c \
process_mcu.c \
process_wireless_setting.c \ process_wireless_setting.c \
sd_event.c \ sd_event.c \
hwi.c \ hwi.c \

View File

@ -61,6 +61,7 @@ void KamiPxiInit( void );
KAMIResult ExeFormatAsync(FormatMode format_mode, KAMICallback callback); KAMIResult ExeFormatAsync(FormatMode format_mode, KAMICallback callback);
KAMIResult kamiNandIo(u32 block, void* buffer, u32 count, BOOL is_read); KAMIResult kamiNandIo(u32 block, void* buffer, u32 count, BOOL is_read);
KAMIResult kamiNvramIo(u32 address, void* buffer, u32 size, BOOL is_read); KAMIResult kamiNvramIo(u32 address, void* buffer, u32 size, BOOL is_read);
KAMIResult kamiMcuWriteFirm(void* buffer );
KAMIResult kamiMcuIo(u32 reg_no, void* buffer, u32 value, BOOL is_read); KAMIResult kamiMcuIo(u32 reg_no, void* buffer, u32 value, BOOL is_read);
KAMIResult kamiARM7Io(u32 addr, u32* buffer, u32 value, BOOL is_read); KAMIResult kamiARM7Io(u32 addr, u32* buffer, u32 value, BOOL is_read);
KAMIResult kamiCDC_GoDsMode( void ); KAMIResult kamiCDC_GoDsMode( void );

View File

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - NandInitializer
File: process_mcu.h
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef PROCESS_MCU_H_
#define PROCESS_MCU_H_
#ifdef __cplusplus
extern "C" {
#endif
/*===========================================================================*/
#include <nitro.h>
/*---------------------------------------------------------------------------*
è<EFBFBD>è`
*---------------------------------------------------------------------------*/
#define MCU_DATA_FILE_PATH_IN_ROM "rom:/data/mcu_twl.hex"
/*---------------------------------------------------------------------------*
ŠÖ<EFBFBD>è`
*---------------------------------------------------------------------------*/
void* mcuProcess0(void);
void* mcuProcess1(void);
void* mcuProcess2(void);
void* mcuProcess3(void);
void* mcuProcess4(void);
/*===========================================================================*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* PROCESS_MCU_H_ */
/*---------------------------------------------------------------------------*
End of file
*---------------------------------------------------------------------------*/

View File

@ -225,6 +225,50 @@ KAMIResult kamiNvramIo(u32 address, void* buffer, u32 size, BOOL is_read)
return KAMI_RESULT_SEND_ERROR; return KAMI_RESULT_SEND_ERROR;
} }
/*---------------------------------------------------------------------------*
Name: kamiMcuWriteFirm
Description: MCUファーム更新関数
Arguments: buffer : new mcu data buffer
Returns:
*---------------------------------------------------------------------------*/
KAMIResult kamiMcuWriteFirm(void* buffer )
{
OSIntrMode enabled;
u8 data[4];
int i;
// ロック
enabled = OS_DisableInterrupts();
if (kamiWork.lock)
{
(void)OS_RestoreInterrupts(enabled);
return KAMI_RESULT_BUSY;
}
kamiWork.lock = TRUE;
(void)OS_RestoreInterrupts(enabled);
kamiWork.callback = NULL;
kamiWork.arg = 0;
// データ作成
KAMI_PACK_U32(&data[0], &buffer);
if (KamiSendPxiCommand(KAMI_MCU_WRITE_FIRM, 4, (u8)0))
{
for (i = 0; i < 4; i+=3)
{
KamiSendPxiData(&data[i]);
}
KamiWaitBusy();
return (KAMIResult)kamiWork.result;
}
return KAMI_RESULT_SEND_ERROR;
}
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Name: MCUアクセス関数 Name: MCUアクセス関数

View File

@ -104,7 +104,6 @@ static void MakeFullPathForSD(char* file_name, char* full_path);
static void ShowTitleinfoDifference( NAMTitleInfo* titleInfoNand, NAMTitleInfo* titleInfoSd); static void ShowTitleinfoDifference( NAMTitleInfo* titleInfoNand, NAMTitleInfo* titleInfoSd);
void ProgessInit(void); void ProgessInit(void);
void ProgressDraw(f32 ratio); void ProgressDraw(f32 ratio);
static void* ImportProcessReturn0(void);
static void* ImportProcessReturn1(void); static void* ImportProcessReturn1(void);
static void* ImportIndividuallyProcess0(void); static void* ImportIndividuallyProcess0(void);
@ -141,19 +140,6 @@ void* ImportProcess0(void)
FSFile dir; FSFile dir;
int i; int i;
// 2008/05/20 もうcert.sysは必要なし。
#if 0
FATFSFileHandle fat_handle;
// F:sys/cert.sysが存在しないなら出直してもらう
fat_handle = FATFS_OpenFile(E_TICKET_FILE_PATH_IN_NAND, "r");
if (!fat_handle)
{
FATFS_CloseFile(fat_handle);
return ImportProcessReturn0;
}
FATFS_CloseFile(fat_handle);
#endif
// 文字列全クリア // 文字列全クリア
kamiFontClear(); kamiFontClear();
@ -327,51 +313,6 @@ void* ImportProcess2(void)
return ImportProcess1; return ImportProcess1;
} }
/*---------------------------------------------------------------------------*
Name: ImportProcessReturn0
Description:
Arguments: None.
Returns: next sequence
*---------------------------------------------------------------------------*/
void* ImportProcessReturn0(void)
{
int i;
// 文字列全クリア
kamiFontClear();
kamiFontPrintf(2, 10, FONT_COLOR_RED, "%s is not exist", E_TICKET_FILE_PATH_IN_NAND);
kamiFontPrintf(2, 11, FONT_COLOR_RED, "You should write e-ticket", E_TICKET_FILE_PATH_IN_NAND);
kamiFontPrintf(2, 12, FONT_COLOR_RED, "beforehand.", E_TICKET_FILE_PATH_IN_NAND);
kamiFontPrintf(2, 22, FONT_COLOR_BLACK, "B Button : return to menu");
// バージョン表示
kamiFontPrintf(2, 1, FONT_COLOR_BLACK, "Import TAD from SD");
kamiFontPrintf(0, 2, FONT_COLOR_BLACK, "--------------------------------");
// 背景全クリア
for (i=0;i<24;i++)
{
kamiFontFillChar( i, BG_COLOR_TRANS, BG_COLOR_TRANS );
}
// 背景上部
kamiFontFillChar( 0, BG_COLOR_PINK, BG_COLOR_PINK );
kamiFontFillChar( 1, BG_COLOR_PINK, BG_COLOR_PINK );
kamiFontFillChar( 2, BG_COLOR_PINK, BG_COLOR_TRANS );
// カーソル消去
SetCursorPos((u16)200, (u16)200);
// フォントスクリーンデータロード
kamiFontLoadScreenData();
FADE_IN_RETURN( ImportProcessReturn1 );
}
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Name: ImportProcessReturn1 Name: ImportProcessReturn1

View File

@ -0,0 +1,251 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - NandInitializer
File: process_mcu.c
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <nitro/snd.h>
#include <twl/fatfs.h>
#include <nitro/card.h>
#include "kami_font.h"
#include "kami_pxi.h"
#include "process_topmenu.h"
#include "process_mcu.h"
#include "process_auto.h"
#include "process_fade.h"
#include "cursor.h"
#include "keypad.h"
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
#define NUM_OF_MENU_SELECT 2
#define DOT_OF_MENU_SPACE 16
#define CURSOR_ORIGIN_X 32
#define CURSOR_ORIGIN_Y 56
#define ROUND_UP(value, alignment) \
(((u32)(value) + (alignment-1)) & ~(alignment-1))
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
static s8 sMenuSelectNo;
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
static BOOL WriteMcuData(void);
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
Name: mcu
Description:
Arguments: None.
Returns: next sequence
*---------------------------------------------------------------------------*/
void* mcuProcess0(void)
{
int i;
// 文字列全クリア
kamiFontClear();
// バージョン表示
kamiFontPrintf(2, 1, FONT_COLOR_BLACK, "Write MCU Data");
kamiFontPrintf(0, 2, FONT_COLOR_BLACK, "--------------------------------");
// メニュー一覧
kamiFontPrintf(3, 6, FONT_COLOR_BLACK, "+-------------------+-----+");
kamiFontPrintf(3, 7, FONT_COLOR_BLACK, "l WRITE MCU DATA l l");
kamiFontPrintf(3, 8, FONT_COLOR_BLACK, "+-------------------+-----+");
kamiFontPrintf(3, 9, FONT_COLOR_BLACK, "l RETURN l l");
kamiFontPrintf(3, 10, FONT_COLOR_BLACK, "+-------------------+-----+");
// 背景全クリア
for (i=0;i<24;i++)
{
kamiFontFillChar( i, BG_COLOR_TRANS, BG_COLOR_TRANS );
}
// 背景上部
kamiFontFillChar( 0, BG_COLOR_GRAY, BG_COLOR_GRAY );
kamiFontFillChar( 1, BG_COLOR_GRAY, BG_COLOR_GRAY );
kamiFontFillChar( 2, BG_COLOR_GRAY, BG_COLOR_TRANS );
// カーソル消去
SetCursorPos((u16)200, (u16)200);
FADE_IN_RETURN( mcuProcess1 );
}
/*---------------------------------------------------------------------------*
Name: mcu
Description:
Arguments: None.
Returns: next sequence
*---------------------------------------------------------------------------*/
void* mcuProcess1(void)
{
/*
#ifndef NAND_INITIALIZER_LIMITED_MODE
// オート実行用
if (gAutoFlag)
{
sMenuSelectNo = 0;
return mcuProcess2;
}
#endif
*/
// 選択メニューの変更
if ( kamiPadIsRepeatTrigger(PAD_KEY_UP) )
{
if (--sMenuSelectNo < 0) sMenuSelectNo = NUM_OF_MENU_SELECT -1;
}
else if ( kamiPadIsRepeatTrigger(PAD_KEY_DOWN) )
{
if (++sMenuSelectNo >= NUM_OF_MENU_SELECT) sMenuSelectNo = 0;
}
// カーソル配置
SetCursorPos((u16)CURSOR_ORIGIN_X, (u16)(CURSOR_ORIGIN_Y + sMenuSelectNo * DOT_OF_MENU_SPACE));
// 決定
if (kamiPadIsTrigger(PAD_BUTTON_A))
{
return mcuProcess2;
}
// トップメニューへ戻る
else if (kamiPadIsTrigger(PAD_BUTTON_B))
{
FADE_OUT_RETURN( TopmenuProcess0 );
}
return mcuProcess1;
}
/*---------------------------------------------------------------------------*
Name: mcu
Description:
Arguments: None.
Returns: next sequence
*---------------------------------------------------------------------------*/
void* mcuProcess2(void)
{
BOOL result;
switch( sMenuSelectNo )
{
case 0:
result = WriteMcuData();
if (result)
{
kamiFontPrintf(25, 7, FONT_COLOR_GREEN, "OK");
}
else
{
kamiFontPrintf(25, 7, FONT_COLOR_RED, "NG");
}
break;
case 1:
FADE_OUT_RETURN( TopmenuProcess0 );
}
/*
#ifndef NAND_INITIALIZER_LIMITED_MODE
// Auto用
if (gAutoFlag)
{
if (result) { FADE_OUT_RETURN( AutoProcess1 ); }
else { FADE_OUT_RETURN( AutoProcess2); }
}
#endif
*/
return mcuProcess1;
}
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
static BOOL WriteMcuData(void)
{
FSFile file;
BOOL open_is_ok;
BOOL read_is_ok;
void* pTempBuf;
u32 file_size;
u32 alloc_size;
BOOL result = TRUE;
// ROMファイルオープン
FS_InitFile(&file);
open_is_ok = FS_OpenFile(&file, MCU_DATA_FILE_PATH_IN_ROM);
if (!open_is_ok)
{
OS_Printf("FS_OpenFile(\"%s\") ... ERROR!\n", MCU_DATA_FILE_PATH_IN_ROM);
return FALSE;
}
// ROMファイルリード
file_size = FS_GetFileLength(&file) ;
alloc_size = ROUND_UP(file_size, 32) ;
pTempBuf = OS_Alloc( alloc_size );
SDK_NULL_ASSERT(pTempBuf);
DC_InvalidateRange(pTempBuf, alloc_size);
read_is_ok = FS_ReadFile( &file, pTempBuf, (s32)file_size );
if (!read_is_ok)
{
kamiFontPrintfConsoleEx(CONSOLE_RED, "FS_ReadFile(\"%s\") ... ERROR!\n", MCU_DATA_FILE_PATH_IN_ROM);
FS_CloseFile(&file);
OS_Free(pTempBuf);
return FALSE;
}
// ROMファイルクローズ
FS_CloseFile(&file);
if (kamiMcuWriteFirm(pTempBuf) != KAMI_RESULT_SUCCESS)
{
result = FALSE;
}
OS_Free(pTempBuf);
return result;
}

View File

@ -27,6 +27,7 @@
#include "process_fade.h" #include "process_fade.h"
#include "process_wireless_setting.h" #include "process_wireless_setting.h"
#include "process_font.h" #include "process_font.h"
#include "process_mcu.h"
#include "cursor.h" #include "cursor.h"
#include "keypad.h" #include "keypad.h"
@ -50,6 +51,7 @@ enum {
MENU_IMPORT_TAD, MENU_IMPORT_TAD,
MENU_IMPORT_NANDFIRM, MENU_IMPORT_NANDFIRM,
MENU_IMPORT_NORFIRM, MENU_IMPORT_NORFIRM,
MENU_WRITE_MCU_DATA,
#endif // NAND_INITIALIZER_LIMITED_MODE #endif // NAND_INITIALIZER_LIMITED_MODE
NUM_OF_MENU_SELECT NUM_OF_MENU_SELECT
}; };
@ -86,7 +88,8 @@ static const MenuAndColor sMenuArray[] =
#ifndef NAND_INITIALIZER_LIMITED_MODE #ifndef NAND_INITIALIZER_LIMITED_MODE
{" IMPORT TAD FROM SD ", BG_COLOR_PINK }, {" IMPORT TAD FROM SD ", BG_COLOR_PINK },
{" IMPORT NANDFIRM FROM SD", BG_COLOR_GREEN }, {" IMPORT NANDFIRM FROM SD", BG_COLOR_GREEN },
{" IMPORT NORFIRM FROM SD", BG_COLOR_VIOLET } {" IMPORT NORFIRM FROM SD", BG_COLOR_VIOLET },
{" WRITE MCU DATA ", BG_COLOR_GRAY }
#endif // NAND_INITIALIZER_LIMITED_MODE #endif // NAND_INITIALIZER_LIMITED_MODE
}; };
@ -238,6 +241,8 @@ void* TopmenuProcess2(void)
FADE_OUT_RETURN( NandfirmProcess0 ); FADE_OUT_RETURN( NandfirmProcess0 );
case MENU_IMPORT_NORFIRM: case MENU_IMPORT_NORFIRM:
FADE_OUT_RETURN( NorfirmProcess0 ); FADE_OUT_RETURN( NorfirmProcess0 );
case MENU_WRITE_MCU_DATA:
FADE_OUT_RETURN( mcuProcess0 );
#endif // NAND_INITIALIZER_LIMITED_MODE #endif // NAND_INITIALIZER_LIMITED_MODE
} }

View File

@ -65,6 +65,7 @@ typedef enum KamiCommand
KAMI_NAND_IO, KAMI_NAND_IO,
KAMI_NVRAM_IO, KAMI_NVRAM_IO,
KAMI_MCU_IO, KAMI_MCU_IO,
KAMI_MCU_WRITE_FIRM,
KAMI_ARM7_IO, KAMI_ARM7_IO,
KAMI_CDC_GO_DSMODE, KAMI_CDC_GO_DSMODE,
KAMI_CLEAR_NAND_ERRORLOG, KAMI_CLEAR_NAND_ERRORLOG,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - libraties - mcu
File: mcu_firm.c
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef TWL_IPL_MCU_WRITEFIRM_H_
#define TWL_IPL_MCU_WRITEFIRM_H_
BOOL MCU_WriteFirm(const unsigned char* hex);
#endif

View File

@ -0,0 +1,226 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - libraties - mcu
File: mcu_firm.c
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <twl/i2c/ARM7/i2c.h>
#include "mcu_firm.h"
#define PRINT_DEBUG
//#define PRINT_DEBUG_MINI // rough version
#ifdef PRINT_DEBUG
#include <nitro/os/common/printf.h>
#define DBG_PRINTF OS_TPrintf
#undef PRINT_DEBUG_MINI // because of the alternative option
#define DBG_PRINT_PROFILE_INIT OSTick debug
#define DBG_PRINT_PROFILE_BEGIN() (debug = OS_GetTick())
#define DBG_PRINT_PROFILE_END() OS_TPrintf("(%d msec)\n", (int)OS_TicksToMilliSeconds(OS_GetTick()-debug))
#else
#define DBG_PRINTF( ... ) ((void)0)
#define DBG_PRINT_PROFILE_INIT
#define DBG_PRINT_PROFILE_BEGIN() ((void)0)
#define DBG_PRINT_PROFILE_END() ((void)0)
#endif
#ifdef PRINT_DEBUG_MINI
#include <nitro/os/common/printf.h>
#define DBG_PRINT_FUNC() OS_TPrintf("%s(0x%02X, 0x%02X);\n", __func__, I2CiDeviceAddrTable[id], reg)
#define DBG_PRINT_FUNC1(data) OS_TPrintf("%s(0x%02X, 0x%02X, 0x%02X);\n", __func__, I2CiDeviceAddrTable[id], reg, (data))
#define DBG_PRINT_ERR() OS_TPrintf(" Failed(%d) @ %d\n", error, r)
#else
#define DBG_PRINT_FUNC() ((void)0)
#define DBG_PRINT_FUNC1(data) ((void)0)
//#define DBG_PRINT_ERR() ((void)0)
#define DBG_PRINT_ERR() OS_TPrintf("%s: I2C Error (0x%X, 0x%X) %d/%d.\n", __func__, I2CiDeviceAddrTable[id], reg, r+1, RETRY_COUNT);
//#define DBG_PRINT_ERR() OS_TPanic("%s: I2C Error (0x%X, 0x%X) %d/%d.\n", __func__, I2CiDeviceAddrTable[id], reg, r+1, RETRY_COUNT);
#endif
static const u8 I2CiDeviceAddrTable[I2C_SLAVE_NUM] =
{
I2C_ADDR_CAMERA_MICRON_IN,
I2C_ADDR_CAMERA_MICRON_OUT,
I2C_ADDR_CAMERA_SHARP_IN,
I2C_ADDR_CAMERA_SHARP_OUT,
I2C_ADDR_MICRO_CONTROLLER,
I2C_ADDR_DEBUG_LED,
I2C_ADDR_DEBUGGER,
};
static BOOL slowRate = 0;
static inline void I2Ci_Start( void )
{
reg_OS_I2C_CNT = (u8)((1 << REG_OS_I2C_CNT_E_SHIFT) |
(1 << REG_OS_I2C_CNT_I_SHIFT) | // 割り込み禁止は IE にて行うことで仕様統一
(I2C_WRITE << REG_OS_I2C_CNT_RW_SHIFT) |
(0 << REG_OS_I2C_CNT_ACK_SHIFT) |
(1 << REG_OS_I2C_CNT_START_SHIFT));
}
static inline void I2Ci_Continue( I2CReadWrite rw )
{
reg_OS_I2C_CNT = (u8)((1 << REG_OS_I2C_CNT_E_SHIFT) |
(1 << REG_OS_I2C_CNT_I_SHIFT) |
(rw << REG_OS_I2C_CNT_RW_SHIFT) |
(rw << REG_OS_I2C_CNT_ACK_SHIFT));
}
static inline void I2Ci_Stop( I2CReadWrite rw )
{
reg_OS_I2C_CNT = (u8)((1 << REG_OS_I2C_CNT_E_SHIFT) |
(1 << REG_OS_I2C_CNT_I_SHIFT) |
(rw << REG_OS_I2C_CNT_RW_SHIFT) |
(0 << REG_OS_I2C_CNT_ACK_SHIFT) |
(1 << REG_OS_I2C_CNT_STOP_SHIFT));
}
static inline void I2Ci_StopPhase1( I2CReadWrite rw )
{
reg_OS_I2C_CNT = (u8)((1 << REG_OS_I2C_CNT_E_SHIFT) |
(1 << REG_OS_I2C_CNT_I_SHIFT) |
(rw << REG_OS_I2C_CNT_RW_SHIFT) |
(0 << REG_OS_I2C_CNT_ACK_SHIFT));
}
static inline void I2Ci_StopPhase2( void )
{
reg_OS_I2C_CNT = (u8)((1 << REG_OS_I2C_CNT_E_SHIFT) |
(1 << REG_OS_I2C_CNT_I_SHIFT) |
(1 << REG_OS_I2C_CNT_STOP_SHIFT) |
(1 << REG_OS_I2C_CNT_NT_SHIFT));
}
static inline void I2Ci_WaitEx( void ) // support slowRate
{
I2Ci_Wait();
SVC_WaitByLoop(slowRate);
}
static inline void I2Ci_StopEx( I2CReadWrite rw ) // support slowRate
{
if (slowRate)
{
I2Ci_StopPhase1(rw);
I2Ci_Wait();
SVC_WaitByLoop(slowRate);
I2Ci_StopPhase2();
}
else
{
I2Ci_Stop(rw);
}
}
static inline void I2Ci_SetData( u8 data )
{
DBG_PRINTF("%02X", data);
reg_OS_I2C_DAT = data;
}
static inline BOOL I2Ci_GetResult( void )
{
I2Ci_Wait();
DBG_PRINTF("%c", (reg_OS_I2C_CNT & REG_OS_I2C_CNT_ACK_MASK) ? '.' : '*');
return (BOOL)((reg_OS_I2C_CNT & REG_OS_I2C_CNT_ACK_MASK) >> REG_OS_I2C_CNT_ACK_SHIFT);
}
static inline BOOL I2Ci_SendStart( I2CSlave id )
{
DBG_PRINTF("\n");
I2Ci_Wait();
I2Ci_SetData( (u8)(I2CiDeviceAddrTable[id] | I2C_WRITE) );
I2Ci_Start();
return I2Ci_GetResult();
}
static inline BOOL I2Ci_SendMiddle( u8 data )
{
I2Ci_WaitEx();
I2Ci_SetData( data );
I2Ci_Continue( I2C_WRITE );
return I2Ci_GetResult();
}
static inline BOOL I2Ci_SendLast( u8 data )
{
I2Ci_WaitEx();
I2Ci_SetData( data );
I2Ci_StopEx( I2C_WRITE );
return I2Ci_GetResult();
}
#define SLOW_RATE_DEFAULT 0x90
#define SLOW_RATE_LONG HW_CPU_CLOCK_ARM7 // 4 sec
#define SLOW_RATE_ENTER (HW_CPU_CLOCK_ARM7 / 400) // 10msec
BOOL MCU_WriteFirm(const unsigned char* hex)
{
BOOL result = TRUE;
DBG_PRINT_PROFILE_INIT;
I2C_Lock();
// start phase
slowRate = SLOW_RATE_DEFAULT;
result &= I2Ci_SendStart( I2C_SLAVE_MICRO_CONTROLLER );
result &= I2Ci_SendMiddle( 0x77 ); // free register 7
slowRate = SLOW_RATE_LONG;
DBG_PRINT_PROFILE_BEGIN();
result &= I2Ci_SendMiddle( 0x4A ); // goto firm writing mode
DBG_PRINT_PROFILE_END();
// main phase
while ( hex[0] == ':' && hex[3] < '3' ) // フォーマットが正しく0x3000以前のアドレスである場合に処理する
{
// データ終端チェック (基本的にこの前で終了している)
if ( !MI_CpuComp8( hex, ":00000001FF", 11) )
{
break;
}
// 無視行チェック
if ( hex[1] == '1' && hex[2] == '0' && !MI_CpuComp8( &hex[9], "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 32 ) )
{
while ( *hex++ != '\n' )
{
// skip
}
continue;
}
// 通常出力
slowRate = SLOW_RATE_DEFAULT;
while ( *hex != '\n' )
{
result &= I2Ci_SendMiddle( *hex++ );
}
// 最後の1文字(\n固定)
slowRate = SLOW_RATE_ENTER;
DBG_PRINT_PROFILE_BEGIN();
result &= I2Ci_SendMiddle( *hex++ );
DBG_PRINT_PROFILE_END();
}
// stop phase
I2Ci_Wait();
DBG_PRINT_PROFILE_BEGIN();
SVC_WaitByLoop(slowRate);
DBG_PRINT_PROFILE_END();
I2Ci_StopPhase2();
I2C_Unlock();
return result;
}