微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 手机设计讨论 > MTK手机平台交流 > Linux的芯片驱动firmware自动升级之二:MELFAS的TP升级实例

Linux的芯片驱动firmware自动升级之二:MELFAS的TP升级实例

时间:10-02 整理:3721RD 点击:

      以MELFAS的MS6000芯片固件升级实例,说明一般的数组格式的IMAGE文件烧录的过程。该芯片需要PIN脚组合完成一定的时序并实现一组命令码进入烧录模式,并且在烧录模式下的I2C地址是0XFA(跟芯片正常工作时的地址0X40不同),在烧录完毕后进行复位并开始相应正常的TP操作。芯片大致的烧录了流程图如下:

         

实现代码如下:

(1)基础宏定义

[cpp] view plaincopy

  • #define FIAMWARE_NAME   "MELFAS_W105.h"                     //数组格式IMAGE的名字  
  • static unsigned char MS6000CTPM_FW[] =                      //以数组划分空间存储烧录映象  
  • {  
  •     #include FIAMWARE_NAME  
  • };  
  • #define MS6000_ADDR_MODULE_REVISION                 0x98  
  • #define MS6000_ADDR_FIRMWARE_VERSION                    0x9C        //烧录IMAGE中对应的特定字节地址  
  • #define MS6000_TRANSFER_LENGTH                      64  //一次烧录的packet字节数  
  •   
  • /*ISP command*/  
  • #define MS6000_ISP_CMD_ERASE                    0x02  
  • #define MS6000_ISP_CMD_ERASE_TIMING                 0x0F  
  • #define MS6000_ISP_CMD_PROGRAM_FLASH                    0x03  
  • #define MS6000_ISP_CMD_READ_FLASH                   0x04  
  • #define MS6000_ISP_CMD_PROGRAM_TIMING               0x0F  
  • #define MS6000_ISP_CMD_READ_INFORMATION             0x06  
  • #define MS6000_ISP_CMD_RESET                            0x07  
  •   
  • #define MS6000_7BIT_DOWNLOAD_ADDR                   0x7D         
  • #define MS6000_8BIT_DOWNLOAD_ADDR                   (MS6000_7BIT_DOWNLOAD_ADDR<<1) //linux的i2CCLIent需8位地址   
  • #define MS6000_I2C_SLAVE_READY_STATUS               0x55  
  •   
  • // MCS6000's responses  
  • #define MS6000_ISP_ACK_ERASE_DONE                   0x82  
  • #define MS6000_ISP_ACK_PREPARE_ERASE_DONE           0x8F  
  • #define MS6000_I2C_ACK_PREPARE_PROGRAM              0x8F  
  • #define MS6000_MDS_ACK_PROGRAM_FLASH                    0x83  
  • #define MS6000_MDS_ACK_READ_FLASH                   0x84  
  • #define MS6000_MDS_ACK_PROGRAM_INFORMATION          0x88  
  • #define MS6000_MDS_ACK_PROGRAM_LOCKED               0xFE  
  • #define MS6000_MDS_ACK_READ_LOCKED                  0xFE  
  • #define MS6000_MDS_ACK_FAIL                         0xFE  
  •   
  • #define MS6000_ISP_ERASE_TIMING_VALUE_0             0x01  
  • #define MS6000_ISP_ERASE_TIMING_VALUE_1             0xD4  
  • #define MS6000_ISP_ERASE_TIMING_VALUE_2             0xC0  
  •   
  • #define MS6000_ISP_PROGRAM_TIMING_VALUE_0           0x00  
  • #define MS6000_ISP_PROGRAM_TIMING_VALUE_1           0x00  
  • #define MS6000_ISP_PROGRAM_TIMING_VALUE_2           0x78  

(2)I2C烧写和读TP FLASH的函数
       注意:该芯片在烧录模式下的单字节读操作和写操作都不需要寄存器地址,只send芯片地址就行。里面用到的i2c_client->address已变换地址。

