TwlIPL/build/systemMenu_tools/common/ARM7/src/mcu_firm.c
yutaka 1319c59d23 アドレスの上限判定削除、
スキップ可能行判定の削除、
成否判定のポイント限定

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1666 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-06-20 02:18:23 +00:00

227 lines
6.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
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, d
#define DBG_PRINT_PROFILE_BEGIN() (debug = OS_GetTick())
#define DBG_PRINT_PROFILE_END() (d=(int)OS_TicksToMilliSeconds(OS_GetTick()-debug), (d ? OS_TPrintf("(%d msec)\n", d) : (void)0))
#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) | // <20><><EFBFBD><EFBFBD>݋֎~<7E><> IE <20>ɂčs<C48D><73><EFBFBD><EFBFBD><EFBFBD>ƂŎd<C58E>l<EFBFBD><6C><EFBFBD><EFBFBD>
(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
{
DBG_PRINT_PROFILE_INIT;
I2Ci_Wait();
DBG_PRINT_PROFILE_BEGIN();
SVC_WaitByLoop(slowRate);
DBG_PRINT_PROFILE_END();
}
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 0x50
#define SLOW_RATE_SHORT 0x140
#define SLOW_RATE_LONG (HW_CPU_CLOCK_ARM7 / 13) // 300msec
#define SLOW_RATE_ENTER (HW_CPU_CLOCK_ARM7 / 160) // 25msec
BOOL MCU_WriteFirm(const unsigned char* hex)
{
BOOL result = TRUE;
if ( !hex )
{
return FALSE; // no data
}
I2C_Lock();
slowRate = SLOW_RATE_DEFAULT;
// start phase
result &= I2Ci_SendStart( I2C_SLAVE_MICRO_CONTROLLER );
result &= I2Ci_SendMiddle( 0x77 ); // free register 7
result &= I2Ci_SendMiddle( 0x4A ); // goto firm writing mode
slowRate = SLOW_RATE_LONG;
// main phase
while ( hex[0] == ':' ) // ':'<27><><EFBFBD><EFBFBD><EFBFBD>n<EFBFBD>܂<EFBFBD><DC82>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B>v<EFBFBD><76><EFBFBD><EFBFBD>
{
int isContinue = MI_CpuComp8( hex, ":00000001FF", 11); // <20>f<EFBFBD>[<5B>^<5E>I<EFBFBD>[<5B>`<60>F<EFBFBD>b<EFBFBD>N
// <20>ŏ<EFBFBD><C58F><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD> (':'<27>̂͂<CC82>)
result &= I2Ci_SendMiddle( *hex++ );
slowRate = SLOW_RATE_SHORT;
// <20>ʏ<EFBFBD><CA8F>o<EFBFBD><6F>
do
{
I2Ci_SendMiddle( *hex );
}
while ( *hex++ != '\n' );
slowRate = SLOW_RATE_ENTER;
if ( !isContinue ) // <20>ŏI<C58F>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
break;
}
}
// stop phase (only 2nd call)
I2Ci_WaitEx();
I2Ci_StopPhase2();
I2C_Unlock();
return result;
}