1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_i2c_drv.h"
9 
10 #ifndef HPM_I2C_DRV_DEFAULT_TPM
11 #define HPM_I2C_DRV_DEFAULT_TPM (0U)
12 #endif
13 
14 #ifndef HPM_I2C_DRV_DEFAULT_RETRY_COUNT
15 #define HPM_I2C_DRV_DEFAULT_RETRY_COUNT (5000U)
16 #endif
17 
18 #define period_in_100ps(freq) (10000000000UL / (freq))
19 
20 typedef struct {
21     uint32_t t_high;
22     uint32_t t_low;
23     uint16_t t_sp;
24     uint16_t t_sudat;
25     uint16_t t_hddat;
26     uint16_t t_sclhi;
27     uint16_t t_sclratio;
28 } i2c_timing_t;
29 
i2c_configure_timing(uint32_t src_clk_in_hz,i2c_mode_t i2c_mode,i2c_timing_t * timing)30 static hpm_stat_t i2c_configure_timing(uint32_t src_clk_in_hz,
31                                        i2c_mode_t i2c_mode,
32                                        i2c_timing_t *timing)
33 {
34     int32_t setup_time, hold_time, period;
35     int32_t temp1, temp2, temp3;
36     int32_t tpclk = period_in_100ps(src_clk_in_hz);
37 
38     switch (i2c_mode) {
39     /*
40      *          |Standard mode | Fast mode | Fast mode plus | Uint
41      * ---------+--------------+-----------+----------------+-------
42      *  t_high  |     4.0      |    0.6    |     0.26       |   us
43      *  t_low   |     4.7      |    1.3    |     0.5        |   us
44      *
45      */
46     /* time uint: 100ps */
47     case i2c_mode_fast:
48         timing->t_high = 6000;
49         timing->t_low = 13000;
50         timing->t_sclratio = 2;
51         setup_time = 1000;
52         hold_time = 3000;
53         period = period_in_100ps(400000); /**< baudrate 400KHz */
54         break;
55     case i2c_mode_fast_plus:
56         timing->t_high = 2600;
57         timing->t_low = 5000;
58         timing->t_sclratio = 2;
59         setup_time = 500;
60         hold_time = 0;
61         period = period_in_100ps(1000000); /**< baudrate 1MHz */
62         break;
63     case i2c_mode_normal:
64         timing->t_high = 40000;
65         timing->t_low = 47000;
66         timing->t_sclratio = 1;
67         setup_time = 2500;
68         hold_time = 3000;
69         period = period_in_100ps(100000); /**< baudrate 100KHz */
70         break;
71     default:
72         return status_i2c_not_supported;
73     }
74 
75     /*
76      * Spike Suppression | Standard | Fast mode | Fast mode plus | Uint
77      *                   | mode     |           |                |
78      * ------------------+----------+-----------+----------------+-------
79      *    t_sp (min)     |    -     |  0 - 50   |    0 - 50      |   ns
80      *
81      * T_SP = 50ns / (tpclk * (TPM + 1))
82      */
83     timing->t_sp = 500 / period_in_100ps(src_clk_in_hz) / (HPM_I2C_DRV_DEFAULT_TPM + 1);
84 
85     /*
86      * Setup time       |Standard mode | Fast mode | Fast mode plus | Uint
87      * -----------------+--------------+-----------+----------------+-------
88      *  t_sudat (min)   |     250      |    100    |     50         |   ns
89      *
90      * Setup time = (2 * tpclk) + (2 + T_SP + T_SUDAT) * tpclk * (TPM + 1)
91      */
92     temp1 = (setup_time - 2 * tpclk) / tpclk / (HPM_I2C_DRV_DEFAULT_TPM + 1) - 2 - timing->t_sp;
93     timing->t_sudat = MAX(temp1, 0);
94     /*
95      * Hold time       |Standard mode | Fast mode | Fast mode plus | Uint
96      * ----------------+--------------+-----------+----------------+-------
97      *  t_hddata (min) |     300      |    300    |     0          |   ns
98      *
99      * Hold time = (2 * tpclk) + (2 + T_SP + T_HDDAT) * tpclk * (TPM + 1)
100      */
101     temp1 = (hold_time - 2 * tpclk) / tpclk / (HPM_I2C_DRV_DEFAULT_TPM + 1) - 2 - timing->t_sp;
102     timing->t_hddat = MAX(temp1, 0);
103 
104     /*
105      * SCLK High period = (2 * tpclk) + (2 + T_SP + T_SCLHi) * tpclk * (TPM + 1) > t_high;
106      */
107     temp1 = (timing->t_high - 2 * tpclk) / tpclk / (HPM_I2C_DRV_DEFAULT_TPM + 1) - 2 - timing->t_sp;
108 
109     /*
110      * SCLK High period = (2 * tpclk) + (2 + T_SP + T_SCLHi) * tpclk * (TPM + 1) > period / (1 + ratio);
111      */
112     temp2 = (period / (1 + timing->t_sclratio) - 2 * tpclk) / tpclk / (HPM_I2C_DRV_DEFAULT_TPM + 1) - 2 - timing->t_sp;
113 
114     /*
115      * SCLK Low period = (2 * tpclk) + (2 + T_SP + T_SCLHi * ratio) * tpclk * (TPM + 1) > t_low;
116      */
117     temp3 = ((timing->t_low - 2 * tpclk) / tpclk / (HPM_I2C_DRV_DEFAULT_TPM + 1) - 2 - timing->t_sp) / (timing->t_sclratio);
118 
119     timing->t_sclhi = MAX(MAX(temp1, temp2), temp3);
120 
121     /* update high_period and low_period to calculated value */
122     timing->t_high = 2 * tpclk + (2 + timing->t_sp + timing->t_sclhi) * tpclk;
123     timing->t_low = timing->t_high * timing->t_sclratio;
124 
125     return status_success;
126 }
127 
i2c_reset(I2C_Type * ptr)128 void i2c_reset(I2C_Type *ptr)
129 {
130     ptr->CTRL = 0;
131     ptr->CMD = I2C_CMD_RESET;
132     ptr->SETUP &= ~I2C_SETUP_IICEN_MASK;
133 }
134 
i2c_init_master(I2C_Type * ptr,uint32_t src_clk_in_hz,i2c_config_t * config)135 hpm_stat_t i2c_init_master(I2C_Type *ptr, uint32_t src_clk_in_hz, i2c_config_t *config)
136 {
137     hpm_stat_t stat = status_success;
138     i2c_timing_t timing = {0};
139 
140     i2c_reset(ptr);
141 
142     stat = i2c_configure_timing(src_clk_in_hz, config->i2c_mode, &timing);
143     if (status_success != stat) {
144         return stat;
145     }
146 
147     ptr->TPM = I2C_TPM_TPM_SET(HPM_I2C_DRV_DEFAULT_TPM);
148 
149     ptr->SETUP = I2C_SETUP_T_SP_SET(timing.t_sp)
150         | I2C_SETUP_T_SUDAT_SET(timing.t_sudat)
151         | I2C_SETUP_T_HDDAT_SET(timing.t_hddat)
152         | I2C_SETUP_T_SCLRADIO_SET(timing.t_sclratio - 1)
153         | I2C_SETUP_T_SCLHI_SET(timing.t_sclhi)
154         | I2C_SETUP_ADDRESSING_SET(config->is_10bit_addressing)
155         | I2C_SETUP_IICEN_MASK
156         | I2C_SETUP_MASTER_MASK;
157 
158     return status_success;
159 }
160 
i2c_master_address_read(I2C_Type * ptr,const uint16_t device_address,uint8_t * addr,uint32_t addr_size_in_byte,uint8_t * buf,const uint32_t size_in_byte)161 hpm_stat_t i2c_master_address_read(I2C_Type *ptr, const uint16_t device_address,
162                                    uint8_t *addr, uint32_t addr_size_in_byte,
163                                    uint8_t *buf, const uint32_t size_in_byte)
164 {
165     hpm_stat_t stat = status_success;
166     uint32_t left;
167     uint32_t retry;
168     if (((addr_size_in_byte == 0) || (addr_size_in_byte > I2C_SOC_TRANSFER_COUNT_MAX)) ||
169         ((size_in_byte == 0) || (size_in_byte > I2C_SOC_TRANSFER_COUNT_MAX))) {
170         return status_invalid_argument;
171     }
172 
173     retry = 0;
174     while (ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
175         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
176             break;
177         }
178         retry++;
179     }
180     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
181         return status_timeout;
182     }
183 
184     /* W1C, clear CMPL bit to avoid blocking the transmission */
185     ptr->STATUS = I2C_STATUS_CMPL_MASK;
186 
187     ptr->CMD = I2C_CMD_CLEAR_FIFO;
188     ptr->CTRL = I2C_CTRL_PHASE_START_MASK
189         | I2C_CTRL_PHASE_ADDR_MASK
190         | I2C_CTRL_PHASE_DATA_MASK
191         | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE)
192 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
193         | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(addr_size_in_byte) >> 8U)
194 #endif
195         | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(addr_size_in_byte));
196 
197     ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
198 
199     left = addr_size_in_byte;
200     while (left) {
201         ptr->DATA = *(addr++);
202         left--;
203     }
204     ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
205 
206     /* Before starting to transmit data, judge addrhit to ensure that the slave address exists on the bus. */
207     retry = 0;
208     while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
209         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
210             break;
211         }
212         retry++;
213     }
214     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
215         /* the address misses, a stop needs to be added to prevent the bus from being busy. */
216         ptr->STATUS = I2C_STATUS_CMPL_MASK;
217         ptr->CTRL = I2C_CTRL_PHASE_STOP_MASK;
218         ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
219         return status_i2c_no_addr_hit;
220     }
221     ptr->STATUS = I2C_STATUS_ADDRHIT_MASK;
222 
223     retry = 0;
224     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
225         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
226             break;
227         }
228         retry++;
229     }
230     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
231         return status_timeout;
232     }
233     /* W1C, clear CMPL bit to avoid blocking the transmission */
234     ptr->STATUS = I2C_STATUS_CMPL_MASK;
235 
236     ptr->CMD = I2C_CMD_CLEAR_FIFO;
237     ptr->CTRL = I2C_CTRL_PHASE_START_MASK
238         | I2C_CTRL_PHASE_STOP_MASK
239         | I2C_CTRL_PHASE_ADDR_MASK
240         | I2C_CTRL_PHASE_DATA_MASK
241         | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ)
242 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
243         | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(addr_size_in_byte) >> 8U)
244 #endif
245         | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size_in_byte));
246     ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
247 
248     retry = 0;
249     left = size_in_byte;
250     while (left) {
251         if (!(ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK)) {
252             *(buf++) = ptr->DATA;
253             left--;
254             retry = 0;
255         } else {
256             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
257                 break;
258             }
259             retry++;
260         }
261     }
262 
263     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
264         return status_timeout;
265     }
266 
267     retry = 0;
268     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
269         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
270             break;
271         }
272         retry++;
273     }
274     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
275         return status_timeout;
276     }
277     return stat;
278 }
279 
i2c_master_address_write(I2C_Type * ptr,const uint16_t device_address,uint8_t * addr,uint32_t addr_size_in_byte,uint8_t * buf,const uint32_t size_in_byte)280 hpm_stat_t i2c_master_address_write(I2C_Type *ptr, const uint16_t device_address,
281                                     uint8_t *addr, uint32_t addr_size_in_byte,
282                                     uint8_t *buf, const uint32_t size_in_byte)
283 {
284     hpm_stat_t stat = status_success;
285     uint32_t left;
286     uint32_t retry;
287 
288     if (((addr_size_in_byte == 0) || (addr_size_in_byte > I2C_SOC_TRANSFER_COUNT_MAX)) ||
289         ((size_in_byte == 0) || (size_in_byte > I2C_SOC_TRANSFER_COUNT_MAX)) ||
290         ((addr_size_in_byte + size_in_byte) > I2C_SOC_TRANSFER_COUNT_MAX)) {
291         return status_invalid_argument;
292     }
293 
294     retry = 0;
295     while (ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
296         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
297             break;
298         }
299         retry++;
300     }
301     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
302         return status_timeout;
303     }
304 
305     /* W1C, clear CMPL bit to avoid blocking the transmission */
306     ptr->STATUS = I2C_STATUS_CMPL_MASK;
307 
308     ptr->CMD = I2C_CMD_CLEAR_FIFO;
309     ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
310     ptr->CTRL = I2C_CTRL_PHASE_START_MASK
311         | I2C_CTRL_PHASE_STOP_MASK
312         | I2C_CTRL_PHASE_ADDR_MASK
313         | I2C_CTRL_PHASE_DATA_MASK
314         | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE)
315 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
316         | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size_in_byte + addr_size_in_byte) >> 8U)
317 #endif
318         | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size_in_byte + addr_size_in_byte));
319 
320     left = addr_size_in_byte;
321     while (left) {
322         ptr->DATA = *(addr++);
323         left--;
324     }
325     ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
326 
327     /* Before starting to transmit data, judge addrhit to ensure that the slave address exists on the bus. */
328     retry = 0;
329     while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
330         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
331             break;
332         }
333         retry++;
334     }
335     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
336         return status_i2c_no_addr_hit;
337     }
338     ptr->STATUS = I2C_STATUS_ADDRHIT_MASK;
339 
340     retry = 0;
341     left = size_in_byte;
342     while (left) {
343         if (!(ptr->STATUS & I2C_STATUS_FIFOFULL_MASK)) {
344             ptr->DATA = *(buf++);
345             left--;
346             retry = 0;
347         } else {
348             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
349                 break;
350             }
351             retry++;
352         }
353     }
354     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
355         return status_timeout;
356     }
357 
358     retry = 0;
359     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
360         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
361             break;
362         } else {
363             retry++;
364         }
365     }
366 
367     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
368         return status_timeout;
369     }
370 
371     return stat;
372 }
373 
i2c_master_read(I2C_Type * ptr,const uint16_t device_address,uint8_t * buf,const uint32_t size)374 hpm_stat_t i2c_master_read(I2C_Type *ptr, const uint16_t device_address,
375                            uint8_t *buf, const uint32_t size)
376 {
377     hpm_stat_t stat = status_success;
378     uint32_t left;
379     uint32_t retry;
380     if (size > I2C_SOC_TRANSFER_COUNT_MAX) {
381         return status_invalid_argument;
382     }
383 
384     retry = 0;
385     while (ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
386         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
387             break;
388         }
389         retry++;
390     }
391     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
392         return status_timeout;
393     }
394 
395     /* W1C, clear CMPL bit to avoid blocking the transmission */
396     ptr->STATUS = I2C_STATUS_CMPL_MASK;
397 
398     ptr->CMD = I2C_CMD_CLEAR_FIFO;
399     ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
400     ptr->CTRL = I2C_CTRL_PHASE_START_MASK
401         | I2C_CTRL_PHASE_STOP_MASK
402         | I2C_CTRL_PHASE_ADDR_MASK
403         | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ);
404     if (size > 0) {
405         ptr->CTRL |= I2C_CTRL_PHASE_DATA_MASK
406 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
407             | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
408 #endif
409             | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
410     }
411     ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
412 
413     /* Before starting to transmit data, judge addrhit to ensure that the slave address exists on the bus. */
414     retry = 0;
415     while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
416         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
417             break;
418         }
419         retry++;
420     }
421     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
422         return status_i2c_no_addr_hit;
423     }
424     ptr->STATUS = I2C_STATUS_ADDRHIT_MASK;
425     /* when size is zero, it's probe slave device, so directly return success */
426     if (size == 0) {
427         return status_success;
428     }
429 
430     retry = 0;
431     left = size;
432     while (left) {
433         if (!(ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK)) {
434             *(buf++) = ptr->DATA;
435             left--;
436             retry = 0;
437         } else {
438             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
439                 break;
440             }
441             retry++;
442         }
443     }
444     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
445         return status_timeout;
446     }
447 
448     retry = 0;
449     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
450         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
451             break;
452         }
453         retry++;
454     };
455     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
456         return status_timeout;
457     }
458 
459     if (i2c_get_data_count(ptr) && (size)) {
460         return status_i2c_transmit_not_completed;
461     }
462 
463     return stat;
464 }
465 
i2c_master_write(I2C_Type * ptr,const uint16_t device_address,uint8_t * buf,const uint32_t size)466 hpm_stat_t i2c_master_write(I2C_Type *ptr, const uint16_t device_address,
467                             uint8_t *buf, const uint32_t size)
468 {
469     hpm_stat_t stat = status_success;
470     uint32_t retry;
471     uint32_t left;
472 
473     if (size > I2C_SOC_TRANSFER_COUNT_MAX) {
474         return status_invalid_argument;
475     }
476 
477     retry = 0;
478     while (ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
479         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
480             break;
481         }
482         retry++;
483     }
484     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
485         return status_timeout;
486     }
487 
488     /* W1C, clear CMPL bit to avoid blocking the transmission */
489     ptr->STATUS = I2C_STATUS_CMPL_MASK;
490 
491     ptr->CMD = I2C_CMD_CLEAR_FIFO;
492     ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
493     ptr->CTRL = I2C_CTRL_PHASE_START_MASK
494         | I2C_CTRL_PHASE_STOP_MASK
495         | I2C_CTRL_PHASE_ADDR_MASK
496         | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE);
497     if (size > 0) {
498         ptr->CTRL |= I2C_CTRL_PHASE_DATA_MASK
499 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
500             | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
501 #endif
502             | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
503     }
504     ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
505 
506     /* Before starting to transmit data, judge addrhit to ensure that the slave address exists on the bus. */
507     retry = 0;
508     while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
509         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
510             break;
511         }
512         retry++;
513     }
514     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
515         return status_i2c_no_addr_hit;
516     }
517     ptr->STATUS = I2C_STATUS_ADDRHIT_MASK;
518     /* when size is zero, it's probe slave device, so directly return success */
519     if (size == 0) {
520         return status_success;
521     }
522 
523     retry = 0;
524     left = size;
525     while (left) {
526         if (!(ptr->STATUS & I2C_STATUS_FIFOFULL_MASK)) {
527             ptr->DATA = *(buf++);
528             left--;
529             retry = 0;
530         } else {
531             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
532                 break;
533             }
534             retry++;
535         }
536     }
537     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
538         return status_timeout;
539     }
540 
541     retry = 0;
542     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
543         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
544             break;
545         }
546         retry++;
547     }
548     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
549         return status_timeout;
550     }
551 
552     if (i2c_get_data_count(ptr) && (size)) {
553         return status_i2c_transmit_not_completed;
554     }
555 
556     return stat;
557 }
558 
i2c_init_slave(I2C_Type * ptr,uint32_t src_clk_in_hz,i2c_config_t * config,const uint16_t slave_address)559 hpm_stat_t i2c_init_slave(I2C_Type *ptr, uint32_t src_clk_in_hz,
560                           i2c_config_t *config, const uint16_t slave_address)
561 {
562     hpm_stat_t stat = status_success;
563     i2c_timing_t timing = {0};
564 
565     i2c_reset(ptr);
566 
567     ptr->ADDR = I2C_ADDR_ADDR_SET(slave_address);
568 
569     stat = i2c_configure_timing(src_clk_in_hz, config->i2c_mode, &timing);
570     if (status_success != stat) {
571         return stat;
572     }
573 
574     ptr->TPM = I2C_TPM_TPM_SET(HPM_I2C_DRV_DEFAULT_TPM);
575 
576     ptr->SETUP = I2C_SETUP_T_SP_SET(timing.t_sp)
577         | I2C_SETUP_T_SUDAT_SET(timing.t_sudat)
578         | I2C_SETUP_T_HDDAT_SET(timing.t_hddat)
579         | I2C_SETUP_T_SCLRADIO_SET(timing.t_sclratio - 1)
580         | I2C_SETUP_T_SCLHI_SET(timing.t_sclhi)
581         | I2C_SETUP_ADDRESSING_SET(config->is_10bit_addressing)
582         | I2C_SETUP_IICEN_MASK;
583 
584     return stat;
585 }
586 
i2c_slave_write(I2C_Type * ptr,uint8_t * buf,const uint32_t size)587 hpm_stat_t i2c_slave_write(I2C_Type *ptr, uint8_t *buf, const uint32_t size)
588 {
589     volatile uint32_t status;
590     uint32_t retry;
591     uint32_t left;
592 
593     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
594         return status_invalid_argument;
595     }
596 
597     /* wait for address hit */
598     retry = 0;
599     while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
600         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
601             break;
602         }
603         retry++;
604     }
605     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
606         return status_fail;
607     }
608 
609     /* W1C, clear CMPL bit and clear ADDRHIT bit to avoid blocking the transmission */
610     ptr->STATUS = I2C_STATUS_CMPL_MASK | I2C_STATUS_ADDRHIT_MASK;
611     ptr->CMD = I2C_CMD_CLEAR_FIFO;
612 
613     retry = 0;
614     left = size;
615     while (left) {
616         status = ptr->STATUS;
617         if (!(status & I2C_STATUS_FIFOFULL_MASK)) {
618             ptr->DATA = *(buf++);
619             left--;
620             retry = 0;
621         } else {
622             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
623                 break;
624             }
625             retry++;
626         }
627     }
628     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
629         return status_timeout;
630     }
631 
632     retry = 0;
633     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
634         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
635             break;
636         }
637         retry++;
638     }
639     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
640         return status_timeout;
641     }
642     /* clear status, CMPL must to be cleared at slave mode before next transaction */
643     ptr->STATUS = I2C_STATUS_CMPL_MASK;
644 
645     if (i2c_get_data_count(ptr) != size) {
646         return status_i2c_transmit_not_completed;
647     }
648 
649     return status_success;
650 }
651 
i2c_slave_read(I2C_Type * ptr,uint8_t * buf,const uint32_t size)652 hpm_stat_t i2c_slave_read(I2C_Type *ptr,
653                           uint8_t *buf,
654                           const uint32_t size)
655 {
656     volatile uint32_t status;
657     uint32_t retry;
658     uint32_t left;
659 
660     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
661         return status_invalid_argument;
662     }
663 
664     /* wait for address hit */
665     retry = 0;
666     while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
667         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
668             break;
669         }
670         retry++;
671     }
672     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
673         return status_fail;
674     }
675 
676     /* W1C, clear CMPL bit and clear ADDRHIT bit to avoid blocking the transmission */
677     ptr->STATUS = I2C_STATUS_CMPL_MASK | I2C_STATUS_ADDRHIT_MASK;
678     ptr->CMD = I2C_CMD_CLEAR_FIFO;
679 
680     retry = 0;
681     left = size;
682     while (left) {
683         status = ptr->STATUS;
684         if (!(status & I2C_STATUS_FIFOEMPTY_MASK)) {
685             *(buf++) = ptr->DATA;
686             left--;
687             retry = 0;
688         } else {
689             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
690                 break;
691             }
692             retry++;
693         }
694     }
695     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
696         return status_timeout;
697     }
698 
699     retry = 0;
700     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
701         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
702             break;
703         }
704         retry++;
705     }
706     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
707         return status_timeout;
708     }
709     /* clear status, CMPL must to be cleared at slave mode before next transaction */
710     ptr->STATUS = I2C_STATUS_CMPL_MASK;
711 
712     if (i2c_get_data_count(ptr) != size) {
713         return status_i2c_transmit_not_completed;
714     }
715 
716     return status_success;
717 }
718 
i2c_master_start_dma_write(I2C_Type * i2c_ptr,const uint16_t device_address,uint32_t size)719 hpm_stat_t i2c_master_start_dma_write(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size)
720 {
721     uint32_t retry = 0;
722     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
723         return status_invalid_argument;
724     }
725 
726     while (i2c_ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
727         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
728             break;
729         }
730         retry++;
731     }
732     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
733         return status_timeout;
734     }
735 
736     /* W1C, clear CMPL bit to avoid blocking the transmission */
737     i2c_ptr->STATUS = I2C_STATUS_CMPL_MASK;
738 
739     i2c_ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
740     i2c_ptr->CTRL = I2C_CTRL_PHASE_START_MASK
741         | I2C_CTRL_PHASE_STOP_MASK
742         | I2C_CTRL_PHASE_ADDR_MASK
743         | I2C_CTRL_PHASE_DATA_MASK
744         | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE)
745 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
746         | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
747 #endif
748         | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
749 
750     i2c_ptr->SETUP |= I2C_SETUP_DMAEN_MASK;
751 
752     i2c_ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
753 
754     return status_success;
755 }
756 
i2c_master_start_dma_read(I2C_Type * i2c_ptr,const uint16_t device_address,uint32_t size)757 hpm_stat_t i2c_master_start_dma_read(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size)
758 {
759     uint32_t retry = 0;
760     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
761         return status_invalid_argument;
762     }
763 
764     while (i2c_ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
765         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
766             break;
767         }
768         retry++;
769     }
770     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
771         return status_timeout;
772     }
773     /* W1C, clear CMPL bit to avoid blocking the transmission */
774     i2c_ptr->STATUS = I2C_STATUS_CMPL_MASK;
775 
776     i2c_ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
777     i2c_ptr->CTRL = I2C_CTRL_PHASE_START_MASK
778         | I2C_CTRL_PHASE_STOP_MASK
779         | I2C_CTRL_PHASE_ADDR_MASK
780         | I2C_CTRL_PHASE_DATA_MASK
781         | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ)
782 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
783         | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
784 #endif
785         | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
786 
787     i2c_ptr->SETUP |= I2C_SETUP_DMAEN_MASK;
788 
789     i2c_ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
790 
791     return status_success;
792 }
793 
i2c_slave_dma_transfer(I2C_Type * i2c_ptr,uint32_t size)794 hpm_stat_t i2c_slave_dma_transfer(I2C_Type *i2c_ptr, uint32_t size)
795 {
796     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
797         return status_invalid_argument;
798     }
799 
800     /* W1C, clear CMPL bit to avoid blocking the transmission */
801     i2c_ptr->STATUS = I2C_STATUS_CMPL_MASK;
802 
803 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
804     i2c_ptr->CTRL &= ~(I2C_CTRL_DATACNT_HIGH_MASK | I2C_CTRL_DATACNT_MASK);
805     i2c_ptr->CTRL |= I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U) | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
806 #else
807     i2c_ptr->CTRL &= ~I2C_CTRL_DATACNT_MASK;
808     i2c_ptr->CTRL |= I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
809 #endif
810 
811     i2c_ptr->SETUP |= I2C_SETUP_DMAEN_MASK;
812 
813     return status_success;
814 }
815 
i2c_master_configure_transfer(I2C_Type * i2c_ptr,const uint16_t device_address,uint32_t size,bool read)816 hpm_stat_t i2c_master_configure_transfer(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size, bool read)
817 {
818     uint32_t retry = 0;
819     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
820         return status_invalid_argument;
821     }
822 
823     while (i2c_ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
824         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
825             break;
826         }
827         retry++;
828     }
829     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
830         return status_timeout;
831     }
832     /* W1C, clear CMPL bit to avoid blocking the transmission */
833     i2c_ptr->STATUS = I2C_STATUS_CMPL_MASK;
834     i2c_ptr->CMD = I2C_CMD_CLEAR_FIFO;
835     i2c_ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
836     i2c_ptr->CTRL = I2C_CTRL_PHASE_START_MASK
837                 | I2C_CTRL_PHASE_STOP_MASK
838                 | I2C_CTRL_PHASE_ADDR_MASK
839                 | I2C_CTRL_PHASE_DATA_MASK
840                 | I2C_CTRL_DIR_SET(read)
841 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
842                 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
843 #endif
844                 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
845 
846     i2c_ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
847 
848     return status_success;
849 }
850 
i2c_master_seq_transmit(I2C_Type * ptr,const uint16_t device_address,uint8_t * buf,const uint32_t size,i2c_seq_transfer_opt_t opt)851 hpm_stat_t i2c_master_seq_transmit(I2C_Type *ptr, const uint16_t device_address,
852                                     uint8_t *buf, const uint32_t size, i2c_seq_transfer_opt_t opt)
853 {
854     uint32_t ctrl;
855     uint32_t retry = 0;
856     uint32_t left = 0;
857 
858     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
859         return status_invalid_argument;
860     }
861 
862     /* W1C, clear CMPL bit to avoid blocking the transmission */
863     ptr->STATUS = I2C_STATUS_CMPL_MASK;
864     ptr->CMD = I2C_CMD_CLEAR_FIFO;
865     ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
866 
867     switch (opt) {
868     case i2c_frist_frame:
869         ctrl = I2C_CTRL_PHASE_START_SET(true) | I2C_CTRL_PHASE_STOP_SET(false) \
870                | I2C_CTRL_PHASE_ADDR_SET(true);
871         break;
872     case i2c_next_frame:
873         ctrl = I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(false) \
874                | I2C_CTRL_PHASE_ADDR_SET(false);
875         break;
876     case i2c_last_frame:
877         ctrl = I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(true) \
878                | I2C_CTRL_PHASE_ADDR_SET(false);
879         break;
880     default:
881         return status_invalid_argument;
882     }
883 
884     ptr->CTRL = ctrl | I2C_CTRL_PHASE_DATA_SET(true)
885                 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE)
886 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
887                 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
888 #endif
889                 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
890     /* enable auto ack */
891     ptr->INTEN &= ~I2C_EVENT_BYTE_RECEIVED;
892     ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
893 
894     retry = 0;
895     left = size;
896     while (left) {
897         if (!(ptr->STATUS & I2C_STATUS_FIFOFULL_MASK)) {
898             ptr->DATA = *(buf++);
899             left--;
900             retry = 0;
901         } else {
902             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
903                 break;
904             }
905             retry++;
906         }
907     }
908     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
909         return status_timeout;
910     }
911 
912     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
913         return status_timeout;
914     }
915     retry = 0;
916     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
917         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
918             break;
919         }
920         retry++;
921     }
922     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
923         return status_timeout;
924     }
925     /* clear status, CMPL must to be cleared at slave mode before next transaction */
926     ptr->STATUS = I2C_STATUS_CMPL_MASK;
927     return status_success;
928 }
929 
i2c_master_seq_receive(I2C_Type * ptr,const uint16_t device_address,uint8_t * buf,const uint32_t size,i2c_seq_transfer_opt_t opt)930 hpm_stat_t i2c_master_seq_receive(I2C_Type *ptr, const uint16_t device_address,
931                                     uint8_t *buf, const uint32_t size, i2c_seq_transfer_opt_t opt)
932 {
933    uint32_t ctrl;
934     uint32_t retry = 0;
935     uint32_t left = 0;
936 
937     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
938         return status_invalid_argument;
939     }
940 
941     /* W1C, clear CMPL bit to avoid blocking the transmission */
942     ptr->STATUS = I2C_STATUS_CMPL_MASK;
943     ptr->CMD = I2C_CMD_CLEAR_FIFO;
944     ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
945 
946     switch (opt) {
947     case i2c_frist_frame:
948         ctrl = I2C_CTRL_PHASE_START_SET(true) | I2C_CTRL_PHASE_STOP_SET(false) \
949                | I2C_CTRL_PHASE_ADDR_SET(true);
950         break;
951     case i2c_next_frame:
952         ctrl = I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(false) \
953                | I2C_CTRL_PHASE_ADDR_SET(false);
954         break;
955     case i2c_last_frame:
956         ctrl = I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(true) \
957                | I2C_CTRL_PHASE_ADDR_SET(false);
958         break;
959     default:
960         return status_invalid_argument;
961     }
962 
963     ptr->CTRL = ctrl | I2C_CTRL_PHASE_DATA_SET(true)
964                 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ)
965 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
966                 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
967 #endif
968                 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
969 
970     /* disable auto ack */
971     ptr->INTEN |= I2C_EVENT_BYTE_RECEIVED;
972     ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
973 
974     retry = 0;
975     left = size;
976     while (left) {
977         if (!(ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK)) {
978             *(buf++) = ptr->DATA;
979             left--;
980             if ((left == 0) && (opt == i2c_last_frame)) {
981                 ptr->CMD = I2C_CMD_NACK;
982             } else {
983                 ptr->CMD = I2C_CMD_ACK;
984             }
985             retry = 0;
986         } else {
987             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
988                 break;
989             }
990             retry++;
991         }
992     }
993     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
994         return status_timeout;
995     }
996 
997     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
998         return status_timeout;
999     }
1000     if (opt  == i2c_last_frame) {
1001         retry = 0;
1002         while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
1003             if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
1004                 break;
1005             }
1006             retry++;
1007         }
1008         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
1009             return status_timeout;
1010         }
1011     }
1012     /* clear status, CMPL must to be cleared at slave mode before next transaction */
1013     ptr->STATUS = I2C_STATUS_CMPL_MASK;
1014     /* default auto ack */
1015     ptr->INTEN &= ~I2C_EVENT_BYTE_RECEIVED;
1016 
1017     return status_success;
1018 }
1019 
i2c_master_transfer(I2C_Type * ptr,const uint16_t device_address,uint8_t * buf,const uint32_t size,uint16_t flags)1020 hpm_stat_t i2c_master_transfer(I2C_Type *ptr, const uint16_t device_address,
1021                                     uint8_t *buf, const uint32_t size,  uint16_t flags)
1022 {
1023     uint32_t ctrl = 0;
1024     uint32_t retry = 0;
1025     uint32_t left = 0;
1026     if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
1027         return status_invalid_argument;
1028     }
1029     if (flags & I2C_ADDR_10BIT) {
1030         i2c_enable_10bit_address_mode(ptr, true);
1031     } else {
1032         i2c_enable_10bit_address_mode(ptr, false);
1033     }
1034     /* W1C, clear CMPL bit to avoid blocking the transmission */
1035     ptr->STATUS = I2C_STATUS_CMPL_MASK;
1036     ptr->CMD = I2C_CMD_CLEAR_FIFO;
1037     ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
1038 
1039     if (flags & I2C_RD) {
1040         ctrl |= I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ);
1041     } else {
1042         ctrl |= I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE);/* is write flag */
1043     }
1044     /* start signal */
1045     if (flags & I2C_NO_START) {
1046         ctrl |= I2C_CTRL_PHASE_START_SET(false);
1047     } else {
1048         ctrl |= I2C_CTRL_PHASE_START_SET(true);
1049     }
1050     /* end signal*/
1051     if (flags & I2C_NO_STOP) {
1052         ctrl |= I2C_CTRL_PHASE_STOP_SET(false);
1053     } else {
1054         ctrl |= I2C_CTRL_PHASE_STOP_SET(true);
1055     }
1056 
1057     ptr->CTRL = ctrl | I2C_CTRL_PHASE_DATA_SET(true)
1058                 | I2C_CTRL_PHASE_ADDR_SET(true)
1059 #ifdef I2C_CTRL_DATACNT_HIGH_MASK
1060                 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
1061 #endif
1062                 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
1063     /* disable auto ack */
1064     ptr->INTEN |= I2C_EVENT_BYTE_RECEIVED;
1065     ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
1066     retry = 0;
1067     left = size;
1068     if (flags & I2C_RD) {
1069         while (left) {
1070             if (!(ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK)) {
1071                 *(buf++) = ptr->DATA;
1072                 left--;
1073                 if (left == 0) {
1074                     ptr->CMD = I2C_CMD_NACK;
1075                 } else {
1076                     /* ACK is sent when reading */
1077                     if (!(flags & I2C_NO_READ_ACK)) {
1078                         ptr->CMD = I2C_CMD_ACK;
1079                     }
1080                 }
1081                 retry = 0;
1082             } else {
1083                 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
1084                     break;
1085                 }
1086                 retry++;
1087             }
1088         }
1089         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
1090             return status_timeout;
1091         }
1092     } else {
1093         while (left) {
1094             if (!(ptr->STATUS & I2C_STATUS_FIFOFULL_MASK)) {
1095                 ptr->DATA = *(buf++);
1096                 left--;
1097                 retry = 0;
1098             } else {
1099                 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
1100                     break;
1101                 }
1102                 retry++;
1103             }
1104         }
1105         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
1106             return status_timeout;
1107         }
1108     }
1109     retry = 0;
1110     while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
1111         if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
1112             break;
1113         }
1114         retry++;
1115     }
1116     if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
1117         return status_timeout;
1118     }
1119 
1120     if (i2c_get_data_count(ptr) && (size)) {
1121         return status_i2c_transmit_not_completed;
1122     }
1123     return status_success;
1124 }
1125