清洁机器人之音频方案 ISD2360 开发总结2 基于GD32F103的音频控制播放与升级
清洁机器人之音频方案 ISD2360 开发总结2–基于GD32F103的音频控制播放与升级
文章目录
- 清洁机器人之音频方案 ISD2360 开发总结2--基于GD32F103的音频控制播放与升级
-
- 3. 系统硬件设计实现电路
-
- 3.1硬件连接示意图
- 3.2 MCU与ISD2360的具体硬件连接
- 4. 系统软件设计
-
- 4.1 GPIO模拟SPI
- 4.2 精确延时方法
- 4.3 ISD2360初始化流程
- 4.4 ISD2360状态解析
-
- 4.4.1 位获取方法1
- 4.4.2 位获取方法2
- 4.4.3 位解析
- 4.5 ISD2360设置音量
- 4.6 ISD2360设置数据路径以及播放audio channel
- 4.7 ISD2360 CLK设置
- 4.8 ISD2360 PIN IO设置
- 4.9 ISD2360 播放音频 以及查询读取芯片状态以及中断状态 来判断播放是否完成
- 4.10 ISD2360 mem读取
- 4.11 ISD2360 chip ERASE
- 4.12 ISD2360 mem写入
-
- 4.12.1 命令执行前提以及命令执行完成判断
- 4.12.2 单字节以及多字节写入
- 4.12.3 单字节以及多字节写函数实现
- 4.13 ISD2360 checksum计算
-
- 4.13.1 ISD2360 checksum 硬件计算
- 4.13.2 ISD2360 checksum 软件计算
-
- 4.13.2.1 ISD2360 checksum 软件MCU端计算
- 4.13.2.1 ISD2360 checksum 软件linux 编译服务器端计算
- 4.13.2.3 fletcher32_RevrseCalculate实现
- 4.14 ISD2360 memlayout
- 5.ISD2360 mem工程
-
- 4.14 ISD2360 memlayout
- 5.ISD2360 mem工程
3. 系统硬件设计实现电路
3.1硬件连接示意图
ISD2360的电源有2个 ,一个VDD 一个是Vpwm ,可以共用一个电源,也可以分开供电
MCU是3.3V,VDD 也需要采用3.3 否则存在电平不匹配
Vpwm 可以是5V 这样可以获取较大的音频喇叭输出功率
硬件需可以对这两个电源进行切断,以进行硬件冷复位
3.2 MCU与ISD2360的具体硬件连接
MCU 是GD32F103
语音模块 | MCU管脚 | |
---|---|---|
SCLK | PIN30 | SPI1_SCK |
MISO | PIN32 | SPI1_MOSI |
MOSI | PIN31 | SPI1_MISO |
SSB | PIN29 | SPI1_CS |
INTB | PIN98 PE1 | IO_INT |
RDY/B | PIN39 PE8 | IO_INT |
RST | PIN40 PE9 |
4. 系统软件设计
4.1 GPIO模拟SPI
/*SPI0_SCLK*/#define SPI0_SCLK_GPIO_PORT GPIOA#define SPI0_SCLK_GPIO_PIN GPIO_PIN_5#define SPI0_SCLK_RCU RCU_GPIOA/*SPI0_MISO*/#define SPI0_MISO_GPIO_PORT GPIOA#define SPI0_MISO_GPIO_PIN GPIO_PIN_6#define SPI0_MISO_RCU RCU_GPIOA/*SPI0_MOSI*/#define SPI0_MOSI_GPIO_PORT GPIOA#define SPI0_MOSI_GPIO_PIN GPIO_PIN_7#define SPI0_MOSI_RCU RCU_GPIOA/*SPI0_NSS*/#define SPI0_NSS_GPIO_PORT GPIOA#define SPI0_NSS_GPIO_PIN GPIO_PIN_4#define SPI0_NSS_RCU RCU_GPIOA#define ISD2130_NSS_HIGH gpio_bit_set(SPI0_NSS_GPIO_PORT,SPI0_NSS_GPIO_PIN)#define ISD2130_NSS_LOW gpio_bit_reset(SPI0_NSS_GPIO_PORT,SPI0_NSS_GPIO_PIN)#define ISD2130_SCLK_HIGH gpio_bit_set(SPI0_SCLK_GPIO_PORT,SPI0_SCLK_GPIO_PIN)#define ISD2130_SCLK_LOW gpio_bit_reset(SPI0_SCLK_GPIO_PORT,SPI0_SCLK_GPIO_PIN)#define ISD2130_SDIN_HIGH gpio_bit_set(SPI0_MOSI_GPIO_PORT,SPI0_MOSI_GPIO_PIN)#define ISD2130_SDIN_LOW gpio_bit_reset(SPI0_MOSI_GPIO_PORT,SPI0_MOSI_GPIO_PIN)#define ISD2130_SDOUT gpio_input_bit_get(SPI0_MISO_GPIO_PORT,SPI0_MISO_GPIO_PIN)#define ISD2130_RDY_BSY_GPIO_PORT (GPIOE)#define ISD2130_RDY_BSY_GPIO_PIN (GPIO_PIN_8)#define ISD2130_RDY gpio_input_bit_get(ISD2130_RDY_BSY_GPIO_PORT,ISD2130_RDY_BSY_GPIO_PIN)
/*函数名称:void Spi_Init(void)入口参数:无返回参数:无使用说明:调用此函数从而初始化SPI操作作用:初始化SPI*/void Spi_Init(void){//ISD2130_CS =1;//ISD2130_CS =1; ISD2130_NSS_HIGH; Delay_1us();//asm("nop");//asm("nop");//asm("nop");//asm("nop"); ISD2130_SCLK_HIGH; Delay_1us();//add for cmd errorDelay_1us();//asm("nop");//asm("nop");//asm("nop");//asm("nop");}
4.2 精确延时方法
void Delay_1us(void){#if 0 while(nUsTime--) { __NOP(); }#else__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); /*__nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); \__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop(); */ #endif}
4.3 ISD2360初始化流程
热复位
读取芯片状态以及中断状态
上电
//停止播放, 可加可不加
获取芯片ID
printf("\r\Reset_Device...\r\n"); Reset_Device(); printf("\r\n ReadStatus...\r\n"); Device_status[0] = 0x00; Device_status[1] = 0x00; ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[1] != 0x00 ) ReadInt(); printf("\r\Power_Up...\r\n"); Power_Up(); printf("\r\n ReadStatus...\r\n"); Device_status[0] = 0x00; Device_status[1] = 0x00; ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]); printf("\r\n Stop...\r\n"); Stop(); printf("\r\n ReadStatus...\r\n"); Device_status[0] = 0x00; Device_status[1] = 0x00; ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]); printf("\r\nReadId...\r\n"); ReadId(); printf("\r\nDevice_ID_Buffer 0x%02x", Device_ID_Buffer[0]); printf("\r\nDevice_ID_Buffer 0x%02x", Device_ID_Buffer[1]); printf("\r\nDevice_ID_Buffer 0x%02x", Device_ID_Buffer[2]); printf("\r\nDevice_ID_Buffer 0x%02x", Device_ID_Buffer[3]);
4.4 ISD2360状态解析
4.4.1 位获取方法1
byData = Device_status[0]; n0 = (byData & 0x01) == 0x01 ? 1 : 0; n1 = (byData & 0x02) == 0x02 ? 1 : 0; n2 = (byData & 0x04) == 0x04 ? 1 : 0; n3 = (byData & 0x08) == 0x08 ? 1 : 0; n4 = (byData & 0x10) == 0x10 ? 1 : 0; n5 = (byData & 0x20) == 0x20 ? 1 : 0; n6 = (byData & 0x40) == 0x40 ? 1 : 0; n7 = (byData & 0x80) == 0x80 ? 1 : 0;
4.4.2 位获取方法2
//获取某一位#defineGET_BIT(x, bit)((x & (1 <> bit)/* 获取第bit位 *///清零某一位#defineCLEAR_BIT(x, bit)(x &= ~(1 << bit))/* 清零第bit位 *///置位某一位#defineSET_BIT(x, bit)(x |= (1 << bit))/* 置位第bit位 */
4.4.3 位解析
Device_status[0] = 0x00; Device_status[1] = 0x00; ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]); //chaip status byData = Device_status[0]; n0 = (byData & 0x01) == 0x01 ? 1 : 0; n1 = (byData & 0x02) == 0x02 ? 1 : 0; n2 = (byData & 0x04) == 0x04 ? 1 : 0; n3 = (byData & 0x08) == 0x08 ? 1 : 0; n4 = (byData & 0x10) == 0x10 ? 1 : 0; n5 = (byData & 0x20) == 0x20 ? 1 : 0; n6 = (byData & 0x40) == 0x40 ? 1 : 0; n7 = (byData & 0x80) == 0x80 ? 1 : 0; if(n0 == 1) printf("this bit indicates that the Flash controller is still processing a digital memory access.\r\n"); if(n1 == 1) printf("this bit indicates that channel [1] is in one of the following conditions\r\n"); if(n2 == 1) printf("this bit indicates that channel [2] is in one of the following conditions\r\n"); if(n3 == 1) printf("this bit indicates that channel [3] is in one of the following conditions\r\n"); if(n5 == 1) { printf("Indicates that an interrupt has been generated\r\n"); status = gpio_input_bit_get(SPI_TRIG_GPIO_PORT, SPI_TRIG_GPIO_PIN); printf("\r\n mcu int io status=%d\r\n",status); } if(n6 == 1) { printf("When PD is low, this bit reflects the state of the RDY/BSY pin\r\n"); status = gpio_input_bit_get(IR_BL_GPIO_PORT, IR_BL_GPIO_PINS); printf("\r\n isd2360 rdy/busy io status=%d\r\n",status); } //IR_BL_GPIO_PINS --RDY if(n7 == 1) printf("the device is powered down\r\n"); else { printf("the device is powered up\r\n"); }{//获取某一位#defineGET_BIT(x, bit)((x & (1 <> bit)/* 获取第bit位 *///清零某一位#defineCLEAR_BIT(x, bit)(x &= ~(1 << bit))/* 清零第bit位 *///置位某一位#defineSET_BIT(x, bit)(x |= (1 << bit))/* 置位第bit位 *///判断某一位或某几位连续位的值//判断某一位//if(x & (1 << bit)) printf("x的第 bit位为1 ")//断某几位连续位的值/* 获取第[n:m]位的值 ,如 第[30:3] BIT_M_TO_N(x, 3, 30),n是高bit index */ //#define BIT_M_TO_N(x, m, n) ((unsigned int)(x <> ((31 - (n)) + (m)))byData = Device_status[0];printf("0x%02x 的第0 BIT是%d\r\n",byData,GET_BIT(byData, 0));printf("0x%02x 的第1 BIT是%d\r\n",byData,GET_BIT(byData, 1));printf("0x%02x 的第2 BIT是%d\r\n",byData,GET_BIT(byData, 2));printf("0x%02x 的第3 BIT是%d\r\n",byData,GET_BIT(byData, 3));printf("0x%02x 的第4 BIT是%d\r\n",byData,GET_BIT(byData, 4));printf("0x%02x 的第5 BIT是%d\r\n",byData,GET_BIT(byData, 5));printf("0x%02x 的第6 BIT是%d\r\n",byData,GET_BIT(byData, 6));printf("0x%02x 的第7 BIT是%d\r\n",byData,GET_BIT(byData, 7));} //chip int status byData = Device_status[1]; n0 = (byData & 0x01) == 0x01 ? 1 : 0; n1 = (byData & 0x02) == 0x02 ? 1 : 0; n2 = (byData & 0x04) == 0x04 ? 1 : 0; n3 = (byData & 0x08) == 0x08 ? 1 : 0; n4 = (byData & 0x10) == 0x10 ? 1 : 0; n5 = (byData & 0x20) == 0x20 ? 1 : 0; n6 = (byData & 0x40) == 0x40 ? 1 : 0; n7 = (byData & 0x80) == 0x80 ? 1 : 0; if(n7 == 1) printf("TALARM_INT, Indicates that a temperature alarm has been set\r\n"); if(n6 == 1) printf("MPT_ERR, Indicates a memory protection error. Digital access is attempted for protected memory.\r\n"); if(n5 == 1) printf("WR_FIN, Indicates a digital write command has finished writing to the Flash memory.\r\n"); if(n4 == 1) printf("CMD_ERR, An invalid command was sent to the device. The invalid command will be\r\n \ignored because the command buffer was full, a Voice Macro has been\r\n \active, or the device was not ready to respond to an erase command\r\n"); if(n3 == 1) printf("OVF_ERR, This error is generated if the host illegally tries to read or write data while the\r\n \RDY/BSYB pin is low. It is also generated if a digital read or write attempts to\r\n \read or write past the end of memory.\r\n"); if(n2 == 1 ) printf("CH2_FIN, This bit indicates an interrupt was generated because a command finished \r\n \executing on Channel X. A CHx_FIN interrupt will be generated each time a\r\n \Voice Macro or Voice Prompt play finishes.\r\n"); if( n1 == 1) printf("CH1_FIN, This bit indicates an interrupt was generated because a command finished \r\n \executing on Channel X. A CHx_FIN interrupt will be generated each time a\r\n \Voice Macro or Voice Prompt play finishes.\r\n"); if(n0 == 1) printf("CH0_FIN, This bit indicates an interrupt was generated because a command finished \r\n \executing on Channel X. A CHx_FIN interrupt will be generated each time a\r\n \Voice Macro or Voice Prompt play finishes.\r\n");
4.5 ISD2360设置音量
最大0dbm
可以在POI VM中设置,上电初始化读取,判断芯片是否初始化正确
//set volc byData = Read_CFG_REG(VOLC); printf("reg VOLC[0x%02x] = 0x%02x\r\n", VOLC,byData); Write_CFG_REG(VOLC,0); byData = Read_CFG_REG(VOLC); printf("reg VOLC[0x%02x] = 0x%02x\r\n", VOLC,byData);
4.6 ISD2360设置数据路径以及播放audio channel
可以在POI VM中设置,上电初始化读取,判断芯片是否初始化正确
mem–dec com-pwm out
//ba 01 00 -->60 60 60 byData = Read_CFG_REG(REG1); printf("Decompression Control Register[0x%02x] = 0x%02x\r\n", REG1,byData); byData = Read_CFG_REG(REG2); printf("Path Control Register[0x%02x] = 0x%02x\r\n", REG2,byData);
4.7 ISD2360 CLK设置
可以在POI VM中设置,上电初始化读取,判断芯片是否初始化正确
//chip clk cfg byData = Read_CLK_CFG_REG(); printf(" Clock Register = 0x%02x\r\n", byData);
4.8 ISD2360 PIN IO设置
根据硬件连接,ISD2360的SPI PIN设置,可以在POI VM中设置,上电初始化读取,判断芯片是否初始化正确
//chip clk cfg byData = Read_CLK_CFG_REG(); printf(" Clock Register = 0x%02x\r\n", byData); //获取GPIO配置寄存器 reg_AF1 = Read_CFG_REG(REG_GPIO_AF1); reg_AF0 = Read_CFG_REG(REG_GPIO_AF0);//reg_AF1 0x37 0011 0111//reg_AF0 0x00 printf("reg_AF1 0x%02x\r\n", reg_AF1); printf("reg_AF0 0x%02x\r\n", reg_AF0);
4.9 ISD2360 播放音频 以及查询读取芯片状态以及中断状态 来判断播放是否完成
可以采用 Exe_VM 播放一段或者多段音频资源组合,VM定义需预先定义好
byData = read_RDY_Busy_status(); printf("read_RDY_Busy_status=%d\r\n",byData);#if 1 printf("\r\n Exe_VM...\r\n"); Exe_VM(0x3); while (1) { ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[0] == 0x40 )break;else if(Device_status[0] == 0x60 && Device_status[1] == 0x01)//play end{ReadInt();//clear int statuscontinue;} Delay_10ms(); }
不查询则发送其他命令会出现CMD_ERR中断错误
4.10 ISD2360 mem读取
4.10.1 命令执行前提以及命令执行完成判断
//The command is accepted if status bits PD=0, DBUF_RDY=1, CHx_BSY=0, DIG_BSY=0 and CMD_BSY=0.
判断代码如下:
while (1) { ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[0] == 0x40 )break;else if(Device_status[0] == 0x60 ){ReadInt();//clear int status} Delay_10ms(); }
4.10.2 单字节以及多字节读取
//dig readbyData = Dig_Read(0x00);printf("Dig_Read byData 0x%02x\r\n", byData); printf("sizeof(buffer 0x%02x\r\n", sizeof(buffer));Dig_Read_nums(0x00,sizeof(buffer),buffer);for(i =0 ;i< sizeof(buffer) ;i++){printf("0x%02x ",*(char *)(buffer+i) &0xff);if((i+1) % 16 ==0 )printf("\r\n");}
4.10.3 单字节以及多字节读函数实现
/*函数名称:unsigned char Dig_Read(unsigned long int Addr_Byte)入口参数:unsigned long int Addr_Byte返回参数:RX_dat使用说明:Addr_Byte为ISD的地址,共三个字节;如果需要连续字节读取内存中的数据,需要读取RDY引脚的状态作用:从内存指定地址中读取一个字节*/unsigned char Dig_Read(unsigned long int Addr_Byte){unsigned char RX_dat=0;Spi_Enable();SendByte(Dig_Read_Code);SendByte((unsigned char)(Addr_Byte>>16));SendByte((unsigned char)(Addr_Byte>>8));SendByte((unsigned char)Addr_Byte); RX_dat=ReadByte(0x00);Spi_Disable();return (RX_dat);}unsigned char Dig_Read_nums(unsigned long int Addr_Byte,unsigned long int num,unsigned char* buffer){unsigned char RX_dat=0;int i=0;Spi_Enable();SendByte(Dig_Read_Code);SendByte((unsigned char)(Addr_Byte>>16));SendByte((unsigned char)(Addr_Byte>>8));SendByte((unsigned char)Addr_Byte);for(i=0;i<num;i++) *(buffer+i)=ReadByte(0x00);printf("Dig_Read_nums end i=%d\r\n",i);Spi_Disable();return 0;}
4.11 ISD2360 chip ERASE
设计使用中存在通过MCU 在线升级音频资源的问题,需要对MEM进行升级,升级前需要进行erase
//The command is accepted if status bits PD=0, DBUF_RDY=1, CHx_BSY=0, DIG_BSY=0 and CMD_BSY=0. ChipErase();//check status while (1) { ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[0] == 0x40 )break;else if(Device_status[0] == 0x60 ){ReadInt();//clear int status} Delay_10ms(); }printf("ChipErase read check\n");
4.12 ISD2360 mem写入
4.12.1 命令执行前提以及命令执行完成判断
//The command is accepted if status bits PD=0, DBUF_RDY=1, CHx_BSY=0, DIG_BSY=0 and CMD_BSY=0.
判断代码如下:
printf("Dig_Write_nums ...\r\n", ISD2360_Example_Project_1_mem_len);printf("read_RDY_Busy_status()=%d...\r\n", read_RDY_Busy_status());Dig_Write_nums(0x00,ISD2360_Example_Project_1_mem_len,(unsigned char*)ISD2360_Example_Project_1_mem);//check statusloop_times=0; while (1) {printf("loop_times=%d\r\n", loop_times); ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[0] == 0x40 )break;else if(Device_status[0] == 0x60 ){ReadInt();//clear int status} Delay_10ms();loop_times++; }
4.12.2 单字节以及多字节写入
4.12.3 单字节以及多字节写函数实现
/*函数名称:void Dig_Write(unsigned long int Addr_Byte,unsigned char TX_dat)入口参数:unsigned long int Addr_Byte,unsigned char TX_dat返回参数:无使用说明:Addr_Byte为ISD的地址,共三个字节;TX_dat=0~255;如果需要连续字节读取内存中的数据,需要读取RDY引脚的状态作用:向内存指定地址中写入一个字节*/void Dig_Write(unsigned long int Addr_Byte,unsigned char TX_dat){Spi_Enable();SendByte(Dig_Write_Code);SendByte((unsigned char)(Addr_Byte>>16));SendByte((unsigned char)(Addr_Byte>>8));SendByte((unsigned char)Addr_Byte); SendByte(TX_dat);Spi_Disable();}void Dig_Write_nums(unsigned long int Addr_Byte,unsigned long int num,unsigned char* buffer){int i=0;Spi_Enable();SendByte(Dig_Write_Code);SendByte((unsigned char)(Addr_Byte>>16));SendByte((unsigned char)(Addr_Byte>>8));SendByte((unsigned char)Addr_Byte);for(i=0;i<num;i++){ SendByte(*(buffer+i));}printf("Dig_Write_nums end i=%d\r\n",i);Spi_Disable();}
4.13 ISD2360 checksum计算
4.13.1 ISD2360 checksum 硬件计算
//hw check sumprintf("FLASH_END_ADDR =0x%08x\r\n",FLASH_END_ADDR); byData = Read_CFG_REG(REG4); printf("REG4 byData 0x%02x\r\n", byData); byData |= (1<<4) ;Write_CFG_REG(REG4,byData);loop_times=0; //if(Device_status[0] == 0x60 && Device_status[0] == 0x20) while (1) {printf("loop_times=%d\r\n", loop_times); ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[0] == 0x40 )break;else if(Device_status[0] == 0x60 && Device_status[1] == 0x20){ReadInt();//clear int statuscontinue;} Delay_10ms();loop_times++; }byData &= ~(1<<4) ; Write_CFG_REG(REG4,byData);loop_times=0; //if(Device_status[0] == 0x60 && Device_status[0] == 0x20) while (1) {printf("loop_times=%d\r\n", loop_times); ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[0] == 0x40 )break;else if(Device_status[0] == 0x60 && Device_status[1] == 0x20){ReadInt();//clear int statuscontinue;} Delay_10ms();loop_times++; } byData = Read_CFG_REG(REG4); printf("after set REG4 byData 0x%02x\r\n", byData); byData = Read_CFG_REG(REG_CHK_SUM1_LB); printf("1 LB byData 0x%02x\r\n", byData); byData = Read_CFG_REG(REG_CHK_SUM1_HB); printf("1 HB byData 0x%02x\r\n", byData); byData = Read_CFG_REG(REG_CHK_SUM2_LB); printf("2 LB byData 0x%02x\r\n", byData); byData = Read_CFG_REG(REG_CHK_SUM2_HB); printf("2 hB byData 0x%02x\r\n", byData);CheckSum(FLASH_END_ADDR);//wait end ,WR_FIN: 1loop_times=0; //if(Device_status[0] == 0x60 && Device_status[0] == 0x20) while (1) {printf("loop_times=%d\r\n", loop_times); ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[0] == 0x40 )break;else if(Device_status[0] == 0x60 && Device_status[1] == 0x20){ReadInt();//clear int statuscontinue;} Delay_10ms();loop_times++; }hw_check_sum = 0; byData = Read_CFG_REG(REG_CHK_SUM1_LB);hw_check_sum = byData; byData = Read_CFG_REG(REG_CHK_SUM1_HB);hw_check_sum += (byData<<8); byData = Read_CFG_REG(REG_CHK_SUM2_LB);hw_check_sum += (byData<<16); byData = Read_CFG_REG(REG_CHK_SUM2_HB);hw_check_sum += (byData<<24);printf("hw_check_sums=0x%08x\r\n",hw_check_sum);
4.13.2 ISD2360 checksum 软件计算
4.13.2.1 ISD2360 checksum 软件MCU端计算
//sw_check_sumDig_Read_nums(0x00,sizeof(fw_buffer),fw_buffer);//wait end ,WR_FIN: 1loop_times=0; //if(Device_status[0] == 0x60 && Device_status[0] == 0x20) while (1) {printf("loop_times=%d\r\n", loop_times); ReadStatus(); printf("Device_status 0x%02x\r\n", Device_status[0]); printf("Device_status 0x%02x\r\n", Device_status[1]);if(Device_status[0] == 0x40 )break;else if(Device_status[0] == 0x60 && Device_status[1] == 0x20){ReadInt();//clear int status//break;} Delay_10ms();loop_times++; }pdata= (unsigned char *)(fw_buffer+sizeof(fw_buffer)-1) ; sw_check_sum = fletcher32_RevrseCalculate(pdata,sizeof(fw_buffer));printf("sizeof(fw_buffer) =0x%08x\r\n",sizeof(fw_buffer)); printf("fletcher32_RevrseCalculate sw_check_sum =0x%08x\r\n",sw_check_sum);
4.13.2.1 ISD2360 checksum 软件linux 编译服务器端计算
对上位机生成的mem文件 ISD2360_Example_Project_1.mem 进行计算
4.13.2.3 fletcher32_RevrseCalculate实现
unsigned int fletcher32_RevrseCalculate(unsigned char *data, size_t len){ int temp; unsigned int sum1 = 0xffff, sum2 = 0xffff; while (len){ unsigned tlen = len> 360 ? 360 : len; len -= tlen; do { sum1 += *data; data--; sum2 += sum1; } while (--tlen); sum1 = (sum1 & 0xffff) + (sum1 >> 16); sum2 = (sum2 & 0xffff) + (sum2 >> 16); }// Second reduction step to reduce sums to 16 bits sum1 = (sum1 & 0xffff) + (sum1 >> 16); sum2 = (sum2 & 0xffff) + (sum2 >> 16); return sum2 << 16 | sum1;}
4.14 ISD2360 memlayout
5.ISD2360 mem工程
符合洗地机需求的工程DEMO
C:\Program Files (x86)\ISD-VPE2360\isd_pro\pro1\ISD2360_Example_Project_1
Calculate实现
unsigned int fletcher32_RevrseCalculate(unsigned char *data, size_t len){ int temp; unsigned int sum1 = 0xffff, sum2 = 0xffff; while (len){ unsigned tlen = len> 360 ? 360 : len; len -= tlen; do { sum1 += *data; data--; sum2 += sum1; } while (--tlen); sum1 = (sum1 & 0xffff) + (sum1 >> 16); sum2 = (sum2 & 0xffff) + (sum2 >> 16); }// Second reduction step to reduce sums to 16 bits sum1 = (sum1 & 0xffff) + (sum1 >> 16); sum2 = (sum2 & 0xffff) + (sum2 >> 16); return sum2 << 16 | sum1;}
4.14 ISD2360 memlayout
5.ISD2360 mem工程
符合洗地机需求的工程DEMO
C:\Program Files (x86)\ISD-VPE2360\isd_pro\pro1\ISD2360_Example_Project_1