[cpp] view plaincopy

  • static bool mfs_i2c_write_single_byte(unsigned char bufVal)  
  • {  
  •     int ret;  
  •     unsigned char buf;  
  •     buf = bufVal;  
  •   
  •     ret = i2c_master_send(i2c_client, &buf, 1);  
  •     if(ret <= 0){  
  •                 printk("mfs_i2c_write_single_byte error line = %d, ret = %d\n", __LINE__, ret);  
  •                 return false;  
  •         }  
  •     return true;  
  • }  
  • static bool mfs_i2c_read_single_byte(unsigned char *buf)  
  • {  
  •     int ret;  
  •     ret = i2c_master_recv(i2c_client, buf, 1);  
  •     if(ret <= 0){  
  •                 printk("mfs_i2c_read_single_byte error line = %d, ret = %d\n", __LINE__, ret);  
  •                 return false;  
  •         }  
  •     return true;  
  • }  
  • static int mfs_i2c_read_flash(unsigned char *pBuffer,UINT16 nAddr_start,unsigned char cLength)  
  • {                               //将nAddr_start开始的cLength个字节读到pBuffer所指的空间中  
  •     int nRet = MS6000_RET_READ_FLASH_FAILED,i;  
  •     BOOL bRet;  
  •     unsigned char cmd[4],ucTemp;  
  •   
  • // Send Read Flash command   [ Read code - address high - address low - size ]   
  •     cmd[0] = MS6000_ISP_CMD_READ_FLASH;  
  •     cmd[1] = (UINT8)((nAddr_start >> 8 ) & 0xFF);  
  •     cmd[2] = (UINT8)((nAddr_start      ) & 0xFF);  
  •     cmd[3] = cLength;  
  •   
  •     for(i=0;i<4;i++){  
  •         bRet = mfs_i2c_write_single_byte(cmd);  
  •         udelay(15);  
  •         if(bRet == FALSE)  
  •             goto MS6000_I2C_READ_FLASH_FINISH;  
  •     }  
  • // Read 'Result of command'  
  •     bRet = mfs_i2c_read_single_byte(&ucTemp);  
  •     if( !bRet || ucTemp != MS6000_MDS_ACK_READ_FLASH){  
  •         goto MS6000_I2C_READ_FLASH_FINISH;  
  •     }  
  • // Read Data  [ pCmd[3] == Size ]  
  •     for(i=0; i<(int)cmd[3]; i++){  
  •         udelay(100);  
  •         bRet = mfs_i2c_read_single_byte(pBuffer++);  
  •         if( bRet == FALSE && i!=(int)(cmd[3]-1) )  
  •             goto MS6000_I2C_READ_FLASH_FINISH;  
  •     }  
  •     nRet = MS6000_RET_SUCCESS;  
  •       
  • MS6000_I2C_READ_FLASH_FINISH:  
  •     return nRet;  
  • }  


(3)进入download功能

