2015年3月30日月曜日

FON2405EのGPIOでキャラクタ液晶を制御する

先週からGPIOの出力が一部間延びしてしまうことで、行き詰っていた。
気分を変えて、同期シリアル通信でキャラクタ液晶を制御したいと考えた。

結論から書くと、以下の2点の課題から、表示速度はすこぶる遅い。
1.仲介役のPICマイコンの動作速度は4MHz(内臓のオシレーターを使ったため)
2.やっぱりGPIO出力が間延びするから1クロック4msのディレーを入れた

 16文字のデータを送るのに、現状1.3秒かかる。
いざまとめるとこんなものなのだけど、なかなか時間がかかったし、
間延び問題が気になる・・・。



 ハード
FON2405EのGPIO---CLK,DATA---PICマイコン---キャラクタ液晶



ソフト
1.gpioのドライバ
2.gpioのアプリ
3.PICマイコンのファーム

1.gpioのドライバ
  標準のものから変更なし
  RALINK_GPIO_WRITE_BYTEを使用。
  今までの試行錯誤は何だったんだ・・・・。

2.gpioのアプリ
  変更点
  オプション[s]を追加
  s  <gpio clk> <gpio data> <delaytime> <char>
  これを指定するとgptio_test_write_srを呼ぶようにした。
  usleepを使うと4ms以下にはならないようだし、
  ドライバの方で、udelayを使って短くしても、
  前回の間延び問題のように不安定になってしまう。
  なので、CLKの変化のタイミングだけusleepを使って、
  DATAのセット部分はディレーなしにした。
  多少は速くなった。


3.PICマイコンのファーム
  変更点
  1ms毎にタイマー割り込みを行って、
  CLKがH→L(立ち下がり)のタイミングを探す。
  更に1ms経過してもLの状態だったら、DATAを読み込む。
main.c
rcv_lib.c

2015年3月23日月曜日

FON2405EのGPIOでなんちゃってシリアル通信

GPIOの制御が少しわかってきたので、
前回、同期シリアル通信の下準備を行った。

汎用性とか考えると、やっぱりUART(調歩シリアル通信)をやってみたくなり、
ドライバ部分を書き換えてみた。

実験なので、通信速度は9600bpsで、パリティなし、ストップビットは1ビットとした。
やっていることは、結構単純で、1クロック分=1^6μs ÷9600=104μs分ごとにデータを出力するというもの。

http://www5b.biglobe.ne.jp/~kouta_y/news/newsvb/vb14.html

まず、比較のためにFT232RLにて'a'の1文字を送信した場合
調べたとおり、104μsになっていた。

これを目指して、作ってみよう。
linux-2.6.21.x/drivers/char/ralink_gpio.cに追記
80行目付近にある[int ralink_gpio_ioctl]のcase文に

