Paparazzi UAS  v4.2.2_stable-4-gcc32f65
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
i2c_arch.c
Go to the documentation of this file.
1 #include "mcu_periph/i2c.h"
2 
3 #include <stm32/rcc.h>
4 #include <stm32/gpio.h>
5 #include <stm32/flash.h>
6 #include <stm32/misc.h>
7 
8 static void start_transaction(struct i2c_periph* p);
9 static inline void end_of_transaction(struct i2c_periph *p);
10 static inline void i2c_hard_reset(struct i2c_periph *p);
11 static inline void i2c_reset_init(struct i2c_periph *p);
12 
13 #define I2C_BUSY 0x20
14 
15 // If a hard reset cannot free up SDA, SCL lines abort. Previously stm32 would hang
16 // when lines stuck i.e. no pullups on I2C lines
17 #define I2C_MAX_RESET_FAIL_COUNT 20
18 
19 #ifdef DEBUG_I2C
20 #define SPURIOUS_INTERRUPT(_periph, _status, _event) { while(1); }
21 #define OUT_OF_SYNC_STATE_MACHINE(_periph, _status, _event) { while(1); }
22 #else
23 //#define SPURIOUS_INTERRUPT(_periph, _status, _event) { periph->errors->unexpected_event_cnt++; abort_and_reset(_periph);}
24 #define SPURIOUS_INTERRUPT(_periph, _status, _event) { if (_status == I2CAddrWrSent) abort_and_reset(_periph);}
25 #define OUT_OF_SYNC_STATE_MACHINE(_periph, _status, _event) { abort_and_reset(_periph);}
26 #endif
27 
28 #ifdef USE_I2C0
29 #error "The STM32 doesn't have I2C0, use I2C1 or I2C2"
30 #endif
31 
32 #ifdef USE_I2C1
33 #ifndef I2C1_BITRATE
34 #define I2C1_BITRATE 200000
35 #endif
36 static I2C_InitTypeDef I2C1_InitStruct = {
37  .I2C_Mode = I2C_Mode_I2C,
38  .I2C_DutyCycle = I2C_DutyCycle_2,
39  .I2C_OwnAddress1 = 0x00,
40  .I2C_Ack = I2C_Ack_Enable,
41  .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
42  .I2C_ClockSpeed = I2C1_BITRATE
43 };
44 #endif
45 
46 #ifdef USE_I2C2
47 #ifndef I2C2_BITRATE
48 #define I2C2_BITRATE 300000
49 #endif
50 static I2C_InitTypeDef I2C2_InitStruct = {
51  .I2C_Mode = I2C_Mode_I2C,
52  .I2C_DutyCycle = I2C_DutyCycle_2,
53  .I2C_OwnAddress1 = 0x00,
54  .I2C_Ack = I2C_Ack_Enable,
55  .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
56  .I2C_ClockSpeed = I2C2_BITRATE
57 };
58 #endif
59 
60 static inline void i2c_delay(void)
61 {
62  for (__IO int j = 0; j < 50; j++);
63 }
64 
65 static inline void i2c_apply_config(struct i2c_periph *p)
66 {
67  I2C_Init(p->reg_addr, p->init_struct);
68 }
69 
70 static inline void end_of_transaction(struct i2c_periph *p)
71 {
72  p->trans_extract_idx++;
74  p->trans_extract_idx = 0;
75  /* if we have no more transaction to process, stop here */
77  p->status = I2CIdle;
78  /* if not, start next transaction */
79  else
81 }
82 
83 static inline void abort_and_reset(struct i2c_periph *p) {
84  struct i2c_transaction* trans = p->trans[p->trans_extract_idx];
85  trans->status = I2CTransFailed;
86  I2C_ITConfig(p->reg_addr, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE);
87  i2c_hard_reset(p);
88  I2C_ITConfig(p->reg_addr, I2C_IT_ERR, ENABLE);
90 }
91 
92 static inline void on_status_start_requested(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event);
93 static inline void on_status_addr_wr_sent(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event);
94 static inline void on_status_sending_byte(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event);
95 static inline void on_status_stop_requested(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event);
96 static inline void on_status_addr_rd_sent(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event);
97 static inline void on_status_reading_byte(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event);
98 static inline void on_status_reading_last_byte(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event);
99 static inline void on_status_restart_requested(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event);
100 
101 /*
102  * Start Requested
103  *
104  */
105 static inline void on_status_start_requested(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event) {
106  if (event & I2C_FLAG_SB) {
107  if(trans->type == I2CTransRx) {
108  I2C_Send7bitAddress(periph->reg_addr, trans->slave_addr, I2C_Direction_Receiver);
109  periph->status = I2CAddrRdSent;
110  }
111  else {
112  I2C_Send7bitAddress(periph->reg_addr, trans->slave_addr, I2C_Direction_Transmitter);
113  periph->status = I2CAddrWrSent;
114  }
115  }
116  // else
117  // SPURIOUS_INTERRUPT(periph, I2CStartRequested, event);
118  // FIXME: this one seems to get called all the time with mkk controllers
119 }
120 
121 /*
122  * Addr WR sent
123  *
124  */
125 static inline void on_status_addr_wr_sent(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event) {
126  if ((event & I2C_FLAG_ADDR) && (event & I2C_FLAG_TRA)) {
127  I2C_SendData(periph->reg_addr, trans->buf[0]);
128  if (trans->len_w > 1) {
129  I2C_SendData(periph->reg_addr, trans->buf[1]);
130  periph->idx_buf = 2;
131  I2C_ITConfig(periph->reg_addr, I2C_IT_BUF, ENABLE);
132  periph->status = I2CSendingByte;
133  }
134  else {
135  periph->idx_buf = 1;
136  if (trans->type == I2CTransTx) {
137  I2C_GenerateSTOP(periph->reg_addr, ENABLE);
138  periph->status = I2CStopRequested;
139  }
140  else {
141  I2C_GenerateSTART(periph->reg_addr, ENABLE);
142  periph->status = I2CRestartRequested;
143  }
144  }
145  }
146  else {
147  SPURIOUS_INTERRUPT(periph, I2CAddrWrSent, event);
148  // FIXME: this was where the code would break with mkk controllers on april 10 2011
149  // now have SPURIOUS_INTERRUPT call abort_and_reset
150  }
151 }
152 
153 /*
154  * Sending Byte
155  *
156  */
157 static inline void on_status_sending_byte(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event) {
158  I2C_TypeDef *regs = (I2C_TypeDef *) periph->reg_addr;
159  if (event & I2C_FLAG_TXE) {
160  if (periph->idx_buf < trans->len_w) {
161  I2C_SendData(periph->reg_addr, trans->buf[periph->idx_buf]);
162  periph->idx_buf++;
163  }
164  else {
165  I2C_ITConfig(periph->reg_addr, I2C_IT_BUF, DISABLE);
166  if (trans->type == I2CTransTx) {
167  I2C_GenerateSTOP(periph->reg_addr, ENABLE);
168  /* Make sure that the STOP bit is cleared by Hardware */
169  static __IO uint8_t counter = 0;
170  while ((regs->CR1 & 0x200) == 0x200) {
171  counter++;
172  if (counter > 100) break;
173  }
174  periph->status = I2CStopRequested;
175  }
176  else {
177  I2C_GenerateSTART(periph->reg_addr, ENABLE);
178  periph->status = I2CRestartRequested;
179  }
180  }
181  }
182  else
183  SPURIOUS_INTERRUPT(periph, I2CSendingByte, event);
184 }
185 
186 /*
187  * Stop Requested
188  *
189  */
190 static inline void on_status_stop_requested(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event) {
191  /* bummer.... */
192  if (event & I2C_FLAG_RXNE) {
193  uint8_t read_byte = I2C_ReceiveData(periph->reg_addr);
194  if (periph->idx_buf < trans->len_r) {
195  trans->buf[periph->idx_buf] = read_byte;
196  }
197  }
198  I2C_ITConfig(periph->reg_addr, I2C_IT_EVT|I2C_IT_BUF, DISABLE); // should only need to disable evt, buf already disabled
199  trans->status = I2CTransSuccess;
200  end_of_transaction(periph);
201 }
202 
203 /*
204  * Addr RD sent
205  *
206  */
207 static inline void on_status_addr_rd_sent(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event) {
208  I2C_TypeDef *regs = (I2C_TypeDef *) periph->reg_addr;
209 
210  if ((event & I2C_FLAG_ADDR) && !(event & I2C_FLAG_TRA)) {
211  periph->idx_buf = 0;
212  if(trans->len_r == 1) { // If we're going to read only one byte
213  I2C_AcknowledgeConfig(periph->reg_addr, DISABLE); // make sure it's gonna be nacked
214  I2C_GenerateSTOP(periph->reg_addr, ENABLE); // and followed by a stop
215  /* Make sure that the STOP bit is cleared by Hardware */
216  static __IO uint8_t counter = 0;
217  while ((regs->CR1 & 0x200) == 0x200) {
218  counter++;
219  if (counter > 100) break;
220  }
221  periph->status = I2CReadingLastByte; // and remember we did
222  }
223  else {
224  I2C_AcknowledgeConfig(periph->reg_addr, ENABLE); // if it's more than one byte, ack it
225  I2C_ITConfig(periph->reg_addr, I2C_IT_BUF, ENABLE);
226  periph->status = I2CReadingByte; // and remember we did
227  }
228  }
229  else
230  SPURIOUS_INTERRUPT(periph, I2CAddrRdSent, event);
231 }
232 
233 
234 /*
235  * Reading byte
236  *
237  */
238 static inline void on_status_reading_byte(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event) {
239  I2C_TypeDef *regs = (I2C_TypeDef *) periph->reg_addr;
240  if (event & I2C_FLAG_RXNE) {
241  uint8_t read_byte = I2C_ReceiveData(periph->reg_addr);
242  if (periph->idx_buf < trans->len_r) {
243  trans->buf[periph->idx_buf] = read_byte;
244  periph->idx_buf++;
245  if (periph->idx_buf >= trans->len_r-1) { // We're reading our last byte
246  I2C_AcknowledgeConfig(periph->reg_addr, DISABLE); // give them a nack once it's done
247  I2C_GenerateSTOP(periph->reg_addr, ENABLE); // and follow with a stop
248  /* Make sure that the STOP bit is cleared by Hardware */
249  static __IO uint8_t counter = 0;
250  while ((regs->CR1 & 0x200) == 0x200) {
251  counter++;
252  if (counter > 100) break;
253  }
254  periph->status = I2CStopRequested; // remember we already trigered the stop
255  }
256  } // else { something very wrong has happened }
257  }
258  else
259  SPURIOUS_INTERRUPT(periph, I2CReadingByte, event);
260 }
261 
262 /*
263  * Reading last byte
264  *
265  */
266 static inline void on_status_reading_last_byte(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event) {
267  if (event & I2C_FLAG_BTF) {
268  uint8_t read_byte = I2C_ReceiveData(periph->reg_addr);
269  trans->buf[periph->idx_buf] = read_byte;
270  I2C_GenerateSTOP(periph->reg_addr, ENABLE);
271  periph->status = I2CStopRequested;
272  }
273  else if (event & I2C_FLAG_RXNE) { // should really be BTF ?
274  uint8_t read_byte = I2C_ReceiveData(periph->reg_addr);
275  trans->buf[periph->idx_buf] = read_byte;
276  periph->status = I2CStopRequested;
277  }
278  else
279  SPURIOUS_INTERRUPT(periph, I2CReadingLastByte, event);
280 }
281 
282 /*
283  * Restart requested
284  *
285  */
286 static inline void on_status_restart_requested(struct i2c_periph *periph, struct i2c_transaction* trans, uint32_t event) {
287  if (event & I2C_FLAG_SB) {
288  I2C_Send7bitAddress(periph->reg_addr, trans->slave_addr, I2C_Direction_Receiver);
289  periph->status = I2CAddrRdSent;
290  }
291 }
292 
293 void i2c_event(void)
294 {
295 }
296 
297 static inline void i2c_driver_event(struct i2c_periph *p, uint32_t event)
298 {
299  struct i2c_transaction* trans = p->trans[p->trans_extract_idx];
300  switch (p->status) {
301  case I2CStartRequested:
302  on_status_start_requested(p, trans, event);
303  break;
304  case I2CAddrWrSent:
305  on_status_addr_wr_sent(p, trans, event);
306  break;
307  case I2CSendingByte:
308  on_status_sending_byte(p, trans, event);
309  break;
310  case I2CStopRequested:
311  on_status_stop_requested(p, trans, event);
312  break;
313  case I2CAddrRdSent:
314  on_status_addr_rd_sent(p, trans, event);
315  break;
316  case I2CReadingByte:
317  on_status_reading_byte(p, trans, event);
318  break;
319  case I2CReadingLastByte:
320  on_status_reading_last_byte(p, trans, event);
321  break;
322  case I2CRestartRequested:
323  on_status_restart_requested(p, trans, event);
324  break;
325  default:
326  OUT_OF_SYNC_STATE_MACHINE(p, p->status, event);
327  break;
328  }
329 }
330 
331 static inline void i2c_error(struct i2c_periph *p)
332 {
333  p->errors->er_irq_cnt;
334  if (I2C_GetITStatus(p->reg_addr, I2C_IT_AF)) { /* Acknowledge failure */
335  p->errors->ack_fail_cnt++;
336  I2C_ClearITPendingBit(p->reg_addr, I2C_IT_AF);
337  }
338  if (I2C_GetITStatus(p->reg_addr, I2C_IT_BERR)) { /* Misplaced Start or Stop condition */
340  I2C_ClearITPendingBit(p->reg_addr, I2C_IT_BERR);
341  }
342  if (I2C_GetITStatus(p->reg_addr, I2C_IT_ARLO)) { /* Arbitration lost */
343  p->errors->arb_lost_cnt++;
344  I2C_ClearITPendingBit(p->reg_addr, I2C_IT_ARLO);
345  // I2C_AcknowledgeConfig(I2C2, DISABLE);
346  // uint8_t dummy __attribute__ ((unused)) = I2C_ReceiveData(I2C2);
347  // I2C_GenerateSTOP(I2C2, ENABLE);
348  }
349  if (I2C_GetITStatus(p->reg_addr, I2C_IT_OVR)) { /* Overrun/Underrun */
350  p->errors->over_under_cnt++;
351  I2C_ClearITPendingBit(p->reg_addr, I2C_IT_OVR);
352  }
353  if (I2C_GetITStatus(p->reg_addr, I2C_IT_PECERR)) { /* PEC Error in reception */
354  p->errors->pec_recep_cnt++;
355  I2C_ClearITPendingBit(p->reg_addr, I2C_IT_PECERR);
356  }
357  if (I2C_GetITStatus(p->reg_addr, I2C_IT_TIMEOUT)) { /* Timeout or Tlow error */
358  p->errors->timeout_tlow_cnt++;
359  I2C_ClearITPendingBit(p->reg_addr, I2C_IT_TIMEOUT);
360  }
361  if (I2C_GetITStatus(p->reg_addr, I2C_IT_SMBALERT)) { /* SMBus alert */
362  p->errors->smbus_alert_cnt++;
363  I2C_ClearITPendingBit(p->reg_addr, I2C_IT_SMBALERT);
364  }
365 
366  abort_and_reset(p);
367 }
368 
369 
370 static inline void i2c_hard_reset(struct i2c_periph *p)
371 {
372  uint8_t timeout_fails=0;
373  I2C_TypeDef *regs = (I2C_TypeDef *) p->reg_addr;
374 
375  I2C_DeInit(p->reg_addr);
376 
377  GPIO_InitTypeDef GPIO_InitStructure;
378  GPIO_InitStructure.GPIO_Pin = p->scl_pin | p->sda_pin;
379  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
380  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
381  GPIO_SetBits(GPIOB, p->scl_pin | p->sda_pin);
382  GPIO_Init(GPIOB, &GPIO_InitStructure);
383 
384  while((GPIO_ReadInputDataBit(GPIOB, p->sda_pin) == Bit_RESET) && timeout_fails < I2C_MAX_RESET_FAIL_COUNT) {
385  // Raise SCL, wait until SCL is high (in case of clock stretching)
386  GPIO_SetBits(GPIOB, p->scl_pin);
387  while ((GPIO_ReadInputDataBit(GPIOB, p->scl_pin) == Bit_RESET) && timeout_fails < I2C_MAX_RESET_FAIL_COUNT) {
388  i2c_delay();
389  timeout_fails++;
390  }
391  i2c_delay();
392 
393  // Lower SCL, wait
394  GPIO_ResetBits(GPIOB, p->scl_pin);
395  i2c_delay();
396 
397  // Raise SCL, wait
398  GPIO_SetBits(GPIOB, p->scl_pin);
399  i2c_delay();
400  timeout_fails++;
401  }
402 
403  // Generate a start condition followed by a stop condition
404  GPIO_SetBits(GPIOB, p->scl_pin);
405  i2c_delay();
406  GPIO_ResetBits(GPIOB, p->sda_pin);
407  i2c_delay();
408  GPIO_ResetBits(GPIOB, p->sda_pin);
409  i2c_delay();
410 
411  // Raise both SCL and SDA and wait for SCL high (in case of clock stretching)
412  GPIO_SetBits(GPIOB, p->scl_pin | p->sda_pin);
413  while (GPIO_ReadInputDataBit(GPIOB, p->scl_pin) == Bit_RESET && timeout_fails < I2C_MAX_RESET_FAIL_COUNT) {
414  i2c_delay();
415  timeout_fails++;
416  }
417 
418  // Wait for SDA to be high
419  while (GPIO_ReadInputDataBit(GPIOB, p->sda_pin) != Bit_SET && timeout_fails < I2C_MAX_RESET_FAIL_COUNT)
420  {
421  i2c_delay();
422  timeout_fails++;
423  }
424 
425  // SCL and SDA should be high at this point, bus should be free
426  // Return the GPIO pins to the alternate function
427  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
428  GPIO_Init(GPIOB, &GPIO_InitStructure);
429 
430  I2C_DeInit(p->reg_addr);
431 
432  i2c_apply_config(p);
433 
434  if (regs->SR2 & I2C_BUSY) {
435  // Reset the I2C block
436  I2C_SoftwareResetCmd(p->reg_addr, ENABLE);
437  I2C_SoftwareResetCmd(p->reg_addr, DISABLE);
438  }
439 }
440 
441 static inline void i2c_reset_init(struct i2c_periph *p)
442 {
443  // Reset bus and configure GPIO pins
444  i2c_hard_reset(p);
445 
446  // enable peripheral
447  I2C_Cmd(p->reg_addr, ENABLE);
448 
449  // enable error interrupts
450  I2C_ITConfig(p->reg_addr, I2C_IT_ERR, ENABLE);
451 }
452 
453 
454 #ifdef USE_I2C1
455 
456 struct i2c_errors i2c1_errors;
457 
458 #include "my_debug_servo.h"
459 
460 void i2c1_hw_init(void) {
461 
462  i2c1.reg_addr = I2C1;
463  i2c1.init_struct = &I2C1_InitStruct;
464  i2c1.scl_pin = GPIO_Pin_6;
465  i2c1.sda_pin = GPIO_Pin_7;
466  i2c1.errors = &i2c1_errors;
467 
468  /* zeros error counter */
469  ZEROS_ERR_COUNTER(i2c1_errors);
470 
471  /* reset peripheral to default state ( sometimes not achieved on reset :( ) */
472  I2C_DeInit(I2C1);
473 
474  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
475  NVIC_InitTypeDef NVIC_InitStructure;
476 
477  /* Configure and enable I2C1 event interrupt -------------------------------*/
478  NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
479  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
480  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
481  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
482  NVIC_Init(&NVIC_InitStructure);
483 
484  /* Configure and enable I2C1 err interrupt -------------------------------*/
485  NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
486  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
487  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
488  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
489  NVIC_Init(&NVIC_InitStructure);
490 
491  /* Enable peripheral clocks --------------------------------------------------*/
492  /* Enable I2C1 clock */
493  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
494  /* Enable GPIOB clock */
495  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
496 
497  /* Configure I2C1 pins: SCL and SDA ------------------------------------------*/
498  GPIO_InitTypeDef GPIO_InitStructure;
499  GPIO_StructInit(&GPIO_InitStructure);
500  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
501  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
502  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
503  GPIO_Init(GPIOB, &GPIO_InitStructure);
504 
505  /* I2C configuration ----------------------------------------------------------*/
506 
507 
508  /* Reset and initialize I2C HW */
509  i2c_reset_init(&i2c1);
510 
511 }
512 
513 
514 void i2c1_ev_irq_handler(void) {
515 
516  uint32_t event = I2C_GetLastEvent(I2C1);
517  i2c_driver_event(&i2c1, event);
518 
519 }
520 
521 
522 void i2c1_er_irq_handler(void) {
523  i2c_error(&i2c1);
524 }
525 
526 #endif /* USE_I2C1 */
527 
528 
529 
530 
531 
532 #ifdef USE_I2C2
533 
534 // dec hex
535 // 196609 30001 BUSY MSL | SB
536 // 458882 70082 TRA BUSY MSL | TXE ADDR
537 // 458884 70084 TRA BUSY MSL | TXE BTF
538 // 196609 30001 BUSY MSL | SB
539 // 196610 30002 BUSY MSL | ADDR
540 //
541 
542 
543 struct i2c_errors i2c2_errors;
544 
545 #include "my_debug_servo.h"
546 
547 void i2c2_hw_init(void) {
548 
549  i2c2.reg_addr = I2C2;
550  i2c2.init_struct = &I2C2_InitStruct;
551  i2c2.scl_pin = GPIO_Pin_10;
552  i2c2.sda_pin = GPIO_Pin_11;
553  i2c2.errors = &i2c2_errors;
554 
555  /* zeros error counter */
556  ZEROS_ERR_COUNTER(i2c2_errors);
557 
558  /* reset peripheral to default state ( sometimes not achieved on reset :( ) */
559  I2C_DeInit(I2C2);
560 
561  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
562  NVIC_InitTypeDef NVIC_InitStructure;
563 
564  /* Configure and enable I2C2 event interrupt --------------------------------*/
565  NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
566  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
567  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
568  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
569  NVIC_Init(&NVIC_InitStructure);
570 
571  /* Configure and enable I2C2 err interrupt ----------------------------------*/
572  NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQn;
573  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
574  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
575  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
576  NVIC_Init(&NVIC_InitStructure);
577 
578  /* Enable peripheral clocks -------------------------------------------------*/
579  /* Enable I2C2 clock */
580  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
581  /* Enable GPIOB clock */
582  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
583 
584  // Reset and initialize I2C HW
585  i2c_reset_init(&i2c2);
586 
587 }
588 
589 
590 
591 
592 void i2c2_ev_irq_handler(void) {
593  uint32_t event = I2C_GetLastEvent(I2C2);
594  i2c_driver_event(&i2c2, event);
595 }
596 
597 void i2c2_er_irq_handler(void) {
598  i2c_error(&i2c2);
599 
600 }
601 
602 #endif /* USE_I2C2 */
603 
604 
605 
606 bool_t i2c_idle(struct i2c_periph* p)
607 {
608  return !I2C_GetFlagStatus(p->reg_addr, I2C_FLAG_BUSY);
609 }
610 
611 bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) {
612 
613  uint8_t temp;
614  temp = p->trans_insert_idx + 1;
615  if (temp >= I2C_TRANSACTION_QUEUE_LEN) temp = 0;
616  if (temp == p->trans_extract_idx)
617  return FALSE; // queue full
618 
619  t->status = I2CTransPending;
620 
621 
622  __disable_irq();
623  /* put transacation in queue */
624  p->trans[p->trans_insert_idx] = t;
625  p->trans_insert_idx = temp;
626 
627  /* if peripheral is idle, start the transaction */
628  if (p->status == I2CIdle)
630  /* else it will be started by the interrupt handler when the previous transactions completes */
631  __enable_irq();
632 
633  return TRUE;
634 }
635 
636 
637 static void start_transaction(struct i2c_periph* p) {
638  p->idx_buf = 0;
640  I2C_ITConfig(p->reg_addr, I2C_IT_EVT, ENABLE);
641  I2C_GenerateSTART(p->reg_addr, ENABLE);
642 }
static void on_status_reading_last_byte(struct i2c_periph *periph, struct i2c_transaction *trans, uint32_t event)
Definition: i2c_arch.c:266
#define I2C1
Definition: LPC21xx.h:166
static void on_status_restart_requested(struct i2c_periph *periph, struct i2c_transaction *trans, uint32_t event)
Definition: i2c_arch.c:286
void i2c_event(void)
Definition: i2c_arch.c:344
static void on_status_start_requested(struct i2c_periph *periph, struct i2c_transaction *trans, uint32_t event)
Definition: i2c_arch.c:105
void * reg_addr
Definition: i2c.h:62
uint8_t trans_extract_idx
Definition: i2c.h:58
static void on_status_stop_requested(struct i2c_periph *periph, struct i2c_transaction *trans, uint32_t event)
Definition: i2c_arch.c:190
volatile uint16_t ack_fail_cnt
Definition: i2c.h:71
static void end_of_transaction(struct i2c_periph *p)
Definition: i2c_arch.c:70
static void i2c_apply_config(struct i2c_periph *p)
Definition: i2c_arch.c:65
#define I2C_MAX_RESET_FAIL_COUNT
Definition: i2c_arch.c:17
bool_t i2c_idle(struct i2c_periph *p)
Definition: i2c_arch.c:317
static void on_status_sending_byte(struct i2c_periph *periph, struct i2c_transaction *trans, uint32_t event)
Definition: i2c_arch.c:157
#define OUT_OF_SYNC_STATE_MACHINE(_periph, _status, _event)
Definition: i2c_arch.c:25
static void on_status_addr_rd_sent(struct i2c_periph *periph, struct i2c_transaction *trans, uint32_t event)
Definition: i2c_arch.c:207
volatile uint8_t idx_buf
Definition: i2c.h:61
enum I2CStatus status
Definition: i2c.h:60
uint8_t slave_addr
Definition: i2c.h:43
#define FALSE
Definition: imu_chimu.h:141
volatile uint16_t smbus_alert_cnt
Definition: i2c.h:77
volatile uint16_t timeout_tlow_cnt
Definition: i2c.h:76
void * init_struct
Definition: i2c.h:63
Definition: i2c.h:23
#define I2C_BUSY
Definition: i2c_arch.c:13
bool_t i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
Definition: i2c_arch.c:321
volatile uint16_t miss_start_stop_cnt
Definition: i2c.h:72
static void start_transaction(struct i2c_periph *p)
Definition: i2c_arch.c:637
uint16_t scl_pin
Definition: i2c.h:64
unsigned long uint32_t
Definition: types.h:18
static void i2c_driver_event(struct i2c_periph *p, uint32_t event)
Definition: i2c_arch.c:297
uint16_t sda_pin
Definition: i2c.h:65
static void abort_and_reset(struct i2c_periph *p)
Definition: i2c_arch.c:83
static void i2c_error(struct i2c_periph *p)
Definition: i2c_arch.c:331
static void i2c_hard_reset(struct i2c_periph *p)
Definition: i2c_arch.c:370
Definition: i2c.h:70
enum I2CTransactionStatus status
Definition: i2c.h:47
volatile uint16_t over_under_cnt
Definition: i2c.h:74
volatile uint16_t pec_recep_cnt
Definition: i2c.h:75
#define TRUE
Definition: imu_chimu.h:144
volatile uint32_t er_irq_cnt
Definition: i2c.h:80
volatile uint8_t buf[I2C_BUF_LEN]
Definition: i2c.h:46
uint8_t len_w
Definition: i2c.h:45
uint16_t len_r
Definition: i2c.h:44
unsigned char uint8_t
Definition: types.h:14
volatile uint16_t arb_lost_cnt
Definition: i2c.h:73
static void i2c_reset_init(struct i2c_periph *p)
Definition: i2c_arch.c:441
uint8_t trans_insert_idx
Definition: i2c.h:57
#define ZEROS_ERR_COUNTER(_i2c_err)
Definition: i2c.h:94
struct i2c_errors * errors
Definition: i2c.h:66
Definition: i2c.h:54
enum I2CTransactionType type
Definition: i2c.h:42
Definition: i2c.h:10
#define SPURIOUS_INTERRUPT(_periph, _status, _event)
Definition: i2c_arch.c:24
static void on_status_reading_byte(struct i2c_periph *periph, struct i2c_transaction *trans, uint32_t event)
Definition: i2c_arch.c:238
#define I2C_TRANSACTION_QUEUE_LEN
Definition: i2c.h:51
static void on_status_addr_wr_sent(struct i2c_periph *periph, struct i2c_transaction *trans, uint32_t event)
Definition: i2c_arch.c:125
static void i2c_delay(void)
Definition: i2c_arch.c:60
Definition: i2c.h:9
struct i2c_transaction * trans[I2C_TRANSACTION_QUEUE_LEN]
Definition: i2c.h:56