[cpp] view plaincopy

  • static void ms6000_write_download_mode_signal(void)                 //通过RESET脚和EINT脚发出一组组合电平  
  • {  
  •     int i;  
  •     unsigned char enter_code[14] = { 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1 };  
  •   
  •     for(i=0; i<14; i++){  
  •         if(enter_code){  
  •             mt_set_GPIO_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);      
  •             mt_set_gpio_out(GPIO_CTP_EINT_PIN, GPIO_OUT_ONE);  
  •         }  
  •         else{  
  •             mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO);     
  •             mt_set_gpio_out(GPIO_CTP_EINT_PIN, GPIO_OUT_ZERO);  
  •         }  
  •         mt_set_gpio_out(GPIO_I2C0_SCA_PIN, GPIO_OUT_ONE);  
  •         udelay(15);  
  •         mt_set_gpio_out(GPIO_I2C0_SCA_PIN, GPIO_OUT_ZERO);  
  •   
  •         mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO);     
  •         mt_set_gpio_out(GPIO_CTP_EINT_PIN, GPIO_OUT_ZERO);  
  •         udelay(100);  
  •     }  
  •     mt_set_gpio_out(GPIO_I2C0_SCA_PIN, GPIO_OUT_ONE);  
  •     udelay(100);  
  •     mt_set_gpio_out(GPIO_CTP_EINT_PIN, GPIO_OUT_ONE);  
  •     mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);      
  • }  
  • static int ms6000_enter_download_mode(void)  
  • {  
  •     bool bRet;  
  •     int nRet = MS6000_RET_ENTER_DOWNLOAD_MODE_FAILED;  
  •   
  •     unsigned char cData=0;  
  •   
  •     hwpowerDown(MT65XX_POWER_LDO_VGP2, "TP");   //TKEY_VDD_SET_LOW();      
  •   
  •     mt_set_gpio_mode(GPIO_I2C0_SCA_PIN, GPIO_I2C0_SCA_PIN_M_GPIO);  
  •     mt_set_gpio_dir(GPIO_I2C0_SCA_PIN, GPIO_DIR_OUT);  
  •     mt_set_gpio_out(GPIO_I2C0_SCA_PIN, GPIO_OUT_ZERO);   
  •     mt_set_gpio_mode(GPIO_I2C0_SDA_PIN, GPIO_I2C0_SDA_PIN_M_GPIO);  
  •     mt_set_gpio_dir(GPIO_I2C0_SDA_PIN, GPIO_DIR_OUT);  
  •     mt_set_gpio_out(GPIO_I2C0_SDA_PIN, GPIO_OUT_ZERO);      //I2C变GPIO功能  
  •   
  •     mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_GPIO);  
  •     mt_set_gpio_dir(GPIO_CTP_EINT_PIN, GPIO_DIR_OUT);           //TKEY_INTR_SET_OUTPUT();  
  •     mt_set_gpio_out(GPIO_CTP_EINT_PIN, GPIO_OUT_ZERO);      //TKEY_INTR_SET_LOW();  
  •   
  •     mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);  
  •         mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);        //TKEY_RESETB_SET_OUTPUT();  
  •         mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO);       //若干功能脚均需完成电平拉低的作用   
  •   
  •     mdelay(90);     //Delay for Stable VDD  
  •   
  •     hwPowerOn(MT65XX_POWER_LDO_VGP2, VOL_2800, "TP");   //TKEY_VDD_SET_HIGH();  
  •     mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);        //TKEY_CE_SET_HIGH();  
  •     mt_set_gpio_out(GPIO_I2C0_SDA_PIN, GPIO_OUT_ONE);       //TKEY_I2C_SDA_SET_HIGH();  
  •     mdelay(25);  
  •   
  •     ms6000_write_download_mode_signal();                    //写命令码  
  •     mt_set_gpio_mode(GPIO_I2C0_SCA_PIN, GPIO_I2C0_SCA_PIN_M_SCL);  
  •     mt_set_gpio_mode(GPIO_I2C0_SDA_PIN, GPIO_I2C0_SDA_PIN_M_SDA);      //使能I2C的PIN脚恢复I2C功能  
  •     mdelay(2);  
  •     bRet = mfs_i2c_read_single_byte(&cData);  
  •     if( bRet != TRUE || cData != MS6000_I2C_SLAVE_READY_STATUS ){  
  •         goto MS6000_ENTER_DOWNLOAD_MODE_FINISH;  
  •     }  
  •     else  
  •         printk("respond fROM download mode commande is 0x55 \r\n");   //只有芯片状态返回0x55,才说明进入DOWNLOAD模式  
  •     nRet = MS6000_RET_SUCCESS;  //Entering MDS ISP mode finished.  
  •   
  • MS6000_ENTER_DOWNLOAD_MODE_FINISH:  
  •     return nRet;  
  • }  


(4)芯片复位和TP FLASH擦除

