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