CuVoodoo STM32F1 firmware template
i2c_master.c
Go to the documentation of this file.
1 /* This program is free software: you can redistribute it and/or modify
2  * it under the terms of the GNU General Public License as published by
3  * the Free Software Foundation, either version 3 of the License, or
4  * (at your option) any later version.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program. If not, see <http://www.gnu.org/licenses/>.
13  *
14  */
22 /* standard libraries */
23 #include <stdint.h> // standard integer types
24 #include <stdlib.h> // general utilities
25 
26 /* STM32 (including CM3) libraries */
27 #include <libopencm3/stm32/rcc.h> // real-time control clock library
28 #include <libopencm3/stm32/gpio.h> // general purpose input output library
29 #include <libopencm3/stm32/i2c.h> // I2C library
30 
31 /* own libraries */
32 #include "global.h" // global utilities
33 #include "i2c_master.h" // I2C header and definitions
34 
39 static uint32_t RCC_I2C(uint32_t i2c)
40 {
41  switch (i2c) {
42  case I2C1:
43  return RCC_I2C1;
44  break;
45  case I2C2:
46  return RCC_I2C2;
47  break;
48  default:
49  while (true);
50  }
51 }
52 
57 static uint32_t RCC_GPIO_PORT_SCL(uint32_t i2c)
58 {
59  switch (i2c) {
60  case I2C1:
61  case I2C2:
62  return RCC_GPIOB;
63  break;
64  default:
65  while (true);
66  }
67 }
68 
73 static uint32_t RCC_GPIO_PORT_SDA(uint32_t i2c)
74 {
75  switch (i2c) {
76  case I2C1:
77  case I2C2:
78  return RCC_GPIOB;
79  break;
80  default:
81  while (true);
82  }
83 }
84 
89 static uint32_t GPIO_PORT_SCL(uint32_t i2c)
90 {
91  switch (i2c) {
92  case I2C1:
93  if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
94  return GPIO_BANK_I2C1_RE_SCL;
95  } else {
96  return GPIO_BANK_I2C1_SCL;
97  }
98  break;
99  case I2C2:
100  return GPIO_BANK_I2C2_SCL;
101  break;
102  default:
103  while (true);
104  }
105 }
106 
111 static uint32_t GPIO_PORT_SDA(uint32_t i2c)
112 {
113  switch (i2c) {
114  case I2C1:
115  if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
116  return GPIO_BANK_I2C1_RE_SDA;
117  } else {
118  return GPIO_BANK_I2C1_SDA;
119  }
120  break;
121  case I2C2:
122  return GPIO_BANK_I2C2_SDA;
123  break;
124  default:
125  while (true);
126  }
127 }
128 
133 static uint32_t GPIO_PIN_SCL(uint32_t i2c)
134 {
135  switch (i2c) {
136  case I2C1:
137  if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
138  return GPIO_I2C1_RE_SCL;
139  } else {
140  return GPIO_I2C1_SCL;
141  }
142  break;
143  case I2C2:
144  return GPIO_I2C2_SCL;
145  break;
146  default:
147  while (true);
148  }
149 }
150 
155 static uint32_t GPIO_PIN_SDA(uint32_t i2c)
156 {
157  switch (i2c) {
158  case I2C1:
159  if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
160  return GPIO_I2C1_RE_SDA;
161  } else {
162  return GPIO_I2C1_SDA;
163  }
164  break;
165  case I2C2:
166  return GPIO_I2C2_SDA;
167  break;
168  default:
169  while (true);
170  }
171 }
172 
173 void i2c_master_setup(uint32_t i2c, uint16_t frequency)
174 {
175  // check I2C peripheral
176  if (I2C1!=i2c && I2C2!=i2c) {
177  while (true);
178  }
179 
180  // configure I2C peripheral
181  rcc_periph_clock_enable(RCC_GPIO_PORT_SCL(i2c)); // enable clock for I2C I/O peripheral
182  gpio_set(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // already put signal high to avoid small pulse
183  gpio_set_mode(GPIO_PORT_SCL(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO_PIN_SCL(i2c)); // setup I2C I/O pins
184  rcc_periph_clock_enable(RCC_GPIO_PORT_SDA(i2c)); // enable clock for I2C I/O peripheral
185  gpio_set(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // already put signal high to avoid small pulse
186  gpio_set_mode(GPIO_PORT_SDA(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO_PIN_SDA(i2c)); // setup I2C I/O pins
187  rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function
188  rcc_periph_clock_enable(RCC_I2C(i2c)); // enable clock for I2C peripheral
189  i2c_reset(i2c); // reset peripheral domain
190  i2c_peripheral_disable(i2c); // I2C needs to be disable to be configured
191  I2C_CR1(i2c) |= I2C_CR1_SWRST; // reset peripheral
192  I2C_CR1(i2c) &= ~I2C_CR1_SWRST; // clear peripheral reset
193  if (0==frequency) { // don't allow null frequency
194  frequency = 1;
195  } else if (frequency>400) { // limit frequency to 400 kHz
196  frequency = 400;
197  }
198  i2c_set_clock_frequency(i2c, rcc_apb1_frequency/1000000); // configure the peripheral clock to the APB1 freq (where it is connected to)
199  if (frequency>100) { // use fast mode for frequencies over 100 kHz
200  i2c_set_fast_mode(i2c); // set fast mode (Fm)
201  i2c_set_ccr(i2c, rcc_apb1_frequency/(frequency*1000*2)); // set Thigh/Tlow to generate frequency (fast duty not used)
202  i2c_set_trise(i2c, (300/(1000/(rcc_apb1_frequency/1000000)))+1); // max rise time for Fm mode (< 400) kHz is 300 ns
203  } else { // use fast mode for frequencies below 100 kHz
204  i2c_set_standard_mode(i2c); // set standard mode (Sm)
205  i2c_set_ccr(i2c, rcc_apb1_frequency/(frequency*1000*2)); // set Thigh/Tlow to generate frequency of 100 kHz
206  i2c_set_trise(i2c, (1000/(1000/(rcc_apb1_frequency/1000000)))+1); // max rise time for Sm mode (< 100 kHz) is 1000 ns (~1 MHz)
207  }
208  i2c_peripheral_enable(i2c); // enable I2C after configuration completed
209 }
210 
211 void i2c_master_release(uint32_t i2c)
212 {
213  // check I2C peripheral
214  if (I2C1!=i2c && I2C2!=i2c) {
215  while (true);
216  }
217 
218  i2c_reset(i2c); // reset I2C peripheral configuration
219  i2c_peripheral_disable(i2c); // disable I2C peripheral
220  rcc_periph_clock_disable(RCC_I2C(i2c)); // disable clock for I2C peripheral
221  gpio_set_mode(GPIO_PORT_SCL(i2c), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_PIN_SCL(i2c)); // put I2C I/O pins back to floating
222  gpio_set_mode(GPIO_PORT_SDA(i2c), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_PIN_SDA(i2c)); // put I2C I/O pins back to floating
223 }
224 
225 bool i2c_master_check_signals(uint32_t i2c)
226 {
227  // check I2C peripheral
228  if (I2C1!=i2c && I2C2!=i2c) {
229  while (true);
230  }
231 
232  // pull SDA and SDC low to check if there are pull-up resistors
233  uint32_t sda_crl = GPIO_CRL(GPIO_PORT_SDA(i2c)); // backup port configuration
234  uint32_t sda_crh = GPIO_CRH(GPIO_PORT_SDA(i2c)); // backup port configuration
235  uint32_t sda_bsrr = GPIO_BSRR(GPIO_PORT_SDA(i2c)); // backup port configuration
236  uint32_t scl_crl = GPIO_CRL(GPIO_PORT_SCL(i2c)); // backup port configuration
237  uint32_t scl_crh = GPIO_CRH(GPIO_PORT_SCL(i2c)); // backup port configuration
238  uint32_t scl_bsrr = GPIO_BSRR(GPIO_PORT_SCL(i2c)); // backup port configuration
239  gpio_set_mode(GPIO_PORT_SDA(i2c), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_PIN_SDA(i2c)); // configure signal as pull down
240  gpio_set_mode(GPIO_PORT_SCL(i2c), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_PIN_SCL(i2c)); // configure signal as pull down
241  gpio_clear(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // pull down
242  gpio_clear(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // pull down
243  bool to_return = (0!=gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)) && 0!=gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c))); // check if the signals are still pulled high by external stronger pull-up resistors
244  GPIO_CRL(GPIO_PORT_SDA(i2c)) = sda_crl; // restore port configuration
245  GPIO_CRH(GPIO_PORT_SDA(i2c)) = sda_crh; // restore port configuration
246  GPIO_BSRR(GPIO_PORT_SDA(i2c)) = sda_bsrr; // restore port configuration
247  GPIO_CRL(GPIO_PORT_SCL(i2c)) = scl_crl; // restore port configuration
248  GPIO_CRH(GPIO_PORT_SCL(i2c)) = scl_crh; // restore port configuration
249  GPIO_BSRR(GPIO_PORT_SCL(i2c)) = scl_bsrr; // restore port configuration
250 
251  return to_return;
252 }
253 
254 void i2c_master_reset(uint32_t i2c)
255 {
256  // check I2C peripheral
257  if (I2C1!=i2c && I2C2!=i2c) {
258  while (true);
259  }
260 
261  // follow procedure described in STM32F10xxC/D/E Errata sheet, Section 2.14.7
262  i2c_peripheral_disable(i2c); // disable i2c peripheral
263  gpio_set_mode(GPIO_PORT_SCL(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO_PIN_SCL(i2c)); // put I2C I/O pins to general output
264  gpio_set(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // set high
265  while (!gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c))); // ensure it is high
266  gpio_set_mode(GPIO_PORT_SDA(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO_PIN_SDA(i2c)); // put I2C I/O pins to general output
267  gpio_set(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // set high
268  while (!gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c))); // ensure it is high
269  gpio_clear(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // set low (try first transition)
270  while (gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c))); // ensure it is low
271  gpio_clear(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // set low (try first transition)
272  while (gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c))); // ensure it is low
273  gpio_set(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c)); // set high (try second transition)
274  while (!gpio_get(GPIO_PORT_SCL(i2c), GPIO_PIN_SCL(i2c))); // ensure it is high
275  gpio_set(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c)); // set high (try second transition)
276  while (!gpio_get(GPIO_PORT_SDA(i2c), GPIO_PIN_SDA(i2c))); // ensure it is high
277  gpio_set_mode(GPIO_PORT_SCL(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO_PIN_SCL(i2c)); // set I2C I/O pins back
278  gpio_set_mode(GPIO_PORT_SDA(i2c), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO_PIN_SDA(i2c)); // set I2C I/O pins back
279  I2C_CR1(i2c) |= I2C_CR1_SWRST; // reset device
280  I2C_CR1(i2c) &= ~I2C_CR1_SWRST; // reset device
281  i2c_peripheral_enable(i2c); // re-enable device
282 }
283 
284 enum i2c_master_rc i2c_master_start(uint32_t i2c)
285 {
286  // check I2C peripheral
287  if (I2C1!=i2c && I2C2!=i2c) {
288  while (true);
289  }
290 
291  // send (re-)start condition
292  if (I2C_CR1(i2c) & (I2C_CR1_START|I2C_CR1_STOP)) { // ensure start or stop operations are not in progress
294  }
295  i2c_send_start(i2c); // send start condition to start transaction
296  while ((I2C_CR1(i2c) & I2C_CR1_START) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until start condition has been accepted and cleared
297  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
299  }
300  while (!(I2C_SR1(i2c) & I2C_SR1_SB) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until start condition is transmitted
301  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
303  }
304  if (!(I2C_SR2(i2c) & I2C_SR2_MSL)) { // verify if in master mode
306  }
307 
308  return I2C_MASTER_RC_NONE;
309 }
310 
311 enum i2c_master_rc i2c_master_select_slave(uint32_t i2c, uint16_t slave, bool address_10bit, bool write)
312 {
313  // check I2C peripheral
314  if (I2C1!=i2c && I2C2!=i2c) {
315  while (true);
316  }
317 
318  enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
319  if (!(I2C_SR1(i2c) & I2C_SR1_SB)) { // start condition has not been sent
320  rc = i2c_master_start(i2c); // send start condition
321  if (I2C_MASTER_RC_NONE!=rc) {
322  return rc;
323  }
324  }
325  if (!(I2C_SR2(i2c) & I2C_SR2_MSL)) { // I2C device is not in master mode
327  }
328 
329  // select slave
330  if (!address_10bit) { // 7-bit address
331  I2C_SR1(i2c) &= ~(I2C_SR1_AF); // clear acknowledgement failure
332  i2c_send_7bit_address(i2c, slave, write ? I2C_WRITE : I2C_READ); // select slave, with read/write flag
333  while (!(I2C_SR1(i2c) & (I2C_SR1_ADDR|I2C_SR1_AF)) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until address is transmitted
334  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
336  }
337  if (I2C_SR1(i2c) & I2C_SR1_AF) { // address has not been acknowledged
338  return I2C_MASTER_RC_NAK;
339  }
340  } else { // 10-bit address
341  // send first part of address
342  I2C_SR1(i2c) &= ~(I2C_SR1_AF); // clear acknowledgement failure
343  I2C_DR(i2c) = 11110000 | (((slave>>8)&0x3)<<1); // send first header (11110xx0, where xx are 2 MSb of slave address)
344  while (!(I2C_SR1(i2c) & (I2C_SR1_ADD10|I2C_SR1_AF)) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until first part of address is transmitted
345  if (I2C_SR1(i2c) & I2C_SR1_AF) { // address has not been acknowledged
346  return I2C_MASTER_RC_NAK;
347  }
348  // send second part of address
349  I2C_SR1(i2c) &= ~(I2C_SR1_AF); // clear acknowledgement failure
350  I2C_DR(i2c) = (slave&0xff); // send remaining of address
351  while (!(I2C_SR1(i2c) & (I2C_SR1_ADDR|I2C_SR1_AF)) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until remaining part of address is transmitted
352  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
354  }
355  if (I2C_SR1(i2c) & I2C_SR1_AF) { // address has not been acknowledged
356  return I2C_MASTER_RC_NAK;
357  }
358  // go into receive mode if necessary
359  if (!write) {
360  rc = i2c_master_start(i2c); // send start condition
361  if (I2C_MASTER_RC_NONE!=rc) {
362  return rc;
363  }
364  // send first part of address with receive flag
365  I2C_SR1(i2c) &= ~(I2C_SR1_AF); // clear acknowledgement failure
366  I2C_DR(i2c) = 11110001 | (((slave>>8)&0x3)<<1); // send header (11110xx1, where xx are 2 MSb of slave address)
367  while (!(I2C_SR1(i2c) & (I2C_SR1_ADDR|I2C_SR1_AF)) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until remaining part of address is transmitted
368  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
370  }
371  if (I2C_SR1(i2c) & I2C_SR1_AF) { // address has not been acknowledged
372  return I2C_MASTER_RC_NAK;
373  }
374  }
375  }
376  if (write) {
377  if (!((I2C_SR2(i2c) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
379  }
380  } else {
381  if ((I2C_SR2(i2c) & I2C_SR2_TRA)) { // verify we are in read mode (and read SR2 to clear ADDR)
383  }
384  }
385 
386  return I2C_MASTER_RC_NONE;
387 }
388 
389 enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size)
390 {
391  // check I2C peripheral
392  if (I2C1!=i2c && I2C2!=i2c) {
393  while (true);
394  }
395 
396  // sanity check
397  if (data==NULL || data_size==0) { // no data to read
398  return I2C_MASTER_RC_NONE;
399  }
400  if (!(I2C_SR2(i2c) & I2C_SR2_MSL)) { // I2C device is not master
402  }
403  if ((I2C_SR2(i2c) & I2C_SR2_TRA)) { // I2C device not in receiver mode
405  }
406  if (I2C_SR1(i2c) & I2C_SR1_AF) { // check if the previous transaction went well
408  }
409 
410  // read data
411  for (size_t i=0; i<data_size; i++) { // read bytes
412  if (i==data_size-1) { // prepare to sent NACK for last byte
413  i2c_disable_ack(i2c); // NACK received to stop slave transmission
414  } else {
415  i2c_enable_ack(i2c); // ACK received byte to continue slave transmission
416  }
417  while (!(I2C_SR1(i2c) & I2C_SR1_RxNE) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until byte has been received
418  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
420  }
421  data[i] = i2c_get_data(i2c); // read received byte
422  }
423 
424  return I2C_MASTER_RC_NONE;
425 }
426 
427 enum i2c_master_rc i2c_master_write(uint32_t i2c, const uint8_t* data, size_t data_size)
428 {
429  // check I2C peripheral
430  if (I2C1!=i2c && I2C2!=i2c) {
431  while (true);
432  }
433 
434  // sanity check
435  if (data==NULL || data_size==0) { // no data to write
436  return I2C_MASTER_RC_NONE;
437  }
438  if (!(I2C_SR2(i2c) & I2C_SR2_MSL)) { // I2C device is not master
440  }
441  if (!(I2C_SR2(i2c) & I2C_SR2_TRA)) { // I2C device not in transmitter mode
443  }
444  if (I2C_SR1(i2c) & I2C_SR1_AF) { // check if the previous transaction went well
446  }
447 
448  // write data
449  for (size_t i=0; i<data_size; i++) { // write bytes
450  I2C_SR1(i2c) &= ~(I2C_SR1_AF); // clear acknowledgement failure
451  i2c_send_data(i2c, data[i]); // send byte to be written in memory
452  while (!(I2C_SR1(i2c) & (I2C_SR1_TxE|I2C_SR1_AF)) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until byte has been transmitted
453  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
455  }
456  if (I2C_SR1(i2c) & I2C_SR1_AF) { // data has not been acknowledged
457  return I2C_MASTER_RC_NAK;
458  }
459  }
460 
461  return I2C_MASTER_RC_NONE;
462 }
463 
464 enum i2c_master_rc i2c_master_stop(uint32_t i2c)
465 {
466  // check I2C peripheral
467  if (I2C1!=i2c && I2C2!=i2c) {
468  while (true);
469  }
470 
471  // sanity check
472  if (!(I2C_SR2(i2c) & I2C_SR2_BUSY)) { // release is not busy
473  return I2C_MASTER_RC_NONE; // bus has probably already been released
474  }
475  // send stop condition
476  if (I2C_CR1(i2c) & (I2C_CR1_START|I2C_CR1_STOP)) { // ensure start or stop operations are not in progress
478  }
479 
480  i2c_send_stop(i2c); // send stop to release bus
481  while ((I2C_CR1(i2c) & I2C_CR1_STOP) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until stop condition is accepted and cleared
482  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
484  }
485  while ((I2C_SR2(i2c) & I2C_SR2_MSL) && !(I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO))); // wait until bus released (non master mode)
486  if (I2C_SR1(i2c) & (I2C_SR1_BERR|I2C_SR1_ARLO)) {
488  }
489 
490  return I2C_MASTER_RC_NONE;
491 }
492 
493 enum i2c_master_rc i2c_master_slave_read(uint32_t i2c, uint16_t slave, bool address_10bit, uint8_t* data, size_t data_size)
494 {
495  // check I2C peripheral
496  if (I2C1!=i2c && I2C2!=i2c) {
497  while (true);
498  }
499 
500  enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
501  rc = i2c_master_start(i2c); // send (re-)start condition
502  if (I2C_MASTER_RC_NONE!=rc) {
503  return rc;
504  }
505  rc = i2c_master_select_slave(i2c, slave, address_10bit, false); // select slave to read
506  if (I2C_MASTER_RC_NONE!=rc) {
507  goto error;
508  }
509  if (NULL!=data && data_size>0) { // only read data if needed
510  rc = i2c_master_read(i2c, data, data_size);
511  if (I2C_MASTER_RC_NONE!=rc) {
512  goto error;
513  }
514  }
515 
516  rc = I2C_MASTER_RC_NONE; // all went well
517 error:
518  i2c_master_stop(i2c); // sent stop condition
519  return rc;
520 }
521 
522 enum i2c_master_rc i2c_master_slave_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* data, size_t data_size)
523 {
524  // check I2C peripheral
525  if (I2C1!=i2c && I2C2!=i2c) {
526  while (true);
527  }
528 
529  enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
530  rc = i2c_master_start(i2c); // send (re-)start condition
531  if (I2C_MASTER_RC_NONE!=rc) {
532  return rc;
533  }
534  rc = i2c_master_select_slave(i2c, slave, address_10bit, true); // select slave to write
535  if (I2C_MASTER_RC_NONE!=rc) {
536  goto error;
537  }
538  if (NULL!=data && data_size>0) { // write data only is some is available
539  rc = i2c_master_write(i2c, data, data_size); // write data
540  if (I2C_MASTER_RC_NONE!=rc) {
541  goto error;
542  }
543  }
544 
545  rc = I2C_MASTER_RC_NONE; // all went well
546 error:
547  i2c_master_stop(i2c); // sent stop condition
548  return rc;
549 }
550 
551 enum i2c_master_rc i2c_master_address_read(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size)
552 {
553  // check I2C peripheral
554  if (I2C1!=i2c && I2C2!=i2c) {
555  while (true);
556  }
557 
558  enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
559  rc = i2c_master_start(i2c); // send (re-)start condition
560  if (I2C_MASTER_RC_NONE!=rc) {
561  return rc;
562  }
563  rc = i2c_master_select_slave(i2c, slave, address_10bit, true); // select slave to write
564  if (I2C_MASTER_RC_NONE!=rc) {
565  goto error;
566  }
567 
568  // write address
569  if (NULL!=address && address_size>0) {
570  rc = i2c_master_write(i2c, address, address_size); // send memory address
571  if (I2C_MASTER_RC_NONE!=rc) {
572  goto error;
573  }
574  }
575  // read data
576  if (NULL!=data && data_size>0) {
577  rc = i2c_master_start(i2c); // send re-start condition
578  if (I2C_MASTER_RC_NONE!=rc) {
579  return rc;
580  }
581  rc = i2c_master_select_slave(i2c, slave, address_10bit, false); // select slave to read
582  if (I2C_MASTER_RC_NONE!=rc) {
583  goto error;
584  }
585  rc = i2c_master_read(i2c, data, data_size); // read memory
586  if (I2C_MASTER_RC_NONE!=rc) {
587  goto error;
588  }
589  }
590 
591  rc = I2C_MASTER_RC_NONE; // all went well
592 error:
593  i2c_master_stop(i2c); // sent stop condition
594  return rc;
595 }
596 
597 enum i2c_master_rc i2c_master_address_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size)
598 {
599  // check I2C peripheral
600  if (I2C1!=i2c && I2C2!=i2c) {
601  while (true);
602  }
603 
604  enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
605  rc = i2c_master_start(i2c); // send (re-)start condition
606  if (I2C_MASTER_RC_NONE!=rc) {
607  return rc;
608  }
609  rc = i2c_master_select_slave(i2c, slave, address_10bit, true); // select slave to write
610  if (I2C_MASTER_RC_NONE!=rc) {
611  goto error;
612  }
613 
614  // write address
615  if (NULL!=address && address_size>0) {
616  rc = i2c_master_write(i2c, address, address_size); // send memory address
617  if (I2C_MASTER_RC_NONE!=rc) {
618  goto error;
619  }
620  }
621  // read data
622  if (NULL!=data && data_size>0) {
623  rc = i2c_master_write(i2c, data, data_size); // write memory
624  if (I2C_MASTER_RC_NONE!=rc) {
625  goto error;
626  }
627  }
628 
629  rc = I2C_MASTER_RC_NONE; // all went well
630 error:
631  i2c_master_stop(i2c); // sent stop condition
632  return rc;
633 }
library to communicate using I2C as master (API)
enum i2c_master_rc i2c_master_stop(uint32_t i2c)
sent stop condition
Definition: i2c_master.c:464
enum i2c_master_rc i2c_master_select_slave(uint32_t i2c, uint16_t slave, bool address_10bit, bool write)
select I2C slave device
Definition: i2c_master.c:311
not in receive mode
Definition: i2c_master.h:29
enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t *data, size_t data_size)
read data over I2C
Definition: i2c_master.c:389
void i2c_master_reset(uint32_t i2c)
reset I2C peripheral, fixing any locked state
Definition: i2c_master.c:254
an error on the I2C bus occurred
Definition: i2c_master.h:32
enum i2c_master_rc i2c_master_start(uint32_t i2c)
send start condition
Definition: i2c_master.c:284
global definitions and methods (API)
not in master mode
Definition: i2c_master.h:27
enum i2c_master_rc i2c_master_slave_read(uint32_t i2c, uint16_t slave, bool address_10bit, uint8_t *data, size_t data_size)
read data from slave device
Definition: i2c_master.c:493
static uint32_t RCC_GPIO_PORT_SDA(uint32_t i2c)
get RCC for GPIO port for SDA pin based on I2C identifier
Definition: i2c_master.c:73
enum i2c_master_rc i2c_master_write(uint32_t i2c, const uint8_t *data, size_t data_size)
write data over I2C
Definition: i2c_master.c:427
a start or stop condition is already in progress
Definition: i2c_master.h:26
void i2c_master_setup(uint32_t i2c, uint16_t frequency)
setup I2C peripheral
Definition: i2c_master.c:173
static uint32_t GPIO_PORT_SDA(uint32_t i2c)
get GPIO port for SDA pin based on I2C identifier
Definition: i2c_master.c:111
void i2c_master_release(uint32_t i2c)
release I2C peripheral
Definition: i2c_master.c:211
static uint32_t RCC_I2C(uint32_t i2c)
get RCC for I2C based on I2C identifier
Definition: i2c_master.c:39
static uint32_t GPIO_PIN_SCL(uint32_t i2c)
get GPIO pin for SCL pin based on I2C identifier
Definition: i2c_master.c:133
static uint32_t GPIO_PIN_SDA(uint32_t i2c)
get GPIO pin for SDA pin based on I2C identifier
Definition: i2c_master.c:155
enum i2c_master_rc i2c_master_slave_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t *data, size_t data_size)
write data to slave device
Definition: i2c_master.c:522
static uint32_t RCC_GPIO_PORT_SCL(uint32_t i2c)
get RCC for GPIO port for SCL pin based on I2C identifier
Definition: i2c_master.c:57
enum i2c_master_rc i2c_master_address_read(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t *address, size_t address_size, uint8_t *data, size_t data_size)
read data at specific address from an I2C memory slave
Definition: i2c_master.c:551
static uint32_t GPIO_PORT_SCL(uint32_t i2c)
get GPIO port for SCL pin based on I2C identifier
Definition: i2c_master.c:89
slave is not read (previous operations has been nacked)
Definition: i2c_master.h:30
bool i2c_master_check_signals(uint32_t i2c)
check if SDA and SCL signals are high
Definition: i2c_master.c:225
i2c_master_rc
I2C return codes.
Definition: i2c_master.h:24
not in transmit mode
Definition: i2c_master.h:28
enum i2c_master_rc i2c_master_address_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t *address, size_t address_size, const uint8_t *data, size_t data_size)
write data at specific address on an I2C memory slave
Definition: i2c_master.c:597
not acknowledge received
Definition: i2c_master.h:31