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:
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user