产品己经完成一年,中间使用I2C介面来更新APROM,在此提供的范例是I2C bootloader。使用的一年中,还没有发生问题。如果大家有需求时,可以直接使用。这是一个I2C从机的boot loader。程序流程很简单。程序上电时,会判断重置旗标,如果是软重置,就进行程序更新流程,反之就跳到APROM。在跳到APROM之前,会对APROM check sum。保证APROM的程序是正确,才会跳到APROM。一旦check sum错误,就进行程序更新流程。 
程序更新流程提供以下6个I2C指令。从机地址设定为0x32,主机可以使用0x32, 0x04, DATA0 ~DATA31。依序烧写料到APROM里。程序大小设定为8KB。这8KB资料全部都要烧录进去。才不会在check sum时产生错误。烧写完後,使用0x32, 0x03, 0xA5跳到APROM。 
 
| 0x00 | R  | MicroP H/W ID  code  |  | 0x01 | R  | uP F/W version  provided by vendor  |  | 0x02 | R  | uP_Boot_Selection  |  | 0x03 | W  | Set uP boot from  APROM  |  | 0x04 | W  | Program and verify  APROM  |  | 0x05 | R  | Read programming  address  |  
  
 
如果要自行新增I2C指令,可以修改DrvI2C_HW.c, 按照以下红字,遂一增加你需求的CMD。 
 
以PV_APROM_Address为例, 
 
 
#define PV_APROM_Address                        0x05  
uint32_t u32APROMaddress = 0; 
PV_APROM_Address指令为4B,read only。 
HW_I2C_Data_t const HW_I2C_Cmd[]={ 
        {uP_HW_ID_code                                        ,HW_I2C_RO,4,(uint8_t*)&u32HW_ID_code},                                        /*--------- 0 ------------*/                        
        {uP_FW_ID_code                                        ,HW_I2C_RO,2,&u8FW_ID_code[0]},                                                        /*--------- 1 ------------*/ 
        {uP_Boot_Selection                                ,HW_I2C_RO,1,&u8uP_Boot_Selection}, 
        {Set_uP_boot_from_APROM                        ,HW_I2C_WO,1,&u8Set_uP_boot_from_APROM}, 
        {PV_APROM                                                ,HW_I2C_WO,32,(uint8_t*)u32PV_APROM},         
        {UNDEF_CMD                                                ,HW_I2C_RW,HW_I2C_MAX_DATA_LENGHT,&HW_I2C_temp_val[0]},        /*--------- 5 ------------*/ 
    {PV_APROM_Address                                ,HW_I2C_RO,4,(uint8_t*)&u32APROMaddress},         
}; 
 
这是一个look out table,对应i2c cmd,指向那一个指令,以对应到HW_I2C_Cmd的命令。 
const uint8_t HW_I2C_Cmd_LookUp_Tab1[]={ 
        0,1,2,3,4,6,5,5                ,5,5,5,5,5,5,5,5,                           /*0x00~0x0F*/ 
}; 
 
 
void Do_HW_I2C(HW_I2C_Data_t* HW_I2C_Data_Temp) 
{ 
        switch(HW_I2C_Data_Temp->Cmd) 
        { 
                case Set_uP_boot_from_APROM: 
                        if(u8Set_uP_boot_from_APROM == 0xA5) 
                        { 
                                EnterAPROM(); 
                                u32APROMaddress = 0; 
                                #ifdef DEBUG_ENABLE_LED 
                                O_R_LED = 1; 
                                #endif 
                        } 
                        break; 
                case PV_APROM: 
                        Set_PV_flag(); 
                        break; 
                case PV_APROM_Address: 
                        break; 
        }         
} 
void Read_HW_I2C(HW_I2C_Data_t* HW_I2C_Data_Temp) 
{ 
        switch(HW_I2C_Data_Temp->Cmd) 
        { 
                case PV_APROM_Address: 
                        break;     
 
        }         
} 
 
 
在这个程序里,只能支持16指令。如果需更多指令,需要修改以下数字。如果大家有空也可以修改以下程序,不要使用look out table。用polling的方式,一个一个判断,寻找HW_I2C_Cmd[]对应的指令。如果没对找到对应的指令,就使用HW_I2C_Cmd[5]。 
 
                                if(u32Temp<0x10) 
                                { 
                                        HW_I2C_Data = (HW_I2C_Data_t*) &HW_I2C_Cmd[HW_I2C_Cmd_LookUp_Tab1[u32Temp]]; 
                                }else 
                                { 
                                        HW_I2C_Data = (HW_I2C_Data_t*) &HW_I2C_Cmd[5]; 
                                } 
 
 
 |