From bee1570a7ff00aeb1bf8d297a4ba3ed4f33bdc6c Mon Sep 17 00:00:00 2001 From: Russ Butler Date: Mon, 30 May 2016 22:58:02 -0500 Subject: [PATCH] KSDK2 - Fix repeated starts On repeated starts the flag to indicate this is not being set properly. Because of this the transfer fails. This patch keeps track of the last transfer to determine if a repeated start should be sent and sets the KSDK flags appropriately. --- .../TARGET_KSDK2_MCUS/api/i2c_api.c | 18 ++++++++++++++++-- .../TARGET_KSDK2_MCUS/api/objects.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/api/i2c_api.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/api/i2c_api.c index 0a48a1b11a..059c6fec52 100644 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/api/i2c_api.c +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/api/i2c_api.c @@ -35,6 +35,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA); uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL); obj->instance = pinmap_merge(i2c_sda, i2c_scl); + obj->next_repeated_start = 0; MBED_ASSERT((int)obj->instance != NC); i2c_master_config_t master_config; @@ -77,6 +78,7 @@ int i2c_start(i2c_t *obj) { int i2c_stop(i2c_t *obj) { if (I2C_MasterStop(i2c_addrs[obj->instance]) != kStatus_Success) { + obj->next_repeated_start = 0; return 1; } @@ -100,6 +102,13 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { master_xfer.direction = kI2C_Read; master_xfer.data = (uint8_t *)data; master_xfer.dataSize = length; + if (obj->next_repeated_start) { + master_xfer.flags |= kI2C_TransferRepeatedStartFlag; + } + if (!stop) { + master_xfer.flags |= kI2C_TransferNoStopFlag; + } + obj->next_repeated_start = master_xfer.flags & kI2C_TransferNoStopFlag ? 1 : 0; /* The below function will issue a STOP signal at the end of the transfer. * This is required by the hardware in order to receive the last byte @@ -120,8 +129,13 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { master_xfer.direction = kI2C_Write; master_xfer.data = (uint8_t *)data; master_xfer.dataSize = length; - if (!stop) - master_xfer.flags = kI2C_TransferNoStopFlag; + if (obj->next_repeated_start) { + master_xfer.flags |= kI2C_TransferRepeatedStartFlag; + } + if (!stop) { + master_xfer.flags |= kI2C_TransferNoStopFlag; + } + obj->next_repeated_start = master_xfer.flags & kI2C_TransferNoStopFlag ? 1 : 0; if (I2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) { return I2C_ERROR_NO_SLAVE; diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/api/objects.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/api/objects.h index 68203df302..135b3b74d5 100644 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/api/objects.h +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/api/objects.h @@ -50,6 +50,7 @@ struct analogin_s { struct i2c_s { uint32_t instance; + uint8_t next_repeated_start; }; struct spi_s {