libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
i2c_common_v1.c
Go to the documentation of this file.
1/** @addtogroup i2c_file I2C peripheral API
2 * @ingroup peripheral_apis
3
4@author @htmlonly © @endhtmlonly 2010
5Thomas Otto <tommi@viadmin.org>
6@author @htmlonly &copy; @endhtmlonly 2012
7Ken Sarkies <ksarkies@internode.on.net>
8
9Devices can have up to three I2C peripherals. The peripherals support SMBus and
10PMBus variants.
11
12A peripheral begins after reset in Slave mode. To become a Master a start
13condition must be generated. The peripheral will remain in Master mode unless
14a multimaster contention is lost or a stop condition is generated.
15
16@todo all sorts of lovely stuff like DMA, Interrupts, SMBus variant, Status
17register access, Error conditions
18
19*/
20/*
21 * This file is part of the libopencm3 project.
22 *
23 * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
24 *
25 * This library is free software: you can redistribute it and/or modify
26 * it under the terms of the GNU Lesser General Public License as published by
27 * the Free Software Foundation, either version 3 of the License, or
28 * (at your option) any later version.
29 *
30 * This library is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU Lesser General Public License for more details.
34 *
35 * You should have received a copy of the GNU Lesser General Public License
36 * along with this library. If not, see <http://www.gnu.org/licenses/>.
37 */
38
41
42/**@{*/
43
44
45/*---------------------------------------------------------------------------*/
46/** @brief I2C Peripheral Enable.
47
48@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
49*/
50
51void i2c_peripheral_enable(uint32_t i2c)
52{
53 I2C_CR1(i2c) |= I2C_CR1_PE;
54}
55
56/*---------------------------------------------------------------------------*/
57/** @brief I2C Peripheral Disable.
58
59This must not be reset while in Master mode until a communication has finished.
60In Slave mode, the peripheral is disabled only after communication has ended.
61
62@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
63*/
64
65void i2c_peripheral_disable(uint32_t i2c)
66{
67 I2C_CR1(i2c) &= ~I2C_CR1_PE;
68}
69
70/*---------------------------------------------------------------------------*/
71/** @brief I2C Send Start Condition.
72
73If in Master mode this will cause a restart condition to occur at the end of the
74current transmission. If in Slave mode, this will initiate a start condition
75when the current bus activity is completed.
76
77@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
78*/
79
80void i2c_send_start(uint32_t i2c)
81{
82 I2C_CR1(i2c) |= I2C_CR1_START;
83}
84
85/*---------------------------------------------------------------------------*/
86/** @brief I2C Send Stop Condition.
87
88After the current byte transfer this will initiate a stop condition if in Master
89mode, or simply release the bus if in Slave mode.
90
91@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
92*/
93
94void i2c_send_stop(uint32_t i2c)
95{
96 I2C_CR1(i2c) |= I2C_CR1_STOP;
97}
98
99/*---------------------------------------------------------------------------*/
100/** @brief I2C Clear Stop Flag.
101
102Clear the "Send Stop" flag in the I2C config register
103
104@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
105*/
106void i2c_clear_stop(uint32_t i2c)
107{
108 I2C_CR1(i2c) &= ~I2C_CR1_STOP;
109}
110
111/*---------------------------------------------------------------------------*/
112/** @brief I2C Set the 7 bit Slave Address for the Peripheral.
113
114This sets an address for Slave mode operation, in 7 bit form.
115
116@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
117@param[in] slave Unsigned int8. Slave address 0...127.
118*/
119
120void i2c_set_own_7bit_slave_address(uint32_t i2c, uint8_t slave)
121{
122 uint16_t val = (uint16_t)(slave << 1);
123 /* Datasheet: always keep 1 by software. */
124 val |= (1 << 14);
125 I2C_OAR1(i2c) = val;
126}
127
128/*---------------------------------------------------------------------------*/
129/** @brief I2C Set the 10 bit Slave Address for the Peripheral.
130
131This sets an address for Slave mode operation, in 10 bit form.
132
133@todo add "I2C_OAR1(i2c) |= (1 << 14);" as above
134
135@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
136@param[in] slave Unsigned int16. Slave address 0...1023.
137*/
138
139void i2c_set_own_10bit_slave_address(uint32_t i2c, uint16_t slave)
140{
141 I2C_OAR1(i2c) = (uint16_t)(I2C_OAR1_ADDMODE | slave);
142}
143
144/*---------------------------------------------------------------------------*/
145/** @brief I2C Set the secondary 7 bit Slave Address for the Peripheral.
146
147This sets a secondary address for Slave mode operation, in 7 bit form.
148
149
150@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
151@param[in] slave Unsigned int8. Slave address 0...127.
152*/
153
154void i2c_set_own_7bit_slave_address_two(uint32_t i2c, uint8_t slave)
155{
156 uint16_t val = (uint16_t)(slave << 1);
157 I2C_OAR2(i2c) = val;
158}
159
160/*---------------------------------------------------------------------------*/
161/** @brief I2C Enable dual addressing mode for the Peripheral.
162
163Both OAR1 and OAR2 are recognised in 7-bit addressing mode.
164
165@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
166*/
167
169{
171}
172
173/*---------------------------------------------------------------------------*/
174/** @brief I2C Disable dual addressing mode for the Peripheral.
175
176Only OAR1 is recognised in 7-bit addressing mode.
177
178@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
179*/
180
182{
183 I2C_OAR2(i2c) &= ~(I2C_OAR2_ENDUAL);
184}
185
186/*---------------------------------------------------------------------------*/
187/** @brief I2C Set Peripheral Clock Frequency.
188
189Set the peripheral clock frequency: 2MHz to 36MHz (the APB frequency). Note
190that this is <b> not </b> the I2C bus clock. This is set in conjunction with
191the Clock Control register to generate the Master bus clock, see @ref
192i2c_set_ccr
193
194@param[in] i2c I2C register base address @ref i2c_reg_base
195@param[in] freq Clock Frequency Setting in MHz, valid range depends on part,+
196 normally 2Mhz->Max APB speed.
197*/
198
199void i2c_set_clock_frequency(uint32_t i2c, uint8_t freq)
200{
201 uint16_t reg16;
202 reg16 = I2C_CR2(i2c) & 0xffc0; /* Clear bits [5:0]. */
203 reg16 |= freq;
204 I2C_CR2(i2c) = reg16;
205}
206
207/*---------------------------------------------------------------------------*/
208/** @brief I2C Send Data.
209
210@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
211@param[in] data Unsigned int8. Byte to send.
212*/
213
214void i2c_send_data(uint32_t i2c, uint8_t data)
215{
216 I2C_DR(i2c) = data;
217}
218
219/*---------------------------------------------------------------------------*/
220/** @brief I2C Set Fast Mode.
221
222Set the clock frequency to the high clock rate mode (up to 400kHz). The actual
223clock frequency must be set with @ref i2c_set_clock_frequency
224
225@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
226*/
227
228void i2c_set_fast_mode(uint32_t i2c)
229{
230 I2C_CCR(i2c) |= I2C_CCR_FS;
231}
232
233/*---------------------------------------------------------------------------*/
234/** @brief I2C Set Standard Mode.
235
236Set the clock frequency to the standard clock rate mode (up to 100kHz). The
237actual clock frequency must be set with @ref i2c_set_clock_frequency
238
239@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
240*/
241
242void i2c_set_standard_mode(uint32_t i2c)
243{
244 I2C_CCR(i2c) &= ~I2C_CCR_FS;
245}
246
247/*---------------------------------------------------------------------------*/
248/** @brief I2C Set Bus Clock Frequency.
249
250Set the bus clock frequency. This is a 12 bit number (0...4095) calculated
251from the formulae given in the STM32F1 reference manual in the description
252of the CCR field. It is a divisor of the peripheral clock frequency
253@ref i2c_set_clock_frequency modified by the fast mode setting
254@ref i2c_set_fast_mode
255
256@todo provide additional API assitance to set the clock, eg macros
257
258@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
259@param[in] freq Unsigned int16. Bus Clock Frequency Setting 0...4095.
260*/
261
262void i2c_set_ccr(uint32_t i2c, uint16_t freq)
263{
264 uint16_t reg16;
265 reg16 = I2C_CCR(i2c) & 0xf000; /* Clear bits [11:0]. */
266 reg16 |= freq;
267 I2C_CCR(i2c) = reg16;
268}
269
270/*---------------------------------------------------------------------------*/
271/** @brief I2C Set the Rise Time.
272
273Set the maximum rise time on the bus according to the I2C specification, as 1
274more than the specified rise time in peripheral clock cycles. This is a 6 bit
275number.
276
277@todo provide additional APIP assistance.
278
279@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
280@param[in] trise Unsigned int16. Rise Time Setting 0...63.
281*/
282
283void i2c_set_trise(uint32_t i2c, uint16_t trise)
284{
285 I2C_TRISE(i2c) = trise;
286}
287
288/*---------------------------------------------------------------------------*/
289/** @brief I2C Send the 7-bit Slave Address.
290
291@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
292@param[in] slave Unsigned int16. Slave address 0...1023.
293@param[in] readwrite Unsigned int8. Single bit to instruct slave to receive or
294send @ref i2c_rw.
295*/
296
297void i2c_send_7bit_address(uint32_t i2c, uint8_t slave, uint8_t readwrite)
298{
299 I2C_DR(i2c) = (uint8_t)((slave << 1) | readwrite);
300}
301
302/*---------------------------------------------------------------------------*/
303/** @brief I2C Get Data.
304
305@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
306*/
307uint8_t i2c_get_data(uint32_t i2c)
308{
309 return I2C_DR(i2c) & 0xff;
310}
311
312/*---------------------------------------------------------------------------*/
313/** @brief I2C Enable Interrupt
314
315@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
316@param[in] interrupt Unsigned int32. Interrupt to enable.
317*/
318void i2c_enable_interrupt(uint32_t i2c, uint32_t interrupt)
319{
320 I2C_CR2(i2c) |= interrupt;
321}
322
323/*---------------------------------------------------------------------------*/
324/** @brief I2C Disable Interrupt
325
326@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
327@param[in] interrupt Unsigned int32. Interrupt to disable.
328*/
329void i2c_disable_interrupt(uint32_t i2c, uint32_t interrupt)
330{
331 I2C_CR2(i2c) &= ~interrupt;
332}
333
334/*---------------------------------------------------------------------------*/
335/** @brief I2C Enable ACK
336
337Enables acking of own 7/10 bit address
338@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
339*/
340void i2c_enable_ack(uint32_t i2c)
341{
342 I2C_CR1(i2c) |= I2C_CR1_ACK;
343}
344
345/*---------------------------------------------------------------------------*/
346/** @brief I2C Disable ACK
347
348Disables acking of own 7/10 bit address
349@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
350*/
351void i2c_disable_ack(uint32_t i2c)
352{
353 I2C_CR1(i2c) &= ~I2C_CR1_ACK;
354}
355
356/*---------------------------------------------------------------------------*/
357/** @brief I2C NACK Next Byte
358
359Causes the I2C controller to NACK the reception of the next byte
360@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
361*/
362void i2c_nack_next(uint32_t i2c)
363{
364 I2C_CR1(i2c) |= I2C_CR1_POS;
365}
366
367/*---------------------------------------------------------------------------*/
368/** @brief I2C NACK Next Byte
369
370Causes the I2C controller to NACK the reception of the current byte
371
372@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
373*/
374void i2c_nack_current(uint32_t i2c)
375{
376 I2C_CR1(i2c) &= ~I2C_CR1_POS;
377}
378
379/*---------------------------------------------------------------------------*/
380/** @brief I2C Set clock duty cycle
381
382@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
383@param[in] dutycycle Unsigned int32. I2C duty cycle @ref i2c_duty_cycle.
384*/
385void i2c_set_dutycycle(uint32_t i2c, uint32_t dutycycle)
386{
387 if (dutycycle == I2C_CCR_DUTY_DIV2) {
388 I2C_CCR(i2c) &= ~I2C_CCR_DUTY;
389 } else {
390 I2C_CCR(i2c) |= I2C_CCR_DUTY;
391 }
392}
393
394/*---------------------------------------------------------------------------*/
395/** @brief I2C Enable DMA
396
397@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
398*/
399void i2c_enable_dma(uint32_t i2c)
400{
401 I2C_CR2(i2c) |= I2C_CR2_DMAEN;
402}
403
404/*---------------------------------------------------------------------------*/
405/** @brief I2C Disable DMA
406
407@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
408*/
409void i2c_disable_dma(uint32_t i2c)
410{
411 I2C_CR2(i2c) &= ~I2C_CR2_DMAEN;
412}
413
414/*---------------------------------------------------------------------------*/
415/** @brief I2C Set DMA last transfer
416
417@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
418*/
420{
421 I2C_CR2(i2c) |= I2C_CR2_LAST;
422}
423
424/*---------------------------------------------------------------------------*/
425/** @brief I2C Clear DMA last transfer
426
427@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
428*/
430{
431 I2C_CR2(i2c) &= ~I2C_CR2_LAST;
432}
433
434static void i2c_write7_v1(uint32_t i2c, int addr, const uint8_t *data, size_t n)
435{
436 while ((I2C_SR2(i2c) & I2C_SR2_BUSY)) {
437 }
438
439 i2c_send_start(i2c);
440
441 /* Wait for the end of the start condition, master mode selected, and BUSY bit set */
442 while ( !( (I2C_SR1(i2c) & I2C_SR1_SB)
443 && (I2C_SR2(i2c) & I2C_SR2_MSL)
444 && (I2C_SR2(i2c) & I2C_SR2_BUSY) ));
445
447
448 /* Waiting for address is transferred. */
449 while (!(I2C_SR1(i2c) & I2C_SR1_ADDR));
450
451 /* Clearing ADDR condition sequence. */
452 (void)I2C_SR2(i2c);
453
454 for (size_t i = 0; i < n; i++) {
455 i2c_send_data(i2c, data[i]);
456 while (!(I2C_SR1(i2c) & (I2C_SR1_BTF)));
457 }
458}
459
460static void i2c_read7_v1(uint32_t i2c, int addr, uint8_t *res, size_t n)
461{
462 i2c_send_start(i2c);
463 i2c_enable_ack(i2c);
464
465 /* Wait for the end of the start condition, master mode selected, and BUSY bit set */
466 while ( !( (I2C_SR1(i2c) & I2C_SR1_SB)
467 && (I2C_SR2(i2c) & I2C_SR2_MSL)
468 && (I2C_SR2(i2c) & I2C_SR2_BUSY) ));
469
471
472 /* Waiting for address is transferred. */
473 while (!(I2C_SR1(i2c) & I2C_SR1_ADDR));
474 /* Clearing ADDR condition sequence. */
475 (void)I2C_SR2(i2c);
476
477 for (size_t i = 0; i < n; ++i) {
478 if (i == n - 1) {
479 i2c_disable_ack(i2c);
480 }
481 while (!(I2C_SR1(i2c) & I2C_SR1_RxNE));
482 res[i] = i2c_get_data(i2c);
483 }
484 i2c_send_stop(i2c);
485
486 return;
487}
488
489/**
490 * Run a write/read transaction to a given 7bit i2c address
491 * If both write & read are provided, the read will use repeated start.
492 * Both write and read are optional
493 * There are likely still issues with repeated start/stop condtions!
494 * @param i2c peripheral of choice, eg I2C1
495 * @param addr 7 bit i2c device address
496 * @param w buffer of data to write
497 * @param wn length of w
498 * @param r destination buffer to read into
499 * @param rn number of bytes to read (r should be at least this long)
500 */
501void i2c_transfer7(uint32_t i2c, uint8_t addr, const uint8_t *w, size_t wn, uint8_t *r, size_t rn) {
502 if (wn) {
503 i2c_write7_v1(i2c, addr, w, wn);
504 }
505 if (rn) {
506 i2c_read7_v1(i2c, addr, r, rn);
507 } else {
508 i2c_send_stop(i2c);
509 }
510}
511
512/**
513 * Set the i2c communication speed.
514 * @param i2c peripheral, eg I2C1
515 * @param speed one of the listed speed modes @ref i2c_speeds
516 * @param clock_megahz i2c peripheral clock speed in MHz. Usually, rcc_apb1_frequency / 1e6
517 */
518void i2c_set_speed(uint32_t i2c, enum i2c_speeds speed, uint32_t clock_megahz)
519{
520 i2c_set_clock_frequency(i2c, clock_megahz);
521 switch(speed) {
524 i2c_set_ccr(i2c, clock_megahz * 5 / 6);
525 i2c_set_trise(i2c, clock_megahz + 1);
526 break;
527 default:
528 /* fall back to standard mode */
531 /* x Mhz / (100kHz * 2) */
532 i2c_set_ccr(i2c, clock_megahz * 5);
533 /* Sm mode, (100kHz) freqMhz + 1 */
534 i2c_set_trise(i2c, clock_megahz + 1);
535 break;
536 }
537}
538
539
540/**@}*/
#define I2C_CCR(i2c_base)
Definition: i2c_common_v1.h:93
#define I2C_CR1(i2c_base)
Definition: i2c_common_v1.h:58
#define I2C_CR1_START
#define I2C_SR1_RxNE
#define I2C_CR1_POS
#define I2C_SR2_BUSY
#define I2C_TRISE(i2c_base)
Definition: i2c_common_v1.h:98
#define I2C_SR1_ADDR
#define I2C_SR1(i2c_base)
Definition: i2c_common_v1.h:83
#define I2C_SR2(i2c_base)
Definition: i2c_common_v1.h:88
#define I2C_SR1_SB
#define I2C_CR2_LAST
#define I2C_SR2_MSL
#define I2C_OAR1_ADDMODE
#define I2C_CR1_PE
i2c_speeds
I2C speed modes.
#define I2C_OAR1(i2c_base)
Definition: i2c_common_v1.h:68
#define I2C_OAR2(i2c_base)
Definition: i2c_common_v1.h:73
#define I2C_OAR2_ENDUAL
#define I2C_CR1_STOP
#define I2C_CR2_DMAEN
#define I2C_CR2(i2c_base)
Definition: i2c_common_v1.h:63
#define I2C_DR(i2c_base)
Definition: i2c_common_v1.h:78
#define I2C_CCR_FS
#define I2C_CR1_ACK
#define I2C_SR1_BTF
@ i2c_speed_fm_400k
@ i2c_speed_sm_100k
#define I2C_CCR_DUTY_DIV2
#define I2C_CCR_DUTY
void i2c_disable_interrupt(uint32_t i2c, uint32_t interrupt)
I2C Disable Interrupt.
void i2c_enable_interrupt(uint32_t i2c, uint32_t interrupt)
I2C Enable Interrupt.
static void i2c_write7_v1(uint32_t i2c, int addr, const uint8_t *data, size_t n)
void i2c_disable_ack(uint32_t i2c)
I2C Disable ACK.
void i2c_set_dma_last_transfer(uint32_t i2c)
I2C Set DMA last transfer.
void i2c_nack_current(uint32_t i2c)
I2C NACK Next Byte.
void i2c_set_fast_mode(uint32_t i2c)
I2C Set Fast Mode.
void i2c_enable_ack(uint32_t i2c)
I2C Enable ACK.
void i2c_send_start(uint32_t i2c)
I2C Send Start Condition.
Definition: i2c_common_v1.c:80
void i2c_set_clock_frequency(uint32_t i2c, uint8_t freq)
I2C Set Peripheral Clock Frequency.
void i2c_peripheral_disable(uint32_t i2c)
I2C Peripheral Disable.
Definition: i2c_common_v1.c:65
void i2c_set_own_7bit_slave_address_two(uint32_t i2c, uint8_t slave)
I2C Set the secondary 7 bit Slave Address for the Peripheral.
void i2c_set_dutycycle(uint32_t i2c, uint32_t dutycycle)
I2C Set clock duty cycle.
void i2c_set_own_7bit_slave_address(uint32_t i2c, uint8_t slave)
I2C Set the 7 bit Slave Address for the Peripheral.
void i2c_disable_dual_addressing_mode(uint32_t i2c)
I2C Disable dual addressing mode for the Peripheral.
void i2c_set_standard_mode(uint32_t i2c)
I2C Set Standard Mode.
void i2c_set_trise(uint32_t i2c, uint16_t trise)
I2C Set the Rise Time.
void i2c_send_stop(uint32_t i2c)
I2C Send Stop Condition.
Definition: i2c_common_v1.c:94
void i2c_peripheral_enable(uint32_t i2c)
I2C Peripheral Enable.
Definition: i2c_common_v1.c:51
void i2c_nack_next(uint32_t i2c)
I2C NACK Next Byte.
void i2c_set_own_10bit_slave_address(uint32_t i2c, uint16_t slave)
I2C Set the 10 bit Slave Address for the Peripheral.
void i2c_disable_dma(uint32_t i2c)
I2C Disable DMA.
void i2c_send_data(uint32_t i2c, uint8_t data)
I2C Send Data.
void i2c_clear_dma_last_transfer(uint32_t i2c)
I2C Clear DMA last transfer.
uint8_t i2c_get_data(uint32_t i2c)
I2C Get Data.
static void i2c_read7_v1(uint32_t i2c, int addr, uint8_t *res, size_t n)
void i2c_clear_stop(uint32_t i2c)
I2C Clear Stop Flag.
void i2c_set_ccr(uint32_t i2c, uint16_t freq)
I2C Set Bus Clock Frequency.
void i2c_send_7bit_address(uint32_t i2c, uint8_t slave, uint8_t readwrite)
I2C Send the 7-bit Slave Address.
void i2c_enable_dual_addressing_mode(uint32_t i2c)
I2C Enable dual addressing mode for the Peripheral.
void i2c_transfer7(uint32_t i2c, uint8_t addr, const uint8_t *w, size_t wn, uint8_t *r, size_t rn)
Run a write/read transaction to a given 7bit i2c address If both write & read are provided,...
void i2c_enable_dma(uint32_t i2c)
I2C Enable DMA.
void i2c_set_speed(uint32_t i2c, enum i2c_speeds speed, uint32_t clock_megahz)
Set the i2c communication speed.
#define I2C_WRITE
#define I2C_READ