2013年8月22日 星期四

控制網樂通LED

昨天早上突然興起要繼續包Archlinux的package,
因為miniDlna相依性太複雜,
先從簡單的ushare開始。


很幸運的發現 make 的參數可以設定要不要支援DLNA,
不支援就可以不用管libdlna了。
因為libdlna需要ffmpeg,
ffmpeg又拖了一大串相依套件。

很高興的編完了 libupnp,
結果sh4twbox的套件庫裡原本就有,
所以又是再做一次蠢事。
之前還有Apach、apr、vsftp等。



編完後用VLC測試、寫wiki
VLC左邊的區域網路選項內有Universal Plug 'n' Play,
ushare設定沒問題就的話,
點這裡就可以看到分享出來的名稱。

因為ushare得要手動重啟動才能更新檔案清單,
試了控制網頁也沒校,
就順手寫了一個紅外線遙控的控制碼,
按鍵一按自動重新啟動和更新清單。

begin
  button = KEY_SEARCH
  prog   = irexec    
  repeat = 0          
  config = killall -9 ushare;ushare -D -p 54321
  flags  = quit                                 
end

之後看到有人提no-ip,
因為我也有在用,(只是現在是留著網址沒實際效用)
Archlinux 剛好也有包裝的設定檔,
不過其中可能因為網樂通上的gcc太舊,
要手動去掉編譯參數中忽略某個warning的項目。
編完又是測試寫Wiki
順利搞定。

下午睡個午覺後,
精神好多了。
開始挖u-boot程式碼,
目標是控制LED。

一開始亂看很沒效率的亂看,
之後在看README時,
花了好長一段時間。
乾脆用搜尋關鍵字,
找到一個超級大檔案board/st/pdk7105/swUpdate.c

前面一大段都沒有看到要的東西,
中間則是這個logo顯示的原始資料,
讓我想到之前在上嵌入式裝置課時,
也是直接將畫面要顯示的圖案一個一個byte輸入。
原本要做菱形,
沒注意到MSB LSB 而變成蘿菠型。
打地鼠就變成拔蘿菠了。

後半段程式終於找到處理LED的。
static void init_led(void)
{    
    set_led_green(0x01);   //close
    set_led_red(0x00);     //open    
}
 追回set_led的函式:
static void set_led_green(int v)
{    
    STPIO_SET_PIN(PIO0_BASSADDRESS,4,v);
}


static void set_led_red(int v)
{    
    STPIO_SET_PIN(PIO0_BASSADDRESS,5,v);
}
#define PIO0_BASSADDRESS  0xFD020000 找出在 io map memory 的位置:0xFD020000 的 pin 4 和 pin 5。
到這裡,最關鍵的已經算完成了。
但是距離完全控制還有好幾個小時。

另外後面還有選擇開機bootenv的程式碼,
和reset 按鈕的處理程式碼,
我應該接下來會試看看reset 按鈕。

吃完晚餐(已經變宵夜了),
看完上週的海賊王( 可惜這週的沒錄到)
接著就開始找 io map memory 在 linux 下要如何控制。
最後在三個地方找到有用的資料:
  1. https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/5/html/Deployment_Guide/s2-proc-iomem.html
  2. https://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gpio-sysfs
  3. http://www.avrfreaks.net/wiki/index.php/Documentation:Linux/GPIO

第一個提到列出io map
# less /proc/iomem
可以確認需要的0xFD020000 在gpiochip0 內。

第二個提示在編kernel時要選
Device Drivers  --->
  [*] GPIO Support  --->
    [*]   /sys/class/gpio/... (sysfs interface)
 
還好這週末編的大雜燴版本有編到,
順利找到要用的 /sys/class/gpio/ 

第三個的 GPIO Numbers 段落有教如何找出需要的 gpio號碼。
產生gpio資料夾:
# echo "4" > /sys/class/gpio/export
# echo "5" > /sys/class/gpio/export
看裡面的value值和現在亮的燈完全符合。
可是direction 是in 讓我有點懷疑。


因為在u-boot程式碼 STPIO_SET_PIN() 中有 1<<(PIN),
所以測試看看pin 5是不是指 gpio32,
結果出現沒這東西的訊息。

所以就直接寫個high到gpio5/direction內,
# echo "high" > /sys/class/gpio/gpio5/direction
看到燈變成紫色超高興的。 
(原本藍色加上紅色)

至於direction的問題,
想到學校上課時,
老師好像有說過控制的 io pin 是負的,
這樣應該就符合狀況了。

接著試試看讓燈熄掉
# echo "in" > /sys/class/gpio/gpio5/direction
就恢復成藍色,
測試藍色亮暗也沒問題,
終於可以安心睡覺了,
程式等早上醒來再寫。
(已經連續兩天超過12點才睡了)

最根本應該是要加到kernel的led之類的項目內,
但是那個工程對目前來說有點浩大。
雖然第3個連結後面有附C程式碼,
不過決定先從簡單的bash script開始。
分成兩個階段,
一個專心控制亮暗,
之後再用另一個處理閃爍或恆亮。
最後附上控制亮暗的bash script內容:
#!/bin/bash
ioroot=/sys/class/gpio
iored=$ioroot/gpio5
ioblue=$ioroot/gpio4
on="high"
off="in"

  cd $ioroot
  #if gpio4 not exist, create it.
  if test ! -d $ioblue; then
    echo "4" > $ioroot/export
  fi

  #if gpio5 not exist, create it.
  if test ! -d $iored; then
    echo "5" > $ioroot/export
  fi

valred=`cat $iored/value`
valblue=`cat $ioblue/value`
  case $1 in
  #red
  "r")
    if test $valred -eq 0; then
      echo $on > $iored/direction
    fi
    if test $valblue -eq 1; then
      echo $off > $ioblue/direction
    fi
    ;;

  #blue
  "b")
    if test $valred -eq 1; then
      echo $off > $iored/direction
    fi
    if test $valblue -eq 0; then
      echo $on > $ioblue/direction
    fi
    ;;

  #purple
   "p")
    if test $valred -eq 0; then
      echo $on > $iored/direction
    fi
    if test $valblue -eq 0; then
      echo $on > $ioblue/direction
    fi
    ;;

  #delete gpio4 gpio5
  "d")
    echo 4 > $ioroot/unexport
    echo 5 > $ioroot/unexport
    ;;
  #off
  "o")
    if test $valred -eq 1; then
      echo $off > $iored/direction
    fi
    if test $valblue -eq 1; then
      echo $off > $ioblue/direction
    fi
    ;;
  *)
    echo "use $0 [r:red/b:blue/p:purple/o:off/d:delete]"
    ;;
  esac

1 則留言: