Paparazzi UAS  v5.2.2_stable-0-gd6b9f29
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
i2c.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010-2012 The Paparazzi Team
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 
28 #include "mcu_periph/i2c.h"
29 
30 #if PERIODIC_TELEMETRY
32 #endif
33 
34 #if USE_I2C0
35 
36 struct i2c_periph i2c0;
37 
38 #if PERIODIC_TELEMETRY
39 static void send_i2c0_err(void) {
40  uint16_t i2c0_queue_full_cnt = i2c0.errors->queue_full_cnt;
41  uint16_t i2c0_ack_fail_cnt = i2c0.errors->ack_fail_cnt;
42  uint16_t i2c0_miss_start_stop_cnt = i2c0.errors->miss_start_stop_cnt;
43  uint16_t i2c0_arb_lost_cnt = i2c0.errors->arb_lost_cnt;
44  uint16_t i2c0_over_under_cnt = i2c0.errors->over_under_cnt;
45  uint16_t i2c0_pec_recep_cnt = i2c0.errors->pec_recep_cnt;
46  uint16_t i2c0_timeout_tlow_cnt = i2c0.errors->timeout_tlow_cnt;
47  uint16_t i2c0_smbus_alert_cnt = i2c0.errors->smbus_alert_cnt;
48  uint16_t i2c0_unexpected_event_cnt = i2c0.errors->unexpected_event_cnt;
49  uint32_t i2c0_last_unexpected_event = i2c0.errors->last_unexpected_event;
50  const uint8_t _bus0 = 0;
51  DOWNLINK_SEND_I2C_ERRORS(DefaultChannel, DefaultDevice,
52  &i2c0_queue_full_cnt,
53  &i2c0_ack_fail_cnt,
54  &i2c0_miss_start_stop_cnt,
55  &i2c0_arb_lost_cnt,
56  &i2c0_over_under_cnt,
57  &i2c0_pec_recep_cnt,
58  &i2c0_timeout_tlow_cnt,
59  &i2c0_smbus_alert_cnt,
60  &i2c0_unexpected_event_cnt,
61  &i2c0_last_unexpected_event,
62  &_bus0);
63 }
64 #endif
65 
66 void i2c0_init(void) {
67  i2c_init(&i2c0);
68  i2c0_hw_init();
69 }
70 
71 #endif /* USE_I2C0 */
72 
73 
74 #if USE_I2C1
75 
76 struct i2c_periph i2c1;
77 
78 #if PERIODIC_TELEMETRY
79 static void send_i2c1_err(void) {
80  uint16_t i2c1_queue_full_cnt = i2c1.errors->queue_full_cnt;
81  uint16_t i2c1_ack_fail_cnt = i2c1.errors->ack_fail_cnt;
82  uint16_t i2c1_miss_start_stop_cnt = i2c1.errors->miss_start_stop_cnt;
83  uint16_t i2c1_arb_lost_cnt = i2c1.errors->arb_lost_cnt;
84  uint16_t i2c1_over_under_cnt = i2c1.errors->over_under_cnt;
85  uint16_t i2c1_pec_recep_cnt = i2c1.errors->pec_recep_cnt;
86  uint16_t i2c1_timeout_tlow_cnt = i2c1.errors->timeout_tlow_cnt;
87  uint16_t i2c1_smbus_alert_cnt = i2c1.errors->smbus_alert_cnt;
88  uint16_t i2c1_unexpected_event_cnt = i2c1.errors->unexpected_event_cnt;
89  uint32_t i2c1_last_unexpected_event = i2c1.errors->last_unexpected_event;
90  const uint8_t _bus1 = 1;
91  DOWNLINK_SEND_I2C_ERRORS(DefaultChannel, DefaultDevice,
92  &i2c1_queue_full_cnt,
93  &i2c1_ack_fail_cnt,
94  &i2c1_miss_start_stop_cnt,
95  &i2c1_arb_lost_cnt,
96  &i2c1_over_under_cnt,
97  &i2c1_pec_recep_cnt,
98  &i2c1_timeout_tlow_cnt,
99  &i2c1_smbus_alert_cnt,
100  &i2c1_unexpected_event_cnt,
101  &i2c1_last_unexpected_event,
102  &_bus1);
103 }
104 #endif
105 
106 void i2c1_init(void) {
107  i2c_init(&i2c1);
108  i2c1_hw_init();
109 }
110 
111 #endif /* USE_I2C1 */
112 
113 
114 #if USE_I2C2
115 
116 struct i2c_periph i2c2;
117 
118 #if PERIODIC_TELEMETRY
119 static void send_i2c2_err(void) {
120  uint16_t i2c2_queue_full_cnt = i2c2.errors->queue_full_cnt;
121  uint16_t i2c2_ack_fail_cnt = i2c2.errors->ack_fail_cnt;
122  uint16_t i2c2_miss_start_stop_cnt = i2c2.errors->miss_start_stop_cnt;
123  uint16_t i2c2_arb_lost_cnt = i2c2.errors->arb_lost_cnt;
124  uint16_t i2c2_over_under_cnt = i2c2.errors->over_under_cnt;
125  uint16_t i2c2_pec_recep_cnt = i2c2.errors->pec_recep_cnt;
126  uint16_t i2c2_timeout_tlow_cnt = i2c2.errors->timeout_tlow_cnt;
127  uint16_t i2c2_smbus_alert_cnt = i2c2.errors->smbus_alert_cnt;
128  uint16_t i2c2_unexpected_event_cnt = i2c2.errors->unexpected_event_cnt;
129  uint32_t i2c2_last_unexpected_event = i2c2.errors->last_unexpected_event;
130  const uint8_t _bus2 = 2;
131  DOWNLINK_SEND_I2C_ERRORS(DefaultChannel, DefaultDevice,
132  &i2c2_queue_full_cnt,
133  &i2c2_ack_fail_cnt,
134  &i2c2_miss_start_stop_cnt,
135  &i2c2_arb_lost_cnt,
136  &i2c2_over_under_cnt,
137  &i2c2_pec_recep_cnt,
138  &i2c2_timeout_tlow_cnt,
139  &i2c2_smbus_alert_cnt,
140  &i2c2_unexpected_event_cnt,
141  &i2c2_last_unexpected_event,
142  &_bus2);
143 }
144 #endif
145 
146 void i2c2_init(void) {
147  i2c_init(&i2c2);
148  i2c2_hw_init();
149 }
150 
151 #endif /* USE_I2C2 */
152 
153 #if USE_I2C3
154 
155 struct i2c_periph i2c3;
156 
157 void i2c3_init(void) {
158  i2c_init(&i2c3);
159  i2c3_hw_init();
160 }
161 
162 #if PERIODIC_TELEMETRY
163 static void send_i2c3_err(void) {
164  uint16_t i2c3_queue_full_cnt = i2c3.errors->queue_full_cnt;
165  uint16_t i2c3_ack_fail_cnt = i2c3.errors->ack_fail_cnt;
166  uint16_t i2c3_miss_start_stop_cnt = i2c3.errors->miss_start_stop_cnt;
167  uint16_t i2c3_arb_lost_cnt = i2c3.errors->arb_lost_cnt;
168  uint16_t i2c3_over_under_cnt = i2c3.errors->over_under_cnt;
169  uint16_t i2c3_pec_recep_cnt = i2c3.errors->pec_recep_cnt;
170  uint16_t i2c3_timeout_tlow_cnt = i2c3.errors->timeout_tlow_cnt;
171  uint16_t i2c3_smbus_alert_cnt = i2c3.errors->smbus_alert_cnt;
172  uint16_t i2c3_unexpected_event_cnt = i2c3.errors->unexpected_event_cnt;
173  uint32_t i2c3_last_unexpected_event = i2c3.errors->last_unexpected_event;
174  const uint8_t _bus3 = 3;
175  DOWNLINK_SEND_I2C_ERRORS(DefaultChannel, DefaultDevice,
176  &i2c3_queue_full_cnt,
177  &i2c3_ack_fail_cnt,
178  &i2c3_miss_start_stop_cnt,
179  &i2c3_arb_lost_cnt,
180  &i2c3_over_under_cnt,
181  &i2c3_pec_recep_cnt,
182  &i2c3_timeout_tlow_cnt,
183  &i2c3_smbus_alert_cnt,
184  &i2c3_unexpected_event_cnt,
185  &i2c3_last_unexpected_event,
186  &_bus3);
187 }
188 #endif
189 
190 #endif /* USE_I2C3 */
191 
192 #if PERIODIC_TELEMETRY
193 static void send_i2c_err(void) {
194  static uint8_t _i2c_nb_cnt = 0;
195  switch (_i2c_nb_cnt) {
196  case 0:
197 #if USE_I2C0
198  send_i2c0_err();
199 #endif
200  break;
201  case 1:
202 #if USE_I2C1
203  send_i2c1_err();
204 #endif
205  break;
206  case 2:
207 #if USE_I2C2
208  send_i2c2_err();
209 #endif
210  break;
211  case 3:
212 #if USE_I2C3
213  send_i2c3_err();
214 #endif
215  break;
216  default:
217  break;
218  }
219  _i2c_nb_cnt++;
220  if (_i2c_nb_cnt == 4)
221  _i2c_nb_cnt = 0;
222 }
223 #endif
224 
225 
226 void i2c_init(struct i2c_periph* p) {
227  p->trans_insert_idx = 0;
228  p->trans_extract_idx = 0;
229  p->status = I2CIdle;
230 
231 #if PERIODIC_TELEMETRY
232  // the first to register do it for the others
233  register_periodic_telemetry(DefaultPeriodic, "I2C_ERRORS", send_i2c_err);
234 #endif
235 }
236 
237 
238 bool_t i2c_transmit(struct i2c_periph* p, struct i2c_transaction* t,
239  uint8_t s_addr, uint8_t len)
240 {
241  t->type = I2CTransTx;
242  t->slave_addr = s_addr;
243  t->len_w = len;
244  t->len_r = 0;
245  return i2c_submit(p, t);
246 }
247 
248 bool_t i2c_receive(struct i2c_periph* p, struct i2c_transaction* t,
249  uint8_t s_addr, uint16_t len)
250 {
251  t->type = I2CTransRx;
252  t->slave_addr = s_addr;
253  t->len_w = 0;
254  t->len_r = len;
255  return i2c_submit(p, t);
256 }
257 
258 bool_t i2c_transceive(struct i2c_periph* p, struct i2c_transaction* t,
259  uint8_t s_addr, uint8_t len_w, uint16_t len_r)
260 {
261  t->type = I2CTransTxRx;
262  t->slave_addr = s_addr;
263  t->len_w = len_w;
264  t->len_r = len_r;
265  return i2c_submit(p, t);
266 }
unsigned short uint16_t
Definition: types.h:16
bool_t i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
Submit a I2C transaction.
Definition: i2c_arch.c:335
volatile uint16_t queue_full_cnt
Definition: i2c.h:155
Periodic telemetry system header (includes downlink utility and generated code).
I2C transaction structure.
Definition: i2c.h:93
uint8_t trans_extract_idx
Definition: i2c.h:142
transmit and receive transaction
Definition: i2c.h:49
void i2c_init(struct i2c_periph *p)
Initialize I2C peripheral.
Definition: i2c.c:226
Definition: i2c.h:66
bool_t register_periodic_telemetry(struct pprz_telemetry *_pt, const char *_msg, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:38
bool_t i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition: i2c.c:258
enum I2CStatus status
Definition: i2c.h:144
uint8_t slave_addr
Slave address.
Definition: i2c.h:104
bool_t i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition: i2c.c:238
unsigned long uint32_t
Definition: types.h:18
uint8_t len_w
Number of bytes to write/transmit.
Definition: i2c.h:116
uint16_t len_r
Number of bytes to read/receive.
Definition: i2c.h:110
unsigned char uint8_t
Definition: types.h:14
uint8_t trans_insert_idx
Definition: i2c.h:141
struct i2c_errors * errors
Definition: i2c.h:148
I2C peripheral structure.
Definition: i2c.h:138
transmit only transaction
Definition: i2c.h:47
enum I2CTransactionType type
Transaction type.
Definition: i2c.h:98
static float p[2][2]
receive only transaction
Definition: i2c.h:48
bool_t i2c_receive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint16_t len)
Submit a read only transaction.
Definition: i2c.c:248
Architecture independent I2C (Inter-Integrated Circuit Bus) API.