LPC MCUXpresso: Remove extra I2C transaction on byte write

An extra start signal was observed on the bus which was
discovered by the FPGA test shield.
This is because the hardware sends out a transaction as soon
as a write to the START bit. Hence the write to the START
bit is delayed by using a flag.

Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
pull/11003/head
Mahesh Mahadevan 2019-07-09 15:32:35 -05:00
parent 28eb39c724
commit aef60d7edf
2 changed files with 19 additions and 19 deletions

View File

@ -32,6 +32,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->instance = pinmap_merge(i2c_sda, i2c_scl);
obj->next_repeated_start = 0;
obj->issue_start = 0;
MBED_ASSERT((int)obj->instance != NC);
i2c_master_config_t master_config;
@ -92,23 +93,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
int i2c_start(i2c_t *obj)
{
I2C_Type *base = i2c_addrs[obj->instance];
uint32_t status;
do {
status = I2C_GetStatusFlags(base);
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
/* Clear controller state. */
I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK);
/* Start the transfer */
base->MSTDAT = 0;
base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK;
do {
status = I2C_GetStatusFlags(base);
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
obj->issue_start = 1;
return 0;
}
@ -131,6 +116,8 @@ int i2c_stop(i2c_t *obj)
status = I2C_GetStatusFlags(base);
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
obj->issue_start = 0;
return 0;
}
@ -236,12 +223,24 @@ int i2c_byte_write(i2c_t *obj, int data)
// write the data
base->MSTDAT = data;
base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;
do {
status = I2C_GetStatusFlags(base);
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
/* Clear controller state. */
I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK);
if (obj->issue_start) {
base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK;
/* Clear the flag */
obj->issue_start = 0;
} else {
base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;
}
do {
status = I2C_GetStatusFlags(base);
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
/* Check if arbitration lost */
if (status & I2C_STAT_MSTARBLOSS_MASK) {

View File

@ -52,6 +52,7 @@ struct analogin_s {
struct i2c_s {
uint32_t instance;
uint8_t next_repeated_start;
uint8_t issue_start;
};
struct spi_s {