mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-03 14:08:52 +08:00
io_timer: reserve pins & timers on first use
This allows modules to do a first-come-first-serve pin/timer reservation on bootup. E.g. camera trigger reserves any of the pins, and then PWM/DShot output will just use the rest of the available pins.
This commit is contained in:
@@ -51,15 +51,35 @@ CameraInterfaceGPIO::CameraInterfaceGPIO()
|
||||
setup();
|
||||
}
|
||||
|
||||
CameraInterfaceGPIO::~CameraInterfaceGPIO()
|
||||
{
|
||||
unsigned channel = 0;
|
||||
|
||||
while (_allocated_channels != 0) {
|
||||
if (((1 << channel) & _allocated_channels)) {
|
||||
io_timer_unallocate_channel(channel);
|
||||
_allocated_channels &= ~(1u << channel);
|
||||
}
|
||||
|
||||
++channel;
|
||||
}
|
||||
}
|
||||
|
||||
void CameraInterfaceGPIO::setup()
|
||||
{
|
||||
_allocated_channels = 0;
|
||||
|
||||
for (unsigned i = 0, t = 0; i < arraySize(_pins); i++) {
|
||||
// Pin range is from 0 to num_gpios - 1
|
||||
if (_pins[i] >= 0 && t < (int)arraySize(_triggers)) {
|
||||
uint32_t gpio = io_timer_channel_get_gpio_output(_pins[i]);
|
||||
_triggers[t++] = gpio;
|
||||
px4_arch_configgpio(gpio);
|
||||
px4_arch_gpiowrite(gpio, false ^ _trigger_invert);
|
||||
|
||||
if (io_timer_allocate_channel(_pins[i], IOTimerChanMode_Trigger) == 0) {
|
||||
_allocated_channels |= 1 << _pins[i];
|
||||
_triggers[t++] = gpio;
|
||||
px4_arch_configgpio(gpio);
|
||||
px4_arch_gpiowrite(gpio, false ^ _trigger_invert);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class CameraInterfaceGPIO : public CameraInterface
|
||||
{
|
||||
public:
|
||||
CameraInterfaceGPIO();
|
||||
virtual ~CameraInterfaceGPIO() = default;
|
||||
virtual ~CameraInterfaceGPIO();
|
||||
|
||||
void trigger(bool trigger_on_true);
|
||||
|
||||
@@ -65,6 +65,7 @@ private:
|
||||
bool _trigger_invert{false};
|
||||
|
||||
uint32_t _triggers[num_gpios] {};
|
||||
uint32_t _allocated_channels{0};
|
||||
};
|
||||
|
||||
#endif /* ifdef __PX4_NUTTX */
|
||||
|
||||
@@ -68,7 +68,22 @@ void CameraInterfacePWM::setup()
|
||||
}
|
||||
|
||||
// Initialize and arm channels
|
||||
up_pwm_trigger_init(pin_bitmask);
|
||||
int ret = up_pwm_trigger_init(pin_bitmask);
|
||||
|
||||
if (ret < 0) {
|
||||
PX4_ERR("up_pwm_trigger_init failed (%i)", ret);
|
||||
pin_bitmask = 0;
|
||||
|
||||
} else {
|
||||
pin_bitmask = ret;
|
||||
}
|
||||
|
||||
// Clear pins that could not be initialized
|
||||
for (unsigned i = 0; i < arraySize(_pins); i++) {
|
||||
if (_pins[i] >= 0 && ((1 << _pins[i]) & pin_bitmask) == 0) {
|
||||
_pins[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Set neutral pulsewidths
|
||||
for (unsigned i = 0; i < arraySize(_pins); i++) {
|
||||
|
||||
@@ -69,7 +69,12 @@ void CameraInterfaceSeagull::setup()
|
||||
|
||||
// Initialize the interface
|
||||
uint32_t pin_bitmask = (1 << _pins[i + 1]) | (1 << _pins[i]);
|
||||
up_pwm_trigger_init(pin_bitmask);
|
||||
int ret = up_pwm_trigger_init(pin_bitmask);
|
||||
|
||||
if (ret != (int)pin_bitmask) {
|
||||
PX4_WARN("up_pwm_trigger_init failed (%i)", ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set both interface pins to disarmed
|
||||
int ret1 = up_pwm_trigger_set(_pins[i + 1], PWM_CAMERA_DISARMED);
|
||||
|
||||
Reference in New Issue
Block a user