Skip to content

Commit 1cc78f8

Browse files
author
Cruz Monrreal
authored
Merge pull request #6647 from codeauroraforum/Fix_LPC54xxx_I2C
Fix MCUXpresso LPC I2C driver
2 parents 1df9f7d + 6e9f99c commit 1cc78f8

File tree

3 files changed

+61
-27
lines changed

3 files changed

+61
-27
lines changed

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC/i2c_api.c

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323
#include "fsl_i2c.h"
2424
#include "PeripheralPins.h"
2525

26-
/* 7 bit IIC addr - R/W flag not included */
27-
static int i2c_address = 0;
28-
2926
/* Array of I2C peripheral base address. */
3027
static I2C_Type *const i2c_addrs[] = I2C_BASE_PTRS;
3128

@@ -98,17 +95,21 @@ int i2c_start(i2c_t *obj)
9895
I2C_Type *base = i2c_addrs[obj->instance];
9996
uint32_t status;
10097

101-
do
102-
{
98+
do {
10399
status = I2C_GetStatusFlags(base);
104100
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
105101

106102
/* Clear controller state. */
107103
I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK);
108104

109105
/* Start the transfer */
106+
base->MSTDAT = 0;
110107
base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK;
111108

109+
do {
110+
status = I2C_GetStatusFlags(base);
111+
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
112+
112113
return 0;
113114
}
114115

@@ -117,8 +118,7 @@ int i2c_stop(i2c_t *obj)
117118
I2C_Type *base = i2c_addrs[obj->instance];
118119
uint32_t status;
119120

120-
do
121-
{
121+
do {
122122
status = I2C_GetStatusFlags(base);
123123
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
124124

@@ -127,6 +127,10 @@ int i2c_stop(i2c_t *obj)
127127

128128
base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;
129129

130+
do {
131+
status = I2C_GetStatusFlags(base);
132+
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
133+
130134
return 0;
131135
}
132136

@@ -140,7 +144,6 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
140144
I2C_Type *base = i2c_addrs[obj->instance];
141145
i2c_master_transfer_t master_xfer;
142146

143-
i2c_address = address >> 1;
144147
memset(&master_xfer, 0, sizeof(master_xfer));
145148
master_xfer.slaveAddress = address >> 1;
146149
master_xfer.direction = kI2C_Read;
@@ -154,9 +157,6 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
154157
}
155158
obj->next_repeated_start = master_xfer.flags & kI2C_TransferNoStopFlag ? 1 : 0;
156159

157-
/* The below function will issue a STOP signal at the end of the transfer.
158-
* This is required by the hardware in order to receive the last byte
159-
*/
160160
if (I2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) {
161161
return I2C_ERROR_NO_SLAVE;
162162
}
@@ -212,33 +212,49 @@ int i2c_byte_read(i2c_t *obj, int last)
212212
{
213213
uint8_t data;
214214
I2C_Type *base = i2c_addrs[obj->instance];
215-
i2c_master_transfer_t master_xfer;
215+
uint32_t status;
216216

217-
memset(&master_xfer, 0, sizeof(master_xfer));
218-
master_xfer.slaveAddress = i2c_address;
219-
master_xfer.direction = kI2C_Read;
220-
master_xfer.data = &data;
221-
master_xfer.dataSize = 1;
217+
do {
218+
status = I2C_GetStatusFlags(base);
219+
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
222220

223-
if (I2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) {
224-
return I2C_ERROR_NO_SLAVE;
221+
data = base->MSTDAT;
222+
223+
if (!last) {
224+
base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; //ACK and Continue
225225
}
226+
226227
return data;
227228
}
228229

229230
int i2c_byte_write(i2c_t *obj, int data)
230231
{
231-
status_t ret_value;
232+
I2C_Type *base = i2c_addrs[obj->instance];
233+
uint32_t status;
234+
int ret_value = 1;
232235

233-
ret_value = I2C_MasterWriteBlocking(i2c_addrs[obj->instance], (uint8_t *)(&data), 1, kI2C_TransferNoStopFlag);
236+
// write the data
237+
base->MSTDAT = data;
234238

235-
if (ret_value == kStatus_Success) {
236-
return 1;
237-
} else if (ret_value == kStatus_I2C_Nak) {
238-
return 0;
239-
} else {
240-
return 2;
239+
base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;
240+
241+
do {
242+
status = I2C_GetStatusFlags(base);
243+
} while ((status & I2C_STAT_MSTPENDING_MASK) == 0);
244+
245+
246+
/* Check if arbitration lost */
247+
if (status & I2C_STAT_MSTARBLOSS_MASK) {
248+
I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK);
249+
ret_value = 2;
241250
}
251+
252+
/* Check if no acknowledgement (NAK) */
253+
if (((status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT) == I2C_STAT_MSTCODE_NACKDAT) {
254+
ret_value = 0;
255+
}
256+
257+
return ret_value;
242258
}
243259

244260

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/drivers/fsl_i2c.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direct
163163
/* Start the transfer */
164164
base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK;
165165

166+
I2C_PendingStatusWait(base);
167+
166168
return kStatus_Success;
167169
}
168170

@@ -171,6 +173,9 @@ status_t I2C_MasterStop(I2C_Type *base)
171173
I2C_PendingStatusWait(base);
172174

173175
base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;
176+
177+
I2C_PendingStatusWait(base);
178+
174179
return kStatus_Success;
175180
}
176181

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC546XX/drivers/fsl_i2c.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direct
201201
/* Start the transfer */
202202
base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK;
203203

204+
result = I2C_PendingStatusWait(base);
205+
if (result == kStatus_I2C_Timeout)
206+
{
207+
return kStatus_I2C_Timeout;
208+
}
209+
204210
return kStatus_Success;
205211
}
206212

@@ -214,6 +220,13 @@ status_t I2C_MasterStop(I2C_Type *base)
214220
}
215221

216222
base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;
223+
224+
result = I2C_PendingStatusWait(base);
225+
if (result == kStatus_I2C_Timeout)
226+
{
227+
return kStatus_I2C_Timeout;
228+
}
229+
217230
return kStatus_Success;
218231
}
219232

0 commit comments

Comments
 (0)