Пример #1
0
int softpwm_start(const char *key, float duty, float freq, int polarity)
{
    struct softpwm *new_pwm, *pwm;
    pthread_t new_thread;
    pthread_mutex_t *new_params_lock;
    int gpio;
    int ret;

    if (get_gpio_number(key, &gpio) < 0)
        return -1;
    if (gpio_export(gpio) < 0)
        return -1;
    if (gpio_set_direction(gpio, OUTPUT) < 0)
        return -1;

    // add to list
    new_pwm = malloc(sizeof(struct softpwm));  ASSRT(new_pwm != NULL);
    new_params_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
    if (new_pwm == 0) {
        return -1; // out of memory
    }
    pthread_mutex_init(new_params_lock, NULL);
    pthread_mutex_lock(new_params_lock);

    strncpy(new_pwm->key, key, KEYLEN);  /* can leave string unterminated */
    new_pwm->key[KEYLEN] = '\0'; /* terminate string */
    new_pwm->gpio = gpio;
    new_pwm->params.enabled = true;
    new_pwm->params.stop_flag = false;
    new_pwm->params_lock = new_params_lock;
    new_pwm->next = NULL;

    if (exported_pwms == NULL)
    {
        // create new list
        exported_pwms = new_pwm;
    } else {
        // add to end of existing list
        pwm = exported_pwms;
        while (pwm->next != NULL)
            pwm = pwm->next;
        pwm->next = new_pwm;
    }
    pthread_mutex_unlock(new_params_lock);

    ASSRT(softpwm_set_duty_cycle(new_pwm->key, duty) == 0);
    ASSRT(softpwm_set_frequency(new_pwm->key, freq) == 0);
    ASSRT(softpwm_set_polarity(new_pwm->key, polarity) == 0);

    pthread_mutex_lock(new_params_lock);
    // create thread for pwm
    ret = pthread_create(&new_thread, NULL, softpwm_thread_toggle, (void *)new_pwm);
    ASSRT(ret == 0);

    new_pwm->thread = new_thread;

    pthread_mutex_unlock(new_params_lock);

    return 1;
}
Пример #2
0
// python method PWM.set_duty_cycle(channel, duty_cycle)
static PyObject *py_set_duty_cycle(PyObject *self, PyObject *args, PyObject *kwargs)
{
    char key[8];
    char *channel;
    int gpio;
    int allowed = -1;
    float duty_cycle = 0.0;
    static char *kwlist[] = {"channel", "duty_cycle", NULL};

    clear_error_msg();

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|f", kwlist, &channel, &duty_cycle))
        return NULL;

    if (duty_cycle < 0.0 || duty_cycle > 100.0) {
        PyErr_SetString(PyExc_ValueError, "duty_cycle must have a value from 0.0 to 100.0");
        return NULL;
    }

    if (!get_key(channel, key)) {
        PyErr_SetString(PyExc_ValueError, "Invalid PWM key or name.");
        return NULL;
    }

    // check to ensure gpio is one of the allowed pins
    // Not protecting the call as if the get_key() fails, we won't make it here
    get_gpio_number(channel, &gpio);

    // Check to see if GPIO is allowed on the hardware
    // A 1 means we're good to go
    allowed = gpio_allowed(gpio);
    if (allowed == -1) {
        char err[2000];
        snprintf(err, sizeof(err), "Error determining hardware. (%s)", get_error_msg());
        PyErr_SetString(PyExc_ValueError, err);
        return NULL;
    } else if (allowed == 0) {
        char err[2000];
        snprintf(err, sizeof(err), "GPIO %d not available on current Hardware", gpio);
        PyErr_SetString(PyExc_ValueError, err);
        return NULL;
    }

    if (softpwm_set_duty_cycle(key, duty_cycle) == -1) {
        PyErr_SetString(PyExc_RuntimeError, "You must start() the PWM channel first");
        return NULL;
    }

    Py_RETURN_NONE;
}