[cpp] view plaincopy

  • static void ms6000_reset_command(void)                  //不管是升级过程失败还是成功,最后都需要复位并使能芯片  
  • {  
  •     unsigned char buf;  
  •     mdelay(1);  
  •     buf = MS6000_ISP_CMD_RESET;  
  •     if(mfs_i2c_write_single_byte(buf) == true)  
  •         printk("mfs6000_reset_command reset success \r\n");  
  •     mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_EINT);  
  •     mt_set_gpio_dir(GPIO_CTP_EINT_PIN, GPIO_DIR_IN);  
  •     mt_set_gpio_pull_enable(GPIO_CTP_EINT_PIN, GPIO_PULL_ENABLE);  
  •     mt_set_gpio_pull_select(GPIO_CTP_EINT_PIN, GPIO_PULL_UP);           //恢复EINT的pin功能  
  •     mdelay(180);  
  • }  
  • static unsigned char ms6000_GetLibVer(void)                     //取得新固件中的版本号,以便比较  
  • {  
  •      unsigned int sz;  
  •         sz = sizeof(MS6000CTPM_FW);  
  •   
  •         if(sz > 2){  
  •                 return (MS6000CTPM_FW[157]-0X30);                   //版本号字节数据  
  •         }  
  •         else{  
  •                 return 0xff;  
  •         }  
  • }  
  • static int ms6000_i2c_prepare_erase_flash(void)  
  • {  
  •     int   nRet = MS6000_RET_PREPARE_ERASE_FLASH_FAILED,i;  
  •     BOOL bRet;  
  •   
  •     UINT8 i2c_buffer[4] = { MS6000_ISP_CMD_ERASE_TIMING,  
  •                             MS6000_ISP_ERASE_TIMING_VALUE_0,  
  •                             MS6000_ISP_ERASE_TIMING_VALUE_1,  
  •                             MS6000_ISP_ERASE_TIMING_VALUE_2   };  
  •     UINT8   ucTemp;  
  • // Send Erase Setting code  
  •     for(i=0; i<4; i++){  
  •         bRet = mfs_i2c_write_single_byte(i2c_buffer);  
  •         if( !bRet ){  
  •             goto MS6000_I2C_PREPARE_ERASE_FLASH_FINISH;  
  •         }  
  •         udelay(15);  
  •     }  
  • // Read Result  
  •     udelay(500);  
  •     bRet = mfs_i2c_read_single_byte(&ucTemp);  
  •     if( bRet && ucTemp == MS6000_ISP_ACK_PREPARE_ERASE_DONE ){  
  •         nRet = MS6000_RET_SUCCESS;  
  •     }  
  •   
  • MS6000_I2C_PREPARE_ERASE_FLASH_FINISH:  
  •     return nRet;  
  • }  
  • static int ms6000_i2c_erase_flash(void)  
  • {  
  •     int   nRet = MS6000_RET_ERASE_FLASH_FAILED,i;  
  •     BOOL bRet;  
  •     UINT8   i2c_buffer[1] = {   MS6000_ISP_CMD_ERASE};  
  •     UINT8   ucTemp;  
  • // Send Erase code  
  •     for(i=0; i<1; i++){  
  •         bRet = mfs_i2c_write_single_byte(i2c_buffer);  
  •         if( !bRet )  
  •             goto MS6000_I2C_ERASE_FLASH_FINISH;  
  •         udelay(15);  
  •     }  
  • // Read Result  
  •     mdelay(45);  
  •     bRet = mfs_i2c_read_single_byte(&ucTemp);  
  •     if( bRet && ucTemp == MS6000_ISP_ACK_ERASE_DONE ){  
  •         nRet = MS6000_RET_SUCCESS;  
  •     }  
  •   
  • MS6000_I2C_ERASE_FLASH_FINISH:   
  •     return nRet;  
  • }  


(5)预编程和编程函数,以及download映象主函数

