From 1bbc2d770aba38f12e5dd9df5ce8b82ea2d7dd5f Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Tue, 9 Jul 2019 15:32:35 -0500 Subject: [PATCH] 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 --- .../TARGET_LPC/i2c_api.c | 37 +++++++++---------- .../TARGET_LPC/objects.h | 1 + 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/i2c_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/i2c_api.c index acfa4488e1..38b4780e98 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/i2c_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/i2c_api.c @@ -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) { diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/objects.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/objects.h index 23a50cd072..2eb11fa8e2 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/objects.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/objects.h @@ -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 {