2008年03月11日

gauche.gongの発表で使ったプレゼン資料等を公開します。


※livedoor Blogの追記欄容量をオーバーするので、この記事は3エントリに分けました。



発表スライドの内容

※会場に向かうタクシーでKeynoteを開いて、楽屋で完成させたもの。
リンクなど追加。

自己紹介

  • naoya_t@生駒山
  • 文系プログラマ
  • 普段は Gauche, AWK, Brainf*ck, ...
  • R5RS > PIC > R6RS
最後のは愛情の大きさ順。 第一部座談会「R6RSを斬る」をスルーしてPICデモコードを書いていた自分を揶揄

事の発端

紫ログによると購入は12/29になっています。gauche.gong当日でPIC歴ちょうど100日!

苦難の道程

  • PICの開発環境一式(MPASM, C, 書き込みアプリ等)がWindows専用。
  • マカーです><
  • → 読み書きはlibusbpk2-3.00αで読み書き出来るよ
  • → asm/disasmぐらい自分で作るか
詳しくは拙エントリ「libusbをインストール」「Mac OS Xから直接PICkit2を読み書きする」を参照のこと

asm/disasm

  • PICkit2 Starter Kitに付いてる PIC16F690 の場合、命令長は14bit固定。命令数も少ないのでdisasmもasmも容易に書ける li>→デブサミ2008会場4FでひげぽんとLiveCoding
ひげぽんとはデブサミ会場でたまたま・・・
コードを見せあったりとかして良い勉強になりました。

どこまで行けるか

  • 時間がとれればSchemeを実装するぐらいは行けそう
  • 時間ない><
  • SICP5章のregister-machineとか?
  • 3軸加速度センサ使いたいけど
Scheme実装のプランはだいぶ出来ていたのですが、実装にとれる時間が限られていて断念。

バイナリデータの処理はR5RSでは処理系依存?

  • Gaucheはバイナリ大丈夫だけど
  • Intel HEX形式を読み書きすればいいのでこの問題はスルー
  • 将来はpk2を使わずに直接読み書き?
これは楽屋のモニタでR6RSが斬られてるのを聞いていて小耳に挟んで

デモその1 - LEDを光らせる

  • 表示デバイスはPICkit2 Starter Kitのボード上のLED(×4)を使う
  • LED点灯用マクロとか書く
webcamのピントが合わなくて、ここで余計な時間をとってしまった><
(そのためのリハーサルですよ!)
(require "./demo-base")

