Paparazzi UAS  v5.18.0_stable-1-g6993852-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
pca9685_i2c.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013-2020 Chris Efstathiou hendrixgr@gmail.com
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 
29 //###################################################################################################
30 // I N C L U D E D H E A D E R F I L E S
31 //###################################################################################################
33 #include "math/pprz_algebra_int.h"
34 #include "mcu_periph/i2c.h"
35 #include "mcu_periph/sys_time.h"
36 
37 #include "math/pprz_isa.h"
38 #include "mcu_periph/sys_time.h"
39 #include "subsystems/abi.h"
40 #include "mcu_periph/uart.h"
41 
42 #if DOWNLINK
44 #endif
45 
46 
47 
48 
49 
50 //###################################################################################################
51 // P R E P R O C E S S O R D I R E C T I V E S A N D D E F I N I T I O N S
52 //###################################################################################################
53 // BIG ENDIAN DEFINITIONS
54 //#define BUF2INT(_buf,_idx) ((int16_t)((_buf[_idx]<<8) | _buf[_idx+1]))
55 //#define INT2BUF(_int,_buf,_idx) { _buf[_idx] = (_int>>8); _buf[_idx+1] = _int; }
56 
57 // LITTLE ENDIAN DEFINITIONS USED FOR AvR CPU DUE TO MORE EFFICIENT DATA TRANSFERS
58 #define BUF2INT(_buf,_idx) ((int16_t)((_buf[_idx+1]<<8) | _buf[_idx]))
59 #define INT2BUF(_int,_buf,_idx) { _buf[_idx] = _int; _buf[_idx+1] = (_int>>8); }
60 
61 #ifndef PCA9685_I2C_DEV
62 #define PCA9685_I2C_DEV i2c2
63 #endif
64 PRINT_CONFIG_VAR(PCA9685_I2C_DEV)
65 
66 #ifndef PCA9865_SRV_RESOLUTION
67 #define PCA9865_SRV_RESOLUTION 1. // in microseconds
68 #endif
69 
70 #ifndef PCA9865_SRV_DEFAULT_VAL_US
71 #define PCA9865_SRV_DEFAULT_VAL_US 1000. // in microseconds
72 #endif
73 
74 #ifndef PCA9865_SRV_NUMBER
75 #define PCA9865_SRV_NUMBER 16 // in microseconds
76 #endif
77 
78 // I2C Addreses
79 #ifndef PCA9685_I2C_SLAVE_ADDR
80 #define PCA9685_I2C_SLAVE_ADDR 0xE0
81 #endif
82 PRINT_CONFIG_VAR(PCA9685_I2C_SLAVE_ADDR)
83 
84 #ifndef PCA9685_I2C_ALLCALL_ADDR
85 #define PCA9685_I2C_ALLCALL_ADDR 0xE0
86 #endif
87 #ifndef PCA9685_I2C_RESET_ADDR
88 #define PCA9685_I2C_RESET_ADDR 0x06
89 #endif
90 #ifndef PCA9685_I2C_GEN_CALL_ADDR
91 #define PCA9685_I2C_GEN_CALL_ADDR 0x00
92 #endif
93 
94 // Register addresses
95 #define PCA9685_MODE1_REG_ADDR 0x00
96 #define PCA9685_MODE2_REG_ADDR 0x01
97 #define PCA9685_ALLCALL_ADDR 0x05
98 
99 #define PCA9685_LED0_ON_L_REG_ADDR 0X06
100 #define PCA9685_LED0_ON_H_REG_ADDR 0X07
101 #define PCA9685_LED0_OFF_L_REG_ADDR 0X08
102 #define PCA9685_LED0_OFF_H_REG_ADDR 0X09
103 
104 #define PCA9685_LED1_ON_L_REG_ADDR 0X0A
105 #define PCA9685_LED1_ON_H_REG_ADDR 0X0B
106 #define PCA9685_LED1_OFF_L_REG_ADDR 0X0C
107 #define PCA9685_LED1_OFF_H_REG_ADDR 0X0D
108 
109 #define PCA9685_LED2_ON_L_REG_ADDR 0X0E
110 #define PCA9685_LED2_ON_H_REG_ADDR 0X0F
111 #define PCA9685_LED2_OFF_L_REG_ADDR 0X10
112 #define PCA9685_LED2_OFF_H_REG_ADDR 0X11
113 
114 #define PCA9685_LED3_ON_L_REG_ADDR 0X12
115 #define PCA9685_LED3_ON_H_REG_ADDR 0X13
116 #define PCA9685_LED3_OFF_L_REG_ADDR 0X14
117 #define PCA9685_LED3_OFF_H_REG_ADDR 0X15
118 
119 #define PCA9685_LED4_ON_L_REG_ADDR 0X16
120 #define PCA9685_LED4_ON_H_REG_ADDR 0X17
121 #define PCA9685_LED4_OFF_L_REG_ADDR 0X18
122 #define PCA9685_LED4_OFF_H_REG_ADDR 0X19
123 
124 #define PCA9685_LED5_ON_L_REG_ADDR 0X1A
125 #define PCA9685_LED5_ON_H_REG_ADDR 0X1B
126 #define PCA9685_LED5_OFF_L_REG_ADDR 0X1C
127 #define PCA9685_LED5_OFF_H_REG_ADDR 0X1D
128 
129 #define PCA9685_LED6_ON_L_REG_ADDR 0X1E
130 #define PCA9685_LED6_ON_H_REG_ADDR 0X1F
131 #define PCA9685_LED6_OFF_L_REG_ADDR 0X20
132 #define PCA9685_LED6_OFF_H_REG_ADDR 0X21
133 
134 #define PCA9685_LED7_ON_L_REG_ADDR 0X22
135 #define PCA9685_LED7_ON_H_REG_ADDR 0X23
136 #define PCA9685_LED7_OFF_L_REG_ADDR 0X24
137 #define PCA9685_LED7_OFF_H_REG_ADDR 0X25
138 
139 
140 #define PCA9685_LED8_ON_L_REG_ADDR 0X26
141 #define PCA9685_LED8_ON_H_REG_ADDR 0X27
142 #define PCA9685_LED8_OFF_L_REG_ADDR 0X28
143 #define PCA9685_LED8_OFF_H_REG_ADDR 0X29
144 
145 #define PCA9685_LED9_ON_L_REG_ADDR 0X2A
146 #define PCA9685_LED9_ON_H_REG_ADDR 0X2B
147 #define PCA9685_LED9_OFF_L_REG_ADDR 0X2C
148 #define PCA9685_LED9_OFF_H_REG_ADDR 0X2D
149 
150 #define PCA9685_LED10_ON_L_REG_ADDR 0X2E
151 #define PCA9685_LED10_ON_H_REG_ADDR 0X2F
152 #define PCA9685_LED10_OFF_L_REG_ADDR 0X30
153 #define PCA9685_LED10_OFF_H_REG_ADDR 0X31
154 
155 #define PCA9685_LED11_ON_L_REG_ADDR 0X32
156 #define PCA9685_LED11_ON_H_REG_ADDR 0X33
157 #define PCA9685_LED11_OFF_L_REG_ADDR 0X34
158 #define PCA9685_LED11_OFF_H_REG_ADDR 0X35
159 
160 #define PCA9685_LED12_ON_L_REG_ADDR 0X36
161 #define PCA9685_LED12_ON_H_REG_ADDR 0X37
162 #define PCA9685_LED12_OFF_L_REG_ADDR 0X38
163 #define PCA9685_LED12_OFF_H_REG_ADDR 0X39
164 
165 #define PCA9685_LED13_ON_L_REG_ADDR 0X3A
166 #define PCA9685_LED13_ON_H_REG_ADDR 0X3B
167 #define PCA9685_LED13_OFF_L_REG_ADDR 0X3C
168 #define PCA9685_LED13_OFF_H_REG_ADDR 0X3D
169 
170 #define PCA9685_LED14_ON_L_REG_ADDR 0X3E
171 #define PCA9685_LED14_ON_H_REG_ADDR 0X3F
172 #define PCA9685_LED14_OFF_L_REG_ADDR 0X40
173 #define PCA9685_LED14_OFF_H_REG_ADDR 0X41
174 
175 #define PCA9685_LED15_ON_L_REG_ADDR 0X42
176 #define PCA9685_LED15_ON_H_REG_ADDR 0X43
177 #define PCA9685_LED15_OFF_L_REG_ADDR 0X44
178 #define PCA9685_LED15_OFF_H_REG_ADDR 0X45
179 
180 #define PCA9685_ALL_LED_ON_L_REG_ADDR 0XFA
181 #define PCA9685_ALL_LED_ON_H_REG_ADDR 0XFB
182 #define PCA9685_ALL_LED_OFF_L_REG_ADDR 0XFC
183 #define PCA9685_ALL_LED_OFF_H_REG_ADDR 0XFD
184 
185 #define PCA9685_PRESCALER_REG_ADDR 0XFE
186 
187 //Bit positions
188 //MODE 0 REGISTER
189 #define PCA9865_RESTART_BIT 7 // 1= RESTART ENABLE, DEFAULT = 0
190 #define PCA9865_AUTO_INCREMENT_BIT 5 // 1 = AUTO INCREMENT, DEFAULT = 0
191 #define PCA9865_SLEEP_BIT 4 // 1 = LOW POWER MODE (OSC OFF), 0=NORMAL MODE, DEFAULT=0
192 #define PCA9865_ALLCALL_BIT 0 // 1 = ALL LED ENABLE, DEFAULT = 1
193 //MODE 1 REGISTER
194 #define PCA9865_OUTDRV_BIT 2 // 1 = TOTEM POLE, 0 = OPEN DRAIN, DEFAULT = 1
195 
196 
197 
198 
199 #if !defined(SITL)
200 //###################################################################################################
201 // P R I V A T E F U N C T I O N P R O T O T Y P E S
202 //###################################################################################################
203 #if defined(PCA9685_SEND_SERVO_VALUES) && PCA9685_SEND_SERVO_VALUES == 1
204 static void pca9685_send_servo_values(struct transport_tx *trans, struct link_device *dev);
205 #endif
206 
207 
208 
209 
210 //###################################################################################################
211 // G L O B A L V A R I A B L E S
212 //###################################################################################################
213 
214 enum {
221 };
222 
227 #if defined(PCA9685_SEND_SERVO_VALUES) && PCA9685_SEND_SERVO_VALUES == 1
228 PRINT_CONFIG_MSG("PCA9685 servo values can be found in the ""BARO_WORDS"" message")
229 uint16_t pca9865_read_servo_vals[PCA9865_SRV_NUMBER];
230 #endif
232 
233 
234 //###################################################################################################
235 // P R I V A T E F U N C T I O N D E F I N I T I O N S
236 //###################################################################################################
237 
238 //111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
239 #if defined(PCA9685_SEND_SERVO_VALUES) && PCA9685_SEND_SERVO_VALUES == 1
240 static void pca9685_send_servo_values(struct transport_tx *trans, struct link_device *dev)
241 {
242 
243 // For debugging purposes we send anly the first 4 servo values using the BARO_WORDS message.
244 // Those values are read back from PCA9865 so they indicate if the module is working as intended.
245  pprz_msg_send_CSC_SERVO_CMD(
246  trans, dev, AC_ID,
247  &pca9865_read_servo_vals[0], &pca9865_read_servo_vals[1],
248  &pca9865_read_servo_vals[2], &pca9865_read_servo_vals[3]
249  );
250 
251 
252  return;
253 }
254 #endif
255 
256 
257 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
258 // P U B L I C F U N C T I O N D E F I N I T I O N S
259 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
260 
261 //111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
262 bool pca9865_set_servo(uint8_t srv_nb, uint16_t srv_val)
263 {
264  uint16_t servo_value = 0;
265 
266  if (srv_nb < 16) {
267  servo_value = (uint16_t)((float)srv_val / (float)PCA9865_SRV_RESOLUTION);
268  pca9865_write_servo_vals[srv_nb] = servo_value;
269  pca9865_reg_nb[srv_nb] = (srv_nb * 4) + 8;
270 
271  }
272 
273  return (FALSE);
274 }
275 
276 
277 
278 //222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
280 {
281 
282  uint16_t reg_value = 0;
283  uint32_t timer0 = 0;
284 
285 // clear all arrays to zero.
286  for (srv_cnt = 0; srv_cnt < PCA9865_SRV_NUMBER; srv_cnt++) {
287  pca9865_write_servo_vals[srv_cnt] = 0;
288 #if defined(PCA9685_SEND_SERVO_VALUES) && PCA9685_SEND_SERVO_VALUES == 1
289  pca9865_read_servo_vals[srv_cnt] = 0;
290 #endif
291  pca9865_reg_nb[srv_cnt] = 0;
292  }
293  srv_cnt = 0;
295  pca9685_i2c_status = PCA9685_I2C_STATUS_UNINIT;
296 
299  timer0 = sys_time.nb_tick + (SYS_TIME_FREQUENCY / 2);
301  if (sys_time.nb_tick > timer0) { break; }
302  }
303 
304 // Internal Oscillator Off, the oscillator is off by default on power up.
306  pca9685_i2c_trans.buf[1] = (1 << PCA9865_SLEEP_BIT) | (1 << PCA9865_ALLCALL_BIT); // OSC off
308  timer0 = sys_time.nb_tick + (SYS_TIME_FREQUENCY / 2);
310  if (sys_time.nb_tick > timer0) { break; }
311  }
312 
313  reg_value = (uint16_t)((float)PCA9865_SRV_RESOLUTION / 0.04); //0.04 = 1/25 Mhz
314  if (reg_value > 0xFF) { reg_value = 0xFF; } // Sanity check.
316  pca9685_i2c_trans.buf[1] = (uint8_t)reg_value;
318  timer0 = sys_time.nb_tick + (SYS_TIME_FREQUENCY / 2);
320  if (sys_time.nb_tick > timer0) { break; }
321  }
322 
323 // Internal Oscillator On, Auto Increment on, AllCall enabled, 500 microseconds needed.
327  timer0 = sys_time.nb_tick + (SYS_TIME_FREQUENCY / 2);
329  if (sys_time.nb_tick > timer0) { break; }
330  }
331 
332  do {
335  timer0 = sys_time.nb_tick + (SYS_TIME_FREQUENCY / 2);
337  if (sys_time.nb_tick > timer0) { break; }
338  }
339 
340  } while ((pca9685_i2c_trans.buf[0] & (1 << PCA9865_RESTART_BIT)) != 0);
341 
343  pca9685_i2c_trans.buf[1] = 0;
344  pca9685_i2c_trans.buf[2] = 0;
345  reg_value = (uint16_t)((float)PCA9865_SRV_DEFAULT_VAL_US / (float)PCA9865_SRV_RESOLUTION);
346  pca9685_i2c_trans.buf[3] = (uint8_t)reg_value;
347  pca9685_i2c_trans.buf[4] = (uint8_t)((reg_value >> 8) & 0x000F);
349  timer0 = sys_time.nb_tick + (SYS_TIME_FREQUENCY / 2);
351  if (sys_time.nb_tick > timer0) { break; }
352  }
353 
354 
356  pca9685_i2c_status = PCA9685_I2C_STATUS_INITIALIZED;
357 
358 #if DOWNLINK
359 #if defined(PCA9685_SEND_SERVO_VALUES) && PCA9685_SEND_SERVO_VALUES == 1
360  register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_CSC_SERVO_CMD, pca9685_send_servo_values);
361 #endif
362 #endif
363 
364 // Initialize all 16 servo with the default values
365  pca9865_set_servo(0, 1500);
366  pca9865_set_servo(1, 1500);
367  pca9865_set_servo(2, 1000);
368  pca9865_set_servo(3, 1500);
369  for (srv_cnt = 4; srv_cnt < PCA9865_SRV_NUMBER; srv_cnt++) {
370  pca9865_set_servo(srv_cnt, 1000);
371  }
372  srv_cnt = 0;
373 
374  return;
375 }
376 
377 
378 
379 //333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
381 {
382 // If a servo change was requested write the appropriate pca9685 registers.
383 // Since those servos are not intented for flight surface control they can be updated slower
384 // at about one servo each module cycle. This way i2c load is minimized.
385 //
386 // Start searching for a servo change request either after intialization or after all
387 // servo channels have been searched (looping).
388 // This loop will be executed always until a servo value change is requested.
389 // Then it will break with "srv_cnt" having the servo number to be changed.
390 
391 // DELAY IN ORDER TO GIVE TIME TO THE INTERNAL PCA9865 OSCILLATOR TO STABILIZE.
392 //if (sys_time.nb_sec > 3){
393  if (srv_cnt >= 16 || pca9685_i2c_status == PCA9685_I2C_STATUS_INITIALIZED) {
394  for (srv_cnt = 0; srv_cnt < 16; srv_cnt++) {
395  if (pca9865_reg_nb[srv_cnt] > 0) {
396  pca9685_i2c_status = PCA9865_I2C_STATUS_CHANGE_LED_REG_FINISHED;
397  break;
398  }
399  }
400  }
401 
402  // Change the above found register in order to update the servo pwm value.
403  // The search for another servo to change is completed in the "event" function.
404  if (srv_cnt < 16) {
405  if (pca9685_i2c_status == PCA9865_I2C_STATUS_CHANGE_LED_REG_FINISHED) {
406  pca9685_i2c_trans.buf[0] = pca9865_reg_nb[srv_cnt];
407  pca9685_i2c_trans.buf[1] = (uint8_t)pca9865_write_servo_vals[srv_cnt];
408  pca9685_i2c_trans.buf[2] = (uint8_t)(pca9865_write_servo_vals[srv_cnt] >> 8) & 0x0F;
410  pca9685_i2c_status = PCA9865_I2C_STATUS_WRITE_LED_REG_BUSY;
411  }
412  }
413 //}
414 
415  return;
416 }
417 
418 
419 
420 //444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
422 {
423 
424 //--------------------------------------------------------------------------------------------------
425 // IF SUCCESFULL
426 //--------------------------------------------------------------------------------------------------
428 
429  if (pca9685_i2c_status == PCA9865_I2C_STATUS_WRITE_LED_REG_BUSY) {
430  // Read back the changed value just to be sure...
431  pca9685_i2c_trans.buf[0] = pca9865_reg_nb[srv_cnt];
433  pca9685_i2c_status = PCA9865_I2C_STATUS_READ_LED_REG_BUSY;
434 
435  } else if (pca9685_i2c_status == PCA9865_I2C_STATUS_READ_LED_REG_BUSY) {
436 #if defined(PCA9685_SEND_SERVO_VALUES) && PCA9685_SEND_SERVO_VALUES == 1
437  pca9865_read_servo_vals[srv_cnt] = BUF2INT(pca9685_i2c_trans.buf, 0);
438 #endif
439  if (BUF2INT(pca9685_i2c_trans.buf, 0) != pca9865_write_servo_vals[srv_cnt]) {
440  //pca9685_i2c_init();
441  return;
442  }
443  pca9685_i2c_status = PCA9865_I2C_STATUS_CHANGE_LED_REG_FINISHED;
444  // Delete this request.
445  pca9865_reg_nb[srv_cnt] = 0;
446  // Search for the next changed servo value.
447  // If a value > 0 is detected x will contain the new servo number to be changed.
448  srv_cnt++;
449  for (; srv_cnt < 16; srv_cnt++) { if (pca9865_reg_nb[srv_cnt] > 0) { break; } }
450  }
451 //-------------------------------------------------------------------------------------------------
452 // ELSE IF NOT SUCCESFULL
453 //-------------------------------------------------------------------------------------------------
454  }//else{ pca9685_i2c_init(); }
455 
456  return;
457 }
458 
459 #else
460 // just to stop the compiler complaining i manipulte srv_nb and srv_val a little.
461 bool pca9865_set_servo(uint8_t srv_nb, uint16_t srv_val) { srv_nb = srv_val; srv_nb /= 2; return (FALSE); }
462 void pca9685_i2c_init(void) { return; }
463 void pca9685_i2c_periodic(void) { return; }
464 void pca9685_i2c_event(void) { return; }
465 
466 #endif // #if !defined(SITL)
467 
468 /************************************************************************************************/
469 // T H E E N D
470 /************************************************************************************************/
471 
uint8_t pca9685_i2c_status
Definition: pca9685_i2c.c:224
unsigned short uint16_t
Definition: types.h:16
#define BUF2INT(_buf, _idx)
Definition: pca9685_i2c.c:58
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
transaction successfully finished by I2C driver
Definition: i2c.h:57
#define PCA9865_ALLCALL_BIT
Definition: pca9685_i2c.c:192
Periodic telemetry system header (includes downlink utility and generated code).
Main include for ABI (AirBorneInterface).
struct i2c_transaction pca9685_i2c_trans
Definition: pca9685_i2c.c:223
#define PCA9865_SRV_DEFAULT_VAL_US
Definition: pca9685_i2c.c:71
#define PCA9685_I2C_SLAVE_ADDR
Definition: pca9685_i2c.c:80
volatile uint32_t nb_tick
SYS_TIME_TICKS since startup.
Definition: sys_time.h:74
#define PCA9865_RESTART_BIT
Definition: pca9685_i2c.c:189
#define FALSE
Definition: std.h:5
#define PCA9685_I2C_RESET_ADDR
Definition: pca9685_i2c.c:88
#define PCA9865_SRV_RESOLUTION
Definition: pca9685_i2c.c:67
transaction set to done by user level
Definition: i2c.h:59
Architecture independent timing functions.
#define PCA9865_AUTO_INCREMENT_BIT
Definition: pca9685_i2c.c:190
Paparazzi atmospheric pressure conversion utilities.
unsigned long uint32_t
Definition: types.h:18
void pca9685_i2c_init(void)
Definition: pca9685_i2c.c:279
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
#define SYS_TIME_FREQUENCY
(Default) sys_time timer frequency in Hz.
Definition: sys_time.h:55
#define PCA9865_SRV_NUMBER
Definition: pca9685_i2c.c:75
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
I2C transaction structure.
Definition: i2c.h:93
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
void pca9685_i2c_periodic(void)
Definition: pca9685_i2c.c:380
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
#define PCA9685_PRESCALER_REG_ADDR
Definition: pca9685_i2c.c:185
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
uint8_t srv_cnt
Definition: pca9685_i2c.c:225
unsigned char uint8_t
Definition: types.h:14
#define PCA9685_ALL_LED_ON_L_REG_ADDR
Definition: pca9685_i2c.c:180
uint8_t pca9865_reg_nb[16]
Definition: pca9685_i2c.c:231
#define PCA9685_I2C_DEV
Definition: pca9685_i2c.c:62
void pca9685_i2c_event(void)
Definition: pca9685_i2c.c:421
uint16_t pca9865_write_servo_vals[PCA9865_SRV_NUMBER]
Definition: pca9685_i2c.c:226
bool pca9865_set_servo(uint8_t srv_nb, uint16_t srv_val)
Definition: pca9685_i2c.c:262
#define PCA9865_SLEEP_BIT
Definition: pca9685_i2c.c:191
transaction is pending in queue
Definition: i2c.h:55
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:46
Paparazzi fixed point algebra.
Architecture independent I2C (Inter-Integrated Circuit Bus) API.
#define PCA9685_I2C_ALLCALL_ADDR
Definition: pca9685_i2c.c:85
#define PCA9685_I2C_GEN_CALL_ADDR
Definition: pca9685_i2c.c:91
#define PCA9685_MODE1_REG_ADDR
Definition: pca9685_i2c.c:95