Skip to content

Commit 842a86a

Browse files
authored
Merge pull request #6310 from codeauroraforum/Fix_K82F_I2C
MCUXpresso: Fix test failures seen with ci-test shield
2 parents 872634d + 5230bca commit 842a86a

File tree

2 files changed

+62
-32
lines changed

2 files changed

+62
-32
lines changed

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/peripheral_clock_defines.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
/* Array for I2C module clocks */
3737
#define I2C_CLOCK_FREQS \
3838
{ \
39-
I2C0_CLK_SRC, I2C1_CLK_SRC, I2C2_CLK_SRC \
39+
I2C0_CLK_SRC, I2C1_CLK_SRC, I2C2_CLK_SRC, I2C3_CLK_SRC \
4040
}
4141

4242
/* Array for DSPI module clocks */

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/i2c_api.c

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
3636
{
3737
uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA);
3838
uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL);
39+
PORT_Type *port_addrs[] = PORT_BASE_PTRS;
40+
PORT_Type *base = port_addrs[sda >> GPIO_PORT_SHIFT];
41+
3942
obj->instance = pinmap_merge(i2c_sda, i2c_scl);
4043
obj->next_repeated_start = 0;
4144
MBED_ASSERT((int)obj->instance != NC);
@@ -49,10 +52,11 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
4952
pinmap_pinout(sda, PinMap_I2C_SDA);
5053
pinmap_pinout(scl, PinMap_I2C_SCL);
5154

52-
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
53-
PORT_Type *port_addrs[] = PORT_BASE_PTRS;
54-
PORT_Type *base = port_addrs[sda >> GPIO_PORT_SHIFT];
55+
/* Enable internal pullup resistor */
56+
base->PCR[sda & 0xFF] |= (PORT_PCR_PE_MASK | PORT_PCR_PS_MASK);
57+
base->PCR[scl & 0xFF] |= (PORT_PCR_PE_MASK | PORT_PCR_PS_MASK);
5558

59+
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
5660
base->PCR[sda & 0xFF] |= PORT_PCR_ODE_MASK;
5761
base->PCR[scl & 0xFF] |= PORT_PCR_ODE_MASK;
5862
#endif
@@ -63,12 +67,14 @@ int i2c_start(i2c_t *obj)
6367
I2C_Type *base = i2c_addrs[obj->instance];
6468
uint32_t statusFlags = I2C_MasterGetStatusFlags(base);
6569

66-
/* Return an error if the bus is already in use. */
70+
/* Check if the bus is already in use. */
6771
if (statusFlags & kI2C_BusBusyFlag) {
68-
return 1;
72+
/* Send a repeat START signal. */
73+
base->C1 |= I2C_C1_RSTA_MASK;
74+
} else {
75+
/* Send the START signal. */
76+
base->C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK;
6977
}
70-
/* Send the START signal. */
71-
base->C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK;
7278

7379
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING
7480
while (!(base->S2 & I2C_S2_EMPTY_MASK))
@@ -81,7 +87,6 @@ int i2c_start(i2c_t *obj)
8187

8288
int i2c_stop(i2c_t *obj)
8389
{
84-
obj->next_repeated_start = 0;
8590
if (I2C_MasterStop(i2c_addrs[obj->instance]) != kStatus_Success) {
8691
return 1;
8792
}
@@ -179,39 +184,64 @@ int i2c_byte_read(i2c_t *obj, int last)
179184
{
180185
uint8_t data;
181186
I2C_Type *base = i2c_addrs[obj->instance];
182-
i2c_master_transfer_t master_xfer;
183187

184-
memset(&master_xfer, 0, sizeof(master_xfer));
185-
master_xfer.slaveAddress = i2c_address;
186-
master_xfer.direction = kI2C_Read;
187-
master_xfer.data = &data;
188-
master_xfer.dataSize = 1;
188+
/* Setup the I2C peripheral to receive data. */
189+
base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
189190

190-
/* The below function will issue a STOP signal at the end of the transfer.
191-
* This is required by the hardware in order to receive the last byte
192-
*/
193-
if (I2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) {
194-
return I2C_ERROR_NO_SLAVE;
191+
if (last) {
192+
base->C1 |= I2C_C1_TXAK_MASK; // NACK
193+
}
194+
195+
data = (base->D & 0xFF);
196+
197+
/* Change direction to Tx to avoid extra clocks. */
198+
base->C1 |= I2C_C1_TX_MASK;
199+
200+
/* Wait until data transfer complete. */
201+
while (!(base->S & kI2C_IntPendingFlag))
202+
{
195203
}
204+
205+
/* Clear the IICIF flag. */
206+
base->S = kI2C_IntPendingFlag;
207+
196208
return data;
197209
}
198210

199211
int i2c_byte_write(i2c_t *obj, int data)
200212
{
201-
status_t ret_value;
202-
#if FSL_I2C_DRIVER_VERSION > MAKE_VERSION(2, 0, 1)
203-
ret_value = I2C_MasterWriteBlocking(i2c_addrs[obj->instance], (uint8_t *)(&data), 1, kI2C_TransferNoStopFlag);
204-
#else
205-
ret_value = I2C_MasterWriteBlocking(i2c_addrs[obj->instance], (uint8_t *)(&data), 1);
206-
#endif
213+
int ret_value = 1;
214+
uint8_t statusFlags = 0;
215+
I2C_Type *base = i2c_addrs[obj->instance];
207216

208-
if (ret_value == kStatus_Success) {
209-
return 1;
210-
} else if (ret_value == kStatus_I2C_Nak) {
211-
return 0;
212-
} else {
213-
return 2;
217+
/* Setup the I2C peripheral to transmit data. */
218+
base->C1 |= I2C_C1_TX_MASK;
219+
220+
/* Send a byte of data. */
221+
base->D = data;
222+
223+
/* Wait until data transfer complete. */
224+
while (!(base->S & kI2C_IntPendingFlag)) {
225+
}
226+
227+
statusFlags = base->S;
228+
229+
/* Clear the IICIF flag. */
230+
base->S = kI2C_IntPendingFlag;
231+
232+
/* Check if arbitration lost */
233+
if (statusFlags & kI2C_ArbitrationLostFlag) {
234+
base->S = kI2C_ArbitrationLostFlag;
235+
ret_value = 2;
214236
}
237+
238+
/* Check if no acknowledgement (NAK) */
239+
if (statusFlags & kI2C_ReceiveNakFlag) {
240+
base->S = kI2C_ReceiveNakFlag;
241+
ret_value = 0;
242+
}
243+
244+
return ret_value;
215245
}
216246

217247

0 commit comments

Comments
 (0)