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 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(addr_size_in_byte) >> 8U)
193 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(addr_size_in_byte));
194
195 ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
196
197 left = addr_size_in_byte;
198 while (left) {
199 ptr->DATA = *(addr++);
200 left--;
201 }
202 ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
203
204 /* Before starting to transmit data, judge addrhit to ensure that the slave address exists on the bus. */
205 retry = 0;
206 while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
207 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
208 break;
209 }
210 retry++;
211 }
212 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
213 /* the address misses, a stop needs to be added to prevent the bus from being busy. */
214 ptr->STATUS = I2C_STATUS_CMPL_MASK;
215 ptr->CTRL = I2C_CTRL_PHASE_STOP_MASK;
216 ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
217 return status_i2c_no_addr_hit;
218 }
219 ptr->STATUS = I2C_STATUS_ADDRHIT_MASK;
220
221 retry = 0;
222 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
223 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
224 break;
225 }
226 retry++;
227 }
228 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
229 return status_timeout;
230 }
231 /* W1C, clear CMPL bit to avoid blocking the transmission */
232 ptr->STATUS = I2C_STATUS_CMPL_MASK;
233
234 ptr->CMD = I2C_CMD_CLEAR_FIFO;
235 ptr->CTRL = I2C_CTRL_PHASE_START_MASK
236 | I2C_CTRL_PHASE_STOP_MASK
237 | I2C_CTRL_PHASE_ADDR_MASK
238 | I2C_CTRL_PHASE_DATA_MASK
239 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ)
240 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(addr_size_in_byte) >> 8U)
241 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size_in_byte));
242 ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
243
244 retry = 0;
245 left = size_in_byte;
246 while (left) {
247 if (!(ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK)) {
248 *(buf++) = ptr->DATA;
249 left--;
250 retry = 0;
251 } else {
252 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
253 break;
254 }
255 retry++;
256 }
257 }
258
259 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
260 return status_timeout;
261 }
262
263 retry = 0;
264 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
265 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
266 break;
267 }
268 retry++;
269 }
270 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
271 return status_timeout;
272 }
273 return stat;
274 }
275
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)276 hpm_stat_t i2c_master_address_write(I2C_Type *ptr, const uint16_t device_address,
277 uint8_t *addr, uint32_t addr_size_in_byte,
278 uint8_t *buf, const uint32_t size_in_byte)
279 {
280 hpm_stat_t stat = status_success;
281 uint32_t left;
282 uint32_t retry;
283
284 if (((addr_size_in_byte == 0) || (addr_size_in_byte > I2C_SOC_TRANSFER_COUNT_MAX)) ||
285 ((size_in_byte == 0) || (size_in_byte > I2C_SOC_TRANSFER_COUNT_MAX)) ||
286 ((addr_size_in_byte + size_in_byte) > I2C_SOC_TRANSFER_COUNT_MAX)) {
287 return status_invalid_argument;
288 }
289
290 retry = 0;
291 while (ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
292 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
293 break;
294 }
295 retry++;
296 }
297 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
298 return status_timeout;
299 }
300
301 /* W1C, clear CMPL bit to avoid blocking the transmission */
302 ptr->STATUS = I2C_STATUS_CMPL_MASK;
303
304 ptr->CMD = I2C_CMD_CLEAR_FIFO;
305 ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
306 ptr->CTRL = I2C_CTRL_PHASE_START_MASK
307 | I2C_CTRL_PHASE_STOP_MASK
308 | I2C_CTRL_PHASE_ADDR_MASK
309 | I2C_CTRL_PHASE_DATA_MASK
310 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE)
311 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size_in_byte + addr_size_in_byte) >> 8U)
312 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size_in_byte + addr_size_in_byte));
313
314 left = addr_size_in_byte;
315 while (left) {
316 ptr->DATA = *(addr++);
317 left--;
318 }
319 ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
320
321 /* Before starting to transmit data, judge addrhit to ensure that the slave address exists on the bus. */
322 retry = 0;
323 while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
324 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
325 break;
326 }
327 retry++;
328 }
329 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
330 return status_i2c_no_addr_hit;
331 }
332 ptr->STATUS = I2C_STATUS_ADDRHIT_MASK;
333
334 retry = 0;
335 left = size_in_byte;
336 while (left) {
337 if (!(ptr->STATUS & I2C_STATUS_FIFOFULL_MASK)) {
338 ptr->DATA = *(buf++);
339 left--;
340 retry = 0;
341 } else {
342 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
343 break;
344 }
345 retry++;
346 }
347 }
348 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
349 return status_timeout;
350 }
351
352 retry = 0;
353 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
354 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
355 break;
356 } else {
357 retry++;
358 }
359 }
360
361 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
362 return status_timeout;
363 }
364
365 return stat;
366 }
367
i2c_master_read(I2C_Type * ptr,const uint16_t device_address,uint8_t * buf,const uint32_t size)368 hpm_stat_t i2c_master_read(I2C_Type *ptr, const uint16_t device_address,
369 uint8_t *buf, const uint32_t size)
370 {
371 hpm_stat_t stat = status_success;
372 uint32_t left;
373 uint32_t retry;
374 if (size > I2C_SOC_TRANSFER_COUNT_MAX) {
375 return status_invalid_argument;
376 }
377
378 retry = 0;
379 while (ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
380 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
381 break;
382 }
383 retry++;
384 }
385 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
386 return status_timeout;
387 }
388
389 /* W1C, clear CMPL bit to avoid blocking the transmission */
390 ptr->STATUS = I2C_STATUS_CMPL_MASK;
391
392 ptr->CMD = I2C_CMD_CLEAR_FIFO;
393 ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
394 ptr->CTRL = I2C_CTRL_PHASE_START_MASK
395 | I2C_CTRL_PHASE_STOP_MASK
396 | I2C_CTRL_PHASE_ADDR_MASK
397 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ);
398 if (size > 0) {
399 ptr->CTRL |= I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
400 | I2C_CTRL_PHASE_DATA_MASK
401 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
402 }
403 ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
404
405 /* Before starting to transmit data, judge addrhit to ensure that the slave address exists on the bus. */
406 retry = 0;
407 while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
408 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
409 break;
410 }
411 retry++;
412 }
413 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
414 return status_i2c_no_addr_hit;
415 }
416 ptr->STATUS = I2C_STATUS_ADDRHIT_MASK;
417 /* when size is zero, it's probe slave device, so directly return success */
418 if (size == 0) {
419 return status_success;
420 }
421
422 retry = 0;
423 left = size;
424 while (left) {
425 if (!(ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK)) {
426 *(buf++) = ptr->DATA;
427 left--;
428 retry = 0;
429 } else {
430 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
431 break;
432 }
433 retry++;
434 }
435 }
436 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
437 return status_timeout;
438 }
439
440 retry = 0;
441 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
442 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
443 break;
444 }
445 retry++;
446 };
447 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
448 return status_timeout;
449 }
450
451 if (i2c_get_data_count(ptr) && (size)) {
452 return status_i2c_transmit_not_completed;
453 }
454
455 return stat;
456 }
457
i2c_master_write(I2C_Type * ptr,const uint16_t device_address,uint8_t * buf,const uint32_t size)458 hpm_stat_t i2c_master_write(I2C_Type *ptr, const uint16_t device_address,
459 uint8_t *buf, const uint32_t size)
460 {
461 hpm_stat_t stat = status_success;
462 uint32_t retry;
463 uint32_t left;
464
465 if (size > I2C_SOC_TRANSFER_COUNT_MAX) {
466 return status_invalid_argument;
467 }
468
469 retry = 0;
470 while (ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
471 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
472 break;
473 }
474 retry++;
475 }
476 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
477 return status_timeout;
478 }
479
480 /* W1C, clear CMPL bit to avoid blocking the transmission */
481 ptr->STATUS = I2C_STATUS_CMPL_MASK;
482
483 ptr->CMD = I2C_CMD_CLEAR_FIFO;
484 ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
485 ptr->CTRL = I2C_CTRL_PHASE_START_MASK
486 | I2C_CTRL_PHASE_STOP_MASK
487 | I2C_CTRL_PHASE_ADDR_MASK
488 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE);
489 if (size > 0) {
490 ptr->CTRL |= I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
491 | I2C_CTRL_PHASE_DATA_MASK
492 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
493 }
494 ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
495
496 /* Before starting to transmit data, judge addrhit to ensure that the slave address exists on the bus. */
497 retry = 0;
498 while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
499 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
500 break;
501 }
502 retry++;
503 }
504 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
505 return status_i2c_no_addr_hit;
506 }
507 ptr->STATUS = I2C_STATUS_ADDRHIT_MASK;
508 /* when size is zero, it's probe slave device, so directly return success */
509 if (size == 0) {
510 return status_success;
511 }
512
513 retry = 0;
514 left = size;
515 while (left) {
516 if (!(ptr->STATUS & I2C_STATUS_FIFOFULL_MASK)) {
517 ptr->DATA = *(buf++);
518 left--;
519 retry = 0;
520 } else {
521 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
522 break;
523 }
524 retry++;
525 }
526 }
527 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
528 return status_timeout;
529 }
530
531 retry = 0;
532 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
533 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
534 break;
535 }
536 retry++;
537 }
538 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
539 return status_timeout;
540 }
541
542 if (i2c_get_data_count(ptr) && (size)) {
543 return status_i2c_transmit_not_completed;
544 }
545
546 return stat;
547 }
548
i2c_init_slave(I2C_Type * ptr,uint32_t src_clk_in_hz,i2c_config_t * config,const uint16_t slave_address)549 hpm_stat_t i2c_init_slave(I2C_Type *ptr, uint32_t src_clk_in_hz,
550 i2c_config_t *config, const uint16_t slave_address)
551 {
552 hpm_stat_t stat = status_success;
553 i2c_timing_t timing = {0};
554
555 i2c_reset(ptr);
556
557 ptr->ADDR = I2C_ADDR_ADDR_SET(slave_address);
558
559 stat = i2c_configure_timing(src_clk_in_hz, config->i2c_mode, &timing);
560 if (status_success != stat) {
561 return stat;
562 }
563
564 ptr->TPM = I2C_TPM_TPM_SET(HPM_I2C_DRV_DEFAULT_TPM);
565
566 ptr->SETUP = I2C_SETUP_T_SP_SET(timing.t_sp)
567 | I2C_SETUP_T_SUDAT_SET(timing.t_sudat)
568 | I2C_SETUP_T_HDDAT_SET(timing.t_hddat)
569 | I2C_SETUP_T_SCLRADIO_SET(timing.t_sclratio - 1)
570 | I2C_SETUP_T_SCLHI_SET(timing.t_sclhi)
571 | I2C_SETUP_ADDRESSING_SET(config->is_10bit_addressing)
572 | I2C_SETUP_IICEN_MASK;
573
574 return stat;
575 }
576
i2c_slave_write(I2C_Type * ptr,uint8_t * buf,const uint32_t size)577 hpm_stat_t i2c_slave_write(I2C_Type *ptr, uint8_t *buf, const uint32_t size)
578 {
579 volatile uint32_t status;
580 uint32_t retry;
581 uint32_t left;
582
583 if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
584 return status_invalid_argument;
585 }
586
587 /* wait for address hit */
588 retry = 0;
589 while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
590 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
591 break;
592 }
593 retry++;
594 }
595 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
596 return status_fail;
597 }
598
599 /* W1C, clear CMPL bit and clear ADDRHIT bit to avoid blocking the transmission */
600 ptr->STATUS = I2C_STATUS_CMPL_MASK | I2C_STATUS_ADDRHIT_MASK;
601 ptr->CMD = I2C_CMD_CLEAR_FIFO;
602
603 retry = 0;
604 left = size;
605 while (left) {
606 status = ptr->STATUS;
607 if (!(status & I2C_STATUS_FIFOFULL_MASK)) {
608 ptr->DATA = *(buf++);
609 left--;
610 retry = 0;
611 } else {
612 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
613 break;
614 }
615 retry++;
616 }
617 }
618 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
619 return status_timeout;
620 }
621
622 retry = 0;
623 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
624 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
625 break;
626 }
627 retry++;
628 }
629 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
630 return status_timeout;
631 }
632 /* clear status, CMPL must to be cleared at slave mode before next transaction */
633 ptr->STATUS = I2C_STATUS_CMPL_MASK;
634
635 if (i2c_get_data_count(ptr) != size) {
636 return status_i2c_transmit_not_completed;
637 }
638
639 return status_success;
640 }
641
i2c_slave_read(I2C_Type * ptr,uint8_t * buf,const uint32_t size)642 hpm_stat_t i2c_slave_read(I2C_Type *ptr,
643 uint8_t *buf,
644 const uint32_t size)
645 {
646 volatile uint32_t status;
647 uint32_t retry;
648 uint32_t left;
649
650 if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
651 return status_invalid_argument;
652 }
653
654 /* wait for address hit */
655 retry = 0;
656 while (!(ptr->STATUS & I2C_STATUS_ADDRHIT_MASK)) {
657 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
658 break;
659 }
660 retry++;
661 }
662 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
663 return status_fail;
664 }
665
666 /* W1C, clear CMPL bit and clear ADDRHIT bit to avoid blocking the transmission */
667 ptr->STATUS = I2C_STATUS_CMPL_MASK | I2C_STATUS_ADDRHIT_MASK;
668 ptr->CMD = I2C_CMD_CLEAR_FIFO;
669
670 retry = 0;
671 left = size;
672 while (left) {
673 status = ptr->STATUS;
674 if (!(status & I2C_STATUS_FIFOEMPTY_MASK)) {
675 *(buf++) = ptr->DATA;
676 left--;
677 retry = 0;
678 } else {
679 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
680 break;
681 }
682 retry++;
683 }
684 }
685 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
686 return status_timeout;
687 }
688
689 retry = 0;
690 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
691 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
692 break;
693 }
694 retry++;
695 }
696 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
697 return status_timeout;
698 }
699 /* clear status, CMPL must to be cleared at slave mode before next transaction */
700 ptr->STATUS = I2C_STATUS_CMPL_MASK;
701
702 if (i2c_get_data_count(ptr) != size) {
703 return status_i2c_transmit_not_completed;
704 }
705
706 return status_success;
707 }
708
i2c_master_start_dma_write(I2C_Type * i2c_ptr,const uint16_t device_address,uint32_t size)709 hpm_stat_t i2c_master_start_dma_write(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size)
710 {
711 uint32_t retry = 0;
712 if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
713 return status_invalid_argument;
714 }
715
716 while (i2c_ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
717 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
718 break;
719 }
720 retry++;
721 }
722 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
723 return status_timeout;
724 }
725
726 /* W1C, clear CMPL bit to avoid blocking the transmission */
727 i2c_ptr->STATUS = I2C_STATUS_CMPL_MASK;
728
729 i2c_ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
730 i2c_ptr->CTRL = I2C_CTRL_PHASE_START_MASK
731 | I2C_CTRL_PHASE_STOP_MASK
732 | I2C_CTRL_PHASE_ADDR_MASK
733 | I2C_CTRL_PHASE_DATA_MASK
734 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE)
735 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
736 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
737
738 i2c_ptr->SETUP |= I2C_SETUP_DMAEN_MASK;
739
740 i2c_ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
741
742 return status_success;
743 }
744
i2c_master_start_dma_read(I2C_Type * i2c_ptr,const uint16_t device_address,uint32_t size)745 hpm_stat_t i2c_master_start_dma_read(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size)
746 {
747 uint32_t retry = 0;
748 if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
749 return status_invalid_argument;
750 }
751
752 while (i2c_ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
753 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
754 break;
755 }
756 retry++;
757 }
758 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
759 return status_timeout;
760 }
761 /* W1C, clear CMPL bit to avoid blocking the transmission */
762 i2c_ptr->STATUS = I2C_STATUS_CMPL_MASK;
763
764 i2c_ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
765 i2c_ptr->CTRL = I2C_CTRL_PHASE_START_MASK
766 | I2C_CTRL_PHASE_STOP_MASK
767 | I2C_CTRL_PHASE_ADDR_MASK
768 | I2C_CTRL_PHASE_DATA_MASK
769 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ)
770 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
771 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
772
773 i2c_ptr->SETUP |= I2C_SETUP_DMAEN_MASK;
774
775 i2c_ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
776
777 return status_success;
778 }
779
i2c_slave_dma_transfer(I2C_Type * i2c_ptr,uint32_t size)780 hpm_stat_t i2c_slave_dma_transfer(I2C_Type *i2c_ptr, uint32_t size)
781 {
782 if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
783 return status_invalid_argument;
784 }
785
786 /* W1C, clear CMPL bit to avoid blocking the transmission */
787 i2c_ptr->STATUS = I2C_STATUS_CMPL_MASK;
788
789 i2c_ptr->CTRL &= ~(I2C_CTRL_DATACNT_HIGH_MASK | I2C_CTRL_DATACNT_MASK);
790 i2c_ptr->CTRL |= I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U) | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
791
792 i2c_ptr->SETUP |= I2C_SETUP_DMAEN_MASK;
793
794 return status_success;
795 }
796
i2c_master_configure_transfer(I2C_Type * i2c_ptr,const uint16_t device_address,uint32_t size,bool read)797 hpm_stat_t i2c_master_configure_transfer(I2C_Type *i2c_ptr, const uint16_t device_address, uint32_t size, bool read)
798 {
799 uint32_t retry = 0;
800 if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
801 return status_invalid_argument;
802 }
803
804 while (i2c_ptr->STATUS & I2C_STATUS_BUSBUSY_MASK) {
805 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
806 break;
807 }
808 retry++;
809 }
810 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
811 return status_timeout;
812 }
813 /* W1C, clear CMPL bit to avoid blocking the transmission */
814 i2c_ptr->STATUS = I2C_STATUS_CMPL_MASK;
815 i2c_ptr->CMD = I2C_CMD_CLEAR_FIFO;
816 i2c_ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
817 i2c_ptr->CTRL = I2C_CTRL_PHASE_START_MASK
818 | I2C_CTRL_PHASE_STOP_MASK
819 | I2C_CTRL_PHASE_ADDR_MASK
820 | I2C_CTRL_PHASE_DATA_MASK
821 | I2C_CTRL_DIR_SET(read)
822 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U)
823 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
824
825 i2c_ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
826
827 return status_success;
828 }
829
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)830 hpm_stat_t i2c_master_seq_transmit(I2C_Type *ptr, const uint16_t device_address,
831 uint8_t *buf, const uint32_t size, i2c_seq_transfer_opt_t opt)
832 {
833 uint32_t ctrl;
834 uint32_t retry = 0;
835 uint32_t left = 0;
836
837 if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
838 return status_invalid_argument;
839 }
840
841 /* W1C, clear CMPL bit to avoid blocking the transmission */
842 ptr->STATUS = I2C_STATUS_CMPL_MASK;
843 ptr->CMD = I2C_CMD_CLEAR_FIFO;
844 ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
845
846 switch (opt) {
847 case i2c_frist_frame:
848 ctrl = I2C_CTRL_PHASE_START_SET(true) | I2C_CTRL_PHASE_STOP_SET(false) \
849 | I2C_CTRL_PHASE_ADDR_SET(true);
850 break;
851 case i2c_next_frame:
852 ctrl = I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(false) \
853 | I2C_CTRL_PHASE_ADDR_SET(false);
854 break;
855 case i2c_last_frame:
856 ctrl = I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(true) \
857 | I2C_CTRL_PHASE_ADDR_SET(false);
858 break;
859 default:
860 return status_invalid_argument;
861 }
862
863 ptr->CTRL = ctrl | I2C_CTRL_PHASE_DATA_SET(true) \
864 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_WRITE) \
865 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U) \
866 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
867 /* enable auto ack */
868 ptr->INTEN &= ~I2C_EVENT_BYTE_RECEIVED;
869 ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
870
871 retry = 0;
872 left = size;
873 while (left) {
874 if (!(ptr->STATUS & I2C_STATUS_FIFOFULL_MASK)) {
875 ptr->DATA = *(buf++);
876 left--;
877 retry = 0;
878 } else {
879 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
880 break;
881 }
882 retry++;
883 }
884 }
885 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
886 return status_timeout;
887 }
888
889 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
890 return status_timeout;
891 }
892 retry = 0;
893 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
894 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
895 break;
896 }
897 retry++;
898 }
899 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
900 return status_timeout;
901 }
902 /* clear status, CMPL must to be cleared at slave mode before next transaction */
903 ptr->STATUS = I2C_STATUS_CMPL_MASK;
904 return status_success;
905 }
906
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)907 hpm_stat_t i2c_master_seq_receive(I2C_Type *ptr, const uint16_t device_address,
908 uint8_t *buf, const uint32_t size, i2c_seq_transfer_opt_t opt)
909 {
910 uint32_t ctrl;
911 uint32_t retry = 0;
912 uint32_t left = 0;
913
914 if (((size == 0) || (size > I2C_SOC_TRANSFER_COUNT_MAX))) {
915 return status_invalid_argument;
916 }
917
918 /* W1C, clear CMPL bit to avoid blocking the transmission */
919 ptr->STATUS = I2C_STATUS_CMPL_MASK;
920 ptr->CMD = I2C_CMD_CLEAR_FIFO;
921 ptr->ADDR = I2C_ADDR_ADDR_SET(device_address);
922
923 switch (opt) {
924 case i2c_frist_frame:
925 ctrl = I2C_CTRL_PHASE_START_SET(true) | I2C_CTRL_PHASE_STOP_SET(false) \
926 | I2C_CTRL_PHASE_ADDR_SET(true);
927 break;
928 case i2c_next_frame:
929 ctrl = I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(false) \
930 | I2C_CTRL_PHASE_ADDR_SET(false);
931 break;
932 case i2c_last_frame:
933 ctrl = I2C_CTRL_PHASE_START_SET(false) | I2C_CTRL_PHASE_STOP_SET(true) \
934 | I2C_CTRL_PHASE_ADDR_SET(false);
935 break;
936 default:
937 return status_invalid_argument;
938 }
939
940 ptr->CTRL = ctrl | I2C_CTRL_PHASE_DATA_SET(true) \
941 | I2C_CTRL_DIR_SET(I2C_DIR_MASTER_READ) \
942 | I2C_CTRL_DATACNT_HIGH_SET(I2C_DATACNT_MAP(size) >> 8U) \
943 | I2C_CTRL_DATACNT_SET(I2C_DATACNT_MAP(size));
944
945 /* disable auto ack */
946 ptr->INTEN |= I2C_EVENT_BYTE_RECEIVED;
947 ptr->CMD = I2C_CMD_ISSUE_DATA_TRANSMISSION;
948
949 retry = 0;
950 left = size;
951 while (left) {
952 if (!(ptr->STATUS & I2C_STATUS_FIFOEMPTY_MASK)) {
953 *(buf++) = ptr->DATA;
954 left--;
955 if ((left == 0) && (opt == i2c_last_frame)) {
956 ptr->CMD = I2C_CMD_NACK;
957 } else {
958 ptr->CMD = I2C_CMD_ACK;
959 }
960 retry = 0;
961 } else {
962 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
963 break;
964 }
965 retry++;
966 }
967 }
968 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
969 return status_timeout;
970 }
971
972 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
973 return status_timeout;
974 }
975 if (opt == i2c_last_frame) {
976 retry = 0;
977 while (!(ptr->STATUS & I2C_STATUS_CMPL_MASK)) {
978 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
979 break;
980 }
981 retry++;
982 }
983 if (retry > HPM_I2C_DRV_DEFAULT_RETRY_COUNT) {
984 return status_timeout;
985 }
986 }
987 /* clear status, CMPL must to be cleared at slave mode before next transaction */
988 ptr->STATUS = I2C_STATUS_CMPL_MASK;
989 /* default auto ack */
990 ptr->INTEN &= ~I2C_EVENT_BYTE_RECEIVED;
991
992 return status_success;
993 }
994
995