PX4 Firmware
PX4 Autopilot Software http://px4.io
voxlpm.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2019 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file voxlpm.cpp
36  * Driver for the VOXL Power Management unit
37  */
38 
39 #include "voxlpm.hpp"
40 
41 /*
42  * The VOXLPM has two LTC2946 ICs on it.
43  * Address 0x6A - measures battery voltage and current with a 0.0005 ohm sense resistor
44  * Address 0x6B - measures 5VDC ouptut voltage and current
45  */
46 VOXLPM::VOXLPM(const char *path, int bus, int address, VOXLPM_CH_TYPE ch_type) :
47  I2C("voxlpm", path, bus, address, 400000),
48  ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(I2C::get_device_id())),
49  _sample_perf(perf_alloc(PC_ELAPSED, "voxlpm: sample")),
50  _bat_pub_topic(nullptr),
51  _pm_pub_topic(nullptr),
52  _voltage(0.0f),
53  _amperage(0.0f)
54 {
55  _ch_type = ch_type;
56 
59 
60  } else {
62  }
63 }
64 
66 {
67  // make sure we are truly inactive
68  stop();
70 }
71 
72 int
74 {
75  int ret = PX4_ERROR;
76 
77  /* do I2C init (and probe) first */
78  if (I2C::init() != OK) {
79  return ret;
80  }
81 
84 
86 
87  start();
88 
89  return PX4_OK;
90 }
91 
92 void
94 {
96 
98  printf("- type: BATT\n");
99 
100  } else {
101  printf("- type: P5VDC\n");
102  }
103 
104  printf(" - voltage: %9.2f VDC \n", (double)_voltage);
105  printf(" - current: %9.2f ADC \n", (double)_amperage);
106  printf(" - rsense: %9.6f ohm \n", (double)_rsense);
107  printf(" - meas interval: %u us \n", _meas_interval);
108 }
109 
110 void
112 {
113  /* make sure we are stopped first */
114  uint32_t last_meas_interval = _meas_interval;
115  stop();
116  _meas_interval = last_meas_interval;
117 
118  ScheduleOnInterval(_meas_interval, 1000);
119 }
120 
121 void
123 {
124  ScheduleClear();
125 }
126 
127 void
129 {
130  measure();
131 }
132 
133 int
135 {
136  _voltage = 0.0f;
137  _amperage = 0.0f;
138 
139  uint8_t vraw[2];
140  uint8_t iraw[2];
141 
143 
145 
146  int curr_read_ret = read_reg_buf(VOXLPM_LTC2946_DELTA_SENSE_MSB_REG, iraw, sizeof(iraw)); // 0x14
147  int volt_read_ret = read_reg_buf(VOXLPM_LTC2946_VIN_MSB_REG, vraw, sizeof(vraw)); // 0x1E
148 
149  if ((volt_read_ret == 0) && (curr_read_ret == 0)) {
150  uint16_t volt16 = (((uint16_t)vraw[0]) << 8) | vraw[1]; // MSB first
151  volt16 >>= 4; // data is 12 bit and left-aligned
153 
154  uint16_t curr16 = (((uint16_t)iraw[0]) << 8) | iraw[1]; // MSB first
155  curr16 >>= 4; // data is 12 bit and left-aligned
157 
158  switch (_ch_type) {
159  case VOXLPM_CH_TYPE_VBATT: {
160  _battery.updateBatteryStatus(tnow, _voltage, _amperage, true, true, 0, 0, false, &_bat_status);
161 
162  if (_bat_pub_topic != nullptr) {
164 
165  } else {
167  }
168  }
169 
170  // fallthrough
171 
172  case VOXLPM_CH_TYPE_P5VDC: {
173  memset(&_pm_status, 0x00, sizeof(_pm_status));
174  _pm_status.timestamp = tnow;
175  _pm_status.voltage_v = (float) _voltage;
176  _pm_status.current_a = (float) _amperage;
177 
178  //_pm_pub_topic.power_w = (float) _power * _power_lsb;
179 
180  if (_pm_pub_topic != nullptr) {
181  orb_publish(ORB_ID(power_monitor), _pm_pub_topic, &_pm_status);
182 
183  } else {
184  _pm_pub_topic = orb_advertise(ORB_ID(power_monitor), &_pm_status);
185  }
186  }
187  break;
188 
189  }
190 
191  } else {
192  switch (_ch_type) {
193  case VOXLPM_CH_TYPE_VBATT: {
194  _battery.updateBatteryStatus(tnow, 0.0, 0.0, true, true, 0, 0, false, &_bat_status);
195 
196  if (_bat_pub_topic != nullptr) {
198 
199  } else {
201  }
202  }
203  break;
204 
205  default:
206  break;
207  }
208  }
209 
211 
212  return OK;
213 }
214 
215 uint8_t
216 VOXLPM::read_reg(uint8_t addr)
217 {
218  uint8_t cmd[2] = { (uint8_t)(addr), 0};
219  transfer(&cmd[0], 1, &cmd[1], 1);
220 
221  return cmd[1];
222 }
223 
224 int
225 VOXLPM::read_reg_buf(uint8_t addr, uint8_t *buf, uint8_t len)
226 {
227  const uint8_t cmd = (uint8_t)(addr);
228  return transfer(&cmd, sizeof(cmd), buf, len);
229 }
230 
231 int
232 VOXLPM::write_reg(uint8_t value, uint8_t addr)
233 {
234  uint8_t cmd[2] = { (uint8_t)(addr), value};
235  return transfer(cmd, sizeof(cmd), nullptr, 0);
236 }
float _amperage
Definition: voxlpm.hpp:171
perf_counter_t _sample_perf
Definition: voxlpm.hpp:161
void print_info()
Definition: voxlpm.cpp:93
#define VOXLPM_LTC2946_VFS_SENSE
Definition: voxlpm.hpp:129
measure the time elapsed performing an event
Definition: perf_counter.h:56
VOXLPM_CH_TYPE
Definition: voxlpm.hpp:140
struct power_monitor_s _pm_status
Definition: voxlpm.hpp:167
void reset(battery_status_s *battery_status)
Reset all battery stats and report invalid/nothing.
Definition: battery.cpp:55
int read_reg_buf(uint8_t addr, uint8_t *buf, uint8_t len)
Definition: voxlpm.cpp:225
unsigned _meas_interval
Definition: voxlpm.hpp:155
orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data)
Definition: uORB.cpp:43
int write_reg(uint8_t value, uint8_t addr)
Definition: voxlpm.cpp:232
#define DEFAULT_CTRLB_REG_VAL
Definition: voxlpm.hpp:123
float _voltage
Definition: voxlpm.hpp:170
uint64_t timestamp
Definition: power_monitor.h:53
struct battery_status_s _bat_status
Definition: voxlpm.hpp:166
Shared defines for the voxlpm (QTY2 LTC2946) driver.
VOXLPM_CH_TYPE _ch_type
Definition: voxlpm.hpp:169
void Run() override
Definition: voxlpm.cpp:128
Battery _battery
Definition: voxlpm.hpp:174
#define VOXLPM_LTC2946_DELTA_SENSE_MSB_REG
Definition: voxlpm.hpp:87
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
#define VOXLPM_LTC2946_VFS_DELTA_SENSE
Definition: voxlpm.hpp:132
#define DEFAULT_CTRLA_REG_VAL
Definition: voxlpm.hpp:105
void perf_free(perf_counter_t handle)
Free a counter.
void init()
Activates/configures the hardware registers.
#define perf_alloc(a, b)
Definition: px4io.h:59
orb_advert_t _bat_pub_topic
Definition: voxlpm.hpp:163
void stop()
Definition: voxlpm.cpp:122
VOXLPM(const char *path, int bus, int address, VOXLPM_CH_TYPE ch_type)
Definition: voxlpm.cpp:46
float _rsense
Definition: voxlpm.hpp:172
void start()
Definition: voxlpm.cpp:111
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
void perf_end(perf_counter_t handle)
End a performance event.
#define VOXLPM_LTC2946_CTRLB_REG
Definition: voxlpm.hpp:81
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
Definition: drv_hrt.h:58
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
Definition: uORB.cpp:70
void updateBatteryStatus(hrt_abstime timestamp, float voltage_v, float current_a, bool connected, bool selected_source, int priority, float throttle_normalized, bool armed, battery_status_s *status)
Update current battery status message.
Definition: battery.cpp:68
uint8_t read_reg(uint8_t addr)
Definition: voxlpm.cpp:216
#define VOXLPM_LTC2946_CTRLA_REG
Definition: voxlpm.hpp:80
#define VOXLPM_LTC2946_RESOLUTION
Definition: voxlpm.hpp:126
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
virtual int init()
Definition: voxlpm.cpp:73
Definition: bst.cpp:62
int measure()
Definition: voxlpm.cpp:134
#define VOXLPM_RSENSE_VBATT
Definition: voxlpm.hpp:135
#define OK
Definition: uavcan_main.cpp:71
#define VOXLPM_RSENSE_5VOUT
Definition: voxlpm.hpp:138
#define VOXLPM_LTC2946_VIN_MSB_REG
Definition: voxlpm.hpp:90
orb_advert_t _pm_pub_topic
Definition: voxlpm.hpp:164
void perf_begin(perf_counter_t handle)
Begin a performance event.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
virtual ~VOXLPM()
Definition: voxlpm.cpp:65