国民技术N32G430开发笔记(19)- IAP 升级 I2C1 从机收发数据
IAP 升级 I2C1 从机收发数据
1、之前讲过usart2收发数据进行IAP升级,上节i2c1设置为从机后,可跟Android版卡通讯,那么融合之前的代码,我们这一节用i2c收发数据进行IAP升级。
2、升级的协议跟之前的usart协议一样:
/*串口升级协议如下:
cmd + data_lenght + data0 + ....+ datax + checksum
1、获取版本号 0x01 0x02 0x00 0x00 checksum
2、升级
1、进入升级模式 0x02 0x02 0x00 0x00 checksum
2、升级文件大小 0x03 0x04 0x00 0x00 0x00 0x00 checksum
3、数据包发送 0x04 0x80 0x00 0x00 0x00 0x00 ..... checksum
4、数据包发送完成 0x05 0x02 0x00 0x00 checksum
*/
3、Android版卡这边的流程:
发送升级模式指令 —>>> 发送升级文件大小—>>>>
分包发送数据—>>>数据包发送完成指令。
4、N32版卡都在handle_i2c_message函数中处理,
跟usart不用的是数据包数据长度为0x80,串口之前受限于usb转串口驱动,长度为0x40
#define UART_UPGRADE_DATA_PACKAGES_LENGHT 0x40
#define I2C_UPGRADE_DATA_PACKAGES_LENGHT 0x80
处理函数:
MI_BOOL handle_i2c_message(MI_U8 *p_buff,MI_U32 len)
{
switch (p_buff[I2C_CMD_INDEX])
{
case I2C_GET_SYSTEM_VERSION_CMD/* constant-expression */:
/* 获取系统版本号 */
/* Noting to do send_i2c_message 中处理*/
break;
case I2C_ENTER_SYSTEM_UPDATE_MODE_CMD:
/* 进入升级模式命令 指示灯变为100ms闪烁一次*/
if (calculate_checksum_and_length(p_buff,len) == MI_TRUE)
{
led_freq = LED_TOGGLE_100_MS;
w_time = 0;
packets_numer = 0;
upgrade_file_size = 0;
remain_packets_numer = 0;
isRunningUpdate = 1;
printf("Mcu Receive Update Command and Wait Receive Data Packets \r\n");
printf("Now to Erase Download Pages \r\n");
printf("\r\n");
n32_flash_erase(DOWNLOAD_START_ADDRESS,DOWNLOAD_END_ADDRESS);
printf("\r\n");
}
break;
case I2C_GET_SYSTEM_FILE_SIZE_CMD:
if (calculate_checksum_and_length(p_buff,len) == MI_TRUE)
{
int a = (int)p_buff[2];
int b = (int)p_buff[3];
int c = (int)p_buff[4];
int d = (int)p_buff[5];
upgrade_file_size = (a<<24) | (b<<16) | (c<<8) | (d);
if (upgrade_file_size % I2C_UPGRADE_DATA_PACKAGES_LENGHT == 0) //如果整除128
{
packets_numer = upgrade_file_size/I2C_UPGRADE_DATA_PACKAGES_LENGHT;
}
else
{
packets_numer = ((upgrade_file_size/I2C_UPGRADE_DATA_PACKAGES_LENGHT) + 1);
}
printf("End Erase Download Pages DONE!!\r\n");
printf("\r\n");
printf("receive upgrade file size %d\r\n",upgrade_file_size);
printf("data packets number %d\r\n",packets_numer);
printf("\r\n");
}
break;
case I2C_RECEIVE_SYSTEM_UPDATE_CMD:
if (calculate_checksum_and_length(p_buff,len) == MI_TRUE)
{
printf("receive packets........................%03d [100] \r\n",(((w_time + 1) * 100) / packets_numer));
memset(i2c_w_buff,0,sizeof(i2c_w_buff));
memcpy(i2c_w_buff,&p_buff[2],sizeof(i2c_w_buff));
n32_flash_write(DOWNLOAD_START_ADDRESS+(w_time * I2C_UPGRADE_DATA_PACKAGES_LENGHT),i2c_w_buff,sizeof(i2c_w_buff));
if (w_time + 1 == packets_numer)
{
led_freq = LED_TOGGLE_1000_MS;
printf("receive packets........................ done!\r\n");
}
w_time ++;
}
break;
case I2C_COMPLETE_SYSTEM_UPDATE_CMD:
if (calculate_checksum_and_length(p_buff,len) == MI_TRUE)
{
system_info_set_update_flag(1);
printf("Now Reboot !\r\n");
app_soft_reset();
}
break;
default:break;
}
#if DEBUG
if(p_buff != 0)
{
for(int i=0;i<len;i++)
{
printf("0x%02x " ,p_buff[i]);
}
printf("\r\n");
}
#endif
return MI_TRUE;
}
5、其他 写flash以及跳转跟串口升级一样。
6、视频:
i2c Tap upgrade