nusrobomaster / PX4-Autopilot

PX4 Autopilot Software
https://px4.io
BSD 3-Clause "New" or "Revised" License
2 stars 0 forks source link

PWM Actuator Out Support #11

Open chengguizi opened 3 years ago

chengguizi commented 3 years ago

Refer to https://github.com/nusrobomaster/PX4-Autopilot/blob/rm2021/src/systemcmds/pwm/pwm.cpp for a start

chengguizi commented 3 years ago
// Configure the GPIO pins to outputs and keep them low.
    for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) {
        px4_arch_configgpio(io_timer_channel_get_gpio_output(i));
    }

This thing looks interesting, in configuring the PWM and GPIO dual pins, this is for the aux pin.

chengguizi commented 3 years ago

The up_pwm_servo_set function in pwm_servo.c file and io_timer_set_ccr in io_timer.c is interesting.

Compare &. Capture. Register (CCR)

chengguizi commented 3 years ago

The following code in the PWMOut is interesting, and it is called by the mixer_module.

bool PWMOut::updateOutputs(bool stop_motors, uint16_t outputs[MAX_ACTUATORS],
               unsigned num_outputs, unsigned num_control_groups_updated)
{
    if (_test_mode) {
        return false;
    }

    /* output to the servos */
    if (_pwm_initialized) {
        for (size_t i = 0; i < math::min(_num_outputs, num_outputs); i++) {
            up_pwm_servo_set(i, outputs[i]);
        }
    }

    /* Trigger all timer's channels in Oneshot mode to fire
     * the oneshots with updated values.
     */
    if (num_control_groups_updated > 0) {
        up_pwm_update();
    }

    return true;
}
chengguizi commented 3 years ago

Camera capture hardcoded the mode to be 4 + 2

    if (enabled) {

        conf.callback = &CameraCapture::capture_trampoline;
        conf.context = this;

        unsigned int capture_count = 0;

        if (::ioctl(fd, INPUT_CAP_GET_COUNT, (unsigned long)&capture_count) != 0) {
            PX4_INFO("Not in a capture mode");

            unsigned long mode = PWM_SERVO_MODE_4PWM2CAP;

            if (::ioctl(fd, PWM_SERVO_SET_MODE, mode) == 0) {
                PX4_INFO("Mode changed to 4PWM2CAP");

            } else {
                PX4_ERR("Mode NOT changed to 4PWM2CAP!");
                goto err_out;
            }
        }
    }
chengguizi commented 3 years ago

src/drivers/drv_pwm_output.h

/** set auxillary output mode. These correspond to enum Mode in px4fmu/fmu.cpp */
#define PWM_SERVO_MODE_NONE         0
#define PWM_SERVO_MODE_1PWM         1
#define PWM_SERVO_MODE_2PWM         2
#define PWM_SERVO_MODE_2PWM2CAP     3
#define PWM_SERVO_MODE_3PWM         4
#define PWM_SERVO_MODE_3PWM1CAP     5
#define PWM_SERVO_MODE_4PWM         6
#define PWM_SERVO_MODE_4PWM1CAP     7
#define PWM_SERVO_MODE_4PWM2CAP     8
#define PWM_SERVO_MODE_5PWM         9
#define PWM_SERVO_MODE_5PWM1CAP    10
#define PWM_SERVO_MODE_6PWM        11
#define PWM_SERVO_MODE_8PWM        12
#define PWM_SERVO_MODE_14PWM       13
#define PWM_SERVO_MODE_4CAP        14
#define PWM_SERVO_MODE_5CAP        15
#define PWM_SERVO_MODE_6CAP        16
#define PWM_SERVO_ENTER_TEST_MODE  17
#define PWM_SERVO_EXIT_TEST_MODE   18
#define PWM_SERVO_SET_MODE         _PX4_IOC(_PWM_SERVO_BASE, 34)
chengguizi commented 3 years ago
//  NotUsed   PWMOut  PWMIn Capture OneShot Trigger Dshot
io_timer_channel_allocation_t channel_allocations[IOTimerChanModeSize] = { UINT16_MAX,   0,  0,  0, 0, 0, 0 };
int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
              channel_handler_t channel_handler, void *context)

io_timer_channel_init <- up_pwm_servo_init <- update_pwm_out_state

/**
 * Intialise the PWM servo outputs using the specified configuration.
 *
 * @param channel_mask  Bitmask of channels (LSB = channel 0) to enable.
 *          This allows some of the channels to remain configured
 *          as GPIOs or as another function.
 * @return      OK on success.
 */
__EXPORT extern int up_pwm_servo_init(uint32_t channel_mask);
chengguizi commented 3 years ago

up_pwm_trigger_init

cctt1014 commented 3 years ago

image

figure out the rough structure of calling functions to allocate channels, don't understand how timer_io_channels[MAX_TIMER_IO_CHANNELS] in timer_config.cpp works.

chengguizi commented 3 years ago

image

figure out the rough structure of calling functions to allocate channels, don't understand how timer_io_channels[MAX_TIMER_IO_CHANNELS] in timer_config.cpp works.

I believe the timer_io_channels is defined to number the channels in sequence. That is to say, the sequence defined by the timer_config.cpp, would be the channel number recognised by PX4 system.

Are we able to perform a pull request soon?

cctt1014 commented 3 years ago

image figure out the rough structure of calling functions to allocate channels, don't understand how timer_io_channels[MAX_TIMER_IO_CHANNELS] in timer_config.cpp works.

I believe the timer_io_channels is defined to number the channels in sequence. That is to say, the sequence defined by the timer_config.cpp, would be the channel number recognised by PX4 system.

Are we able to perform a pull request soon?

Yes, I created a pull request just now. It is ready to merge. Should I do it?