Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
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#include "mcu_periph/sys_time.h"
30
31#if PERIODIC_TELEMETRY
33#endif
34
35#if USE_I2C0
36
37struct i2c_periph i2c0;
38
39#if PERIODIC_TELEMETRY
40static void send_i2c0_err(struct transport_tx *trans, struct link_device *dev)
41{
43 uint16_t i2c0_queue_full_cnt = i2c0.errors->queue_full_cnt;
44 uint16_t i2c0_ack_fail_cnt = i2c0.errors->ack_fail_cnt;
45 uint16_t i2c0_miss_start_stop_cnt = i2c0.errors->miss_start_stop_cnt;
46 uint16_t i2c0_arb_lost_cnt = i2c0.errors->arb_lost_cnt;
47 uint16_t i2c0_over_under_cnt = i2c0.errors->over_under_cnt;
48 uint16_t i2c0_pec_recep_cnt = i2c0.errors->pec_recep_cnt;
49 uint16_t i2c0_timeout_tlow_cnt = i2c0.errors->timeout_tlow_cnt;
50 uint16_t i2c0_smbus_alert_cnt = i2c0.errors->smbus_alert_cnt;
51 uint16_t i2c0_unexpected_event_cnt = i2c0.errors->unexpected_event_cnt;
52 uint32_t i2c0_last_unexpected_event = i2c0.errors->last_unexpected_event;
53 uint8_t _bus0 = 0;
66 &_bus0);
67}
68#endif
69
70void i2c0_init(void)
71{
72 i2c_init(&i2c0);
74}
75
76#endif /* USE_I2C0 */
77
78
79#if USE_I2C1
80
81struct i2c_periph i2c1;
82
83#if PERIODIC_TELEMETRY
84static void send_i2c1_err(struct transport_tx *trans, struct link_device *dev)
85{
87 uint16_t i2c1_queue_full_cnt = i2c1.errors->queue_full_cnt;
88 uint16_t i2c1_ack_fail_cnt = i2c1.errors->ack_fail_cnt;
89 uint16_t i2c1_miss_start_stop_cnt = i2c1.errors->miss_start_stop_cnt;
90 uint16_t i2c1_arb_lost_cnt = i2c1.errors->arb_lost_cnt;
91 uint16_t i2c1_over_under_cnt = i2c1.errors->over_under_cnt;
92 uint16_t i2c1_pec_recep_cnt = i2c1.errors->pec_recep_cnt;
93 uint16_t i2c1_timeout_tlow_cnt = i2c1.errors->timeout_tlow_cnt;
94 uint16_t i2c1_smbus_alert_cnt = i2c1.errors->smbus_alert_cnt;
95 uint16_t i2c1_unexpected_event_cnt = i2c1.errors->unexpected_event_cnt;
96 uint32_t i2c1_last_unexpected_event = i2c1.errors->last_unexpected_event;
97 uint8_t _bus1 = 1;
110 &_bus1);
111}
112#endif
113
114void i2c1_init(void)
115{
116 i2c_init(&i2c1);
117 i2c1_hw_init();
118}
119
120#endif /* USE_I2C1 */
121
122
123#if USE_I2C2
124
125struct i2c_periph i2c2;
126
127#if PERIODIC_TELEMETRY
128static void send_i2c2_err(struct transport_tx *trans, struct link_device *dev)
129{
131 uint16_t i2c2_queue_full_cnt = i2c2.errors->queue_full_cnt;
132 uint16_t i2c2_ack_fail_cnt = i2c2.errors->ack_fail_cnt;
133 uint16_t i2c2_miss_start_stop_cnt = i2c2.errors->miss_start_stop_cnt;
134 uint16_t i2c2_arb_lost_cnt = i2c2.errors->arb_lost_cnt;
135 uint16_t i2c2_over_under_cnt = i2c2.errors->over_under_cnt;
136 uint16_t i2c2_pec_recep_cnt = i2c2.errors->pec_recep_cnt;
137 uint16_t i2c2_timeout_tlow_cnt = i2c2.errors->timeout_tlow_cnt;
138 uint16_t i2c2_smbus_alert_cnt = i2c2.errors->smbus_alert_cnt;
139 uint16_t i2c2_unexpected_event_cnt = i2c2.errors->unexpected_event_cnt;
140 uint32_t i2c2_last_unexpected_event = i2c2.errors->last_unexpected_event;
141 uint8_t _bus2 = 2;
154 &_bus2);
155}
156#endif
157
158void i2c2_init(void)
159{
160 i2c_init(&i2c2);
161 i2c2_hw_init();
162}
163
164#endif /* USE_I2C2 */
165
166#if USE_I2C3
167
168struct i2c_periph i2c3;
169
170void i2c3_init(void)
171{
172 i2c_init(&i2c3);
173 i2c3_hw_init();
174}
175
176#if PERIODIC_TELEMETRY
177static void send_i2c3_err(struct transport_tx *trans, struct link_device *dev)
178{
179 uint16_t i2c3_wd_reset_cnt = i2c3.errors->wd_reset_cnt;
180 uint16_t i2c3_queue_full_cnt = i2c3.errors->queue_full_cnt;
181 uint16_t i2c3_ack_fail_cnt = i2c3.errors->ack_fail_cnt;
182 uint16_t i2c3_miss_start_stop_cnt = i2c3.errors->miss_start_stop_cnt;
183 uint16_t i2c3_arb_lost_cnt = i2c3.errors->arb_lost_cnt;
184 uint16_t i2c3_over_under_cnt = i2c3.errors->over_under_cnt;
185 uint16_t i2c3_pec_recep_cnt = i2c3.errors->pec_recep_cnt;
186 uint16_t i2c3_timeout_tlow_cnt = i2c3.errors->timeout_tlow_cnt;
187 uint16_t i2c3_smbus_alert_cnt = i2c3.errors->smbus_alert_cnt;
188 uint16_t i2c3_unexpected_event_cnt = i2c3.errors->unexpected_event_cnt;
189 uint32_t i2c3_last_unexpected_event = i2c3.errors->last_unexpected_event;
190 uint8_t _bus3 = 3;
203 &_bus3);
204}
205#endif
206
207#endif /* USE_I2C3 */
208
209#if USE_I2C4
210
211struct i2c_periph i2c4;
212
213void i2c4_init(void)
214{
215 i2c_init(&i2c4);
216 i2c4_hw_init();
217}
218
219#if PERIODIC_TELEMETRY
220static void send_i2c4_err(struct transport_tx *trans, struct link_device *dev)
221{
222 uint16_t i2c4_wd_reset_cnt = i2c4.errors->wd_reset_cnt;
223 uint16_t i2c4_queue_full_cnt = i2c4.errors->queue_full_cnt;
224 uint16_t i2c4_ack_fail_cnt = i2c4.errors->ack_fail_cnt;
225 uint16_t i2c4_miss_start_stop_cnt = i2c4.errors->miss_start_stop_cnt;
226 uint16_t i2c4_arb_lost_cnt = i2c4.errors->arb_lost_cnt;
227 uint16_t i2c4_over_under_cnt = i2c4.errors->over_under_cnt;
228 uint16_t i2c4_pec_recep_cnt = i2c4.errors->pec_recep_cnt;
229 uint16_t i2c4_timeout_tlow_cnt = i2c4.errors->timeout_tlow_cnt;
230 uint16_t i2c4_smbus_alert_cnt = i2c4.errors->smbus_alert_cnt;
231 uint16_t i2c4_unexpected_event_cnt = i2c4.errors->unexpected_event_cnt;
232 uint32_t i2c4_last_unexpected_event = i2c4.errors->last_unexpected_event;
233 uint8_t _bus4 = 4;
246 &_bus4);
247}
248#endif
249
250#endif /* USE_I2C4 */
251
252#if USE_SOFTI2C0
253extern void send_softi2c0_err(struct transport_tx *trans, struct link_device *dev);
254#endif /* USE_SOFTI2C0 */
255
256#if USE_SOFTI2C1
257extern void send_softi2c1_err(struct transport_tx *trans, struct link_device *dev);
258#endif /* USE_SOFTI2C1 */
259
260#if PERIODIC_TELEMETRY
261static void send_i2c_err(struct transport_tx *trans __attribute__((unused)),
262 struct link_device *dev __attribute__((unused)))
263{
264 static uint8_t _i2c_nb_cnt = 0;
265 switch (_i2c_nb_cnt) {
266 case 0:
267#if USE_I2C0
269#endif
270 break;
271 case 1:
272#if USE_I2C1
274#endif
275 break;
276 case 2:
277#if USE_I2C2
279#endif
280 break;
281 case 3:
282#if USE_I2C3
284#endif
285 break;
286 case 4:
287#if USE_I2C4
289#endif
290 case 5:
291#if USE_SOFTI2C0
293#endif
294 case 6:
295#if USE_SOFTI2C1
297#endif
298 break;
299 default:
300 break;
301 }
302 _i2c_nb_cnt++;
303 if (_i2c_nb_cnt == 7) {
304 _i2c_nb_cnt = 0;
305 }
306}
307#endif
308
309
310void i2c_init(struct i2c_periph *p)
311{
312 p->trans_insert_idx = 0;
313 p->trans_extract_idx = 0;
314 p->status = I2CIdle;
315 p->reg_addr = NULL;
316
317#if PERIODIC_TELEMETRY
318 // the first to register do it for the others
320#endif
321}
322
323
326{
327 t->type = I2CTransTx;
328 t->slave_addr = s_addr;
329 t->len_w = len;
330 t->len_r = 0;
331 return i2c_submit(p, t);
332}
333
336{
337 t->type = I2CTransRx;
338 t->slave_addr = s_addr;
339 t->len_w = 0;
340 t->len_r = len;
341 return i2c_submit(p, t);
342}
343
345 uint8_t s_addr, uint8_t len_w, uint16_t len_r)
346{
347 t->type = I2CTransTxRx;
348 t->slave_addr = s_addr;
349 t->len_w = len_w;
350 t->len_r = len_r;
351 return i2c_submit(p, t);
352}
353
355#ifndef I2C_BLOCKING_TIMEOUT
356#define I2C_BLOCKING_TIMEOUT 1.f
357#endif
358
361{
362 t->type = I2CTransTx;
363 t->slave_addr = s_addr;
364 t->len_w = len;
365 t->len_r = 0;
366 if (!i2c_submit(p, t)) {
367 return false;
368 }
369
370 // Wait for transaction to complete
371 float start_t = get_sys_time_float();
372 while (t->status == I2CTransPending || t->status == I2CTransRunning) {
373 if (p->spin) p->spin(p);
375 break; // timeout after 1 second
376 }
377 }
378 return true;
379}
380
383{
384 t->type = I2CTransRx;
385 t->slave_addr = s_addr;
386 t->len_w = 0;
387 t->len_r = len;
388 if (!i2c_submit(p, t)) {
389 return false;
390 }
391
392 // Wait for transaction to complete
393 float start_t = get_sys_time_float();
394 while (t->status == I2CTransPending || t->status == I2CTransRunning) {
395 if (p->spin) p->spin(p);
397 break; // timeout after 1 second
398 }
399 }
400 return true;
401}
402
404 uint8_t s_addr, uint8_t len_w, uint16_t len_r)
405{
406 t->type = I2CTransTxRx;
407 t->slave_addr = s_addr;
408 t->len_w = len_w;
409 t->len_r = len_r;
410 if (!i2c_submit(p, t)) {
411 return false;
412 }
413
414 // Wait for transaction to complete
415 float start_t = get_sys_time_float();
416 while (t->status == I2CTransPending || t->status == I2CTransRunning) {
417 if (p->spin) p->spin(p);
419 break; // timeout after 1 second
420 }
421 }
422 return true;
423}
struct i2c_errors * errors
Definition i2c.h:159
volatile uint16_t wd_reset_cnt
Definition i2c.h:166
struct i2c_transaction * trans[I2C_TRANSACTION_QUEUE_LEN]
Definition i2c.h:151
bool i2c_blocking_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 and wait for it to complete.
Definition i2c.c:403
bool i2c_blocking_receive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint16_t len)
Submit a read only transaction and wait for it to complete.
Definition i2c.c:381
static bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
Submit a I2C transaction.
Definition i2c.h:266
bool 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:324
void i2c_init(struct i2c_periph *p)
Initialize I2C peripheral.
Definition i2c.c:310
bool 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:334
bool i2c_blocking_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction and wait for it to complete.
Definition i2c.c:359
bool 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:344
@ I2CIdle
Definition i2c.h:66
@ I2CTransRunning
transaction is currently ongoing
Definition i2c.h:56
@ I2CTransPending
transaction is pending in queue
Definition i2c.h:55
@ I2CTransRx
receive only transaction
Definition i2c.h:48
@ I2CTransTx
transmit only transaction
Definition i2c.h:47
@ I2CTransTxRx
transmit and receive transaction
Definition i2c.h:49
I2C transaction structure.
Definition i2c.h:93
static void send_i2c_err(struct transport_tx *trans, struct link_device *dev)
Definition i2c.c:261
#define I2C_BLOCKING_TIMEOUT
Default timeout for blocking I2C transactions.
Definition i2c.c:356
Architecture independent I2C (Inter-Integrated Circuit Bus) API.
static float p[2][2]
uint16_t foo
Definition main_demo5.c:58
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
Architecture independent timing functions.
static float get_sys_time_float(void)
Get the time in seconds since startup.
Definition sys_time.h:138
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.