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 value = input(channel) static PyObject *py_input_gpio(PyObject *self, PyObject *args) { unsigned int gpio; int channel; PyObject *value; if (!PyArg_ParseTuple(args, "i", &channel)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; // check channel is set up as an input or output if (gpio_direction[gpio] != INPUT && gpio_direction[gpio] != OUTPUT) { PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel first"); return NULL; } if (check_gpio_priv()) return NULL; if (input_gpio(gpio)) { value = Py_BuildValue("i", HIGH); } else { value = Py_BuildValue("i", LOW); } return value; }
void bsp_gpio_direction_output(u32 gpio, u32 value) { unsigned int gpio_base_addr = 0; unsigned int gpio_number = 0; unsigned int reg_value_old = 0; unsigned int reg_value_new = 0; if(value > 1 || gpio > GPIO_TOTAL) { gpio_print_error("para is error, gpio = %d, value = %d.\n", gpio, value); return ; } gpio_base_addr = get_gpio_base_addr(gpio); gpio_number = get_gpio_number(gpio); reg_value_old = readl(gpio_base_addr + GPIODIR); reg_value_new = (((unsigned int)0x1 << gpio_number)) | (reg_value_old); writel(reg_value_new, gpio_base_addr + GPIODIR); bsp_gpio_set_value( gpio, value); }
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None) static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; int channel, direction; int pud = PUD_OFF + PY_PUD_CONST_OFFSET; int initial = -1; static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL}; int func; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", kwlist, &channel, &direction, &pud, &initial)) return NULL; // check module has been imported cleanly if (setup_error) { PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!"); return NULL; } // run init_module if module not set up if (!module_setup && (init_module() != SETUP_OK)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (direction != INPUT && direction != OUTPUT) { PyErr_SetString(PyExc_ValueError, "An invalid direction was passed to setup()"); return NULL; } if (direction == OUTPUT) pud = PUD_OFF + PY_PUD_CONST_OFFSET; pud -= PY_PUD_CONST_OFFSET; if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) { PyErr_SetString(PyExc_ValueError, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN"); return NULL; } func = gpio_function(gpio); if (gpio_warnings && // warnings enabled and ((func != 0 && func != 1) || // (already one of the alt functions or (gpio_direction[gpio] == -1 && func == 1))) // already an output not set from this program) { PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.", 1); } if (direction == OUTPUT && (initial == LOW || initial == HIGH)) { output_gpio(gpio, initial); } setup_gpio(gpio, direction, pud); gpio_direction[gpio] = direction; Py_RETURN_NONE; }
// python function add_event_detect(gpio, edge, callback=None, bouncetime=0 static PyObject *py_add_event_detect(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; int channel, edge, result; unsigned int bouncetime = 0; PyObject *cb_func = NULL; char *kwlist[] = {"gpio", "edge", "callback", "bouncetime", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|Oi", kwlist, &channel, &edge, &cb_func, &bouncetime)) return NULL; if (cb_func != NULL && !PyCallable_Check(cb_func)) { PyErr_SetString(PyExc_TypeError, "Parameter must be callable"); return NULL; } if (get_gpio_number(channel, &gpio)) return NULL; // check channel is set up as an input if (gpio_direction[gpio] != INPUT) { PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel as an input first"); return NULL; } // is edge valid value edge -= PY_EVENT_CONST_OFFSET; if (edge != RISING_EDGE && edge != FALLING_EDGE && edge != BOTH_EDGE) { PyErr_SetString(PyExc_ValueError, "The edge must be set to RISING, FALLING or BOTH"); return NULL; } if (check_gpio_priv()) return NULL; if ((result = add_edge_detect(gpio, edge, bouncetime)) != 0) // starts a thread { if (result == 1) { PyErr_SetString(PyExc_RuntimeError, "Edge detection already enabled for this GPIO channel"); return NULL; } else { PyErr_SetString(PyExc_RuntimeError, "Failed to add edge detection"); return NULL; } } if (cb_func != NULL) if (add_py_callback(gpio, cb_func) != 0) return NULL; Py_RETURN_NONE; }
// python function cleanup(channel=None) static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs) { int i = 0; int found = 0,v = 0; int channel = -666; unsigned int gpio; unsigned int sys_gpio; static char *kwlist[] = {"channel", NULL}; v = get_lmk_revision(); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &channel)) return NULL; if (channel != -666 && get_gpio_number(channel, &gpio, &sys_gpio)) return NULL; if (module_setup && !setup_error) { if (channel == -666) { // clean up any /sys/class exports event_cleanup_all(); // set everything back to input for (i=0; i<256; i++) { if (gpio_direction[i] != -1) { debug("Clean %d \n",i); if(v == BANANAPRO){ setup_gpio(*(pinTobcm_BP+i), INPUT, PUD_OFF);//take care } else if(v == LEMAKER_GUITAR){ setup_gpio(*(pinTobcm_GT+i), INPUT, PUD_OFF);//take care } gpio_direction[i] = -1; found = 1; } } } else { // clean up any /sys/class exports event_cleanup(sys_gpio); // set everything back to input if (gpio_direction[sys_gpio] != -1) { setup_gpio(gpio, INPUT, PUD_OFF); gpio_direction[i] = -1; found = 1; } } } //printf("-->Before set warning\n"); //printf("found %d \t gpio_warnings %d\n",found,gpio_warnings); // check if any channels set up - if not warn about misuse of GPIO.cleanup() if (!found && gpio_warnings) { PyErr_WarnEx(NULL, "No channels have been set up yet - nothing to clean up! Try cleaning up at the end of your program instead!", 1); } //printf("-->After set warning\n"); Py_RETURN_NONE; }
// python method PWM.set_frequency(channel, frequency) static PyObject *py_set_frequency(PyObject *self, PyObject *args, PyObject *kwargs) { char key[8]; char *channel; int gpio; int allowed = -1; float frequency = 1.0; static char *kwlist[] = {"channel", "frequency", NULL}; clear_error_msg(); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|f", kwlist, &channel, &frequency)) return NULL; if ((frequency <= 0.0) || (frequency > 10000.0)) { PyErr_SetString(PyExc_ValueError, "frequency must be greater than 0.0 and less than 10000.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_frequency(key, frequency) == -1) { PyErr_SetString(PyExc_RuntimeError, "You must start() the PWM channel first"); return NULL; } Py_RETURN_NONE; }
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None) static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; int channel, direction; int pud = PUD_OFF; int initial = -1; static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL}; int func; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", kwlist, &channel, &direction, &pud, &initial)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (direction != INPUT && direction != OUTPUT) { PyErr_SetString(InvalidDirectionException, "An invalid direction was passed to setup()"); return NULL; } if (direction == OUTPUT) pud = PUD_OFF; if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) { PyErr_SetString(InvalidPullException, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN"); return NULL; } func = gpio_function(gpio); if (gpio_warnings && // warnings enabled and ((func != 0 && func != 1) || // (already one of the alt functions or (gpio_direction[gpio] == -1 && func == 1))) // already an output not set from this program) { PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.", 1); } // printf("Setup GPIO %d direction %d pud %d\n", gpio, direction, pud); if (direction == OUTPUT && (initial == LOW || initial == HIGH)) { // printf("Writing intial value %d\n",initial); output_gpio(gpio, initial); } setup_gpio(gpio, direction, pud); gpio_direction[gpio] = direction; Py_INCREF(Py_None); return Py_None; }
// python function setup(channel, direction, pull_up_down=PUD_OFF, initial=None) static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; int channel, direction; unsigned int sys_gpio; int pud = PUD_OFF + PY_PUD_CONST_OFFSET; static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL}; int initial = -1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ii", kwlist, &channel, &direction, &pud, &initial)) return NULL; // check module has been imported cleanly if (setup_error) { PyErr_SetString(PyExc_RuntimeError, "Module not imported correctly!"); return NULL; } if (get_gpio_number(channel, &gpio, &sys_gpio)){ return NULL; } if (direction != INPUT && direction != OUTPUT) { PyErr_SetString(PyExc_ValueError, "An invalid direction was passed to setup()"); return NULL; } if (direction == OUTPUT) pud = PUD_OFF + PY_PUD_CONST_OFFSET; pud -= PY_PUD_CONST_OFFSET; if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) { PyErr_SetString(PyExc_ValueError, "Invalid value for pull_up_down - should be either PUD_OFF, PUD_UP or PUD_DOWN"); return NULL; } if (direction == OUTPUT && (initial == LOW || initial == HIGH)) { output_gpio(gpio, initial); } setup_gpio(gpio, direction, pud); gpio_direction[sys_gpio] = direction; Py_RETURN_NONE; }
// python function py_wait_for_edge(gpio, edge) static PyObject *py_wait_for_edge(PyObject *self, PyObject *args) { unsigned int gpio; int channel, edge, result; char error[30]; if (!PyArg_ParseTuple(args, "ii", &channel, &edge)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; // check channel is setup as an input if (gpio_direction[gpio] != INPUT) { PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel as an input first"); return NULL; } // is edge a valid value? edge -= PY_EVENT_CONST_OFFSET; if (edge != RISING_EDGE && edge != FALLING_EDGE && edge != BOTH_EDGE) { PyErr_SetString(PyExc_ValueError, "The edge must be set to RISING, FALLING or BOTH"); return NULL; } if (check_gpio_priv()) return NULL; Py_BEGIN_ALLOW_THREADS // disable GIL result = blocking_wait_for_edge(gpio, edge); Py_END_ALLOW_THREADS // enable GIL if (result == 0) { Py_INCREF(Py_None); return Py_None; } else if (result == 1) { PyErr_SetString(PyExc_RuntimeError, "Edge detection events already enabled for this GPIO channel"); return NULL; } else { sprintf(error, "Error #%d waiting for edge", result); PyErr_SetString(PyExc_RuntimeError, error); return NULL; } Py_RETURN_NONE; }
void bsp_gpio_direction_input(u32 gpio) { unsigned int gpio_base_addr, gpio_number, reg_value_old, reg_value_new; gpio_number = get_gpio_number(gpio); if (gpio_number >= GPIO_MAX_NUMBER) { return; } gpio_base_addr = get_gpio_base_addr(gpio); reg_value_old = readl(gpio_base_addr + GPIODIR); reg_value_new = (~(0x1UL << gpio_number)) & reg_value_old; writel(reg_value_new, gpio_base_addr + GPIODIR); }
// python function value = event_detected(channel) static PyObject *py_event_detected(PyObject *self, PyObject *args) { unsigned int gpio; int channel; if (!PyArg_ParseTuple(args, "i", &channel)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (event_detected(gpio)) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
// python function cleanup(channel=None) static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs) { int i; int found = 0; int channel = -666; unsigned int gpio; static char *kwlist[] = {"channel", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &channel)) return NULL; if (channel != -666 && get_gpio_number(channel, &gpio)) return NULL; if (module_setup && !setup_error) { if (channel == -666) { // clean up any /sys/class exports event_cleanup_all(); // set everything back to input for (i=0; i<54; i++) { if (gpio_direction[i] != -1) { setup_gpio(i, INPUT, PUD_OFF); gpio_direction[i] = -1; found = 1; } } } else { // clean up any /sys/class exports event_cleanup(gpio); // set everything back to input if (gpio_direction[gpio] != -1) { setup_gpio(gpio, INPUT, PUD_OFF); gpio_direction[i] = -1; found = 1; } } } // check if any channels set up - if not warn about misuse of GPIO.cleanup() if (!found && gpio_warnings) { PyErr_WarnEx(NULL, "No channels have been set up yet - nothing to clean up! Try cleaning up at the end of your program instead!", 1); } Py_RETURN_NONE; }
void bsp_gpio_set_value(u32 gpio,u32 value) { u32 gpio_base_addr = 0; u32 gpio_number = 0; u32 gpio_data_reg = 0; if(value > 1 || (gpio > GPIO_TOTAL)) { gpio_print_error("para is error, gpio = %d, value = %d.\n", gpio, value); return ; } gpio_base_addr = get_gpio_base_addr(gpio); gpio_number = get_gpio_number(gpio); gpio_data_reg = ((unsigned int)0x1 << (gpio_number + 2)); writel(value << gpio_number, gpio_base_addr + gpio_data_reg); }
// python function output(channel, value) static PyObject *py_output_gpio(PyObject *self, PyObject *args) { unsigned int gpio; int channel, value; if (!PyArg_ParseTuple(args, "ii", &channel, &value)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (gpio_direction[gpio] != OUTPUT) { PyErr_SetString(PyExc_RuntimeError, "The GPIO channel has not been set up as an OUTPUT"); return NULL; } output_gpio(gpio, value); Py_RETURN_NONE; }
// python function remove_event_detect(gpio) static PyObject *py_remove_event_detect(PyObject *self, PyObject *args) { unsigned int gpio; unsigned int sys_gpio; int channel; struct py_callback *cb = py_callbacks; struct py_callback *temp; struct py_callback *prev = NULL; if (!PyArg_ParseTuple(args, "i", &channel)) return NULL; if (get_gpio_number(channel, &gpio, &sys_gpio)) return NULL; // remove all python callbacks for gpio while (cb != NULL) { if (cb->gpio == gpio) { Py_XDECREF(cb->py_cb); if (prev == NULL) py_callbacks = cb->next; else prev->next = cb->next; temp = cb; cb = cb->next; free(temp); } else { prev = cb; cb = cb->next; } } if (check_gpio_priv()) return NULL; remove_edge_detect(sys_gpio); Py_RETURN_NONE; }
// python function stop(channel) static PyObject *py_stop_channel(PyObject *self, PyObject *args, PyObject *kwargs) { char key[8]; char *channel; int gpio; int allowed = -1; clear_error_msg(); if (!PyArg_ParseTuple(args, "s", &channel)) 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; } softpwm_disable(key); Py_RETURN_NONE; }
// python function add_event_callback(gpio, callback, bouncetime=0) static PyObject *py_add_event_callback(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; int channel; unsigned int bouncetime = 0; PyObject *cb_func; char *kwlist[] = {"gpio", "callback", "bouncetime", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO|i", kwlist, &channel, &cb_func, &bouncetime)) return NULL; if (!PyCallable_Check(cb_func)) { PyErr_SetString(PyExc_TypeError, "Parameter must be callable"); return NULL; } if (get_gpio_number(channel, &gpio)) return NULL; // check channel is set up as an input if (gpio_direction[gpio] != INPUT) { PyErr_SetString(WrongDirectionException, "You must setup() the GPIO channel as an input first"); return NULL; } if (!gpio_event_added(gpio)) { PyErr_SetString(AddEventException, "Add event detection using add_event_detect first before adding a callback"); return NULL; } if (add_py_callback(gpio, bouncetime, cb_func) != 0) return NULL; Py_INCREF(Py_None); return Py_None; }
s32 bsp_gpio_get_value(u32 gpio) { s32 value = 0; u32 gpio_base_addr = 0; u32 gpio_number = 0; u32 gpio_data_reg = 0; if(gpio > GPIO_TOTAL) { gpio_print_error("para is error, gpio = %d.\n", gpio); return -1; } gpio_base_addr = get_gpio_base_addr(gpio); gpio_number = get_gpio_number(gpio); gpio_data_reg = ((unsigned int)0x1 << (gpio_number + 2)); value = (s32)(readl(gpio_base_addr + gpio_data_reg) >> gpio_number); return value; }
s32 bsp_gpio_direction_get(u32 gpio) { unsigned int gpio_base_addr, gpio_number; if(gpio > GPIO_TOTAL) { gpio_print_error("para is error, gpio = %d.\n", gpio); return -1; } gpio_number = get_gpio_number(gpio); if (gpio_number >= GPIO_MAX_NUMBER) { gpio_print_error("para is error, gpio = %d.\n", gpio); return -1; } gpio_base_addr = get_gpio_base_addr(gpio); unsigned int reg_value = readl(gpio_base_addr + GPIODIR); return (reg_value >> gpio_number) & 0x01; }
// python function add_event_callback(gpio, callback) static PyObject *py_add_event_callback(PyObject *self, PyObject *args, PyObject *kwargs) { unsigned int gpio; unsigned int sys_gpio; int channel; PyObject *cb_func; char *kwlist[] = {"gpio", "callback", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO|i", kwlist, &channel, &cb_func)) return NULL; if (!PyCallable_Check(cb_func)) { PyErr_SetString(PyExc_TypeError, "Parameter must be callable"); return NULL; } if (get_gpio_number(channel, &gpio, &sys_gpio)) return NULL; // check channel is set up as an input if (gpio_direction[sys_gpio] != INPUT) { PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel as an input first"); return NULL; } if (!gpio_event_added(sys_gpio)) { PyErr_SetString(PyExc_RuntimeError, "Add event detection using add_event_detect first before adding a callback"); return NULL; } if (add_py_callback(sys_gpio, cb_func) != 0) return NULL; Py_RETURN_NONE; }
// python function output(channel, value) static PyObject *py_output_gpio(PyObject *self, PyObject *args) { unsigned int gpio; int channel, value; if (!PyArg_ParseTuple(args, "ii", &channel, &value)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (gpio_direction[gpio] != OUTPUT) { PyErr_SetString(WrongDirectionException, "The GPIO channel has not been set up as an OUTPUT"); return NULL; } // printf("Output GPIO %d value %d\n", gpio, value); output_gpio(gpio, value); Py_INCREF(Py_None); return Py_None; }
// python method PWM.__init__(self, channel, frequency) static int PWM_init(PWMObject *self, PyObject *args, PyObject *kwds) { int channel; float frequency; unsigned int tempt_gpio; if (!PyArg_ParseTuple(args, "if", &channel, &frequency)) return -1; // convert channel to gpio if (get_gpio_number(channel, &tempt_gpio, &(self->gpio))) return -1; debug("pwm_init self->gpio = %d\n",self->gpio); // ensure channel set as output if (gpio_direction[self->gpio] != OUTPUT) { PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel as an output first"); return -1; } if (frequency <= 0.0) { PyErr_SetString(PyExc_ValueError, "frequency must be greater than 0.0"); return -1; } self->freq = frequency; debug("self->gpio = %d and self->freq = %f\n", self->gpio, self->freq); pwm_set_frequency(self->gpio, self->freq); return 0; }
// python function py_wait_for_edge(gpio, edge) static PyObject *py_wait_for_edge(PyObject *self, PyObject *args) { unsigned int gpio; unsigned int sys_gpio; int channel, edge, result; char error[30]; if (!PyArg_ParseTuple(args, "ii", &channel, &edge)) return NULL; if (get_gpio_number(channel, &gpio, &sys_gpio)) return NULL; // check channel is setup as an input if (gpio_direction[sys_gpio] != INPUT) { PyErr_SetString(PyExc_RuntimeError, "You must setup() the GPIO channel as an input first"); return NULL; } //check channel whether support the event detected or not if(is_a20_platform()) { if(support_event_detect(gpio, gpioEdge_BP) < 0) { PyErr_SetString(PyExc_RuntimeError, "the pin doesn't support to detect the external event!"); return NULL; } } else if(is_s500_platform()) { if(support_event_detect(gpio, gpioEdge_GT) < 0) { PyErr_SetString(PyExc_RuntimeError, "the pin doesn't support to detect the external event!"); return NULL; } } // is edge a valid value? edge -= PY_EVENT_CONST_OFFSET; if(is_a20_platform()) { if (edge != RISING_EDGE && edge != FALLING_EDGE && edge != BOTH_EDGE) { PyErr_SetString(PyExc_ValueError, "The edge must be set to RISING, FALLING or BOTH"); return NULL; } } else if(is_s500_platform()) //s500 doesn't support the "BOTH" trigger mode. { if (edge != RISING_EDGE && edge != FALLING_EDGE) { PyErr_SetString(PyExc_ValueError, "The edge must be set to RISING and FALLING"); return NULL; } } if (check_gpio_priv()) return NULL; Py_BEGIN_ALLOW_THREADS // disable GIL result = blocking_wait_for_edge(sys_gpio, edge); Py_END_ALLOW_THREADS // enable GIL if (result == 0) { Py_INCREF(Py_None); return Py_None; } else if (result == 1) { PyErr_SetString(PyExc_RuntimeError, "Edge detection events already enabled for this GPIO channel"); return NULL; } else { sprintf(error, "Error #%d waiting for edge", result); PyErr_SetString(PyExc_RuntimeError, error); return NULL; } Py_RETURN_NONE; }
// python function value = gpio_function(channel) static PyObject *py_gpio_function(PyObject *self, PyObject *args) { unsigned int gpio; int channel; int f; PyObject *func; if (!PyArg_ParseTuple(args, "i", &channel)) return NULL; if (get_gpio_number(channel, &gpio)) return NULL; if (mmap_gpio_mem()) return NULL; f = gpio_function(gpio); switch (f) { case 0 : f = INPUT; break; case 1 : f = OUTPUT; break; // ALT 0 case 4 : switch (gpio) { case 0 : case 1 : case 2 : case 3 : f = I2C; break; case 7 : case 8 : case 9 : case 10 : case 11 : f = SPI; break; case 12 : case 13 : f = PWM; break; case 14 : case 15 : f = SERIAL; break; case 28 : case 29 : f = I2C; break; default : f = MODE_UNKNOWN; break; } break; // ALT 5 case 2 : if (gpio == 18 || gpio == 19) f = PWM; else f = MODE_UNKNOWN; break; // ALT 4 case 3 : switch (gpio) { case 16 : case 17 : case 18 : case 19 : case 20 : case 21 : f = SPI; break; default : f = MODE_UNKNOWN; break; } break; default : f = MODE_UNKNOWN; break; } func = Py_BuildValue("i", f); return func; }
// 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; }
// python function value = gpio_function(channel) static PyObject *py_gpio_function(PyObject *self, PyObject *args) { unsigned int gpio; unsigned int sys_gpio; int channel; int f,v; PyObject *func; if (!PyArg_ParseTuple(args, "i", &channel)) return NULL; if (get_gpio_number(channel, &gpio, &sys_gpio)) return NULL; v = get_lmk_revision(); f = gpio_function(gpio); debug("### %s: f=%d, gpio=%d ###\n",__func__, f, gpio); switch (f) { case 0 : f = INPUT; break; case 1 : f = OUTPUT; break; // ALT 0 case 4 :if(v == BANANAPRO){ //a20 switch (gpio) { case 257 : case 256 : case 53 : case 52 : f = I2C; break; case 270 : case 266 : case 269 : case 268 : case 267 : f = SPI; break; case 276 : case 45 : f = PWM; break; case 228 : case 229 : f = SERIAL; break; //case 28 : //case 29 : f = I2C; break; default : f = MODE_UNKNOWN; break; } }else if(v == LEMAKER_GUITAR) { //add for guitar switch (gpio) { case 131 : //GPIOE3 case 130 : f = I2C; break;//GPIOE2 case 87 : //GPIOC23 case 88 : //GPIOC24 case 89 : //GPIOC25 case 86 : f = SPI; break;//GPIOC22 case 40 : f = PWM; break;//GPIOB8 case 91 : //GPIOC27 case 90 : f = SERIAL; break;//GPIOD18 default : f = MODE_UNKNOWN; break; } } break; // ALT 5 case 2 : if (gpio == 259 || gpio == 39) f = PWM; else f = MODE_UNKNOWN; break; // ALT 4 case 3 : switch (gpio) { case 38 : case 275 : case 259 : case 39 : case 44 : case 40 : f = SPI; break; default : f = MODE_UNKNOWN; break; } break; default : f = MODE_UNKNOWN; break; } func = Py_BuildValue("i", f); return func; }