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
3 changed files with 89 additions and 47 deletions
|
@ -263,8 +263,7 @@ uint8_t pat9125_rd_reg(uint8_t addr)
|
|||
if (!swi2c_readByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error
|
||||
goto error;
|
||||
#elif defined(PAT9125_I2C)
|
||||
if (twi_rw8(PAT9125_I2C_ADDR,TW_WRITE,&addr) ||
|
||||
twi_rw8(PAT9125_I2C_ADDR,TW_READ,&data))
|
||||
if (twi_r8(PAT9125_I2C_ADDR,addr,&data))
|
||||
goto error;
|
||||
#endif
|
||||
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
|
||||
goto error;
|
||||
#elif defined(PAT9125_I2C)
|
||||
if (twi_rw8(PAT9125_I2C_ADDR,TW_WRITE,&addr) ||
|
||||
twi_rw8(PAT9125_I2C_ADDR,TW_READ,&data))
|
||||
if (twi_w8(PAT9125_I2C_ADDR,addr,data))
|
||||
goto error;
|
||||
#endif
|
||||
return;
|
||||
|
|
110
Firmware/twi.c
110
Firmware/twi.c
|
@ -48,55 +48,89 @@ void twi_disable(void)
|
|||
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
|
||||
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA);
|
||||
twi_wait();
|
||||
if(TW_STATUS != TW_START)
|
||||
if(twi_wait(TW_START))
|
||||
return 1;
|
||||
|
||||
// send address
|
||||
TWDR = mode;
|
||||
TWDR |= (address << 1);
|
||||
TWDR = TW_WRITE | (address << 1);
|
||||
TWCR = _BV(TWEN) | _BV(TWINT);
|
||||
twi_wait();
|
||||
if(twi_wait(TW_MT_SLA_ACK))
|
||||
return 2;
|
||||
|
||||
if(mode == TW_WRITE)
|
||||
{
|
||||
if(TW_STATUS != TW_MT_SLA_ACK)
|
||||
return 2;
|
||||
|
||||
// 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);
|
||||
// send register
|
||||
TWDR = reg;
|
||||
TWCR = _BV(TWEN) | _BV(TWINT);
|
||||
if(twi_wait(TW_MT_DATA_ACK))
|
||||
return 3;
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
* Function twi_rw8
|
||||
* Desc read/write a single byte from a device
|
||||
* Function twi_r8
|
||||
* Desc read a single byte from a device
|
||||
* Input address: 7bit i2c device address
|
||||
* mode: TW_READ or TW_WRITE
|
||||
* data: pointer to byte
|
||||
* reg: register address
|
||||
* data: pointer to byte for result
|
||||
* 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 a new issue