> 文档中心 > 清洁机器人之音频方案 ISD2360 开发总结2 基于GD32F103的音频控制播放与升级

清洁机器人之音频方案 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.10.1 命令执行前提以及命令执行完成判断
        • 4.10.2 单字节以及多字节读取
        • 4.10.3 单字节以及多字节读函数实现
      • 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