1us Lチカ

2016年 謹賀新年、あけましておめでとうございます。おせち料理も31日と1日で食べつくしてしまいました。

さて、今年最初のブログですね。0.000001秒のLチカをロジックアナライザーでモニタリングして光らせてみました。

あと、オレンジパイで、8本のGPIO を使って安価なロジックアナライザーで採取できるかも確認してみました。

 

サンプルプログラムを採取したデータが以下です。8本分は取れていますが、速すぎるところは取りこぼしているようです。

1

矢印は500ns で光っている部分で採取に失敗し、取りこぼす事がありました。このあたりが2Mhz の限界なんですね。今のファームウェアとソフトウェアだとこれが限界のようです。

2

複数のLED は、blink ファンクションにて光らせていますが、呼び出しと初期化の処理で250us 程度使っているようです。

3

usleep 関数を使っても思ったより、処理に時間がかかるようです。1us を指定して光らせているんですが、実際は69us 光っています。nanosleep を使っても66us は使われてしまうようで、1us を光らせる為にwhile で調整してみました。

4

サンプルのプログラムは以下です。

/*
 *  +-----+-----+----------+------+---+--OrangePiPC--+---+------+---------+-----+--+
 *  | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 *  +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 *  |     |     |     3.3v |      |   |  1 || 2  |   |      | 5v       |     |     |
 *  |   2 |  -1 |    SDA.0 |      |   |  3 || 4  |   |      | 5V       |     |     |
 *  |   3 |  -1 |    SCL.0 |      |   |  5 || 6  |   |      | 0v       |     |     |
 *  |   4 |   6 | IO6 PA06 |  OUT | 0 |  7 || 8  |   |      | TxD3     |     |     |
 *  |     |     |       0v |      |   |  9 || 10 |   |      | RxD3     |     |     |
 *  |  17 |  -1 |     RxD2 |      |   | 11 || 12 | 0 | OUT  | IO1 PD14 | 1   | 18  |
 *  |  27 |  -1 |     TxD2 |      |   | 13 || 14 |   |      | 0v       |     |     |
 *  |  22 |  -1 |     CTS2 |      |   | 15 || 16 | 0 | OUT  | IO4 PC04 | 4   | 23  |
 *  |     |     |     3.3v |      |   | 17 || 18 | 0 | OUT  | IO5 PC07 | 5   | 24  |
 *  |  10 |  -1 |     MOSI |      |   | 19 || 20 |   |      | 0v       |     |     |
 *  |   9 |  -1 |     MISO |      |   | 21 || 22 |   |      | RTS2     |     |     |
 *  |  11 |  -1 |     SCLK |      |   | 23 || 24 |   |      | SPI-CE0  |     |     |
 *  |     |     |       0v |      |   | 25 || 26 |   |      | CE1      |     |     |
 *  |   0 |  -1 |    SDA.1 |      |   | 27 || 28 |   |      | SCL.1    |     |     |
 *  |   5 |   7 |  IO7 PA7 |  OUT | 0 | 29 || 30 |   |      | 0v       |     |     |
 *  |   6 |   8 |  IO8 PA8 |  OUT | 0 | 31 || 32 | 0 | OUT  | IO9 PG08 | 9   | 12  |
 *  |  13 |  10 | IO10 PA9 |  OUT | 0 | 33 || 34 |   |      | 0v       |     |     |
 *  |  19 |  12 | IO12PA10 |  OUT | 0 | 35 || 36 | 0 | OUT  | IO13PG09 | 13  | 16  |
 *  |  26 |  14 | IO14PA20 | ALT3 | 0 | 37 || 38 | 0 | OUT  | IO15PG06 | 15  | 20  |
 *  |     |     |       0v |      |   | 39 || 40 | 0 | OUT  | IO16PG07 | 16  | 21  |
 *  +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 *  | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 *  +-----+-----+----------+------+---+--OrangePIPC--+------+----------+-----+-----+
 *         ^^^^ Pin NO                                                   ^^^^ Pin NO
 * 1us LED blink.
 * building ex) gcc -lwiringPi -lpthread -I/usr/local/include -L/usr/local/lib -levent -o 2016blinkall 2016blinkall.c
 * 
 *
*/
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <wiringPi.h>

#define MSEC 1
#define USEC 33
#define NANOSEC 1000

int blink2(int led, int delay);

int main (void)
{
  int led;
  int i = 0;

  while (i < 3)
  {
    blink2(16, 1000);
      blink2(15, 1000); //Next blink 250 us
      blink2(13, 1000);
      blink2(9, 1000);
      blink2(5, 1000);
      blink2(4, 1000);
      blink2(1, 1000);
      blink2(6, 1000);

    i++;
  }

  delay (MSEC);
  return 0;
}

int blink2(int led, int delay){
    // unsigned int usecs;
    // usecs = delay;
    // sec = delay;
    led = led;
    int i = 0;

    // nano sec
    struct timespec nano;
    nano.tv_sec = 0;
    nano.tv_nsec = delay;

    wiringPiSetup () ;
    pinMode (led, OUTPUT) ;

    digitalWrite (led, HIGH) ;
    nanosleep(&nano, NULL); // 66us
    // usleep (usecs) ; // 66us
    // delay (delay);
    digitalWrite (led,  LOW) ;
    usleep (1);

    digitalWrite (led, HIGH) ;

    // 1us
    while (i < 100)
    {
        i++;
    }
    digitalWrite (led,  LOW) ;
    usleep (1); // 66us

    digitalWrite (led, HIGH) ;
    // 500 ns
    digitalWrite (led,  LOW) ;
}

GPIO の8本を同時に処理させるにはどうしたらいいんでしょうかね。マルチスレッド処理ですかね?シフトレジスタに投げて、一括処理とかですかね?

 

前ちょっと触ったイベント処理のlibevent とかを使うとどのくらいの精度になるんでしょうかね。いろいろ疑問がわいてきます。

E-ink を表示するためにはまだまだ超えないといけない山がたくさんあるようです。

なんとか、春までには表示したいんですが。こつこつとやっていきます。

FX2LP でsigrok のロジックアナライザー

年末で、何かとイベントごとがあってなかなかブログを更新できずにいました。

Aliexpress からもどんどんお品が届いて、ロジックアナライザーとして使うボードも到着しました。テストがてら、OrangePi PC の GPIO につないだLED のタイミングを計測してみること。

配線は、とりあえず1チャンネルでテスト。全部で8チャンネルいけます。

logic2

ちょっとわかりにくいですが、PB0 ~ PB7 までの端子が sigrok でいう0から7 までに対応しています。とりあえず今回はPB0 の端子につないで1チャンネルの表示をしてみました。

PulseView1

全体のテスト配線は以下のような感じです。

 

logic

osx だと sigrok のソフトウェアの中にファームウェアがあります。最新のファームウェアは、以下にビルド済みのものがあります。

fx2lafw (pre-built firmware files の項を参照)
http://sigrok.org/wiki/Fx2lafw

つい先月にリリースされている0.1.3 を使いました。

sigrok-firmware-fx2lafw-bin-0.1.3.tar.gz

http://sigrok.org/download/binary/sigrok-firmware-fx2lafw/

ほどよく、配置。*.fw がファームウェアです。

HOPE:sigrok-firmware junkhack$ pwd
/Applications/PulseView.app/Contents/share/sigrok-firmware
HOPE:sigrok-firmware junkhack$ ll
total 1088
-rw-r--r--@ 1 junkhack  admin  45268 11  3  2014 asix-sigma-100.fw
-rw-r--r--@ 1 junkhack  admin  45396 11  3  2014 asix-sigma-200.fw
-rw-r--r--@ 1 junkhack  admin  45396 11  3  2014 asix-sigma-50.fw
-rw-r--r--@ 1 junkhack  admin  45360 11  3  2014 asix-sigma-50sync.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-braintechnology-usb-lps.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-cwav-usbeeax.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-cwav-usbeedx.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-cwav-usbeesx.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-cypress-fx2.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-saleae-logic.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-sigrok-fx2-16ch.fw
-rw-r--r--@ 1 junkhack  admin   8120 11 27 09:09 fx2lafw-sigrok-fx2-8ch.fw
-rw-r--r--@ 1 junkhack  admin  81808 11  3  2014 sysclk-lwla1034-extneg.rbf
-rw-r--r--@ 1 junkhack  admin  81808 11  3  2014 sysclk-lwla1034-extpos.rbf
-rw-r--r--@ 1 junkhack  admin  81460 11  3  2014 sysclk-lwla1034-int.rbf
-rw-r--r--@ 1 junkhack  admin  48521 11  3  2014 sysclk-lwla1034-off.rbf
HOPE:sigrok-firmware junkhack$ 