[cpp] view plaincopy

  • static int ms6000_i2c_prepare_program(void)  
  • {  
  •     int nRet = MS6000_RET_PREPARE_PROGRAM_FAILED,i;  
  •     BOOL bRet;  
  •     UINT8 i2c_buffer[4] = { MS6000_ISP_CMD_PROGRAM_TIMING,  
  •                             MS6000_ISP_PROGRAM_TIMING_VALUE_0,  
  •                             MS6000_ISP_PROGRAM_TIMING_VALUE_1,  
  •                             MS6000_ISP_PROGRAM_TIMING_VALUE_2};  
  • //   Write Program timing information  
  •     for(i=0; i<4; i++){  
  •         bRet = mfs_i2c_write_single_byte(i2c_buffer);  
  •         if( bRet == FALSE )  
  •             goto MS6000_I2C_PREPARE_PROGRAM_FINISH;  
  •         udelay(15);  
  •     }  
  •     udelay(500);  
  • //   Read command's result  
  •     bRet = mfs_i2c_read_single_byte(&i2c_buffer[4]);  
  •     if( bRet == FALSE || i2c_buffer[4] != MS6000_I2C_ACK_PREPARE_PROGRAM)  
  •         goto MS6000_I2C_PREPARE_PROGRAM_FINISH;  
  •     mdelay(100);  
  •     nRet = MS6000_RET_SUCCESS;  
  •   
  • MS6000_I2C_PREPARE_PROGRAM_FINISH:   
  •     return nRet;  
  • }  
  • static int ms6000_i2c_program_flash( UINT8 *pData, UINT16 nAddr_start, UINT8 cLength )  //FLASH one packet编程主函数  
  • {                                   //参数是待编程数据,写入地址,待编程数据长度  
  •     int nRet = MS6000_RET_PROGRAM_FLASH_FAILED;  
  •     int     i,j;  
  •     BOOL   bRet;  
  •     UINT8    cData;  
  •     UINT8    tmp;  
  •     UINT8    cmd[4];  
  • // Send program code      
  •     cmd[0] = MS6000_ISP_CMD_PROGRAM_FLASH;  
  •     cmd[1] = (UINT8)((nAddr_start >> 8 ) & 0xFF);  
  •     cmd[2] = (UINT8)((nAddr_start      ) & 0xFF);  
  •     cmd[3] = cLength;  
  •     for(i=0; i<4; i++){  
  •         bRet = mfs_i2c_write_single_byte(cmd);  
  •         udelay(15);  
  •         if( bRet == FALSE )  
  •             goto MS6000_I2C_PROGRAM_FLASH_FINISH;  
  •     }  
  • // Check command result  
  •     bRet = mfs_i2c_read_single_byte(&cData);  
  •     if( bRet == FALSE || cData != MS6000_MDS_ACK_PROGRAM_FLASH ){  
  •         goto MS6000_I2C_PROGRAM_FLASH_FINISH;  
  •     }  
  • // Program Data  
  •     udelay(150);  
  •     for(i=0; i<(int)cmd[3]; i+=2){               //一次写入两个字节,先写高位,再写低位  
  •         bRet = mfs_i2c_write_single_byte(pData[i+1]);  
  •         if( bRet == FALSE )  
  •             goto MS6000_I2C_PROGRAM_FLASH_FINISH;  
  •         udelay(100);              // Delay about 150us  
  •         bRet = mfs_i2c_write_single_byte(pData);  
  •         udelay(150);                   // Delay about 150us  
  •         if( bRet == FALSE )  
  •             goto MS6000_I2C_PROGRAM_FLASH_FINISH;  
  •     }  
  •     nRet = MS6000_RET_SUCCESS;  
  •   
  • MS6000_I2C_PROGRAM_FLASH_FINISH:      
  •     return nRet;  
  • }  
  • static int ms6000_download(const UINT8 *pData, const UINT16 nLength )   //download主函数,参数是映象内存首地址及映象长度  
  • {  
  •     int i,nRet;  
  •     unsigned char cLength,buffer[MS6000_TRANSFER_LENGTH];  
  •     uint16_t nStart_address=0;  
  •     unsigned char *pOriginal_data;  
  • //enter in download mode  
  •     nRet = ms6000_enter_download_mode();  
  •     if(nRet != MS6000_RET_SUCCESS)  
  •         goto MS6000_DOWNLOAD_FINISH;  
  •   
  •     mdelay(1);  
  • // Erase Flash  
  •     nRet = ms6000_i2c_prepare_erase_flash();  
  •     if(nRet !=MS6000_RET_SUCCESS){  
  •         goto MS6000_DOWNLOAD_FINISH;      
  •     }  
  •     mdelay(1);  
  •     nRet = ms6000_i2c_erase_flash();  
  •     if(nRet !=MS6000_RET_SUCCESS)  
  •         goto MS6000_DOWNLOAD_FINISH;  
  •     mdelay(1);  
  • // Verify erase  
  •     nRet = mfs_i2c_read_flash( buffer, 0x00, 16 );      // Must be '0xFF' after erase  
  •     if( nRet != MS6000_RET_SUCCESS )  
  •         goto MS6000_DOWNLOAD_FINISH;  
  •     for(i=0; i<16; i++){  
  •         if( buffer != 0xFF ){  
  •             nRet = MS6000_RET_ERASE_VERIFY_FAILED;  
  •             goto MS6000_DOWNLOAD_FINISH;  
  •         }  
  •     }  
  •     mdelay(1);  
  • // Prepare for Program flash.     
  •     nRet = ms6000_i2c_prepare_program();  
  •     if( nRet != MS6000_RET_SUCCESS )  
  •         goto MS6000_DOWNLOAD_FINISH;  
  •     mdelay(1);  
  • // Program flash  
  • #if 1  
  •     pOriginal_data  = (UINT8 *)pData;                   //保留原始首地址  
  •     nStart_address = 0;                     //烧录起始地址  
  •     cLength  = MS6000_TRANSFER_LENGTH;                  //一次烧录长度,64B  
  •     for( nStart_address = 0; nStart_address < nLength; nStart_address+=cLength ){  
  •         if( ( nLength - nStart_address ) < MS6000_TRANSFER_LENGTH ){  
  •             cLength  = (UINT8)(nLength - nStart_address);  
  •             cLength += (cLength%2);     // For odd length.最后不足64B的,补上1字节当偶数处理,因为以WORD烧录  
  •         }  
  •         nRet = ms6000_i2c_program_flash( pOriginal_data, nStart_address, cLength );  
  •         if( nRet != MS6000_RET_SUCCESS ){  
  •             goto MS6000_DOWNLOAD_FINISH;  
  •         }  
  •         pOriginal_data  += cLength;  
  •         udelay(500);  
  •         printk("#");  
  •     }  
  •     printk("mfs6000 program finished \r\n");  
  • #endif   
  • // Verify flash  
  • #if 1  
  •     pOriginal_data  = (UINT8 *) pData;                  //保留原始首地址  
  •     nStart_address = 0;  
  •     cLength  = MS6000_TRANSFER_LENGTH;  
  •     for( nStart_address = 0; nStart_address < nLength; nStart_address+=cLength ){  
  •         if( ( nLength - nStart_address ) < MS6000_TRANSFER_LENGTH ){  
  •             cLength = (UINT8)(nLength - nStart_address);  
  •             cLength += (cLength%2);             // For odd length.  
  •         }  
  •         // Read flash  
  •         nRet = mfs_i2c_read_flash( buffer, nStart_address, cLength );  
  •         // Comparing  
  •         for(i=0; i<(int)cLength; i++){  
  •             if( buffer != pOriginal_data ){       //如果读出的对应地址字节与原始对应地址数据不同  
  •                 nRet = MS6000_RET_PROGRAM_VERIFY_FAILED;  
  •                 goto MS6000_DOWNLOAD_FINISH;  
  •             }  
  •         }  
  •         pOriginal_data += cLength;  
  •         udelay(500);  
  •         printk("*");  
  •     }  
  •     printk("mfs6000 Verify finished \r\n");  
  • #endif   
  •     nRet = MS6000_RET_SUCCESS;  
  •   
  • MS6000_DOWNLOAD_FINISH:  
  •     ms6000_reset_command();  
  •     return nRet;  
  • }  


