1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * Description: Provides i2c driver source \n
16 *
17 * History: \n
18 * 2022-08-15, Create file. \n
19 */
20
21 #include <stdbool.h>
22 #include "soc_osal.h"
23 #include "securec.h"
24 #include "common_def.h"
25 #include "tcxo.h"
26 #include "i2c.h"
27 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
28 #include "dma.h"
29 #include "hal_dma.h"
30 #endif /* CONFIG_I2C_SUPPORT_DMA */
31
32 #define I2C_DEFAULT_DEV_ADDRESS 0x0
33
34 typedef struct i2c_ctrl_block_info {
35 bool init_flag; /* When the I2C bus is initialized, the flag is true. */
36 bool master_flag; /* when init_flag is True, the flag can be valid. */
37 uint8_t hscode; /* High speeed mode master code. */
38 uint8_t operate_type; /* I2C data operation type. */
39 uint16_t addr; /* I2C slave address, valid for slave mode. */
40 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
41 i2c_irq_callback_t callback;
42 #endif
43 } i2c_ctrl_block_info_t;
44
45 static i2c_ctrl_block_info_t g_i2c_ctrl[I2C_BUS_MAX_NUM];
46
47 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
48 typedef struct i2c_dma_trans_inf {
49 bool trans_succ;
50 uint8_t read_channel;
51 uint8_t write_channel;
52 osal_semaphore dma_sem;
53 } i2c_dma_trans_inf_t;
54
55 static i2c_dma_trans_inf_t g_dma_trans[I2C_BUS_NONE] = { 0 };
56 #endif /* CONFIG_I2C_SUPPORT_DMA */
57
58 #if defined(CONFIG_I2C_SUPPORT_CONCURRENCY) && (CONFIG_I2C_SUPPORT_CONCURRENCY == 1)
59 static osal_mutex g_i2c_mutex[I2C_BUS_NONE];
60 #endif /* CONFIG_I2C_SUPPORT_CONCURRENCY */
61
62 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
63 static osal_semaphore g_i2c_int_sem[I2C_BUS_MAX_NUM];
64 static hal_i2c_buffer_wrap_t g_i2c_buffer_wrap[I2C_BUS_MAX_NUM];
65 #endif /* CONFIG_I2C_SUPPORT_INT */
66
i2c_bus_init_check(i2c_bus_t bus)67 static errcode_t i2c_bus_init_check(i2c_bus_t bus)
68 {
69 if (bus >= I2C_BUS_MAX_NUMBER) {
70 return ERRCODE_I2C_INVALID_PARAMETER;
71 }
72
73 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
74 if (i2c_ctrl->init_flag == false) {
75 return ERRCODE_I2C_NOT_INIT;
76 }
77 return ERRCODE_SUCC;
78 }
79
i2c_write_pre_check(i2c_bus_t bus,const i2c_data_t * data)80 static errcode_t i2c_write_pre_check(i2c_bus_t bus, const i2c_data_t *data)
81 {
82 if ((data == NULL) || (data->send_buf == NULL) || (data->send_len == 0)) {
83 return ERRCODE_I2C_SEND_PARAM_INVALID;
84 }
85
86 errcode_t ret = i2c_bus_init_check(bus);
87 if (ret != ERRCODE_SUCC) {
88 return ret;
89 }
90 return ERRCODE_SUCC;
91 }
92
i2c_read_pre_check(i2c_bus_t bus,const i2c_data_t * data)93 static errcode_t i2c_read_pre_check(i2c_bus_t bus, const i2c_data_t *data)
94 {
95 if ((data == NULL) || (data->receive_buf == NULL) || (data->receive_len == 0)) {
96 return ERRCODE_I2C_RECEIVE_PARAM_INVALID;
97 }
98
99 errcode_t ret = i2c_bus_init_check(bus);
100 if (ret != ERRCODE_SUCC) {
101 return ret;
102 }
103 return ERRCODE_SUCC;
104 }
105
i2c_event_get_mask(hal_i2c_evt_id_t evt_id)106 static inline uint32_t i2c_event_get_mask(hal_i2c_evt_id_t evt_id)
107 {
108 return (1 << (uint32_t)evt_id);
109 }
110
i2c_ctrl_get_mask(hal_i2c_ctrl_id_t ctrl_id)111 static inline uint32_t i2c_ctrl_get_mask(hal_i2c_ctrl_id_t ctrl_id)
112 {
113 return (1 << (uint32_t)ctrl_id);
114 }
115
i2c_ctrl_get_id(uint32_t ctrl_mask,hal_i2c_ctrl_id_t ctrl_id)116 static inline bool i2c_ctrl_get_id(uint32_t ctrl_mask, hal_i2c_ctrl_id_t ctrl_id)
117 {
118 return (ctrl_mask >> (uint32_t)ctrl_id) & 1;
119 }
120
i2c_comm_ctrl_check(i2c_bus_t bus,hal_i2c_ctrl_id_t id)121 static errcode_t i2c_comm_ctrl_check(i2c_bus_t bus, hal_i2c_ctrl_id_t id)
122 {
123 uint32_t flag = false;
124 errcode_t ret = hal_i2c_ctrl(bus, id, (uintptr_t)&flag);
125 if (ret != ERRCODE_SUCC) {
126 return ret;
127 }
128 if (flag == true) {
129 return ERRCODE_SUCC;
130 }
131 return ERRCODE_I2C_WAIT_CONTINUE;
132 }
133
i2c_ctrl_wait(i2c_bus_t bus,uint32_t ctrl_mask,uint32_t timeout)134 static errcode_t i2c_ctrl_wait(i2c_bus_t bus, uint32_t ctrl_mask, uint32_t timeout)
135 {
136 errcode_t ret;
137 uint32_t tmp_ctrl_mask = ctrl_mask;
138 uint64_t start_time = uapi_tcxo_get_ms();
139
140 do {
141 for (uint32_t loop = 0; loop <= (uint32_t)I2C_CTRL_NORMAL_MAX; loop++) {
142 if (i2c_ctrl_get_id(tmp_ctrl_mask, loop) == false) {
143 continue;
144 }
145 ret = i2c_comm_ctrl_check(bus, loop);
146 if (ret == ERRCODE_SUCC) {
147 tmp_ctrl_mask &= ~(1 << loop);
148 } else if (ret == ERRCODE_I2C_WAIT_CONTINUE) {
149 continue;
150 }
151 }
152
153 ret = i2c_comm_ctrl_check(bus, I2C_CTRL_CHECK_TRANSMIT_ABRT);
154 if (ret == ERRCODE_SUCC) {
155 return ERRCODE_I2C_WAIT_EXCEPTION;
156 }
157
158 if ((uapi_tcxo_get_ms() - start_time) > timeout) {
159 return ERRCODE_I2C_TIMEOUT;
160 }
161 } while (tmp_ctrl_mask != 0);
162 return ERRCODE_SUCC;
163 }
164
i2c_wait(i2c_bus_t bus,i2c_wait_condition_t * condition,uint32_t timeout)165 static errcode_t i2c_wait(i2c_bus_t bus, i2c_wait_condition_t *condition, uint32_t timeout)
166 {
167 errcode_t ret = ERRCODE_SUCC;
168 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
169
170 if (i2c_ctrl->operate_type == I2C_DATA_OPERATION_TYPE_POLL) {
171 ret = i2c_ctrl_wait(bus, condition->ctrl_mask, timeout);
172 }
173 return ret;
174 }
175
i2c_write(i2c_bus_t bus,hal_i2c_buffer_wrap_t * buffer_wrap)176 static errcode_t i2c_write(i2c_bus_t bus, hal_i2c_buffer_wrap_t *buffer_wrap)
177 {
178 errcode_t ret = ERRCODE_SUCC;
179 uint32_t real_write_num = 0;
180 uint8_t *buffer = buffer_wrap->buffer;
181 uint32_t len = buffer_wrap->len;
182 i2c_wait_condition_t condition = { 0 };
183
184 uint32_t burst_num = 0;
185 hal_i2c_ctrl(bus, I2C_CTRL_GET_WRITE_NUM, (uintptr_t)&burst_num);
186 if (burst_num == 0) {
187 return ret;
188 }
189
190 while (real_write_num < len) {
191 condition.ctrl_mask = i2c_ctrl_get_mask(I2C_CTRL_CHECK_TX_AVAILABLE);
192 condition.evt_mask = i2c_event_get_mask(I2C_EVT_TX_AVAILABLE) | i2c_event_get_mask(I2C_EVT_TX_READY);
193 ret = i2c_wait(bus, &condition, CONFIG_I2C_WAIT_CONDITION_TIMEOUT);
194 if (ret != ERRCODE_SUCC) {
195 break;
196 }
197
198 uint32_t remain_num = len - real_write_num;
199 hal_i2c_buffer_wrap_t write_data = { 0 };
200 if (remain_num > burst_num) {
201 write_data.len = burst_num;
202 } else {
203 write_data.len = remain_num;
204 write_data.stop_flag = buffer_wrap->stop_flag;
205 }
206
207 if (real_write_num == 0) {
208 write_data.restart_flag = buffer_wrap->restart_flag;
209 }
210
211 write_data.buffer = &buffer[real_write_num];
212 unsigned int irq_sts = i2c_porting_lock(bus);
213 ret = hal_i2c_write(bus, &write_data);
214 i2c_porting_unlock(bus, irq_sts);
215 if (ret != ERRCODE_SUCC) {
216 break;
217 }
218
219 real_write_num += write_data.len;
220 }
221
222 return ret;
223 }
224
i2c_read(i2c_bus_t bus,hal_i2c_buffer_wrap_t * buffer_wrap)225 static errcode_t i2c_read(i2c_bus_t bus, hal_i2c_buffer_wrap_t *buffer_wrap)
226 {
227 uint8_t *buffer = buffer_wrap->buffer;
228 uint32_t len = buffer_wrap->len;
229 uint32_t real_read_num = 0;
230 i2c_wait_condition_t condition = { 0 };
231 errcode_t ret = ERRCODE_SUCC;
232
233 while (real_read_num < len) {
234 uint32_t burst_num = 0;
235 hal_i2c_ctrl(bus, I2C_CTRL_GET_READ_NUM, (uintptr_t)&burst_num);
236
237 uint32_t remain_num = len - real_read_num;
238 hal_i2c_buffer_wrap_t read_data = { 0 };
239 if (remain_num > burst_num) {
240 read_data.len = burst_num;
241 } else {
242 read_data.len = remain_num;
243 read_data.stop_flag = buffer_wrap->stop_flag;
244 }
245
246 if (real_read_num == 0) {
247 read_data.restart_flag = buffer_wrap->restart_flag;
248 }
249
250 ret = hal_i2c_ctrl(bus, I2C_CTRL_FLUSH_RX_FIFO, (uintptr_t)&read_data);
251 if (ret == ERRCODE_SUCC) {
252 condition.ctrl_mask = i2c_ctrl_get_mask(I2C_CTRL_CHECK_RX_AVAILABLE);
253 condition.evt_mask = i2c_event_get_mask(I2C_EVT_RX_READY);
254 (void)i2c_wait(bus, &condition, CONFIG_I2C_WAIT_CONDITION_TIMEOUT);
255 }
256
257 read_data.buffer = &buffer[real_read_num];
258 unsigned int irq_sts = i2c_porting_lock(bus);
259 ret = hal_i2c_read(bus, &read_data);
260 i2c_porting_unlock(bus, irq_sts);
261 if (ret != ERRCODE_SUCC) {
262 break;
263 }
264 real_read_num += read_data.len;
265 }
266 return ret;
267 }
268
i2c_poll_write(i2c_bus_t bus,uint16_t dev_addr,hal_i2c_buffer_wrap_t * data_cfg,bool end_flag)269 static errcode_t i2c_poll_write(i2c_bus_t bus, uint16_t dev_addr, hal_i2c_buffer_wrap_t *data_cfg, bool end_flag)
270 {
271 hal_i2c_prepare_config_t cfg = { 0 };
272 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
273
274 cfg.addr = dev_addr;
275 cfg.operation_type = I2C_DATA_OPERATION_TYPE_POLL;
276 i2c_ctrl->operate_type = cfg.operation_type;
277
278 errcode_t ret = hal_i2c_ctrl(bus, I2C_CTRL_WRITE_PREPARE, (uintptr_t)&cfg);
279 if (ret != ERRCODE_SUCC) {
280 return ret;
281 }
282
283 ret = i2c_write(bus, data_cfg);
284 if (ret != ERRCODE_SUCC) {
285 (void)hal_i2c_ctrl(bus, I2C_CTRL_WRITE_RESTORE, (uintptr_t)NULL);
286 return ret;
287 }
288
289 i2c_wait_condition_t condition = { 0 };
290 if (end_flag) {
291 condition.ctrl_mask = i2c_ctrl_get_mask(I2C_CTRL_CHECK_TX_PROCESS_DONE);
292 }
293 ret = i2c_wait(bus, &condition, CONFIG_I2C_WAIT_CONDITION_TIMEOUT);
294
295 (void)hal_i2c_ctrl(bus, I2C_CTRL_WRITE_RESTORE, (uintptr_t)NULL);
296 return ret;
297 }
298
i2c_poll_read(i2c_bus_t bus,uint16_t dev_addr,hal_i2c_buffer_wrap_t * data_cfg,bool end_flag)299 static errcode_t i2c_poll_read(i2c_bus_t bus, uint16_t dev_addr, hal_i2c_buffer_wrap_t *data_cfg, bool end_flag)
300 {
301 unused(end_flag);
302 hal_i2c_prepare_config_t cfg = { 0 };
303 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
304
305 cfg.addr = dev_addr;
306 cfg.operation_type = I2C_DATA_OPERATION_TYPE_POLL;
307 i2c_ctrl->operate_type = cfg.operation_type;
308
309 errcode_t ret = hal_i2c_ctrl(bus, I2C_CTRL_READ_PREPARE, (uintptr_t)&cfg);
310 if (ret != ERRCODE_SUCC) {
311 return ret;
312 }
313
314 ret = i2c_read(bus, data_cfg);
315 if (ret != ERRCODE_SUCC) {
316 (void)hal_i2c_ctrl(bus, I2C_CTRL_READ_RESTORE, (uintptr_t)NULL);
317 return ret;
318 }
319
320 i2c_wait_condition_t condition = { 0 };
321 condition.ctrl_mask = i2c_ctrl_get_mask(I2C_CTRL_CHECK_RX_PROCESS_DONE);
322
323 ret = i2c_wait(bus, &condition, CONFIG_I2C_WAIT_CONDITION_TIMEOUT);
324
325 (void)hal_i2c_ctrl(bus, I2C_CTRL_READ_RESTORE, (uintptr_t)NULL);
326 return ret;
327 }
328
329 #if (defined(CONFIG_I2C_SUPPORT_DMA) || defined(CONFIG_I2C_SUPPORT_INT))
i2c_int_mode_down(osal_semaphore * sem)330 static int i2c_int_mode_down(osal_semaphore *sem)
331 {
332 unused(sem);
333 int osal_value = OSAL_SUCCESS;
334 #if !defined(CONFIG_I2C_SUPPORT_IN_CHIP_LOOPBACK)
335 osal_value = osal_sem_down(sem);
336 #endif
337 return osal_value;
338 }
339
i2c_int_mode_up(osal_semaphore * sem)340 static void i2c_int_mode_up(osal_semaphore *sem)
341 {
342 unused(sem);
343 #if !defined(CONFIG_I2C_SUPPORT_IN_CHIP_LOOPBACK)
344 osal_sem_up(sem);
345 #endif
346 }
347 #endif
348
349 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
i2c_dma_isr(uint8_t int_type,uint8_t ch,uintptr_t arg)350 static void i2c_dma_isr(uint8_t int_type, uint8_t ch, uintptr_t arg)
351 {
352 unused(arg);
353 uint8_t bus = I2C_BUS_NONE;
354 for (uint8_t i = I2C_BUS_0; i < I2C_BUS_NONE; i++) {
355 /* channel default value is 0, means not used. channel > 0 means used.
356 So ch + 1 will not misjudgment with channel value 0. */
357 if (g_dma_trans[i].read_channel == ch + 1) {
358 bus = i;
359 break;
360 }
361 if (g_dma_trans[i].write_channel == ch + 1) {
362 bus = i;
363 break;
364 }
365 }
366
367 if (bus != I2C_BUS_NONE) {
368 if (int_type == 0) {
369 g_dma_trans[bus].trans_succ = true;
370 }
371 i2c_int_mode_up(&(g_dma_trans[bus].dma_sem));
372 }
373 }
374
i2c_write_by_dma_config(i2c_bus_t bus,uint16_t * buffer,uint32_t length,dma_ch_user_peripheral_config_t * user_cfg)375 static void i2c_write_by_dma_config(i2c_bus_t bus, uint16_t *buffer,
376 uint32_t length,
377 dma_ch_user_peripheral_config_t *user_cfg)
378 {
379 uint32_t data_addr = 0;
380 hal_i2c_ctrl(bus, I2C_CTRL_GET_DMA_DATA_ADDR, (uintptr_t)(&data_addr));
381
382 user_cfg->src = (uint32_t)(uintptr_t)buffer;
383 user_cfg->dest = (uint32_t)data_addr;
384 user_cfg->transfer_num = (uint16_t)length;
385 user_cfg->src_handshaking = 0;
386 user_cfg->trans_type = HAL_DMA_TRANS_MEMORY_TO_PERIPHERAL_DMA;
387 user_cfg->trans_dir = HAL_DMA_TRANSFER_DIR_MEM_TO_PERIPHERAL;
388 user_cfg->priority = HAL_DMA_CH_PRIORITY_0;
389 user_cfg->src_width = HAL_DMA_TRANSFER_WIDTH_8;
390 user_cfg->dest_width = HAL_DMA_TRANSFER_WIDTH_8;
391 user_cfg->burst_length = HAL_DMA_BURST_TRANSACTION_LENGTH_4;
392 user_cfg->src_increment = HAL_DMA_ADDRESS_INC_INCREMENT;
393 user_cfg->dest_increment = HAL_DMA_ADDRESS_INC_NO_CHANGE;
394 user_cfg->protection = HAL_DMA_PROTECTION_CONTROL_PRIVILEGED;
395 user_cfg->dest_handshaking = (uint16_t)i2c_port_get_dma_trans_dest_handshaking(bus);
396 }
397
i2c_read_by_dma_config(i2c_bus_t bus,uint8_t * buffer,uint32_t length,dma_ch_user_peripheral_config_t * user_cfg)398 static void i2c_read_by_dma_config(i2c_bus_t bus,
399 uint8_t *buffer,
400 uint32_t length,
401 dma_ch_user_peripheral_config_t *user_cfg)
402 {
403 uint32_t data_addr = 0;
404 hal_i2c_ctrl(bus, I2C_CTRL_GET_DMA_DATA_ADDR, (uintptr_t)(&data_addr));
405
406 user_cfg->src = (uint32_t)data_addr;
407 user_cfg->dest = (uint32_t)(uintptr_t)buffer;
408 user_cfg->transfer_num = (uint16_t)length;
409 user_cfg->src_handshaking = (uint16_t)i2c_port_get_dma_trans_src_handshaking(bus);
410 user_cfg->trans_type = HAL_DMA_TRANS_PERIPHERAL_TO_MEMORY_DMA;
411 user_cfg->trans_dir = HAL_DMA_TRANSFER_DIR_PERIPHERAL_TO_MEM;
412 user_cfg->priority = HAL_DMA_CH_PRIORITY_0;
413 user_cfg->src_width = HAL_DMA_TRANSFER_WIDTH_8;
414 user_cfg->dest_width = HAL_DMA_TRANSFER_WIDTH_8;
415 user_cfg->burst_length = HAL_DMA_BURST_TRANSACTION_LENGTH_4;
416 user_cfg->src_increment = HAL_DMA_ADDRESS_INC_NO_CHANGE;
417 user_cfg->dest_increment = HAL_DMA_ADDRESS_INC_INCREMENT;
418 user_cfg->protection = HAL_DMA_PROTECTION_CONTROL_BUFFERABLE;
419 user_cfg->dest_handshaking = 0;
420 }
421
i2c_start_transmit_dma(i2c_bus_t bus,uint8_t dma_ch)422 static errcode_t i2c_start_transmit_dma(i2c_bus_t bus, uint8_t dma_ch)
423 {
424 g_dma_trans[bus].write_channel = dma_ch + 1;
425 g_dma_trans[bus].trans_succ = false;
426 if (uapi_dma_start_transfer(dma_ch) != ERRCODE_SUCC) {
427 g_dma_trans[bus].write_channel = 0;
428 return ERRCODE_I2C_DMA_CONFIG_ERROR;
429 }
430 return ERRCODE_SUCC;
431 }
432
i2c_transmit_dma(i2c_bus_t bus,hal_i2c_buffer_wrap_t * data_cfg)433 static errcode_t i2c_transmit_dma(i2c_bus_t bus, hal_i2c_buffer_wrap_t *data_cfg)
434 {
435 uint8_t dma_ch;
436 dma_ch_user_peripheral_config_t user_cfg = {0};
437
438 i2c_write_by_dma_config(bus, (uint16_t*)data_cfg->buffer, (uint16_t)data_cfg->len, &user_cfg);
439
440 if (uapi_dma_configure_peripheral_transfer_single(&user_cfg, &dma_ch,
441 i2c_dma_isr, (uintptr_t)NULL) != ERRCODE_SUCC) {
442 return ERRCODE_I2C_DMA_CONFIG_ERROR;
443 }
444
445 return i2c_start_transmit_dma(bus, dma_ch);
446 }
447
i2c_transmit_read_cmd_by_dma(i2c_bus_t bus,hal_i2c_buffer_wrap_t * data_cfg)448 static errcode_t i2c_transmit_read_cmd_by_dma(i2c_bus_t bus, hal_i2c_buffer_wrap_t *data_cfg)
449 {
450 uint8_t dma_ch;
451 static uint16_t read_cmd = 0x100;
452 dma_ch_user_peripheral_config_t user_cfg = {0};
453
454 i2c_write_by_dma_config(bus, &read_cmd, data_cfg->len, &user_cfg);
455 user_cfg.src_width = HAL_DMA_TRANSFER_WIDTH_16;
456 user_cfg.dest_width = HAL_DMA_TRANSFER_WIDTH_16;
457 user_cfg.src_increment = HAL_DMA_ADDRESS_INC_NO_CHANGE;
458
459 if (uapi_dma_configure_peripheral_transfer_single(&user_cfg, &dma_ch,
460 i2c_dma_isr, (uintptr_t)NULL) != ERRCODE_SUCC) {
461 return ERRCODE_I2C_DMA_CONFIG_ERROR;
462 }
463
464 return i2c_start_transmit_dma(bus, dma_ch);
465 }
466
i2c_start_recv_dma(i2c_bus_t bus,hal_i2c_buffer_wrap_t * data_cfg)467 static errcode_t i2c_start_recv_dma(i2c_bus_t bus, hal_i2c_buffer_wrap_t *data_cfg)
468 {
469 uint8_t dma_ch;
470 dma_ch_user_peripheral_config_t user_cfg = {0};
471
472 i2c_read_by_dma_config(bus, data_cfg->buffer, data_cfg->len, &user_cfg);
473
474 if (uapi_dma_configure_peripheral_transfer_single(&user_cfg, &dma_ch,
475 i2c_dma_isr, (uintptr_t)NULL) != ERRCODE_SUCC) {
476 return ERRCODE_I2C_DMA_CONFIG_ERROR;
477 }
478
479 g_dma_trans[bus].read_channel = dma_ch + 1;
480 g_dma_trans[bus].trans_succ = false;
481 if (uapi_dma_start_transfer(dma_ch) != ERRCODE_SUCC) {
482 g_dma_trans[bus].read_channel = 0;
483 return ERRCODE_I2C_DMA_CONFIG_ERROR;
484 }
485 return ERRCODE_SUCC;
486 }
487
i2c_write_by_dma(i2c_bus_t bus,uint16_t dev_addr,hal_i2c_buffer_wrap_t * data)488 static errcode_t i2c_write_by_dma(i2c_bus_t bus, uint16_t dev_addr, hal_i2c_buffer_wrap_t *data)
489 {
490 hal_i2c_prepare_config_t cfg = { 0 };
491 hal_i2c_buffer_wrap_t buffer_wrap;
492 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
493
494 cfg.addr = dev_addr;
495 cfg.operation_type = I2C_DATA_OPERATION_TYPE_DMA;
496 i2c_ctrl->operate_type = cfg.operation_type;
497 errcode_t ret = hal_i2c_ctrl(bus, I2C_CTRL_WRITE_PREPARE, (uintptr_t)&cfg);
498 if (ret != ERRCODE_SUCC) {
499 return ret;
500 }
501
502 buffer_wrap.buffer = data->buffer;
503 buffer_wrap.len = data->stop_flag ? data->len - 1 : data->len;
504
505 /* if the lenth is 0 here, send stop byte straightforward */
506 if (buffer_wrap.len != 0) {
507 ret = i2c_transmit_dma(bus, &buffer_wrap);
508 if (ret != ERRCODE_SUCC) {
509 return ret;
510 }
511
512 /* wait for trans */
513 if (i2c_int_mode_down(&(g_dma_trans[bus].dma_sem)) != OSAL_SUCCESS) {
514 g_dma_trans[bus].write_channel = 0;
515 return ERRCODE_I2C_DMA_TRANSFER_ERROR;
516 }
517 g_dma_trans[bus].write_channel = 0;
518 if (!g_dma_trans[bus].trans_succ) {
519 return ERRCODE_I2C_DMA_TRANSFER_ERROR;
520 }
521 }
522
523 if (data->stop_flag) {
524 buffer_wrap.buffer = data->buffer + data->len - 1;
525 buffer_wrap.len = 1;
526 buffer_wrap.restart_flag = false;
527 buffer_wrap.stop_flag = true;
528
529 ret = i2c_write(bus, &buffer_wrap);
530 if (ret != ERRCODE_SUCC) {
531 (void)hal_i2c_ctrl(bus, I2C_CTRL_WRITE_RESTORE, (uintptr_t)NULL);
532 return ret;
533 }
534
535 i2c_wait_condition_t condition = { 0 };
536 condition.ctrl_mask = i2c_ctrl_get_mask(I2C_CTRL_CHECK_TX_PROCESS_DONE);
537 ret = i2c_wait(bus, &condition, CONFIG_I2C_WAIT_CONDITION_TIMEOUT);
538 }
539
540 (void)hal_i2c_ctrl(bus, I2C_CTRL_WRITE_RESTORE, (uintptr_t)NULL);
541
542 return ret;
543 }
544
i2c_read_by_dma(i2c_bus_t bus,uint16_t dev_addr,hal_i2c_buffer_wrap_t * data)545 static errcode_t i2c_read_by_dma(i2c_bus_t bus, uint16_t dev_addr, hal_i2c_buffer_wrap_t *data)
546 {
547 hal_i2c_prepare_config_t cfg = { 0 };
548 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
549 cfg.addr = dev_addr;
550 cfg.operation_type = I2C_DATA_OPERATION_TYPE_DMA;
551 i2c_ctrl->operate_type = cfg.operation_type;
552 /* 读准备 */
553 errcode_t ret = hal_i2c_ctrl(bus, I2C_CTRL_READ_PREPARE, (uintptr_t)&cfg);
554 if (ret != ERRCODE_SUCC) {
555 return ret;
556 }
557
558 hal_i2c_buffer_wrap_t buffer_wrap;
559
560 buffer_wrap.len = data->len;
561 buffer_wrap.buffer = data->buffer;
562
563 /* 开启一个dma接收传输 */
564 ret = i2c_start_recv_dma(bus, &buffer_wrap);
565 if (ret != ERRCODE_SUCC) {
566 return ret;
567 }
568
569 /* 从模式在这里接收信号量,主模式在发送读命令之后接收信号量 */
570 if (!i2c_ctrl->master_flag) {
571 if (i2c_int_mode_down(&(g_dma_trans[bus].dma_sem)) != OSAL_SUCCESS) {
572 g_dma_trans[bus].write_channel = 0;
573 return ERRCODE_I2C_DMA_TRANSFER_ERROR;
574 }
575
576 g_dma_trans[bus].write_channel = 0;
577 if (!g_dma_trans[bus].trans_succ) {
578 return ERRCODE_I2C_DMA_TRANSFER_ERROR;
579 }
580
581 (void)hal_i2c_ctrl(bus, I2C_CTRL_READ_RESTORE, (uintptr_t)NULL);
582 }
583
584 return ERRCODE_SUCC;
585 }
586
i2c_read_do_send_cmd(i2c_bus_t bus,hal_i2c_buffer_wrap_t * data)587 static errcode_t i2c_read_do_send_cmd(i2c_bus_t bus, hal_i2c_buffer_wrap_t *data)
588 {
589 errcode_t ret;
590 hal_i2c_buffer_wrap_t buffer_wrap;
591
592 buffer_wrap.buffer = data->buffer;
593 buffer_wrap.len = data->len - 1;
594 buffer_wrap.stop_flag = data->stop_flag;
595
596 /* 先通过dma发送len - 1个没有停止位的读命令 */
597 if (buffer_wrap.len != 0) {
598 ret = i2c_transmit_read_cmd_by_dma(bus, &buffer_wrap);
599 if (ret != ERRCODE_SUCC) {
600 return ret;
601 }
602
603 /* 发送len - 1个命令的dma中断 */
604 if (i2c_int_mode_down(&(g_dma_trans[bus].dma_sem)) != OSAL_SUCCESS) {
605 g_dma_trans[bus].write_channel = 0;
606 g_dma_trans[bus].read_channel = 0;
607 return ERRCODE_I2C_DMA_TRANSFER_ERROR;
608 }
609 }
610
611 /* 单独发送最后一个cmd,会包含停止位,触发数据接收流程 */
612 buffer_wrap.len = 1;
613 hal_i2c_ctrl(bus, I2C_CTRL_FLUSH_RX_FIFO, (uintptr_t)&buffer_wrap);
614 /* 等待接收数据的dma中断释放信号量 */
615 if (i2c_int_mode_down(&(g_dma_trans[bus].dma_sem)) != OSAL_SUCCESS) {
616 g_dma_trans[bus].read_channel = 0;
617 (void)hal_i2c_ctrl(bus, I2C_CTRL_READ_RESTORE, (uintptr_t)NULL);
618 return ERRCODE_I2C_DMA_TRANSFER_ERROR;
619 }
620
621 (void)hal_i2c_ctrl(bus, I2C_CTRL_READ_RESTORE, (uintptr_t)NULL);
622
623 return ERRCODE_SUCC;
624 }
625 #endif /* CONFIG_I2C_SUPPORT_DMA */
626
627 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
i2c_evt_busy_callback(i2c_bus_t bus)628 static void i2c_evt_busy_callback(i2c_bus_t bus)
629 {
630 if (g_i2c_ctrl[bus].callback != NULL) {
631 g_i2c_ctrl[bus].callback(bus, I2C_IRQ_EVT_I2C_BUSY);
632 }
633 }
634
i2c_evt_err_callback(i2c_bus_t bus)635 static void i2c_evt_err_callback(i2c_bus_t bus)
636 {
637 if (g_i2c_ctrl[bus].callback != NULL) {
638 g_i2c_ctrl[bus].callback(bus, I2C_IRQ_EVT_I2C_ERR);
639 }
640 }
641
i2c_evt_tx_callback(i2c_bus_t bus)642 static void i2c_evt_tx_callback(i2c_bus_t bus)
643 {
644 hal_i2c_buffer_wrap_t hal_wrap;
645 uint32_t burst_len;
646
647 /* 如果没有要写的数据了,就退出 */
648 if (g_i2c_buffer_wrap[bus].len == 0) {
649 (void)hal_i2c_ctrl(bus, I2C_CTRL_WRITE_RESTORE, (uintptr_t)NULL);
650 if (g_i2c_ctrl[bus].callback != NULL) {
651 g_i2c_ctrl[bus].callback(bus, I2C_IRQ_EVT_TX_DONE);
652 }
653 return;
654 }
655
656 hal_i2c_ctrl(bus, I2C_CTRL_GET_WRITE_NUM, (uintptr_t)&burst_len);
657 uint32_t remain_len = g_i2c_buffer_wrap[bus].len;
658
659 burst_len = burst_len < remain_len ? burst_len : remain_len;
660 hal_wrap.len = burst_len;
661 hal_wrap.buffer = g_i2c_buffer_wrap[bus].buffer;
662 hal_wrap.restart_flag = g_i2c_buffer_wrap[bus].restart_flag;
663 /* 只有在发送到末尾时,才发送停止位 */
664 if (burst_len == g_i2c_buffer_wrap[bus].len) {
665 hal_wrap.stop_flag = g_i2c_buffer_wrap[bus].stop_flag;
666 } else {
667 hal_wrap.stop_flag = false;
668 }
669
670 g_i2c_buffer_wrap[bus].len -= burst_len;
671 g_i2c_buffer_wrap[bus].buffer += burst_len;
672
673 hal_i2c_write(bus, &hal_wrap);
674 }
675
i2c_evt_rx_callback(i2c_bus_t bus)676 static void i2c_evt_rx_callback(i2c_bus_t bus)
677 {
678 uint32_t burst_len;
679 uint32_t read_len;
680 uint32_t cmd_len;
681 hal_i2c_buffer_wrap_t read_wrap;
682 hal_i2c_buffer_wrap_t cmd_wrap;
683
684 hal_i2c_ctrl(bus, I2C_CTRL_GET_READ_NUM, (uintptr_t)&burst_len);
685
686 read_len = g_i2c_buffer_wrap[bus].len;
687 read_len = burst_len < read_len ? burst_len : read_len;
688
689 read_wrap.len = read_len;
690 read_wrap.buffer = g_i2c_buffer_wrap[bus].buffer;
691 read_wrap.restart_flag = g_i2c_buffer_wrap[bus].restart_flag;
692 read_wrap.stop_flag = g_i2c_buffer_wrap[bus].stop_flag;
693
694 hal_i2c_read(bus, &read_wrap);
695
696 g_i2c_buffer_wrap[bus].buffer += read_len;
697 g_i2c_buffer_wrap[bus].len -= read_len;
698
699 /* 先是读取已有的数据,接下来发送读取之后的数据的命令 */
700 if (g_i2c_buffer_wrap[bus].len == 0) {
701 hal_i2c_ctrl(bus, I2C_CTRL_READ_RESTORE, (uintptr_t)NULL);
702 i2c_int_mode_up(&g_i2c_int_sem[bus]);
703 if (g_i2c_ctrl[bus].callback != NULL) {
704 g_i2c_ctrl[bus].callback(bus, I2C_IRQ_EVT_RX_DONE);
705 }
706 return;
707 }
708
709 hal_i2c_ctrl(bus, I2C_CTRL_GET_READ_NUM, (uintptr_t)&burst_len);
710 cmd_len = g_i2c_buffer_wrap[bus].len;
711 cmd_len = burst_len < cmd_len ? burst_len : cmd_len;
712
713 cmd_wrap.buffer = g_i2c_buffer_wrap[bus].buffer;
714 cmd_wrap.len = cmd_len;
715 cmd_wrap.restart_flag = g_i2c_buffer_wrap[bus].restart_flag;
716 /* 只有在发送到末尾时,才发送停止位 */
717 if (cmd_len < g_i2c_buffer_wrap[bus].len) {
718 cmd_wrap.stop_flag = false;
719 } else {
720 cmd_wrap.stop_flag = g_i2c_buffer_wrap[bus].stop_flag;
721 }
722
723 hal_i2c_ctrl(bus, I2C_CTRL_FLUSH_RX_FIFO, (uintptr_t)&cmd_wrap);
724 }
725
i2c_write_int(i2c_bus_t bus,uint16_t dev_addr,hal_i2c_buffer_wrap_t * data_cfg)726 static errcode_t i2c_write_int(i2c_bus_t bus, uint16_t dev_addr, hal_i2c_buffer_wrap_t *data_cfg)
727 {
728 hal_i2c_prepare_config_t cfg = { 0 };
729 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
730
731 cfg.addr = dev_addr;
732 cfg.operation_type = I2C_DATA_OPERATION_TYPE_INT;
733 cfg.total_len = data_cfg->len;
734 i2c_ctrl->operate_type = cfg.operation_type;
735
736 g_i2c_buffer_wrap[bus].buffer = data_cfg->buffer;
737 g_i2c_buffer_wrap[bus].len = data_cfg->len;
738 g_i2c_buffer_wrap[bus].restart_flag = data_cfg->restart_flag;
739 g_i2c_buffer_wrap[bus].stop_flag = data_cfg->stop_flag;
740
741 errcode_t ret = hal_i2c_ctrl(bus, I2C_CTRL_WRITE_PREPARE, (uintptr_t)&cfg);
742 if (ret != ERRCODE_SUCC) {
743 return ret;
744 }
745
746 if (i2c_int_mode_down(&g_i2c_int_sem[bus]) != OSAL_SUCCESS) {
747 return ERRCODE_I2C_DMA_TRANSFER_ERROR;
748 }
749
750 return ret;
751 }
752
i2c_read_int(i2c_bus_t bus,uint16_t dev_addr,hal_i2c_buffer_wrap_t * data_cfg)753 static errcode_t i2c_read_int(i2c_bus_t bus, uint16_t dev_addr, hal_i2c_buffer_wrap_t *data_cfg)
754 {
755 hal_i2c_prepare_config_t cfg = { 0 };
756 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
757
758 cfg.addr = dev_addr;
759 cfg.operation_type = I2C_DATA_OPERATION_TYPE_INT;
760 cfg.total_len = data_cfg->len;
761 i2c_ctrl->operate_type = cfg.operation_type;
762
763 errcode_t ret = hal_i2c_ctrl(bus, I2C_CTRL_READ_PREPARE, (uintptr_t)&cfg);
764 if (ret != ERRCODE_SUCC) {
765 return ret;
766 }
767
768 uint32_t burst_num;
769 uint32_t len = data_cfg->len;
770 hal_i2c_buffer_wrap_t hal_read_cmd;
771
772 hal_i2c_ctrl(bus, I2C_CTRL_GET_READ_NUM, (uintptr_t)&burst_num);
773 burst_num = burst_num < len ? burst_num : len;
774 g_i2c_buffer_wrap[bus].len = data_cfg->len;
775 g_i2c_buffer_wrap[bus].buffer = data_cfg->buffer;
776 g_i2c_buffer_wrap[bus].restart_flag = data_cfg->restart_flag;
777 g_i2c_buffer_wrap[bus].stop_flag = data_cfg->stop_flag;
778
779 hal_read_cmd.len = burst_num;
780 hal_read_cmd.buffer = data_cfg->buffer;
781 hal_read_cmd.restart_flag = data_cfg->restart_flag;
782 if (burst_num == g_i2c_buffer_wrap[bus].len) {
783 hal_read_cmd.stop_flag = data_cfg->stop_flag;
784 } else {
785 hal_read_cmd.stop_flag = false;
786 }
787 hal_i2c_ctrl(bus, I2C_CTRL_FLUSH_RX_FIFO, (uintptr_t)&hal_read_cmd);
788
789 if (i2c_int_mode_down(&g_i2c_int_sem[bus]) != OSAL_SUCCESS) {
790 return ERRCODE_I2C_DMA_TRANSFER_ERROR;
791 }
792
793 return ret;
794 }
795
796 #endif /* CONFIG_I2C_SUPPORT_INT */
797
i2c_evt_callback(i2c_bus_t bus,hal_i2c_evt_id_t evt,uintptr_t param)798 static errcode_t i2c_evt_callback(i2c_bus_t bus, hal_i2c_evt_id_t evt, uintptr_t param)
799 {
800 unused(param);
801 unused(evt);
802 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_POLL) {
803 return ERRCODE_SUCC;
804 }
805
806 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
807 if (evt == I2C_EVT_TX_READY) {
808 i2c_evt_tx_callback(bus);
809 } else if (evt == I2C_EVT_RX_READY) {
810 i2c_evt_rx_callback(bus);
811 } else if (evt == I2C_EVT_TRANSMITION_DONE) {
812 i2c_int_mode_up(&g_i2c_int_sem[bus]);
813 } else if (evt == I2C_EVT_TRANSMITION_ABRT) {
814 i2c_evt_err_callback(bus);
815 } else if (evt == I2C_EVT_TRANSMITION_BUSY) {
816 i2c_evt_busy_callback(bus);
817 }
818
819 #endif /* CONFIG_I2C_SUPPORT_INT */
820 return ERRCODE_SUCC;
821 }
822
823 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
uapi_i2c_set_irq_mode(i2c_bus_t bus,bool irq_en)824 errcode_t uapi_i2c_set_irq_mode(i2c_bus_t bus, bool irq_en)
825 {
826 if (bus >= I2C_BUS_NONE) {
827 return ERRCODE_I2C_INVALID_PARAMETER;
828 }
829 if (irq_en) {
830 g_i2c_ctrl[bus].operate_type = I2C_DATA_OPERATION_TYPE_INT;
831 } else {
832 g_i2c_ctrl[bus].operate_type = I2C_DATA_OPERATION_TYPE_POLL;
833 }
834
835 return ERRCODE_SUCC;
836 }
837
uapi_i2c_register_irq_callback(i2c_bus_t bus,i2c_irq_callback_t callback)838 errcode_t uapi_i2c_register_irq_callback(i2c_bus_t bus, i2c_irq_callback_t callback)
839 {
840 g_i2c_ctrl[bus].callback = callback;
841 return ERRCODE_SUCC;
842 }
843
uapi_i2c_unregister_irq_callback(i2c_bus_t bus)844 errcode_t uapi_i2c_unregister_irq_callback(i2c_bus_t bus)
845 {
846 g_i2c_ctrl[bus].callback = NULL;
847 return ERRCODE_SUCC;
848 }
849 #endif /* CONFIG_I2C_SUPPORT_INT */
850
i2c_int_mode_init(i2c_bus_t bus)851 static void i2c_int_mode_init(i2c_bus_t bus)
852 {
853 unused(bus);
854 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
855 (void)memset_s(&g_i2c_int_sem[bus], sizeof(g_i2c_int_sem[bus]),
856 0, sizeof(g_i2c_int_sem[bus]));
857 #if !defined(CONFIG_I2C_SUPPORT_IN_CHIP_LOOPBACK)
858 (void)osal_sem_init(&g_i2c_int_sem[bus], 0);
859 #endif
860 #endif /* CONFIG_I2C_SUPPORT_INT */
861 }
862
i2c_int_mode_sem_deinit(i2c_bus_t bus)863 static void i2c_int_mode_sem_deinit(i2c_bus_t bus)
864 {
865 unused(bus);
866 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
867 #if !defined(CONFIG_I2C_SUPPORT_IN_CHIP_LOOPBACK)
868 osal_sem_destroy(&g_i2c_int_sem[bus]);
869 #endif
870 #endif /* CONFIG_I2C_SUPPORT_INT */
871 }
872
873 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
uapi_i2c_set_dma_mode(i2c_bus_t bus,bool dma_en)874 errcode_t uapi_i2c_set_dma_mode(i2c_bus_t bus, bool dma_en)
875 {
876 if (bus >= I2C_BUS_NONE) {
877 return ERRCODE_I2C_INVALID_PARAMETER;
878 }
879 if (dma_en) {
880 g_i2c_ctrl[bus].operate_type = I2C_DATA_OPERATION_TYPE_DMA;
881 } else {
882 g_i2c_ctrl[bus].operate_type = I2C_DATA_OPERATION_TYPE_POLL;
883 }
884 return ERRCODE_SUCC;
885 }
886 #endif /* CONFIG_I2C_SUPPORT_DMA */
887
i2c_dma_mode_init(i2c_bus_t bus)888 static void i2c_dma_mode_init(i2c_bus_t bus)
889 {
890 unused(bus);
891 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
892 (void)memset_s(&(g_dma_trans[bus].dma_sem), sizeof(g_dma_trans[bus].dma_sem),
893 0, sizeof(g_dma_trans[bus].dma_sem));
894 (void)osal_sem_init(&(g_dma_trans[bus].dma_sem), 0);
895 #endif /* CONFIG_I2C_SUPPORT_DMA */
896 }
897
i2c_dma_mode_sem_deinit(i2c_bus_t bus)898 static void i2c_dma_mode_sem_deinit(i2c_bus_t bus)
899 {
900 unused(bus);
901 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
902 osal_sem_destroy(&(g_dma_trans[bus].dma_sem));
903 #endif /* CONFIG_I2C_SUPPORT_DMA */
904 }
905
i2c_mutex_init(i2c_bus_t bus)906 static void i2c_mutex_init(i2c_bus_t bus)
907 {
908 unused(bus);
909 #if defined(CONFIG_I2C_SUPPORT_CONCURRENCY) && (CONFIG_I2C_SUPPORT_CONCURRENCY == 1)
910 (void)memset_s(&g_i2c_mutex[bus], sizeof(g_i2c_mutex[bus]), 0, sizeof(g_i2c_mutex[bus]));
911 (void)osal_mutex_init(&g_i2c_mutex[bus]);
912 #endif /* CONFIG_I2C_SUPPORT_CONCURRENCY */
913 }
914
i2c_mutex_destroy(i2c_bus_t bus)915 static void i2c_mutex_destroy(i2c_bus_t bus)
916 {
917 unused(bus);
918 #if defined(CONFIG_I2C_SUPPORT_CONCURRENCY) && (CONFIG_I2C_SUPPORT_CONCURRENCY == 1)
919 osal_mutex_destroy(&g_i2c_mutex[bus]);
920 #endif /* CONFIG_I2C_SUPPORT_CONCURRENCY */
921 }
922
i2c_mutex_lock(i2c_bus_t bus)923 static void i2c_mutex_lock(i2c_bus_t bus)
924 {
925 unused(bus);
926 #if defined(CONFIG_I2C_SUPPORT_CONCURRENCY) && (CONFIG_I2C_SUPPORT_CONCURRENCY == 1)
927 osal_mutex_lock(&g_i2c_mutex[bus]);
928 #endif /* CONFIG_I2C_SUPPORT_CONCURRENCY */
929 }
930
i2c_mutex_unlock(i2c_bus_t bus)931 static void i2c_mutex_unlock(i2c_bus_t bus)
932 {
933 unused(bus);
934 #if defined(CONFIG_I2C_SUPPORT_CONCURRENCY) && (CONFIG_I2C_SUPPORT_CONCURRENCY == 1)
935 osal_mutex_unlock(&g_i2c_mutex[bus]);
936 #endif /* CONFIG_I2C_SUPPORT_CONCURRENCY */
937 }
938
i2c_init_check(i2c_bus_t bus,uint32_t baudrate)939 static errcode_t i2c_init_check(i2c_bus_t bus, uint32_t baudrate)
940 {
941 if (unlikely(bus >= I2C_BUS_MAX_NUM)) {
942 return ERRCODE_I2C_INVALID_PARAMETER;
943 }
944 if (unlikely(baudrate > I2C_HS_MODE_BAUDRATE_HIGH_LIMIT || baudrate == 0)) {
945 return ERRCODE_I2C_RATE_INVALID;
946 }
947 if (g_i2c_ctrl[bus].init_flag == true) {
948 return ERRCODE_I2C_ALREADY_INIT;
949 }
950 return ERRCODE_SUCC;
951 }
952
953 #if defined(CONFIG_I2C_SUPPORT_MASTER) && (CONFIG_I2C_SUPPORT_MASTER == 1)
i2c_master_init_check(i2c_bus_t bus,uint32_t baudrate,uint8_t hscode)954 static errcode_t i2c_master_init_check(i2c_bus_t bus, uint32_t baudrate, uint8_t hscode)
955 {
956 errcode_t ret = i2c_init_check(bus, baudrate);
957 if (ret != ERRCODE_SUCC) {
958 return ret;
959 }
960
961 if (unlikely(hscode > I2C_HS_MODE_MASTER_CODE_MAX)) {
962 return ERRCODE_I2C_INVALID_PARAMETER;
963 }
964 return ERRCODE_SUCC;
965 }
966
uapi_i2c_master_init(i2c_bus_t bus,uint32_t baudrate,uint8_t hscode)967 errcode_t uapi_i2c_master_init(i2c_bus_t bus, uint32_t baudrate, uint8_t hscode)
968 {
969 errcode_t ret = i2c_master_init_check(bus, baudrate, hscode);
970 if (ret != ERRCODE_SUCC) {
971 return ret;
972 }
973
974 #if defined(CONFIG_I2C_SUPPORT_LPC)
975 i2c_port_clock_enable(bus, true);
976 #endif
977
978 i2c_mutex_init(bus);
979 i2c_int_mode_init(bus);
980 i2c_dma_mode_init(bus);
981
982 ret = hal_i2c_master_init(bus, baudrate, hscode, i2c_evt_callback);
983 if (ret != ERRCODE_SUCC) {
984 i2c_int_mode_sem_deinit(bus);
985 i2c_dma_mode_sem_deinit(bus);
986 i2c_mutex_destroy(bus);
987 return ret;
988 }
989
990 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
991 i2c_port_register_irq(bus);
992 #endif
993
994 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
995 i2c_ctrl->init_flag = true;
996 i2c_ctrl->master_flag = true;
997 i2c_ctrl->hscode = hscode;
998 return ERRCODE_SUCC;
999 }
1000
i2c_fifo_check(i2c_bus_t bus)1001 static errcode_t i2c_fifo_check(i2c_bus_t bus)
1002 {
1003 if (hal_i2c_ctrl(bus, I2C_CTRL_CHECK_TX_FIFO_EMPTY, (uintptr_t)CONFIG_I2C_WAIT_CONDITION_TIMEOUT) != ERRCODE_SUCC) {
1004 return ERRCODE_I2C_TIMEOUT;
1005 }
1006 return ERRCODE_SUCC;
1007 }
1008
uapi_i2c_master_write(i2c_bus_t bus,uint16_t dev_addr,i2c_data_t * data)1009 errcode_t uapi_i2c_master_write(i2c_bus_t bus, uint16_t dev_addr, i2c_data_t *data)
1010 {
1011 errcode_t ret = i2c_write_pre_check(bus, data);
1012 if (ret != ERRCODE_SUCC) {
1013 return ret;
1014 }
1015
1016 ret = i2c_fifo_check(bus);
1017 if (ret != ERRCODE_SUCC) {
1018 return ret;
1019 }
1020
1021 hal_i2c_buffer_wrap_t buffer_wrap = { 0 };
1022 buffer_wrap.buffer = data->send_buf;
1023 buffer_wrap.len = data->send_len;
1024 buffer_wrap.stop_flag = true;
1025 buffer_wrap.restart_flag = false;
1026
1027 i2c_mutex_lock(bus);
1028 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
1029 #if defined(CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH) && (CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH == 1)
1030 if (buffer_wrap.len > CONFIG_I2C_POLL_AND_DMA_AUTO_SWITCH_THRESHOLD) {
1031 uapi_i2c_set_dma_mode(bus, true);
1032 ret = i2c_write_by_dma(bus, dev_addr, &buffer_wrap);
1033 i2c_mutex_unlock(bus);
1034 return ret;
1035 }
1036 uapi_i2c_set_dma_mode(bus, false);
1037 #else
1038 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_DMA) {
1039 ret = i2c_write_by_dma(bus, dev_addr, &buffer_wrap);
1040 i2c_mutex_unlock(bus);
1041 return ret;
1042 }
1043 #endif /* CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH */
1044 #endif /* CONFIG_I2C_SUPPORT_DMA */
1045 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
1046 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_INT) {
1047 ret = i2c_write_int(bus, dev_addr, &buffer_wrap);
1048 i2c_mutex_unlock(bus);
1049 return ret;
1050 }
1051 #endif /* CONFIG_I2C_SUPPORT_INT */
1052 ret = i2c_poll_write(bus, dev_addr, &buffer_wrap, true);
1053 i2c_mutex_unlock(bus);
1054 return ret;
1055 }
1056
uapi_i2c_master_read(i2c_bus_t bus,uint16_t dev_addr,i2c_data_t * data)1057 errcode_t uapi_i2c_master_read(i2c_bus_t bus, uint16_t dev_addr, i2c_data_t *data)
1058 {
1059 errcode_t ret = i2c_read_pre_check(bus, data);
1060 if (ret != ERRCODE_SUCC) {
1061 return ret;
1062 }
1063
1064 hal_i2c_buffer_wrap_t buffer_wrap = { 0 };
1065 buffer_wrap.buffer = data->receive_buf;
1066 buffer_wrap.len = data->receive_len;
1067 buffer_wrap.stop_flag = true;
1068 buffer_wrap.restart_flag = false;
1069
1070 i2c_mutex_lock(bus);
1071 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
1072 #if defined(CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH) && (CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH == 1)
1073 if (buffer_wrap.len > CONFIG_I2C_POLL_AND_DMA_AUTO_SWITCH_THRESHOLD) {
1074 uapi_i2c_set_dma_mode(bus, true);
1075 errcode_t ret = i2c_read_by_dma(bus, dev_addr, &buffer_wrap);
1076 if (ret != ERRCODE_SUCC) {
1077 i2c_mutex_unlock(bus);
1078 return ret;
1079 }
1080 ret = i2c_read_do_send_cmd(bus, &buffer_wrap);
1081 i2c_mutex_unlock(bus);
1082 return ret;
1083 }
1084 uapi_i2c_set_dma_mode(bus, false);
1085 #else
1086 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_DMA) {
1087 errcode_t ret = i2c_read_by_dma(bus, dev_addr, &buffer_wrap);
1088 if (ret != ERRCODE_SUCC) {
1089 i2c_mutex_unlock(bus);
1090 return ret;
1091 }
1092 ret = i2c_read_do_send_cmd(bus, &buffer_wrap);
1093 i2c_mutex_unlock(bus);
1094 return ret;
1095 }
1096 #endif /* CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH */
1097 #endif /* CONFIG_I2C_SUPPORT_DMA */
1098 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
1099 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_INT) {
1100 ret = i2c_read_int(bus, dev_addr, &buffer_wrap);
1101 i2c_mutex_unlock(bus);
1102 return ret;
1103 }
1104 #endif /* CONFIG_I2C_SUPPORT_INT */
1105 ret = i2c_poll_read(bus, dev_addr, &buffer_wrap, true);
1106 i2c_mutex_unlock(bus);
1107 return ret;
1108 }
1109
uapi_i2c_master_writeread(i2c_bus_t bus,uint16_t dev_addr,i2c_data_t * data)1110 errcode_t uapi_i2c_master_writeread(i2c_bus_t bus, uint16_t dev_addr, i2c_data_t *data)
1111 {
1112 errcode_t ret = i2c_write_pre_check(bus, data);
1113 if (ret != ERRCODE_SUCC) {
1114 return ret;
1115 }
1116 ret = i2c_read_pre_check(bus, data);
1117 if (ret != ERRCODE_SUCC) {
1118 return ret;
1119 }
1120 ret = i2c_fifo_check(bus);
1121 if (ret != ERRCODE_SUCC) {
1122 return ret;
1123 }
1124
1125 i2c_mutex_lock(bus);
1126 ret = uapi_i2c_master_write(bus, dev_addr, data);
1127 if (ret != ERRCODE_SUCC) {
1128 i2c_mutex_unlock(bus);
1129 return ret;
1130 }
1131
1132 i2c_wait_condition_t condition = { 0 };
1133 condition.ctrl_mask = i2c_ctrl_get_mask(I2C_CTRL_CHECK_RESTART_READY);
1134 (void)i2c_wait(bus, &condition, CONFIG_I2C_WAIT_CONDITION_TIMEOUT);
1135
1136 ret = uapi_i2c_master_read(bus, dev_addr, data);
1137 i2c_mutex_unlock(bus);
1138 return ret;
1139 }
1140 #endif /* CONFIG_I2C_SUPPORT_MASTER */
1141
1142 #if defined(CONFIG_I2C_SUPPORT_SLAVE) && (CONFIG_I2C_SUPPORT_SLAVE == 1)
uapi_i2c_slave_init(i2c_bus_t bus,uint32_t baudrate,uint16_t addr)1143 errcode_t uapi_i2c_slave_init(i2c_bus_t bus, uint32_t baudrate, uint16_t addr)
1144 {
1145 errcode_t ret = i2c_init_check(bus, baudrate);
1146 if (ret != ERRCODE_SUCC) {
1147 return ret;
1148 }
1149
1150 #if defined(CONFIG_I2C_SUPPORT_LPC)
1151 i2c_port_clock_enable(bus, true);
1152 #endif
1153
1154 i2c_mutex_init(bus);
1155 i2c_int_mode_init(bus);
1156 i2c_dma_mode_init(bus);
1157
1158 ret = hal_i2c_slave_init(bus, baudrate, addr, i2c_evt_callback);
1159 if (ret != ERRCODE_SUCC) {
1160 i2c_int_mode_sem_deinit(bus);
1161 i2c_dma_mode_sem_deinit(bus);
1162 i2c_mutex_destroy(bus);
1163 return ret;
1164 }
1165
1166 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
1167 i2c_port_register_irq(bus);
1168 #endif
1169
1170 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
1171 i2c_ctrl->init_flag = true;
1172 i2c_ctrl->master_flag = false;
1173 i2c_ctrl->addr = addr;
1174 return ERRCODE_SUCC;
1175 }
1176
uapi_i2c_slave_write(i2c_bus_t bus,i2c_data_t * data)1177 errcode_t uapi_i2c_slave_write(i2c_bus_t bus, i2c_data_t *data)
1178 {
1179 errcode_t ret = i2c_write_pre_check(bus, data);
1180 if (ret != ERRCODE_SUCC) {
1181 return ret;
1182 }
1183
1184 ret = i2c_fifo_check(bus);
1185 if (ret != ERRCODE_SUCC) {
1186 return ret;
1187 }
1188
1189 hal_i2c_buffer_wrap_t buffer_wrap = { 0 };
1190 buffer_wrap.buffer = data->send_buf;
1191 buffer_wrap.len = data->send_len;
1192 buffer_wrap.stop_flag = false;
1193
1194 i2c_mutex_lock(bus);
1195 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
1196 #if defined(CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH) && (CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH == 1)
1197 if (buffer_wrap.len > CONFIG_I2C_POLL_AND_DMA_AUTO_SWITCH_THRESHOLD) {
1198 uapi_i2c_set_dma_mode(bus, true);
1199 ret = i2c_write_by_dma(bus, I2C_DEFAULT_DEV_ADDRESS, &buffer_wrap);
1200 i2c_mutex_unlock(bus);
1201 return ret;
1202 }
1203 uapi_i2c_set_dma_mode(bus, false);
1204 #else
1205 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_DMA) {
1206 ret = i2c_write_by_dma(bus, I2C_DEFAULT_DEV_ADDRESS, &buffer_wrap);
1207 i2c_mutex_unlock(bus);
1208 return ret;
1209 }
1210 #endif /* CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH */
1211 #endif /* CONFIG_I2C_SUPPORT_DMA */
1212 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
1213 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_INT) {
1214 ret = i2c_write_int(bus, I2C_DEFAULT_DEV_ADDRESS, &buffer_wrap);
1215 i2c_mutex_unlock(bus);
1216 return ret;
1217 }
1218 #endif /* CONFIG_I2C_SUPPORT_INT */
1219 ret = i2c_poll_write(bus, I2C_DEFAULT_DEV_ADDRESS, &buffer_wrap, true);
1220 i2c_mutex_unlock(bus);
1221 return ret;
1222 }
1223
uapi_i2c_slave_read(i2c_bus_t bus,i2c_data_t * data)1224 errcode_t uapi_i2c_slave_read(i2c_bus_t bus, i2c_data_t *data)
1225 {
1226 errcode_t ret = i2c_read_pre_check(bus, data);
1227 if (ret != ERRCODE_SUCC) {
1228 return ret;
1229 }
1230
1231 hal_i2c_buffer_wrap_t buffer_wrap;
1232 buffer_wrap.buffer = data->receive_buf;
1233 buffer_wrap.len = data->receive_len;
1234 buffer_wrap.stop_flag = false;
1235 buffer_wrap.restart_flag = false;
1236
1237 i2c_mutex_lock(bus);
1238 #if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1)
1239 #if defined(CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH) && (CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH == 1)
1240 if (buffer_wrap.len > CONFIG_I2C_POLL_AND_DMA_AUTO_SWITCH_THRESHOLD) {
1241 uapi_i2c_set_dma_mode(bus, true);
1242 ret = i2c_read_by_dma(bus, I2C_DEFAULT_DEV_ADDRESS, &buffer_wrap);
1243 i2c_mutex_unlock(bus);
1244 return ret;
1245 }
1246 uapi_i2c_set_dma_mode(bus, false);
1247 #else
1248 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_DMA) {
1249 ret = i2c_read_by_dma(bus, I2C_DEFAULT_DEV_ADDRESS, &buffer_wrap);
1250 i2c_mutex_unlock(bus);
1251 return ret;
1252 }
1253 #endif /* CONFIG_I2C_SUPPORT_POLL_AND_DMA_AUTO_SWITCH */
1254 #endif /* CONFIG_I2C_SUPPORT_DMA */
1255
1256 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
1257 if (g_i2c_ctrl[bus].operate_type == I2C_DATA_OPERATION_TYPE_INT) {
1258 ret = i2c_read_int(bus, I2C_DEFAULT_DEV_ADDRESS, &buffer_wrap);
1259 i2c_mutex_unlock(bus);
1260 return ret;
1261 }
1262 #endif /* CONFIG_I2C_SUPPORT_INT */
1263 ret = i2c_poll_read(bus, I2C_DEFAULT_DEV_ADDRESS, &buffer_wrap, true);
1264 i2c_mutex_unlock(bus);
1265 return ret;
1266 }
1267 #endif /* CONFIG_I2C_SUPPORT_SLAVE */
1268
uapi_i2c_deinit(i2c_bus_t bus)1269 errcode_t uapi_i2c_deinit(i2c_bus_t bus)
1270 {
1271 errcode_t ret = i2c_bus_init_check(bus);
1272 if (ret != ERRCODE_SUCC) {
1273 return ret;
1274 }
1275 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
1276
1277 hal_i2c_deinit(bus);
1278 i2c_int_mode_sem_deinit(bus);
1279 i2c_dma_mode_sem_deinit(bus);
1280 i2c_mutex_destroy(bus);
1281 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
1282 i2c_port_unregister_irq(bus);
1283 #endif
1284 #if defined(CONFIG_I2C_SUPPORT_LPC)
1285 i2c_port_clock_enable(bus, false);
1286 #endif
1287
1288 i2c_ctrl->init_flag = false;
1289 i2c_ctrl->master_flag = false;
1290 return ERRCODE_SUCC;
1291 }
1292
uapi_i2c_set_baudrate(i2c_bus_t bus,uint32_t baudrate)1293 errcode_t uapi_i2c_set_baudrate(i2c_bus_t bus, uint32_t baudrate)
1294 {
1295 if (baudrate > I2C_HS_MODE_BAUDRATE_HIGH_LIMIT || baudrate == 0) {
1296 return ERRCODE_I2C_RATE_INVALID;
1297 }
1298 errcode_t ret = i2c_bus_init_check(bus);
1299 if (ret != ERRCODE_SUCC) {
1300 return ret;
1301 }
1302
1303 i2c_ctrl_block_info_t *i2c_ctrl = &g_i2c_ctrl[bus];
1304 i2c_mutex_lock(bus);
1305 if (i2c_ctrl->master_flag == true) {
1306 ret = hal_i2c_master_init(bus, baudrate, i2c_ctrl->hscode, i2c_evt_callback);
1307 } else {
1308 ret = hal_i2c_slave_init(bus, baudrate, i2c_ctrl->addr, i2c_evt_callback);
1309 }
1310 i2c_mutex_unlock(bus);
1311 return ret;
1312 }
1313
1314 #if defined(CONFIG_I2C_SUPPORT_LPM)
uapi_i2c_suspend(uintptr_t arg)1315 errcode_t uapi_i2c_suspend(uintptr_t arg)
1316 {
1317 unused(arg);
1318 return ERRCODE_SUCC;
1319 }
1320
uapi_i2c_resume(uintptr_t arg)1321 errcode_t uapi_i2c_resume(uintptr_t arg)
1322 {
1323 unused(arg);
1324 return ERRCODE_SUCC;
1325 }
1326 #endif