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; }
// python function start(channel, duty_cycle, freq, polarity) static PyObject *py_start_channel(PyObject *self, PyObject *args, PyObject *kwargs) { char key[8]; char *channel = NULL; float frequency = 2000.0; float duty_cycle = 0.0; int polarity = 0; int gpio; int allowed = -1; static char *kwlist[] = {"channel", "duty_cycle", "frequency", "polarity", NULL}; clear_error_msg(); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ffi", kwlist, &channel, &duty_cycle, &frequency, &polarity)) { return NULL; } ASSRT(channel != NULL); if (!module_setup) { init_module(); } if (!get_key(channel, key)) { PyErr_SetString(PyExc_ValueError, "Invalid SOFTPWM 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 (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 (frequency <= 0.0) { PyErr_SetString(PyExc_ValueError, "frequency must be greater than 0.0"); return NULL; } if (polarity < 0 || polarity > 1) { PyErr_SetString(PyExc_ValueError, "polarity must be either 0 or 1"); return NULL; } if (softpwm_start(key, duty_cycle, frequency, polarity) < 0) { printf("softpwm_start failed"); char err[2000]; snprintf(err, sizeof(err), "Error starting softpwm on pin %s (%s)", key, get_error_msg()); PyErr_SetString(PyExc_RuntimeError, err); return NULL; } Py_RETURN_NONE; }