23
23
#include "fsl_i2c.h"
24
24
#include "PeripheralPins.h"
25
25
26
- /* 7 bit IIC addr - R/W flag not included */
27
- static int i2c_address = 0 ;
28
-
29
26
/* Array of I2C peripheral base address. */
30
27
static I2C_Type * const i2c_addrs [] = I2C_BASE_PTRS ;
31
28
@@ -98,17 +95,21 @@ int i2c_start(i2c_t *obj)
98
95
I2C_Type * base = i2c_addrs [obj -> instance ];
99
96
uint32_t status ;
100
97
101
- do
102
- {
98
+ do {
103
99
status = I2C_GetStatusFlags (base );
104
100
} while ((status & I2C_STAT_MSTPENDING_MASK ) == 0 );
105
101
106
102
/* Clear controller state. */
107
103
I2C_MasterClearStatusFlags (base , I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK );
108
104
109
105
/* Start the transfer */
106
+ base -> MSTDAT = 0 ;
110
107
base -> MSTCTL = I2C_MSTCTL_MSTSTART_MASK ;
111
108
109
+ do {
110
+ status = I2C_GetStatusFlags (base );
111
+ } while ((status & I2C_STAT_MSTPENDING_MASK ) == 0 );
112
+
112
113
return 0 ;
113
114
}
114
115
@@ -117,8 +118,7 @@ int i2c_stop(i2c_t *obj)
117
118
I2C_Type * base = i2c_addrs [obj -> instance ];
118
119
uint32_t status ;
119
120
120
- do
121
- {
121
+ do {
122
122
status = I2C_GetStatusFlags (base );
123
123
} while ((status & I2C_STAT_MSTPENDING_MASK ) == 0 );
124
124
@@ -127,6 +127,10 @@ int i2c_stop(i2c_t *obj)
127
127
128
128
base -> MSTCTL = I2C_MSTCTL_MSTSTOP_MASK ;
129
129
130
+ do {
131
+ status = I2C_GetStatusFlags (base );
132
+ } while ((status & I2C_STAT_MSTPENDING_MASK ) == 0 );
133
+
130
134
return 0 ;
131
135
}
132
136
@@ -140,7 +144,6 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
140
144
I2C_Type * base = i2c_addrs [obj -> instance ];
141
145
i2c_master_transfer_t master_xfer ;
142
146
143
- i2c_address = address >> 1 ;
144
147
memset (& master_xfer , 0 , sizeof (master_xfer ));
145
148
master_xfer .slaveAddress = address >> 1 ;
146
149
master_xfer .direction = kI2C_Read ;
@@ -154,9 +157,6 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
154
157
}
155
158
obj -> next_repeated_start = master_xfer .flags & kI2C_TransferNoStopFlag ? 1 : 0 ;
156
159
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
- */
160
160
if (I2C_MasterTransferBlocking (base , & master_xfer ) != kStatus_Success ) {
161
161
return I2C_ERROR_NO_SLAVE ;
162
162
}
@@ -212,33 +212,49 @@ int i2c_byte_read(i2c_t *obj, int last)
212
212
{
213
213
uint8_t data ;
214
214
I2C_Type * base = i2c_addrs [obj -> instance ];
215
- i2c_master_transfer_t master_xfer ;
215
+ uint32_t status ;
216
216
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 );
222
220
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
225
225
}
226
+
226
227
return data ;
227
228
}
228
229
229
230
int i2c_byte_write (i2c_t * obj , int data )
230
231
{
231
- status_t ret_value ;
232
+ I2C_Type * base = i2c_addrs [obj -> instance ];
233
+ uint32_t status ;
234
+ int ret_value = 1 ;
232
235
233
- ret_value = I2C_MasterWriteBlocking (i2c_addrs [obj -> instance ], (uint8_t * )(& data ), 1 , kI2C_TransferNoStopFlag );
236
+ // write the data
237
+ base -> MSTDAT = data ;
234
238
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 ;
241
250
}
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 ;
242
258
}
243
259
244
260
0 commit comments