Exemple #1
0
BBIO_err pwm_set_duty_cycle(const char *key, float duty) {
    int len;
    char buffer[20];
    struct pwm_exp *pwm;

    if (duty < 0.0 || duty > 100.0)
        return BBIO_INVARG;

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_duty_cycle: %s couldn't find key", key);
        return BBIO_GEN;
    }

    pwm->duty = duty;
    pwm->duty_ns = (unsigned long)(pwm->period_ns * (duty / 100.0));

    len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty_ns);
    lseek(pwm->duty_fd, 0, SEEK_SET); // Seek to beginning of file
    if (write(pwm->duty_fd, buffer, len) < 0) {
        syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_duty_cycle: %s couldn't write duty: %i-%s",
               key, errno, strerror(errno));
        return BBIO_SYSFS;
    }

    syslog(LOG_DEBUG, "Adafruit_BBIO: pwm_set_duty_cycle: %s %f OK", key, duty);
    return BBIO_OK;
}
Exemple #2
0
int pwm_set_frequency(const char *key, float freq) {
    int len;
    char buffer[20];
    unsigned long period_ns;
    struct pwm_exp *pwm;

    if (freq <= 0.0)
        return -1;

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        return -1;
    }

    period_ns = (unsigned long)(1e9 / freq);

    if (period_ns != pwm->period_ns) {
        pwm->period_ns = period_ns;

        len = snprintf(buffer, sizeof(buffer), "%lu", period_ns);
        write(pwm->period_fd, buffer, len);
    }

    return 1;
}
Exemple #3
0
int pwm_set_polarity(const char *key, int polarity) {
    int len;
    char buffer[7]; /* allow room for trailing NUL byte */
    struct pwm_exp *pwm;

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        return -1;
    }

    len = snprintf(buffer, sizeof(buffer), "%d", polarity);
    write(pwm->polarity_fd, buffer, len);

    return 0;
}
Exemple #4
0
int softpwm_set_frequency(const char *key, float freq) {
    struct softpwm *pwm;

    if (freq <= 0.0)
        return -1;

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        return -1;
    }

    pthread_mutex_lock(pwm->params_lock);
    pwm->params.freq = freq;
    pthread_mutex_unlock(pwm->params_lock);

    return 0;
}
Exemple #5
0
int softpwm_set_duty_cycle(const char *key, float duty) {;
    struct softpwm *pwm;

    if (duty < 0.0 || duty > 100.0)
        return -1;

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        return -1;
    }

    pthread_mutex_lock(pwm->params_lock);
    pwm->params.duty = duty;
    pthread_mutex_unlock(pwm->params_lock);

    return 0;
}
Exemple #6
0
int softpwm_set_polarity(const char *key, int polarity) {
    struct softpwm *pwm;

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        return -1;
    }

    if (polarity < 0 || polarity > 1) {
        return -1;
    }

    pthread_mutex_lock(pwm->params_lock);
    pwm->params.polarity = polarity;
    pthread_mutex_unlock(pwm->params_lock);

    return 0;
}
Exemple #7
0
int pwm_set_duty_cycle(const char *key, float duty) {
    int len;
    char buffer[20];
    struct pwm_exp *pwm;

    if (duty < 0.0 || duty > 100.0)
        return -1;

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        return -1;
    }    

    pwm->duty = (unsigned long)(pwm->period_ns * (duty / 100.0));

    len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty);
    write(pwm->duty_fd, buffer, len);

    return 0;
}
Exemple #8
0
// Only works before chip is enabled
BBIO_err pwm_set_polarity(const char *key, int polarity) {
    int len;
    char buffer[9]; /* allow room for trailing NUL byte */
    struct pwm_exp *pwm;
#ifdef BBBVERSION41
    int enabled; /* Maintain original state */
#endif

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_polarity: %s couldn't find key", key);
        return BBIO_GEN;
    }

    // polarity can't be changed with enabled.
#ifdef BBBVERSION41
    // Read the current enabled status
    len = 1;
    memset(buffer, 0, 9);  // Initialize buffer
    lseek(pwm->enable_fd, 0, SEEK_SET);
    if (read(pwm->enable_fd, buffer, len) < 0) {
        syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_polarity: %s couldn't read enable: %i-%s",
               key, errno, strerror(errno));
        return BBIO_SYSFS;
    }

    // If the PWM is enabled, disable it
    // Can't set the polarity with device enabled
    // It will be reenabled after the parameters are set
    if (buffer[0] == '1') {
        enabled = 1;
        lseek(pwm->enable_fd, 0, SEEK_SET);
        len = snprintf(buffer, sizeof(buffer), "0");
        if (write(pwm->enable_fd, buffer, len) < 0) {
            syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_polarity: %s couldn't write enable: %i-%s",
                   key, errno, strerror(errno));
            return BBIO_SYSFS;
        }
    }

    // Treating 0 as normal, 1 as inversed
    // See documentation of sysfs interface at
    // https://www.kernel.org/doc/Documentation/pwm.txt
    if (polarity == 0) {
        len = snprintf(buffer, sizeof(buffer), "normal");
    } else if (polarity == 1) {
        len = snprintf(buffer, sizeof(buffer), "inversed");
    } else {
        syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_polarity: %s invalid argument value: %i", key, polarity);
        return BBIO_INVARG;
    }
