Be more compliant in the I2C protocol
- Enter a repeated-start for reading data - Write in the same session
This commit is contained in:
parent
384f40956c
commit
c2e8d229a7
|
|
@ -263,8 +263,7 @@ uint8_t pat9125_rd_reg(uint8_t addr)
|
||||||
if (!swi2c_readByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error
|
if (!swi2c_readByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error
|
||||||
goto error;
|
goto error;
|
||||||
#elif defined(PAT9125_I2C)
|
#elif defined(PAT9125_I2C)
|
||||||
if (twi_rw8(PAT9125_I2C_ADDR,TW_WRITE,&addr) ||
|
if (twi_r8(PAT9125_I2C_ADDR,addr,&data))
|
||||||
twi_rw8(PAT9125_I2C_ADDR,TW_READ,&data))
|
|
||||||
goto error;
|
goto error;
|
||||||
#endif
|
#endif
|
||||||
return data;
|
return data;
|
||||||
|
|
@ -286,8 +285,7 @@ void pat9125_wr_reg(uint8_t addr, uint8_t data)
|
||||||
if (!swi2c_writeByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error
|
if (!swi2c_writeByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error
|
||||||
goto error;
|
goto error;
|
||||||
#elif defined(PAT9125_I2C)
|
#elif defined(PAT9125_I2C)
|
||||||
if (twi_rw8(PAT9125_I2C_ADDR,TW_WRITE,&addr) ||
|
if (twi_w8(PAT9125_I2C_ADDR,addr,data))
|
||||||
twi_rw8(PAT9125_I2C_ADDR,TW_READ,&data))
|
|
||||||
goto error;
|
goto error;
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
110
Firmware/twi.c
110
Firmware/twi.c
|
|
@ -48,55 +48,89 @@ void twi_disable(void)
|
||||||
digitalWrite(SCL, 0);
|
digitalWrite(SCL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void twi_wait()
|
|
||||||
|
static void twi_stop()
|
||||||
{
|
{
|
||||||
while(!(TWCR & _BV(TWINT)));
|
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data)
|
|
||||||
|
static uint8_t twi_wait(uint8_t status)
|
||||||
|
{
|
||||||
|
while(!(TWCR & _BV(TWINT)));
|
||||||
|
if(TW_STATUS != status)
|
||||||
|
{
|
||||||
|
twi_stop();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t twi_start(uint8_t address, uint8_t reg)
|
||||||
{
|
{
|
||||||
// send start condition
|
// send start condition
|
||||||
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA);
|
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA);
|
||||||
twi_wait();
|
if(twi_wait(TW_START))
|
||||||
if(TW_STATUS != TW_START)
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// send address
|
// send address
|
||||||
TWDR = mode;
|
TWDR = TW_WRITE | (address << 1);
|
||||||
TWDR |= (address << 1);
|
|
||||||
TWCR = _BV(TWEN) | _BV(TWINT);
|
TWCR = _BV(TWEN) | _BV(TWINT);
|
||||||
twi_wait();
|
if(twi_wait(TW_MT_SLA_ACK))
|
||||||
|
return 2;
|
||||||
|
|
||||||
if(mode == TW_WRITE)
|
// send register
|
||||||
{
|
TWDR = reg;
|
||||||
if(TW_STATUS != TW_MT_SLA_ACK)
|
TWCR = _BV(TWEN) | _BV(TWINT);
|
||||||
return 2;
|
if(twi_wait(TW_MT_DATA_ACK))
|
||||||
|
return 3;
|
||||||
// send data
|
|
||||||
TWDR = *data;
|
|
||||||
TWCR = _BV(TWEN) | _BV(TWINT);
|
|
||||||
twi_wait();
|
|
||||||
if(TW_STATUS != TW_MT_DATA_ACK)
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(TW_STATUS != TW_MR_SLA_ACK)
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
// receive data
|
|
||||||
TWCR = _BV(TWEN) | _BV(TWINT);
|
|
||||||
twi_wait();
|
|
||||||
|
|
||||||
// accept ACK or NACK (since only 1 byte is read)
|
|
||||||
if(!(TW_STATUS & TW_MR_DATA_ACK))
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
*data = TWDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send stop
|
|
||||||
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t twi_r8(uint8_t address, uint8_t reg, uint8_t* data)
|
||||||
|
{
|
||||||
|
if(twi_start(address, reg))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// repeat start
|
||||||
|
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA);
|
||||||
|
if(twi_wait(TW_REP_START))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
// start receiving
|
||||||
|
TWDR = TW_READ | (address << 1);
|
||||||
|
TWCR = _BV(TWEN) | _BV(TWINT);
|
||||||
|
if(twi_wait(TW_MR_SLA_ACK))
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
// receive data
|
||||||
|
TWCR = _BV(TWEN) | _BV(TWINT);
|
||||||
|
if(twi_wait(TW_MR_DATA_NACK))
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
*data = TWDR;
|
||||||
|
|
||||||
|
// send stop
|
||||||
|
twi_stop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t twi_w8(uint8_t address, uint8_t reg, uint8_t data)
|
||||||
|
{
|
||||||
|
if(twi_start(address, reg))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// send data
|
||||||
|
TWDR = data;
|
||||||
|
TWCR = _BV(TWEN) | _BV(TWINT);
|
||||||
|
if(twi_wait(TW_MT_DATA_ACK))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
// send stop
|
||||||
|
twi_stop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,21 @@ void twi_init(void);
|
||||||
void twi_disable(void);
|
void twi_disable(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function twi_rw8
|
* Function twi_r8
|
||||||
* Desc read/write a single byte from a device
|
* Desc read a single byte from a device
|
||||||
* Input address: 7bit i2c device address
|
* Input address: 7bit i2c device address
|
||||||
* mode: TW_READ or TW_WRITE
|
* reg: register address
|
||||||
* data: pointer to byte
|
* data: pointer to byte for result
|
||||||
* Output 0 on success
|
* Output 0 on success
|
||||||
*/
|
*/
|
||||||
uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data);
|
uint8_t twi_r8(uint8_t address, uint8_t reg, uint8_t* data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function twi_w8
|
||||||
|
* Desc write a single byte from a device
|
||||||
|
* Input address: 7bit i2c device address
|
||||||
|
* reg: register address
|
||||||
|
* data: byte to write
|
||||||
|
* Output 0 on success
|
||||||
|
*/
|
||||||
|
uint8_t twi_w8(uint8_t address, uint8_t reg, uint8_t data);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue