Paparazzi UAS  v5.12_stable-4-g9b43e9b
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces 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(struct transport_tx *trans, struct link_device *dev)
40 {
41  uint16_t i2c0_wd_reset_cnt = i2c0.errors->wd_reset_cnt;
42  uint16_t i2c0_queue_full_cnt = i2c0.errors->queue_full_cnt;
43  uint16_t i2c0_ack_fail_cnt = i2c0.errors->ack_fail_cnt;
44  uint16_t i2c0_miss_start_stop_cnt = i2c0.errors->miss_start_stop_cnt;
45  uint16_t i2c0_arb_lost_cnt = i2c0.errors->arb_lost_cnt;
46  uint16_t i2c0_over_under_cnt = i2c0.errors->over_under_cnt;
47  uint16_t i2c0_pec_recep_cnt = i2c0.errors->pec_recep_cnt;
48  uint16_t i2c0_timeout_tlow_cnt = i2c0.errors->timeout_tlow_cnt;
49  uint16_t i2c0_smbus_alert_cnt = i2c0.errors->smbus_alert_cnt;
50  uint16_t i2c0_unexpected_event_cnt = i2c0.errors->unexpected_event_cnt;
51  uint32_t i2c0_last_unexpected_event = i2c0.errors->last_unexpected_event;
52  uint8_t _bus0 = 0;
53  pprz_msg_send_I2C_ERRORS(trans, dev, AC_ID,
54  &i2c0_wd_reset_cnt,
55  &i2c0_queue_full_cnt,
56  &i2c0_ack_fail_cnt,
57  &i2c0_miss_start_stop_cnt,
58  &i2c0_arb_lost_cnt,
59  &i2c0_over_under_cnt,
60  &i2c0_pec_recep_cnt,
61  &i2c0_timeout_tlow_cnt,
62  &i2c0_smbus_alert_cnt,
63  &i2c0_unexpected_event_cnt,
64  &i2c0_last_unexpected_event,
65  &_bus0);
66 }
67 #endif
68 
69 void i2c0_init(void)
70 {
71  i2c_init(&i2c0);
72  i2c0_hw_init();
73 }
74 
75 #endif /* USE_I2C0 */
76 
77 
78 #if USE_I2C1
79 
80 struct i2c_periph i2c1;
81 
82 #if PERIODIC_TELEMETRY
83 static void send_i2c1_err(struct transport_tx *trans, struct link_device *dev)
84 {
85  uint16_t i2c1_wd_reset_cnt = i2c1.errors->wd_reset_cnt;
86  uint16_t i2c1_queue_full_cnt = i2c1.errors->queue_full_cnt;
87  uint16_t i2c1_ack_fail_cnt = i2c1.errors->ack_fail_cnt;
88  uint16_t i2c1_miss_start_stop_cnt = i2c1.errors->miss_start_stop_cnt;
89  uint16_t i2c1_arb_lost_cnt = i2c1.errors->arb_lost_cnt;
90  uint16_t i2c1_over_under_cnt = i2c1.errors->over_under_cnt;
91  uint16_t i2c1_pec_recep_cnt = i2c1.errors->pec_recep_cnt;
92  uint16_t i2c1_timeout_tlow_cnt = i2c1.errors->timeout_tlow_cnt;
93  uint16_t i2c1_smbus_alert_cnt = i2c1.errors->smbus_alert_cnt;
94  uint16_t i2c1_unexpected_event_cnt = i2c1.errors->unexpected_event_cnt;
95  uint32_t i2c1_last_unexpected_event = i2c1.errors->last_unexpected_event;
96  uint8_t _bus1 = 1;
97  pprz_msg_send_I2C_ERRORS(trans, dev, AC_ID,
98  &i2c1_wd_reset_cnt,
99  &i2c1_queue_full_cnt,
100  &i2c1_ack_fail_cnt,
101  &i2c1_miss_start_stop_cnt,
102  &i2c1_arb_lost_cnt,
103  &i2c1_over_under_cnt,
104  &i2c1_pec_recep_cnt,
105  &i2c1_timeout_tlow_cnt,
106  &i2c1_smbus_alert_cnt,
107  &i2c1_unexpected_event_cnt,
108  &i2c1_last_unexpected_event,
109  &_bus1);
110 }
111 #endif
112 
113 void i2c1_init(void)
114 {
115  i2c_init(&i2c1);
116  i2c1_hw_init();
117 }
118 
119 #endif /* USE_I2C1 */
120 
121 
122 #if USE_I2C2
123 
124 struct i2c_periph i2c2;
125 
126 #if PERIODIC_TELEMETRY
127 static void send_i2c2_err(struct transport_tx *trans, struct link_device *dev)
128 {
129  uint16_t i2c2_wd_reset_cnt = i2c2.errors->wd_reset_cnt;
130  uint16_t i2c2_queue_full_cnt = i2c2.errors->queue_full_cnt;
131  uint16_t i2c2_ack_fail_cnt = i2c2.errors->ack_fail_cnt;
132  uint16_t i2c2_miss_start_stop_cnt = i2c2.errors->miss_start_stop_cnt;
133  uint16_t i2c2_arb_lost_cnt = i2c2.errors->arb_lost_cnt;
134  uint16_t i2c2_over_under_cnt = i2c2.errors->over_under_cnt;
135  uint16_t i2c2_pec_recep_cnt = i2c2.errors->pec_recep_cnt;
136  uint16_t i2c2_timeout_tlow_cnt = i2c2.errors->timeout_tlow_cnt;
137  uint16_t i2c2_smbus_alert_cnt = i2c2.errors->smbus_alert_cnt;
138  uint16_t i2c2_unexpected_event_cnt = i2c2.errors->unexpected_event_cnt;
139  uint32_t i2c2_last_unexpected_event = i2c2.errors->last_unexpected_event;
140  uint8_t _bus2 = 2;
141  pprz_msg_send_I2C_ERRORS(trans, dev, AC_ID,
142  &i2c2_wd_reset_cnt,
143  &i2c2_queue_full_cnt,
144  &i2c2_ack_fail_cnt,
145  &i2c2_miss_start_stop_cnt,
146  &i2c2_arb_lost_cnt,
147  &i2c2_over_under_cnt,
148  &i2c2_pec_recep_cnt,
149  &i2c2_timeout_tlow_cnt,
150  &i2c2_smbus_alert_cnt,
151  &i2c2_unexpected_event_cnt,
152  &i2c2_last_unexpected_event,
153  &_bus2);
154 }
155 #endif
156 
157 void i2c2_init(void)
158 {
159  i2c_init(&i2c2);
160  i2c2_hw_init();
161 }
162 
163 #endif /* USE_I2C2 */
164 
165 #if USE_I2C3
166 
167 struct i2c_periph i2c3;
168 
169 void i2c3_init(void)
170 {
171  i2c_init(&i2c3);
172  i2c3_hw_init();
173 }
174 
175 #if PERIODIC_TELEMETRY
176 static void send_i2c3_err(struct transport_tx *trans, struct link_device *dev)
177 {
178  uint16_t i2c3_wd_reset_cnt = i2c3.errors->wd_reset_cnt;
179  uint16_t i2c3_queue_full_cnt = i2c3.errors->queue_full_cnt;
180  uint16_t i2c3_ack_fail_cnt = i2c3.errors->ack_fail_cnt;
181  uint16_t i2c3_miss_start_stop_cnt = i2c3.errors->miss_start_stop_cnt;
182  uint16_t i2c3_arb_lost_cnt = i2c3.errors->arb_lost_cnt;
183  uint16_t i2c3_over_under_cnt = i2c3.errors->over_under_cnt;
184  uint16_t i2c3_pec_recep_cnt = i2c3.errors->pec_recep_cnt;
185  uint16_t i2c3_timeout_tlow_cnt = i2c3.errors->timeout_tlow_cnt;
186  uint16_t i2c3_smbus_alert_cnt = i2c3.errors->smbus_alert_cnt;
187  uint16_t i2c3_unexpected_event_cnt = i2c3.errors->unexpected_event_cnt;
188  uint32_t i2c3_last_unexpected_event = i2c3.errors->last_unexpected_event;
189  uint8_t _bus3 = 3;
190  pprz_msg_send_I2C_ERRORS(trans, dev, AC_ID,
191  &i2c3_wd_reset_cnt,
192  &i2c3_queue_full_cnt,
193  &i2c3_ack_fail_cnt,
194  &i2c3_miss_start_stop_cnt,
195  &i2c3_arb_lost_cnt,
196  &i2c3_over_under_cnt,
197  &i2c3_pec_recep_cnt,
198  &i2c3_timeout_tlow_cnt,
199  &i2c3_smbus_alert_cnt,
200  &i2c3_unexpected_event_cnt,
201  &i2c3_last_unexpected_event,
202  &_bus3);
203 }
204 #endif
205 
206 #endif /* USE_I2C3 */
207 
208 #if PERIODIC_TELEMETRY
209 static void send_i2c_err(struct transport_tx *trans __attribute__((unused)),
210  struct link_device *dev __attribute__((unused)))
211 {
212  static uint8_t _i2c_nb_cnt = 0;
213  switch (_i2c_nb_cnt) {
214  case 0:
215 #if USE_I2C0
216  send_i2c0_err(trans, dev);
217 #endif
218  break;
219  case 1:
220 #if USE_I2C1
221  send_i2c1_err(trans, dev);
222 #endif
223  break;
224  case 2:
225 #if USE_I2C2
226  send_i2c2_err(trans, dev);
227 #endif
228  break;
229  case 3:
230 #if USE_I2C3
231  send_i2c3_err(trans, dev);
232 #endif
233  break;
234  default:
235  break;
236  }
237  _i2c_nb_cnt++;
238  if (_i2c_nb_cnt == 4) {
239  _i2c_nb_cnt = 0;
240  }
241 }
242 #endif
243 
244 
245 void i2c_init(struct i2c_periph *p)
246 {
247  p->trans_insert_idx = 0;
248  p->trans_extract_idx = 0;
249  p->status = I2CIdle;
250 
251 #if PERIODIC_TELEMETRY
252  // the first to register do it for the others
253  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_I2C_ERRORS, send_i2c_err);
254 #endif
255 }
256 
257 
258 bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t,
259  uint8_t s_addr, uint8_t len)
260 {
261  t->type = I2CTransTx;
262  t->slave_addr = s_addr;
263  t->len_w = len;
264  t->len_r = 0;
265  return i2c_submit(p, t);
266 }
267 
268 bool i2c_receive(struct i2c_periph *p, struct i2c_transaction *t,
269  uint8_t s_addr, uint16_t len)
270 {
271  t->type = I2CTransRx;
272  t->slave_addr = s_addr;
273  t->len_w = 0;
274  t->len_r = len;
275  return i2c_submit(p, t);
276 }
277 
278 bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t,
279  uint8_t s_addr, uint8_t len_w, uint16_t len_r)
280 {
281  t->type = I2CTransTxRx;
282  t->slave_addr = s_addr;
283  t->len_w = len_w;
284  t->len_r = len_r;
285  return i2c_submit(p, t);
286 }
unsigned short uint16_t
Definition: types.h:16
uint16_t len_r
Number of bytes to read/receive.
Definition: i2c.h:110
Periodic telemetry system header (includes downlink utility and generated code).
transmit and receive transaction
Definition: i2c.h:49
uint8_t trans_extract_idx
Definition: i2c.h:142
void i2c_init(struct i2c_periph *p)
Initialize I2C peripheral.
Definition: i2c.c:245
Definition: i2c.h:66
struct i2c_errors * errors
Definition: i2c.h:148
enum I2CStatus status
Definition: i2c.h:144
uint8_t len_w
Number of bytes to write/transmit.
Definition: i2c.h:116
unsigned long uint32_t
Definition: types.h:18
struct i2c_transaction * trans[I2C_TRANSACTION_QUEUE_LEN]
Definition: i2c.h:140
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
i2c_submit() function
Definition: i2c_arch.c:375
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:278
I2C transaction structure.
Definition: i2c.h:93
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:258
static void send_i2c_err(struct transport_tx *trans, struct link_device *dev)
Definition: i2c.c:209
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:73
uint8_t slave_addr
Slave address.
Definition: i2c.h:104
I2C peripheral structure.
Definition: i2c.h:138
unsigned char uint8_t
Definition: types.h:14
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:268
transmit only transaction
Definition: i2c.h:47
static float p[2][2]
volatile uint16_t wd_reset_cnt
Definition: i2c.h:155
enum I2CTransactionType type
Transaction type.
Definition: i2c.h:98
uint8_t trans_insert_idx
Definition: i2c.h:141
receive only transaction
Definition: i2c.h:48
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:46
Architecture independent I2C (Inter-Integrated Circuit Bus) API.