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