#else
    len = snprintf(buffer, sizeof(buffer), "%d", polarity);
#endif

    lseek(pwm->polarity_fd, 0, SEEK_SET); // Seek to beginning of file
    if (write(pwm->polarity_fd, buffer, len) < 0) {
        syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_polarity: %s couldn't write polarity: %i-%s",
               key, errno, strerror(errno));
        return BBIO_SYSFS;
    }

    /* If we were enabled before, restore state */
#ifdef BBBVERSION41
    if (enabled) {
        lseek(pwm->enable_fd, 0, SEEK_SET);
        len = snprintf(buffer, sizeof(buffer), "1");
        if (write(pwm->enable_fd, buffer, len) < 0) {
            syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_polarity: %s couldn't write enable: %i-%s",
                   key, errno, strerror(errno));
            return BBIO_SYSFS;
        }
    }
#endif

    syslog(LOG_DEBUG, "Adafruit_BBIO: pwm_set_polarity: %s %i OK", key, polarity);
    return BBIO_OK;
}
Exemple #9
0
BBIO_err initialize_pwm(void)
{
#ifdef BBBVERSION41  // don't load overlay in 4.1+
    if (!pwm_initialized) {
      strncpy(ocp_dir, "/sys/devices/platform/ocp", sizeof(ocp_dir));
#else
    BBIO_err err;
    if  (!pwm_initialized && load_device_tree("am33xx_pwm")) {
        err = build_path("/sys/devices", "ocp", ocp_dir, sizeof(ocp_dir));
        if (err != BBIO_OK)
        {
            return BBIO_SYSFS;
        }
#endif
        pwm_initialized = 1;
        #ifdef DEBUGINFO
        syslog(LOG_DEBUG, "Adafruit_BBIO: initialize_pwm: OK");
        #endif
        return BBIO_OK;
    }
    #ifdef DEBUGINFO
    syslog(LOG_DEBUG, "Adafruit_BBIO: initialize_pwm: OK");
    #endif

    return BBIO_OK;
}

BBIO_err pwm_set_frequency(const char *key, float freq) {
    int len;
    char buffer[20];
    unsigned long period_ns;
    struct pwm_exp *pwm;

    if (freq <= 0.0) {
        #ifdef DEBUGINFO
        syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_frequency: %s freq %f <= 0.0", key, freq);
        #endif
        return BBIO_INVARG;
    }

    pwm = lookup_exported_pwm(key);

    if (pwm == NULL) {
        #ifdef DEBUGINFO
        syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_frequency: %s couldn't find key", key);
        #endif
        return BBIO_GEN;
    }

    period_ns = (unsigned long)(1e9 / freq);

    // If we're going to a shorter period, update the
    // duty cycle first, in order to avoid ever setting
    // the period < duty cycle (which would throw error)
    if (period_ns < pwm->period_ns) {
        pwm->period_ns = period_ns;

        // Update duty ns
        pwm->duty_ns = (unsigned long)(period_ns * (pwm->duty / 100.0));
        len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty_ns);
        lseek(pwm->duty_fd, 0, SEEK_SET); // Seek to beginning of file
        if (write(pwm->duty_fd, buffer, len) < 0) {
            syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_frequency: %s couldn't write duty: %i-%s",
                   key, errno, strerror(errno));
            return BBIO_SYSFS;
        }

        // Update period ns
        len = snprintf(buffer, sizeof(buffer), "%lu", period_ns);
        lseek(pwm->period_fd, 0, SEEK_SET); // Seek to beginning of file
        if (write(pwm->period_fd, buffer, len) < 0) {
            syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_frequency: %s couldn't write period: %i-%s",
                   key, errno, strerror(errno));
            return BBIO_SYSFS;
        }

    } else if (period_ns > pwm->period_ns) {
        pwm->period_ns = period_ns;
        // Ordinarily update the period first,
        // to avoid the opposite bug - kernel won't
        // let us set duty greater than period

        // Update period ns
        len = snprintf(buffer, sizeof(buffer), "%lu", period_ns);
        lseek(pwm->period_fd, 0, SEEK_SET); // Seek to beginning of file
        if (write(pwm->period_fd, buffer, len) < 0) {
            syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_frequency: %s couldn't write period: %i-%s",
                   key, errno, strerror(errno));
            return BBIO_SYSFS;
        }

        // Update duty ns
        pwm->duty_ns = (unsigned long)(period_ns * (pwm->duty / 100.0));
        len = snprintf(buffer, sizeof(buffer), "%lu", pwm->duty_ns);
        lseek(pwm->duty_fd, 0, SEEK_SET); // Seek to beginning of file
        if (write(pwm->duty_fd, buffer, len) < 0) {
            syslog(LOG_ERR, "Adafruit_BBIO: pwm_set_frequency: %s couldn't write duty: %i-%s",
                   key, errno, strerror(errno));
            return BBIO_SYSFS;
        }
    } // else do nothing

    syslog(LOG_DEBUG, "Adafruit_BBIO: pwm_set_frequency: %s %f OK", key, freq);
    return BBIO_OK;
}