(define code '(
             loop
               (LED #b0000 0.1) ; LEDをパターン0000で0.1秒間点灯する
               (LED #b0001 0.1)
               (LED #b0011 0.1)
               (LED #b0010 0.1)
               (LED #b0110 0.1)
               (LED #b0100 0.1)
               (LED #b1100 0.1)
               (LED #b1000 0.1)
               (LED #b0000 0.1)
               (LED #b1000 0.1)
               (LED #b1100 0.1)
               (LED #b0100 0.1)
               (LED #b0110 0.1)
               (LED #b0010 0.1)
               (LED #b0011 0.1)
               (LED #b0001 0.1)
               (LED #b0000 0.1)

               (goto loop)
               ))

(macro-asm-test code #t #t #t 10)

デモその2 - GCD (最大公約数) を計算し、結果をLEDで2進数表示する

  • LEDが4つしかないので、できれば0〜15で結果が出る演算がいい!
  • fibonacciはどんどん数がでかくなる><
  • GCD(最大公約数)の計算とかどうよ
fibonacciを避ける理由のもう1つ(というかそっちが最大)は、CALLスタックが8段しかないこと。自前で帰り先を積まないといけないのを今回は忌避。
計算結果(デモでは 3)が2進数 0011 で表示されるところで会場が妙に受けていた。
(require "./demo-base")

(define code '(
               (alloc a)
               (alloc b)
               (alloc t)

               (assign a 24)       ; 24と15の最大子役数は?
               (assign b 15)

               ; gcd
             test-b
               (test = b 0)
               (branch gcd-done)   ; goto gcd-done if b == 0
               (assign t a)        ; t = a
             rem-loop
               (test < t b)
               (branch rem-done)   ; goto rem-done if t < b
               (assign t - t b)    ; t = t - b
               (goto rem-loop)
             rem-done

               (assign a b)        ; a = b
               (assign b t)        ; b = t
               (goto test-b)
             gcd-done

               (LED/display-reg a)
               (LED/display-reg a)
               (LED/display-reg a)
               ))

(macro-asm-test code #t #t #t 5)

デモその3 - RA0への電圧入力をA/Dで変換しLED表示。

  • 時間切れ・・・ここまでか?
  • 3軸加速度センサもやりたい
  • 出力を内蔵A/Dコンバータで10bitデジタル値に変換し、上の方のbitを表示、とか
このコードでは上の方のbitを取らず、動かしたらLEDに反応が出るだけ。
Starter Kitボードの配線上、可変抵抗RP1を通した電流との合算値になるので適宜調整しながら。
(require "./demo-base")

(define code '(
             loop
               (a2d)
               ;; デフォルトは RA0 (=AN0) ; = #7
               ;;  // これは可変抵抗RP1との合算なので、可変抵抗で適宜調整
               ;; A/D変換結果の上位8ビットが a2d-upper および Wレジスタに入る
               (ADDLW  #b11100111) ; W -= 11001b
               (MOVWF  display)
               (MOVF   display W)
               (MOVWF  PORTC))
               ;↑すみませんアセンブラ直書きです。インラインアセンブリっぽく
               ;  (asm (ADDLW  #b11100111) ; W -= 11001b
               ;       (MOVWF  display)
               ;       (MOVF   display W)
               ;       (MOVWF  PORTC))
               ;のようにも書けます。でも実は
               ;  (assign display - a2d-upper #b11001)
               ;  (assign PORTC display)
               ;と書けます。
               ;
               (goto loop)
               ))

(macro-asm-test code #t #t #t 60)

あと少しで

  • スタック(save/restore)の実装
  • consセル(Pair)を表現するデータ形式を実装してリスト処理
  • register-machineをフル実装
  • call/ccの実装
目星はついているので、時間が取れ次第書きますよ!>ひげぽんほか

最後に

  • 3月に会社抜けるので春から比較的暇です
  • 東京に出たい
  • お仕事のお誘いWelcome!!
www
ご清聴ありがとうございました。

★おまけ - デモその3の改良版

3軸加速度センサの出力をRA4から入力し、A/D変換し、加速度に応じたLEDを表示。
(require "./demo-base")

(define code '(
             loop
               (a2d RA4) ; AN2; 使えるのは RA1(=AN1) RA2(=AN2) RA4(=AN3) の3つ
               ;; RA5 RA4 RA3 RC5 RC4 RC3 RA0 RA1 RA2 RC0 RC1 RC2 +5V GND
               ;;  -  <3>  -   -   -  <7> <0> <1> <2> <4> <5> <6>
               ;;         SW1         LED RP1          LED LED LED

               (test < 213 a2d-upper)
               (branch +2g)
               
               (test < 161 a2d-upper)
               (branch +1g)

               (test < 113 a2d-upper)
               (branch 0g)
               
               (test < 61 a2d-upper)
               (branch -1g)

             -2g
               (LED #b0011 0.1)
               (goto loop)
             -1g
               (LED #b0010 0.1)
               (goto loop)
             0g
               (LED #b0000 0.1)
               (GOTO loop)
             +1g
               (LED #b0100 0.1)
               (goto loop)
             +2g
               (LED #b1100 0.1)
               (goto loop)
               ))

(macro-asm-test code #t #t #t 60)

demo-base.scm - macro-asm-test関数

(use srfi-1)
(use util.match)

(require "./macro-asm")
(require "./pic-asm")
(require "./pic-disasm")
(require "./pic-device")

(define (macro-asm-test src asm? disasm? write? runsec)
  (print "-------")
  ;;コンパイル
  (let1 asm-code (pic-macro-asm src)
    (when asm?
      (map asm-pp asm-code)
      (print "-------"))

    ;;アセンブル
    (let1 obj-code (pic-asm asm-code)
      ;;(map print obj-code)
      ;;(print "-------")

      ;;オブジェクトコードをdisasmして表示(デバッグ用)
      (when disasm? 
        (map print (pic-disasm obj-code))
        (print "-------"))

      (when write?
        ;;オブジェクトコードをPICに書き込んで実行(5秒)
        (pic-write obj-code)

          ;;指定した秒数だけ給電
        (when (number? runsec)
          (pic-on)
          (sys-sleep runsec)
          (pic-off))
          ;;delete hex-file here if you wish
        ))))

pic-device.scm - pk2への書き込みとか給電on/offとか

;
; オブジェクトコードをhex化して書き込み
;
(define (pic-write obj-code)
  (let1 hex-file "_test.hex"
    (save-obj-code obj-code hex-file)
    (pic-write-hex-file hex-file)))
  
;
; hexファイルを書き込み
;
(define (pic-write-hex-file hex-file)
  (sys-system (format "pk2 -write ~a" hex-file)))

;
; 給電ON
;
(define (pic-on) (sys-system (format "pk2 -on")))
;
; 給電OFF
;
(define (pic-off) (sys-system (format "pk2 -off")))

;
; オブジェクトコードを書き込んで走らせる
;
(require "./intelhex")
(define (pic-run obj-code name sec)
  (let1 hex-file (string-append name ".hex")
    (save-obj-code obj-code hex-file)
    (pic-write-hex-file hex-file)
    (pic-on)
    (sys-sleep sec)
    (pic-off)
    ;delete hex-file here
    ))

>>gauche.gong発表資料2(asm/disasm)
>>gauche.gong発表資料3(マクロアセンブラ)



(12:34)

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