2410646_en-US

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2410646_en-US

2410646_en-US

user LED control on i.MX93 FRDM board

Hi all,
I started to play with i.MX93 FRDM board and when I wrote a simple script to control RGB LEDs on the board, I've managed to control only Green and Blue LEDs. Red LED stays ON whatever I tried.
Based on the schematics, all leds are connected in a similar manner, so they operate Active High.
Here is my script:

---------------------------

#!/bin/sh

PERIOD=1000000

set_pwm() {
CHIP=$1
CHANNEL=$2
DUTY=$3
PWM_PATH="/sys/class/pwm/pwmchip${CHIP}/pwm${CHANNEL}"

if [ ! -d "$PWM_PATH" ]; then
echo "$CHANNEL" > "/sys/class/pwm/pwmchip${CHIP}/export" 2>/dev/null
fi

# Reset duty cycle to 0 first to satisfy TPM driver constraints
echo 0 > "${PWM_PATH}/duty_cycle" 2>/dev/null
echo "$PERIOD" > "${PWM_PATH}/period"
echo "$DUTY" > "${PWM_PATH}/duty_cycle"
echo 1 > "${PWM_PATH}/enable" 2>/dev/null
}

# Red is Active-Low: Default OFF = 1000000 (3.3V / High)
RED_DUTY=${1:-0}

# Green and Blue are Active-High: Default OFF = 0 (0V / Low)
GREEN_DUTY=${2:-0}
BLUE_DUTY=${3:-0}

# Red -> pwmchip4, Channel 3
set_pwm 4 3 "$RED_DUTY"

# Green -> pwmchip0, Channel 0
set_pwm 0 0 "$GREEN_DUTY"

# Blue -> pwmchip0, Channel 2
set_pwm 0 2 "$BLUE_DUTY"
-------------------------------------------

I've checked that red LED (GPIO_IO13) is allocated to the ledsgrp2:
pin 17 (IMX93_IOMUXC_GPIO_IO13): 424f0000.pwm (GPIO UNCLAIMED) function pinctrl group ledsgrp2

as far as I can see with debugfs commands, the pin GPIO_IO13 is configured for ALT1 mode, which is a TPM2 channel 3 (PWM).

when I run the script, I can successfully control Blue and Green LEDS but Red LED stays ON.

Is there something that I miss?

Re: user LED control on i.MX93 FRDM board

Hi @ilya_chepurin 

The RED LED is channel 2, please use below script to test(verified on L6.18.20)

#!/bin/sh
# RGB LED PWM cycle test for i.MX93 EVK/FRDM.
# Sequence per cycle: RED on 1s -> all off 1s -> GREEN on 1s -> all off 1s -> BLUE on 1s -> all off 1s
# Usage: ./run.sh [LOOPS]        LOOPS: number of full cycles, 0 = infinite, default 3
# Timing overridable via env:    ON_TIME=2 REST_TIME=1 ./run.sh

PERIOD=1000000                 # 1 kHz period in ns
ON_TIME=${ON_TIME:-1}          # seconds a color stays ON
REST_TIME=${REST_TIME:-1}      # seconds all OFF between colors
LOOPS=${1:-3}
RETRIES=50

# Channel mapping and polarity (verified on this board, all ACTIVE-HIGH):
#   Red   -> 424f0000.pwm = pwmchip1 ch2  ON=duty PERIOD  OFF=duty 0
#   Green -> 424e0000.pwm = pwmchip0 ch0  ON=duty PERIOD  OFF=duty 0
#   Blue  -> 424e0000.pwm = pwmchip0 ch2  ON=duty PERIOD  OFF=duty 0
RED_CHIP=1;  RED_CH=2
GRN_CHIP=0;  GRN_CH=0
BLU_CHIP=0;  BLU_CH=2

# write_retry FILE VALUE : write VALUE to FILE, retry on transient TPM busy/-ETIME,
# and confirm the value took effect. Returns 0 on success.
write_retry() {
    t=0
    while [ "$t" -lt "$RETRIES" ]; do
        echo "$2" > "$1" 2>/dev/null
        [ "$(cat "$1" 2>/dev/null)" = "$2" ] && return 0
        t=$((t+1))
    done
    echo "WARN: could not write $2 to $1" >&2
    return 1
}

# init_pwm CHIP CH : export (fresh), set period BEFORE duty, start disabled with duty 0.
# The i.MX TPM shares a counter between channels; a stale export with period=0 makes
# later period writes fail with -EBUSY, so we unexport first for a clean state.
init_pwm() {
    P="/sys/class/pwm/pwmchip${1}"
    [ -d "${P}/pwm${2}" ] && echo "$2" > "${P}/unexport" 2>/dev/null
    echo "$2" > "${P}/export" 2>/dev/null
    write_retry "${P}/pwm${2}/period" "$PERIOD"      # period must be set before duty
    write_retry "${P}/pwm${2}/duty_cycle" 0          # start OFF
    echo 1 > "${P}/pwm${2}/enable" 2>/dev/null
}

set_duty() {   # CHIP CH DUTY
    write_retry "/sys/class/pwm/pwmchip${1}/pwm${2}/duty_cycle" "$3"
}

led() {        # CHIP CH STATE(on|off)  -- all channels active-high
    if [ "$3" = on ]; then set_duty "$1" "$2" "$PERIOD"; else set_duty "$1" "$2" 0; fi
}

all_off() {
    led $RED_CHIP $RED_CH off
    led $GRN_CHIP $GRN_CH off
    led $BLU_CHIP $BLU_CH off
}

# Init: green and blue share pwmchip0, so init green first, then blue.
init_pwm $RED_CHIP $RED_CH
init_pwm $GRN_CHIP $GRN_CH
init_pwm $BLU_CHIP $BLU_CH

trap "all_off; echo; echo interrupted, all LEDs off; exit 0" INT TERM

all_off
echo "start: all OFF"

n=0
while :; do
    c=$((n+1))
    echo "[cycle $c] RED   on";  led $RED_CHIP $RED_CH on;  sleep "$ON_TIME"
    echo "[cycle $c] --- off";   all_off;                  sleep "$REST_TIME"
    echo "[cycle $c] GREEN on";  led $GRN_CHIP $GRN_CH on;  sleep "$ON_TIME"
    echo "[cycle $c] --- off";   all_off;                  sleep "$REST_TIME"
    echo "[cycle $c] BLUE  on";  led $BLU_CHIP $BLU_CH on;  sleep "$ON_TIME"
    echo "[cycle $c] --- off";   all_off;                  sleep "$REST_TIME"

    n=$c
    [ "$LOOPS" -eq 0 ] && continue
    [ "$n" -ge "$LOOPS" ] && break
done

all_off
echo "done ($n cycle(s)), all LEDs off"



Best Regards,
Zhiming

タグ(1)
評価なし
バージョン履歴
最終更新日:
2 週間前
更新者: