mstar 平台typec 5450 升级
1. 主體流程
如果是原廠提供的PC 工具端的基本升級流程: 大體就是啟動(dòng)VENDOR_CMD_ENABLE,FLASH_ACCESS_ENABLE,SMBUS_REASE_FLASH,CHECK_BANK,WRITE_BANK,FLASH_ACCESS_DISABLE,SMBUS_ISP_VALIDATION,RESET_TO_FLASH。
其中GET_IC_STATUS 獲取芯片狀態(tài)信息。
詳細(xì)信息可以查看文檔:
https://download.csdn.net/download/kehyuanyu/12629812
操作碼為0x01, 發(fā)送三個(gè)字節(jié)的指令“0xDA,0x0B,0x01”,code 如下:
sendCmdToRtl5450 是發(fā)送指令給5450
static MAPI_BOOL sendCmdToRtl5450(int nDevFd, MAPI_U8 u8Cmd[], MAPI_U8 u8Size) {int nRet = -1;struct i2c_msg msg;struct i2c_rdwr_ioctl_data ioctl_data = {0};msg.addr = RTL5450_IIC_ADDR;msg.flags = I2C_SMBUS_WRITE; /* write */msg.len = u8Size;msg.buf = u8Cmd;ioctl_data.msgs = &msg;ioctl_data.nmsgs = 1;nRet = ioctl(nDevFd, I2C_RDWR, &ioctl_data);if( nRet < 0){printf("[%s][%d] ioctl rtl5450 i2c reg[0x%02x] failed! nRet: = %d, errno: %d, error: %s. \n", \__FUNCTION__,__LINE__,u8Cmd[0],nRet, errno,strerror(errno));return MAPI_FALSE;}return MAPI_TRUE; }其中 RTL5450_IIC_ADDR 為typec 7位的設(shè)備地址,kernel 會(huì)根據(jù)上層的操作(讀/寫)來補(bǔ)全最后一位。
recvFeedbackFromRtl5450Sigle 獲取指令執(zhí)行后,5450 發(fā)過來的返回值,使用與所有指令執(zhí)行后的返回值
通過msg.buf 返回上調(diào)指令的執(zhí)行結(jié)果。
2. 獲取芯片信息
操作碼(亦寄存器)為0x3A,發(fā)送三個(gè)字節(jié)指令"0x00 0x00 0x14"到5450 ,其中主要是操作碼,及最后一個(gè)0x14(表示將返回0x14 個(gè)字節(jié)的狀態(tài)信息)。
recvFeedbackFromRtl5450Sigle 返回值為0x01 ,表示5450 正常收到請求GET_IC_STATUS的指令,接著通過recvFeedbackFromRtl5450FromReg獲取0x14 (20)個(gè)的信息
static MAPI_BOOL recvFeedbackFromRtl5450FromReg(int nDevFd, MAPI_U8 u8Cmd, MAPI_U8 *pu8FeedBuf, MAPI_U8 u8FeedSize) {struct i2c_msg msg[2];struct i2c_rdwr_ioctl_data data_ioctl;MAPI_U8 ucAddr = u8Cmd;msg[0].addr = RTL5450_IIC_ADDR;msg[0].flags = I2C_SMBUS_WRITE;msg[0].len = 1;msg[0].buf = &ucAddr; // cmd or regmsg[1].addr = RTL5450_IIC_ADDR;msg[1].flags = I2C_M_RD;msg[1].len = u8FeedSize;msg[1].buf = pu8FeedBuf;data_ioctl.msgs = msg;data_ioctl.nmsgs = 2;if(ioctl(nDevFd, I2C_RDWR, &data_ioctl) < 0){printf("[%s][%d] read back value failed! \n", __FUNCTION__,__LINE__);return MAPI_FALSE;}return MAPI_TRUE; }成功之后,解析這個(gè)20個(gè)bytes,其中byte【1】表示Rom code 還是MCM flash code,而byte【15】為0x10 時(shí)表示運(yùn)行在bank1,其他值則表示運(yùn)行在bank0,這個(gè)會(huì)影響寫flash的地址。
3. 啟動(dòng)falsh訪問權(quán)限
操作碼0x0a, 發(fā)送三個(gè)字節(jié)0xDA,0x0B,0x03 到5450
// 3. falsh enable accessdo{MAPI_U8 data[5] = {0x01,0x03,0xDA,0x0B,0x03};MAPI_BOOL bRet = MAPI_FALSE;bRet = sendCmdToRtl5450(nFd, data, 5);if(!bRet){printf("[%s][%d] send cmd <0x01,0x03,0xDA,0x0B,0x03> failed. Count [%d]\n",\__FUNCTION__,__LINE__,uCount);break;}uCount = 0;while(uCount++ < 350){u8FeedBuf = 0x00;bRet = recvFeedbackFromRtl5450Sigle(nFd,&u8FeedBuf);if(bRet && u8FeedBuf == 0x01){bStep3 = MAPI_TRUE;break;}else{continue;}usleep(1000);}} while (0);4. 擦寫flash
static MAPI_BOOL writeBinTo5450m(MAPI_U8 u8CodeRun, const char* filename, int nFd) {MAPI_U8 u8Step4CmdCode1 = 0x00;MAPI_U8 u8Step4CmdCode2 = 0x00;char binFile[1024];MAPI_U8 u8TmpBin[32] = {0x00};MAPI_U8 u8WData[34] = {0x00};MAPI_U8 u8RUnitLen = 0x1D;MAPI_BOOL bWRet = MAPI_FALSE;const MAPI_U8 u8RUnitHeadLen = 5; // cmd, byte count, addr_l, addr_h,wData_countconst MAPI_U32 nBankHalfSize = 65536; // 64KFILE *pFHandle = NULL;int nLen = 0;MAPI_U16 uReadCnt = 0;MAPI_U32 uWAddr = 0x0000;MAPI_U16 uWUsdAddr = 0x0000;MAPI_U32 u32RTotal = 0x0000;MAPI_U8 u8RItemSize = 29;MAPI_U8 u8RItem = 1;MAPI_U8 u8LoopCnt = 0;if(u8CodeRun == 0x10) // bank1{// bank 0 cmd codeu8Step4CmdCode1 = 0x04;u8Step4CmdCode2 = 0x06;}else // bank0{// bank 1 cmd codeu8Step4CmdCode1 = 0x13;u8Step4CmdCode2 = 0x14;}printf("[%s][%d] will upgrade %s \n", __FUNCTION__,__LINE__,u8CodeRun ? "bank0" : "bank1");printf("[%s][%d] cmd code1: 0x%02x , cmd: code2 0x%02x .\n", __FUNCTION__,__LINE__,u8Step4CmdCode1,u8Step4CmdCode2);memset(binFile,0x00,sizeof(binFile));memcpy(binFile,filename,strlen(filename));pFHandle = fopen(binFile, "r");if(pFHandle == NULL){printf("[%s][%d] open %s failed! \n",__FUNCTION__,__LINE__,binFile);return MAPI_FALSE;}fseek(pFHandle, 0, SEEK_END);nLen = ftell(pFHandle);fseek(pFHandle, 0, SEEK_SET);printf("[%s][%d] file %s size: %d[0x%05x] \n",__FUNCTION__,__LINE__,binFile,nLen,nLen);while(TRUE){MAPI_BOOL bBackVal = MAPI_FALSE;u8RItem = (u8RItem % 10) == 0 ? 1 : (u8RItem % 10) ;if(u8RItem % 9 == 0){u8RItemSize = 24;}else{u8RItemSize = 29;}// init bufmemset(u8TmpBin, 0x00, sizeof(u8TmpBin));memset(u8WData, 0x00, sizeof(u8WData));u8RUnitLen = fread(u8TmpBin, sizeof(char), u8RItemSize, pFHandle);if(u8RUnitLen <= 0){int nCurPosition = ftell(pFHandle);if(nCurPosition >= nLen){break;}}u32RTotal = u32RTotal + u8RUnitLen;if(u32RTotal < nBankHalfSize){u8WData[0] = u8Step4CmdCode1;}else{u8RItem = 1;u8WData[0] = u8Step4CmdCode2;}#if (KERNEL_I2C_DEBUG == 1)if(u32RTotal % 1024 == 0){printf("[%s][%d] read item ( %d KB) from bin, two banks size: %d KB . \n", \__FUNCTION__,__LINE__,(u32RTotal/1024),(nLen/1024));}#endif// byte countu8WData[1] = u8RUnitLen + (u8RUnitHeadLen - 2); // remove 2 byte(cmd , byte count)uWUsdAddr = uWAddr % nBankHalfSize;// ADDR_Lu8WData[2] = (MAPI_U8)uWUsdAddr&0x00FF;// ADDR_Hu8WData[3] = ((MAPI_U8)((uWUsdAddr&0xFF00) >> 8));// WData_countu8WData[4] = u8RUnitLen;// data1 ~ dataNmemcpy(u8WData + u8RUnitHeadLen, u8TmpBin, u8RUnitLen);bWRet = sendCmdToRtl5450(nFd, u8WData, (u8RUnitLen+u8RUnitHeadLen));if(!bWRet){printf("[%s][%d] wirte bin data to 5450 failed\n", __FUNCTION__,__LINE__);break;}u8LoopCnt = 0;while(u8LoopCnt++ < 350){// MAPI_U8 u8CmdCode = u8WData[0];MAPI_BOOL bRetFeedval = MAPI_FALSE;MAPI_U8 u8FeedBuf = 0x00;usleep(1000);bRetFeedval = recvFeedbackFromRtl5450Sigle(nFd,&u8FeedBuf);if(bRetFeedval && u8FeedBuf == 0x01){bBackVal = MAPI_TRUE;break;}else{continue;}}if(!bBackVal){printf("[%s][%d] get back value failed , when wirte date to 0x%04x\n",\__FUNCTION__,__LINE__,uWAddr);break;}uReadCnt++;u8RItem++;uWAddr = uWAddr + u8RUnitLen;}if(feof(pFHandle) != 0 || (ftell(pFHandle) == nLen)){printf("[%s][%d] wirte bin file completed .\n", __FUNCTION__,__LINE__);fclose(pFHandle);return MAPI_TRUE;}printf("[%s][%d] write %d bytes to dev [addr: 0x%04x], [failed] \n",\__FUNCTION__,__LINE__,u8RUnitLen,uWAddr);fclose(pFHandle);return MAPI_FALSE; }
bank0 : 0~ 128K, bank1: 128K~256K。 根據(jù)GET_IC_STATUS獲取信息,如果運(yùn)行在bank1就寫bank0,如果運(yùn)行在bank0 就寫bank1.
根據(jù)對應(yīng)操作碼,將從bin文件中讀取的數(shù)據(jù)封裝成包,寫入mcu 的flash中。一個(gè)輪回寫8次29bytes,接著寫1次24bytes,共計(jì)256 bytes,如此反復(fù)512次即可燒錄完128K數(shù)據(jù)。
5. 關(guān)閉smbus
do{MAPI_U8 data[5] = {0x01,0x03,0xDA,0x0B,0x01};MAPI_BOOL bRet = MAPI_FALSE;memset(u8FeedBufs, 0x00, sizeof(u8FeedBufs));bRet = sendCmdToRtl5450(nFd, data, 5);if(!bRet){printf("[%s][%d] send cmd <0x01,0x03,0xDA,0x0B,0x01> failed. Count [%d]\n",\__FUNCTION__,__LINE__,uCount);break;}uCount = 0;while(uCount++ < 350){usleep(1000);u8FeedBuf = 0x00;bRet = recvFeedbackFromRtl5450Sigle(nFd,&u8FeedBuf);if(bRet && u8FeedBuf == 0x01){bStep5_1 = MAPI_TRUE;break;}else{continue;}}} while (0);6. 校驗(yàn)數(shù)據(jù)
操作碼0x01,發(fā)送三字節(jié)數(shù)據(jù)0xDA,0x0B,0x01給mcu
// 5. smbus isp validationdo{MAPI_U8 data[3] = {0x16,0x01,0x01};MAPI_BOOL bRet = MAPI_FALSE;bRet = sendCmdToRtl5450(nFd, data, 3);if(!bRet){printf("[%s][%d] send cmd <0x16,0x01,0x01> failed. Count [%d]\n",\__FUNCTION__,__LINE__,uCount);break;}uCount = 0;while(uCount++ < 350){usleep(1000);u8FeedBuf = 0x00;bRet = recvFeedbackFromRtl5450Sigle(nFd,&u8FeedBuf);if(bRet && u8FeedBuf == 0x01){bStep5_2 = MAPI_TRUE;break;}else{continue;}}} while (0);7. 重啟flash
do{MAPI_U8 data[5] = {0x05,0x03,0xDA,0x0B,0x01};MAPI_BOOL bRet = MAPI_FALSE;bRet = sendCmdToRtl5450(nFd, data, 5);if(!bRet){printf("[%s][%d] send cmd <0x05,0x03,0xDA,0x0B,0x01> failed. Count [%d]\n",\__FUNCTION__,__LINE__,uCount);break;}uCount = 0;while(uCount++ < 350){usleep(1000);u8FeedBuf = 0x00;bRet = recvFeedbackFromRtl5450Sigle(nFd,&u8FeedBuf);if(bRet && u8FeedBuf == 0x01){bStep6 = MAPI_TRUE;break;}else{continue;}}} while (0);至此,整個(gè)升級流程完成。
總結(jié)
以上是生活随笔為你收集整理的mstar 平台typec 5450 升级的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈加密存储的应用
- 下一篇: 如何使Winamp看起来像iTunes