@@ -67,12 +67,14 @@ int i2c_start(i2c_t *obj)
67
67
I2C_Type * base = i2c_addrs [obj -> instance ];
68
68
uint32_t statusFlags = I2C_MasterGetStatusFlags (base );
69
69
70
- /* Return an error if the bus is already in use. */
70
+ /* Check if the bus is already in use. */
71
71
if (statusFlags & kI2C_BusBusyFlag ) {
72
- 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 ;
73
77
}
74
- /* Send the START signal. */
75
- base -> C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK ;
76
78
77
79
#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING ) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING
78
80
while (!(base -> S2 & I2C_S2_EMPTY_MASK ))
@@ -85,7 +87,6 @@ int i2c_start(i2c_t *obj)
85
87
86
88
int i2c_stop (i2c_t * obj )
87
89
{
88
- obj -> next_repeated_start = 0 ;
89
90
if (I2C_MasterStop (i2c_addrs [obj -> instance ]) != kStatus_Success ) {
90
91
return 1 ;
91
92
}
@@ -183,39 +184,64 @@ int i2c_byte_read(i2c_t *obj, int last)
183
184
{
184
185
uint8_t data ;
185
186
I2C_Type * base = i2c_addrs [obj -> instance ];
186
- i2c_master_transfer_t master_xfer ;
187
187
188
- memset (& master_xfer , 0 , sizeof (master_xfer ));
189
- master_xfer .slaveAddress = i2c_address ;
190
- master_xfer .direction = kI2C_Read ;
191
- master_xfer .data = & data ;
192
- master_xfer .dataSize = 1 ;
188
+ /* Setup the I2C peripheral to receive data. */
189
+ base -> C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK );
193
190
194
- /* The below function will issue a STOP signal at the end of the transfer.
195
- * This is required by the hardware in order to receive the last byte
196
- */
197
- if (I2C_MasterTransferBlocking (base , & master_xfer ) != kStatus_Success ) {
198
- return I2C_ERROR_NO_SLAVE ;
191
+ if (last ) {
192
+ base -> C1 |= I2C_C1_TXAK_MASK ; // NACK
199
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
+ {
203
+ }
204
+
205
+ /* Clear the IICIF flag. */
206
+ base -> S = kI2C_IntPendingFlag ;
207
+
200
208
return data ;
201
209
}
202
210
203
211
int i2c_byte_write (i2c_t * obj , int data )
204
212
{
205
- status_t ret_value ;
206
- #if FSL_I2C_DRIVER_VERSION > MAKE_VERSION (2 , 0 , 1 )
207
- ret_value = I2C_MasterWriteBlocking (i2c_addrs [obj -> instance ], (uint8_t * )(& data ), 1 , kI2C_TransferNoStopFlag );
208
- #else
209
- ret_value = I2C_MasterWriteBlocking (i2c_addrs [obj -> instance ], (uint8_t * )(& data ), 1 );
210
- #endif
213
+ int ret_value = 1 ;
214
+ uint8_t statusFlags = 0 ;
215
+ I2C_Type * base = i2c_addrs [obj -> instance ];
211
216
212
- if (ret_value == kStatus_Success ) {
213
- return 1 ;
214
- } else if (ret_value == kStatus_I2C_Nak ) {
215
- return 0 ;
216
- } else {
217
- 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 ;
236
+ }
237
+
238
+ /* Check if no acknowledgement (NAK) */
239
+ if (statusFlags & kI2C_ReceiveNakFlag ) {
240
+ base -> S = kI2C_ReceiveNakFlag ;
241
+ ret_value = 0 ;
218
242
}
243
+
244
+ return ret_value ;
219
245
}
220
246
221
247
0 commit comments