From 82d6fef1731dff16e1578f8a106d8639eb834a7e Mon Sep 17 00:00:00 2001 From: Robert Wolterman Date: Sat, 24 Sep 2016 14:22:05 -0500 Subject: [PATCH] checking in debug stuff for the hw pwm issue #17 --- source/c_pwm.c | 98 +++++++++++++++++++++++++++++++----------- source/common.c | 2 + test/pwmtest.py | 97 +++++++++++++++++++++++++++++++++++++++++ test/test_pwm_setup.py | 52 ++++++++++++++++++++++ 4 files changed, 223 insertions(+), 26 deletions(-) create mode 100755 test/pwmtest.py diff --git a/source/c_pwm.c b/source/c_pwm.c index bbd86b0..fdf689e 100644 --- a/source/c_pwm.c +++ b/source/c_pwm.c @@ -84,12 +84,14 @@ int initialize_pwm(void) // we need to export 0 here to enable pwm0 int gpio = 0; + printf(" ** EXPORTING PWM0 **\n"); if ((fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY)) < 0) { return -1; } - len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); BUF2SMALL(str_gpio); - ssize_t s = write(fd, str_gpio, len); ASSRT(s == len); + len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); //BUF2SMALL(str_gpio); + ssize_t s = write(fd, str_gpio, len); //ASSRT(s == len); + printf(" ** IN initialize_pwm: s = %d, len = %d\n", s, len); close(fd); pwm_initialized = 1; @@ -116,11 +118,14 @@ int pwm_set_frequency(const char *key, float freq) { period_ns = (unsigned long)(1e9 / freq); + 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); - ssize_t s = write(pwm->period_fd, buffer, len); ASSRT(s == len); + len = snprintf(buffer, sizeof(buffer), "%lu", period_ns); //BUF2SMALL(buffer); + printf(" ** pwm_set_frequency: buffer: %s\n", buffer); + ssize_t s = write(pwm->period_fd, buffer, len); //ASSRT(s == len); + printf(" ** IN pwm_set_frequency: s = %d, len = %d\n", s, len); } return 1; @@ -141,14 +146,17 @@ int pwm_set_polarity(const char *key, int polarity) { return -1; } + printf(" ** IN pwm_set_polarity: pwm_initialized = %d\n", pwm_initialized); if (polarity == 0) { - len = snprintf(buffer, sizeof(buffer), "%s", "normal"); BUF2SMALL(buffer); + len = snprintf(buffer, sizeof(buffer), "%s", "normal"); //BUF2SMALL(buffer); } else { - len = snprintf(buffer, sizeof(buffer), "%s", "inverted"); BUF2SMALL(buffer); + len = snprintf(buffer, sizeof(buffer), "%s", "inverted"); //BUF2SMALL(buffer); } - ssize_t s = write(pwm->polarity_fd, buffer, len); ASSRT(s == len); + 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; } @@ -169,8 +177,11 @@ int pwm_set_duty_cycle(const char *key, float duty) { pwm->duty = (unsigned long)(pwm->period_ns * (duty / 100.0)); - len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty); BUF2SMALL(buffer); - ssize_t s = write(pwm->duty_fd, buffer, len); ASSRT(s == len); + printf(" ** IN pwm_set_duty_cycle: pwm_initialized = %d\n", pwm_initialized); + len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty); //BUF2SMALL(buffer); + printf(" ** pwm_set_duty_cycle: buffer: %s\n", buffer); + ssize_t s = write(pwm->duty_fd, buffer, len); //ASSRT(s == len); + printf(" ** IN pwm_set_duty_cycle: s = %d, len = %d\n", s, len); return 0; } @@ -178,24 +189,37 @@ int pwm_set_duty_cycle(const char *key, float duty) { int pwm_set_enable(const char *key, int enable) { int len; + int rtnval = -1; char buffer[80]; struct pwm_exp *pwm; if (enable != 0 || enable != 1) - return -1; + return rtnval; pwm = lookup_exported_pwm(key); if (pwm == NULL) { - return -1; + return rtnval; } - pwm->enable = enable; + //pwm->enable = enable; - len = snprintf(buffer, sizeof(buffer), "%d", pwm->enable); BUF2SMALL(buffer); - ssize_t s = write(pwm->enable_fd, buffer, len); ASSRT(s == len); + printf(" ** IN pwm_set_enable: pwm_initialized = %d\n", pwm_initialized); + 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); + printf(" ** IN pwm_set_enable: s = %d, len = %d\n", s, len); - return 0; + //if (s == len) + //{ + printf(" ** SETTING pwm->enable to %d\n", enable); + pwm->enable = enable; + rtnval = 0; + //} else { + // rtnval = -1; + //} + + return rtnval; } int pwm_start(const char *key, float duty, float freq, int polarity) @@ -208,18 +232,26 @@ int pwm_start(const char *key, float duty, float freq, int polarity) int period_fd, duty_fd, polarity_fd, enable_fd; struct pwm_exp *new_pwm, *pwm; + printf(" ** IN pwm_start: pwm_initialized = %d\n", pwm_initialized); if(!pwm_initialized) { initialize_pwm(); } + printf(" ** IN pwm_start: pwm_initialized = %d\n", pwm_initialized); //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); //create the path for the period and duty - 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(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(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(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); + + printf(" ** IN pwm_start: pwm_base_path: %s\n", pwm_base_path); + printf(" ** IN pwm_start: enable_path: %s\n", enable_path); + printf(" ** IN pwm_start: period_path: %s\n", period_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 if ((enable_fd = open(enable_path, O_RDWR)) < 0) @@ -230,7 +262,6 @@ int pwm_start(const char *key, float duty, float freq, int polarity) return -1; } - if ((duty_fd = open(duty_path, O_RDWR)) < 0) { //error, close already opened period_fd. close(enable_fd); @@ -252,6 +283,7 @@ int pwm_start(const char *key, float duty, float freq, int polarity) return -1; // out of memory } + 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 */ new_pwm->key[KEYLEN] = '\0'; /* terminate string */ new_pwm->period_fd = period_fd; @@ -272,11 +304,25 @@ int pwm_start(const char *key, float duty, float freq, int polarity) pwm->next = new_pwm; } - pwm_set_frequency(key, freq); - pwm_set_polarity(key, polarity); - pwm_set_enable(key, 1); - pwm_set_duty_cycle(key, duty); + printf(" ** IN pwm_start: CALLING THE SET FUNCTIONS **\n"); + int rtnval = 0; + rtnval = pwm_set_enable(key, 1); + printf(" ** pwm_set_enable rtnval = %d\n", rtnval); + rtnval = 0; + rtnval = pwm_set_frequency(key, freq); + printf(" ** pwm_set_frequency rtnval = %d\n", rtnval); + rtnval = 0; + rtnval = pwm_set_polarity(key, polarity); + printf(" ** pwm_set_polarity rtnval = %d\n", rtnval); + //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); + printf(" ** pwm_set_duty_cycle rtnval = %d\n", rtnval); + rtnval = 0; + // TODO: SET RETURN BASED UPON 4 FUNCTIONS ABOVE return 1; } @@ -300,8 +346,8 @@ int pwm_disable(const char *key) { return -1; } - len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); BUF2SMALL(str_gpio); - ssize_t s = write(fd, str_gpio, len); ASSRT(s == len); + len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio); //BUF2SMALL(str_gpio); + ssize_t s = write(fd, str_gpio, len); //ASSRT(s == len); close(fd); // remove from list diff --git a/source/common.c b/source/common.c index 6441f7b..49055a9 100644 --- a/source/common.c +++ b/source/common.c @@ -352,10 +352,12 @@ int get_pwm_key_by_name(const char *name, char *key) pins_t *p; for (p = pins_info; p->name != NULL; ++p) { if (strcmp(p->name, name) == 0) { + printf("## FOUND PWM KEY, VALIDATING MUX MODE ##\n"); //validate it's a valid pwm pin if (p->pwm_mux_mode == -1) return 0; + printf("## PWM KEY IS VALID ##\n"); strncpy(key, p->key, 7); key[7] = '\0'; return 1; diff --git a/test/pwmtest.py b/test/pwmtest.py new file mode 100755 index 0000000..9140af1 --- /dev/null +++ b/test/pwmtest.py @@ -0,0 +1,97 @@ +#!/usr/bin/python + +import CHIP_IO.PWM as PWM +import CHIP_IO.GPIO as GPIO +import CHIP_IO.OverlayManager as OM +import time +import datetime +import threading + +class PWMReceiver(threading.Thread): + def __init__(self,gpio,key,maxcount=20,sleeptime=0.5): + self.gpio = gpio + self.key = key + self.counter = 0 + self.maxcount = maxcount + self.sleeptime = sleeptime + threading.Thread.__init__(self) + + def run(self): + print("SETTING UP RECEIVER GPIO") + self.gpio.cleanup() + self.gpio.setup(self.key, self.gpio.IN) + print("STARTING RECEIVE LOOP") + try: + while self.counter < self.maxcount: + pwmval = self.gpio.input(self.key) + print("PWM VALUE: {0} @ {1}".format(pwmval, datetime.datetime.now())) + time.sleep(self.sleeptime) + self.counter += 1 + except KeyboardInterrupt: + self.gpio.cleanup(self.key) + +def PrintPwmData(): + print("PRINTING PWM SYSFS DATA") + f = open("/sys/class/pwm/pwmchip0/pwm0/enable") + print("PWM0 ENABLE:\t{}".format(f.readline())) + f.close() + f = open("/sys/class/pwm/pwmchip0/pwm0/period") + print("PWM0 PERIOD:\t{}".format(f.readline())) + f.close() + f = open("/sys/class/pwm/pwmchip0/pwm0/duty_cycle") + print("PWM0 DUTY CYCLE:\t{}".format(f.readline())) + f.close() + f = open("/sys/class/pwm/pwmchip0/pwm0/polarity") + print("PWM0 POLARITY:\t{}".format(f.readline())) + f.close() + +if __name__ == "__main__": + # SETUP VARIABLES + PWMGPIO = "PWM0" + RECEIVERGPIO = "CSID0" + COUNT = 50 + SLEEPTIME = 0.01 + + # LOAD THE PWM OVERLAY + print("LOADING PWM OVERLAY") + OM.load("PWM0") + + time.sleep(1) + + # CLEANUP THE GPIO + GPIO.cleanup() + PWM.cleanup() + + # SETUP PWM + try: + print("PWM START") + PWM.start(PWMGPIO, 35, 20, 0) + PrintPwmData() + + # UNCOMMENT FOR CRASH + #print("PWM SET FREQUENCY") + #PWM.set_frequency(PWMGPIO, 200) + #PrintPwmData() + + # UNCOMMENT FOR CRASH + #print("PWM SET DUTY CYCLE") + #PWM.set_duty_cycle(PWMGPIO, 25) + #PrintPwmData() + + # SETUP PWM RECEIVER + rcvr = PWMReceiver(GPIO, RECEIVERGPIO, COUNT, SLEEPTIME) + rcvr.start() + + time.sleep(COUNT*SLEEPTIME + 1) + + except: + raise + finally: + # CLEANUP + print("CLEANUP") + PWM.stop(PWMGPIO) + PWM.cleanup() + #OM.unload("PWM0") + GPIO.cleanup() + + diff --git a/test/test_pwm_setup.py b/test/test_pwm_setup.py index 48e0e88..b953e34 100644 --- a/test/test_pwm_setup.py +++ b/test/test_pwm_setup.py @@ -2,12 +2,15 @@ import pytest import os import CHIP_IO.PWM as PWM +import CHIP_IO.OverlayManager as OM def teardown_module(module): PWM.cleanup() + OM.unload("PWM0") class TestPwmSetup: def test_start_pwm(self): + OM.load("PWM0") PWM.start("PWM0", 0) pwm_test = '/sys/class/pwm/pwmchip0/pwm0' @@ -18,8 +21,10 @@ class TestPwmSetup: assert int(duty) == 0 assert int(period) == 500000 PWM.cleanup() + OM.unload("PWM0") def test_start_pwm_with_polarity_one(self): + OM.load("PWM0") PWM.start("PWM0", 0, 2000, 1) pwm_test = '/sys/class/pwm/pwmchip0/pwm0' @@ -32,8 +37,10 @@ class TestPwmSetup: assert int(period) == 500000 assert str(polarity) == "inverted" PWM.cleanup() + OM.unload("PWM0") def test_start_pwm_with_polarity_default(self): + OM.load("PWM0") PWM.start("PWM0", 0, 2000, 0) pwm_test = '/sys/class/pwm/pwmchip0/pwm0' @@ -46,8 +53,10 @@ class TestPwmSetup: assert int(period) == 500000 assert str(polarity) == "normal" PWM.cleanup() + OM.unload("PWM0") def test_start_pwm_with_polarity_zero(self): + OM.load("PWM0") PWM.start("PWM0", 0, 2000, 0) pwm_test = '/sys/class/pwm/pwmchip0/pwm0' @@ -60,54 +69,78 @@ class TestPwmSetup: assert int(period) == 500000 assert str(polarity) == "normal" PWM.cleanup() + OM.unload("PWM0") def test_pwm_start_invalid_pwm_key(self): with pytest.raises(ValueError): + OM.load("PWM0") PWM.start("P8_25", -1) + OM.unload("PWM0") def test_pwm_start_invalid_duty_cycle_negative(self): with pytest.raises(ValueError): + OM.load("PWM0") PWM.start("PWM0", -1) + OM.unload("PWM0") def test_pwm_start_valid_duty_cycle_min(self): #testing an exception isn't thrown + OM.load("PWM0") PWM.start("PWM0", 0) PWM.cleanup() + OM.unload("PWM0") def test_pwm_start_valid_duty_cycle_max(self): #testing an exception isn't thrown + OM.load("PWM0") PWM.start("PWM0", 100) PWM.cleanup() + OM.unload("PWM0") def test_pwm_start_invalid_duty_cycle_high(self): with pytest.raises(ValueError): + OM.load("PWM0") PWM.start("PWM0", 101) + OM.unload("PWM0") def test_pwm_start_invalid_duty_cycle_string(self): with pytest.raises(TypeError): + OM.load("PWM0") PWM.start("PWM0", "1") + OM.unload("PWM0") def test_pwm_start_invalid_frequency_negative(self): with pytest.raises(ValueError): + OM.load("PWM0") PWM.start("PWM0", 0, -1) + OM.unload("PWM0") def test_pwm_start_invalid_frequency_string(self): with pytest.raises(TypeError): + OM.load("PWM0") PWM.start("PWM0", 0, "1") + OM.unload("PWM0") def test_pwm_start_negative_polarity(self): with pytest.raises(ValueError): + OM.load("PWM0") PWM.start("PWM0", 0, 100, -1) + OM.unload("PWM0") def test_pwm_start_invalid_positive_polarity(self): with pytest.raises(ValueError): + OM.load("PWM0") PWM.start("PWM0", 0, 100, 2) + OM.unload("PWM0") def test_pwm_start_invalid_polarity_type(self): with pytest.raises(TypeError): + OM.load("PWM0") PWM.start("PWM0", 0, 100, "1") + OM.unload("PWM0") def test_pwm_duty_modified(self): + OM.load("PWM0") PWM.start("PWM0", 0) pwm_test = '/sys/class/pwm/pwmchip0/pwm0' @@ -124,56 +157,75 @@ class TestPwmSetup: assert int(duty) == 500000 assert int(period) == 500000 PWM.cleanup() + OM.unload("PWM0") def test_pwm_duty_cycle_non_setup_key(self): with pytest.raises(RuntimeError): + OM.load("PWM0") PWM.set_duty_cycle("PWM0", 100) PWM.cleanup() + OM.unload("PWM0") def test_pwm_duty_cycle_invalid_key(self): with pytest.raises(ValueError): + OM.load("PWM0") PWM.set_duty_cycle("P9_15", 100) PWM.cleanup() + OM.unload("PWM0") def test_pwm_duty_cycle_invalid_value_high(self): + OM.load("PWM0") PWM.start("PWM0", 0) with pytest.raises(ValueError): PWM.set_duty_cycle("PWM0", 101) PWM.cleanup() + OM.unload("PWM0") def test_pwm_duty_cycle_invalid_value_negative(self): + OM.load("PWM0") PWM.start("PWM0", 0) with pytest.raises(ValueError): PWM.set_duty_cycle("PWM0", -1) PWM.cleanup() + OM.unload("PWM0") def test_pwm_duty_cycle_invalid_value_string(self): + OM.load("PWM0") PWM.start("PWM0", 0) with pytest.raises(TypeError): PWM.set_duty_cycle("PWM0", "a") PWM.cleanup() + OM.unload("PWM0") def test_pwm_frequency_invalid_value_negative(self): + OM.load("PWM0") PWM.start("PWM0", 0) with pytest.raises(ValueError): PWM.set_frequency("PWM0", -1) PWM.cleanup() + OM.unload("PWM0") def test_pwm_frequency_invalid_value_string(self): + OM.load("PWM0") PWM.start("PWM0", 0) with pytest.raises(TypeError): PWM.set_frequency("PWM0", "11") PWM.cleanup() + OM.unload("PWM0") def test_pwm_freq_non_setup_key(self): with pytest.raises(RuntimeError): + OM.load("PWM0") PWM.set_frequency("PWM0", 100) PWM.cleanup() + OM.unload("PWM0") def test_pwm_freq_non_setup_key(self): with pytest.raises(ValueError): + OM.load("PWM0") PWM.set_frequency("P9_15", 100) PWM.cleanup() + OM.unload("PWM0") def test_stop_pwm(self): pass