68411 是麦道微代理的一款hdmiout ic, 可以完成主芯片信源通道的扩展功能。
这里主芯片输出vb1 给68411, 然后68411 输出vb1 及一路hdmi out。该ic 也是一块由I2c控制的芯片但却是非标的i2c,所以我们需要对协议进行调整。

1. 总线配置

关于总线配置,可以参考"mstar 平台内核i2c总线介绍"
这篇博客。

2. 升级流程

novatek 升级流程,主要包含以下几个步骤:
一. ISP 模式设置;
二. 关闭写保护;
三. 擦除novatek 存储分区;
四. 写分区;
五. 校验分区;
六 . 开启写保护,退出ISP模式;

code 如下:

MAPI_BOOL mapi_i2c::doUpgradeNovaTek(const char* filePath)
{MAPI_BOOL bRet      = MAPI_FALSE;MS_U16 u16Page      = 0x000;MAPI_U8 u8CurPage   = 0x00;MAPI_BOOL bSkipPage = MAPI_FALSE;int nFileFd = open(NOVA_TEK_MASTER_DEV, O_RDWR);if(nFileFd < 0){return MAPI_FALSE;}bRet = NovaTekLoadFwBin(filePath);if(!bRet){goto END;}configIIcSpeed(nFileFd,50);if(!NovaTekEnterIsp(nFileFd)){bRet = MAPI_FALSE;close(nFileFd);return bRet;}configIIcSpeed(nFileFd,100);if(DualFwEnable == 1){NovaTekEraseIDSector(nFileFd);}if(!NovaTekTErase(nFileFd)){bRet = MAPI_FALSE;goto END;}configIIcSpeed(nFileFd,400);MaxPages = Flash.Page;if(DualFwEnable == 1){CodePages   = MaxPages/2 ;FlashOffset = MaxPages/2 ;}else{CodePages = MaxPages;FlashOffset = 0;}if (McuId == 0xa390 || McuId == 0xA400 || McuId == 0xA450){bRet = NovaTek68390ProgramEnable(nFileFd, MAPI_TRUE);}for(u16Page = FlashOffset; (u16Page<(CodePages+FlashOffset))&&(u16Page<TOTAL_PAGE_SIZE); u16Page++){u8CurPage = (u16Page - FlashOffset)%256;bRet = NovaTekSetExntend(nFileFd,u16Page);if(!bRet){goto END;}else{g_current_bank  = u16Page>>8;}SPageSum  = 0;bSkipPage = MAPI_TRUE;for (int i = 0; i < 512; i++){if(BinFilePageBuffer[u16Page-FlashOffset][i] != 0xff){bSkipPage = MAPI_FALSE;}SPageSum += BinFilePageBuffer[u16Page-FlashOffset][i];}if (NovaTekCheckOverLap(u8CurPage)){bSkipPage = MAPI_TRUE;}if(!bSkipPage)   //Bypass program?{bRet = NovaTekTProgram(nFileFd,u16Page);if(!bRet){goto END;}}if(!bSkipPage){bRet = NovaTekCmdGetCheckSum(nFileFd, u8CurPage);if(!bRet){goto END;}}}if (McuId == 0xa390 || McuId == 0xA400 || McuId == 0xA450){bRet = NovaTek68390ProgramEnable(nFileFd, MAPI_FALSE);}if(DualFwEnable == 1){if(!NovaTekUpdateIDSector(nFileFd)){bRet = MAPI_FALSE;goto END;}}END:NovaTekBlockProtect(nFileFd,1);configIIcSpeed(nFileFd,100);NovaTekISPOff(nFileFd);close(nFileFd);if(!bRet){printf("[%s][%d] novatek upgrade failed. \n", __FUNCTION__,__LINE__);}else{printf("[%s][%d] novatek upgrade successully. \n", __FUNCTION__,__LINE__);}return bRet;
}

2.1 升级文件加载

novatek 提供的bin 升级文件大小为1M,分成2048 个page,每个page大小为512 Bytes。

static MAPI_BOOL NovaTekLoadFwBin(const char* FwPath)
{int nLen = 0;FILE *pHandle = NULL;char binFile[1024];MS_U8  u8RSize     = 0x00;MS_U16 u16PageNo   = 0x0000;MS_U16 u16PageCnt  = 0x0000;MS_U32 u32TotalLen = 0x0000;int nCurPosition   = 0;MAPI_BOOL bRet     = MAPI_FALSE;memset(binFile,0x00,sizeof(binFile));memcpy(binFile,FwPath,strlen(FwPath));pHandle = fopen(binFile, "r");if(pHandle == NULL){return MAPI_FALSE;}fseek(pHandle, 0, SEEK_END);nLen = ftell(pHandle);if(nLen != 1024*1024){fclose(pHandle);return MAPI_FALSE;}u16PageCnt = nLen/512;// set to the file headfseek(pHandle, 0, SEEK_SET);for (u16PageNo = 0; u16PageNo < u16PageCnt; u16PageNo++){u8RSize = fread(BinFilePageBuffer[u16PageNo], sizeof(char)*512, 1, pHandle);u32TotalLen = u32TotalLen + u8RSize*512; // bytesif(u8RSize <= 0){bRet = MAPI_FALSE;break;}}nCurPosition = ftell(pHandle);if(nCurPosition >= nLen){bRet = MAPI_TRUE;}fclose(pHandle);return bRet;
}

将升级文件存储在BinFilePageBuffer[2048][512] 的二维结构体中。

2.2 进入ISP mode


蓝色框框中的byte 序列就是发送给ic 的指令,发送完成之后,就可以通过reply 指令读取mcu id,本款芯片的mcu id 是0xA400。

static MAPI_BOOL NovaTekEnterIsp(int nDevFd)
{MAPI_BOOL bStep1 = MAPI_FALSE;MAPI_BOOL bStep2 = MAPI_FALSE;MAPI_BOOL bStep3 = MAPI_FALSE;MAPI_BOOL bStep4 = MAPI_FALSE;MAPI_BOOL bStep5 = MAPI_FALSE;NOVATEK_DG(printf("[%s][%d] Enter .\n", __FUNCTION__,__LINE__);)do{bStep1 = NovaTekISPOn(nDevFd);if(!bStep1){printf("[%s][%d] novatek enter isp on mode failed. \n", __FUNCTION__,__LINE__);break;}bStep2 = NovaTekSendSpecialCmd(nDevFd);if(!bStep2){printf("[%s][%d] send special cmd to novatek failed. \n", __FUNCTION__,__LINE__);break;}bStep3 = NovaTekGetFlashId(nDevFd);if(!bStep3){printf("[%s][%d] novatek get flash id failed. \n", __FUNCTION__,__LINE__);break;}bStep4 = NovaTekWpEnable(nDevFd);if(!bStep4){printf("[%s][%d] novatek wp enable failed. \n", __FUNCTION__,__LINE__);break;}bStep5 = NovaTekBlockProtect(nDevFd,0);if(!bStep5){printf("[%s][%d] novatek block protect failed. \n", __FUNCTION__,__LINE__);break;}}while(0);return (bStep5 && bStep4 && bStep3 && bStep2 && bStep1);
}

NovaTekISPOn 是发送enter isp 的指令并通过reply 值校验mcu id。NovaTekSendSpecialCmd 发送一些特殊指令配置芯片烧写前的状态。NovaTekGetFlashId 读取flash id。
NovaTekWpEnable 设置novatek 模组wp 脚。NovaTekBlockProtect 关闭写保护。

2.3 擦除芯片

static MAPI_BOOL NovaTekTErase(int nDevFd)
{MAPI_BOOL bRet  = MAPI_FALSE;MS_U32 BlkStart = 0x0000;MS_U32 BlkEnd   = 0x0000;if (McuId == 0xa390 || McuId == 0xA400 || McuId == 0xA450){bRet = NovaTek68390ProgramEnable(nDevFd, MAPI_TRUE);}{bRet = NovaTekChipErase(nDevFd);//6seconds M25P20 erase time max<6sec//5seconds w25x40b erase time max<4secusleep(5*1000*1000);bRet = NovaTekChipEraseReply(nDevFd);if(!bRet){return MAPI_FALSE;}}if (McuId == 0xa390 || McuId == 0xA400 || McuId == 0xA450){bRet = NovaTek68390ProgramEnable(nDevFd, MAPI_FALSE);}return bRet;
}

2.4 升级芯片

    for(u16Page = FlashOffset; (u16Page<(CodePages+FlashOffset))&&(u16Page<TOTAL_PAGE_SIZE); u16Page++){u8CurPage = (u16Page - FlashOffset)%256;bRet = NovaTekSetExntend(nFileFd,u16Page);if(!bRet){printf("[%s][%d][error] set bank: 0x%x failed. \n", __FUNCTION__,__LINE__,u16Page>>8);goto END;}else{g_current_bank  = u16Page>>8;}printf("\n\n[%s][%d] start upgrade bank[%d], page[%d] \n",__FUNCTION__,__LINE__,g_current_bank,u8CurPage);SPageSum  = 0;bSkipPage = MAPI_TRUE;for (int i = 0; i < 512; i++){if(BinFilePageBuffer[u16Page-FlashOffset][i] != 0xff){bSkipPage = MAPI_FALSE;}SPageSum += BinFilePageBuffer[u16Page-FlashOffset][i];}if (NovaTekCheckOverLap(u8CurPage)){bSkipPage = MAPI_TRUE;}printf("\n[%s][%d] bSkipPage: %d, SPageSum: 0x%4x \n",__FUNCTION__,__LINE__,bSkipPage,SPageSum);if(!bSkipPage)   //Bypass program?{bRet = NovaTekTProgram(nFileFd,u16Page);if(!bRet){printf("[%s][%d][error] T Program failed\n", __FUNCTION__,__LINE__);goto END;}}printf("[%s][%d] bank: %d , Page : %d , SPageSum: 0x%4x .\n",__FUNCTION__,__LINE__,g_current_bank, u8CurPage,SPageSum);if(!bSkipPage){bRet = NovaTekCmdGetCheckSum(nFileFd, u8CurPage);if(!bRet){printf("[%s][%d][error] cmd get checksum failed\n", __FUNCTION__,__LINE__);goto END;}}printf("[%s][%d] upgrade bank[%d], page[%d] completed\n",__FUNCTION__,__LINE__,u16Page>>8,u8CurPage);}

将前面保存bin 的二维数组数据写入分区中。NovaTekSetExntend 设置bank(每个bank 256 page), NovaTekTProgram 则是写page

static MAPI_BOOL NovaTekTProgram(int nDevFd, MS_U16 u16BufIndex)
{MAPI_BOOL bRet      = MAPI_FALSE;MAPI_BOOL bRetReply = MAPI_FALSE;bRet = NovaTekWritePgData(nDevFd, u16BufIndex);usleep(200*1000);bRetReply = NovaTekWritePgDataReply(nDevFd);return (bRetReply&&bRet);
}

NovaTekCmdGetCheckSum 则是对每个写入的page 进行校验,通过则继续写下个page 的数据。

2.5 升级完成

升级完成之后,NovaTekBlockProtect打开数据保护,NovaTekISPOff 退出ISP 模式,进入用户模式。

3. 协议客制化

由于novatek 协议主要是ISP ON指令的交互时是非标的,另外一些功能指令交互时的时钟周期不一样。所以我们只需要对这个两部分进行修改即可,没有必要将整个i2c 协议修改。

3.1 i2c 总线周期设置

#define NOVA_TEK__IIC_ADDR   (0x6E >> 1)
static MAPI_BOOL WriteBytesToDev(int nDevFd, MAPI_U8 u8Data[] , MAPI_U16 uDataLen)
{int nRet = -1;struct i2c_msg msg;struct i2c_rdwr_ioctl_data ioctl_data = {0};msg.addr          = NOVA_TEK__IIC_ADDR;msg.flags         = I2C_SMBUS_WRITE; /* write */msg.len           = uDataLen;msg.buf           = u8Data;ioctl_data.msgs   = &msg;ioctl_data.nmsgs  = 1;nRet = ioctl(nDevFd, I2C_RDWR, &ioctl_data);if( nRet < 0){return MAPI_FALSE;}return MAPI_TRUE;
}static MAPI_BOOL configIIcSpeed(int nDevFd, MS_U16 u16Spd)
{MS_U8 u8SRamPkg[4] = {0x88, 0x00, 0x00, 0x00};u8SRamPkg[1] = u16Spd >> 8;u8SRamPkg[2] = u16Spd & 0xFF;u8SRamPkg[3] = (MS_U8)(0x6E^u8SRamPkg[0]^u8SRamPkg[1]^u8SRamPkg[2]);if(WriteBytesToDev(nDevFd, u8SRamPkg, sizeof(u8SRamPkg)/sizeof(u8SRamPkg[0])) == MAPI_FALSE){return MAPI_FALSE;}return MAPI_TRUE;
}

configIIcSpeed 通过 /dev/i2c-2 对应novatek 设备(0x6E)发送指令“0x6E 0x04 0x88 speekH speedL checkSum” 其中speedH 为i2c周期的高8位,speedL为i2c周期的低8位。

在kernel 的master_xfer 回调中会处理i2c 指令,mstar 平台则在vendor\mstar\kernel\linaro\mstar2\drv\iic\mdrv_iic_io.c中

g_i2c_speed 提取i2c 总线速率。

u16  getCustomerSpeed(void)
{return g_i2c_speed;
}

3.2 ISP ON 指令客制化

int MDrv_SW_IIC_WriteBytesForCustomerIspEnable(u8 u8BusNum, u8 u8SlaveID, u16 u16size, u8* pu8Data, int stop)
{int bRet = -EIO;u16 u16Retries = g_IICBus[u8BusNum].u16Retries;u16 u16size_temp=0;u8* pu8Data_temp=(u8*)NULL;SWI2C_DBG_FUNC();if (u8BusAllocNum == 0)return -ENOENT;if (IIC_UseBusForCustomer(u8BusNum, getCustomerSpeed())  == FALSE){return -ENOENT;}u16size_temp = u16size;pu8Data_temp = (u8*)pu8Data;while (u16size_temp){u16size_temp--;if ( IIC_Start(u8BusNum) == FALSE){continue;}if (IIC_SendByte(u8BusNum, *pu8Data_temp) == FALSE) {// goto fail;}// switch to next bytepu8Data_temp++;}bRet = u16size - u16size_temp;iic_delay(u8BusNum);if (stop){IIC_Stop(u8BusNum);}return bRet;
}
EXPORT_SYMBOL(MDrv_SW_IIC_WriteBytesForCustomerIspEnable);

至此,整个升级流程我介绍完成,更多指令客制化可以自己根据需求修改。 如果IO足够多也值可以使用IO口来模拟i2c, 这样会减小对原生协议干扰。

参考资料:
https://app.yinxiang.com/Home.action#n=88618994-1419-47ef-923f-79ecaf89d7d0&s=s30&ses=4&sh=5&sds=2&

hdmiout 68411升级相关推荐

  1. 系统架构升级要不要上微服务?历“久”弥新微服务——你真的需要升级微服务架构吗

    在 <微服务架构设计模式> 一书中,作者总结了关于微服务的一些"重点",原文如下: 中国企业和开发者对微服务架构的热情让我印象深刻.但如同我给所有客户的忠告一样,我想对 ...

  2. 使用rancher对Docker容器服务升级

    这是笔者以前使用到的一个docker管理工具--rancher 升级服务的步骤 记录一下,说不定有人需要或者以后能用上呢? 1.打包好后上传服务器,编写Dockerfile FROM jdk8apli ...

  3. pip 升级之后提示 bash: /usr/bin/pip3: No such file or directory

    1. 问题现象 pip 升级之后使用时报错: $ pip3 -V bash: /usr/bin/pip3: No such file or directory 通过命令查找 pip 位置 $ whic ...

  4. 旷视MegEngine核心技术升级

    旷视MegEngine核心技术升级 7 月 11 日,旷视研究院在 2020 WAIC · 开发者日「深度学习框架与技术生态论坛」上围绕 6 月底发布的天元深度学习框架(MegEngine)Beta ...

  5. 计图(Jittor) 1.1版本:新增骨干网络、JIT功能升级、支持多卡训练

    计图(Jittor) 1.1版本:新增骨干网络.JIT功能升级.支持多卡训练 深度学习框架-计图(Jittor),Jittor的新版本V1.1上线了.主要变化包括: • 增加了大量骨干网络的支持,增强 ...

  6. 快手推荐系统及 Redis 升级存储

    快手推荐系统及 Redis 升级存储 借傲腾™ 补上 DRAM 短板 内容简介: · 作为短视频领域的领先企业,快手需要不断导入更先进的技术手段来调整和优化其系统架构,以应对用户量和短视频作品数量的爆 ...

  7. YOLO3升级优化版!Poly-YOLO:支持实例分割!

    YOLO3升级优化版!Poly-YOLO:支持实例分割! POLY-YOLO: HIGHER SPEED, MORE PRECISE DETECTION AND INSTANCE SEGMENTATI ...

  8. CentOS7 php7.0 升级到php7.3

    不要问我为什么要升级,我不是运维.如果你也不是运维的话,而且是公司的服务器的话,那你还是要慎重啊,我他么的就这样填了一天的坑,简单记录一下这坑爹的一天 备份之前的php7.0(这很重要,非常重要) 如 ...

  9. web app升级—带进度条的App自动更新

    带进度条的App自动更新,效果如下图所示:   技术:vue.vant-ui.5+ 封装独立组件AppProgress.vue: <template><div><van- ...

最新文章

  1. 2006年大话IT数码新潮
  2. Challenge: Machine Learning Basics
  3. Insertion Sort
  4. Integer.parseInt() 与 Integer.valueOf() 区别
  5. php cli 判断,php cli 命令行详解【转】
  6. 【一】Jmeter:体系结构
  7. stl之multiset容器的应用
  8. UnityShader - 模拟动态光照特效
  9. qt可以实现创建临时无线热点吗?_数据线断了,身边又没有路由,如何无线高速传输文件?...
  10. python qq空间登录_Python案例之QQ空间自动登录程序实现-阿里云开发者社区
  11. 悲:又有华为员工猝死,原因调查中
  12. A/Btest:组间的差异性检验,统计功效以及反选样本量,附python底层实现代码
  13. andorid自动化测试之Monkey(上)
  14. plsql窗口文件怎么找回_简单粗暴搞定网易云音乐限制!找回失去的灰色快乐
  15. android5.0 应用闪退,【Android】MultiDex;NoClassDefFoundError;5.0以下系统应用闪退
  16. 广东技术师范大学一行来访虹科并进行“见习-实习-就业一体化基地 ”挂牌仪式
  17. iOS 给NSString文字中间或底部添加横线
  18. 微信小程序API----授权登录拿到用户头像昵称等信息
  19. 研究生平均年薪26.5万!本科生20万!南京大学软件学院19年就这么高!
  20. win7系统 激活步骤

热门文章

  1. HDOJ 动态规划总结
  2. Jason和xml两者的区别
  3. 使用信任集利用腐败矩阵提高网络对含噪标签的鲁棒性
  4. vb/vb.net开发精粹(4)
  5. vb数据库编程(二)--数据控件
  6. 计算机工程学院文艺例会,信息科学与工程学院学生会学生会全体例会暨部门风采展示大会...
  7. 网上报修 php源码,25175网上报修系统管理平台 v2.9
  8. pfamscan 的使用_【HMMSCAN】使用pfam数据库对多序列文件进行结构域注释
  9. Alexa | Alexa通信扩展
  10. 小微企业怎么实现数字化转型