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