mirror of
https://github.com/xtacocorex/CHIP_IO
synced 2025-07-19 20:33:21 +00:00
Copied over 2 new pwm functions from @streamnsight to close #46. these 2 functions are untested, which is why i'm not updating the readme at the moment.
This commit is contained in:
@ -47,7 +47,6 @@ SOFTWARE.
|
||||
|
||||
// Global variables
|
||||
int pwm_initialized = 0;
|
||||
//int DEBUG = 0;
|
||||
|
||||
// pwm devices (future chip pro use)
|
||||
struct pwm_dev
|
||||
@ -173,6 +172,66 @@ int pwm_set_frequency(const char *key, float freq) {
|
||||
return rtnval;
|
||||
}
|
||||
|
||||
int pwm_set_period_ns(const char *key, unsigned long period_ns) {
|
||||
int len;
|
||||
int rtnval = -1;
|
||||
char buffer[80];
|
||||
struct pwm_exp *pwm;
|
||||
|
||||
//TODO: ADD CHECK FOR period_ns
|
||||
|
||||
pwm = lookup_exported_pwm(key);
|
||||
|
||||
if (pwm == NULL) {
|
||||
return rtnval;
|
||||
}
|
||||
|
||||
if (pwm->enable) {
|
||||
if (period_ns != pwm->period_ns) {
|
||||
pwm->period_ns = period_ns;
|
||||
|
||||
len = snprintf(buffer, sizeof(buffer), "%lu", period_ns); BUF2SMALL(buffer);
|
||||
ssize_t s = write(pwm->period_fd, buffer, len); //ASSRT(s == len);
|
||||
if (DEBUG) {
|
||||
printf(" ** pwm_set_period_ns: pwm_initialized = %d\n", pwm_initialized);
|
||||
printf(" ** pwm_set_period_ns: buffer: %s\n", buffer);
|
||||
printf(" ** pwm_set_period_ns: s = %d, len = %d\n", s, len);
|
||||
}
|
||||
if (s != len) {
|
||||
rtnval = -1;
|
||||
} else {
|
||||
rtnval = 1;
|
||||
}
|
||||
} else {
|
||||
rtnval = 0;
|
||||
}
|
||||
} else {
|
||||
rtnval = 0;
|
||||
}
|
||||
|
||||
return rtnval;
|
||||
}
|
||||
|
||||
int pwm_get_period_ns(const char *key, unsigned long *period_ns) {
|
||||
int rtnval = -1;
|
||||
struct pwm_exp *pwm;
|
||||
|
||||
pwm = lookup_exported_pwm(key);
|
||||
|
||||
if (pwm == NULL) {
|
||||
return rtnval;
|
||||
}
|
||||
|
||||
if (DEBUG)
|
||||
printf(" ** pwm_get_period_ns: %lu **\n",pwm->period_ns);
|
||||
|
||||
// Set period_ns to what we have in the struct
|
||||
*period_ns = pwm->period_ns;
|
||||
|
||||
rtnval = 0;
|
||||
return rtnval;
|
||||
}
|
||||
|
||||
int pwm_set_polarity(const char *key, int polarity) {
|
||||
int len;
|
||||
int rtnval = -1;
|
||||
@ -252,6 +311,44 @@ int pwm_set_duty_cycle(const char *key, float duty) {
|
||||
return rtnval;
|
||||
}
|
||||
|
||||
int pwm_set_pulse_width_ns(const char *key, unsigned long pulse_width_ns) {
|
||||
int len;
|
||||
int rtnval = -1;
|
||||
char buffer[80];
|
||||
struct pwm_exp *pwm;
|
||||
|
||||
pwm = lookup_exported_pwm(key);
|
||||
|
||||
if (pwm == NULL) {
|
||||
return rtnval;
|
||||
}
|
||||
|
||||
if (pulse_width_ns < 0 || pulse_width_ns > pwm->period_ns)
|
||||
return rtnval;
|
||||
|
||||
pwm->duty = pulse_width_ns / pwm->period_ns;
|
||||
|
||||
if (pwm->enable) {
|
||||
len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty); BUF2SMALL(buffer);
|
||||
ssize_t s = write(pwm->duty_fd, buffer, len); //ASSRT(s == len);
|
||||
if (DEBUG) {
|
||||
printf(" ** pwm_set_pulse_width_ns: pwm_initialized = %d\n", pwm_initialized);
|
||||
printf(" ** pwm_set_pulse_width_ns: buffer: %s\n", buffer);
|
||||
printf(" ** pwm_set_pulse_width_ns: s = %d, len = %d\n", s, len);
|
||||
}
|
||||
if (s != len) {
|
||||
rtnval = -1;
|
||||
} else {
|
||||
rtnval = 1;
|
||||
}
|
||||
} else {
|
||||
rtnval = 0;
|
||||
}
|
||||
|
||||
return rtnval;
|
||||
|
||||
}
|
||||
|
||||
int pwm_set_enable(const char *key, int enable)
|
||||
{
|
||||
int len;
|
||||
|
@ -32,6 +32,9 @@ SOFTWARE.
|
||||
int pwm_start(const char *key, float duty, float freq, int polarity);
|
||||
int pwm_disable(const char *key);
|
||||
int pwm_set_frequency(const char *key, float freq);
|
||||
int pwm_set_period_ns(const char *key, unsigned long period_ns);
|
||||
int pwm_get_period_ns(const char *key, unsigned long *period_ns);
|
||||
int pwm_set_duty_cycle(const char *key, float duty);
|
||||
int pwm_set_pulse_width_ns(const char *key, unsigned long pulse_width_ns);
|
||||
int pwm_set_enable(const char *key, int enable);
|
||||
void pwm_cleanup(void);
|
||||
|
@ -143,6 +143,45 @@ static PyObject *py_set_duty_cycle(PyObject *self, PyObject *args, PyObject *kwa
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
// python method PWM.set_pulse_width(channel, pulse_width_ns)
|
||||
static PyObject *py_set_pulse_width_ns(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
char key[8];
|
||||
char *channel;
|
||||
unsigned long pulse_width_ns = 0.0;
|
||||
unsigned long period_ns;
|
||||
static char *kwlist[] = {"channel", "pulse_width_ns", NULL};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|k", kwlist, &channel, &pulse_width_ns))
|
||||
return NULL;
|
||||
|
||||
if (!get_pwm_key(channel, key)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Invalid PWM key or name.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the period out of the data struct
|
||||
int rtn = pwm_get_period_ns(key, &period_ns);
|
||||
if (rtn == -1)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "period unable to be obtained");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pulse_width_ns < 0.0 || pulse_width_ns > period_ns)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "pulse width must have a value from 0 to period");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pwm_set_pulse_width_ns(key, pulse_width_ns) == -1) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "You must start() the PWM channel first");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
// python method PWM.set_frequency(channel, frequency)
|
||||
static PyObject *py_set_frequency(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
@ -173,6 +212,35 @@ static PyObject *py_set_frequency(PyObject *self, PyObject *args, PyObject *kwar
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
// python method PWM.set_period_ns(channel, period_ns)
|
||||
static PyObject *py_set_period_ns(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
char key[8];
|
||||
char *channel;
|
||||
unsigned long period_ns = 2e6;
|
||||
static char *kwlist[] = {"channel", "period_ns", NULL};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|k", kwlist, &channel, &period_ns))
|
||||
return NULL;
|
||||
|
||||
if (period_ns <= 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "period must be greater than 0ns");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!get_pwm_key(channel, key)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Invalid PWM key or name.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pwm_set_period_ns(key, period_ns) == -1) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "You must start() the PWM channel first");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static const char moduledocstring[] = "Hardware PWM functionality of a CHIP using Python";
|
||||
|
||||
@ -181,6 +249,8 @@ PyMethodDef pwm_methods[] = {
|
||||
{"stop", (PyCFunction)py_stop_channel, METH_VARARGS | METH_KEYWORDS, "Stop the PWM channel. channel can be in the form of 'PWM0', or 'U13_18'"},
|
||||
{"set_duty_cycle", (PyCFunction)py_set_duty_cycle, METH_VARARGS, "Change the duty cycle\ndutycycle - between 0.0 and 100.0" },
|
||||
{"set_frequency", (PyCFunction)py_set_frequency, METH_VARARGS, "Change the frequency\nfrequency - frequency in Hz (freq > 0.0)" },
|
||||
{"set_period_ns", (PyCFunction)py_set_period_ns, METH_VARARGS, "Change the period\nperiod_ns - period in nanoseconds" },
|
||||
{"set_pulse_width_ns", (PyCFunction)py_set_pulse_width_ns, METH_VARARGS, "Change the period\npulse_width_ns - pulse width in nanoseconds" },
|
||||
{"cleanup", py_cleanup, METH_VARARGS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection"},
|
||||
{"toggle_debug", py_toggle_debug, METH_VARARGS, "Toggles the enabling/disabling of Debug print output"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
|
Reference in New Issue
Block a user