1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 #include <stdio.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include "mxc_device.h"
25 #include "mxc_assert.h"
26 #include "mxc_lock.h"
27 #include "mxc_sys.h"
28 #include "mxc_delay.h"
29 #include "i2c_regs.h"
30 #include "dma_regs.h"
31 #include "i2c.h"
32 #include "i2c_reva.h"
33 
34 /* **** Variable Declaration **** */
35 uint32_t interruptCheck = MXC_F_I2C_INTFL0_RD_ADDR_MATCH | MXC_F_I2C_INTFL0_WR_ADDR_MATCH |
36                           MXC_F_I2C_INTFL0_ADDR_MATCH | MXC_F_I2C_INTFL0_DNR_ERR;
37 
38 /* **** Function Prototypes **** */
39 
40 /* ************************************************************************* */
41 /* Control/Configuration functions                                           */
42 /* ************************************************************************* */
MXC_I2C_Init(mxc_i2c_regs_t * i2c,int masterMode,unsigned int slaveAddr)43 int MXC_I2C_Init(mxc_i2c_regs_t *i2c, int masterMode, unsigned int slaveAddr)
44 {
45     if (i2c == NULL) {
46         return E_NULL_PTR;
47     }
48 
49     MXC_I2C_Shutdown(i2c); // Clear everything out
50 
51     if (i2c == MXC_I2C0) {
52         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C0);
53         MXC_GPIO_Config(&gpio_cfg_i2c0);
54     } else if (i2c == MXC_I2C1) {
55         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C1);
56         MXC_GPIO_Config(&gpio_cfg_i2c1);
57     } else {
58         return E_NO_DEVICE;
59     }
60 
61     return MXC_I2C_RevA_Init((mxc_i2c_reva_regs_t *)i2c, masterMode, slaveAddr);
62 }
63 
MXC_I2C_SetSlaveAddr(mxc_i2c_regs_t * i2c,unsigned int slaveAddr,int idx)64 int MXC_I2C_SetSlaveAddr(mxc_i2c_regs_t *i2c, unsigned int slaveAddr, int idx)
65 {
66     return MXC_I2C_RevA_SetSlaveAddr((mxc_i2c_reva_regs_t *)i2c, slaveAddr, idx);
67 }
68 
MXC_I2C_Shutdown(mxc_i2c_regs_t * i2c)69 int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c)
70 {
71     // Configure GPIO for I2C
72     if (i2c == MXC_I2C0) {
73         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C0);
74     } else if (i2c == MXC_I2C1) {
75         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C1);
76     } else {
77         return E_NO_DEVICE;
78     }
79 
80     return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c);
81 }
82 
MXC_I2C_Reset(mxc_i2c_regs_t * i2c)83 int MXC_I2C_Reset(mxc_i2c_regs_t *i2c)
84 {
85     // Configure GPIO for I2C
86     if (i2c == MXC_I2C0) {
87         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_I2C0);
88     } else if (i2c == MXC_I2C1) {
89         MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C1);
90     } else {
91         return E_NO_DEVICE;
92     }
93 
94     return E_NO_ERROR;
95 }
96 
MXC_I2C_SetFrequency(mxc_i2c_regs_t * i2c,unsigned int hz)97 int MXC_I2C_SetFrequency(mxc_i2c_regs_t *i2c, unsigned int hz)
98 {
99     return MXC_I2C_RevA_SetFrequency((mxc_i2c_reva_regs_t *)i2c, hz);
100 }
101 
MXC_I2C_GetFrequency(mxc_i2c_regs_t * i2c)102 unsigned int MXC_I2C_GetFrequency(mxc_i2c_regs_t *i2c)
103 {
104     return MXC_I2C_RevA_GetFrequency((mxc_i2c_reva_regs_t *)i2c);
105 }
106 
MXC_I2C_ReadyForSleep(mxc_i2c_regs_t * i2c)107 int MXC_I2C_ReadyForSleep(mxc_i2c_regs_t *i2c)
108 {
109     return MXC_I2C_RevA_ReadyForSleep((mxc_i2c_reva_regs_t *)i2c);
110 }
111 
MXC_I2C_SetClockStretching(mxc_i2c_regs_t * i2c,int enable)112 int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable)
113 {
114     return MXC_I2C_RevA_SetClockStretching((mxc_i2c_reva_regs_t *)i2c, enable);
115 }
116 
MXC_I2C_GetClockStretching(mxc_i2c_regs_t * i2c)117 int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c)
118 {
119     return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c);
120 }
121 
MXC_I2C_DMA_Init(mxc_i2c_regs_t * i2c,mxc_dma_regs_t * dma,bool use_dma_tx,bool use_dma_rx)122 int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx)
123 {
124     return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx,
125                                  use_dma_rx);
126 }
127 
MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t * i2c)128 int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c)
129 {
130     return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c);
131 }
132 
MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t * i2c)133 int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c)
134 {
135     return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c);
136 }
137 
MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t * i2c,uint8_t * txData,uint8_t * rxData)138 int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData)
139 {
140     int i2cNum;
141     int txReqSel = -1;
142     int rxReqSel = -1;
143 
144     if (i2c == NULL) {
145         return E_NULL_PTR;
146     }
147 
148     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
149 
150     if (txData != NULL) {
151         switch (i2cNum) {
152         case 0:
153             txReqSel = MXC_DMA_REQUEST_I2C0TX;
154             break;
155 
156         case 1:
157             txReqSel = MXC_DMA_REQUEST_I2C1TX;
158             break;
159 
160         default:
161             return E_BAD_PARAM;
162         }
163     }
164 
165     if (rxData != NULL) {
166         switch (i2cNum) {
167         case 0:
168             rxReqSel = MXC_DMA_REQUEST_I2C0RX;
169             break;
170 
171         case 1:
172             rxReqSel = MXC_DMA_REQUEST_I2C1RX;
173             break;
174 
175         default:
176             return E_BAD_PARAM;
177         }
178     }
179 
180     return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c,
181                                              (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel);
182 }
183 
184 /* ************************************************************************* */
185 /* Low-level functions                                                       */
186 /* ************************************************************************* */
MXC_I2C_Start(mxc_i2c_regs_t * i2c)187 int MXC_I2C_Start(mxc_i2c_regs_t *i2c)
188 {
189     return MXC_I2C_RevA_Start((mxc_i2c_reva_regs_t *)i2c);
190 }
191 
MXC_I2C_Stop(mxc_i2c_regs_t * i2c)192 int MXC_I2C_Stop(mxc_i2c_regs_t *i2c)
193 {
194     return MXC_I2C_RevA_Stop((mxc_i2c_reva_regs_t *)i2c);
195 }
196 
MXC_I2C_WriteByte(mxc_i2c_regs_t * i2c,unsigned char byte)197 int MXC_I2C_WriteByte(mxc_i2c_regs_t *i2c, unsigned char byte)
198 {
199     return MXC_I2C_RevA_WriteByte((mxc_i2c_reva_regs_t *)i2c, byte);
200 }
201 
MXC_I2C_ReadByte(mxc_i2c_regs_t * i2c,unsigned char * byte,int ack)202 int MXC_I2C_ReadByte(mxc_i2c_regs_t *i2c, unsigned char *byte, int ack)
203 {
204     return MXC_I2C_RevA_ReadByte((mxc_i2c_reva_regs_t *)i2c, byte, ack);
205 }
206 
MXC_I2C_ReadByteInteractive(mxc_i2c_regs_t * i2c,unsigned char * byte,mxc_i2c_getAck_t getAck)207 int MXC_I2C_ReadByteInteractive(mxc_i2c_regs_t *i2c, unsigned char *byte, mxc_i2c_getAck_t getAck)
208 {
209     return MXC_I2C_RevA_ReadByteInteractive((mxc_i2c_reva_regs_t *)i2c, byte,
210                                             (mxc_i2c_reva_getAck_t)getAck);
211 }
212 
MXC_I2C_Write(mxc_i2c_regs_t * i2c,unsigned char * bytes,unsigned int * len)213 int MXC_I2C_Write(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len)
214 {
215     return MXC_I2C_RevA_Write((mxc_i2c_reva_regs_t *)i2c, bytes, len);
216 }
217 
MXC_I2C_Read(mxc_i2c_regs_t * i2c,unsigned char * bytes,unsigned int * len,int ack)218 int MXC_I2C_Read(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len, int ack)
219 {
220     return MXC_I2C_RevA_Read((mxc_i2c_reva_regs_t *)i2c, bytes, len, ack);
221 }
222 
MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t * i2c,volatile unsigned char * bytes,unsigned int len)223 int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsigned int len)
224 {
225     return MXC_I2C_RevA_ReadRXFIFO((mxc_i2c_reva_regs_t *)i2c, bytes, len);
226 }
227 
MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t * i2c,unsigned char * bytes,unsigned int len,mxc_i2c_dma_complete_cb_t callback)228 int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len,
229                           mxc_i2c_dma_complete_cb_t callback)
230 {
231     // The callback parameter was previously unused but keeping it for backwards-compatibility.
232     return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA);
233 }
234 
MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t * i2c)235 int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c)
236 {
237     return MXC_I2C_RevA_GetRXFIFOAvailable((mxc_i2c_reva_regs_t *)i2c);
238 }
239 
MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t * i2c,volatile unsigned char * bytes,unsigned int len)240 int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsigned int len)
241 {
242     return MXC_I2C_RevA_WriteTXFIFO((mxc_i2c_reva_regs_t *)i2c, bytes, len);
243 }
244 
MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t * i2c,unsigned char * bytes,unsigned int len,mxc_i2c_dma_complete_cb_t callback)245 int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len,
246                            mxc_i2c_dma_complete_cb_t callback)
247 {
248     // The callback parameter was previously unused but keeping it for backwards-compatibility.
249     return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA);
250 }
251 
MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t * i2c)252 int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c)
253 {
254     return MXC_I2C_RevA_GetTXFIFOAvailable((mxc_i2c_reva_regs_t *)i2c);
255 }
256 
MXC_I2C_ClearRXFIFO(mxc_i2c_regs_t * i2c)257 void MXC_I2C_ClearRXFIFO(mxc_i2c_regs_t *i2c)
258 {
259     MXC_I2C_RevA_ClearRXFIFO((mxc_i2c_reva_regs_t *)i2c);
260 }
261 
MXC_I2C_ClearTXFIFO(mxc_i2c_regs_t * i2c)262 void MXC_I2C_ClearTXFIFO(mxc_i2c_regs_t *i2c)
263 {
264     MXC_I2C_RevA_ClearTXFIFO((mxc_i2c_reva_regs_t *)i2c);
265 }
266 
MXC_I2C_GetFlags(mxc_i2c_regs_t * i2c,unsigned int * flags0,unsigned int * flags1)267 int MXC_I2C_GetFlags(mxc_i2c_regs_t *i2c, unsigned int *flags0, unsigned int *flags1)
268 {
269     return MXC_I2C_RevA_GetFlags((mxc_i2c_reva_regs_t *)i2c, flags0, flags1);
270 }
271 
MXC_I2C_ClearFlags(mxc_i2c_regs_t * i2c,unsigned int flags0,unsigned int flags1)272 void MXC_I2C_ClearFlags(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1)
273 {
274     MXC_I2C_RevA_ClearFlags((mxc_i2c_reva_regs_t *)i2c, flags0, flags1);
275 }
276 
MXC_I2C_EnableInt(mxc_i2c_regs_t * i2c,unsigned int flags0,unsigned int flags1)277 void MXC_I2C_EnableInt(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1)
278 {
279     MXC_I2C_RevA_EnableInt((mxc_i2c_reva_regs_t *)i2c, flags0, flags1);
280 }
281 
MXC_I2C_DisableInt(mxc_i2c_regs_t * i2c,unsigned int flags0,unsigned int flags1)282 void MXC_I2C_DisableInt(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1)
283 {
284     MXC_I2C_RevA_DisableInt((mxc_i2c_reva_regs_t *)i2c, flags0, flags1);
285 }
286 
MXC_I2C_EnablePreload(mxc_i2c_regs_t * i2c)287 void MXC_I2C_EnablePreload(mxc_i2c_regs_t *i2c)
288 {
289     MXC_I2C_RevA_EnablePreload((mxc_i2c_reva_regs_t *)i2c);
290 }
291 
MXC_I2C_DisablePreload(mxc_i2c_regs_t * i2c)292 void MXC_I2C_DisablePreload(mxc_i2c_regs_t *i2c)
293 {
294     MXC_I2C_RevA_DisablePreload((mxc_i2c_reva_regs_t *)i2c);
295 }
296 
MXC_I2C_EnableGeneralCall(mxc_i2c_regs_t * i2c)297 void MXC_I2C_EnableGeneralCall(mxc_i2c_regs_t *i2c)
298 {
299     MXC_I2C_RevA_EnableGeneralCall((mxc_i2c_reva_regs_t *)i2c);
300 }
301 
MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t * i2c)302 void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c)
303 {
304     MXC_I2C_RevA_DisableGeneralCall((mxc_i2c_reva_regs_t *)i2c);
305 }
306 
MXC_I2C_SetTimeout(mxc_i2c_regs_t * i2c,unsigned int timeout)307 void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout)
308 {
309     MXC_I2C_RevA_SetTimeout((mxc_i2c_reva_regs_t *)i2c, timeout);
310 }
311 
MXC_I2C_GetTimeout(mxc_i2c_regs_t * i2c)312 unsigned int MXC_I2C_GetTimeout(mxc_i2c_regs_t *i2c)
313 {
314     return MXC_I2C_RevA_GetTimeout((mxc_i2c_reva_regs_t *)i2c);
315 }
316 
MXC_I2C_Recover(mxc_i2c_regs_t * i2c,unsigned int retries)317 int MXC_I2C_Recover(mxc_i2c_regs_t *i2c, unsigned int retries)
318 {
319     return MXC_I2C_RevA_Recover((mxc_i2c_reva_regs_t *)i2c, retries);
320 }
321 
322 /* ************************************************************************* */
323 /* Transaction level functions                                               */
324 /* ************************************************************************* */
325 
MXC_I2C_MasterTransaction(mxc_i2c_req_t * req)326 int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req)
327 {
328     return MXC_I2C_RevA_MasterTransaction((mxc_i2c_reva_req_t *)req);
329 }
330 
MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t * req)331 int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req)
332 {
333     return MXC_I2C_RevA_MasterTransactionAsync((mxc_i2c_reva_req_t *)req);
334 }
335 
MXC_I2C_MasterTransactionDMA(mxc_i2c_req_t * req)336 int MXC_I2C_MasterTransactionDMA(mxc_i2c_req_t *req)
337 {
338     return MXC_I2C_RevA_MasterTransactionDMA((mxc_i2c_reva_req_t *)req, MXC_DMA);
339 }
340 
MXC_I2C_SlaveTransaction(mxc_i2c_regs_t * i2c,mxc_i2c_slave_handler_t callback)341 int MXC_I2C_SlaveTransaction(mxc_i2c_regs_t *i2c, mxc_i2c_slave_handler_t callback)
342 {
343     return MXC_I2C_RevA_SlaveTransaction((mxc_i2c_reva_regs_t *)i2c,
344                                          (mxc_i2c_reva_slave_handler_t)callback, interruptCheck);
345 }
346 
MXC_I2C_SlaveTransactionAsync(mxc_i2c_regs_t * i2c,mxc_i2c_slave_handler_t callback)347 int MXC_I2C_SlaveTransactionAsync(mxc_i2c_regs_t *i2c, mxc_i2c_slave_handler_t callback)
348 {
349     return MXC_I2C_RevA_SlaveTransactionAsync(
350         (mxc_i2c_reva_regs_t *)i2c, (mxc_i2c_reva_slave_handler_t)callback, interruptCheck);
351 }
352 
MXC_I2C_SetRXThreshold(mxc_i2c_regs_t * i2c,unsigned int numBytes)353 int MXC_I2C_SetRXThreshold(mxc_i2c_regs_t *i2c, unsigned int numBytes)
354 {
355     return MXC_I2C_RevA_SetRXThreshold((mxc_i2c_reva_regs_t *)i2c, numBytes);
356 }
357 
MXC_I2C_GetRXThreshold(mxc_i2c_regs_t * i2c)358 unsigned int MXC_I2C_GetRXThreshold(mxc_i2c_regs_t *i2c)
359 {
360     return MXC_I2C_RevA_GetRXThreshold((mxc_i2c_reva_regs_t *)i2c);
361 }
362 
MXC_I2C_SetTXThreshold(mxc_i2c_regs_t * i2c,unsigned int numBytes)363 int MXC_I2C_SetTXThreshold(mxc_i2c_regs_t *i2c, unsigned int numBytes)
364 {
365     return MXC_I2C_RevA_SetTXThreshold((mxc_i2c_reva_regs_t *)i2c, numBytes);
366 }
367 
MXC_I2C_GetTXThreshold(mxc_i2c_regs_t * i2c)368 unsigned int MXC_I2C_GetTXThreshold(mxc_i2c_regs_t *i2c)
369 {
370     return MXC_I2C_RevA_GetTXThreshold((mxc_i2c_reva_regs_t *)i2c);
371 }
372 
MXC_I2C_AsyncStop(mxc_i2c_regs_t * i2c)373 void MXC_I2C_AsyncStop(mxc_i2c_regs_t *i2c)
374 {
375     MXC_I2C_RevA_AsyncStop((mxc_i2c_reva_regs_t *)i2c);
376 }
377 
MXC_I2C_AbortAsync(mxc_i2c_regs_t * i2c)378 void MXC_I2C_AbortAsync(mxc_i2c_regs_t *i2c)
379 {
380     MXC_I2C_RevA_AbortAsync((mxc_i2c_reva_regs_t *)i2c);
381 }
382 
MXC_I2C_AsyncHandler(mxc_i2c_regs_t * i2c)383 void MXC_I2C_AsyncHandler(mxc_i2c_regs_t *i2c)
384 {
385     MXC_I2C_RevA_AsyncHandler((mxc_i2c_reva_regs_t *)i2c, interruptCheck);
386 }
387 
MXC_I2C_DMACallback(int ch,int error)388 void MXC_I2C_DMACallback(int ch, int error)
389 {
390     MXC_I2C_RevA_DMACallback(ch, error);
391 }
392