📄 downloadthread.cpp
字号:
if(DownloadStart())
m_pWnd->PostMessage(DL_MSG_WORK_DONE, NULL, m_nPort);
m_nThreadState = DL_THREAD_LOCKED;
m_FileTrace.Close();
}while(m_bRun);
CloseHandle(m_hEvt);
GetExitCodeThread(&m_hThread, &dwExitCode);
ExitThread(dwExitCode);
m_pWnd->PostMessage(DL_MSG_THREAD_EXIT, dwExitCode, m_nPort);
return CWinThread::Run();
}
BOOL CDownloadThread::DownloadStart()
{
if(!SendFirstRecord()) return FALSE;
if(!SendToRam()) return FALSE;
if(!SendToFlash()) return FALSE;
return TRUE;
}
BOOL CDownloadThread::InitCommPort(UINT nBaud)
{
if (m_CommPort.m_bConnected)
{
m_CommPort.ClosePort();
}
if( !m_CommPort.OpenPort( m_nPort, nBaud ))
{
WriteFileTrace("Port Initialization Failed.");
m_bPortInit = FALSE;
return FALSE;
}
else
{
m_bPortInit= TRUE;
}
if (!m_CommPort.SetDCB(nBaud, 8, NOPARITY, ONESTOPBIT))
{
AfxMessageBox("Serial Port Setting Failed.");
return FALSE;
}
return TRUE;
}
BOOL CDownloadThread::ReadCharFromUart(clock_t lTimeout, BYTE *byReceivedChar)
{
clock_t timeout;
DWORD dwRead = 0;
timeout = clock();
*byReceivedChar = 0x00;
while((clock()-timeout) < lTimeout)
{
dwRead = m_CommPort.ReadComm(byReceivedChar, 1);
if(dwRead)
break;
}
if (dwRead) return TRUE;
else return FALSE;
}
BOOL CDownloadThread::WriteCharToUart(BYTE txChar)
{
return (1==m_CommPort.WriteComm(&txChar, 1));
}
BOOL CDownloadThread::SendFirstRecord()
{
BYTE rxChar;
clock_t startTime;
WriteFileTrace("Turn On The Mobile!!!");
if(!InitCommPort(38400))
{
WriteFileTrace("InitCommPort Error");
return FALSE;
}
if (!m_CommPort.SetDCB(38400, 8, EVENPARITY, ONESTOPBIT))
{
WriteFileTrace("Serial Port Setting Failed.");
return FALSE;
}
if(!m_CommPort.ClearDTR())
{
DWORD dwError = GetLastError();
WriteFileTrace("ClearDTR Error");
return FALSE;
}
if(!m_CommPort.SetDTR())
{
WriteFileTrace("Serial Port Setting Failed.");
return FALSE;
}
startTime = clock();
do
{
ReadCharFromUart(TIMEOUT, &rxChar);
if(m_bStop)
{
m_pWnd->PostMessage(DL_MSG_WORK_CANCEL, NULL, m_nPort);
return FALSE;
}
Sleep(20);
} while((clock()-startTime < 30*CLOCKS_PER_SEC) && (rxChar != BOOT_CREQ5087_4));
if(rxChar != BOOT_CREQ5087_4)
{
WriteFileTrace("BOOT_CREQ5087_4 Error");
m_pWnd->PostMessage(DL_MSG_ERR, BOOT_CREQ5087_4_ERR, m_nPort);
return FALSE;
}
if(!WriteCharToUart(BOOT_CCON))
{
WriteFileTrace("Send Boot Confirm Fail!!");
m_pWnd->PostMessage(DL_MSG_ERR, SEND_BOOT_CONFIRM_ERR, m_nPort);
return FALSE;
}
if(!m_CommPort.ClearDTR())
{
WriteFileTrace("ClearDTR Failed.");
m_pWnd->PostMessage(DL_MSG_ERR, CLEAR_DTR_ERR, m_nPort);
return FALSE;
}
WriteFileTrace("Target Detected !!!");
m_pWnd->PostMessage(DL_MSG_TARGETDETECT, DL_TARGET_DETECTED, m_nPort);
BYTE aFirstRecord[] =
{
/*Set CS0 ~ CS3*/
/* CS0 */
0x46, /* MSB */
0x23, /* LSB */
/* CS1 */
0x16, /* MSB */
0x03, /* LSB */
/* CS2 */
0x46, /* MSB */
0x42, /* LSB */
/* CS3 */
0x06, /* MSB */
0x56, /* LSB */
/*SetStartAddress 0xFFFF8002*/
0x00, 0x03, 0xFF, 0xFF, 0x80, 0x02,
/*SetSendCommand2 0x0130*/
0x80, 0x01, 0x01, 0x30,
/*SetStartAddress 0x00000000*/
0x00, 0x03, 0x00, 0x00, 0x00, 0x00
};
if(24 != m_CommPort.WriteComm(aFirstRecord,sizeof(aFirstRecord)))
{
WriteFileTrace("Send System Configuration Error!! ");
m_pWnd->PostMessage(DL_MSG_ERR, SEND_SYSTEM_CFG_ERR, m_nPort);
return FALSE;
}
return TRUE;
}
BOOL CDownloadThread::SendToRam()
{
CString str;
clock_t start;
int Total = 0;
start = clock();
Total = 0;
/* Jump to the given address to execute the code */
BYTE a_JumpExecuteAddress[2];
int nStubSize;
if(gl_strModel == "SGH-D488")
{
nStubSize = StubSize_D488[0];
a_JumpExecuteAddress[0] = (BYTE)((StubSize_D488[0]-1)>>8) | 0x40;
a_JumpExecuteAddress[1] = (BYTE)(StubSize_D488[0]-1);
}
else if(gl_strModel == "SGH-E330")
{
nStubSize = StubSize_E330[0];
a_JumpExecuteAddress[0] = (BYTE)((StubSize_E330[0]-1)>>8) | 0x40;
a_JumpExecuteAddress[1] = (BYTE)(StubSize_E330[0]-1);
}
else
{
nStubSize = StubSize[0];
a_JumpExecuteAddress[0] = (BYTE)((StubSize[0]-1)>>8) | 0x40;
a_JumpExecuteAddress[1] = (BYTE)(StubSize[0]-1);
}
CString strTemp;
strTemp.Format("StubSize = %d, Address : %x, %x", nStubSize, a_JumpExecuteAddress[0], a_JumpExecuteAddress[1]);
WriteFileTrace(strTemp);
if( 2 != m_CommPort.WriteComm(a_JumpExecuteAddress, sizeof(a_JumpExecuteAddress)) )
{
WriteFileTrace("Send JumpExecuteAddress Fail!! ");
m_pWnd->PostMessage(DL_MSG_ERR, SEND_JUMP_ADDR_ERR, m_nPort);
return FALSE;
}
// Loop through RAM blocks
Total = 0;
do
{
if (m_bStop)
{
m_pWnd->PostMessage(DL_MSG_WORK_CANCEL, NULL, m_nPort);
return FALSE;
}
#if 0
/*悼累阑 救窍匙...捞惑窍促..*/
size = (StubSize[0] - Total ) > 32 ? 32 : StubSize[0] - Total ;
if( size != m_CommPort.WriteComm( (void*)&(Stub[Total]) , size))
{
WriteFileTrace("Send Char error during preLoader download");
m_pWnd->PostMessage(DL_MSG_ERR, SEND_CHAR_ERR, m_nPort);
return FALSE;
}
Total += size ;
#else
BYTE byStub;
if(gl_strModel == "SGH-D488")
{
byStub = Stub_D488[0][Total++];
}
else if(gl_strModel == "SGH-E330")
{
byStub = Stub_E330[0][Total++];
}
else
{
byStub = Stub[0][Total++];
}
if(!WriteCharToUart((BYTE)byStub))
{
WriteFileTrace("Send Char error during Loader download");
m_pWnd->PostMessage(DL_MSG_ERR, SEND_CHAR_ERR, m_nPort);
return FALSE;
}
#endif
m_nPercent = (UINT)(Total * 100/nStubSize);
m_pWnd->PostMessage(DL_MSG_PROGRESS, m_nPercent, m_nPort);
}
while (Total < nStubSize);
m_nPercent = 0;
if (m_bStop)
{
m_pWnd->PostMessage(DL_MSG_WORK_CANCEL, NULL, m_nPort);
return FALSE;
}
BYTE aStartAddressRecord[] =
{
/* SetStartAddress 0x00000000 */
0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
/* JumpToStartAddress */
0x60, 0x00
};
if( 8 != m_CommPort.WriteComm(aStartAddressRecord, sizeof(aStartAddressRecord)) )
{
WriteFileTrace("Send JumpExecuteAddress Fail!! ");
m_pWnd->PostMessage(DL_MSG_ERR, SEND_JUMP_ADDR_ERR, m_nPort);
return FALSE;
}
BYTE rxChar;
/* Wait the acknowledge following the jump instruction */
start = clock();
do
{
ReadCharFromUart(TIMEOUT, &rxChar);
if(m_bStop)
{
m_pWnd->PostMessage(DL_MSG_WORK_CANCEL, NULL, m_nPort);
return FALSE;
}
Sleep(0);
} while ((clock()-start < 5*CLOCKS_PER_SEC) && (rxChar != BOOT_CCON));
if(rxChar != BOOT_CCON)
{
WriteFileTrace("BOOT_CCON Error");
m_pWnd->PostMessage(DL_MSG_ERR, BOOT_CCON_ERR, m_nPort);
return FALSE;
}
/* The spm start */
/* Read : Stack pointer is in the mobile */
if(!ReadCharFromUart(TIMEOUT*5,&rxChar))
{
WriteFileTrace("StackPointer not received");
m_pWnd->PostMessage(DL_MSG_ERR, STACK_POINTER_ERR, m_nPort);
return FALSE;
}
else
{
/* Check the Stack pointer */
if (rxChar != DWL_STACK_POINTER_SET) //0xA0
{
WriteFileTrace("StackPointer not set");
m_pWnd->PostMessage(DL_MSG_ERR, STACK_POINTER_ERR, m_nPort);
return FALSE ; /* Exit the function */
}
}
BYTE SpmPrimaryVersion, SpmSecondaryVersion;
ReadCharFromUart(TIMEOUT*5,&SpmPrimaryVersion);
ReadCharFromUart(TIMEOUT*5,&SpmSecondaryVersion);
/* Get the type of terminal flash */
if(!GetTypeFlash())
{
WriteFileTrace("GetTypeFlash Error");
return FALSE;
}
else
{
DisplayFlashName();
}
if(!SetGPIO())
{
WriteFileTrace("SetGPIO Error");
return FALSE;
}
if(!SetSpeedAndPMU())
{
WriteFileTrace("SetSpeedAndPMU Error");
return FALSE;
}
if ( !DownloadExtendMobule())
{
WriteFileTrace("DownloadExtendMobule Error");
return FALSE;
}
str.Format("** Now you can do the followings. **\r\n\r\n"
"-. Download the BINARY and/or TFS files\r\n"
"-. Dump NOR-Flash\r\n"
"-. Erase NOR-Flash\r\n"
"-. Format Nand-Flash\r\n"
/*"-. Dump TFS files\r\n" */
);
WriteFileTrace(str);
return TRUE;
}
BOOL CDownloadThread::GetTypeFlash()
{
BYTE ExtendedBit;
BYTE CommandAck;
TRACE("BOOT : Get the type of flash\n");
/* If the processor use is 5087, get acknowledge */
if(!ReadCharFromUart(TIMEOUT, &CommandAck) || CommandAck != DWL_ACK_FLASH_TYPE_ACK )
{
WriteFileTrace("DWL_ACK_FLASH_TYPE_ACK Error");
m_pWnd->PostMessage(DL_MSG_ERR, FLASH_TYPE_ACK_ERR, m_nPort);
return FALSE;
}
/* Read Flash type */
m_FlashManufacturer = 0 ;
if(!ReadCharFromUart( TIMEOUT, &m_FlashManufacturer ))
{
WriteFileTrace("FlashManufacturer Error");
m_pWnd->PostMessage(DL_MSG_ERR, FLASH_TYPE_READ_ERR, m_nPort);
return FALSE;
}
switch (m_FlashManufacturer)
{
case TYPE_SHARP :
case TYPE_INTEL :
ReadCharFromUart( TIMEOUT, &m_FlashId );
break;
case TYPE_AMD :
case TYPE_SAMSUNG:
ReadCharFromUart( TIMEOUT, &m_FlashId );
switch (m_FlashId)
{
case AMD_FUJI_16MB_PROTO :
case AM29SL160BT :
ReadCharFromUart( TIMEOUT, &ExtendedBit );
break;
default :
break;
}
break;
case TYPE_THOMSON :
case TYPE_HITACHI :
case TYPE_FUJI :
case TYPE_TOSHIBA :
ReadCharFromUart( TIMEOUT, &m_FlashId);
default :
WriteFileTrace("Flash Manufacturer Unknown");
m_pWnd->PostMessage(DL_MSG_ERR, FLASH_TYPE_UNKNOWN, m_nPort);
return FALSE; /* exit the program */
}
/* Return code */
return TRUE;
}
void CDownloadThread::DisplayFlashName()
{
BYTE index;
CString str;
if(!GetFlashIndex(&index))
{
WriteFileTrace("Flash Type Unknown");
return;
}
str.Format("Flash Type Detected [ %s : %s ]",
m_FlashDescription.m_aFlashCharacteristic[index].m_strManufacturerName,
m_FlashDescription.m_aFlashCharacteristic[index].m_strDeviceName);
WriteFileTrace(str);
}
BOOL CDownloadThread::GetFlashIndex(BYTE* Index)
{
BYTE i;
for( i = 0 ; i < m_FlashDescription.m_byNbFlash ; i++ )
{
if( m_FlashDescription.m_aFlashCharacteristic[i].m_byManufacturerId == m_FlashManufacturer &&
m_FlashDescription.m_aFlashCharacteristic[i].m_byDeviceId == m_FlashId )
{
break ;
}
}
if( i == m_FlashDescription.m_byNbFlash )
{
return FALSE;
}
else
{
*Index = i;
}
return TRUE;
}
BOOL CDownloadThread::SetGPIO()
{
if( m_nBaudRatePos > 1 )
{
BYTE Ack;
TRACE("COMMAND : Set GPIO\n");
/*Send command GPIO to the mobil*/
WriteCharToUart(DWL_SET_GPIO);
/*Wait for Acknowledge*/
if( !ReadCharFromUart( TIMEOUT, &Ack ) && Ack != DWL_ACK_COMMAND_OK)
{
WriteFileTrace("DWL_SET_GPIO Error");
m_pWnd->PostMessage(DL_MSG_ERR, SET_GPIO_ERR, m_nPort);
return FALSE;
}
/* Read Set GPIO Acknowledge */
ReadCharFromUart( TIMEOUT, &Ack );
/* Check if the command Set_GPIO is receive by the mobile */
if (Ack != DWL_ACK_SET_GPIO_ACK)
{
WriteFileTrace("DWL_SET_GPIO Error");
m_pWnd->PostMessage(DL_MSG_ERR, SET_GPIO_ERR, m_nPort);
return FALSE;
}
}
/* return code */
return TRUE;
}
BOOL CDownloadThread::SetSpeedAndPMU()
{
u8 vl_TrialNb=0;
BOOL vl_ReturnCode = FALSE ;
/* Send command to change speed. Try 3 times maximum */
do
{
vl_ReturnCode = ChangeSpeed();
vl_TrialNb++;
} while ( (vl_TrialNb<=3) && (vl_ReturnCode!=TRUE));
/* Impossible to change the terminal speed, Function exit ? */
if (!vl_ReturnCode)
{
WriteFileTrace("ChangeSpeed Error");
m_pWnd->PostMessage(DL_MSG_ERR, CHANGE_SPEED_ERR, m_nPort);
return FALSE;
}
TRACE("COMMAND : SetSpeedAndPMU\n");
return TRUE;
}
BOOL CDownloadThread::ChangeSpeed()
{
u16 vl_Checksum = 0;
u8 vl_Params[5];
u8 vl_Ack, vl_Status;
u8 index;
TRACE("COMMAND : Change speed \n");
/* Send command to the mobile to change speed*/
WriteCharToUart( DWL_CMD_CHANGE_SPEED );
/* Wait for Acknowledge */
ReadCharFromUart( TIMEOUT, &vl_Ack );
if (vl_Ack != DWL_ACK_COMMAND_OK)
{
WriteFileTrace("DWL_CMD_CHANGE_SPEED Error");
return FALSE;
}
/* Initialise the buffer to send and calculate the checksum */
for (index=0; index<3; index++)
{
vl_Params[index] = a_SpeedParameters[m_nBaudRatePos][index];
vl_Checksum += vl_Params[index];
}
vl_Params[3] = (vl_Checksum >> 8) & 0xFF;
vl_Params[4] = vl_Checksum & 0xFF;
m_CommPort.WriteComm(vl_Params, 5);
/* Wait for Checksum acknowledge */
ReadCharFromUart( TIMEOUT,&vl_Ack);
/* Check the acknowledge */
if (vl_Ack != DWL_ACK_CHANGE_SPEED_ACK)
{
WriteFileTrace("DWL_COMMAND_BAD_CHANGE_SPEED_ACK");
return FALSE;
}
else
{
ReadCharFromUart( TIMEOUT, &vl_Status );
if (vl_Status != DWL_ACK_CHECKSUM_OK)
{
WriteFileTrace("DWL_COMMAND_BAD_CHANGE_SPEED_CHECKSUM");
return FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -