L3GD20 動作テスト①

急に作りたくなったものがあるので、L3GD20をmbedから使ってみる。

I2Cはちょっと面倒なのでSPIで通信する。

f:id:katakanan:20170714232309p:plain

図にするほどのものでもない図。
akizukidenshi.com
ライブラリがあるいが面白くないので自分で

のチップデータシートによるとSPIの波形は

f:id:katakanan:20170714232625p:plain
のようなタイミングで
SPI - SPIマスター | Mbed

によるとMode3
bitは8で
最初はWho am Iアドレスを読む。

#include "mbed.h"
#include "L3GD20.h"

DigitalOut myled(LED1);

Serial pc(USBTX, USBRX);
//SPI spi(p5, p6, p7); // mosi, miso, sclk
L3GD20 gyro(p5, p6, p7, p8/*, PinName interrupt1=NC, PinName interrupt2=NC*/);

int main() {
    
    pc.baud(115200);

    pc.printf("0x%02X\r\n", gyro.read_byte(0x0F));
    gyro.write_byte(0x20, 0x0F);

    while(1) {
        myled = 1;
        wait(0.5);
        myled = 0;
        wait(0.5);
        pc.printf("0x%02X\r\n", gyro.read_byte(0x0F));
    }
}
#pragma once
#include "mbed.h"

class L3GD20
{
    SPI _spi; // mosi, miso, sclk
    DigitalOut _cs;
    
    public:
    L3GD20(PinName mosi, PinName miso, PinName sclk, PinName cs):_spi(mosi, miso, sclk),_cs(cs)
    {
        _spi.format(8,3);
        _spi.frequency(10000000);
    }
    
    uint8_t write_byte(uint8_t reg, uint8_t val)
    {
        _cs = 0;
        _spi.write(reg);
        _spi.write(val);
        _cs = 1;
        return 0;
    }

    uint8_t read_byte(uint8_t reg)
    {
        _cs = 0;
        _spi.write(reg|0x80);
        uint8_t ret = _spi.write(0x00);
        _cs = 1;
        return ret;
    }
};

これで0xD4が送られてくればOK

"AXI なんとか FIFO" の雑な違い..(?)

Vivado IP の中には今(2016.4)のところ
FIFOで検索すると以下のものがヒットする。

一番目は普通のFIFOである。
最後はおいておいて、その下3つの違いについて

AXI Data FIFO

これについてあまり情報がなかった(おそらく必要となる場面があまりないからか・・)
AXI Interconnectのなかで使われているらしく。
https://www.xilinx.com/support/documentation/ip_documentation/axi_interconnect/v2_0/pg059-axi-interconnect.pdf
これのp76を読む限り、
ユーザーは必要なときにInterconnect内のFIFOをオンオフ擦ることもできるし、
直接ブロックデザインに入れることもできる。
データ幅やクロック変換によってデータレートが違うところで役に立つ。(AXI Crossbar付近)

という感じ。直接使うことはあんまりなさそうだ。

AXI-Stream FIFO

データシート
https://www.xilinx.com/support/documentation/ip_documentation/axi_fifo_mm_s/v4_1/pg080-axi-fifo-mm-s.pdf
によると、
AXI4とかAXI4-LiteをAXI Streamに変換するのにつかえる。イーサネットとかそういうたぐいのパケットコミュニケーションを使うものに良いよ、という。
ただ非同期クロックには対応していない。

使用例をみるとわかりやすい。
p37 Programming Sequence for TX and RX in Store-and-Forward Mode

送信は必要なタイミングでlengthを書き込むことで開始される。
受信はあらかじめThresholdを設定しておくことで割り込みをかけることができるようだ。

AXI4-Stream Data FIFO

https://www.xilinx.com/support/documentation/ip_documentation/axis_infrastructure_ip_suite/v1_1/pg085-axi4stream-infrastructure.pdf
によるとAXI4-Stream Infrastructure のうちの一つである。
そもそもInfrastructuresは

  • Buffering Module
  • Transform Module
  • Routing Module

に分かれており。これらはAXI4-Stream Systemを構成するのに便利なモジュール群である。
その中のBuffering Moduleの一つであるFIFO
FIFO generatorによBRAM,LUTをベースとしてFIFOを実装する。

p13からその説明で基本的なFIFOにAXI4-Streamがくっついたと捉えている。
非同期クロックに対応している。


この中で使いそうなのはAXI Stream FIFOのようだ。
FIFOに特定の情報が集まったらバーストを開始させて、目的のスレーブが処理する。

C# sscanf の代替

C#でsscanfしたいなという人が絶対にいると思っていたら
ネットにあったのでその紹介。

www.blackbeltcoder.com

これは同時に以下のTextParserというものを利用している。
(Microsoft.VisualBasic.FileIOにもTextParserクラスがあるが、それとは別)
www.blackbeltcoder.com

private void button1_Click(object sender, EventArgs e)
{
    ScanFormatted scan = new ScanFormatted();

    scan.Parse("hoge1foo2bar3", "hoge%dfoo%dbar%d");

    foreach (var item in scan.Results)
    {
        Debug.WriteLine("{0}", item);
    }

//1
//2
//3
}

のようだ。

C# serialport ReadExisting

急に作りたくなったもののためのデバッグのために
UARTでパソコンに情報を送信しているが
それを可視化したほうが分かりやすかったので寄り道。

フォームアプリケーションが
楽なのでC#を使用。
2.0あたりで適当に使ってから久しぶりに使ったきがする。

\r\nで通信を区切っているがReadLineだとエラーが出るので
ReadExistingを使う。


COMポートの列挙(comboBoxで選べるように)

private void Form1_Load(object sender, EventArgs e)
{
    string[] ports = SerialPort.GetPortNames();

    foreach (var item in ports)
    {
        comboBox1.Items.Add(item);
    }

    comboBox1.SelectedIndex = 1;
}

データの受信インベント
区切り文字(delim=\r\n or \n)があるときは必ず(?)末尾っぽいので
出力してバッファーを空にする。

private string buffer;

private void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if (serialPort1.IsOpen == false)
    {
        return;
    }

    try {
        buffer += serialPort1.ReadExisting();
                
        if (buffer.IndexOf(delim) >= 0)
        {
            Debug.WriteLine(buffer);
            buffer = string.Empty;
            Debug.WriteLine("---------------");
        }
    }
    catch (Exception ex) {
        MessageBox.Show(ex.Message);
    }

    if (buffer.Length > 1024)
    {
        buffer = string.Empty;
    }
}

区切り文字なくてもバッファーが長くなると困るので適当にリフレッシュ。
(ココらへんは適当仕様)

あとは受信できた一行なんとかする。

BD6231F-E2動作テスト

急に作りたくなったものがあるので
秋月電子の良さそうなモータードライバ
akizukidenshi.com
の動作テスト
雑な図
f:id:katakanan:20170625205945p:plain
モータードライバー自体の電源は6Vでも
入力電圧Hレベルは2.0VなのでmbedのPWM(3.3V)でもOK。

ついでに可変抵抗でも繋いで、
AD変換した値を読み取り、
速度が変わっていることを確認する。

#include "mbed.h"

DigitalOut myled(LED1);
AnalogIn ain(p20);

PwmOut fin(p22);
PwmOut rin(p21);

int main() {
    
    fin.period(0.000010);
    rin.period(0.000010);

    rin = 0;

    while(1) {
        fin = ain;
    }
}

モーターにエンコーダーとかついていたら面白かったが
mbedにはそれをカウントするために周辺回路がない

Bash on Windowsをイイカンジにする②

前回の続き
e-tipsmemo.hatenablog.com

右クリックでアイコンを表示

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\Background\shell\bash]
"icon"="%USERPROFILE%\\AppData\\Local\\lxss\\bash.ico"

ターミナルエミュレーターとして
github.com

ついでにfishをインストールして

sudo apt-add-repository ppa:fish-shell/release-2
sudo apt update
sudo apt install fish

wsl-terminalのetc/wsl-terminal.confで
shell=fishにしてしまった。

RN-42動作確認

急に作りたくなったものがあるので
それのためにRN-42の動作テストを行った。
mbed
RN-42
f:id:katakanan:20170624193501p:plain

#include "mbed.h"

Serial rn42(p13,p14);
Serial pc(USBTX, USBRX);
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);
int main() {
 
    rn42.baud(115200);
    pc.baud(115200);
    wait(1);
    
    while (1) {
        myled1 = !myled1;
        wait(0.1);
        if (pc.readable())
        {
            myled2 = !myled2;
            rn42.putc(pc.getc());
        }
        
        if (rn42.readable())
        {
            myled3 = !myled3;
            pc.putc(rn42.getc());
        }
    }
}

RN-42モジュールのCTSをGNDに落としておく。
www.microchip.com