1 /*!
2 \file gd32a50x_i2c.c
3 \brief I2C driver
4
5 \version 2022-01-30, V1.0.0, firmware for GD32A50x
6 */
7
8 /*
9 Copyright (c) 2022, GigaDevice Semiconductor Inc.
10
11 Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13
14 1. Redistributions of source code must retain the above copyright notice, this
15 list of conditions and the following disclaimer.
16 2. Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19 3. Neither the name of the copyright holder nor the names of its contributors
20 may be used to endorse or promote products derived from this software without
21 specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34
35 #include "gd32a50x_i2c.h"
36
37 /* I2C register bit mask */
38 #define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */
39 #define I2C_ADDRESS2_MASK ((uint32_t)0x000000FEU) /*!< the second i2c address mask */
40
41 /* I2C register bit offset */
42 #define CTL0_DNF_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of DNF in I2C_CTL0 */
43 #define CTL1_BYTENUM_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BYTENUM in I2C_CTL1 */
44 #define STAT_READDR_OFFSET ((uint32_t)0x00000011U) /*!< bit offset of READDR in I2C_STAT */
45 #define TIMING_SCLL_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of SCLL in I2C_TIMING */
46 #define TIMING_SCLH_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of SCLH in I2C_TIMING */
47 #define TIMING_SDADELY_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of SDADELY in I2C_TIMING */
48 #define TIMING_SCLDELY_OFFSET ((uint32_t)0x00000014U) /*!< bit offset of SCLDELY in I2C_TIMING */
49 #define TIMING_PSC_OFFSET ((uint32_t)0x0000001CU) /*!< bit offset of PSC in I2C_TIMING */
50 #define SADDR1_ADDMSK_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of ADDMSK in I2C_SADDR1 */
51 #define TIMEOUT_BUSTOB_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BUSTOB in I2C_TIMEOUT */
52
53 /*!
54 \brief reset I2C
55 \param[in] i2c_periph: I2Cx(x=0,1)
56 \param[out] none
57 \retval none
58 */
i2c_deinit(uint32_t i2c_periph)59 void i2c_deinit(uint32_t i2c_periph)
60 {
61 switch(i2c_periph) {
62 case I2C0:
63 /* reset I2C0 */
64 rcu_periph_reset_enable(RCU_I2C0RST);
65 rcu_periph_reset_disable(RCU_I2C0RST);
66 break;
67 case I2C1:
68 /* reset I2C1 */
69 rcu_periph_reset_enable(RCU_I2C1RST);
70 rcu_periph_reset_disable(RCU_I2C1RST);
71 break;
72 default:
73 break;
74 }
75 }
76
77 /*!
78 \brief configure the timing parameters
79 \param[in] i2c_periph: I2Cx(x=0,1)
80 \param[in] psc: 0-0x0000000F, timing prescaler
81 \param[in] scl_dely: 0-0x0000000F, data setup time
82 \param[in] sda_dely: 0-0x0000000F, data hold time
83 \param[out] none
84 \retval none
85 */
i2c_timing_config(uint32_t i2c_periph,uint32_t psc,uint32_t scl_dely,uint32_t sda_dely)86 void i2c_timing_config(uint32_t i2c_periph, uint32_t psc, uint32_t scl_dely, uint32_t sda_dely)
87 {
88 /* clear PSC, SCLDELY, SDADELY bits in I2C_TIMING register */
89 I2C_TIMING(i2c_periph) &= ~I2C_TIMING_PSC;
90 I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLDELY;
91 I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SDADELY;
92 /* mask PSC, SCLDELY, SDADELY bits in I2C_TIMING register */
93 psc = (uint32_t)(psc << TIMING_PSC_OFFSET) & I2C_TIMING_PSC;
94 scl_dely = (uint32_t)(scl_dely << TIMING_SCLDELY_OFFSET) & I2C_TIMING_SCLDELY;
95 sda_dely = (uint32_t)(sda_dely << TIMING_SDADELY_OFFSET) & I2C_TIMING_SDADELY;
96 /* write PSC, SCLDELY, SDADELY bits in I2C_TIMING register */
97 I2C_TIMING(i2c_periph) |= (psc | scl_dely | sda_dely);
98 }
99
100 /*!
101 \brief configure digital noise filter
102 \param[in] i2c_periph: I2Cx(x=0,1)
103 \param[in] filter_length: the length of filter spikes
104 only one parameter can be selected which is shown as below:
105 \arg FILTER_DISABLE: digital filter is disabled
106 \arg FILTER_LENGTH_1: digital filter is enabled and filter spikes with a length of up to 1 tI2CCLK
107 \arg FILTER_LENGTH_2: digital filter is enabled and filter spikes with a length of up to 2 tI2CCLK
108 \arg FILTER_LENGTH_3: digital filter is enabled and filter spikes with a length of up to 3 tI2CCLK
109 \arg FILTER_LENGTH_4: digital filter is enabled and filter spikes with a length of up to 4 tI2CCLK
110 \arg FILTER_LENGTH_5: digital filter is enabled and filter spikes with a length of up to 5 tI2CCLK
111 \arg FILTER_LENGTH_6: digital filter is enabled and filter spikes with a length of up to 6 tI2CCLK
112 \arg FILTER_LENGTH_7: digital filter is enabled and filter spikes with a length of up to 7 tI2CCLK
113 \arg FILTER_LENGTH_8: digital filter is enabled and filter spikes with a length of up to 8 tI2CCLK
114 \arg FILTER_LENGTH_9: digital filter is enabled and filter spikes with a length of up to 9 tI2CCLK
115 \arg FILTER_LENGTH_10: digital filter is enabled and filter spikes with a length of up to 10 tI2CCLK
116 \arg FILTER_LENGTH_11: digital filter is enabled and filter spikes with a length of up to 11 tI2CCLK
117 \arg FILTER_LENGTH_12: digital filter is enabled and filter spikes with a length of up to 12 tI2CCLK
118 \arg FILTER_LENGTH_13: digital filter is enabled and filter spikes with a length of up to 13 tI2CCLK
119 \arg FILTER_LENGTH_14: digital filter is enabled and filter spikes with a length of up to 14 tI2CCLK
120 \arg FILTER_LENGTH_15: digital filter is enabled and filter spikes with a length of up to 15 tI2CCLK
121 \param[out] none
122 \retval none
123 */
i2c_digital_noise_filter_config(uint32_t i2c_periph,uint32_t filter_length)124 void i2c_digital_noise_filter_config(uint32_t i2c_periph, uint32_t filter_length)
125 {
126 I2C_CTL0(i2c_periph) &= (uint32_t)(~I2C_CTL0_DNF);
127 I2C_CTL0(i2c_periph) |= (uint32_t)(filter_length << CTL0_DNF_OFFSET);
128 }
129
130 /*!
131 \brief enable analog noise filter
132 \param[in] i2c_periph: I2Cx(x=0,1)
133 \param[out] none
134 \retval none
135 */
i2c_analog_noise_filter_enable(uint32_t i2c_periph)136 void i2c_analog_noise_filter_enable(uint32_t i2c_periph)
137 {
138 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_ANOFF;
139 }
140
141 /*!
142 \brief disable analog noise filter
143 \param[in] i2c_periph: I2Cx(x=0,1)
144 \param[out] none
145 \retval none
146 */
i2c_analog_noise_filter_disable(uint32_t i2c_periph)147 void i2c_analog_noise_filter_disable(uint32_t i2c_periph)
148 {
149 I2C_CTL0(i2c_periph) |= I2C_CTL0_ANOFF;
150 }
151
152 /*!
153 \brief configure the SCL high and low period of clock in master mode
154 \param[in] i2c_periph: I2Cx(x=0,1)
155 \param[in] sclh: 0-0x000000FF, SCL high period
156 \param[in] scll: 0-0x000000FF, SCL low period
157 \param[out] none
158 \retval none
159 */
i2c_master_clock_config(uint32_t i2c_periph,uint32_t sclh,uint32_t scll)160 void i2c_master_clock_config(uint32_t i2c_periph, uint32_t sclh, uint32_t scll)
161 {
162 /* clear SCLH, SCLL bits in I2C_TIMING register */
163 I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLH;
164 I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLL;
165 /* mask SCLH, SCLL bits in I2C_TIMING register */
166 sclh = (uint32_t)(sclh << TIMING_SCLH_OFFSET) & I2C_TIMING_SCLH;
167 scll = (uint32_t)(scll << TIMING_SCLL_OFFSET) & I2C_TIMING_SCLL;
168 /* write SCLH, SCLL bits in I2C_TIMING register */
169 I2C_TIMING(i2c_periph) |= (sclh | scll);
170 }
171
172 /*!
173 \brief configure i2c slave address and transfer direction in master mode
174 \param[in] i2c_periph: I2Cx(x=0,1)
175 \param[in] address: 0-0x3FF except reserved address, I2C slave address to be sent
176 \param[in] trans_direction: I2C transfer direction in master mode
177 only one parameter can be selected which is shown as below:
178 \arg I2C_MASTER_TRANSMIT: master transmit
179 \arg I2C_MASTER_RECEIVE: master receive
180 \param[out] none
181 \retval none
182 */
i2c_master_addressing(uint32_t i2c_periph,uint32_t address,uint32_t trans_direction)183 void i2c_master_addressing(uint32_t i2c_periph, uint32_t address, uint32_t trans_direction)
184 {
185 /* configure slave address */
186 I2C_CTL1(i2c_periph) &= ~I2C_CTL1_SADDRESS;
187 I2C_CTL1(i2c_periph) |= address;
188 /* configure transfer direction */
189 I2C_CTL1(i2c_periph) &= ~I2C_CTL1_TRDIR;
190 I2C_CTL1(i2c_periph) |= trans_direction;
191 }
192
193 /*!
194 \brief 10-bit address header executes read direction only in master receive mode
195 \param[in] i2c_periph: I2Cx(x=0,1)
196 \param[out] none
197 \retval none
198 */
i2c_address10_header_enable(uint32_t i2c_periph)199 void i2c_address10_header_enable(uint32_t i2c_periph)
200 {
201 I2C_CTL1(i2c_periph) |= I2C_CTL1_HEAD10R;
202 }
203
204 /*!
205 \brief 10-bit address header executes complete sequence in master receive mode
206 \param[in] i2c_periph: I2Cx(x=0,1)
207 \param[out] none
208 \retval none
209 */
i2c_address10_header_disable(uint32_t i2c_periph)210 void i2c_address10_header_disable(uint32_t i2c_periph)
211 {
212 I2C_CTL1(i2c_periph) &= ~I2C_CTL1_HEAD10R;
213 }
214
215 /*!
216 \brief enable 10-bit addressing mode in master mode
217 \param[in] i2c_periph: I2Cx(x=0,1)
218 \param[out] none
219 \retval none
220 */
i2c_address10_enable(uint32_t i2c_periph)221 void i2c_address10_enable(uint32_t i2c_periph)
222 {
223 I2C_CTL1(i2c_periph) |= I2C_CTL1_ADD10EN;
224 }
225
226 /*!
227 \brief disable 10-bit addressing mode in master mode
228 \param[in] i2c_periph: I2Cx(x=0,1)
229 \param[out] none
230 \retval none
231 */
i2c_address10_disable(uint32_t i2c_periph)232 void i2c_address10_disable(uint32_t i2c_periph)
233 {
234 I2C_CTL1(i2c_periph) &= ~I2C_CTL1_ADD10EN;
235 }
236
237 /*!
238 \brief enable I2C automatic end mode in master mode
239 \param[in] i2c_periph: I2Cx(x=0,1)
240 \param[out] none
241 \retval none
242 */
i2c_automatic_end_enable(uint32_t i2c_periph)243 void i2c_automatic_end_enable(uint32_t i2c_periph)
244 {
245 I2C_CTL1(i2c_periph) |= I2C_CTL1_AUTOEND;
246 }
247
248 /*!
249 \brief disable I2C automatic end mode in master mode
250 \param[in] i2c_periph: I2Cx(x=0,1)
251 \param[out] none
252 \retval none
253 */
i2c_automatic_end_disable(uint32_t i2c_periph)254 void i2c_automatic_end_disable(uint32_t i2c_periph)
255 {
256 I2C_CTL1(i2c_periph) &= ~I2C_CTL1_AUTOEND;
257 }
258
259 /*!
260 \brief enable the response to a general call
261 \param[in] i2c_periph: I2Cx(x=0,1)
262 \param[out] none
263 \retval none
264 */
i2c_slave_response_to_gcall_enable(uint32_t i2c_periph)265 void i2c_slave_response_to_gcall_enable(uint32_t i2c_periph)
266 {
267 I2C_CTL0(i2c_periph) |= I2C_CTL0_GCEN;
268 }
269
270 /*!
271 \brief disable the response to a general call
272 \param[in] i2c_periph: I2Cx(x=0,1)
273 \param[out] none
274 \retval none
275 */
i2c_slave_response_to_gcall_disable(uint32_t i2c_periph)276 void i2c_slave_response_to_gcall_disable(uint32_t i2c_periph)
277 {
278 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_GCEN;
279 }
280
281 /*!
282 \brief enable to stretch SCL low when data is not ready in slave mode
283 \param[in] i2c_periph: I2Cx(x=0,1)
284 \param[in] none
285 \param[out] none
286 \retval none
287 */
i2c_stretch_scl_low_enable(uint32_t i2c_periph)288 void i2c_stretch_scl_low_enable(uint32_t i2c_periph)
289 {
290 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SS;
291 }
292
293 /*!
294 \brief disable to stretch SCL low when data is not ready in slave mode
295 \param[in] i2c_periph: I2Cx(x=0,1)
296 \param[in] none
297 \param[out] none
298 \retval none
299 */
i2c_stretch_scl_low_disable(uint32_t i2c_periph)300 void i2c_stretch_scl_low_disable(uint32_t i2c_periph)
301 {
302 I2C_CTL0(i2c_periph) |= I2C_CTL0_SS;
303 }
304
305 /*!
306 \brief configure i2c slave address
307 \param[in] i2c_periph: I2Cx(x=0,1)
308 \param[in] address: I2C address
309 \param[in] addr_format: 7bits or 10bits
310 only one parameter can be selected which is shown as below:
311 \arg I2C_ADDFORMAT_7BITS: 7bits
312 \arg I2C_ADDFORMAT_10BITS: 10bits
313 \param[out] none
314 \retval none
315 */
i2c_address_config(uint32_t i2c_periph,uint32_t address,uint32_t addr_format)316 void i2c_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_format)
317 {
318 /* configure ADDRESS[7:1] and address format */
319 address = address & I2C_ADDRESS_MASK;
320 I2C_SADDR0(i2c_periph) = (addr_format | address);
321 /* enable i2c address in slave mode */
322 I2C_SADDR0(i2c_periph) |= I2C_SADDR0_ADDRESSEN;
323 }
324
325 /*!
326 \brief define which bits of ADDRESS[7:1] need to compare with the incoming address byte
327 \param[in] i2c_periph: I2Cx(x=0,1)
328 \param[in] compare_bits: the bits need to compare
329 one or more parameters can be selected which are shown as below:
330 ADDRESS_BIT1_COMPARE: address bit1 needs compare
331 ADDRESS_BIT2_COMPARE: address bit2 needs compare
332 ADDRESS_BIT3_COMPARE: address bit3 needs compare
333 ADDRESS_BIT4_COMPARE: address bit4 needs compare
334 ADDRESS_BIT5_COMPARE: address bit5 needs compare
335 ADDRESS_BIT6_COMPARE: address bit6 needs compare
336 ADDRESS_BIT7_COMPARE: address bit7 needs compare
337 \param[out] none
338 \retval none
339 */
i2c_address_bit_compare_config(uint32_t i2c_periph,uint32_t compare_bits)340 void i2c_address_bit_compare_config(uint32_t i2c_periph, uint32_t compare_bits)
341 {
342 I2C_CTL2(i2c_periph) &= ~I2C_CTL2_ADDM;
343 I2C_CTL2(i2c_periph) |= compare_bits;
344 }
345
346 /*!
347 \brief disable i2c address in slave mode
348 \param[in] i2c_periph: I2Cx(x=0,1)
349 \param[out] none
350 \retval none
351 */
i2c_address_disable(uint32_t i2c_periph)352 void i2c_address_disable(uint32_t i2c_periph)
353 {
354 I2C_SADDR0(i2c_periph) &= ~I2C_SADDR0_ADDRESSEN;
355 }
356
357 /*!
358 \brief configure i2c second slave address
359 \param[in] i2c_periph: I2Cx(x=0,1)
360 \param[in] address: I2C address
361 \param[in] addr_mask: the bits not need to compare
362 one or more parameters can be selected which are shown as below:
363 \arg ADDRESS2_NO_MASK: no mask, all the bits must be compared
364 \arg ADDRESS2_MASK_BIT1: ADDRESS2[1] is masked, only ADDRESS2[7:2] are compared
365 \arg ADDRESS2_MASK_BIT1_2: ADDRESS2[2:1] is masked, only ADDRESS2[7:3] are compared
366 \arg ADDRESS2_MASK_BIT1_3: ADDRESS2[3:1] is masked, only ADDRESS2[7:4] are compared
367 \arg ADDRESS2_MASK_BIT1_4: ADDRESS2[4:1] is masked, only ADDRESS2[7:5] are compared
368 \arg ADDRESS2_MASK_BIT1_5: ADDRESS2[5:1] is masked, only ADDRESS2[7:6] are compared
369 \arg ADDRESS2_MASK_BIT1_6: ADDRESS2[6:1] is masked, only ADDRESS2[7] are compared
370 \arg ADDRESS2_MASK_ALL: all the ADDRESS2[7:1] bits are masked
371 \param[out] none
372 \retval none
373 */
i2c_second_address_config(uint32_t i2c_periph,uint32_t address,uint32_t addr_mask)374 void i2c_second_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_mask)
375 {
376 /* configure ADDRESS2[7:1] */
377 address = address & I2C_ADDRESS2_MASK;
378 I2C_SADDR1(i2c_periph) |= address;
379 /* configure ADDRESS2[7:1] mask */
380 I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDMSK2;
381 I2C_SADDR1(i2c_periph) |= (uint32_t)(addr_mask << SADDR1_ADDMSK_OFFSET);
382 /* enable i2c second address in slave mode */
383 I2C_SADDR1(i2c_periph) |= I2C_SADDR1_ADDRESS2EN;
384 }
385
386 /*!
387 \brief disable i2c second address in slave mode
388 \param[in] i2c_periph: I2Cx(x=0,1)
389 \param[out] none
390 \retval none
391 */
i2c_second_address_disable(uint32_t i2c_periph)392 void i2c_second_address_disable(uint32_t i2c_periph)
393 {
394 I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDRESS2EN;
395 }
396
397 /*!
398 \brief get received match address in slave mode
399 \param[in] i2c_periph: I2Cx(x=0,1)
400 \param[out] none
401 \retval received match address
402 */
i2c_recevied_address_get(uint32_t i2c_periph)403 uint32_t i2c_recevied_address_get(uint32_t i2c_periph)
404 {
405 return (uint32_t)((I2C_STAT(i2c_periph) & I2C_STAT_READDR) >> STAT_READDR_OFFSET);
406 }
407
408 /*!
409 \brief enable slave byte control
410 \param[in] i2c_periph: I2Cx(x=0,1)
411 \param[in] none
412 \param[out] none
413 \retval none
414 */
i2c_slave_byte_control_enable(uint32_t i2c_periph)415 void i2c_slave_byte_control_enable(uint32_t i2c_periph)
416 {
417 I2C_CTL0(i2c_periph) |= I2C_CTL0_SBCTL;
418 }
419
420 /*!
421 \brief disable slave byte control
422 \param[in] i2c_periph: I2Cx(x=0,1)
423 \param[in] none
424 \param[out] none
425 \retval none
426 */
i2c_slave_byte_control_disable(uint32_t i2c_periph)427 void i2c_slave_byte_control_disable(uint32_t i2c_periph)
428 {
429 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SBCTL;
430 }
431
432 /*!
433 \brief generate a NACK in slave mode
434 \param[in] i2c_periph: I2Cx(x=0,1)
435 \param[out] none
436 \retval none
437 */
i2c_nack_enable(uint32_t i2c_periph)438 void i2c_nack_enable(uint32_t i2c_periph)
439 {
440 I2C_CTL1(i2c_periph) |= I2C_CTL1_NACKEN;
441 }
442
443 /*!
444 \brief generate an ACK in slave mode
445 \param[in] i2c_periph: I2Cx(x=0,1)
446 \param[out] none
447 \retval none
448 */
i2c_nack_disable(uint32_t i2c_periph)449 void i2c_nack_disable(uint32_t i2c_periph)
450 {
451 I2C_CTL1(i2c_periph) &= ~I2C_CTL1_NACKEN;
452 }
453
454 /*!
455 \brief enable I2C
456 \param[in] i2c_periph: I2Cx(x=0,1)
457 \param[out] none
458 \retval none
459 */
i2c_enable(uint32_t i2c_periph)460 void i2c_enable(uint32_t i2c_periph)
461 {
462 I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN;
463 }
464
465 /*!
466 \brief disable I2C
467 \param[in] i2c_periph: I2Cx(x=0,1)
468 \param[out] none
469 \retval none
470 */
i2c_disable(uint32_t i2c_periph)471 void i2c_disable(uint32_t i2c_periph)
472 {
473 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_I2CEN;
474 }
475
476 /*!
477 \brief generate a START condition on I2C bus
478 \param[in] i2c_periph: I2Cx(x=0,1)
479 \param[out] none
480 \retval none
481 */
i2c_start_on_bus(uint32_t i2c_periph)482 void i2c_start_on_bus(uint32_t i2c_periph)
483 {
484 I2C_CTL1(i2c_periph) |= I2C_CTL1_START;
485 }
486
487 /*!
488 \brief generate a STOP condition on I2C bus
489 \param[in] i2c_periph: I2Cx(x=0,1)
490 \param[out] none
491 \retval none
492 */
i2c_stop_on_bus(uint32_t i2c_periph)493 void i2c_stop_on_bus(uint32_t i2c_periph)
494 {
495 I2C_CTL1(i2c_periph) |= I2C_CTL1_STOP;
496 }
497
498 /*!
499 \brief I2C transmit data
500 \param[in] i2c_periph: I2Cx(x=0,1)
501 \param[in] data: data to be transmitted
502 \param[out] none
503 \retval none
504 */
i2c_data_transmit(uint32_t i2c_periph,uint32_t data)505 void i2c_data_transmit(uint32_t i2c_periph, uint32_t data)
506 {
507 I2C_TDATA(i2c_periph) = (I2C_TDATA_TDATA & data);
508 }
509
510 /*!
511 \brief I2C receive data
512 \param[in] i2c_periph: I2Cx(x=0,1)
513 \param[out] none
514 \retval received data
515 */
i2c_data_receive(uint32_t i2c_periph)516 uint32_t i2c_data_receive(uint32_t i2c_periph)
517 {
518 return (I2C_RDATA(i2c_periph) & I2C_RDATA_RDATA);
519 }
520
521 /*!
522 \brief enable I2C reload mode
523 \param[in] i2c_periph: I2Cx(x=0,1)
524 \param[out] none
525 \retval none
526 */
i2c_reload_enable(uint32_t i2c_periph)527 void i2c_reload_enable(uint32_t i2c_periph)
528 {
529 I2C_CTL1(i2c_periph) |= I2C_CTL1_RELOAD;
530 }
531
532 /*!
533 \brief disable I2C reload mode
534 \param[in] i2c_periph: I2Cx(x=0,1)
535 \param[out] none
536 \retval none
537 */
i2c_reload_disable(uint32_t i2c_periph)538 void i2c_reload_disable(uint32_t i2c_periph)
539 {
540 I2C_CTL1(i2c_periph) &= ~I2C_CTL1_RELOAD;
541 }
542
543 /*!
544 \brief configure number of bytes to be transferred
545 \param[in] i2c_periph: I2Cx(x=0,1)
546 \param[in] byte_number: 0x0-0xFF, number of bytes to be transferred
547 \param[out] none
548 \retval none
549 */
i2c_transfer_byte_number_config(uint32_t i2c_periph,uint32_t byte_number)550 void i2c_transfer_byte_number_config(uint32_t i2c_periph, uint32_t byte_number)
551 {
552 I2C_CTL1(i2c_periph) &= (uint32_t)(~I2C_CTL1_BYTENUM);
553 I2C_CTL1(i2c_periph) |= (uint32_t)(byte_number << CTL1_BYTENUM_OFFSET);
554 }
555
556 /*!
557 \brief enable I2C DMA for transmission or reception
558 \param[in] i2c_periph: I2Cx(x=0,1)
559 \param[in] dma: I2C DMA
560 only one parameter can be selected which is shown as below:
561 \arg I2C_DMA_TRANSMIT: transmit data using DMA
562 \arg I2C_DMA_RECEIVE: receive data using DMA
563 \param[out] none
564 \retval none
565 */
i2c_dma_enable(uint32_t i2c_periph,uint8_t dma)566 void i2c_dma_enable(uint32_t i2c_periph, uint8_t dma)
567 {
568 if(I2C_DMA_TRANSMIT == dma) {
569 I2C_CTL0(i2c_periph) |= I2C_CTL0_DENT;
570 } else {
571 I2C_CTL0(i2c_periph) |= I2C_CTL0_DENR;
572 }
573 }
574
575 /*!
576 \brief disable I2C DMA for transmission or reception
577 \param[in] i2c_periph: I2Cx(x=0,1)
578 \param[in] dma: I2C DMA
579 only one parameter can be selected which is shown as below:
580 \arg I2C_DMA_TRANSMIT: transmit data using DMA
581 \arg I2C_DMA_RECEIVE: receive data using DMA
582 \param[out] none
583 \retval none
584 */
i2c_dma_disable(uint32_t i2c_periph,uint8_t dma)585 void i2c_dma_disable(uint32_t i2c_periph, uint8_t dma)
586 {
587 if(I2C_DMA_TRANSMIT == dma) {
588 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENT;
589 } else {
590 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENR;
591 }
592 }
593
594 /*!
595 \brief I2C transfers PEC value
596 \param[in] i2c_periph: I2Cx(x=0,1)
597 \param[out] none
598 \retval none
599 */
i2c_pec_transfer(uint32_t i2c_periph)600 void i2c_pec_transfer(uint32_t i2c_periph)
601 {
602 I2C_CTL1(i2c_periph) |= I2C_CTL1_PECTRANS;
603 }
604
605 /*!
606 \brief enable I2C PEC calculation
607 \param[in] i2c_periph: I2Cx(x=0,1)
608 \param[in] none
609 \param[out] none
610 \retval none
611 */
i2c_pec_enable(uint32_t i2c_periph)612 void i2c_pec_enable(uint32_t i2c_periph)
613 {
614 I2C_CTL0(i2c_periph) |= I2C_CTL0_PECEN;
615 }
616
617 /*!
618 \brief disable I2C PEC calculation
619 \param[in] i2c_periph: I2Cx(x=0,1)
620 \param[in] none
621 \param[out] none
622 \retval none
623 */
i2c_pec_disable(uint32_t i2c_periph)624 void i2c_pec_disable(uint32_t i2c_periph)
625 {
626 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_PECEN;
627 }
628
629 /*!
630 \brief get packet error checking value
631 \param[in] i2c_periph: I2Cx(x=0,1)
632 \param[out] none
633 \retval PEC value
634 */
i2c_pec_value_get(uint32_t i2c_periph)635 uint32_t i2c_pec_value_get(uint32_t i2c_periph)
636 {
637 return (I2C_PEC(i2c_periph) & I2C_PEC_PECV);
638 }
639
640 /*!
641 \brief enable SMBus alert
642 \param[in] i2c_periph: I2Cx(x=0,1)
643 \param[in] none
644 \param[out] none
645 \retval none
646 */
i2c_smbus_alert_enable(uint32_t i2c_periph)647 void i2c_smbus_alert_enable(uint32_t i2c_periph)
648 {
649 I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBALTEN;
650 }
651
652 /*!
653 \brief disable SMBus alert
654 \param[in] i2c_periph: I2Cx(x=0,1)
655 \param[in] none
656 \param[out] none
657 \retval none
658 */
i2c_smbus_alert_disable(uint32_t i2c_periph)659 void i2c_smbus_alert_disable(uint32_t i2c_periph)
660 {
661 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBALTEN;
662 }
663
664 /*!
665 \brief enable SMBus device default address
666 \param[in] i2c_periph: I2Cx(x=0,1)
667 \param[in] none
668 \param[out] none
669 \retval none
670 */
i2c_smbus_default_addr_enable(uint32_t i2c_periph)671 void i2c_smbus_default_addr_enable(uint32_t i2c_periph)
672 {
673 I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBDAEN;
674 }
675
676 /*!
677 \brief disable SMBus device default address
678 \param[in] i2c_periph: I2Cx(x=0,1)
679 \param[in] none
680 \param[out] none
681 \retval none
682 */
i2c_smbus_default_addr_disable(uint32_t i2c_periph)683 void i2c_smbus_default_addr_disable(uint32_t i2c_periph)
684 {
685 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBDAEN;
686 }
687
688 /*!
689 \brief enable SMBus Host address
690 \param[in] i2c_periph: I2Cx(x=0,1)
691 \param[in] none
692 \param[out] none
693 \retval none
694 */
i2c_smbus_host_addr_enable(uint32_t i2c_periph)695 void i2c_smbus_host_addr_enable(uint32_t i2c_periph)
696 {
697 I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBHAEN;
698 }
699
700 /*!
701 \brief disable SMBus Host address
702 \param[in] i2c_periph: I2Cx(x=0,1)
703 \param[in] none
704 \param[out] none
705 \retval none
706 */
i2c_smbus_host_addr_disable(uint32_t i2c_periph)707 void i2c_smbus_host_addr_disable(uint32_t i2c_periph)
708 {
709 I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBHAEN;
710 }
711
712 /*!
713 \brief enable extended clock timeout detection
714 \param[in] i2c_periph: I2Cx(x=0,1)
715 \param[out] none
716 \retval none
717 */
i2c_extented_clock_timeout_enable(uint32_t i2c_periph)718 void i2c_extented_clock_timeout_enable(uint32_t i2c_periph)
719 {
720 I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_EXTOEN;
721 }
722
723 /*!
724 \brief disable extended clock timeout detection
725 \param[in] i2c_periph: I2Cx(x=0,1)
726 \param[out] none
727 \retval none
728 */
i2c_extented_clock_timeout_disable(uint32_t i2c_periph)729 void i2c_extented_clock_timeout_disable(uint32_t i2c_periph)
730 {
731 I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_EXTOEN;
732 }
733
734 /*!
735 \brief enable clock timeout detection
736 \param[in] i2c_periph: I2Cx(x=0,1)
737 \param[out] none
738 \retval none
739 */
i2c_clock_timeout_enable(uint32_t i2c_periph)740 void i2c_clock_timeout_enable(uint32_t i2c_periph)
741 {
742 I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_TOEN;
743 }
744
745 /*!
746 \brief disable clock timeout detection
747 \param[in] i2c_periph: I2Cx(x=0,1)
748 \param[out] none
749 \retval none
750 */
i2c_clock_timeout_disable(uint32_t i2c_periph)751 void i2c_clock_timeout_disable(uint32_t i2c_periph)
752 {
753 I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOEN;
754 }
755
756 /*!
757 \brief configure bus timeout B
758 \param[in] i2c_periph: I2Cx(x=0,1)
759 \param[in] timeout: bus timeout B
760 \param[out] none
761 \retval none
762 */
i2c_bus_timeout_b_config(uint32_t i2c_periph,uint32_t timeout)763 void i2c_bus_timeout_b_config(uint32_t i2c_periph, uint32_t timeout)
764 {
765 I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOB;
766 I2C_TIMEOUT(i2c_periph) |= (uint32_t)(timeout << TIMEOUT_BUSTOB_OFFSET);
767 }
768
769 /*!
770 \brief configure bus timeout A
771 \param[in] i2c_periph: I2Cx(x=0,1)
772 \param[in] timeout: bus timeout A
773 \param[out] none
774 \retval none
775 */
i2c_bus_timeout_a_config(uint32_t i2c_periph,uint32_t timeout)776 void i2c_bus_timeout_a_config(uint32_t i2c_periph, uint32_t timeout)
777 {
778 I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOA;
779 I2C_TIMEOUT(i2c_periph) |= timeout;
780 }
781
782 /*!
783 \brief configure idle clock timeout detection
784 \param[in] i2c_periph: I2Cx(x=0,1)
785 \param[in] timeout: bus timeout A
786 \arg BUSTOA_DETECT_SCL_LOW: BUSTOA is used to detect SCL low timeout
787 \arg BUSTOA_DETECT_IDLE: BUSTOA is used to detect both SCL and SDA high timeout when the bus is idle
788 \param[out] none
789 \retval none
790 */
i2c_idle_clock_timeout_config(uint32_t i2c_periph,uint32_t timeout)791 void i2c_idle_clock_timeout_config(uint32_t i2c_periph, uint32_t timeout)
792 {
793 I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOIDLE;
794 I2C_TIMEOUT(i2c_periph) |= timeout;
795 }
796
797 /*!
798 \brief get I2C flag status
799 \param[in] i2c_periph: I2Cx(x=0,1)
800 \param[in] flag: I2C flags
801 only one parameter can be selected which is shown as below:
802 \arg I2C_FLAG_TBE: I2C_TDATA is empty during transmitting
803 \arg I2C_FLAG_TI: transmit interrupt
804 \arg I2C_FLAG_RBNE: I2C_RDATA is not empty during receiving
805 \arg I2C_FLAG_ADDSEND: address received matches in slave mode
806 \arg I2C_FLAG_NACK: not acknowledge flag
807 \arg I2C_FLAG_STPDET: STOP condition detected in slave mode
808 \arg I2C_FLAG_TC: transfer complete in master mode
809 \arg I2C_FLAG_TCR: transfer complete reload
810 \arg I2C_FLAG_BERR: bus error
811 \arg I2C_FLAG_LOSTARB: arbitration Lost
812 \arg I2C_FLAG_OUERR: overrun/underrun error in slave mode
813 \arg I2C_FLAG_PECERR: PEC error
814 \arg I2C_FLAG_TIMEOUT: timeout flag
815 \arg I2C_FLAG_SMBALT: SMBus Alert
816 \arg I2C_FLAG_I2CBSY: busy flag
817 \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver in slave mode
818 \param[out] none
819 \retval FlagStatus: SET or RESET
820 */
i2c_flag_get(uint32_t i2c_periph,uint32_t flag)821 FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag)
822 {
823 if(0U != (I2C_STAT(i2c_periph) & flag)) {
824 return SET;
825 } else {
826 return RESET;
827 }
828 }
829
830 /*!
831 \brief clear I2C flag status
832 \param[in] i2c_periph: I2Cx(x=0,1)
833 \param[in] flag: I2C flags
834 one or more parameters can be selected which are shown as below:
835 \arg I2C_FLAG_ADDSEND: address received matches in slave mode
836 \arg I2C_FLAG_NACK: not acknowledge flag
837 \arg I2C_FLAG_STPDET: STOP condition detected in slave mode
838 \arg I2C_FLAG_BERR: bus error
839 \arg I2C_FLAG_LOSTARB: arbitration Lost
840 \arg I2C_FLAG_OUERR: overrun/underrun error in slave mode
841 \arg I2C_FLAG_PECERR: PEC error
842 \arg I2C_FLAG_TIMEOUT: timeout flag
843 \arg I2C_FLAG_SMBALT: SMBus Alert
844 \param[out] none
845 \retval none
846 */
i2c_flag_clear(uint32_t i2c_periph,uint32_t flag)847 void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag)
848 {
849 I2C_STATC(i2c_periph) |= flag;
850 }
851
852 /*!
853 \brief enable I2C interrupt
854 \param[in] i2c_periph: I2Cx(x=0,1)
855 \param[in] interrupt: I2C interrupts
856 one or more parameters can be selected which are shown as below:
857 \arg I2C_INT_ERR: error interrupt
858 \arg I2C_INT_TC: transfer complete interrupt
859 \arg I2C_INT_STPDET: stop detection interrupt
860 \arg I2C_INT_NACK: not acknowledge received interrupt
861 \arg I2C_INT_ADDM: address match interrupt
862 \arg I2C_INT_RBNE: receive interrupt
863 \arg I2C_INT_TI: transmit interrupt
864 \param[out] none
865 \retval none
866 */
i2c_interrupt_enable(uint32_t i2c_periph,uint32_t interrupt)867 void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t interrupt)
868 {
869 I2C_CTL0(i2c_periph) |= interrupt;
870 }
871
872 /*!
873 \brief disable I2C interrupt
874 \param[in] i2c_periph: I2Cx(x=0,1)
875 \param[in] interrupt: I2C interrupts
876 one or more parameters can be selected which are shown as below:
877 \arg I2C_INT_ERR: error interrupt
878 \arg I2C_INT_TC: transfer complete interrupt
879 \arg I2C_INT_STPDET: stop detection interrupt
880 \arg I2C_INT_NACK: not acknowledge received interrupt
881 \arg I2C_INT_ADDM: address match interrupt
882 \arg I2C_INT_RBNE: receive interrupt
883 \arg I2C_INT_TI: transmit interrupt
884 \param[out] none
885 \retval none
886 */
i2c_interrupt_disable(uint32_t i2c_periph,uint32_t interrupt)887 void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t interrupt)
888 {
889 I2C_CTL0(i2c_periph) &= ~interrupt;
890 }
891
892 /*!
893 \brief get I2C interrupt flag status
894 \param[in] i2c_periph: I2Cx(x=0,1)
895 \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
896 only one parameter can be selected which is shown as below:
897 \arg I2C_INT_FLAG_TI: transmit interrupt flag
898 \arg I2C_INT_FLAG_RBNE: I2C_RDATA is not empty during receiving interrupt flag
899 \arg I2C_INT_FLAG_ADDSEND: address received matches in slave mode interrupt flag
900 \arg I2C_INT_FLAG_NACK: not acknowledge interrupt flag
901 \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag
902 \arg I2C_INT_FLAG_TC: transfer complete in master mode interrupt flag
903 \arg I2C_INT_FLAG_TCR: transfer complete reload interrupt flag
904 \arg I2C_INT_FLAG_BERR: bus error interrupt flag
905 \arg I2C_INT_FLAG_LOSTARB: arbitration lost interrupt flag
906 \arg I2C_INT_FLAG_OUERR: overrun/underrun error in slave mode interrupt flag
907 \arg I2C_INT_FLAG_PECERR: PEC error interrupt flag
908 \arg I2C_INT_FLAG_TIMEOUT: timeout interrupt flag
909 \arg I2C_INT_FLAG_SMBALT: SMBus Alert interrupt flag
910 \param[out] none
911 \retval FlagStatus: SET or RESET
912 */
i2c_interrupt_flag_get(uint32_t i2c_periph,i2c_interrupt_flag_enum int_flag)913 FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
914 {
915 uint32_t ret1 = 0U;
916 uint32_t ret2 = 0U;
917
918 /* get the status of interrupt enable bit */
919 ret1 = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag)));
920 /* get the status of interrupt flag */
921 ret2 = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag)));
922 if(ret1 && ret2) {
923 return SET;
924 } else {
925 return RESET;
926 }
927 }
928
929 /*!
930 \brief clear I2C interrupt flag status
931 \param[in] i2c_periph: I2Cx(x=0,1)
932 \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
933 only one parameter can be selected which is shown as below:
934 \arg I2C_INT_FLAG_ADDSEND: address received matches in slave mode interrupt flag
935 \arg I2C_INT_FLAG_NACK: not acknowledge interrupt flag
936 \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag
937 \arg I2C_INT_FLAG_BERR: bus error interrupt flag
938 \arg I2C_INT_FLAG_LOSTARB: arbitration lost interrupt flag
939 \arg I2C_INT_FLAG_OUERR: overrun/underrun error in slave mode interrupt flag
940 \arg I2C_INT_FLAG_PECERR: PEC error interrupt flag
941 \arg I2C_INT_FLAG_TIMEOUT: timeout interrupt flag
942 \arg I2C_INT_FLAG_SMBALT: SMBus Alert interrupt flag
943 \param[out] none
944 \retval none
945 */
i2c_interrupt_flag_clear(uint32_t i2c_periph,i2c_interrupt_flag_enum int_flag)946 void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
947 {
948 I2C_STATC(i2c_periph) |= BIT(I2C_BIT_POS2(int_flag));
949 }
950