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