(6)升级主函数,以及TP probe函数中的处理

[cpp] view plaincopy

  • static int ms6000_firmware_upgrade()  
  • {  
  •     unsigned char NewFwVersion,OldFwVersion;  
  •     uint16_t nBinary_length = 0;  
  •     int nRead = 0;  
  •     unsigned char *ptrBuff = NULL;  
  •     int ret = MS6000_RET_FILE_ACCESS_FAILED;  
  •   
  •     if(mfs_i2c_read_single_reg(0x21,&OldFwVersion) == true){        //在此之前,TP的供电及初始化一定要有,否则读不出来  
  •         NewFwVersion = ms6000_GetLibVer();  
  •         printk("mfs6000 OldFwVersion is %d,and  NewFwVersion is %d \r\n",OldFwVersion,NewFwVersion);  
  •     }  
  • i2c_client->addr = MS6000_8BIT_DOWNLOAD_ADDR;                    //变换成TP的升级I2C地址  
  •     if(NewFwVersion != OldFwVersion){                   //如果版本号不同就升级  
  •         ptrBuff = MS6000CTPM_FW;  
  •         nBinary_length = sizeof(MS6000CTPM_FW);  
  •          
  • //download process  
  •         printk("start download \r\n");  
  •         mtk_wdt_disable();  
  •         ret = ms6000_download(ptrBuff,nBinary_length);  
  •         mtk_wdt_get_en_setting();                   //升级前后必须有禁止WDT和使能WDT的动作,否则易重启  
  • //check process  
  •     }  
  •     else{                               //如果版本号相同则不动作  
  •         printk("because of the same lib, update abort!\r\n");  
  •     }  
  •   
  •     return ret;  
  • }  
  • //如下是TPD_RROBE中的改动  
  • {  
  •     mt65xx_eint_mask(CUST_EINT_touch_PANEL_NUM);                    //mask TP中断  
  •     int UpResult;  
  •     UpResult = ms6000_firmware_upgrade();  
  •     if(UpResult== MS6000_RET_SUCCESS)  
  •         printk("MFS6000 DOWNLOAD SUCCESS \r\n");  
  •     else  
  •         mfs6000_print_fail_result(UpResult);  
  •     i2c_client->addr = MS6000_8BIT_I2CADDR;                  //恢复TP的正常操作时I2C地址  
  •     mt_set_gpio_mode(GPIO_I2C0_SCA_PIN, GPIO_I2C0_SCA_PIN_M_SCL);  
  •     mt_set_gpio_mode(GPIO_I2C0_SDA_PIN, GPIO_I2C0_SDA_PIN_M_SDA);           //恢复I2C功能脚  
  •     mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);              //unmask TP中断  
  • }  


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top