#!/usr/bin/bash ### # # Options Section # ### set -e set -o pipefail ### # # Variable Section # ### CURRENT_DUTY_CYCLE='-1' PWM_CHIP_PATH='/sys/class/pwm/pwmchip0' ### # # Function Section # ### function num_compare () { /usr/bin/mawk "BEGIN {exit !($*)}" } function pwm_get_chip_path () { local SUB_PATH="${1}" if [ -n "${SUB_PATH}" ]; then /usr/bin/echo "${PWM_CHIP_PATH}/${SUB_PATH}" else /usr/bin/echo "${PWM_CHIP_PATH}" fi } function pwm_get_channel_path () { local CHANNEL="${1}" local SUB_PATH="${2}" local PWM_PATH="${PWM_CHIP_PATH}/pwm${CHANNEL}" if [ -n "${SUB_PATH}" ]; then /usr/bin/echo "${PWM_PATH}/${SUB_PATH}" else /usr/bin/echo "${PWM_PATH}" fi } function pwm_create () { local CHANNEL="${1}" PWM_CHANNEL_PATH="$(pwm_get_channel_path "${CHANNEL}")" if [[ ! -d "${PWM_CHANNEL_PATH}" ]]; then /usr/bin/echo "${CHANNEL}" > "$(pwm_get_chip_path 'export')" fi } function frequency_to_period () { local FREQUENCY="${1}" PERC=$(/usr/bin/mawk -v freq="${FREQUENCY}" 'BEGIN { printf "%.0f", 1 / freq * 1000 * 1000000; exit(0) }') /usr/bin/echo "${PERC}" } function pwm_change_duty_cycle () { local CHANNEL="${1}" local FREQUENCY="${2}" local DUTY_CYCLE="${3}" if [[ "${DUTY_CYCLE}" -lt '0' ]] || [[ "${DUTY_CYCLE}" -gt '100' ]]; then return 1 fi PERIOD=$(frequency_to_period "${FREQUENCY}") NEW_DUTY_CYCLE=$(/usr/bin/mawk -v period="${PERIOD}" -v dc="${DUTY_CYCLE}" 'BEGIN { printf "%.0f", period * dc / 100; exit(0) }') /usr/bin/echo "${NEW_DUTY_CYCLE}" > "$(pwm_get_channel_path "${CHANNEL}" 'duty_cycle')" } function pwm_change_frequency () { local CHANNEL="${1}" local FREQUENCY="${2}" if num_compare "${FREQUENCY} < 0.1"; then return 1 fi if [[ "${CURRENT_DUTY_CYCLE}" == '-1' ]]; then CURRENT_DUTY_CYCLE='0' elif [[ "${CURRENT_DUTY_CYCLE}" -gt '0' ]]; then pwm_change_duty_cycle "${CHANNEL}" "${FREQUENCY}" '0' fi PERIOD=$(frequency_to_period "${FREQUENCY}") /usr/bin/echo "${PERIOD}" > "$(pwm_get_channel_path "${CHANNEL}" 'period')" pwm_change_duty_cycle "${CHANNEL}" "${FREQUENCY}" "${CURRENT_DUTY_CYCLE}" } function pwm_start () { local CHANNEL="${1}" /usr/bin/echo '1' > "$(pwm_get_channel_path "${CHANNEL}" 'enable')" } function pwm_stop () { local CHANNEL="${1}" /usr/bin/echo "${CHANNEL}" > "$(pwm_get_chip_path 'unexport')" } function pwm_init () { local CHANNEL="${1}" local FREQUENCY="${2}" if [[ ! -d "${PWM_CHIP_PATH}" ]]; then exit 1 fi if [[ ! -w "$(pwm_get_chip_path 'export')" ]]; then exit 1 fi if [[ "${CHANNEL}" != '0' ]] && [[ "${CHANNEL}" != '1' ]]; then exit 1 fi pwm_create "${CHANNEL}" pwm_change_frequency "${CHANNEL}" "${FREQUENCY}" pwm_start "${CHANNEL}" } function get_temp () { RAW_TEMP="$(/usr/bin/cat '/sys/class/thermal/thermal_zone0/temp')" TEMP="$(/usr/bin/mawk -v temp="${RAW_TEMP}" 'BEGIN { printf "%0.2f", temp / 1000; exit(0) }')" /usr/bin/echo "${TEMP}" } ### # # Runtime Environment # ### trap "pwm_stop '0'" EXIT pwm_init '0' '2000' while true; do TEMP="$(get_temp)" DUTY_CYCLE='0' printf -v 'CUR_TEMP' %0.0f "${TEMP}" if [[ "${CUR_TEMP}" -ge '70' ]]; then DUTY_CYCLE='100' elif [[ "${CUR_TEMP}" -ge '60' ]]; then DUTY_CYCLE='75' elif [[ "${CUR_TEMP}" -ge '50' ]]; then DUTY_CYCLE='50' elif [[ "${CUR_TEMP}" -ge '25' ]]; then DUTY_CYCLE='40' fi if [[ "${DUTY_CYCLE}" != "${CURRENT_DUTY_CYCLE}" ]]; then pwm_change_duty_cycle '0' '2000' "${DUTY_CYCLE}" CURRENT_DUTY_CYCLE="${DUTY_CYCLE}" fi /usr/bin/sleep '15s' done