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回くらい取りこぼしてしまう。
 (成功の場合)


(失敗の場合)


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







0 件のコメント:

コメントを投稿