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 /* **** Definitions **** */
35 #define MXC_I2C_FASTPLUS_SPEED 1000000
36 
37 /* **** Variable Declaration **** */
38 uint32_t interruptCheck = MXC_F_I2C_INT_FL0_RD_ADDR_MATCH | MXC_F_I2C_INT_FL0_WR_ADDR_MATCH |
39                           MXC_F_I2C_INT_FL0_ADDR_MATCH | MXC_F_I2C_INT_FL0_DO_NOT_RESP_ER;
40 
41 /* **** Function Prototypes **** */
42 
43 /* ************************************************************************* */
44 /* Control/Configuration functions                                           */
45 /* ************************************************************************* */
MXC_I2C_Init(mxc_i2c_regs_t * i2c,int masterMode,unsigned int slaveAddr)46 int MXC_I2C_Init(mxc_i2c_regs_t *i2c, int masterMode, unsigned int slaveAddr)
47 {
48     if (i2c == NULL) {
49         return E_NULL_PTR;
50     }
51 
52     MXC_I2C_Shutdown(i2c); // Clear everything out
53 
54     if (i2c == MXC_I2C0) {
55         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C0);
56         MXC_GPIO_Config(&gpio_cfg_i2c0);
57     } else if (i2c == MXC_I2C1) {
58         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C1);
59         MXC_GPIO_Config(&gpio_cfg_i2c1);
60     } else if (i2c == MXC_I2C2) {
61         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C2);
62         MXC_GPIO_Config(&gpio_cfg_i2c2);
63     } else {
64         return E_NO_DEVICE;
65     }
66 
67     return MXC_I2C_RevA_Init((mxc_i2c_reva_regs_t *)i2c, masterMode, slaveAddr);
68 }
69 
MXC_I2C_SetSlaveAddr(mxc_i2c_regs_t * i2c,unsigned int slaveAddr,int idx)70 int MXC_I2C_SetSlaveAddr(mxc_i2c_regs_t *i2c, unsigned int slaveAddr, int idx)
71 {
72     if ((MXC_SYS_GetRev() & 0xF0) == 0xA0 && idx != 0) {
73         // MAX32570 Rev. A only supports one slave address
74         return E_NOT_SUPPORTED;
75     }
76 
77     return MXC_I2C_RevA_SetSlaveAddr((mxc_i2c_reva_regs_t *)i2c, slaveAddr, idx);
78 }
79 
MXC_I2C_Shutdown(mxc_i2c_regs_t * i2c)80 int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c)
81 {
82     // Configure GPIO for I2C
83     if (i2c == MXC_I2C0) {
84         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C0);
85     } else if (i2c == MXC_I2C1) {
86         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C1);
87     } else if (i2c == MXC_I2C2) {
88         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C2);
89     } else {
90         return E_NO_DEVICE;
91     }
92 
93     return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c);
94 }
95 
MXC_I2C_Reset(mxc_i2c_regs_t * i2c)96 int MXC_I2C_Reset(mxc_i2c_regs_t *i2c)
97 {
98     // Configure GPIO for I2C
99     if (i2c == MXC_I2C0) {
100         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_I2C0);
101     } else if (i2c == MXC_I2C1) {
102         MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C1);
103     } else if (i2c == MXC_I2C2) {
104         MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C2);
105     } else {
106         return E_NO_DEVICE;
107     }
108 
109     return E_NO_ERROR;
110 }
111 
MXC_I2C_SetFrequency(mxc_i2c_regs_t * i2c,unsigned int hz)112 int MXC_I2C_SetFrequency(mxc_i2c_regs_t *i2c, unsigned int hz)
113 {
114     // ME13 doesn't support high speed more
115     if (hz > MXC_I2C_FASTPLUS_SPEED) {
116         return E_NOT_SUPPORTED;
117     }
118 
119     return MXC_I2C_RevA_SetFrequency((mxc_i2c_reva_regs_t *)i2c, hz);
120 }
121 
MXC_I2C_GetFrequency(mxc_i2c_regs_t * i2c)122 unsigned int MXC_I2C_GetFrequency(mxc_i2c_regs_t *i2c)
123 {
124     return MXC_I2C_RevA_GetFrequency((mxc_i2c_reva_regs_t *)i2c);
125 }
126 
MXC_I2C_ReadyForSleep(mxc_i2c_regs_t * i2c)127 int MXC_I2C_ReadyForSleep(mxc_i2c_regs_t *i2c)
128 {
129     return MXC_I2C_RevA_ReadyForSleep((mxc_i2c_reva_regs_t *)i2c);
130 }
131 
MXC_I2C_SetClockStretching(mxc_i2c_regs_t * i2c,int enable)132 int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable)
133 {
134     return MXC_I2C_RevA_SetClockStretching((mxc_i2c_reva_regs_t *)i2c, enable);
135 }
136 
MXC_I2C_GetClockStretching(mxc_i2c_regs_t * i2c)137 int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c)
138 {
139     return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c);
140 }
141 
MXC_I2C_DMA_Init(mxc_i2c_regs_t * i2c,mxc_dma_regs_t * dma,bool use_dma_tx,bool use_dma_rx)142 int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx)
143 {
144     return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx,
145                                  use_dma_rx);
146 }
147 
MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t * i2c)148 int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c)
149 {
150     return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c);
151 }
152 
MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t * i2c)153 int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c)
154 {
155     return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c);
156 }
157 
MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t * i2c,uint8_t * txData,uint8_t * rxData)158 int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData)
159 {
160     int i2cNum;
161     int txReqSel = -1;
162     int rxReqSel = -1;
163 
164     if (i2c == NULL) {
165         return E_NULL_PTR;
166     }
167 
168     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
169 
170     if (txData != NULL) {
171         switch (i2cNum) {
172         case 0:
173             txReqSel = MXC_DMA_REQUEST_I2C0TX;
174             break;
175 
176         case 1:
177             txReqSel = MXC_DMA_REQUEST_I2C1TX;
178             break;
179 
180         case 2:
181             txReqSel = MXC_DMA_REQUEST_I2C2TX;
182             break;
183 
184         default:
185             return E_BAD_PARAM;
186         }
187     }
188 
189     if (rxData != NULL) {
190         switch (i2cNum) {
191         case 0:
192             rxReqSel = MXC_DMA_REQUEST_I2C0RX;
193             break;
194 
195         case 1:
196             rxReqSel = MXC_DMA_REQUEST_I2C1RX;
197             break;
198 
199         case 2:
200             rxReqSel = MXC_DMA_REQUEST_I2C2RX;
201             break;
202 
203         default:
204             return E_BAD_PARAM;
205         }
206     }
207 
208     return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c,
209                                              (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel);
210 }
211 
212 /* ************************************************************************* */
213 /* Low-level functions                                                       */
214 /* ************************************************************************* */
MXC_I2C_Start(mxc_i2c_regs_t * i2c)215 int MXC_I2C_Start(mxc_i2c_regs_t *i2c)
216 {
217     return MXC_I2C_RevA_Start((mxc_i2c_reva_regs_t *)i2c);
218 }
219 
MXC_I2C_Stop(mxc_i2c_regs_t * i2c)220 int MXC_I2C_Stop(mxc_i2c_regs_t *i2c)
221 {
222     return MXC_I2C_RevA_Stop((mxc_i2c_reva_regs_t *)i2c);
223 }
224 
MXC_I2C_WriteByte(mxc_i2c_regs_t * i2c,unsigned char byte)225 int MXC_I2C_WriteByte(mxc_i2c_regs_t *i2c, unsigned char byte)
226 {
227     return MXC_I2C_RevA_WriteByte((mxc_i2c_reva_regs_t *)i2c, byte);
228 }
229 
MXC_I2C_ReadByte(mxc_i2c_regs_t * i2c,unsigned char * byte,int ack)230 int MXC_I2C_ReadByte(mxc_i2c_regs_t *i2c, unsigned char *byte, int ack)
231 {
232     return MXC_I2C_RevA_ReadByte((mxc_i2c_reva_regs_t *)i2c, byte, ack);
233 }
234 
MXC_I2C_ReadByteInteractive(mxc_i2c_regs_t * i2c,unsigned char * byte,mxc_i2c_getAck_t getAck)235 int MXC_I2C_ReadByteInteractive(mxc_i2c_regs_t *i2c, unsigned char *byte, mxc_i2c_getAck_t getAck)
236 {
237     return MXC_I2C_RevA_ReadByteInteractive((mxc_i2c_reva_regs_t *)i2c, byte,
238                                             (mxc_i2c_reva_getAck_t)getAck);
239 }
240 
MXC_I2C_Write(mxc_i2c_regs_t * i2c,unsigned char * bytes,unsigned int * len)241 int MXC_I2C_Write(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len)
242 {
243     return MXC_I2C_RevA_Write((mxc_i2c_reva_regs_t *)i2c, bytes, len);
244 }
245 
MXC_I2C_Read(mxc_i2c_regs_t * i2c,unsigned char * bytes,unsigned int * len,int ack)246 int MXC_I2C_Read(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len, int ack)
247 {
248     return MXC_I2C_RevA_Read((mxc_i2c_reva_regs_t *)i2c, bytes, len, ack);
249 }
250 
MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t * i2c,volatile unsigned char * bytes,unsigned int len)251 int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsigned int len)
252 {
253     return MXC_I2C_RevA_ReadRXFIFO((mxc_i2c_reva_regs_t *)i2c, bytes, len);
254 }
255 
MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t * i2c,unsigned char * bytes,unsigned int len,mxc_i2c_dma_complete_cb_t callback)256 int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len,
257                           mxc_i2c_dma_complete_cb_t callback)
258 {
259     // The callback parameter was previously unused but keeping it for backwards-compatibility.
260     return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA);
261 }
262 
MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t * i2c)263 int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c)
264 {
265     return MXC_I2C_RevA_GetRXFIFOAvailable((mxc_i2c_reva_regs_t *)i2c);
266 }
267 
MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t * i2c,volatile unsigned char * bytes,unsigned int len)268 int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsigned int len)
269 {
270     return MXC_I2C_RevA_WriteTXFIFO((mxc_i2c_reva_regs_t *)i2c, bytes, len);
271 }
272 
MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t * i2c,unsigned char * bytes,unsigned int len,mxc_i2c_dma_complete_cb_t callback)273 int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len,
274                            mxc_i2c_dma_complete_cb_t callback)
275 {
276     // The callback parameter was previously unused but keeping it for backwards-compatibility.
277     return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA);
278 }
279 
MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t * i2c)280 int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c)
281 {
282     return MXC_I2C_RevA_GetTXFIFOAvailable((mxc_i2c_reva_regs_t *)i2c);
283 }
284 
MXC_I2C_ClearRXFIFO(mxc_i2c_regs_t * i2c)285 void MXC_I2C_ClearRXFIFO(mxc_i2c_regs_t *i2c)
286 {
287     MXC_I2C_RevA_ClearRXFIFO((mxc_i2c_reva_regs_t *)i2c);
288 }
289 
MXC_I2C_ClearTXFIFO(mxc_i2c_regs_t * i2c)290 void MXC_I2C_ClearTXFIFO(mxc_i2c_regs_t *i2c)
291 {
292     MXC_I2C_RevA_ClearTXFIFO((mxc_i2c_reva_regs_t *)i2c);
293 }
294 
MXC_I2C_GetFlags(mxc_i2c_regs_t * i2c,unsigned int * flags0,unsigned int * flags1)295 int MXC_I2C_GetFlags(mxc_i2c_regs_t *i2c, unsigned int *flags0, unsigned int *flags1)
296 {
297     return MXC_I2C_RevA_GetFlags((mxc_i2c_reva_regs_t *)i2c, flags0, flags1);
298 }
299 
MXC_I2C_ClearFlags(mxc_i2c_regs_t * i2c,unsigned int flags0,unsigned int flags1)300 void MXC_I2C_ClearFlags(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1)
301 {
302     MXC_I2C_RevA_ClearFlags((mxc_i2c_reva_regs_t *)i2c, flags0, flags1);
303 }
304 
MXC_I2C_EnableInt(mxc_i2c_regs_t * i2c,unsigned int flags0,unsigned int flags1)305 void MXC_I2C_EnableInt(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1)
306 {
307     MXC_I2C_RevA_EnableInt((mxc_i2c_reva_regs_t *)i2c, flags0, flags1);
308 }
309 
MXC_I2C_DisableInt(mxc_i2c_regs_t * i2c,unsigned int flags0,unsigned int flags1)310 void MXC_I2C_DisableInt(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1)
311 {
312     MXC_I2C_RevA_DisableInt((mxc_i2c_reva_regs_t *)i2c, flags0, flags1);
313 }
314 
MXC_I2C_EnablePreload(mxc_i2c_regs_t * i2c)315 void MXC_I2C_EnablePreload(mxc_i2c_regs_t *i2c)
316 {
317     MXC_I2C_RevA_EnablePreload((mxc_i2c_reva_regs_t *)i2c);
318 }
319 
MXC_I2C_DisablePreload(mxc_i2c_regs_t * i2c)320 void MXC_I2C_DisablePreload(mxc_i2c_regs_t *i2c)
321 {
322     MXC_I2C_RevA_DisablePreload((mxc_i2c_reva_regs_t *)i2c);
323 }
324 
MXC_I2C_EnableGeneralCall(mxc_i2c_regs_t * i2c)325 void MXC_I2C_EnableGeneralCall(mxc_i2c_regs_t *i2c)
326 {
327     MXC_I2C_RevA_EnableGeneralCall((mxc_i2c_reva_regs_t *)i2c);
328 }
329 
MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t * i2c)330 void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c)
331 {
332     MXC_I2C_RevA_DisableGeneralCall((mxc_i2c_reva_regs_t *)i2c);
333 }
334 
MXC_I2C_SetTimeout(mxc_i2c_regs_t * i2c,unsigned int timeout)335 void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout)
336 {
337     MXC_I2C_RevA_SetTimeout((mxc_i2c_reva_regs_t *)i2c, timeout);
338 }
339 
MXC_I2C_GetTimeout(mxc_i2c_regs_t * i2c)340 unsigned int MXC_I2C_GetTimeout(mxc_i2c_regs_t *i2c)
341 {
342     return MXC_I2C_RevA_GetTimeout((mxc_i2c_reva_regs_t *)i2c);
343 }
344 
MXC_I2C_Recover(mxc_i2c_regs_t * i2c,unsigned int retries)345 int MXC_I2C_Recover(mxc_i2c_regs_t *i2c, unsigned int retries)
346 {
347     return MXC_I2C_RevA_Recover((mxc_i2c_reva_regs_t *)i2c, retries);
348 }
349 
350 /* ************************************************************************* */
351 /* Transaction level functions                                               */
352 /* ************************************************************************* */
353 
MXC_I2C_MasterTransaction(mxc_i2c_req_t * req)354 int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req)
355 {
356     return MXC_I2C_RevA_MasterTransaction((mxc_i2c_reva_req_t *)req);
357 }
358 
MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t * req)359 int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req)
360 {
361     return MXC_I2C_RevA_MasterTransactionAsync((mxc_i2c_reva_req_t *)req);
362 }
363 
MXC_I2C_MasterTransactionDMA(mxc_i2c_req_t * req)364 int MXC_I2C_MasterTransactionDMA(mxc_i2c_req_t *req)
365 {
366     return MXC_I2C_RevA_MasterTransactionDMA((mxc_i2c_reva_req_t *)req, MXC_DMA);
367 }
368 
MXC_I2C_SlaveTransaction(mxc_i2c_regs_t * i2c,mxc_i2c_slave_handler_t callback)369 int MXC_I2C_SlaveTransaction(mxc_i2c_regs_t *i2c, mxc_i2c_slave_handler_t callback)
370 {
371     return MXC_I2C_RevA_SlaveTransaction((mxc_i2c_reva_regs_t *)i2c,
372                                          (mxc_i2c_reva_slave_handler_t)callback, interruptCheck);
373 }
374 
MXC_I2C_SlaveTransactionAsync(mxc_i2c_regs_t * i2c,mxc_i2c_slave_handler_t callback)375 int MXC_I2C_SlaveTransactionAsync(mxc_i2c_regs_t *i2c, mxc_i2c_slave_handler_t callback)
376 {
377     return MXC_I2C_RevA_SlaveTransactionAsync(
378         (mxc_i2c_reva_regs_t *)i2c, (mxc_i2c_reva_slave_handler_t)callback, interruptCheck);
379 }
380 
MXC_I2C_SetRXThreshold(mxc_i2c_regs_t * i2c,unsigned int numBytes)381 int MXC_I2C_SetRXThreshold(mxc_i2c_regs_t *i2c, unsigned int numBytes)
382 {
383     return MXC_I2C_RevA_SetRXThreshold((mxc_i2c_reva_regs_t *)i2c, numBytes);
384 }
385 
MXC_I2C_GetRXThreshold(mxc_i2c_regs_t * i2c)386 unsigned int MXC_I2C_GetRXThreshold(mxc_i2c_regs_t *i2c)
387 {
388     return MXC_I2C_RevA_GetRXThreshold((mxc_i2c_reva_regs_t *)i2c);
389 }
390 
MXC_I2C_SetTXThreshold(mxc_i2c_regs_t * i2c,unsigned int numBytes)391 int MXC_I2C_SetTXThreshold(mxc_i2c_regs_t *i2c, unsigned int numBytes)
392 {
393     return MXC_I2C_RevA_SetTXThreshold((mxc_i2c_reva_regs_t *)i2c, numBytes);
394 }
395 
MXC_I2C_GetTXThreshold(mxc_i2c_regs_t * i2c)396 unsigned int MXC_I2C_GetTXThreshold(mxc_i2c_regs_t *i2c)
397 {
398     return MXC_I2C_RevA_GetTXThreshold((mxc_i2c_reva_regs_t *)i2c);
399 }
400 
MXC_I2C_AsyncStop(mxc_i2c_regs_t * i2c)401 void MXC_I2C_AsyncStop(mxc_i2c_regs_t *i2c)
402 {
403     MXC_I2C_RevA_AsyncStop((mxc_i2c_reva_regs_t *)i2c);
404 }
405 
MXC_I2C_AbortAsync(mxc_i2c_regs_t * i2c)406 void MXC_I2C_AbortAsync(mxc_i2c_regs_t *i2c)
407 {
408     MXC_I2C_RevA_AbortAsync((mxc_i2c_reva_regs_t *)i2c);
409 }
410 
MXC_I2C_AsyncHandler(mxc_i2c_regs_t * i2c)411 void MXC_I2C_AsyncHandler(mxc_i2c_regs_t *i2c)
412 {
413     MXC_I2C_RevA_AsyncHandler((mxc_i2c_reva_regs_t *)i2c, interruptCheck);
414 }
415 
MXC_I2C_DMACallback(int ch,int error)416 void MXC_I2C_DMACallback(int ch, int error)
417 {
418     MXC_I2C_RevA_DMACallback(ch, error);
419 }
420