sigrok の PluseView を開きます。

現在、手元でビルドしていないので、ELIAS さんのビルドしたものです。

osx PulseView.dmg (0.2.0 : 2014/11/04 build)

http://eliasoenal.com/2014/11/04/sigrok-for-os-x/

File Menu から Connect to Device を選択して、以下のようにスキャンすると出ました。

Connect_to_Device

osx の USB 認識は、以下のようでした。

osxusb

system_profiler で見ると以下のように出ます。

 

$ system_profiler SPUSBDataType
USB:
::

            fx2lafw:

              Product ID: 0x3881
              Vendor ID: 0x0925
              Version:  0.01
              Speed: Up to 480 Mb/sec
              Manufacturer: sigrok
              Location ID: 0x1c120000 / 2
              Current Available (mA): 500
              Current Required (mA): 100

 

で、LEDをGPIO で光らせるプログラムで、LED を ON するタイミングを以下のように、usleep を使って1ms 光らせてみました。

抜粋箇所だけ載せておきます。

#include <event.h>
#include <wiringPi.h>
#include <unistd.h>

#define LED 16
#define MSEC 10
#define USEC 1000 // 1000 = 1ms (0.000001 sec = 1 micro second)

int
blink(void){
    wiringPiSetup () ;
    pinMode (LED, OUTPUT) ;

    digitalWrite (LED, HIGH) ;
    // delay (MSEC);
    usleep(USEC);
    digitalWrite (LED,  LOW) ;
}
::

全体のプログラムは、末尾につけておきます。このプログラムは、libevent を使ってfifo ファイルに read イベントがあったら、上記のblink ファンクションが呼ばれる仕組みです。あとで、書きますが、nginx のログをパイプさせて監視させています。

で、他のホストから ab で web アクセスしてみます。

$ ab -n 5 -c 1 http://junkhack.gpl.jp/index.html

とりあえず、5回くらいで。nginx のアクセスログには、5回記録されています。

192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"
192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"
192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"
192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"
192.168.1.17 - - [27/Dec/2015:20:21:27 +0900] "GET /index.html HTTP/1.0" 200 10798 "-" "ApacheBench/2.3" "-"

そのタイミングを取ると以下のようです。

PulseView

今度は、300us ほどにして、100回アクセスしてみました。ちゃんと100回、凹凸があるか数えたらありました。

PulseView_2

マウスホイールすると拡大できます。300us より若干大きくなっているのは、イベント処理のプログラムや時計の誤差などの影響ですかね。

300us

1ms くらいのものは問題なく見れそうということがわかりました。2Mhz 以上あげると、固まるのはなぜですかね。24Mhz までいけるはずですが?

 

1us 単位の計測が今のところできないです。あと、トリガーをかけようとチャンネルをクリックすると落ちる。うーん、独自にコンパイルしてみるしかなさそうですね。

 

▼まとめ

・EZ-USB FX2LP CY7C68013A というのをゲット(非常に安価だった)

・sigrok の PluseView の osx 版(0.2.0)を使ったが、無事チャンネル0のパルスが取れた

・PCB上のPB0 ~ PB7 までの端子が sigrok でいう0から7 までに対応

・fx2lafw はビルド済みの0.1.3 を使用

・2Mhz までは計測できるが、それ以上でかたまる

・fx2lafw が悪いのか、PluseView が悪いのか切り分ける必要あり

・テストプログラム側のusleep を削除して、単純に点灯消灯をしてタイミングを取ったら、500ns という単位が出たので、1us の単位でも取得できそう。

開発ボードがコハクラフトさんより到着

kohacraftさんよりE-ink の開発ボードが到着しました。ありがとうございます。

a

PINヘッダーがあるので、自由に信号を入れ放題!電源部は、LT1945 から供給。コイルは、Coilcraft

b

さぁ、うまく表示できるでしょうか。

Scan 2実験にあたり、まだ下準備が整っていないのでそこから着手しないとです。

まずは、ESP8266 から信号を入れるため、ESP側の開発ボードの半田付けをして、シフトレジスターを用意する作業があります。 ご飯食べて、気力を回復させてから、本日は何か1つ作業を進めたいです。