1 /*
2  * Copyright 2019 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_common.h"
10 #include "fsl_i2c.h"
11 
12 #include "fsl_adapter_i2c.h"
13 
14 /*******************************************************************************
15  * Definitions
16  ******************************************************************************/
17 
18 /*! @brief i2c master state structure. */
19 typedef struct _hal_i2c_master
20 {
21     hal_i2c_master_transfer_callback_t callback;
22     void *callbackParam;
23     i2c_master_handle_t hardwareHandle;
24     uint8_t instance;
25 } hal_i2c_master_t;
26 
27 /*! @brief i2c slave state structure. */
28 typedef struct _hal_i2c_slave
29 {
30     hal_i2c_slave_transfer_callback_t callback;
31     void *callbackParam;
32     hal_i2c_slave_transfer_t transfer;
33     i2c_slave_handle_t hardwareHandle;
34     uint8_t instance;
35 } hal_i2c_slave_t;
36 
37 /*******************************************************************************
38  * Prototypes
39  ******************************************************************************/
40 
41 /*******************************************************************************
42  * Variables
43  ******************************************************************************/
44 
45 /*! @brief Pointers to i2c bases for each instance. */
46 static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS;
47 
48 /*******************************************************************************
49  * Code
50  ******************************************************************************/
51 
HAL_I2cGetStatus(status_t status)52 static hal_i2c_status_t HAL_I2cGetStatus(status_t status)
53 {
54     hal_i2c_status_t returnStatus;
55     switch (status)
56     {
57         case kStatus_Success:
58         {
59             returnStatus = kStatus_HAL_I2cSuccess; /* Successfully */
60             break;
61         }
62         case kStatus_I2C_Busy:
63         {
64             returnStatus = kStatus_HAL_I2cBusy; /* HAL I2C is busy with current transfer */
65             break;
66         }
67         case kStatus_I2C_Idle:
68         {
69             returnStatus = kStatus_HAL_I2cIdle; /* HAL I2C transmitter is idle */
70             break;
71         }
72         case kStatus_I2C_Nak:
73         {
74             returnStatus = kStatus_HAL_I2cNak; /* NAK received during transfer */
75             break;
76         }
77         case kStatus_I2C_ArbitrationLost:
78         {
79             returnStatus = kStatus_HAL_I2cArbitrationLost; /* Arbitration lost during transfer */
80             break;
81         }
82         case kStatus_I2C_Timeout:
83         {
84             returnStatus = kStatus_HAL_I2cTimeout; /* Timeout */
85             break;
86         }
87         default:
88         {
89             returnStatus = kStatus_HAL_I2cError; /* Error occurs on HAL I2C */
90             break;
91         }
92     }
93     return returnStatus;
94 }
95 
HAL_I2cMasterCallback(I2C_Type * base,i2c_master_handle_t * handle,status_t status,void * callbackParam)96 static void HAL_I2cMasterCallback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *callbackParam)
97 {
98     hal_i2c_master_t *i2cMasterHandle;
99     assert(callbackParam);
100 
101     i2cMasterHandle = (hal_i2c_master_t *)callbackParam;
102 
103     if (NULL != i2cMasterHandle->callback)
104     {
105         i2cMasterHandle->callback(i2cMasterHandle, HAL_I2cGetStatus(status),
106                                   i2cMasterHandle->callbackParam); /* Enter I2c master callback */
107     }
108 }
109 
HAL_I2cSlaveCallback(I2C_Type * base,volatile i2c_slave_transfer_t * xfer,void * callbackParam)110 static void HAL_I2cSlaveCallback(I2C_Type *base, volatile i2c_slave_transfer_t *xfer, void *callbackParam)
111 {
112     hal_i2c_slave_t *i2cSlaveHandle;
113     assert(callbackParam);
114 
115     i2cSlaveHandle = (hal_i2c_slave_t *)callbackParam;
116 
117     if (NULL != i2cSlaveHandle->callback)
118     {
119         i2cSlaveHandle->transfer.event            = (hal_i2c_slave_transfer_event_t)xfer->event;
120         i2cSlaveHandle->transfer.completionStatus = HAL_I2cGetStatus(xfer->completionStatus);
121         i2cSlaveHandle->transfer.transferredCount = xfer->transferredCount;
122         i2cSlaveHandle->callback(i2cSlaveHandle, &i2cSlaveHandle->transfer,
123                                  i2cSlaveHandle->callbackParam); /* Enter I2c slave callback */
124         if (kI2C_SlaveTransmitEvent == xfer->event)
125         {
126             /*slave-transmitter role*/
127             xfer->txData = i2cSlaveHandle->transfer.data;
128             xfer->txSize = i2cSlaveHandle->transfer.dataSize;
129         }
130         else
131         {
132             /*slave-receiver role*/
133             xfer->rxData = i2cSlaveHandle->transfer.data;
134             xfer->rxSize = i2cSlaveHandle->transfer.dataSize;
135         }
136     }
137 }
138 
HAL_I2cMasterInit(hal_i2c_master_handle_t handle,const hal_i2c_master_config_t * halI2cConfig)139 hal_i2c_status_t HAL_I2cMasterInit(hal_i2c_master_handle_t handle, const hal_i2c_master_config_t *halI2cConfig)
140 {
141     hal_i2c_master_t *i2cMasterHandle;
142     i2c_master_config_t i2cConfig;
143 
144     assert(handle);
145     assert(halI2cConfig);
146 
147     assert(HAL_I2C_MASTER_HANDLE_SIZE >= sizeof(hal_i2c_master_t));
148 
149     i2cMasterHandle = (hal_i2c_master_t *)handle;
150 
151     I2C_MasterGetDefaultConfig(&i2cConfig); /* Get a default configuration of master */
152     i2cConfig.enableMaster    = halI2cConfig->enableMaster;
153     i2cConfig.baudRate_Bps    = halI2cConfig->baudRate_Bps;
154     i2cMasterHandle->instance = halI2cConfig->instance;
155 
156     /* I2C Master initization*/
157     I2C_MasterInit(s_i2cBases[i2cMasterHandle->instance], &i2cConfig, halI2cConfig->srcClock_Hz);
158 
159     return kStatus_HAL_I2cSuccess;
160 }
161 
HAL_I2cSlaveInit(hal_i2c_slave_handle_t handle,const hal_i2c_slave_config_t * halI2cConfig)162 hal_i2c_status_t HAL_I2cSlaveInit(hal_i2c_slave_handle_t handle, const hal_i2c_slave_config_t *halI2cConfig)
163 {
164     hal_i2c_slave_t *i2cSlaveHandle;
165     i2c_slave_config_t i2cConfig;
166 
167     assert(handle);
168     assert(halI2cConfig);
169 
170     assert(HAL_I2C_SLAVE_HANDLE_SIZE >= sizeof(hal_i2c_slave_t));
171 
172     i2cSlaveHandle = (hal_i2c_slave_t *)handle;
173 
174     I2C_SlaveGetDefaultConfig(&i2cConfig); /* To get a default configuration of slave*/
175     i2cConfig.enableSlave      = halI2cConfig->enableSlave;
176     i2cConfig.address0.address = (uint8_t)halI2cConfig->slaveAddress;
177     i2cSlaveHandle->instance   = halI2cConfig->instance;
178 
179     /* I2C Slave initization*/
180     (void)I2C_SlaveInit(s_i2cBases[i2cSlaveHandle->instance], &i2cConfig, halI2cConfig->srcClock_Hz);
181 
182     return kStatus_HAL_I2cSuccess;
183 }
184 
HAL_I2cMasterDeinit(hal_i2c_master_handle_t handle)185 hal_i2c_status_t HAL_I2cMasterDeinit(hal_i2c_master_handle_t handle)
186 {
187     hal_i2c_master_t *i2cMasterHandle;
188 
189     assert(handle);
190 
191     i2cMasterHandle = (hal_i2c_master_t *)handle;
192 
193     I2C_MasterDeinit(s_i2cBases[i2cMasterHandle->instance]); /*Deinitializes the I2C master peripheral*/
194 
195     return kStatus_HAL_I2cSuccess;
196 }
197 
HAL_I2cSlaveDeinit(hal_i2c_slave_handle_t handle)198 hal_i2c_status_t HAL_I2cSlaveDeinit(hal_i2c_slave_handle_t handle)
199 {
200     hal_i2c_slave_t *i2cSlaveHandle;
201 
202     assert(handle);
203 
204     i2cSlaveHandle = (hal_i2c_slave_t *)handle;
205 
206     I2C_SlaveDeinit(s_i2cBases[i2cSlaveHandle->instance]); /*Deinitializes the I2C slave peripheral*/
207 
208     return kStatus_HAL_I2cSuccess;
209 }
210 
HAL_I2cMasterWriteBlocking(hal_i2c_master_handle_t handle,const uint8_t * txBuff,size_t txSize,uint32_t flags)211 hal_i2c_status_t HAL_I2cMasterWriteBlocking(hal_i2c_master_handle_t handle,
212                                             const uint8_t *txBuff,
213                                             size_t txSize,
214                                             uint32_t flags)
215 {
216     hal_i2c_master_t *i2cMasterHandle;
217 
218     assert(handle);
219 
220     i2cMasterHandle = (hal_i2c_master_t *)handle;
221 
222     /*Performs a polling send transfer on the I2C bus*/
223     return HAL_I2cGetStatus(I2C_MasterWriteBlocking(s_i2cBases[i2cMasterHandle->instance], txBuff, txSize, flags));
224 }
225 
HAL_I2cMasterReadBlocking(hal_i2c_master_handle_t handle,uint8_t * rxBuff,size_t rxSize,uint32_t flags)226 hal_i2c_status_t HAL_I2cMasterReadBlocking(hal_i2c_master_handle_t handle,
227                                            uint8_t *rxBuff,
228                                            size_t rxSize,
229                                            uint32_t flags)
230 {
231     hal_i2c_master_t *i2cMasterHandle;
232 
233     assert(handle);
234 
235     i2cMasterHandle = (hal_i2c_master_t *)handle;
236 
237     return HAL_I2cGetStatus(I2C_MasterReadBlocking(s_i2cBases[i2cMasterHandle->instance], rxBuff, rxSize, flags));
238 }
239 
HAL_I2cSlaveWriteBlocking(hal_i2c_slave_handle_t handle,const uint8_t * txBuff,size_t txSize)240 hal_i2c_status_t HAL_I2cSlaveWriteBlocking(hal_i2c_slave_handle_t handle, const uint8_t *txBuff, size_t txSize)
241 {
242     hal_i2c_slave_t *i2cSlaveHandle;
243 
244     assert(handle);
245 
246     i2cSlaveHandle = (hal_i2c_slave_t *)handle;
247 
248     /*Performs a polling receive transfer on the I2C bus.*/
249     return HAL_I2cGetStatus(I2C_SlaveWriteBlocking(s_i2cBases[i2cSlaveHandle->instance], txBuff, txSize));
250 }
251 
HAL_I2cSlaveReadBlocking(hal_i2c_slave_handle_t handle,uint8_t * rxBuff,size_t rxSize)252 hal_i2c_status_t HAL_I2cSlaveReadBlocking(hal_i2c_slave_handle_t handle, uint8_t *rxBuff, size_t rxSize)
253 {
254     hal_i2c_slave_t *i2cSlaveHandle;
255 
256     assert(handle);
257 
258     i2cSlaveHandle = (hal_i2c_slave_t *)handle;
259 
260     return HAL_I2cGetStatus(I2C_SlaveReadBlocking(s_i2cBases[i2cSlaveHandle->instance], rxBuff, rxSize));
261 }
262 
HAL_I2cMasterTransferBlocking(hal_i2c_master_handle_t handle,hal_i2c_master_transfer_t * xfer)263 hal_i2c_status_t HAL_I2cMasterTransferBlocking(hal_i2c_master_handle_t handle, hal_i2c_master_transfer_t *xfer)
264 {
265     hal_i2c_master_t *i2cMasterHandle;
266     i2c_master_transfer_t transfer;
267 
268     assert(handle);
269     assert(xfer);
270 
271     i2cMasterHandle = (hal_i2c_master_t *)handle;
272 
273     transfer.flags          = xfer->flags;
274     transfer.slaveAddress   = xfer->slaveAddress;
275     transfer.direction      = (kHAL_I2cRead == xfer->direction) ? kI2C_Read : kI2C_Write;
276     transfer.subaddress     = xfer->subaddress;
277     transfer.subaddressSize = xfer->subaddressSize;
278     transfer.data           = xfer->data;
279     transfer.dataSize       = xfer->dataSize;
280 
281     return HAL_I2cGetStatus(I2C_MasterTransferBlocking(s_i2cBases[i2cMasterHandle->instance], &transfer));
282 }
283 
HAL_I2cMasterTransferInstallCallback(hal_i2c_master_handle_t handle,hal_i2c_master_transfer_callback_t callback,void * callbackParam)284 hal_i2c_status_t HAL_I2cMasterTransferInstallCallback(hal_i2c_master_handle_t handle,
285                                                       hal_i2c_master_transfer_callback_t callback,
286                                                       void *callbackParam)
287 {
288     hal_i2c_master_t *i2cMasterHandle;
289 
290     assert(handle);
291 
292     i2cMasterHandle = (hal_i2c_master_t *)handle;
293 
294     i2cMasterHandle->callback      = callback;
295     i2cMasterHandle->callbackParam = callbackParam;
296     I2C_MasterTransferCreateHandle(s_i2cBases[i2cMasterHandle->instance], &i2cMasterHandle->hardwareHandle,
297                                    HAL_I2cMasterCallback, i2cMasterHandle);
298 
299     return kStatus_HAL_I2cSuccess;
300 }
301 
HAL_I2cMasterTransferNonBlocking(hal_i2c_master_handle_t handle,hal_i2c_master_transfer_t * xfer)302 hal_i2c_status_t HAL_I2cMasterTransferNonBlocking(hal_i2c_master_handle_t handle, hal_i2c_master_transfer_t *xfer)
303 {
304     hal_i2c_master_t *i2cMasterHandle;
305     i2c_master_transfer_t transfer;
306 
307     assert(handle);
308     assert(xfer);
309 
310     i2cMasterHandle = (hal_i2c_master_t *)handle;
311 
312     transfer.flags          = xfer->flags;
313     transfer.slaveAddress   = xfer->slaveAddress;
314     transfer.direction      = (kHAL_I2cRead == xfer->direction) ? kI2C_Read : kI2C_Write;
315     transfer.subaddress     = xfer->subaddress;
316     transfer.subaddressSize = xfer->subaddressSize;
317     transfer.data           = xfer->data;
318     transfer.dataSize       = xfer->dataSize;
319     return HAL_I2cGetStatus(I2C_MasterTransferNonBlocking(s_i2cBases[i2cMasterHandle->instance],
320                                                           &i2cMasterHandle->hardwareHandle, &transfer));
321 }
322 
HAL_I2cMasterTransferGetCount(hal_i2c_master_handle_t handle,size_t * count)323 hal_i2c_status_t HAL_I2cMasterTransferGetCount(hal_i2c_master_handle_t handle, size_t *count)
324 {
325     hal_i2c_master_t *i2cMasterHandle;
326 
327     assert(handle);
328     assert(count);
329 
330     i2cMasterHandle = (hal_i2c_master_t *)handle;
331     return HAL_I2cGetStatus(
332         I2C_MasterTransferGetCount(s_i2cBases[i2cMasterHandle->instance], &i2cMasterHandle->hardwareHandle, count));
333 }
334 
HAL_I2cMasterTransferAbort(hal_i2c_master_handle_t handle)335 hal_i2c_status_t HAL_I2cMasterTransferAbort(hal_i2c_master_handle_t handle)
336 {
337     hal_i2c_master_t *i2cMasterHandle;
338 
339     assert(handle);
340 
341     i2cMasterHandle = (hal_i2c_master_t *)handle;
342     return HAL_I2cGetStatus(
343         I2C_MasterTransferAbort(s_i2cBases[i2cMasterHandle->instance], &i2cMasterHandle->hardwareHandle));
344 }
345 
HAL_I2cSlaveTransferInstallCallback(hal_i2c_slave_handle_t handle,hal_i2c_slave_transfer_callback_t callback,void * callbackParam)346 hal_i2c_status_t HAL_I2cSlaveTransferInstallCallback(hal_i2c_slave_handle_t handle,
347                                                      hal_i2c_slave_transfer_callback_t callback,
348                                                      void *callbackParam)
349 {
350     hal_i2c_slave_t *i2cSlaveHandle;
351 
352     assert(handle);
353 
354     i2cSlaveHandle = (hal_i2c_slave_t *)handle;
355 
356     i2cSlaveHandle->callback      = callback;
357     i2cSlaveHandle->callbackParam = callbackParam;
358     I2C_SlaveTransferCreateHandle(s_i2cBases[i2cSlaveHandle->instance], &i2cSlaveHandle->hardwareHandle,
359                                   HAL_I2cSlaveCallback, i2cSlaveHandle);
360 
361     return kStatus_HAL_I2cSuccess;
362 }
363 
HAL_I2cSlaveTransferNonBlocking(hal_i2c_slave_handle_t handle,uint32_t eventMask)364 hal_i2c_status_t HAL_I2cSlaveTransferNonBlocking(hal_i2c_slave_handle_t handle, uint32_t eventMask)
365 {
366     hal_i2c_slave_t *i2cSlaveHandle;
367 
368     assert(handle);
369 
370     i2cSlaveHandle = (hal_i2c_slave_t *)handle;
371 
372     return HAL_I2cGetStatus(
373         I2C_SlaveTransferNonBlocking(s_i2cBases[i2cSlaveHandle->instance], &i2cSlaveHandle->hardwareHandle, eventMask));
374 }
375 
HAL_I2cSlaveTransferAbort(hal_i2c_slave_handle_t handle)376 hal_i2c_status_t HAL_I2cSlaveTransferAbort(hal_i2c_slave_handle_t handle)
377 {
378     hal_i2c_slave_t *i2cSlaveHandle;
379 
380     assert(handle);
381 
382     i2cSlaveHandle = (hal_i2c_slave_t *)handle;
383 
384     I2C_SlaveTransferAbort(s_i2cBases[i2cSlaveHandle->instance], &i2cSlaveHandle->hardwareHandle);
385 
386     return kStatus_HAL_I2cSuccess;
387 }
388 
HAL_I2cSlaveTransferGetCount(hal_i2c_slave_handle_t handle,size_t * count)389 hal_i2c_status_t HAL_I2cSlaveTransferGetCount(hal_i2c_slave_handle_t handle, size_t *count)
390 {
391     hal_i2c_slave_t *i2cSlaveHandle;
392 
393     assert(handle);
394     assert(count);
395 
396     i2cSlaveHandle = (hal_i2c_slave_t *)handle;
397 
398     return HAL_I2cGetStatus(
399         I2C_SlaveTransferGetCount(s_i2cBases[i2cSlaveHandle->instance], &i2cSlaveHandle->hardwareHandle, count));
400 }
401