mirror of
https://github.com/xtacocorex/CHIP_IO
synced 2025-07-20 04:43:21 +00:00
fixes for #17, hardware pwm works now, still can't change polarity, but i think that's a kernel driver/dtb thing.
This commit is contained in:
237
source/c_pwm.c
237
source/c_pwm.c
@ -42,8 +42,23 @@ SOFTWARE.
|
|||||||
|
|
||||||
#define PERIOD 0
|
#define PERIOD 0
|
||||||
#define DUTY 1
|
#define DUTY 1
|
||||||
|
#define ENABLE 1
|
||||||
|
#define DISABLE 0
|
||||||
|
|
||||||
|
// Global variables
|
||||||
int pwm_initialized = 0;
|
int pwm_initialized = 0;
|
||||||
|
int DEBUG = 0;
|
||||||
|
//int ENABLE = 1;
|
||||||
|
//int DISABLE = 0;
|
||||||
|
|
||||||
|
// pwm devices (future chip pro use)
|
||||||
|
struct pwm_dev
|
||||||
|
{
|
||||||
|
char key[KEYLEN+1]; /* leave room for terminating NUL byte */
|
||||||
|
int gpio;
|
||||||
|
int initialized;
|
||||||
|
};
|
||||||
|
struct pwm_dev *initialized_pwms = NULL;
|
||||||
|
|
||||||
// pwm exports
|
// pwm exports
|
||||||
struct pwm_exp
|
struct pwm_exp
|
||||||
@ -71,27 +86,28 @@ struct pwm_exp *lookup_exported_pwm(const char *key)
|
|||||||
}
|
}
|
||||||
pwm = pwm->next;
|
pwm = pwm->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL; /* standard for pointers */
|
return NULL; /* standard for pointers */
|
||||||
}
|
}
|
||||||
|
|
||||||
int initialize_pwm(void)
|
int initialize_pwm(void)
|
||||||
{
|
{
|
||||||
if (!pwm_initialized) {
|
if (!pwm_initialized) {
|
||||||
int fd, len;
|
int fd, len;
|
||||||
char str_gpio[80];
|
char str_gpio[80];
|
||||||
// Per https://github.com/NextThingCo/CHIP-linux/pull/4
|
// Per https://github.com/NextThingCo/CHIP-linux/pull/4
|
||||||
// we need to export 0 here to enable pwm0
|
// we need to export 0 here to enable pwm0
|
||||||
int gpio = 0;
|
int gpio = 0;
|
||||||
|
|
||||||
printf(" ** EXPORTING PWM0 **\n");
|
if (DEBUG)
|
||||||
|
printf(" ** EXPORTING PWM0 **\n");
|
||||||
if ((fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY)) < 0)
|
if ((fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY)) < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); //BUF2SMALL(str_gpio);
|
len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); BUF2SMALL(str_gpio);
|
||||||
ssize_t s = write(fd, str_gpio, len); //ASSRT(s == len);
|
ssize_t s = write(fd, str_gpio, len); ASSRT(s == len);
|
||||||
printf(" ** IN initialize_pwm: s = %d, len = %d\n", s, len);
|
if (DEBUG)
|
||||||
|
printf(" ** IN initialize_pwm: s = %d, len = %d\n", s, len);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
pwm_initialized = 1;
|
pwm_initialized = 1;
|
||||||
@ -103,87 +119,128 @@ int initialize_pwm(void)
|
|||||||
|
|
||||||
int pwm_set_frequency(const char *key, float freq) {
|
int pwm_set_frequency(const char *key, float freq) {
|
||||||
int len;
|
int len;
|
||||||
|
int rtnval = -1;
|
||||||
char buffer[80];
|
char buffer[80];
|
||||||
unsigned long period_ns;
|
unsigned long period_ns;
|
||||||
struct pwm_exp *pwm;
|
struct pwm_exp *pwm;
|
||||||
|
|
||||||
if (freq <= 0.0)
|
if (freq <= 0.0)
|
||||||
return -1;
|
return rtnval;
|
||||||
|
|
||||||
pwm = lookup_exported_pwm(key);
|
pwm = lookup_exported_pwm(key);
|
||||||
|
|
||||||
if (pwm == NULL) {
|
if (pwm == NULL) {
|
||||||
return -1;
|
return rtnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
period_ns = (unsigned long)(1e9 / freq);
|
period_ns = (unsigned long)(1e9 / freq);
|
||||||
|
|
||||||
printf(" ** IN pwm_set_frequency: pwm_initialized = %d\n", pwm_initialized);
|
if (pwm->enable) {
|
||||||
if (period_ns != pwm->period_ns) {
|
if (DEBUG)
|
||||||
pwm->period_ns = period_ns;
|
printf(" ** IN pwm_set_frequency: pwm_initialized = %d\n", pwm_initialized);
|
||||||
|
if (period_ns != pwm->period_ns) {
|
||||||
|
pwm->period_ns = period_ns;
|
||||||
|
|
||||||
len = snprintf(buffer, sizeof(buffer), "%lu", period_ns); //BUF2SMALL(buffer);
|
len = snprintf(buffer, sizeof(buffer), "%lu", period_ns); BUF2SMALL(buffer);
|
||||||
printf(" ** pwm_set_frequency: buffer: %s\n", buffer);
|
if (DEBUG)
|
||||||
ssize_t s = write(pwm->period_fd, buffer, len); //ASSRT(s == len);
|
printf(" ** pwm_set_frequency: buffer: %s\n", buffer);
|
||||||
printf(" ** IN pwm_set_frequency: s = %d, len = %d\n", s, len);
|
ssize_t s = write(pwm->period_fd, buffer, len); //ASSRT(s == len);
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** IN pwm_set_frequency: s = %d, len = %d\n", s, len);
|
||||||
|
if (s != len) {
|
||||||
|
rtnval = -1;
|
||||||
|
} else {
|
||||||
|
rtnval = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rtnval = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rtnval = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return rtnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pwm_set_polarity(const char *key, int polarity) {
|
int pwm_set_polarity(const char *key, int polarity) {
|
||||||
int len;
|
int len;
|
||||||
|
int rtnval = -1;
|
||||||
char buffer[80];
|
char buffer[80];
|
||||||
struct pwm_exp *pwm;
|
struct pwm_exp *pwm;
|
||||||
|
|
||||||
pwm = lookup_exported_pwm(key);
|
pwm = lookup_exported_pwm(key);
|
||||||
|
|
||||||
if (pwm == NULL) {
|
if (pwm == NULL) {
|
||||||
return -1;
|
return rtnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (polarity < 0 || polarity > 1) {
|
if (polarity != 0 && polarity != 1) {
|
||||||
return -1;
|
return rtnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" ** IN pwm_set_polarity: pwm_initialized = %d\n", pwm_initialized);
|
if (pwm->enable) {
|
||||||
if (polarity == 0) {
|
if (DEBUG)
|
||||||
len = snprintf(buffer, sizeof(buffer), "%s", "normal"); //BUF2SMALL(buffer);
|
printf(" ** IN pwm_set_polarity: pwm_initialized = %d\n", pwm_initialized);
|
||||||
|
if (polarity == 0) {
|
||||||
|
len = snprintf(buffer, sizeof(buffer), "%s", "normal"); BUF2SMALL(buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = snprintf(buffer, sizeof(buffer), "%s", "inverted"); BUF2SMALL(buffer);
|
||||||
|
}
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** pwm_set_poliarity: buffer: %s\n", buffer);
|
||||||
|
ssize_t s = write(pwm->polarity_fd, buffer, len); //ASSRT(s == len);
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** IN pwm_set_polarity: s = %d, len = %d\n", s, len);
|
||||||
|
if (s != len) {
|
||||||
|
rtnval = -1;
|
||||||
|
} else {
|
||||||
|
rtnval = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rtnval = 0;
|
||||||
}
|
}
|
||||||
else
|
return rtnval;
|
||||||
{
|
|
||||||
len = snprintf(buffer, sizeof(buffer), "%s", "inverted"); //BUF2SMALL(buffer);
|
|
||||||
}
|
|
||||||
printf(" ** pwm_set_poliarity: buffer: %s\n", buffer);
|
|
||||||
ssize_t s = write(pwm->polarity_fd, buffer, len); //ASSRT(s == len);
|
|
||||||
printf(" ** IN pwm_set_polarity: s = %d, len = %d\n", s, len);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pwm_set_duty_cycle(const char *key, float duty) {
|
int pwm_set_duty_cycle(const char *key, float duty) {
|
||||||
int len;
|
int len;
|
||||||
|
int rtnval = -1;
|
||||||
char buffer[80];
|
char buffer[80];
|
||||||
struct pwm_exp *pwm;
|
struct pwm_exp *pwm;
|
||||||
|
|
||||||
if (duty < 0.0 || duty > 100.0)
|
if (duty < 0.0 || duty > 100.0) {
|
||||||
return -1;
|
return rtnval;
|
||||||
|
}
|
||||||
|
|
||||||
pwm = lookup_exported_pwm(key);
|
pwm = lookup_exported_pwm(key);
|
||||||
|
|
||||||
if (pwm == NULL) {
|
if (pwm == NULL) {
|
||||||
return -1;
|
return rtnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
pwm->duty = (unsigned long)(pwm->period_ns * (duty / 100.0));
|
pwm->duty = (unsigned long)(pwm->period_ns * (duty / 100.0));
|
||||||
|
|
||||||
printf(" ** IN pwm_set_duty_cycle: pwm_initialized = %d\n", pwm_initialized);
|
if (pwm->enable) {
|
||||||
len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty); //BUF2SMALL(buffer);
|
if (DEBUG)
|
||||||
printf(" ** pwm_set_duty_cycle: buffer: %s\n", buffer);
|
printf(" ** IN pwm_set_duty_cycle: pwm_initialized = %d\n", pwm_initialized);
|
||||||
ssize_t s = write(pwm->duty_fd, buffer, len); //ASSRT(s == len);
|
len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty); BUF2SMALL(buffer);
|
||||||
printf(" ** IN pwm_set_duty_cycle: s = %d, len = %d\n", s, len);
|
if (DEBUG)
|
||||||
|
printf(" ** pwm_set_duty_cycle: buffer: %s\n", buffer);
|
||||||
|
ssize_t s = write(pwm->duty_fd, buffer, len); //ASSRT(s == len);
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** IN pwm_set_duty_cycle: s = %d, len = %d\n", s, len);
|
||||||
|
if (s != len) {
|
||||||
|
rtnval = -1;
|
||||||
|
} else {
|
||||||
|
rtnval = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rtnval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return rtnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pwm_set_enable(const char *key, int enable)
|
int pwm_set_enable(const char *key, int enable)
|
||||||
@ -193,31 +250,38 @@ int pwm_set_enable(const char *key, int enable)
|
|||||||
char buffer[80];
|
char buffer[80];
|
||||||
struct pwm_exp *pwm;
|
struct pwm_exp *pwm;
|
||||||
|
|
||||||
if (enable != 0 || enable != 1)
|
if (enable != 0 && enable != 1) {
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** INVALID ENABLE OPTION, NEEDS TO BE EITHER 0 OR 1! **\n");
|
||||||
return rtnval;
|
return rtnval;
|
||||||
|
}
|
||||||
|
|
||||||
pwm = lookup_exported_pwm(key);
|
pwm = lookup_exported_pwm(key);
|
||||||
|
|
||||||
if (pwm == NULL) {
|
if (pwm == NULL) {
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** SOMETHING BAD HAPPEND IN pwm_set_enable, WE'RE EXITING WITH -1 NOW! **\n");
|
||||||
return rtnval;
|
return rtnval;
|
||||||
}
|
}
|
||||||
|
|
||||||
//pwm->enable = enable;
|
|
||||||
|
|
||||||
printf(" ** IN pwm_set_enable: pwm_initialized = %d\n", pwm_initialized);
|
len = snprintf(buffer, sizeof(buffer), "%d", enable); BUF2SMALL(buffer);
|
||||||
len = snprintf(buffer, sizeof(buffer), "%d", enable); //BUF2SMALL(buffer);
|
|
||||||
printf(" ** pwm_set_enable: buffer: %s\n", buffer);
|
|
||||||
ssize_t s = write(pwm->enable_fd, buffer, len); //ASSRT(s == len);
|
ssize_t s = write(pwm->enable_fd, buffer, len); //ASSRT(s == len);
|
||||||
printf(" ** IN pwm_set_enable: s = %d, len = %d\n", s, len);
|
if (DEBUG) {
|
||||||
|
printf(" ** IN pwm_set_enable: pwm_initialized = %d\n", pwm_initialized);
|
||||||
|
printf(" ** pwm_set_enable: buffer: %s\n", buffer);
|
||||||
|
printf(" ** IN pwm_set_enable: s = %d, len = %d\n", s, len);
|
||||||
|
}
|
||||||
|
|
||||||
//if (s == len)
|
if (s == len)
|
||||||
//{
|
{
|
||||||
printf(" ** SETTING pwm->enable to %d\n", enable);
|
if (DEBUG)
|
||||||
|
printf(" ** SETTING pwm->enable to %d\n", enable);
|
||||||
pwm->enable = enable;
|
pwm->enable = enable;
|
||||||
rtnval = 0;
|
rtnval = 0;
|
||||||
//} else {
|
} else {
|
||||||
// rtnval = -1;
|
rtnval = -1;
|
||||||
//}
|
}
|
||||||
|
|
||||||
return rtnval;
|
return rtnval;
|
||||||
}
|
}
|
||||||
@ -232,44 +296,52 @@ int pwm_start(const char *key, float duty, float freq, int polarity)
|
|||||||
int period_fd, duty_fd, polarity_fd, enable_fd;
|
int period_fd, duty_fd, polarity_fd, enable_fd;
|
||||||
struct pwm_exp *new_pwm, *pwm;
|
struct pwm_exp *new_pwm, *pwm;
|
||||||
|
|
||||||
printf(" ** IN pwm_start: pwm_initialized = %d\n", pwm_initialized);
|
if (DEBUG)
|
||||||
|
printf(" ** IN pwm_start: pwm_initialized = %d\n", pwm_initialized);
|
||||||
if(!pwm_initialized) {
|
if(!pwm_initialized) {
|
||||||
initialize_pwm();
|
initialize_pwm();
|
||||||
|
} else {
|
||||||
|
if (DEBUG)
|
||||||
|
printf(" ** ALREADY INITIALIZED, CALLING CLEANUP TO START FRESH **");
|
||||||
|
pwm_cleanup();
|
||||||
}
|
}
|
||||||
printf(" ** IN pwm_start: pwm_initialized = %d\n", pwm_initialized);
|
if (DEBUG)
|
||||||
|
printf(" ** IN pwm_start: pwm_initialized = %d\n", pwm_initialized);
|
||||||
|
|
||||||
//setup the pwm base path, the chip only has one pwm
|
//setup the pwm base path, the chip only has one pwm
|
||||||
snprintf(pwm_base_path, sizeof(pwm_base_path), "/sys/class/pwm/pwmchip0/pwm%d", 0); BUF2SMALL(pwm_base_path);
|
snprintf(pwm_base_path, sizeof(pwm_base_path), "/sys/class/pwm/pwmchip0/pwm%d", 0); BUF2SMALL(pwm_base_path);
|
||||||
|
|
||||||
//create the path for the period and duty
|
//create the path for the period and duty
|
||||||
snprintf(enable_path, sizeof(enable_path), "%s/enable", pwm_base_path); //BUF2SMALL(enable_path);
|
snprintf(enable_path, sizeof(enable_path), "%s/enable", pwm_base_path); BUF2SMALL(enable_path);
|
||||||
snprintf(period_path, sizeof(period_path), "%s/period", pwm_base_path); //BUF2SMALL(period_path);
|
snprintf(period_path, sizeof(period_path), "%s/period", pwm_base_path); BUF2SMALL(period_path);
|
||||||
snprintf(duty_path, sizeof(duty_path), "%s/duty_cycle", pwm_base_path); //BUF2SMALL(duty_path);
|
snprintf(duty_path, sizeof(duty_path), "%s/duty_cycle", pwm_base_path); BUF2SMALL(duty_path);
|
||||||
snprintf(polarity_path, sizeof(polarity_path), "%s/polarity", pwm_base_path); //BUF2SMALL(polarity_path);
|
snprintf(polarity_path, sizeof(polarity_path), "%s/polarity", pwm_base_path); BUF2SMALL(polarity_path);
|
||||||
|
|
||||||
printf(" ** IN pwm_start: pwm_base_path: %s\n", pwm_base_path);
|
if (DEBUG) {
|
||||||
printf(" ** IN pwm_start: enable_path: %s\n", enable_path);
|
printf(" ** IN pwm_start: pwm_base_path: %s\n", pwm_base_path);
|
||||||
printf(" ** IN pwm_start: period_path: %s\n", period_path);
|
printf(" ** IN pwm_start: enable_path: %s\n", enable_path);
|
||||||
printf(" ** IN pwm_start: duty_path: %s\n", duty_path);
|
printf(" ** IN pwm_start: period_path: %s\n", period_path);
|
||||||
printf(" ** IN pwm_start: polarity_path: %s\n", polarity_path);
|
printf(" ** IN pwm_start: duty_path: %s\n", duty_path);
|
||||||
|
printf(" **IN pwm_start: polarity_path: %s\n", polarity_path);
|
||||||
|
}
|
||||||
|
|
||||||
//add period and duty fd to pwm list
|
//add period and duty fd to pwm list
|
||||||
if ((enable_fd = open(enable_path, O_RDWR)) < 0)
|
if ((enable_fd = open(enable_path, O_WRONLY)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((period_fd = open(period_path, O_RDWR)) < 0) {
|
if ((period_fd = open(period_path, O_WRONLY)) < 0) {
|
||||||
close(enable_fd);
|
close(enable_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((duty_fd = open(duty_path, O_RDWR)) < 0) {
|
if ((duty_fd = open(duty_path, O_WRONLY)) < 0) {
|
||||||
//error, close already opened period_fd.
|
//error, close already opened period_fd.
|
||||||
close(enable_fd);
|
close(enable_fd);
|
||||||
close(period_fd);
|
close(period_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((polarity_fd = open(polarity_path, O_RDWR)) < 0) {
|
if ((polarity_fd = open(polarity_path, O_WRONLY)) < 0) {
|
||||||
//error, close already opened period_fd and duty_fd.
|
//error, close already opened period_fd and duty_fd.
|
||||||
close(enable_fd);
|
close(enable_fd);
|
||||||
close(period_fd);
|
close(period_fd);
|
||||||
@ -283,7 +355,8 @@ int pwm_start(const char *key, float duty, float freq, int polarity)
|
|||||||
return -1; // out of memory
|
return -1; // out of memory
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" ** IN pwm_start: IF WE MAKE IT HERE, THE FILES WERE SUCCESSFULLY OPEN **\n");
|
if (DEBUG)
|
||||||
|
printf(" ** IN pwm_start: IF WE MAKE IT HERE, THE FILES WERE SUCCESSFULLY OPEN **\n");
|
||||||
strncpy(new_pwm->key, key, KEYLEN); /* can leave string unterminated */
|
strncpy(new_pwm->key, key, KEYLEN); /* can leave string unterminated */
|
||||||
new_pwm->key[KEYLEN] = '\0'; /* terminate string */
|
new_pwm->key[KEYLEN] = '\0'; /* terminate string */
|
||||||
new_pwm->period_fd = period_fd;
|
new_pwm->period_fd = period_fd;
|
||||||
@ -304,22 +377,14 @@ int pwm_start(const char *key, float duty, float freq, int polarity)
|
|||||||
pwm->next = new_pwm;
|
pwm->next = new_pwm;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" ** IN pwm_start: CALLING THE SET FUNCTIONS **\n");
|
|
||||||
int rtnval = 0;
|
int rtnval = 0;
|
||||||
rtnval = pwm_set_enable(key, 1);
|
rtnval = pwm_set_enable(key, ENABLE);
|
||||||
printf(" ** pwm_set_enable rtnval = %d\n", rtnval);
|
|
||||||
rtnval = 0;
|
rtnval = 0;
|
||||||
rtnval = pwm_set_frequency(key, freq);
|
rtnval = pwm_set_frequency(key, freq);
|
||||||
printf(" ** pwm_set_frequency rtnval = %d\n", rtnval);
|
|
||||||
rtnval = 0;
|
rtnval = 0;
|
||||||
rtnval = pwm_set_polarity(key, polarity);
|
//rtnval = pwm_set_polarity(key, polarity);
|
||||||
printf(" ** pwm_set_polarity rtnval = %d\n", rtnval);
|
|
||||||
//rtnval = 0;
|
//rtnval = 0;
|
||||||
//rtnval = pwm_set_enable(key, 1);
|
|
||||||
//printf(" ** pwm_set_enable rtnval = %d\n", rtnval);
|
|
||||||
rtnval = 0;
|
|
||||||
rtnval = pwm_set_duty_cycle(key, duty);
|
rtnval = pwm_set_duty_cycle(key, duty);
|
||||||
printf(" ** pwm_set_duty_cycle rtnval = %d\n", rtnval);
|
|
||||||
rtnval = 0;
|
rtnval = 0;
|
||||||
|
|
||||||
// TODO: SET RETURN BASED UPON 4 FUNCTIONS ABOVE
|
// TODO: SET RETURN BASED UPON 4 FUNCTIONS ABOVE
|
||||||
@ -339,15 +404,15 @@ int pwm_disable(const char *key)
|
|||||||
// Disable the PWM
|
// Disable the PWM
|
||||||
pwm_set_frequency(key, 0);
|
pwm_set_frequency(key, 0);
|
||||||
pwm_set_polarity(key, 0);
|
pwm_set_polarity(key, 0);
|
||||||
pwm_set_enable(key, 0);
|
|
||||||
pwm_set_duty_cycle(key, 0);
|
pwm_set_duty_cycle(key, 0);
|
||||||
|
pwm_set_enable(key, DISABLE);
|
||||||
|
|
||||||
if ((fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY)) < 0)
|
if ((fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY)) < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); //BUF2SMALL(str_gpio);
|
len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); BUF2SMALL(str_gpio);
|
||||||
ssize_t s = write(fd, str_gpio, len); //ASSRT(s == len);
|
ssize_t s = write(fd, str_gpio, len); ASSRT(s == len);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
// remove from list
|
// remove from list
|
||||||
@ -369,7 +434,6 @@ int pwm_disable(const char *key)
|
|||||||
} else {
|
} else {
|
||||||
prev_pwm->next = pwm->next;
|
prev_pwm->next = pwm->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = pwm;
|
temp = pwm;
|
||||||
pwm = pwm->next;
|
pwm = pwm->next;
|
||||||
free(temp);
|
free(temp);
|
||||||
@ -387,3 +451,12 @@ void pwm_cleanup(void)
|
|||||||
pwm_disable(exported_pwms->key);
|
pwm_disable(exported_pwms->key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pwm_toggle_debug(void)
|
||||||
|
{
|
||||||
|
if (DEBUG) {
|
||||||
|
DEBUG = 0;
|
||||||
|
} else {
|
||||||
|
DEBUG = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -35,3 +35,4 @@ int pwm_set_frequency(const char *key, float freq);
|
|||||||
int pwm_set_duty_cycle(const char *key, float duty);
|
int pwm_set_duty_cycle(const char *key, float duty);
|
||||||
int pwm_set_enable(const char *key, int enable);
|
int pwm_set_enable(const char *key, int enable);
|
||||||
void pwm_cleanup(void);
|
void pwm_cleanup(void);
|
||||||
|
void pwm_toggle_debug(void);
|
||||||
|
@ -77,7 +77,6 @@ struct dyn_int_array_s {
|
|||||||
};
|
};
|
||||||
typedef struct dyn_int_array_s dyn_int_array_t;
|
typedef struct dyn_int_array_s dyn_int_array_t;
|
||||||
|
|
||||||
|
|
||||||
#define FILENAME_BUFFER_SIZE 128
|
#define FILENAME_BUFFER_SIZE 128
|
||||||
|
|
||||||
int setup_error;
|
int setup_error;
|
||||||
|
@ -43,6 +43,15 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args)
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// python function toggle_debug()
|
||||||
|
static PyObject *py_toggle_debug(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
// toggle debug printing
|
||||||
|
pwm_toggle_debug();
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
// python function start(channel, duty_cycle, freq)
|
// python function start(channel, duty_cycle, freq)
|
||||||
static PyObject *py_start_channel(PyObject *self, PyObject *args, PyObject *kwargs)
|
static PyObject *py_start_channel(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
@ -170,9 +179,10 @@ static const char moduledocstring[] = "Hardware PWM functionality of a CHIP usin
|
|||||||
PyMethodDef pwm_methods[] = {
|
PyMethodDef pwm_methods[] = {
|
||||||
{"start", (PyCFunction)py_start_channel, METH_VARARGS | METH_KEYWORDS, "Set up and start the PWM channel. channel can be in the form of 'PWM0', or 'U13_18'"},
|
{"start", (PyCFunction)py_start_channel, METH_VARARGS | METH_KEYWORDS, "Set up and start the PWM channel. channel can be in the form of 'PWM0', or 'U13_18'"},
|
||||||
{"stop", (PyCFunction)py_stop_channel, METH_VARARGS | METH_KEYWORDS, "Stop the PWM channel. channel can be in the form of 'PWM0', or 'U13_18'"},
|
{"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_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_frequency", (PyCFunction)py_set_frequency, METH_VARARGS, "Change the frequency\nfrequency - frequency in Hz (freq > 0.0)" },
|
||||||
{"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"},
|
{"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"},
|
||||||
//{"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
|
//{"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
0
test/gptest.py
Executable file → Normal file
0
test/gptest.py
Executable file → Normal file
0
test/omtest.py
Executable file → Normal file
0
test/omtest.py
Executable file → Normal file
18
test/pwmtest.py
Executable file → Normal file
18
test/pwmtest.py
Executable file → Normal file
@ -49,7 +49,7 @@ if __name__ == "__main__":
|
|||||||
# SETUP VARIABLES
|
# SETUP VARIABLES
|
||||||
PWMGPIO = "PWM0"
|
PWMGPIO = "PWM0"
|
||||||
RECEIVERGPIO = "CSID0"
|
RECEIVERGPIO = "CSID0"
|
||||||
COUNT = 50
|
COUNT = 150
|
||||||
SLEEPTIME = 0.01
|
SLEEPTIME = 0.01
|
||||||
|
|
||||||
# LOAD THE PWM OVERLAY
|
# LOAD THE PWM OVERLAY
|
||||||
@ -59,13 +59,14 @@ if __name__ == "__main__":
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# CLEANUP THE GPIO
|
# CLEANUP THE GPIO
|
||||||
GPIO.cleanup()
|
#GPIO.cleanup()
|
||||||
PWM.cleanup()
|
#PWM.cleanup()
|
||||||
|
|
||||||
# SETUP PWM
|
# SETUP PWM
|
||||||
try:
|
try:
|
||||||
print("PWM START")
|
print("PWM START")
|
||||||
PWM.start(PWMGPIO, 35, 20, 0)
|
PWM.toggle_debug()
|
||||||
|
PWM.start(PWMGPIO, 15, 50, 1)
|
||||||
PrintPwmData()
|
PrintPwmData()
|
||||||
|
|
||||||
# UNCOMMENT FOR CRASH
|
# UNCOMMENT FOR CRASH
|
||||||
@ -79,10 +80,11 @@ if __name__ == "__main__":
|
|||||||
#PrintPwmData()
|
#PrintPwmData()
|
||||||
|
|
||||||
# SETUP PWM RECEIVER
|
# SETUP PWM RECEIVER
|
||||||
rcvr = PWMReceiver(GPIO, RECEIVERGPIO, COUNT, SLEEPTIME)
|
#rcvr = PWMReceiver(GPIO, RECEIVERGPIO, COUNT, SLEEPTIME)
|
||||||
rcvr.start()
|
#rcvr.start()
|
||||||
|
|
||||||
time.sleep(COUNT*SLEEPTIME + 1)
|
#time.sleep(COUNT*SLEEPTIME + 1)
|
||||||
|
raw_input("PRESS ENTER WHEN DONE")
|
||||||
|
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
@ -92,6 +94,6 @@ if __name__ == "__main__":
|
|||||||
PWM.stop(PWMGPIO)
|
PWM.stop(PWMGPIO)
|
||||||
PWM.cleanup()
|
PWM.cleanup()
|
||||||
#OM.unload("PWM0")
|
#OM.unload("PWM0")
|
||||||
GPIO.cleanup()
|
#GPIO.cleanup()
|
||||||
|
|
||||||
|
|
||||||
|
0
test/spwmtest.py
Executable file → Normal file
0
test/spwmtest.py
Executable file → Normal file
0
test/test_gpio_input.py
Executable file → Normal file
0
test/test_gpio_input.py
Executable file → Normal file
Reference in New Issue
Block a user