43 #include <board_config.h> 55 #include <px4_platform_common/px4_config.h> 56 #include <px4_platform_common/getopt.h> 57 #include <px4_platform_common/log.h> 58 #include <px4_platform_common/module.h> 91 #if !defined(BOARD_HAS_PWM) 92 # error "board_config.h needs to define BOARD_HAS_PWM" 95 #define PX4FMU_DEVICE_PATH "/dev/px4fmu" 124 static int task_spawn(
int argc,
char *argv[]);
127 static int custom_command(
int argc,
char *argv[]);
130 static int print_usage(
const char *reason =
nullptr);
138 static int fmu_new_mode(
PortMode new_mode);
142 static int fake(
int argc,
char *argv[]);
144 virtual int ioctl(
file *filp,
int cmd,
unsigned long arg);
151 static int set_i2c_bus_clock(
unsigned bus,
unsigned clock_hz);
153 static void capture_trampoline(
void *context, uint32_t chan_index,
157 void update_pwm_trims();
159 bool updateOutputs(
bool stop_motors, uint16_t outputs[MAX_ACTUATORS],
160 unsigned num_outputs,
unsigned num_control_groups_updated)
override;
163 static constexpr
int FMU_MAX_ACTUATORS = DIRECT_PWM_OUTPUT_CHANNELS;
164 static_assert(FMU_MAX_ACTUATORS <= MAX_ACTUATORS,
"Increase MAX_ACTUATORS if this fails");
170 unsigned _pwm_default_rate{50};
171 unsigned _pwm_alt_rate{50};
172 uint32_t _pwm_alt_rate_channels{0};
174 unsigned _current_update_rate{0};
179 unsigned _num_outputs{0};
180 int _class_instance{-1};
183 uint32_t _pwm_mask{0};
184 bool _pwm_initialized{
false};
185 bool _test_mode{
false};
187 unsigned _num_disarmed_set{0};
191 void capture_callback(uint32_t chan_index,
192 hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow);
193 void update_current_rate();
194 int set_pwm_rate(
unsigned rate_map,
unsigned default_rate,
unsigned alt_rate);
195 int pwm_ioctl(
file *filp,
int cmd,
unsigned long arg);
196 void update_pwm_rev_mask();
197 void update_pwm_out_state(
bool on);
201 static void sensor_reset(
int ms);
202 static void peripheral_reset(
int ms);
204 int capture_ioctl(
file *filp,
int cmd,
unsigned long arg);
250 PX4_ERR(
"FAILED registering class device");
289 #if defined(BOARD_HAS_CAPTURE) 294 PX4_DEBUG(
"MODE_2PWM2CAP");
300 PX4_DEBUG(
"MODE_2PWM");
312 #if defined(BOARD_HAS_CAPTURE) 315 PX4_DEBUG(
"MODE_3PWM1CAP");
322 PX4_DEBUG(
"MODE_3PWM");
334 #if defined(BOARD_HAS_CAPTURE) 337 PX4_DEBUG(
"MODE_4PWM1CAP");
344 PX4_DEBUG(
"MODE_4PWM");
356 #if defined(BOARD_HAS_CAPTURE) 359 PX4_DEBUG(
"MODE_4PWM2CAP");
373 #if defined(BOARD_HAS_CAPTURE) 376 PX4_DEBUG(
"MODE_5PWM1CAP");
383 PX4_DEBUG(
"MODE_5PWM");
395 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 398 PX4_DEBUG(
"MODE_6PWM");
411 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 414 PX4_DEBUG(
"MODE_8PWM");
426 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 14 429 PX4_DEBUG(
"MODE_14PWM");
442 PX4_DEBUG(
"MODE_NONE");
495 PX4_DEBUG(
"set_pwm_rate %x %u %u", rate_map, default_rate, alt_rate);
497 for (
unsigned pass = 0; pass < 2; pass++) {
523 uint32_t alt = rate_map & mask;
527 if ((alt != 0) && (alt != mask)) {
528 PX4_WARN(
"rate group %u mask %x bad overlap %x", group, mask, alt);
537 PX4_WARN(
"rate group set alt failed");
543 PX4_WARN(
"rate group set default failed");
563 return device::I2C::set_bus_clock(bus, clock_hz);
583 const int update_interval_in_us =
math::constrain(1000000 / max_rate, 500, 100000);
593 reverse_pwm_mask = 0;
595 const char *pname_format;
598 pname_format =
"PWM_MAIN_REV%d";
601 pname_format =
"PWM_AUX_REV%d";
604 PX4_ERR(
"PWM REV only for MAIN and AUX");
612 sprintf(pname, pname_format, i + 1);
618 reverse_pwm_mask |= ((int16_t)(ival != 0)) << i;
626 PX4_DEBUG(
"update_pwm_trims");
634 const char *pname_format;
637 pname_format =
"PWM_MAIN_TRIM%d";
640 pname_format =
"PWM_AUX_TRIM%d";
643 PX4_ERR(
"PWM TRIM only for MAIN and AUX");
651 sprintf(pname, pname_format, i + 1);
657 values[i] = (int16_t)(10000 * pval);
658 PX4_DEBUG(
"%s: %d", pname, values[i]);
664 PX4_DEBUG(
"set %d trims", n_out);
673 _object.store(instance);
674 _task_id = task_id_is_work_queue;
676 if (instance->
init() == PX4_OK) {
681 PX4_ERR(
"alloc failed");
685 _object.store(
nullptr);
693 hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow)
701 hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow)
703 fprintf(stdout,
"FMU: Capture chan:%d time:%lld state:%d overflow:%d\n", chan_index, edge_time, edge_state, overflow);
720 unsigned num_outputs,
unsigned num_control_groups_updated)
728 for (
size_t i = 0; i < num_outputs; i++) {
736 if (num_control_groups_updated > 0) {
802 if (ret != -ENOTTY) {
818 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 821 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 824 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 14 831 PX4_DEBUG(
"not in a PWM mode");
836 if (ret == -ENOTTY) {
837 ret = CDev::ioctl(filp, cmd, arg);
848 PX4_DEBUG(
"fmu ioctl cmd: %d, arg: %ld", cmd, arg);
902 if (pwm->
values[i] == 0) {
909 #if PWM_LOWEST_MIN > 0 947 if (pwm->
values[i] == 0) {
953 #if PWM_LOWEST_MIN > 0 1002 if (pwm->
values[i] == 0) {
1009 #if PWM_LOWEST_MIN > 0 1033 arg = (
unsigned long)&pwm;
1047 if (pwm->
values[i] == 0) {
1071 arg = (
unsigned long)&pwm;
1080 PX4_DEBUG(
"error: too many trim values: %d", pwm->
channel_count);
1086 PX4_ERR(
"error: no mixer loaded");
1103 PX4_WARN(
"warning: trim values not valid - no mixer loaded");
1113 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 14 1127 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 1140 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 1150 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 5 1187 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 14 1201 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 1213 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 1223 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 5 1258 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 5 1261 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 1264 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 1268 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 14 1282 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 14 1285 *(
unsigned *)arg = 14;
1289 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 1292 *(
unsigned *)arg = 8;
1296 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 1299 *(
unsigned *)arg = 6;
1305 *(
unsigned *)arg = 5;
1311 *(
unsigned *)arg = 4;
1316 *(
unsigned *)arg = 3;
1321 *(
unsigned *)arg = 2;
1325 *(
unsigned *)arg = 1;
1366 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >=6 1373 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >=8 1475 const char *buf = (
const char *)arg;
1476 unsigned buflen = strlen(buf);
1500 board_spi_reset(ms);
1510 board_peripheral_reset(ms);
1518 #if defined(BOARD_HAS_CAPTURE) 1606 *(
unsigned *)arg = 1;
1611 *(
unsigned *)arg = 2;
1683 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM == 4 1687 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM == 5 1690 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM == 6 1693 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM == 8 1696 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM == 14 1706 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 1713 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 1726 # if defined(BOARD_HAS_CAPTURE) 1741 # if defined(BOARD_HAS_CAPTURE) 1760 # if defined(BOARD_HAS_CAPTURE) 1773 # if defined(BOARD_HAS_CAPTURE) 1787 PX4FMU *
object = get_instance();
1789 if (servo_mode != object->
get_mode()) {
1791 object->set_mode(servo_mode);
1801 int fmu_new_i2c_speed(
unsigned bus,
unsigned clock_hz)
1812 unsigned servo_count = 0;
1813 unsigned capture_count = 0;
1814 unsigned pwm_value = 1000;
1818 uint32_t rate_limit = 0;
1819 struct input_capture_t {
1827 PX4_ERR(
"open fail");
1832 PX4_ERR(
"Failed to Enter pwm test mode");
1833 goto err_out_no_test;
1837 PX4_ERR(
"servo arm failed");
1842 PX4_ERR(
"Unable to get servo count");
1847 PX4_INFO(
"Not in a capture mode");
1850 PX4_INFO(
"Testing %u servos and %u input captures", (
unsigned)servo_count, capture_count);
1851 memset(capture_conf, 0,
sizeof(capture_conf));
1853 if (capture_count != 0) {
1854 for (
unsigned i = 0; i < capture_count; i++) {
1856 capture_conf[i].chan.channel = i + servo_count;
1860 PX4_ERR(
"Unable to get capture callback for chan %u\n", capture_conf[i].chan.channel);
1866 conf.
context = PX4FMU::get_instance();
1869 capture_conf[i].valid =
true;
1872 PX4_ERR(
"Unable to set capture callback for chan %u\n", capture_conf[i].chan.channel);
1884 fds.events = POLLIN;
1886 PX4_INFO(
"Press CTRL-C or 'c' to abort.");
1892 for (
unsigned i = 0; i < servo_count; i++) {
1893 servos[i] = pwm_value;
1896 for (
unsigned i = 0; i < servo_count; i++) {
1898 PX4_ERR(
"servo %u set failed", i);
1903 if (direction > 0) {
1904 if (pwm_value < 2000) {
1912 if (pwm_value > 1000) {
1921 for (
unsigned i = 0; i < servo_count; i++) {
1925 PX4_ERR(
"error reading PWM servo %d", i);
1929 if (value != servos[i]) {
1930 PX4_ERR(
"servo %d readback error, got %u expected %u", i, value, servos[i]);
1935 if (capture_count != 0 && (++rate_limit % 500 == 0)) {
1936 for (
unsigned i = 0; i < capture_count; i++) {
1937 if (capture_conf[i].valid) {
1942 PX4_ERR(
"Unable to get stats for chan %u\n", capture_conf[i].chan.channel);
1946 fprintf(stdout,
"FMU: Status chan:%u edges: %d last time:%lld last state:%d overflows:%d lantency:%u\n",
1947 capture_conf[i].chan.channel,
1948 stats.chan_in_edges_out,
1961 ret =
::poll(&fds, 1, 0);
1967 if (c == 0x03 || c == 0x63 || c ==
'q') {
1968 PX4_INFO(
"User abort");
1974 if (capture_count != 0) {
1975 for (
unsigned i = 0; i < capture_count; i++) {
1977 if (capture_conf[i].valid) {
1980 PX4_ERR(
"Unable to set capture callback for chan %u\n", capture_conf[i].chan.channel);
1992 PX4_ERR(
"Failed to Exit pwm test mode");
2010 ac.
control[0] = strtol(argv[1], 0, 0) / 100.0f;
2012 ac.
control[1] = strtol(argv[2], 0, 0) / 100.0f;
2014 ac.
control[2] = strtol(argv[3], 0, 0) / 100.0f;
2016 ac.
control[3] = strtol(argv[4], 0, 0) / 100.0f;
2020 if (handle ==
nullptr) {
2021 PX4_ERR(
"advertise failed");
2034 if (handle ==
nullptr) {
2035 PX4_ERR(
"advertise failed 2");
2046 const char *verb = argv[0];
2049 if (!strcmp(verb,
"i2c")) {
2051 int bus = strtol(argv[1], 0, 0);
2052 int clock_hz = strtol(argv[2], 0, 0);
2053 int ret = fmu_new_i2c_speed(bus, clock_hz);
2056 PX4_ERR(
"setting I2C clock failed");
2065 if (!strcmp(verb,
"sensor_reset")) {
2067 int reset_time = strtol(argv[1],
nullptr, 0);
2072 PX4_INFO(
"reset default time");
2078 if (!strcmp(verb,
"peripheral_reset")) {
2080 int reset_time = strtol(argv[2], 0, 0);
2085 PX4_INFO(
"reset default time");
2104 if (!strcmp(verb,
"mode_gpio")) {
2107 }
else if (!strcmp(verb,
"mode_pwm")) {
2111 #if defined(BOARD_HAS_PWM) 2113 }
else if (!strcmp(verb,
"mode_pwm1")) {
2117 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 2119 }
else if (!strcmp(verb,
"mode_pwm6")) {
2123 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 5 2125 }
else if (!strcmp(verb,
"mode_pwm5")) {
2128 # if defined(BOARD_HAS_CAPTURE) 2130 }
else if (!strcmp(verb,
"mode_pwm5cap1")) {
2134 }
else if (!strcmp(verb,
"mode_pwm4")) {
2137 # if defined(BOARD_HAS_CAPTURE) 2139 }
else if (!strcmp(verb,
"mode_pwm4cap1")) {
2142 }
else if (!strcmp(verb,
"mode_pwm4cap2")) {
2146 }
else if (!strcmp(verb,
"mode_pwm3")) {
2149 # if defined(BOARD_HAS_CAPTURE) 2151 }
else if (!strcmp(verb,
"mode_pwm3cap1")) {
2155 }
else if (!strcmp(verb,
"mode_pwm2")) {
2158 # if defined(BOARD_HAS_CAPTURE) 2160 }
else if (!strcmp(verb,
"mode_pwm2cap2")) {
2164 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 2166 }
else if (!strcmp(verb,
"mode_pwm8")) {
2178 if (!strcmp(verb,
"test")) {
2182 if (!strcmp(verb,
"fake")) {
2183 return fake(argc - 1, argv + 1);
2193 const char *mode_str =
nullptr;
2196 case MODE_NONE: mode_str =
"no pwm";
break;
2198 case MODE_1PWM: mode_str =
"pwm1";
break;
2200 case MODE_2PWM: mode_str =
"pwm2";
break;
2204 case MODE_3PWM: mode_str =
"pwm3";
break;
2208 case MODE_4PWM: mode_str =
"pwm4";
break;
2214 case MODE_5PWM: mode_str =
"pwm5";
break;
2218 case MODE_6PWM: mode_str =
"pwm6";
break;
2220 case MODE_8PWM: mode_str =
"pwm8";
break;
2222 case MODE_4CAP: mode_str =
"cap4";
break;
2224 case MODE_5CAP: mode_str =
"cap5";
break;
2226 case MODE_6CAP: mode_str =
"cap6";
break;
2233 PX4_INFO(
"PWM Mode: %s", mode_str);
2245 PX4_WARN(
"%s\n", reason);
2248 PRINT_MODULE_DESCRIPTION(
2251 This module is responsible for driving the output and reading the input pins. For boards without a separate IO chip 2252 (eg. Pixracer), it uses the main channels. On boards with an IO chip (eg. Pixhawk), it uses the AUX channels, and the 2253 px4io driver is used for main ones. 2255 It listens on the actuator_controls topics, does the mixing and writes the PWM outputs. 2257 The module is configured via mode_* commands. This defines which of the first N pins the driver should occupy. 2258 By using mode_pwm4 for example, pins 5 and 6 can be used by the camera trigger driver or by a PWM rangefinder 2259 driver. Alternatively, the fmu can be started in one of the capture modes, and then drivers can register a capture 2260 callback with ioctl calls. 2263 By default the module runs on a work queue with a callback on the uORB actuator_controls topic. 2266 It is typically started with: 2268 To drive all available pins. 2270 Capture input (rising and falling edges) and print on the console: start the fmu in one of the capture modes: 2272 This will enable capturing on the 4th pin. Then do: 2275 Use the `pwm` command for further configurations (PWM rate, levels, ...), and the `mixer` command to load 2279 PRINT_MODULE_USAGE_NAME("fmu",
"driver");
2280 PRINT_MODULE_USAGE_COMMAND_DESCR(
"start",
"Start the task (without any mode set, use any of the mode_* cmds)");
2282 PRINT_MODULE_USAGE_PARAM_COMMENT(
"All of the mode_* commands will start the fmu if not running already");
2284 PRINT_MODULE_USAGE_COMMAND(
"mode_gpio");
2285 PRINT_MODULE_USAGE_COMMAND_DESCR(
"mode_pwm",
"Select all available pins as PWM");
2286 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 8 2287 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm8");
2289 #if defined(BOARD_HAS_PWM) && BOARD_HAS_PWM >= 6 2290 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm6");
2291 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm5");
2292 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm5cap1");
2293 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm4");
2294 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm4cap1");
2295 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm4cap2");
2296 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm3");
2297 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm3cap1");
2298 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm2");
2299 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm2cap2");
2301 #if defined(BOARD_HAS_PWM) 2302 PRINT_MODULE_USAGE_COMMAND(
"mode_pwm1");
2305 PRINT_MODULE_USAGE_COMMAND_DESCR(
"sensor_reset",
"Do a sensor reset (SPI bus)");
2306 PRINT_MODULE_USAGE_ARG(
"<ms>",
"Delay time in ms between reset and re-enabling",
true);
2307 PRINT_MODULE_USAGE_COMMAND_DESCR(
"peripheral_reset",
"Reset board peripherals");
2308 PRINT_MODULE_USAGE_ARG(
"<ms>",
"Delay time in ms between reset and re-enabling",
true);
2310 PRINT_MODULE_USAGE_COMMAND_DESCR(
"i2c",
"Configure I2C clock rate");
2311 PRINT_MODULE_USAGE_ARG(
"<bus_id> <rate>",
"Specify the bus id (>=0) and rate in Hz",
false);
2313 PRINT_MODULE_USAGE_COMMAND_DESCR(
"test",
"Test inputs and outputs");
2314 PRINT_MODULE_USAGE_COMMAND_DESCR(
"fake",
"Arm and send an actuator controls command");
2315 PRINT_MODULE_USAGE_ARG(
"<roll> <pitch> <yaw> <thrust>",
"Control values in range [-100, 100]",
false);
2316 PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
#define PWM_DEFAULT_MAX
Default maximum PWM in us.
#define PARAM_INVALID
Handle returned when a parameter cannot be found.
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
#define PWM_SERVO_MODE_2PWM2CAP
#define PWM_SERVO_GET_SELECT_UPDATE_RATE
check the selected update rates
#define PWM_LOWEST_MAX
Lowest PWM allowed as the maximum PWM.
#define MIXERIOCLOADBUF
Add mixer(s) from the buffer in (const char *)arg.
__EXPORT servo_position_t up_pwm_servo_get(unsigned channel)
Get the current output value for a channel.
#define PWM_SERVO_SET_ARM_OK
set the 'ARM ok' bit, which activates the safety switch
const actuator_armed_s & armed() const
virtual int open(file_t *filep)
Handle an open of the device.
#define PWM_SERVO_MODE_2PWM
uint16_t servo_position_t
Servo output signal type, value is actual servo output pulse width in microseconds.
static int task_spawn(int argc, char *argv[])
measure the time elapsed performing an event
__EXPORT uint32_t up_pwm_servo_get_rate_group(unsigned group)
Get a bitmap of output channels assigned to a given rate group.
#define PWM_SERVO_SET_FORCE_SAFETY_ON
force safety switch on (to enable use of safety switch)
#define PWM_SERVO_MODE_4PWM
static int set_i2c_bus_clock(unsigned bus, unsigned clock_hz)
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
#define PWM_SERVO_GET_COUNT
get the number of servos in *(unsigned *)arg
#define PWM_SERVO_ARM
arm all servo outputs handle by this driver
#define PWM_SERVO_MODE_8PWM
#define PWM_SERVO_MODE_5PWM1CAP
virtual int register_class_devname(const char *class_devname)
Register a class device name, automatically adding device class instance suffix if need be...
uint16_t & reverseOutputMask()
int main(int argc, char **argv)
void lock()
Take the driver lock.
static void sensor_reset(int ms)
__EXPORT void up_pwm_servo_deinit(void)
De-initialise the PWM servo outputs.
void setMaxTopicUpdateRate(unsigned max_topic_update_interval_us)
orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data)
#define PWM_SERVO_GET_UPDATE_RATE
get alternate servo update rate
#define PWM_SERVO_GET_DISARMED_PWM
get the PWM value when disarmed
static void capture_trampoline(void *context, uint32_t chan_index, hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow)
#define PWM_SERVO_MODE_NONE
set auxillary output mode.
bool update()
Call this regularly from Run().
#define PWM_SERVO_CLEAR_ARM_OK
clear the 'ARM ok' bit, which deactivates the safety switch
static void print_usage()
uORB::Subscription _parameter_update_sub
#define PWM_SERVO_MODE_4PWM1CAP
bool updateSubscriptions(bool allow_wq_switch)
Check for subscription updates (e.g.
#define PWM_SERVO_SET_SELECT_UPDATE_RATE
selects servo update rates, one bit per servo.
virtual ssize_t read(file_t *filep, char *buffer, size_t buflen)
Perform a read from the device.
High-resolution timer with callouts and timekeeping.
unsigned set_trims(int16_t *v, unsigned n)
virtual int close(file_t *filep)
Handle a close of the device.
static constexpr int MAX_ACTUATORS
Global flash based parameter store.
__EXPORT int fmu_main(int argc, char *argv[])
#define PWM_SERVO_SET(_servo)
set a single servo to a specific value
perf_counter_t _cycle_perf
bool in_esc_calibration_mode
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
void update_current_rate()
#define PWM_SERVO_MODE_6PWM
#define PWM_SERVO_MODE_3PWM
#define PWM_SERVO_GET_DEFAULT_UPDATE_RATE
get default servo update rate
#define PWM_SERVO_SET_FAILSAFE_PWM
set the PWM value for failsafe
Abstract class for any character device.
uint16_t values[PWM_OUTPUT_MAX_CHANNELS]
Drive scheduling based on subscribed actuator controls topics (via uORB callbacks) ...
uint16_t & maxValue(int index)
void perf_free(perf_counter_t handle)
Free a counter.
void init()
Activates/configures the hardware registers.
#define PWM_SERVO_SET_DISARMED_PWM
set the PWM value when disarmed - should be no PWM (zero) by default
virtual int unregister_class_devname(const char *class_devname, unsigned class_instance)
Register a class device name, automatically adding device class instance suffix if need be...
#define PWM_SERVO_MODE_5PWM
unsigned _num_disarmed_set
#define ORB_ID_VEHICLE_ATTITUDE_CONTROLS
#define PWM_SERVO_MODE_5CAP
void capture_callback(uint32_t chan_index, hrt_abstime edge_time, uint32_t edge_state, uint32_t overflow)
__EXPORT int up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate)
Set the update rate for a given rate group.
#define PWM_SERVO_SET_TRIM_PWM
set the TRIM value the output will send
#define PWM_SERVO_ENTER_TEST_MODE
#define PWM_SERVO_MODE_4CAP
void resetMixerThreadSafe()
Reset (unload) the complete mixer, called from another thread.
#define PWM_SERVO_GET_TRIM_PWM
get the TRIM value the output will send
__EXPORT int up_pwm_servo_set(unsigned channel, servo_position_t value)
Set the current output value for a channel.
#define PWM_SERVO_SET_FORCE_SAFETY_OFF
force safety switch off (to disable use of safety switch)
PortMode
Mode given via CLI.
int pwm_ioctl(file *filp, int cmd, unsigned long arg)
void perf_end(perf_counter_t handle)
End a performance event.
bool updateOutputs(bool stop_motors, uint16_t outputs[MAX_ACTUATORS], unsigned num_outputs, unsigned num_control_groups_updated) override
Callback to update the (physical) actuator outputs in the driver.
#define PWM_SERVO_MODE_6CAP
void test(enum LPS25H_BUS busid)
Perform some basic functional tests on the driver; make sure we can collect data from the sensor in p...
bool updated()
Check if there is a new update.
Base class for an output module.
#define PWM_SERVO_GET_RATEGROUP(_n)
get the _n'th rate group's channels; *(uint32_t *)arg returns a bitmap of channels whose update rates...
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
int loadMixerThreadSafe(const char *buf, unsigned len)
Load (append) a new mixer from a buffer, called from another thread.
#define PWM_SERVO_GET(_servo)
get a single specific servo value
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
#define PWM_SERVO_SET_MIN_PWM
set the minimum PWM value the output will send
#define PWM_SERVO_MODE_4PWM2CAP
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
#define MIXERIOCRESET
reset (clear) the mixer configuration
static void update_params(ParameterHandles ¶m_handles, Parameters ¶ms, bool &got_changes)
unsigned _current_update_rate
void setAllMaxValues(uint16_t value)
#define PWM_SERVO_SET_MAX_PWM
set the maximum PWM value the output will send
#define PWM_SERVO_SET_MODE
static int fake(int argc, char *argv[])
uint16_t & disarmedValue(int index)
Disarmed values: disarmedValue < minValue needs to hold.
#define PWM_SERVO_GET_MIN_PWM
get the minimum PWM value the output will send
#define PWM_OUTPUT_BASE_DEVICE_PATH
Path for the default PWM output device.
struct @83::@85::@87 file
static int print_usage(const char *reason=nullptr)
#define PWM_HIGHEST_MIN
Highest PWM allowed as the minimum PWM.
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
void update_pwm_out_state(bool on)
void setDriverInstance(uint8_t instance)
__EXPORT int up_pwm_servo_init(uint32_t channel_mask)
Intialise the PWM servo outputs using the specified configuration.
static int custom_command(int argc, char *argv[])
int orb_unadvertise(orb_advert_t handle)
MixingOutput _mixing_output
__EXPORT void up_pwm_servo_arm(bool armed)
Arm or disarm servo outputs.
uint16_t & minValue(int index)
int capture_ioctl(file *filp, int cmd, unsigned long arg)
static void peripheral_reset(int ms)
#define PWM_HIGHEST_MAX
Highest maximum PWM in us.
MixerGroup * mixers() const
int set_pwm_rate(unsigned rate_map, unsigned default_rate, unsigned alt_rate)
void update_pwm_rev_mask()
uint32_t _pwm_alt_rate_channels
void unregister()
unregister uORB subscription callbacks
#define PX4FMU_DEVICE_PATH
#define PWM_SERVO_MODE_1PWM
static constexpr int FMU_MAX_ACTUATORS
static int fmu_new_mode(PortMode new_mode)
change the FMU mode of the running module
void unlock()
Release the driver lock.
#define PWM_SERVO_GET_FAILSAFE_PWM
get the PWM value for failsafe
#define PWM_DEFAULT_MIN
Default minimum PWM in us.
bool copy(void *dst)
Copy the struct.
__EXPORT void up_pwm_update(void)
Trigger all timer's channels in Oneshot mode to fire the oneshot with updated values.
virtual int ioctl(file *filp, int cmd, unsigned long arg)
int print_status() override
#define PWM_SERVO_MODE_3PWM1CAP
void perf_begin(perf_counter_t handle)
Begin a performance event.
This handles the mixing, arming/disarming and all subscriptions required for that.
unsigned get_trims(int16_t *values)
#define PWM_SERVO_SET_COUNT
set the number of servos in (unsigned)arg - allows change of split between servos and GPIO ...
uint32_t param_t
Parameter handle.
#define PWM_LOWEST_MIN
Lowest minimum PWM in us.
virtual int poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
Perform a poll setup/teardown operation.
#define PWM_SERVO_DISARM
disarm all servo outputs (stop generating pulses)
Performance measuring tools.
unsigned _pwm_default_rate
uint16_t & failsafeValue(int index)
#define PWM_SERVO_GET_MAX_PWM
get the maximum PWM value the output will send
#define PWM_SERVO_SET_UPDATE_RATE
set alternate servo update rate
Base class for devices connected via I2C.
void setAllMinValues(uint16_t value)
#define PWM_SERVO_EXIT_TEST_MODE