From 5fa6f50edccc3835078b56b1caef7e8b2704515b Mon Sep 17 00:00:00 2001 From: Thomas Ingleby Date: Tue, 20 May 2014 13:38:15 +0100 Subject: [PATCH] pwm: added existing exposition logic * Understands when pwm pin is already exported. * Will not unexport if didnt export. Can be forced. Signed-off-by: Thomas Ingleby Signed-off-by: Brendan Le Foll --- api/pwm.h | 18 ++++++++++++++++- api/pwm.hpp | 4 +++- src/pwm/pwm.c | 63 ++++++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/api/pwm.h b/api/pwm.h index 0bf6315..effa8f1 100644 --- a/api/pwm.h +++ b/api/pwm.h @@ -150,8 +150,24 @@ maa_result_t maa_pwm_enable(maa_pwm_context pwm, int enable); */ maa_result_t maa_pwm_unexport(maa_pwm_context pwm); +/** Unexport the PWM context (maa_pwm_close() will call this function) + * Forces operation regardless of ownership. + * + * @param dev The PWM context/ + * + * @return maa result type. + */ +maa_result_t maa_pwm_unexport_force(maa_pwm_context pwm); + +/** Change ownership of context + * + * @param pwm the context + * @param owner ownership , 1 to own + */ +maa_result_t maa_pwm_owner(maa_pwm_context pwm, maa_boolean_t owner); + /** Close and unexport the PWM pin. - * + * * @param pwm The PWM context to use. * * @return maa_result_t the maa result. diff --git a/api/pwm.hpp b/api/pwm.hpp index 9619e5d..2481b63 100644 --- a/api/pwm.hpp +++ b/api/pwm.hpp @@ -36,11 +36,13 @@ namespace maa { class Pwm { public: - Pwm(int pin, int chipid=-1) { + Pwm(int pin, int chipid=-1, bool owner = true) { if (chipid == -1) m_pwm = maa_pwm_init(pin); else m_pwm = maa_pwm_init_raw(pin, chipid); + if (!owner) + maa_pwm_owner(m_pwm, 0); } ~Pwm() { maa_pwm_close(m_pwm); diff --git a/src/pwm/pwm.c b/src/pwm/pwm.c index 1fc65b0..25d1341 100644 --- a/src/pwm/pwm.c +++ b/src/pwm/pwm.c @@ -15,7 +15,7 @@ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND/ + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION @@ -23,10 +23,12 @@ */ #include +#include #include "pwm.h" #define MAX_SIZE 64 +#define SYSFS_PWM "/sys/class/pwm" /** * A structure representing a PWM pin @@ -36,6 +38,7 @@ struct _pwm { int pin; /**< the pin number, as known to the os. */ int chipid; /**< the chip id, which the pwm resides */ int duty_fp; /**< File pointer to duty file */ + maa_boolean_t owner; /**< Owner of pwm context*/ /*@}*/ }; @@ -147,23 +150,33 @@ maa_pwm_init_raw(int chipin, int pin) dev->chipid = chipin; dev->pin = pin; - char buffer[MAX_SIZE]; - snprintf(buffer, MAX_SIZE, "/sys/class/pwm/pwmchip%d/export", dev->chipid); - int export_f = open(buffer, O_WRONLY); - if (export_f == -1) { - fprintf(stderr, "Failed to open export for writing!\n"); - free(dev); - return NULL; - } - - char out[MAX_SIZE]; - int size = snprintf(out, MAX_SIZE, "%d", dev->pin); - if (write(export_f, out, size*sizeof(char)) == -1) { - fprintf(stderr, "Failed to write to export! Potentially already enabled\n"); + char directory[MAX_SIZE]; + snprintf(directory, MAX_SIZE, SYSFS_PWM "/pwmchip%d/pwm%d", dev->chipid, dev->pin); + struct stat dir; + if (stat(directory, &dir) == 0 && S_ISDIR(dir.st_mode)) { + fprintf(stderr, "PWM Pin already exporting, continuing.\n"); + dev->owner = 0; // Not Owner + } else { + char buffer[MAX_SIZE]; + snprintf(buffer, MAX_SIZE, "/sys/class/pwm/pwmchip%d/export", dev->chipid); + int export_f = open(buffer, O_WRONLY); + if (export_f == -1) { + fprintf(stderr, "Failed to open export for writing!\n"); + free(dev); + return NULL; + } + + char out[MAX_SIZE]; + int size = snprintf(out, MAX_SIZE, "%d", dev->pin); + if (write(export_f, out, size*sizeof(char)) == -1) { + fprintf(stderr, "Failed to write to export! Potentially already enabled\n"); + close(export_f); + return NULL; + } + dev->owner = 1; + close(export_f); } - close(export_f); maa_pwm_setup_duty_fp(dev); - return dev; } @@ -248,6 +261,15 @@ maa_pwm_enable(maa_pwm_context dev, int enable) maa_result_t maa_pwm_unexport(maa_pwm_context dev) { + if (dev->owner) { + return maa_pwm_unexport_force(dev); + } + return MAA_ERROR_INVALID_RESOURCE; +} + +maa_result_t +maa_pwm_unexport_force(maa_pwm_context dev) +{ char filepath[MAX_SIZE]; snprintf(filepath, MAX_SIZE, "/sys/class/pwm/pwmchip%d/unexport", dev->chipid); @@ -276,3 +298,12 @@ maa_pwm_close(maa_pwm_context dev) free(dev); return MAA_SUCCESS; } + +maa_result_t +maa_pwm_owner(maa_pwm_context dev, maa_boolean_t owner_new) +{ + if (dev == NULL) + return MAA_ERROR_INVALID_RESOURCE; + dev->owner = owner_new; + return MAA_SUCCESS; +} -- 2.7.4