#include "jw3425iic.h" #include "gpio_cfg.h" #include "base/delay.h" #include "interface/basechecker.h" #include "base/utility.h" void IIC_SDA_DIR(uint8_t dir) { GPIO_InitTypeDef GPIO_InitStructure; if(dir == 0) { GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; }else{ GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; } GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin= I2IC_SDA_Pin; GPIO_Init(GPIOB,&GPIO_InitStructure); } void I2C_init(void) { GPIO_InitTypeDef GPIO_InitStructure; /* enable GPIOB clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //GPIO 配置 GPIO_InitStructure.GPIO_Pin=I2IC_SCL_Pin | I2IC_SDA_Pin; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); IIC_SDA(1); IIC_SCL(1); } void I2C_Definit(void) { GPIO_InitTypeDef GPIO_InitStructure; /* enable GPIOB clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //GPIO 配置 GPIO_InitStructure.GPIO_Pin=I2IC_SCL_Pin | I2IC_SDA_Pin; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); } //产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); //sda线输出 IIC_SDA(1); IIC_SCL(1); delay_us(IIC_PLUS_DELAY); IIC_SDA(0);//START:when CLK is high,DATA change form high to low delay_us(IIC_PLUS_DELAY); IIC_SCL(0);//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT();//sda线输出 IIC_SCL(0); IIC_SDA(0);//STOP:when CLK is high DATA change form low to high delay_us(IIC_PLUS_DELAY); IIC_SCL(1); delay_us(IIC_PLUS_DELAY); IIC_SDA(1);//发送I2C总线结束信号 } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 uint8_t IIC_Wait_Ack(void) { uint32_t ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA(1); delay_us(1); IIC_SCL(1); delay_us(IIC_PLUS_DELAY>>1); while(READ_SDA) { ucErrTime++; if(ucErrTime>I2C_OPERATION_OUTTIME) { IIC_Stop(); return 1; } } IIC_SCL(0);//时钟输出0 return 0; } //产生ACK应答 void IIC_Ack(void) { IIC_SCL(0); SDA_OUT(); IIC_SDA(0); delay_us(IIC_PLUS_DELAY); IIC_SCL(1); delay_us(IIC_PLUS_DELAY); IIC_SCL(0); } //不产生ACK应答 void IIC_NAck(void) { IIC_SCL(0); SDA_OUT(); IIC_SDA(1); delay_us(IIC_PLUS_DELAY); IIC_SCL(1); delay_us(IIC_PLUS_DELAY); IIC_SCL(0); } //IIC发送一个字节 //返回从机有无应答 //0,有应答 //1,无应答 uint8_t IIC_Send_Byte(uint8_t txd) { uint8_t t; SDA_OUT(); for(t=0;t<8;t++) { IIC_SCL(0);//拉低时钟开始数据传输 delay_us(IIC_PLUS_DELAY>>1); IIC_SDA((txd&0x80)>>7); txd<<=1; delay_us(IIC_PLUS_DELAY>>1); IIC_SCL(1); delay_us(IIC_PLUS_DELAY); } IIC_SCL(0); delay_us(IIC_PLUS_DELAY >>1); return IIC_Wait_Ack(); } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK uint8_t IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; SDA_IN();//SDA设置为输入 for(i=0;i<8;i++ ) { IIC_SCL(0); delay_us(IIC_PLUS_DELAY); IIC_SCL(1); delay_us(IIC_PLUS_DELAY>>1); receive<<=1; if(READ_SDA)receive++; delay_us(IIC_PLUS_DELAY >> 1); } if (!ack) IIC_NAck();//发送nACK else IIC_Ack(); //发送ACK return receive; } /* @param bi_dir: option using in transceive */ int32_t I2C_master_write(uint16_t address, uint8_t *src, uint32_t size, uint32_t *nwriten, uint8_t bi_dir) { uint32_t timeout = 0; uint8_t ack = 0; *nwriten = 0; __disable_irq(); IIC_Start(); //发送地址 ack = IIC_Send_Byte(( address<<1)); if(ack) { goto iic_send_stop; } while (*nwriten < size) { ack = IIC_Send_Byte(src[*nwriten]); if(ack) { break; } (*nwriten)++; } iic_send_stop: if(bi_dir ==0)//bi_dir == 1时不发送停止信号 { IIC_Stop(); } __enable_irq(); return ack; } /* @param bi_dir: option using in transceive */ int32_t I2C_master_read(uint16_t address, uint8_t *dst, uint32_t size, uint32_t *nread, uint8_t bi_dir) { uint32_t i; *nread = 0; uint8_t ack = 0; if (size == 0) return 0; __disable_irq(); IIC_Start();//重新发送起始信号 ack = IIC_Send_Byte(( address << 1) | 0x01);//发送读命令地址 if(ack) goto send_stop_err; while(*nread < size) { if((*nread) == (size-1))//倒数1个字节,设置不应答 { dst[*nread] = IIC_Read_Byte(0); }else{ dst[*nread] = IIC_Read_Byte(1); } (*nread)++; } send_stop_err: // If receive NACK or no data to write, send STOP if (bi_dir == 0) IIC_Stop(); __enable_irq(); return ack; } /* @param bi_dir: option using in transceive */ int32_t I2C_master_write_read(uint16_t address, uint8_t*cmd, uint8_t cmd_size,uint8_t *dst, uint32_t read_size, uint32_t *nread) { uint32_t ul_writen; *nread = 0; if (read_size == 0) return 0; I2C_master_write(address,cmd,cmd_size,&ul_writen,1); if(ul_writen != cmd_size) { IIC_Stop(); return 1; } I2C_master_read(address, dst, read_size, nread, 1); IIC_Stop(); if(read_size != *nread) { return 1; } return 0; } int32_t I2C_master_writeCode(uint16_t address, uint8_t *cmd_src, uint32_t cmd_len,const uint8_t* puc_cod,uint32_t code_len ) { uint8_t uc_code; uint8_t ack = 0; __disable_irq(); IIC_Start(); //发送地址 ack = IIC_Send_Byte(( address<<1)); if(ack) { IIC_Stop(); __enable_irq(); return ack; } //发送命令 while (cmd_len > 0) { ack = IIC_Send_Byte(*cmd_src); if(ack) { IIC_Stop(); __enable_irq(); return ack; } cmd_src++; cmd_len--; } //发送代码数据 while (code_len > 0) { uc_code = *puc_cod; ack = IIC_Send_Byte(uc_code); if(ack) { IIC_Stop(); __enable_irq(); return ack; } puc_cod++; code_len--; } IIC_Stop(); __enable_irq(); return ack; } int32_t I2C_master_CodeEquel(uint16_t address, uint8_t *cmd_src, uint32_t cmd_len,const uint8_t* puc_cod,uint32_t code_len ) { uint8_t uc_code; uint8_t uc_rdata; uint8_t ack = 0; __disable_irq(); IIC_Start(); //发送地址 ack = IIC_Send_Byte(( address<<1)); if(ack) { IIC_Stop(); __enable_irq(); return ack; } //发送命令 while (cmd_len > 0) { ack = IIC_Send_Byte(*cmd_src); if(ack) { IIC_Stop(); __enable_irq(); return ack; } cmd_src++; cmd_len--; } IIC_Start();//重新发送起始信号 ack = IIC_Send_Byte(( address << 1) | 0x01);//发送读命令地址 if(ack) { IIC_Stop(); __enable_irq(); return ack; } while(code_len > 0) { uc_code = *puc_cod; puc_cod++; if(code_len == 1)//倒数1个字节,设置不应答 { uc_rdata = IIC_Read_Byte(0); }else{ uc_rdata = IIC_Read_Byte(1); } if(uc_code != uc_rdata) { ack = 1; break; } code_len--; } IIC_Stop(); __enable_irq(); return ack; } /******************IIC trim **********************/ #define SLAVE_IIC_ADDR_ 0x18 /* @brief Vref电压校准 @param0 0不更新,1更新 @param1 校准值 */ void MC_VrefTrim(void) { uint8_t auc_cmd[]={0x10,0xEF,0x00}; uint8_t auc_run_cmd[]={0x18,0xE7}; uint32_t ul_sendlen = 0; uint8_t uc_ack = 0; auc_cmd[2] = checker_runcfg.params[1] & 0x0F; uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_cmd,sizeof(auc_cmd),&ul_sendlen,0); if(uc_ack != 0 || checker_runcfg.params[0] == 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); return ; } uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_run_cmd,sizeof(auc_run_cmd),&ul_sendlen,0); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); } /* @brief Iref电压校准 @param0 Iref1 0不更新,1更新 @param1 Iref2 0不更新,1更新 @param2 Iref1 校准值 @param3 Iref2 校准值 */ void MC_IrefTrim(void) { uint8_t auc_cmd[]={0x12,0xED,0x00}; uint8_t auc_run1_cmd[]={0x19,0xE6}; uint8_t auc_run2_cmd[]={0x1A,0xE5}; uint32_t ul_sendlen = 0; uint8_t uc_ack = 0; auc_cmd[2] = (checker_runcfg.params[2] & 0x0F) | ((checker_runcfg.params[3] & 0x0F)<<4); uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_cmd,sizeof(auc_cmd),&ul_sendlen,0); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); return ; } if(checker_runcfg.params[0] != 0) { uc_ack |= I2C_master_write(SLAVE_IIC_ADDR_,auc_run1_cmd,sizeof(auc_run1_cmd),&ul_sendlen,0); } if(checker_runcfg.params[1] != 0) { uc_ack |= I2C_master_write(SLAVE_IIC_ADDR_,auc_run2_cmd,sizeof(auc_run2_cmd),&ul_sendlen,0); } Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); } /* @brief Iref1电压校准 @param0 0不更新,1更新 @param1 校准值 */ void MC_RC4MTrim(void) { uint8_t auc_cmd[]={0x14,0xEB,0x00}; uint8_t auc_run_cmd[]={0x1B,0xE4}; uint32_t ul_sendlen = 0; uint8_t uc_ack = 0; auc_cmd[2] = checker_runcfg.params[1] & 0x3F; uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_cmd,sizeof(auc_cmd),&ul_sendlen,0); if(uc_ack != 0 || checker_runcfg.params[0] == 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); return ; } uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_run_cmd,sizeof(auc_run_cmd),&ul_sendlen,0); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); } /* @brief RC128K校准 @param0 0不更新,1更新 @param1 校准值 */ void MC_RC128KTrim(void) { uint8_t auc_cmd[]={0x15,0xEA,0x00}; uint8_t auc_run_cmd[]={0x1C,0xE3}; uint32_t ul_sendlen = 0; uint8_t uc_ack = 0; auc_cmd[2] = checker_runcfg.params[1] & 0x1F; uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_cmd,sizeof(auc_cmd),&ul_sendlen,0); if(uc_ack != 0 || checker_runcfg.params[0] == 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); return ; } uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_run_cmd,sizeof(auc_run_cmd),&ul_sendlen,0); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); } /* @brief 设置MTP电压 @param0 低压 @param1 高压 */ void MC_SetMTPVol(void) { uint8_t auc_cmd[]={0x22,0xDD,0x00}; uint32_t ul_sendlen = 0; uint8_t uc_ack = 0; auc_cmd[2] = (checker_runcfg.params[0] & 0x03) | ((checker_runcfg.params[1] & 0x0F)<<2); uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_cmd,sizeof(auc_cmd),&ul_sendlen,0); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); } /* @brief 设置MTP电压 @param0 MTP地址 @param1 擦除模式 */ void MC_EraseMTP(void) { uint8_t auc_erase_cmd[]={0x00,0x00}; uint8_t auc_setAddr_cmd[]={0x23,0xDC,0x00,0x00}; uint32_t ul_sendlen = 0; uint8_t uc_ack = 0; auc_setAddr_cmd[2] = (checker_runcfg.params[0]>>8) & 0xFF; auc_setAddr_cmd[3] = checker_runcfg.params[0] & 0xFF; uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_setAddr_cmd,sizeof(auc_setAddr_cmd),&ul_sendlen,0); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); return; } ul_sendlen = 0; auc_erase_cmd[0] = checker_runcfg.params[1]; switch(checker_runcfg.params[1]) { case 0x25: auc_erase_cmd[1] = 0xDA; break;//全片擦除 case 0x26: auc_erase_cmd[1] = 0xD9; break;//块擦除 case 0x27: auc_erase_cmd[1] = 0xD8; break;//页擦除 case 0x28: auc_erase_cmd[1] = 0xD7; break;//字擦除 } uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_erase_cmd,sizeof(auc_erase_cmd),&ul_sendlen,0); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); } /* @brief MTP写入数据 @param0..N 编程数据 */ void MC_IICWriteMTP(void) { uint8_t auc_cmd[16]={0x29,0xD6}; uint32_t ul_sendlen = 0; uint8_t uc_ack = 0; uint16_t us_index = 0; for(us_index = 0; us_index < checker_runcfg.param_count;us_index++) { auc_cmd[us_index+2] = checker_runcfg.params[us_index]; } uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_cmd,us_index+2,&ul_sendlen,0); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); } /* @brief MTP读数据 @param0 读取MTP地址 @param1 读取数据字节长度 */ void MC_IICReadMTP(void) { uint8_t auc_setAddr_cmd[]={0x23,0xDC,0x00,0x00}; uint8_t auc_cmd[]={0x2A,0xD5}; uint32_t ul_readlen = 0; uint8_t uc_ack = 0; uint16_t us_buf[32]; uint32_t ul_sendlen = 0; auc_setAddr_cmd[2] = (checker_runcfg.params[0]>>8) & 0xFF; auc_setAddr_cmd[3] = checker_runcfg.params[0] & 0xFF; if(checker_runcfg.params[1] > 64) { checker_runcfg.params[1] = 64; } uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_setAddr_cmd,sizeof(auc_setAddr_cmd),&ul_sendlen,0); delay_ms(10); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); return ; } uc_ack = I2C_master_write_read(SLAVE_IIC_ADDR_,auc_cmd,sizeof(auc_cmd),(uint8_t*)us_buf,checker_runcfg.params[1],&ul_readlen); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); Checker_SetRtv(us_buf,checker_runcfg.rtv_count); } /* @brief MTP状态查询 */ void MC_IICCheckMTPState(void) { uint8_t auc_cmd[]={0x30,0xBF}; uint32_t ul_readlen = 0; uint8_t uc_ack = 0; uint16_t ul_rtv; uc_ack = I2C_master_write_read(SLAVE_IIC_ADDR_,auc_cmd,sizeof(auc_cmd),(uint8_t*)&ul_rtv,1,&ul_readlen); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); } /* @brief MTP使能或失能 @param0 0失/1使能 */ void MC_IICEnMTP(void) { uint8_t auc_cmd[]={0x20,0x20,0}; uint32_t ul_sendlen = 0; uint8_t uc_ack = 0; if(checker_runcfg.params[0] == 0) { auc_cmd[2] = 0x33; }else{ auc_cmd[2] = 0xCC; } uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_cmd,sizeof(auc_cmd),&ul_sendlen,0); Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); } /* @brief MTP下载程序 @param 更新地址 @param 烧录长度 */ void MC_IICUpdateMTP(void) { uint8_t uc_ack; uint8_t auc_enMTP_cmd[]={0x20,0x20,0xCC}; uint8_t auc_setAddr_cmd[]={0x23,0xDC,0x00,0x00}; uint8_t auc_setMTPOperReg_cmd[]={0x20,0xDF,0x00}; uint8_t auc_earse_cmd[]={0x25,0xDA}; uint8_t auc_setMTPVol[]={0x22,0xDD,0x18};//1.5V 5V uint8_t auc_program_cmd[]={0x29,0xD6}; uint8_t auc_readCode_cmd[]={0x2A,0xD5}; uint32_t ul_sendlen; uint16_t us_programLen = checker_runcfg.params[1]; uint8_t* puc_Master_addr = (uint8_t*)(MC_CODE_ADDR + checker_runcfg.params[0]); uint16_t ul_rtv = 0; uint32_t ul_crc32 = 0; ul_crc32 = Crc32Calu((uint32_t*)MC_CODE_ADDR,16*1024); if(ul_crc32 != boardinfo_un.boardinfo.mc_ICodeCrc32) { uc_ack = 1; Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 1; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } if(checker_runcfg.params[0] == 0x1000) { auc_setMTPOperReg_cmd[2] = 0x04; auc_earse_cmd[0]= 0x27; auc_earse_cmd[1]= 0xD8; }else{ auc_setMTPOperReg_cmd[2] = 0x00; } auc_setAddr_cmd[2] = (checker_runcfg.params[0]>>8) & 0xFF; auc_setAddr_cmd[3] = checker_runcfg.params[0] & 0xFF; uc_ack = 0; uc_ack += I2C_master_write(SLAVE_IIC_ADDR_,auc_enMTP_cmd,sizeof(auc_enMTP_cmd),&ul_sendlen,0); delay_ms(5); uc_ack += I2C_master_write(SLAVE_IIC_ADDR_,auc_enMTP_cmd,sizeof(auc_enMTP_cmd),&ul_sendlen,0); delay_ms(5); uc_ack += I2C_master_write(SLAVE_IIC_ADDR_,auc_enMTP_cmd,sizeof(auc_enMTP_cmd),&ul_sendlen,0); delay_ms(5); //设置MTP操作范围 if(uc_ack > 2) { uc_ack = 1; Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 2; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_setMTPOperReg_cmd,sizeof(auc_setMTPOperReg_cmd),&ul_sendlen,0); //设置MTP操作范围 if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 3; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } delay_ms(1); //设置MTP电压 uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_setMTPVol,sizeof(auc_setMTPVol),&ul_sendlen,0); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 4; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } delay_ms(1); //设置地址 uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_setAddr_cmd,sizeof(auc_setAddr_cmd),&ul_sendlen,0); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 5; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } delay_ms(1); //擦除 uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_earse_cmd,sizeof(auc_earse_cmd),&ul_sendlen,0); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 6; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } delay_os_ms(200); //设置地址 uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_setAddr_cmd,sizeof(auc_setAddr_cmd),&ul_sendlen,0); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 7; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } delay_ms(1); uc_ack = I2C_master_writeCode(SLAVE_IIC_ADDR_,auc_program_cmd,sizeof(auc_program_cmd),puc_Master_addr,us_programLen); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 8; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } delay_ms(20); //设置地址 uc_ack = I2C_master_write(SLAVE_IIC_ADDR_,auc_setAddr_cmd,sizeof(auc_setAddr_cmd),&ul_sendlen,0); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 9; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } delay_ms(5); uc_ack = I2C_master_CodeEquel(SLAVE_IIC_ADDR_,auc_readCode_cmd,sizeof(auc_readCode_cmd),puc_Master_addr,us_programLen); if(uc_ack != 0) { Checker_MaskResult(uc_ack,checker_runcfg.task_info.runindex); ul_rtv = 10; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; } Checker_MaskResult(0,checker_runcfg.task_info.runindex); ul_rtv = 0; Checker_SetRtv(&ul_rtv,checker_runcfg.rtv_count); return; }