// ============================================================================= // 功能:轮询方式向IIC从设备的写数据 // 参数:reg,寄存器基址 // devaddr,设备地址 // memaddr,设备内部地址 // maddrlen,设备内部地址长度 // buf,存储数据 // len,数据长度,字节 // 返回:len,读取成功;-1,读取失败 // ============================================================================= static s32 __IIC_WritePoll(volatile tagI2CReg *reg,u8 devaddr,u32 memaddr, u8 maddrlen, u8 *buf, u32 len) { u8 mem_addr_buf[4]; //将地址作大小端变换 fill_little_32bit(mem_addr_buf,0,memaddr); // Write Device Address if(0 == __iic_write_addr(reg,devaddr,I2C_WRITE_BIT)) return -1; // Write Memory Address if(maddrlen != __iic_write(reg,mem_addr_buf,maddrlen)) return -1; //Write Data if(len != __iic_write(reg,buf,len)) return -1; return len; }
// ============================================================================= // 功能: 启动读时序,启动读时序的过程为:器件地址(写)、存储地址(写)、器件地址(读) // 当器件地址(读)完成时,需打开中断,重新配置寄存器为接收模式,之后将会发生 // 接收数据中断,在中断中将接收到的数据调用IIC_PortWrite写入缓冲,接收到len字 // 节数的数据后,释放信号量iic_semp // 参数: specific_flag,个性标记,本模块内即IIC寄存器基址 // dev_addr,器件地址的前7比特,已将内部地址所占的bit位更新,该函数需将该地址左 // 移一位增加增加最后一位读/写比特; // mem_addr,存储器内部地址,即发送到总线上的地址,该地址未包含放在器件地址上的 // 比特位; // maddr_len,存储器内部地址的长度,字节单位,未包含在器件地址里面的比特位; // len,接收的数据总量,接收数据的倒数第一字节,即count-1,停止产生ACK信号,当接 // 收的字节数为count时,产生停止时序,并释放信号量iic_semp; // iic_semp,读完成时,驱动需释放的信号量(缓冲区信号量) // 返回: TRUE,启动读时序成功,FALSE失败 // ============================================================================= static bool_t __IIC_GenerateReadStart(ptu32_t specific_flag, u8 dev_addr, u32 mem_addr, u8 maddr_len, u32 length, struct tagSemaphoreLCB *iic_semp) { volatile tagI2CReg *reg; u8 mem_addr_buf[4]; u32 Recv_Times=0; u32 Recv_Index=0; u32 i=0; u32 Single_Length_Max=0; Single_Length_Max=0xFE-maddr_len; Recv_Times=(u32)(length/Single_Length_Max); Recv_Index=Recv_Times; if (length % Single_Length_Max!=0) { Recv_Times++; } for(i=0;i<Recv_Index;i++) { if(specific_flag == CN_IIC_REGISTER_BADDR0) { if(i!=Recv_Index-1) { IntParamset0.TransTotalLen = Single_Length_Max; IntParamset0.TransCount = 0; IntParamset0.pDrvPostSemp = iic_semp; //iic_bus_semp mem_addr=mem_addr+i*Single_Length_Max; } else { IntParamset0.TransTotalLen = length-(Recv_Index-1)*Single_Length_Max; IntParamset0.TransCount = 0; IntParamset0.pDrvPostSemp = iic_semp; //iic_bus_semp } } else { return false; } fill_little_32bit(mem_addr_buf,0,mem_addr); reg=(tagI2CReg *)specific_flag; _IIC_IntDisable(reg); SETBIT(reg->rTWIMITR, TWIEN); //generate START //step1:首先发送start信号 SETBIT(reg->rTWIMCTL,TWIMEN); //MASTER MODE //step2:发送器件地址,最低位置0. if(__TWI_WaitForTwiFree()>=0) { //reg->rTWIMADDR = TWI_ADDR_GET(dev_addr); //device addr reg->rTWIMADDR =dev_addr; reg->rTWIMCTL = 0xFF<<6; //clean MCTL reg //step3:判断是否收到ACK. if(__TWI_WaitForAck(0)==0) { //step4:若收到从机发的ACK,则开始发存储地址. if(__TWI_WriteAddr(reg, mem_addr_buf,maddr_len)==0); { //step5:若成功发送完存储地址,接着发送一个Repeat Start信号 SETBIT(reg->rTWIMCTL,TWIRSTART); //step6:发送器件地址,最低位置1. SETBIT(reg->rTWIMCTL,TWIMDIR); reg->rTWIMADDR = TWI_ADDR_GET(dev_addr); //step7:开中断 _IIC_IntEnable(reg); if(i!=Recv_Index-1) { Lock_SempPend(iic_semp,CN_TIMEOUT_FOREVER); } else { return true; } } } } } return false; }