case RALINK_GPIO_UART_SEND:
   base_delay = 104;
           c = (unsigned char)(arg & 0xFFl);
        if (0L <= idx && idx < RALINK_GPIO_DATA_LEN) {
            tmp =le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODATA));
            //H
            tmp2 = tmp | (1L << idx);
            *(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
            udelay(base_delay*3);
           
            //start_bit(L)
            tmp2 = tmp & ~(1L << idx);
            *(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
            udelay(base_delay);

            //data loop
            for(i=0; i<8; i++){
                if((c & mask) > 0){
                    //h
                    tmp2 = tmp | (1L << idx);
                }else{
                    //l
                    tmp2 = tmp & ~(1L << idx);
                }
                            *(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
                        udelay(base_delay);
                mask = mask <<1;
            }
            //stop bit
                tmp2 = tmp | (1L << idx);
            *(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
            udelay(base_delay*3);
        }else
            return -EINVAL;
            break;

この結果が以下の通り
まぁなんとかそれっぽいものがでてきた。

いざ受信させて見ると、10回に1回くらい取りこぼしてしまう。
 (成功の場合)


(失敗の場合)


データの中間くらいが間延びしているように見える・・・。
なーぜーー







2015年3月15日日曜日

FON2405EのGPIOの速度(かなり改善)

昨日すこし改善できたGPIOの速度。
もう少し何とかならないかと、探していたら
こんなHPを発見
http://d.hatena.ne.jp/naoya/20080122/1200960926

http://proger.blog10.fc2.com/blog-entry-64.html

なるほど合点です。4msより早くならない理由はusleepが原因でしたか。

早速、usleepを削除してみると、4msが1.3μsになりました!!
つまり1周期2.6μsだから384KHz

なので、8bit分送るのには18.4μs!
ざっくり16文字×2行の液晶に表示する場合は、 588μsこれなら全く問題にならないね!



 ちなみに、ドライバー部分で無理やりループした場合は、

 1周期が400nsなので2.5MHz!
チョッ速になった。これでPICとの高速通信も問題なくできそう



2015年3月14日土曜日

FON2405EのGPIOの速度(すこし改善)

gpioコマンドを眺めていたら、
LED用のオプション「l」の他に
テストとして「w」があることにやっと気づいた。

そのままだと、1秒おきに1〜23までのGPIOの出力を変化させるだけなので、
少し変更して、特定のGPIOポートをパタパタさせるようにした。

user/rt2880_app/gpio内のgpio.c
gpio_test_write関数のgpio_write_initの後に
for(i=0; i< 1000; i++){
    gpio_write_bit(11,0);
    usleep(1);
    gpio_write_bit(11,1);
    usleep(1);
}

というのを挿入して、コンパイル。

 /opt/buildroot-gcc342/bin/mipsel-linux-gcc \
-I/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/drivers/char \
-I/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/include \
-L/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/lib \
-o mygpio mygpio.c

 そして、mygpio wを実行してみると

おぉ!ちょっと速くなった! 4ms!!
100msとか780msから比べると激速だね!

1つをクロックとして、もう1つをデータとした場合、
下がクロック、上がデータ a(61h)をbit0から送った場合

クロックの立ち下がりで読み込んだとして、84msかかる。
ざっくり16文字×2行の液晶に表示する場合は、2.7秒近くかかることになるのか・・。
データを2ポートにすれば、 1.3秒くらい。
まだ遅いな。

クロックが一定であれば、UARTみたいにできるのだけど、
4msが8msになっている見えるところがある…。
さてどうしたものか

2015年3月10日火曜日

busyboxでttyのボーレートを変更したい

FON2405EのシリアルコンソールttyS1のボーレートを57600から9600に変更したかった。
ググるとsttyを使って〜とあったので、sttyを含めた形でカーネル再構築。

sttyコマンドを使ってボーレートを指定しても変化なかった。

他のプロセスで使用していると変更できないらしい。
シリアルコンソールを一時的に止めてみるかと
inittabを変更
sdk3301/RT288x_SDK/source/venders/Ralink/RT3052/inittab

ここにttyS1::respawn:/bin/shというのがある。
しかしいきなり変えるのも怖いので、
 ttyS1::askfirst:/sbin/getty 9600 ttyS1
とした。
別途gettyを含めて再構築。

結果・・・失敗です。なぜか57600で動きやがる。。。


2015年3月2日月曜日

いろいろな進捗

なかなか最近意識が発散気味なのだけれど、
いくつかやることを絞っていきたいと思う。

1.FONなどRT305x搭載のルーターの使い道
  勢いで入手したものもあり、現在4台。
  何に使うか。
  現状はキャラクタ液晶を接続できるように計画中。
  複数台の並列プログラミングとかもやってみたい

2.7セグLED基板のファーム開発
  I2C部分をまだ作っていない。
  ラズベリーパイに接続するために、この部分を作ろう。
  これは比較的早くできそう。

3.FPGAにオープンCPUコアを入れることをやってみたい

4.しりとりで用意したウィキペディアのデータを
  他の用途でも使う。

5.SDRでなにかやる?
  勢いで、DS-DT305を入手したけど・・・。


こんな感じだ。今月も頑張ろう。