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