1 /*!
2 \file gd32f4xx_i2c.c
3 \brief I2C driver
4
5 \version 2016-08-15, V1.0.0, firmware for GD32F4xx
6 \version 2018-12-12, V2.0.0, firmware for GD32F4xx
7 \version 2019-04-16, V2.0.2, firmware for GD32F4xx
8 \version 2020-09-30, V2.1.0, firmware for GD32F4xx
9 \version 2022-03-09, V3.0.0, firmware for GD32F4xx
10 */
11
12 /*
13 Copyright (c) 2022, GigaDevice Semiconductor Inc.
14
15 Redistribution and use in source and binary forms, with or without modification,
16 are permitted provided that the following conditions are met:
17
18 1. Redistributions of source code must retain the above copyright notice, this
19 list of conditions and the following disclaimer.
20 2. Redistributions in binary form must reproduce the above copyright notice,
21 this list of conditions and the following disclaimer in the documentation
22 and/or other materials provided with the distribution.
23 3. Neither the name of the copyright holder nor the names of its contributors
24 may be used to endorse or promote products derived from this software without
25 specific prior written permission.
26
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
31 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 OF SUCH DAMAGE.
37 */
38
39 #include "gd32f4xx_i2c.h"
40
41 /* I2C register bit mask */
42 #define I2C_FLAG_MASK ((uint32_t)0x0000FFFFU) /*!< i2c flag mask */
43 #define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */
44 #define I2C_ADDRESS2_MASK ((uint32_t)0x000000FEU) /*!< the second i2c address mask */
45
46 /* I2C register bit offset */
47 #define STAT1_PECV_OFFSET ((uint32_t)0x00000008U) /* bit offset of PECV in I2C_STAT1 */
48
49 /*!
50 \brief reset I2C
51 \param[in] i2c_periph: I2Cx(x=0,1,2)
52 \param[out] none
53 \retval none
54 */
i2c_deinit(uint32_t i2c_periph)55 void i2c_deinit(uint32_t i2c_periph)
56 {
57 switch(i2c_periph) {
58 case I2C0:
59 /* reset I2C0 */
60 rcu_periph_reset_enable(RCU_I2C0RST);
61 rcu_periph_reset_disable(RCU_I2C0RST);
62 break;
63 case I2C1:
64 /* reset I2C1 */
65 rcu_periph_reset_enable(RCU_I2C1RST);
66 rcu_periph_reset_disable(RCU_I2C1RST);
67 break;
68 case I2C2:
69 /* reset I2C2 */
70 rcu_periph_reset_enable(RCU_I2C2RST);
71 rcu_periph_reset_disable(RCU_I2C2RST);
72 break;
73 default:
74 break;
75 }
76 }
77
78 /*!
79 \brief configure I2C clock
80 \param[in] i2c_periph: I2Cx(x=0,1,2)
81 \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz)
82 \param[in] dutycyc: duty cycle in fast mode
83 only one parameter can be selected which is shown as below:
84 \arg I2C_DTCY_2: T_low/T_high = 2 in fast mode
85 \arg I2C_DTCY_16_9: T_low/T_high = 16/9 in fast mode
86 \param[out] none
87 \retval none
88 */
i2c_clock_config(uint32_t i2c_periph,uint32_t clkspeed,uint32_t dutycyc)89 void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc)
90 {
91 uint32_t pclk1, clkc, freq, risetime;
92 uint32_t temp;
93
94 pclk1 = rcu_clock_freq_get(CK_APB1);
95 /* I2C peripheral clock frequency */
96 freq = (uint32_t)(pclk1 / 1000000U);
97 if(freq >= I2CCLK_MAX) {
98 freq = I2CCLK_MAX;
99 }
100 temp = I2C_CTL1(i2c_periph);
101 temp &= ~I2C_CTL1_I2CCLK;
102 temp |= freq;
103
104 I2C_CTL1(i2c_periph) = temp;
105
106 if(100000U >= clkspeed) {
107 /* the maximum SCL rise time is 1000ns in standard mode */
108 risetime = (uint32_t)((pclk1 / 1000000U) + 1U);
109 if(risetime >= I2CCLK_MAX) {
110 I2C_RT(i2c_periph) = I2CCLK_MAX;
111 } else if(risetime <= I2CCLK_MIN) {
112 I2C_RT(i2c_periph) = I2CCLK_MIN;
113 } else {
114 I2C_RT(i2c_periph) = risetime;
115 }
116 clkc = (uint32_t)(pclk1 / (clkspeed * 2U));
117 if(clkc < 0x04U) {
118 /* the CLKC in standard mode minmum value is 4 */
119 clkc = 0x04U;
120 }
121
122 I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc);
123
124 } else if(400000U >= clkspeed) {
125 /* the maximum SCL rise time is 300ns in fast mode */
126 I2C_RT(i2c_periph) = (uint32_t)(((freq * (uint32_t)300U) / (uint32_t)1000U) + (uint32_t)1U);
127 if(I2C_DTCY_2 == dutycyc) {
128 /* I2C duty cycle is 2 */
129 clkc = (uint32_t)(pclk1 / (clkspeed * 3U));
130 I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
131 } else {
132 /* I2C duty cycle is 16/9 */
133 clkc = (uint32_t)(pclk1 / (clkspeed * 25U));
134 I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
135 }
136 if(0U == (clkc & I2C_CKCFG_CLKC)) {
137 /* the CLKC in fast mode minmum value is 1 */
138 clkc |= 0x0001U;
139 }
140 I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
141 I2C_CKCFG(i2c_periph) |= clkc;
142 } else {
143 }
144 }
145
146 /*!
147 \brief configure I2C address
148 \param[in] i2c_periph: I2Cx(x=0,1,2)
149 \param[in] mode:
150 only one parameter can be selected which is shown as below:
151 \arg I2C_I2CMODE_ENABLE: I2C mode
152 \arg I2C_SMBUSMODE_ENABLE: SMBus mode
153 \param[in] addformat: 7bits or 10bits
154 only one parameter can be selected which is shown as below:
155 \arg I2C_ADDFORMAT_7BITS: address format is 7 bits
156 \arg I2C_ADDFORMAT_10BITS: address format is 10 bits
157 \param[in] addr: I2C address
158 \param[out] none
159 \retval none
160 */
i2c_mode_addr_config(uint32_t i2c_periph,uint32_t mode,uint32_t addformat,uint32_t addr)161 void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr)
162 {
163 /* SMBus/I2C mode selected */
164 uint32_t ctl = 0U;
165
166 ctl = I2C_CTL0(i2c_periph);
167 ctl &= ~(I2C_CTL0_SMBEN);
168 ctl |= mode;
169 I2C_CTL0(i2c_periph) = ctl;
170 /* configure address */
171 addr = addr & I2C_ADDRESS_MASK;
172 I2C_SADDR0(i2c_periph) = (addformat | addr);
173 }
174
175 /*!
176 \brief select SMBus type
177 \param[in] i2c_periph: I2Cx(x=0,1,2)
178 \param[in] type:
179 only one parameter can be selected which is shown as below:
180 \arg I2C_SMBUS_DEVICE: SMBus mode device type
181 \arg I2C_SMBUS_HOST: SMBus mode host type
182 \param[out] none
183 \retval none
184 */
i2c_smbus_type_config(uint32_t i2c_periph,uint32_t type)185 void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type)
186 {
187 if(I2C_SMBUS_HOST == type) {
188 I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL;
189 } else {
190 I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL);
191 }
192 }
193
194 /*!
195 \brief whether or not to send an ACK
196 \param[in] i2c_periph: I2Cx(x=0,1,2)
197 \param[in] ack:
198 only one parameter can be selected which is shown as below:
199 \arg I2C_ACK_ENABLE: ACK will be sent
200 \arg I2C_ACK_DISABLE: ACK will not be sent
201 \param[out] none
202 \retval none
203 */
i2c_ack_config(uint32_t i2c_periph,uint32_t ack)204 void i2c_ack_config(uint32_t i2c_periph, uint32_t ack)
205 {
206 uint32_t ctl = 0U;
207
208 ctl = I2C_CTL0(i2c_periph);
209 ctl &= ~(I2C_CTL0_ACKEN);
210 ctl |= ack;
211 I2C_CTL0(i2c_periph) = ctl;
212 }
213
214 /*!
215 \brief configure I2C POAP position
216 \param[in] i2c_periph: I2Cx(x=0,1,2)
217 \param[in] pos:
218 only one parameter can be selected which is shown as below:
219 \arg I2C_ACKPOS_CURRENT: ACKEN bit decides whether or not to send ACK or not for the current byte
220 \arg I2C_ACKPOS_NEXT: ACKEN bit decides whether or not to send ACK for the next byte
221 \param[out] none
222 \retval none
223 */
i2c_ackpos_config(uint32_t i2c_periph,uint32_t pos)224 void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos)
225 {
226 uint32_t ctl = 0U;
227 /* configure I2C POAP position */
228 ctl = I2C_CTL0(i2c_periph);
229 ctl &= ~(I2C_CTL0_POAP);
230 ctl |= pos;
231 I2C_CTL0(i2c_periph) = ctl;
232 }
233
234 /*!
235 \brief master sends slave address
236 \param[in] i2c_periph: I2Cx(x=0,1,2)
237 \param[in] addr: slave address
238 \param[in] trandirection: transmitter or receiver
239 only one parameter can be selected which is shown as below:
240 \arg I2C_TRANSMITTER: transmitter
241 \arg I2C_RECEIVER: receiver
242 \param[out] none
243 \retval none
244 */
i2c_master_addressing(uint32_t i2c_periph,uint32_t addr,uint32_t trandirection)245 void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection)
246 {
247 /* master is a transmitter or a receiver */
248 if(I2C_TRANSMITTER == trandirection) {
249 addr = addr & I2C_TRANSMITTER;
250 } else {
251 addr = addr | I2C_RECEIVER;
252 }
253 /* send slave address */
254 I2C_DATA(i2c_periph) = addr;
255 }
256
257 /*!
258 \brief enable dual-address mode
259 \param[in] i2c_periph: I2Cx(x=0,1,2)
260 \param[in] addr: the second address in dual-address mode
261 \param[out] none
262 \retval none
263 */
i2c_dualaddr_enable(uint32_t i2c_periph,uint32_t addr)264 void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr)
265 {
266 /* configure address */
267 addr = addr & I2C_ADDRESS2_MASK;
268 I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | addr);
269 }
270
271 /*!
272 \brief disable dual-address mode
273 \param[in] i2c_periph: I2Cx(x=0,1,2)
274 \param[out] none
275 \retval none
276 */
i2c_dualaddr_disable(uint32_t i2c_periph)277 void i2c_dualaddr_disable(uint32_t i2c_periph)
278 {
279 I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN);
280 }
281
282 /*!
283 \brief enable I2C
284 \param[in] i2c_periph: I2Cx(x=0,1,2)
285 \param[out] none
286 \retval none
287 */
i2c_enable(uint32_t i2c_periph)288 void i2c_enable(uint32_t i2c_periph)
289 {
290 I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN;
291 }
292
293 /*!
294 \brief disable I2C
295 \param[in] i2c_periph: I2Cx(x=0,1,2)
296 \param[out] none
297 \retval none
298 */
i2c_disable(uint32_t i2c_periph)299 void i2c_disable(uint32_t i2c_periph)
300 {
301 I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN);
302 }
303
304 /*!
305 \brief generate a START condition on I2C bus
306 \param[in] i2c_periph: I2Cx(x=0,1,2)
307 \param[out] none
308 \retval none
309 */
i2c_start_on_bus(uint32_t i2c_periph)310 void i2c_start_on_bus(uint32_t i2c_periph)
311 {
312 I2C_CTL0(i2c_periph) |= I2C_CTL0_START;
313 }
314
315 /*!
316 \brief generate a STOP condition on I2C bus
317 \param[in] i2c_periph: I2Cx(x=0,1,2)
318 \param[out] none
319 \retval none
320 */
i2c_stop_on_bus(uint32_t i2c_periph)321 void i2c_stop_on_bus(uint32_t i2c_periph)
322 {
323 I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP;
324 }
325
326 /*!
327 \brief I2C transmit data function
328 \param[in] i2c_periph: I2Cx(x=0,1,2)
329 \param[in] data: data of transmission
330 \param[out] none
331 \retval none
332 */
i2c_data_transmit(uint32_t i2c_periph,uint8_t data)333 void i2c_data_transmit(uint32_t i2c_periph, uint8_t data)
334 {
335 I2C_DATA(i2c_periph) = DATA_TRANS(data);
336 }
337
338 /*!
339 \brief I2C receive data function
340 \param[in] i2c_periph: I2Cx(x=0,1,2)
341 \param[out] none
342 \retval data of received
343 */
i2c_data_receive(uint32_t i2c_periph)344 uint8_t i2c_data_receive(uint32_t i2c_periph)
345 {
346 return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph));
347 }
348
349 /*!
350 \brief configure I2C DMA mode
351 \param[in] i2c_periph: I2Cx(x=0,1,2)
352 \param[in] dmastate:
353 only one parameter can be selected which is shown as below:
354 \arg I2C_DMA_ON: enable DMA mode
355 \arg I2C_DMA_OFF: disable DMA mode
356 \param[out] none
357 \retval none
358 */
i2c_dma_config(uint32_t i2c_periph,uint32_t dmastate)359 void i2c_dma_config(uint32_t i2c_periph, uint32_t dmastate)
360 {
361 /* configure I2C DMA function */
362 uint32_t ctl = 0U;
363
364 ctl = I2C_CTL1(i2c_periph);
365 ctl &= ~(I2C_CTL1_DMAON);
366 ctl |= dmastate;
367 I2C_CTL1(i2c_periph) = ctl;
368 }
369
370 /*!
371 \brief configure whether next DMA EOT is DMA last transfer or not
372 \param[in] i2c_periph: I2Cx(x=0,1,2)
373 \param[in] dmalast:
374 only one parameter can be selected which is shown as below:
375 \arg I2C_DMALST_ON: next DMA EOT is the last transfer
376 \arg I2C_DMALST_OFF: next DMA EOT is not the last transfer
377 \param[out] none
378 \retval none
379 */
i2c_dma_last_transfer_config(uint32_t i2c_periph,uint32_t dmalast)380 void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast)
381 {
382 /* configure DMA last transfer */
383 uint32_t ctl = 0U;
384
385 ctl = I2C_CTL1(i2c_periph);
386 ctl &= ~(I2C_CTL1_DMALST);
387 ctl |= dmalast;
388 I2C_CTL1(i2c_periph) = ctl;
389 }
390
391 /*!
392 \brief whether to stretch SCL low when data is not ready in slave mode
393 \param[in] i2c_periph: I2Cx(x=0,1,2)
394 \param[in] stretchpara:
395 only one parameter can be selected which is shown as below:
396 \arg I2C_SCLSTRETCH_ENABLE: enable SCL stretching
397 \arg I2C_SCLSTRETCH_DISABLE: disable SCL stretching
398 \param[out] none
399 \retval none
400 */
i2c_stretch_scl_low_config(uint32_t i2c_periph,uint32_t stretchpara)401 void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara)
402 {
403 /* configure I2C SCL strerching */
404 uint32_t ctl = 0U;
405
406 ctl = I2C_CTL0(i2c_periph);
407 ctl &= ~(I2C_CTL0_SS);
408 ctl |= stretchpara;
409 I2C_CTL0(i2c_periph) = ctl;
410 }
411
412 /*!
413 \brief whether or not to response to a general call
414 \param[in] i2c_periph: I2Cx(x=0,1,2)
415 \param[in] gcallpara:
416 only one parameter can be selected which is shown as below:
417 \arg I2C_GCEN_ENABLE: slave will response to a general call
418 \arg I2C_GCEN_DISABLE: slave will not response to a general call
419 \param[out] none
420 \retval none
421 */
i2c_slave_response_to_gcall_config(uint32_t i2c_periph,uint32_t gcallpara)422 void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara)
423 {
424 /* configure slave response to a general call enable or disable */
425 uint32_t ctl = 0U;
426
427 ctl = I2C_CTL0(i2c_periph);
428 ctl &= ~(I2C_CTL0_GCEN);
429 ctl |= gcallpara;
430 I2C_CTL0(i2c_periph) = ctl;
431 }
432
433 /*!
434 \brief configure software reset of I2C
435 \param[in] i2c_periph: I2Cx(x=0,1,2)
436 \param[in] sreset:
437 only one parameter can be selected which is shown as below:
438 \arg I2C_SRESET_SET: I2C is under reset
439 \arg I2C_SRESET_RESET: I2C is not under reset
440 \param[out] none
441 \retval none
442 */
i2c_software_reset_config(uint32_t i2c_periph,uint32_t sreset)443 void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset)
444 {
445 /* modify CTL0 and configure software reset I2C state */
446 uint32_t ctl = 0U;
447
448 ctl = I2C_CTL0(i2c_periph);
449 ctl &= ~(I2C_CTL0_SRESET);
450 ctl |= sreset;
451 I2C_CTL0(i2c_periph) = ctl;
452 }
453
454 /*!
455 \brief configure I2C PEC calculation
456 \param[in] i2c_periph: I2Cx(x=0,1,2)
457 \param[in] pecstate:
458 only one parameter can be selected which is shown as below:
459 \arg I2C_PEC_ENABLE: PEC calculation on
460 \arg I2C_PEC_DISABLE: PEC calculation off
461 \param[out] none
462 \retval none
463 */
i2c_pec_config(uint32_t i2c_periph,uint32_t pecstate)464 void i2c_pec_config(uint32_t i2c_periph, uint32_t pecstate)
465 {
466 /* on/off PEC calculation */
467 uint32_t ctl = 0U;
468
469 ctl = I2C_CTL0(i2c_periph);
470 ctl &= ~(I2C_CTL0_PECEN);
471 ctl |= pecstate;
472 I2C_CTL0(i2c_periph) = ctl;
473 }
474
475 /*!
476 \brief configure whether to transfer PEC value
477 \param[in] i2c_periph: I2Cx(x=0,1,2)
478 \param[in] pecpara:
479 only one parameter can be selected which is shown as below:
480 \arg I2C_PECTRANS_ENABLE: transfer PEC value
481 \arg I2C_PECTRANS_DISABLE: not transfer PEC value
482 \param[out] none
483 \retval none
484 */
i2c_pec_transfer_config(uint32_t i2c_periph,uint32_t pecpara)485 void i2c_pec_transfer_config(uint32_t i2c_periph, uint32_t pecpara)
486 {
487 /* whether to transfer PEC */
488 uint32_t ctl = 0U;
489
490 ctl = I2C_CTL0(i2c_periph);
491 ctl &= ~(I2C_CTL0_PECTRANS);
492 ctl |= pecpara;
493 I2C_CTL0(i2c_periph) = ctl;
494 }
495
496 /*!
497 \brief get packet error checking value
498 \param[in] i2c_periph: I2Cx(x=0,1,2)
499 \param[out] none
500 \retval PEC value
501 */
i2c_pec_value_get(uint32_t i2c_periph)502 uint8_t i2c_pec_value_get(uint32_t i2c_periph)
503 {
504 return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV) >> STAT1_PECV_OFFSET);
505 }
506
507 /*!
508 \brief configure I2C alert through SMBA pin
509 \param[in] i2c_periph: I2Cx(x=0,1,2)
510 \param[in] smbuspara:
511 only one parameter can be selected which is shown as below:
512 \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin
513 \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin
514 \param[out] none
515 \retval none
516 */
i2c_smbus_alert_config(uint32_t i2c_periph,uint32_t smbuspara)517 void i2c_smbus_alert_config(uint32_t i2c_periph, uint32_t smbuspara)
518 {
519 /* configure smubus alert through SMBA pin */
520 uint32_t ctl = 0U;
521
522 ctl = I2C_CTL0(i2c_periph);
523 ctl &= ~(I2C_CTL0_SALT);
524 ctl |= smbuspara;
525 I2C_CTL0(i2c_periph) = ctl;
526 }
527
528 /*!
529 \brief configure I2C ARP protocol in SMBus
530 \param[in] i2c_periph: I2Cx(x=0,1,2)
531 \param[in] arpstate:
532 only one parameter can be selected which is shown as below:
533 \arg I2C_ARP_ENABLE: enable ARP
534 \arg I2C_ARP_DISABLE: disable ARP
535 \param[out] none
536 \retval none
537 */
i2c_smbus_arp_config(uint32_t i2c_periph,uint32_t arpstate)538 void i2c_smbus_arp_config(uint32_t i2c_periph, uint32_t arpstate)
539 {
540 /* enable or disable I2C ARP protocol*/
541 uint32_t ctl = 0U;
542
543 ctl = I2C_CTL0(i2c_periph);
544 ctl &= ~(I2C_CTL0_ARPEN);
545 ctl |= arpstate;
546 I2C_CTL0(i2c_periph) = ctl;
547 }
548
549 /*!
550 \brief disable analog noise filter
551 \param[in] i2c_periph: I2Cx(x=0,1,2)
552 \param[out] none
553 \retval none
554 */
i2c_analog_noise_filter_disable(uint32_t i2c_periph)555 void i2c_analog_noise_filter_disable(uint32_t i2c_periph)
556 {
557 I2C_FCTL(i2c_periph) |= I2C_FCTL_AFD;
558 }
559
560 /*!
561 \brief enable analog noise filter
562 \param[in] i2c_periph: I2Cx(x=0,1,2)
563 \param[out] none
564 \retval none
565 */
i2c_analog_noise_filter_enable(uint32_t i2c_periph)566 void i2c_analog_noise_filter_enable(uint32_t i2c_periph)
567 {
568 I2C_FCTL(i2c_periph) &= ~(I2C_FCTL_AFD);
569 }
570
571 /*!
572 \brief configure digital noise filter
573 \param[in] i2c_periph: I2Cx(x=0,1,2)
574 \param[in] dfilterpara: refer to i2c_digital_filter_enum
575 only one parameter can be selected which is shown as below:
576 \arg I2C_DF_DISABLE: disable digital noise filter
577 \arg I2C_DF_1PCLK: enable digital noise filter and the maximum filtered spiker's length 1 PCLK1
578 \arg I2C_DF_2PCLK: enable digital noise filter and the maximum filtered spiker's length 2 PCLK1
579 \arg I2C_DF_3PCLK: enable digital noise filter and the maximum filtered spiker's length 3 PCLK1
580 \arg I2C_DF_4PCLK: enable digital noise filter and the maximum filtered spiker's length 4 PCLK1
581 \arg I2C_DF_5PCLK: enable digital noise filter and the maximum filtered spiker's length 5 PCLK1
582 \arg I2C_DF_6PCLK: enable digital noise filter and the maximum filtered spiker's length 6 PCLK1
583 \arg I2C_DF_7PCLK: enable digital noise filter and the maximum filtered spiker's length 7 PCLK1
584 \arg I2C_DF_8PCLK: enable digital noise filter and the maximum filtered spiker's length 8 PCLK1
585 \arg I2C_DF_9PCLK: enable digital noise filter and the maximum filtered spiker's length 9 PCLK1
586 \arg I2C_DF_10PCLK: enable digital noise filter and the maximum filtered spiker's length 10 PCLK1
587 \arg I2C_DF_11CLK: enable digital noise filter and the maximum filtered spiker's length 11 PCLK1
588 \arg I2C_DF_12CLK: enable digital noise filter and the maximum filtered spiker's length 12 PCLK1
589 \arg I2C_DF_13PCLK: enable digital noise filter and the maximum filtered spiker's length 13 PCLK1
590 \arg I2C_DF_14PCLK: enable digital noise filter and the maximum filtered spiker's length 14 PCLK1
591 \arg I2C_DF_15PCLK: enable digital noise filter and the maximum filtered spiker's length 15 PCLK1
592 \param[out] none
593 \retval none
594 */
i2c_digital_noise_filter_config(uint32_t i2c_periph,i2c_digital_filter_enum dfilterpara)595 void i2c_digital_noise_filter_config(uint32_t i2c_periph, i2c_digital_filter_enum dfilterpara)
596 {
597 I2C_FCTL(i2c_periph) |= dfilterpara;
598 }
599
600 /*!
601 \brief enable SAM_V interface
602 \param[in] i2c_periph: I2Cx(x=0,1,2)
603 \param[out] none
604 \retval none
605 */
i2c_sam_enable(uint32_t i2c_periph)606 void i2c_sam_enable(uint32_t i2c_periph)
607 {
608 I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN;
609 }
610
611 /*!
612 \brief disable SAM_V interface
613 \param[in] i2c_periph: I2Cx(x=0,1,2)
614 \param[out] none
615 \retval none
616 */
i2c_sam_disable(uint32_t i2c_periph)617 void i2c_sam_disable(uint32_t i2c_periph)
618 {
619 I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN);
620 }
621
622 /*!
623 \brief enable SAM_V interface timeout detect
624 \param[in] i2c_periph: I2Cx(x=0,1,2)
625 \param[out] none
626 \retval none
627 */
i2c_sam_timeout_enable(uint32_t i2c_periph)628 void i2c_sam_timeout_enable(uint32_t i2c_periph)
629 {
630 I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN;
631 }
632
633 /*!
634 \brief disable SAM_V interface timeout detect
635 \param[in] i2c_periph: I2Cx(x=0,1,2)
636 \param[out] none
637 \retval none
638 */
i2c_sam_timeout_disable(uint32_t i2c_periph)639 void i2c_sam_timeout_disable(uint32_t i2c_periph)
640 {
641 I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN);
642 }
643
644 /*!
645 \brief get I2C flag status
646 \param[in] i2c_periph: I2Cx(x=0,1,2)
647 \param[in] flag: I2C flags, refer to i2c_flag_enum
648 only one parameter can be selected which is shown as below:
649 \arg I2C_FLAG_SBSEND: start condition sent out in master mode
650 \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode
651 \arg I2C_FLAG_BTC: byte transmission finishes
652 \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode
653 \arg I2C_FLAG_STPDET: stop condition detected in slave mode
654 \arg I2C_FLAG_RBNE: I2C_DATA is not empty during receiving
655 \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting
656 \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
657 \arg I2C_FLAG_LOSTARB: arbitration lost in master mode
658 \arg I2C_FLAG_AERR: acknowledge error
659 \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode
660 \arg I2C_FLAG_PECERR: PEC error when receiving data
661 \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
662 \arg I2C_FLAG_SMBALT: SMBus alert status
663 \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode
664 \arg I2C_FLAG_I2CBSY: busy flag
665 \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver
666 \arg I2C_FLAG_RXGC: general call address (00h) received
667 \arg I2C_FLAG_DEFSMB: default address of SMBus device
668 \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode
669 \arg I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode
670 \arg I2C_FLAG_TFF: txframe fall flag
671 \arg I2C_FLAG_TFR: txframe rise flag
672 \arg I2C_FLAG_RFF: rxframe fall flag
673 \arg I2C_FLAG_RFR: rxframe rise flag
674 \param[out] none
675 \retval FlagStatus: SET or RESET
676 */
i2c_flag_get(uint32_t i2c_periph,i2c_flag_enum flag)677 FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag)
678 {
679 if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))) {
680 return SET;
681 } else {
682 return RESET;
683 }
684 }
685
686 /*!
687 \brief clear I2C flag status
688 \param[in] i2c_periph: I2Cx(x=0,1,2)
689 \param[in] flag: I2C flags, refer to i2c_flag_enum
690 only one parameter can be selected which is shown as below:
691 \arg I2C_FLAG_SMBALT: SMBus alert status
692 \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
693 \arg I2C_FLAG_PECERR: PEC error when receiving data
694 \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode
695 \arg I2C_FLAG_AERR: acknowledge error
696 \arg I2C_FLAG_LOSTARB: arbitration lost in master mode
697 \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
698 \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode
699 \arg I2C_FLAG_TFF: txframe fall flag
700 \arg I2C_FLAG_TFR: txframe rise flag
701 \arg I2C_FLAG_RFF: rxframe fall flag
702 \arg I2C_FLAG_RFR: rxframe rise flag
703 \param[out] none
704 \retval none
705 */
i2c_flag_clear(uint32_t i2c_periph,i2c_flag_enum flag)706 void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag)
707 {
708 if(I2C_FLAG_ADDSEND == flag) {
709 /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
710 I2C_STAT0(i2c_periph);
711 I2C_STAT1(i2c_periph);
712 } else {
713 I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag));
714 }
715 }
716
717 /*!
718 \brief enable I2C interrupt
719 \param[in] i2c_periph: I2Cx(x=0,1,2)
720 \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum
721 only one parameter can be selected which is shown as below:
722 \arg I2C_INT_ERR: error interrupt
723 \arg I2C_INT_EV: event interrupt
724 \arg I2C_INT_BUF: buffer interrupt
725 \arg I2C_INT_TFF: txframe fall interrupt
726 \arg I2C_INT_TFR: txframe rise interrupt
727 \arg I2C_INT_RFF: rxframe fall interrupt
728 \arg I2C_INT_RFR: rxframe rise interrupt
729 \param[out] none
730 \retval none
731 */
i2c_interrupt_enable(uint32_t i2c_periph,i2c_interrupt_enum interrupt)732 void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt)
733 {
734 I2C_REG_VAL(i2c_periph, interrupt) |= BIT(I2C_BIT_POS(interrupt));
735 }
736
737 /*!
738 \brief disable I2C interrupt
739 \param[in] i2c_periph: I2Cx(x=0,1,2)
740 \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum
741 only one parameter can be selected which is shown as below:
742 \arg I2C_INT_ERR: error interrupt
743 \arg I2C_INT_EV: event interrupt
744 \arg I2C_INT_BUF: buffer interrupt
745 \arg I2C_INT_TFF: txframe fall interrupt
746 \arg I2C_INT_TFR: txframe rise interrupt
747 \arg I2C_INT_RFF: rxframe fall interrupt
748 \arg I2C_INT_RFR: rxframe rise interrupt
749 \param[out] none
750 \retval none
751 */
i2c_interrupt_disable(uint32_t i2c_periph,i2c_interrupt_enum interrupt)752 void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt)
753 {
754 I2C_REG_VAL(i2c_periph, interrupt) &= ~BIT(I2C_BIT_POS(interrupt));
755 }
756
757 /*!
758 \brief get I2C interrupt flag status
759 \param[in] i2c_periph: I2Cx(x=0,1,2)
760 \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
761 only one parameter can be selected which is shown as below:
762 \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag
763 \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
764 \arg I2C_INT_FLAG_BTC: byte transmission finishes interrupt flag
765 \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag
766 \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag
767 \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag
768 \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag
769 \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
770 \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
771 \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
772 \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
773 \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
774 \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
775 \arg I2C_INT_FLAG_SMBALT: SMBus alert status interrupt flag
776 \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag
777 \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag
778 \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag
779 \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag
780 \param[out] none
781 \retval FlagStatus: SET or RESET
782 */
i2c_interrupt_flag_get(uint32_t i2c_periph,i2c_interrupt_flag_enum int_flag)783 FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
784 {
785 uint32_t intenable = 0U, flagstatus = 0U, bufie;
786
787 /* check BUFIE */
788 bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;
789
790 /* get the interrupt enable bit status */
791 intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag)));
792 /* get the corresponding flag bit status */
793 flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag)));
794
795 if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)) {
796 if(intenable && bufie) {
797 intenable = 1U;
798 } else {
799 intenable = 0U;
800 }
801 }
802 if((0U != flagstatus) && (0U != intenable)) {
803 return SET;
804 } else {
805 return RESET;
806 }
807 }
808
809 /*!
810 \brief clear I2C interrupt flag status
811 \param[in] i2c_periph: I2Cx(x=0,1,2)
812 \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
813 only one parameter can be selected which is shown as below:
814 \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
815 \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
816 \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
817 \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
818 \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
819 \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
820 \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
821 \arg I2C_INT_FLAG_SMBALT: SMBus alert status interrupt flag
822 \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag
823 \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag
824 \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag
825 \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag
826 \param[out] none
827 \retval none
828 */
i2c_interrupt_flag_clear(uint32_t i2c_periph,i2c_interrupt_flag_enum int_flag)829 void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
830 {
831 if(I2C_INT_FLAG_ADDSEND == int_flag) {
832 /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
833 I2C_STAT0(i2c_periph);
834 I2C_STAT1(i2c_periph);
835 } else {
836 I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag));
837 }
838 }
839