bool eeprom_read(uint32_t address, void* data, uint16_t length) { uint8_t control[3]; control[0] = (uint8_t)(0xa0 | 0 | 0); // clear read/write bit control[1] = (uint8_t)(address >> 8); control[2] = (uint8_t)address; if (address > 0xffff){ control[0] |= 0x08; } iic_start(EEPROM_IIC_CHANNEL); if (iic_write(EEPROM_IIC_CHANNEL, control, 3) == false){ iic_stop(EEPROM_IIC_CHANNEL); return false; } iic_repeated_start(EEPROM_IIC_CHANNEL); control[0] |= 1; // set read/write bit if (iic_write(EEPROM_IIC_CHANNEL, control, 1) == false){ iic_stop(EEPROM_IIC_CHANNEL); return false; } iic_read(EEPROM_IIC_CHANNEL, data, length); iic_stop(EEPROM_IIC_CHANNEL); return true; }
void iic_control (unsigned char addr, unsigned char loc, unsigned char *buf, int len) { iic_start(); if (iic_sendbyte(addr & 0xfe)) goto error; if (iic_sendbyte(loc)) goto error; if (addr & 1) { int i; for (i = 0; i < len; i++) if (iic_sendbyte (buf[i])) break; } else { int i; iic_stop(); iic_start(); iic_sendbyte(addr|1); for (i = 0; i < len; i++) buf[i] = iic_recvbyte (); } error: iic_stop(); }
static U8 single_write_hmc5883l(U8 reg,U8 dat) { if(OK!=sel_hmc5883l_reg(reg))return ERROR; if(OK!=i2c_senddat(dat)) { iic_stop(); return ERROR; }; return iic_stop(); }
U8 read_mpu6050(U8 reg) { U8 DATA; if(OK!=sel_mpu6050_reg(reg))return ERROR; if(OK!=iic_rstart())return ERROR; if(OK!=i2c_senddat(R_MPU6050_ADDRESS)) { iic_stop(); return ERROR; }; DATA=i2c_recedat(); iic_stop(); return DATA; }
U8 sel_mpu6050_reg(U8 reg) { if(OK!=iic_start())return ERROR; if(OK!=i2c_senddat(W_MPU6050_ADDRESS)) { iic_stop(); return ERROR; }; if(OK!=i2c_senddat(reg)) { iic_stop(); return ERROR; }; return OK; }
U8 write_mpu6050(U8 reg,U8 *datbuf,U16 datl) { if(OK!=sel_mpu6050_reg(reg)) return ERROR; for(;datl!=0;datl--) { if(OK!=i2c_senddat(*datbuf)) { iic_stop(); return ERROR; }; datbuf++; } return iic_stop(); }
static U8 sel_hmc5883l_reg(U8 reg) { if(OK!=iic_start())return ERROR; if(OK!=i2c_senddat(HMC58X3_ADDR)) { iic_stop(); return ERROR; }; if(OK!=i2c_senddat(reg)) { iic_stop(); return ERROR; }; return OK; }
/**************************实现函数******************************************** *函数原型:uint8_t iic_read_bytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data) *功 能:读取指定设备 指定寄存器的 length个值 *输 入:dev 目标设备地址 * reg 寄存器地址 * length 要读的字节数 * *data 读出的数据将要存放的指针 *返 回:读出来的字节数量 *******************************************************************************/ uint8_t iic_read_bytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data) { uint8_t count = 0; iic_start(); iic_send_8bits(dev); //发送写命令 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; iic_send_8bits(reg); //发送地址 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; iic_start(); iic_send_8bits(dev+1); //进入接收模式 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; for(count=0;count<length;count++) { if(count != length-1) data[count] = iic_read_8bits(SEND_ACK); //带ACK的读数据 else data[count] = iic_read_8bits(SEND_NACK); //最后一个字节NACK } iic_stop(); //产生一个停止条件 return IIC_SUCCESS; }
uint8_t htu21d_soft_reset(void) { iic_start(DEV_ADDR | I2C_WR); iic_writebyte(CMD_SOFT_RESET); iic_stop(); return 1; }
static U8 read_hmc5883l(U8 reg,U8 *datbuf,U16 datl) { if(OK!=sel_hmc5883l_reg(reg))return ERROR; if(OK!=iic_rstart())return ERROR; if(OK!=i2c_senddat(HMC58X3_ADDR+1))//not really right { iic_stop(); return ERROR; }; for(;datl!=0;datl--) { *datbuf=i2c_recedat(datl); datbuf++; } return iic_stop(); }
uint8_t htu21d_trigger_measurement_no_hold_master(uint8_t type) { iic_start(DEV_ADDR | I2C_WR); if(type == SELECT_TEMP) iic_writebyte(CMD_TRIGGER_TEMP_NO_HOLD_MASTER); else iic_writebyte(CMD_TRIGGER_HUM_NO_HOLD_MASTER); iic_stop(); return 1; }
static u8_t iic_read_byte(u8_t slave, u8_t reg, u8_t * val) { iic_start(); if (!iic_send_byte(slave << 0x1)) return 0; if (!iic_send_byte(reg)) return 0; iic_stop(); iic_start(); if (!iic_send_byte((slave << 0x1) | 0x1)) return 0; *val = iic_recv_byte(); iic_send_ack(); iic_stop(); return 1; }
static bool eeprom_page_write(uint32_t address, void* data, uint8_t length) { uint8_t control[3]; uint16_t timeout = WRITE_TIMEOUT; control[0] = (uint8_t)(0xa0 | 0 | 0); control[1] = (uint8_t)(address >> 8); control[2] = (uint8_t)address; if (address > 0xffff){ control[0] |= 0x08; } iic_start(EEPROM_IIC_CHANNEL); if (iic_write(EEPROM_IIC_CHANNEL, control, 3) == false){ iic_stop(EEPROM_IIC_CHANNEL); return false; } if (iic_write(EEPROM_IIC_CHANNEL, data, length) == false){ iic_stop(EEPROM_IIC_CHANNEL); return false; } iic_stop(EEPROM_IIC_CHANNEL); while (timeout--){ iic_start(EEPROM_IIC_CHANNEL); if (iic_write(EEPROM_IIC_CHANNEL, control, 1)){ iic_stop(EEPROM_IIC_CHANNEL); return true; } iic_stop(EEPROM_IIC_CHANNEL); } return false; }
/**************************实现函数******************************************** *函数原型:void iic_write_byte(uint8_t dev, uint8_t reg, uint8_t data) *功 能:将一个字节写入指定设备 指定寄存器 *输 入:dev 目标设备地址 * reg 寄存器地址 * data 将要写的数据 *返 回:返回是否成功 *******************************************************************************/ uint8_t iic_write_byte(uint8_t dev, uint8_t reg, uint8_t data) { iic_start(); iic_send_8bits(dev); //发送写命令 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; iic_send_8bits(reg); //发送地址 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; iic_send_8bits(data); //发送数据 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; iic_stop(); //产生一个停止条件 return IIC_SUCCESS; }
/*----------------------------------------------------------------------------*/ void iic_write(u8 chip_id,u8 iic_addr,u8 *iic_dat,u8 n) { iic_busy = 1; iic_start(); //I2C启动 iic_sendbyte(chip_id); //写命令 if (0xff != iic_addr) { iic_sendbyte(iic_addr); //写地址 } for (;n>0;n--) { iic_sendbyte(*iic_dat++); //写数据 } iic_stop(); //I2C停止时序 iic_busy = 0; }
static u8_t iic_write_byte(u8_t slave, u8_t reg, u8_t val) { iic_start(); if(!iic_send_byte(slave << 0x1)) return 0; if(!iic_send_byte(reg)) return 0; if(!iic_send_byte(val)) return 0; iic_stop(); return 1; }
uint8_t htu21d_read_measurement_no_hold_master(uint8_t type, uint16_t *value) { uint16_t temp = 0; iic_start(DEV_ADDR | I2C_RD); temp = iic_readbyte(d_ACK); temp <<= 8; temp |= iic_readbyte(d_ACK); iic_readbyte(d_NACK); // crc, ignore this byte iic_stop(); *value = temp; return (uint8_t)1; }
/*----------------------------------------------------------------------------*/ void iic_readn(u8 chip_id,u8 iic_addr,u8 *iic_dat,u8 n) { iic_busy = 1; iic_start(); //I2C启动 iic_sendbyte(chip_id); //写命令 if (0xff != iic_addr) { iic_sendbyte(iic_addr); //写地址 } for (;n>1;n--) { *iic_dat++ = iic_revbyte(0); //写数据 } *iic_dat++ = iic_revbyte(1); iic_stop(); //I2C停止时序 iic_busy = 0; }
/* ** 函数功能:驱动READ函数 ** 输入参数:count=需读取数据长度 ** 输出参数:buff=用户空间数据缓冲区 ** 返回值: 0=成功 其他=失败 ** 备注: */ ssize_t scull_read(struct file * filp, char __user * buff, size_t count, loff_t * offp) { unsigned char tbuf[256]; int i = 0; unsigned char tmp = 0; for(i = 0; i < 256; i++){ tbuf[i] = 0; } iic_start(); tmp = slave_addr|0x1; iic_write_bytes(&tmp, 1); iic_read_bytes(tbuf, count); iic_stop(); if(copy_to_user(buff, tbuf, count)){ return -1; } return 0; }
/**************************实现函数******************************************** *函数原型:void iic_read_byte(uint8_t dev, uint8_t reg, uint8_t data) *功 能:读取指定设备 指定寄存器的 length个值 *输 入:dev 目标设备地址 * reg 寄存器地址 * data 存放读出的数据 *返 回:void *******************************************************************************/ uint8_t iic_read_byte(uint8_t dev, uint8_t reg, uint8_t *data) { iic_start(); iic_send_8bits(dev); //发送写命令 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; iic_send_8bits(reg); //发送地址 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; iic_start(); iic_send_8bits(dev+1); //进入接收模式 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; *data = iic_read_8bits(SEND_NACK); //最后一个字节NACK iic_stop(); //产生一个停止条件 return IIC_SUCCESS; }
/*----------------------------------------------------------------------------*/ u8 read_eerom(u16 iic_addr) { u8 byte,addr=0,page=0; iic_busy = 1; addr=EEPROM_Addr_Align(iic_addr); page =EEPROM_Addr_to_Page(iic_addr); iic_start(); //I2C启动 iic_sendbyte(0xa0|page); //写命令 iic_sendbyte(addr); //写地址 iic_start(); //写转为读命令,需要再次启动I2C iic_sendbyte(0xa1|page); //读命令 byte = iic_revbyte(1); iic_stop(); //I2C停止 iic_busy = 0; return byte; }
/* ** 函数功能:驱动WRITE函数 ** 输入参数:buff=用户空间数据缓冲区, count=需写入数据长度 ** 输出参数:无 ** 返回值: 0=成功 其他=失败 ** 备注: */ ssize_t scull_write(struct file * filp, const char __user * buff, size_t count, loff_t * offp) { unsigned char tbuf[256]; unsigned char tmp = 0; if(count > 255){ printk("write error. buff is too long!!!\n"); return -2; } if(copy_from_user(tbuf, buff, count)){ return -1; } iic_start(); tmp = slave_addr; iic_write_bytes(&tmp, 1); if(iic_write_bytes(tbuf, count)){ return -1; } iic_stop(); return 0; }
int main(void) { int test; unsigned char byte; // PCF_ADRESS = 0; // Adresse des PCF'S printf("*** i²c-LCD Test (c) Ingo Gerlach 10/2000 *** \n"); COM = 0; // Vorbelegung Ser - Port, 0 Automatisch suchen set_port_delay(15); // Portdelay 0-255 test = init_iic(COM); // Init ii2c printf("Suche i2c-Interface..."); if (test) { printf(" gefunden an Port 0x%03xh! \n",test); } else { printf("Interface nicht gefunden.\n"); exit (0); } /* set_strobe(1); // Für den Seriellen Port nur dummy io_disable(0); */ sda_high(); scl_high(); printf("read_sda %d \n",read_sda()); printf("read_scl %d \n",read_scl()); iic_start(); byte =getchar(); iic_stop(); sda_low(); scl_low(); printf("read_sda %d \n",read_sda()); printf("read_scl %d \n",read_scl()); lcd_backlight(0); byte = getchar(); printf("deinit %d\n",deinit_iic()); return 0; }
/**************************实现函数******************************************** *函数原型:uint8_t iic_write_bytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data) *功 能:将多个字节写入指定设备 指定寄存器 *输 入:dev 目标设备地址 * reg 寄存器地址 * length 要写的字节数 * *data 将要写的数据的首地址 *返 回:返回是否成功 *******************************************************************************/ uint8_t iic_write_bytes(uint8_t dev, uint8_t reg, uint8_t length, uint8_t *data) { uint8_t count = 0; uint8_t *p = data; iic_start(); iic_send_8bits(dev); //发送写命令 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; iic_send_8bits(reg); //发送地址 if(iic_wait_ack()) return IIC_ACK_TIMEOUT; for(count=0;count<length;count++) { iic_send_8bits( *p ); if(iic_wait_ack()) return IIC_ACK_TIMEOUT; p++; } iic_stop(); //产生一个停止条件 return IIC_SUCCESS; }
/**************************实现函数******************************************** *函数原型:uint8_t iic_wait_ack(void) *功 能:等待应答信号到来 *返 回 值:DEBUG_ACK_TIMEOUT,接收应答失败 * DEBUG_SUCCESS,接收应答成功 *******************************************************************************/ uint8_t iic_wait_ack(void) { uint8_t ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA_H(); delay_us(1); IIC_SCL_H(); delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>100) { iic_stop(); ack_timeout_cnt++; return IIC_ACK_TIMEOUT; } delay_us(1); } IIC_SCL_L(); //时钟输出0 ack_success_cnt++; return IIC_SUCCESS; }
uint8_t htu21d_write_user_register(uint8_t bit_index, uint8_t bit_value) { uint8_t reg_tmp; iic_start(DEV_ADDR | I2C_WR); iic_writebyte(CMD_READ_USER_REGISTER); iic_restart(DEV_ADDR | I2C_RD); reg_tmp = iic_readbyte(0); if(bit_value == 1) reg_tmp |= ((int8_t)1 << bit_index); else reg_tmp &= ~((int8_t)1 << bit_index); iic_start(DEV_ADDR | I2C_WR); iic_writebyte(CMD_WRITE_USER_REGISTER); iic_writebyte(reg_tmp); iic_stop(); return 1; /* ack = iic_writebyte(CMD_READ_USER_REGISTER); if(ack == 1) // no ack { iic_stop(); return 0; } iic_start(); ack = iic_writebyte(DEV_ADDR | I2C_RD); if(ack == 1) // no ack { iic_stop(); return 0; } reg_tmp = iic_readbyte(0); if(bit_value == 1) reg_tmp |= ((int8)1 << bit_index); else reg_tmp &= ~((int8)1 << bit_index); iic_start(); ack = iic_writebyte(DEV_ADDR | I2C_WR); if(ack == 1) // no ack { iic_stop(); return 0; } ack = iic_writebyte(CMD_WRITE_USER_REGISTER); if(ack == 1) // no ack { iic_stop(); return 0; } ack = iic_writebyte(reg_tmp); if(ack == 1) // no ack { iic_stop(); return 0; } iic_stop(); return 1;*/ }
/*----------------------------------------------------------------------------*/ void eeprom_page_write_stop(void) { iic_stop(); //I2C停止 iic_busy = 0; }