mirror of
https://github.com/xtacocorex/CHIP_IO
synced 2025-07-20 04:43:21 +00:00
PWM support fixed, the test fails when trying to change the frequency, but I don't think that's an issue. Have not run this against something that needs PWM to operate, but the .dtb I have loaded has /sys/class/pwm/pwmchip0 and it can be configured with this code
This commit is contained in:
2
setup.py
2
setup.py
@ -20,7 +20,7 @@ classifiers = ['Development Status :: 3 - Alpha',
|
||||
'Topic :: System :: Hardware']
|
||||
|
||||
setup(name = 'CHIP_IO',
|
||||
version = '0.0.5',
|
||||
version = '0.0.6',
|
||||
author = 'Robert Wolterman',
|
||||
author_email = 'robert.wolterman@gmail.com',
|
||||
description = 'A module to control CHIP IO channels',
|
||||
|
@ -52,6 +52,8 @@ struct pwm_exp
|
||||
int period_fd;
|
||||
int duty_fd;
|
||||
int polarity_fd;
|
||||
int enable_fd;
|
||||
int enable;
|
||||
unsigned long duty;
|
||||
unsigned long period_ns;
|
||||
struct pwm_exp *next;
|
||||
@ -126,7 +128,7 @@ int pwm_set_frequency(const char *key, float freq) {
|
||||
|
||||
int pwm_set_polarity(const char *key, int polarity) {
|
||||
int len;
|
||||
char buffer[7]; /* allow room for trailing NUL byte */
|
||||
char buffer[9]; /* allow room for trailing NUL byte */
|
||||
struct pwm_exp *pwm;
|
||||
|
||||
pwm = lookup_exported_pwm(key);
|
||||
@ -135,7 +137,17 @@ int pwm_set_polarity(const char *key, int polarity) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = snprintf(buffer, sizeof(buffer), "%d", polarity);
|
||||
if (polarity < 0 || polarity > 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (polarity == 0) {
|
||||
len = snprintf(buffer, sizeof(buffer), "%s", "normal");
|
||||
}
|
||||
else
|
||||
{
|
||||
len = snprintf(buffer, sizeof(buffer), "%s", "inverted");
|
||||
}
|
||||
write(pwm->polarity_fd, buffer, len);
|
||||
|
||||
return 0;
|
||||
@ -163,13 +175,37 @@ int pwm_set_duty_cycle(const char *key, float duty) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwm_set_enable(const char *key, int enable)
|
||||
{
|
||||
int len;
|
||||
char buffer[20];
|
||||
struct pwm_exp *pwm;
|
||||
|
||||
if (enable != 0 || enable != 1)
|
||||
return -1;
|
||||
|
||||
pwm = lookup_exported_pwm(key);
|
||||
|
||||
if (pwm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pwm->enable = enable;
|
||||
|
||||
len = snprintf(buffer, sizeof(buffer), "%d", pwm->enable);
|
||||
write(pwm->enable_fd, buffer, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwm_start(const char *key, float duty, float freq, int polarity)
|
||||
{
|
||||
char pwm_base_path[45];
|
||||
char period_path[50];
|
||||
char duty_path[50];
|
||||
char enable_path[50];
|
||||
char polarity_path[55];
|
||||
int period_fd, duty_fd, polarity_fd;
|
||||
int period_fd, duty_fd, polarity_fd, enable_fd;
|
||||
struct pwm_exp *new_pwm, *pwm;
|
||||
|
||||
if(!pwm_initialized) {
|
||||
@ -180,23 +216,31 @@ int pwm_start(const char *key, float duty, float freq, int polarity)
|
||||
snprintf(pwm_base_path, sizeof(pwm_base_path), "/sys/class/pwm/pwmchip0/%d", "pwm0");
|
||||
|
||||
//create the path for the period and duty
|
||||
snprintf(enable_path, sizeof(enable_path), "%s/enable", pwm_base_path);
|
||||
snprintf(period_path, sizeof(period_path), "%s/period", pwm_base_path);
|
||||
snprintf(duty_path, sizeof(duty_path), "%s/duty", pwm_base_path);
|
||||
snprintf(duty_path, sizeof(duty_path), "%s/duty_cycle", pwm_base_path);
|
||||
snprintf(polarity_path, sizeof(polarity_path), "%s/polarity", pwm_base_path);
|
||||
|
||||
//add period and duty fd to pwm list
|
||||
if ((period_fd = open(period_path, O_RDWR)) < 0)
|
||||
if ((enable_fd = open(enable_path, O_RDWR)) < 0)
|
||||
return -1;
|
||||
|
||||
if ((period_fd = open(period_path, O_RDWR)) < 0) {
|
||||
close(enable_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((duty_fd = open(duty_path, O_RDWR)) < 0) {
|
||||
//error, close already opened period_fd.
|
||||
close(enable_fd);
|
||||
close(period_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((polarity_fd = open(polarity_path, O_RDWR)) < 0) {
|
||||
//error, close already opened period_fd and duty_fd.
|
||||
close(enable_fd);
|
||||
close(period_fd);
|
||||
close(duty_fd);
|
||||
return -1;
|
||||
@ -213,6 +257,7 @@ int pwm_start(const char *key, float duty, float freq, int polarity)
|
||||
new_pwm->period_fd = period_fd;
|
||||
new_pwm->duty_fd = duty_fd;
|
||||
new_pwm->polarity_fd = polarity_fd;
|
||||
new_pwm->enable_fd = enable_fd;
|
||||
new_pwm->next = NULL;
|
||||
|
||||
if (exported_pwms == NULL)
|
||||
@ -229,6 +274,7 @@ int pwm_start(const char *key, float duty, float freq, int polarity)
|
||||
|
||||
pwm_set_frequency(key, freq);
|
||||
pwm_set_polarity(key, polarity);
|
||||
pwm_set_enable(key, 1);
|
||||
pwm_set_duty_cycle(key, duty);
|
||||
|
||||
return 1;
|
||||
@ -245,6 +291,12 @@ int pwm_disable(const char *key)
|
||||
// we need to export 0 here to enable pwm0
|
||||
int gpio = 0;
|
||||
|
||||
// Disable the PWM
|
||||
pwm_set_frequency(key, 0);
|
||||
pwm_set_polarity(key, 0);
|
||||
pwm_set_enable(key, 0);
|
||||
pwm_set_duty_cycle(key, 0);
|
||||
|
||||
if ((fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY)) < 0)
|
||||
{
|
||||
return -1;
|
||||
@ -260,6 +312,7 @@ int pwm_disable(const char *key)
|
||||
if (strcmp(pwm->key, key) == 0)
|
||||
{
|
||||
//close the fd
|
||||
close(pwm->enable_fd);
|
||||
close(pwm->period_fd);
|
||||
close(pwm->duty_fd);
|
||||
close(pwm->polarity_fd);
|
||||
|
@ -33,4 +33,5 @@ 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_duty_cycle(const char *key, float duty);
|
||||
int pwm_set_enable(const char *key, int enable);
|
||||
void pwm_cleanup(void);
|
||||
|
@ -121,19 +121,19 @@ pins_t table[] = {
|
||||
{ "TWI2-SDA", "U14_25", 50, -1, -1},
|
||||
{ "TWI2-SCK", "U14_26", 49, -1, -1},
|
||||
{ "CSIPCK", "U14_27", 128, -1, -1},
|
||||
{ "CSICK", "U14_28", 129, 4, -1},
|
||||
{ "CSICK", "U14_28", 129, -1, -1},
|
||||
{ "CSIHSYNC", "U14_29", 130, 1, -1},
|
||||
{ "CSIVSYNC", "U14_30", 131, -1, -1},
|
||||
{ "CSID0", "U14_31", 132, 1, -1},
|
||||
{ "CSID1", "U14_32", 133, -1, -1},
|
||||
{ "CSID2", "U14_33", 134, -1, 4},
|
||||
{ "CSID2", "U14_33", 134, -1, -1},
|
||||
{ "CSID3", "U14_34", 135, -1, -1},
|
||||
{ "CSID4", "U14_35", 136, -1, 6},
|
||||
{ "CSID5", "U14_36", 137, -1, 5},
|
||||
{ "CSID6", "U14_37", 138, -1, 2},
|
||||
{ "CSID7", "U14_38", 139, -1, 3},
|
||||
{ "GND", "U14_39", 0, -1, 0},
|
||||
{ "GND", "U14_40", 0, -1, 1},
|
||||
{ "CSID4", "U14_35", 136, -1, -1},
|
||||
{ "CSID5", "U14_36", 137, -1, -1},
|
||||
{ "CSID6", "U14_37", 138, -1, -1},
|
||||
{ "CSID7", "U14_38", 139, -1, -1},
|
||||
{ "GND", "U14_39", 0, -1, -1},
|
||||
{ "GND", "U14_40", 0, -1, -1},
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
|
@ -76,6 +76,6 @@ void define_constants(PyObject *module)
|
||||
both_edge = Py_BuildValue("i", BOTH_EDGE);
|
||||
PyModule_AddObject(module, "BOTH", both_edge);
|
||||
|
||||
version = Py_BuildValue("s", "0.0.4");
|
||||
version = Py_BuildValue("s", "0.0.6");
|
||||
PyModule_AddObject(module, "VERSION", version);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class TestPwmSetup:
|
||||
pwm_test = '/sys/class/pwm/pwmchip0/pwm0'
|
||||
|
||||
assert os.path.exists(pwm_test)
|
||||
duty = open(pwm_test + '/duty').read()
|
||||
duty = open(pwm_test + '/duty_cycle').read()
|
||||
period = open(pwm_test + '/period').read()
|
||||
assert int(duty) == 0
|
||||
assert int(period) == 500000
|
||||
@ -25,12 +25,12 @@ class TestPwmSetup:
|
||||
pwm_test = '/sys/class/pwm/pwmchip0/pwm0'
|
||||
|
||||
assert os.path.exists(pwm_test)
|
||||
duty = open(pwm_test + '/duty').read()
|
||||
duty = open(pwm_test + '/duty_cycle').read()
|
||||
period = open(pwm_test + '/period').read()
|
||||
polarity = open(pwm_test + '/polarity').read()
|
||||
assert int(duty) == 0
|
||||
assert int(period) == 500000
|
||||
assert int(polarity) == 1
|
||||
assert string(polarity) == "inverted"
|
||||
PWM.cleanup()
|
||||
|
||||
def test_start_pwm_with_polarity_default(self):
|
||||
@ -39,12 +39,12 @@ class TestPwmSetup:
|
||||
pwm_test = '/sys/class/pwm/pwmchip0/pwm0'
|
||||
|
||||
assert os.path.exists(pwm_test)
|
||||
duty = open(pwm_test + '/duty').read()
|
||||
duty = open(pwm_test + '/duty_cycle').read()
|
||||
period = open(pwm_test + '/period').read()
|
||||
polarity = open(pwm_test + '/polarity').read()
|
||||
assert int(duty) == 0
|
||||
assert int(period) == 500000
|
||||
assert int(polarity) == 0
|
||||
assert string(polarity) == "normal"
|
||||
PWM.cleanup()
|
||||
|
||||
def test_start_pwm_with_polarity_zero(self):
|
||||
@ -53,12 +53,12 @@ class TestPwmSetup:
|
||||
pwm_test = '/sys/class/pwm/pwmchip0/pwm0'
|
||||
|
||||
assert os.path.exists(pwm_test)
|
||||
duty = open(pwm_test + '/duty').read()
|
||||
duty = open(pwm_test + '/duty_cycle').read()
|
||||
period = open(pwm_test + '/period').read()
|
||||
polarity = open(pwm_test + '/polarity').read()
|
||||
assert int(duty) == 0
|
||||
assert int(period) == 500000
|
||||
assert int(polarity) == 0
|
||||
assert string(polarity) == "normal"
|
||||
PWM.cleanup()
|
||||
|
||||
def test_pwm_start_invalid_pwm_key(self):
|
||||
@ -113,13 +113,13 @@ class TestPwmSetup:
|
||||
pwm_test = '/sys/class/pwm/pwmchip0/pwm0'
|
||||
|
||||
assert os.path.exists(pwm_test)
|
||||
duty = open(pwm_test + '/duty').read()
|
||||
duty = open(pwm_test + '/duty_cycle').read()
|
||||
period = open(pwm_test + '/period').read()
|
||||
assert int(duty) == 0
|
||||
assert int(period) == 500000
|
||||
|
||||
PWM.set_duty_cycle("PWM0", 100)
|
||||
duty = open(pwm_test + '/duty').read()
|
||||
duty = open(pwm_test + '/duty_cycle').read()
|
||||
period = open(pwm_test + '/period').read()
|
||||
assert int(duty) == 500000
|
||||
assert int(period) == 500000
|
||||
|
Reference in New Issue
Block a user