1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18
19 /********************************************************************************************************
20 * @file i2c.c
21 *
22 * @brief This is the source file for B91
23 *
24 * @author Driver Group
25 *
26 *******************************************************************************************************/
27 #include "i2c.h"
28
29 static unsigned char i2c_dma_tx_chn;
30 static unsigned char i2c_dma_rx_chn;
31
32 dma_config_t i2c_tx_dma_config={
33 .dst_req_sel= DMA_REQ_I2C_TX,//tx req
34 .src_req_sel=0,
35 .dst_addr_ctrl=DMA_ADDR_FIX,
36 .src_addr_ctrl=DMA_ADDR_INCREMENT,//increment
37 .dstmode=DMA_HANDSHAKE_MODE,//handshake
38 .srcmode=DMA_NORMAL_MODE,
39 .dstwidth=DMA_CTR_WORD_WIDTH,//must word
40 .srcwidth=DMA_CTR_WORD_WIDTH,//must word
41 .src_burst_size=0,//must 0
42 .read_num_en=0,
43 .priority=0,
44 .write_num_en=0,
45 .auto_en=0,//must 0
46 };
47 dma_config_t i2c_rx_dma_config={
48 .dst_req_sel= DMA_REQ_AUDIO0_TX,
49 .src_req_sel=DMA_REQ_I2C_RX,
50 .dst_addr_ctrl=DMA_ADDR_INCREMENT,
51 .src_addr_ctrl=DMA_ADDR_FIX,
52 .dstmode=DMA_NORMAL_MODE,
53 .srcmode=DMA_HANDSHAKE_MODE,
54 .dstwidth=DMA_CTR_WORD_WIDTH,//must word
55 .srcwidth=DMA_CTR_WORD_WIDTH,////must word
56 .src_burst_size=0,
57 .read_num_en=0,
58 .priority=0,
59 .write_num_en=0,
60 .auto_en=0,//must 0
61 };
62
63
64
65 /*
66 * This parameter is 0x20 by default, that is, each write or read API opens the stop command.
67 * if g_i2c_stop_en=0x00,it means every write or read API will disable stop command.
68 */
69 unsigned char g_i2c_stop_en=0x20;
70
71
72 /**
73 * @brief The function of this interface is equivalent to that after the user finishes calling the write or read interface, the stop signal is not sent,
74 * and then the write or read command is executed again. The driver defaults that every write or read API will send a stop command at the end
75 * @param[in] en - Input parameters.Decide whether to disable the stop function after each write or read interface
76 * @return none
77 */
i2c_master_send_stop(unsigned char en)78 void i2c_master_send_stop(unsigned char en)
79 {
80 if(en==1)
81 {
82 g_i2c_stop_en=0x20;
83 }else{
84 g_i2c_stop_en=0x00;
85 }
86
87 }
88
89
90 /**
91 * @brief This function selects a pin port for I2C interface.
92 * @param[in] sda_pin - the pin port selected as I2C sda pin port.
93 * @param[in] scl_pin - the pin port selected as I2C scl pin port.
94 * @return none
95 */
i2c_set_pin(i2c_sda_pin_e sda_pin,i2c_scl_pin_e scl_pin)96 void i2c_set_pin(i2c_sda_pin_e sda_pin,i2c_scl_pin_e scl_pin)
97 {
98
99 unsigned char val = 0;
100 unsigned char mask = 0xff;
101
102 //disable sda_pin and scl_pin gpio function.
103 gpio_function_dis(scl_pin);
104 gpio_function_dis(sda_pin);
105
106 //enable gpio as i2c sda function.
107 if(sda_pin == I2C_GPIO_SDA_B3)
108 {
109 mask= (unsigned char)~(BIT(7)|BIT(6));
110 val = BIT(6);
111 }
112 else if(sda_pin == I2C_GPIO_SDA_C2)
113 {
114 mask = (unsigned char)~(BIT(5)|BIT(4));
115 val = 0;
116 }
117 else if(sda_pin == I2C_GPIO_SDA_E2)
118 {
119 mask = (unsigned char)~(BIT(5)|BIT(4));
120 val = 0;
121 }
122 else if(sda_pin == I2C_GPIO_SDA_E3)
123 {
124 mask = (unsigned char)~(BIT(7)|BIT(6));
125 val = 0;
126 }
127
128 reg_gpio_func_mux(sda_pin)=(reg_gpio_func_mux(sda_pin)& mask)|val;
129
130
131 //enable gpio as i2c scl function.
132 if(scl_pin == I2C_GPIO_SCL_B2)
133 {
134 mask= (unsigned char)~(BIT(5)|BIT(4));
135 val = BIT(4);
136 }
137 else if(scl_pin == I2C_GPIO_SCL_C1)
138 {
139 mask = (unsigned char)~(BIT(3)|BIT(2));
140 val = 0;
141 }
142 else if(scl_pin == I2C_GPIO_SCL_E0)
143 {
144 mask = (unsigned char)~(BIT(1)|BIT(0));
145 val = 0;
146 }
147 else if(scl_pin == I2C_GPIO_SCL_E1)
148 {
149 mask = (unsigned char)~(BIT(3)|BIT(2));
150 val = 0;
151 }
152
153 reg_gpio_func_mux(scl_pin)=(reg_gpio_func_mux(scl_pin)& mask)|val;
154
155 gpio_set_up_down_res(sda_pin, GPIO_PIN_PULLUP_10K);
156 gpio_set_up_down_res(scl_pin, GPIO_PIN_PULLUP_10K);
157 gpio_input_en(sda_pin);//enable sda input
158 gpio_input_en(scl_pin);//enable scl input
159 }
160
161 /**
162 * @brief This function serves to enable i2c master function.
163 * @param[in] none.
164 * @return none.
165 */
i2c_master_init(void)166 void i2c_master_init(void)
167 {
168 reg_i2c_sct0 |= FLD_I2C_MASTER; //i2c master enable.
169 }
170
171
172
173 /**
174 * @brief This function serves to set the i2c clock frequency.The i2c clock is consistent with the system clock.
175 * @param[in] clock - the division factor of I2C clock,
176 * I2C frequency = System_clock / (4*DivClock).
177 * @return none
178 */
i2c_set_master_clk(unsigned char clock)179 void i2c_set_master_clk(unsigned char clock)
180 {
181
182 //i2c frequency = system_clock/(4*clock)
183 reg_i2c_sp = clock;
184
185 //set enable flag.
186 reg_clk_en0 |= FLD_CLK0_I2C_EN;
187 }
188
189
190 /**
191 * @brief This function serves to enable slave mode.
192 * @param[in] id - the id of slave device.it contains write or read bit,the laster bit is write or read bit.
193 * ID|0x01 indicate read. ID&0xfe indicate write.
194 * @return none
195 */
i2c_slave_init(unsigned char id)196 void i2c_slave_init(unsigned char id)
197 {
198 reg_i2c_sct0 &= (~FLD_I2C_MASTER); //enable slave mode.
199
200 reg_i2c_id = id; //defaul eagle slave ID is 0x5a
201 }
202
203
204 /**
205 * @brief The function of this API is to ensure that the data can be successfully sent out.
206 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
207 * @param[in] data - The data to be sent, The first three bytes can be set as the RAM address of the slave.
208 * @param[in] len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent.
209 * @return 0 : the master receive NACK after sending out the id and then send stop. 1: the master sent the data successfully,(master does not detect NACK in data phase)
210 */
i2c_master_write(unsigned char id,unsigned char * data,unsigned char len)211 unsigned char i2c_master_write(unsigned char id, unsigned char *data, unsigned char len)
212 {
213 BM_SET(reg_i2c_status,FLD_I2C_TX_CLR);//clear index
214 //set i2c master write.
215 reg_i2c_data_buf(0)=id & (~FLD_I2C_WRITE_READ_BIT); //BIT(0):R:High W:Low;
216 reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START);
217 while(i2c_master_busy());
218 if(reg_i2c_mst&FLD_I2C_ACK_IN)
219 {
220 reg_i2c_sct1 = (FLD_I2C_LS_STOP);
221 while(i2c_master_busy());
222 return 0;
223 }
224 reg_i2c_len = len;
225 //write data
226 unsigned int cnt = 0;
227 while(cnt<len)
228 {
229 if(i2c_get_tx_buf_cnt()<8)
230 {
231 reg_i2c_data_buf(cnt % 4) = data[cnt]; //write data
232 cnt++;
233 if(cnt==1)
234 {
235 reg_i2c_sct1 = ( FLD_I2C_LS_DATAW|g_i2c_stop_en ); //launch stop cycle
236 }
237 }
238 }
239
240 while(i2c_master_busy());
241 return 1;
242 }
243
244
245 /**
246 * @brief This function serves to read a packet of data from the specified address of slave device
247 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
248 * @param[in] data - Store the read data
249 * @param[in] len - The total length of the data read back.
250 * @return 0 : the master receive NACK after sending out the id and then send stop. 1: the master receive the data successfully.
251 */
i2c_master_read(unsigned char id,unsigned char * data,unsigned char len)252 unsigned char i2c_master_read(unsigned char id, unsigned char *data, unsigned char len)
253 {
254 //set i2c master read.
255 BM_SET(reg_i2c_status,FLD_I2C_RX_CLR);//clear index
256 reg_i2c_sct0 |= FLD_I2C_RNCK_EN; //i2c rnck enable.
257 reg_i2c_data_buf(0)=(id | FLD_I2C_WRITE_READ_BIT); //BIT(0):R:High W:Low;
258 reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START);
259 while(i2c_master_busy());
260 if(reg_i2c_mst&FLD_I2C_ACK_IN)
261 {
262 reg_i2c_sct1 = (FLD_I2C_LS_STOP);
263 while(i2c_master_busy());
264 return 0;
265 }
266 reg_i2c_sct1 = ( FLD_I2C_LS_DATAR | FLD_I2C_LS_ID_R | g_i2c_stop_en);
267 reg_i2c_len = len;
268 unsigned int cnt = 0;
269 while(cnt<len)
270 {
271 if(i2c_get_rx_buf_cnt()>0)
272 {
273 data[cnt] = reg_i2c_data_buf(cnt % 4);
274 cnt++;
275 }
276 }
277 while(i2c_master_busy());
278 return 1;
279 }
280
281
282 /**
283 * @brief This function serves to write data and restart read data.
284 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
285 * @param[in] wr_data - The data to be sent, The first three bytes can be set as the RAM address of the slave.
286 * @param[in] wr_len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent.
287 * @param[in] rd_data - Store the read data
288 * @param[in] rd_len - The total length of the data read back.
289 * @return 0 : the master receive NACK after sending out the id and then send stop. 1: the master receive the data successfully.
290 */
i2c_master_write_read(unsigned char id,unsigned char * wr_data,unsigned char wr_len,unsigned char * rd_data,unsigned char rd_len)291 unsigned char i2c_master_write_read(unsigned char id, unsigned char *wr_data, unsigned char wr_len, unsigned char *rd_data, unsigned char rd_len)
292 {
293 BM_SET(reg_i2c_status,FLD_I2C_TX_CLR);//clear index
294 //set i2c master write.
295 reg_i2c_data_buf(0)=id & (~FLD_I2C_WRITE_READ_BIT); //BIT(0):R:High W:Low;
296 reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START);
297 while(i2c_master_busy());
298 if(reg_i2c_mst&FLD_I2C_ACK_IN)
299 {
300 reg_i2c_sct1 = (FLD_I2C_LS_STOP);
301 while(i2c_master_busy());
302 return 0;
303 }
304 reg_i2c_len = wr_len;
305 //write data
306 unsigned int cnt = 0;
307 while(cnt<wr_len)
308 {
309 if(i2c_get_tx_buf_cnt()<8)
310 {
311 reg_i2c_data_buf(cnt % 4) = wr_data[cnt]; //write data
312 cnt++;
313 if(cnt==1)
314 {
315 reg_i2c_sct1 = ( FLD_I2C_LS_DATAW );
316 }
317 }
318 }
319 while(i2c_master_busy());
320 //set i2c master read.
321 BM_SET(reg_i2c_status,FLD_I2C_RX_CLR);//clear index
322 reg_i2c_sct0 |= FLD_I2C_RNCK_EN; //i2c rnck enable.
323 reg_i2c_data_buf(0)=(id | FLD_I2C_WRITE_READ_BIT); //BIT(0):R:High W:Low;
324 reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START);
325 while(i2c_master_busy());
326 reg_i2c_sct1 = ( FLD_I2C_LS_DATAR | FLD_I2C_LS_ID_R | FLD_I2C_LS_STOP);
327 reg_i2c_len = rd_len;
328 cnt = 0;
329 while(cnt<rd_len)
330 {
331 if(i2c_get_rx_buf_cnt()>0)
332 {
333 rd_data[cnt] = reg_i2c_data_buf(cnt % 4);
334 cnt++;
335 }
336 }
337 while(i2c_master_busy());
338
339 return 1;
340 }
341
342
343 /**
344 * @brief The function of this API is just to write data to the i2c tx_fifo by DMA.
345 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
346 * @param[in] data - The data to be sent, The first three bytes represent the RAM address of the slave.
347 * @param[in] len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent.
348 * @return none.
349 */
i2c_master_write_dma(unsigned char id,unsigned char * data,unsigned char len)350 void i2c_master_write_dma(unsigned char id, unsigned char *data, unsigned char len)
351 {
352
353 //set id.
354 reg_i2c_id = (id & (~FLD_I2C_WRITE_READ_BIT)); //BIT(0):R:High W:Low
355
356 dma_set_size(i2c_dma_tx_chn,len,DMA_WORD_WIDTH);
357 dma_set_address(i2c_dma_tx_chn,(unsigned int)convert_ram_addr_cpu2bus(data),reg_i2c_data_buf0_addr);
358 dma_chn_en(i2c_dma_tx_chn);
359
360 reg_i2c_len = len;
361 reg_i2c_sct1 = (FLD_I2C_LS_ID|FLD_I2C_LS_START|FLD_I2C_LS_DATAW |g_i2c_stop_en);
362
363 }
364
365 /**
366 * @brief This function serves to read a packet of data from the specified address of slave device.
367 * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a.
368 * @param[in] rx_data - Store the read data
369 * @param[in] len - The total length of the data read back.
370 * @return none.
371 */
i2c_master_read_dma(unsigned char id,unsigned char * rx_data,unsigned char len)372 void i2c_master_read_dma(unsigned char id, unsigned char *rx_data, unsigned char len)
373 {
374
375 reg_i2c_sct0 |= FLD_I2C_RNCK_EN; //i2c rnck enable
376
377 //set i2c master read.
378 reg_i2c_id = (id | FLD_I2C_WRITE_READ_BIT); //BIT(0):R:High W:Low
379
380 dma_set_size(i2c_dma_rx_chn,len,DMA_WORD_WIDTH);
381 dma_set_address(i2c_dma_rx_chn,reg_i2c_data_buf0_addr,(unsigned int)convert_ram_addr_cpu2bus(rx_data));
382 dma_chn_en(i2c_dma_rx_chn);
383
384 reg_i2c_len = len;
385 reg_i2c_sct1 = ( FLD_I2C_LS_ID | FLD_I2C_LS_DATAR | FLD_I2C_LS_START | FLD_I2C_LS_ID_R | g_i2c_stop_en);
386
387 }
388
389 /**
390 * @brief This function serves to send a packet of data to master device.It will trigger after the master sends the read sequence.
391 * @param[in] data - the pointer of tx_buff.
392 * @param[in] len - The total length of the data .
393 * @return none.
394 */
i2c_slave_set_tx_dma(unsigned char * data,unsigned char len)395 void i2c_slave_set_tx_dma( unsigned char *data, unsigned char len)
396 {
397 dma_set_address(i2c_dma_tx_chn,(unsigned int)convert_ram_addr_cpu2bus(data),reg_i2c_data_buf0_addr);
398 dma_set_size(i2c_dma_tx_chn,len,DMA_WORD_WIDTH);
399 dma_chn_en(i2c_dma_tx_chn);
400 }
401
402
403 /**
404 * @brief This function serves to receive a packet of data from master device,It will trigger after the master sends the write sequence.
405 * @param[in] data - the pointer of rx_buff.
406 * @param[in] len - The total length of the data.
407 * @return none.
408 */
i2c_slave_set_rx_dma(unsigned char * data,unsigned char len)409 void i2c_slave_set_rx_dma(unsigned char *data, unsigned char len)
410 {
411 dma_set_address(i2c_dma_rx_chn,reg_i2c_data_buf0_addr,(unsigned int)convert_ram_addr_cpu2bus(data));
412 dma_set_size(i2c_dma_rx_chn,len,DMA_WORD_WIDTH);
413 dma_chn_en(i2c_dma_rx_chn);
414 }
415
416
417 /**
418 * @brief This function serves to receive data .
419 * @param[in] data - the data need read.
420 * @param[in] len - The total length of the data
421 * @return none
422 */
i2c_slave_read(unsigned char * data,unsigned char len)423 void i2c_slave_read(unsigned char* data , unsigned char len )
424 {
425 unsigned int cnt = 0;
426 while(cnt<len)
427 {
428 if(i2c_get_rx_buf_cnt()>0)
429 {
430 data[cnt] = reg_i2c_data_buf(cnt % 4);
431 cnt++;
432 }
433 }
434 }
435
436 /**
437 * @brief This function serves to receive uart data by byte with not DMA method.
438 * @param[in] data - the data need send.
439 * @param[in] len - The total length of the data.
440 * @return none
441 */
i2c_slave_write(unsigned char * data,unsigned char len)442 void i2c_slave_write(unsigned char* data , unsigned char len)
443 {
444 i2c_clr_fifo(I2C_TX_BUFF_CLR);
445 unsigned int cnt = 0;
446 while(cnt<len)
447 {
448 if(i2c_get_tx_buf_cnt()<8)
449 {
450 reg_i2c_data_buf(cnt % 4) = data[cnt];
451 cnt++;
452 }
453 }
454 }
455
456
457 /**
458 * @brief This function serves to set i2c tx_dam channel and config dma tx default.
459 * @param[in] chn: dma channel.
460 * @return none
461 */
i2c_set_tx_dma_config(dma_chn_e chn)462 void i2c_set_tx_dma_config(dma_chn_e chn)
463 {
464 i2c_dma_tx_chn = chn;
465 dma_config(chn, &i2c_tx_dma_config);
466 }
467
468 /**
469 * @brief This function serves to set i2c rx_dam channel and config dma rx default.
470 * @param[in] chn: dma channel.
471 * @return none
472 */
i2c_set_rx_dma_config(dma_chn_e chn)473 void i2c_set_rx_dma_config(dma_chn_e chn)
474 {
475 i2c_dma_rx_chn = chn;
476 dma_config(chn, &i2c_rx_dma_config);
477 }
478
479
480
481
482
483
484
485
486