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