LoginSignup
1
1

More than 5 years have passed since last update.

Realtek AmebaのSPIを使う

Posted at

Realtek AmebaのSPIを使ってみました。

まとめ

  • Realtek AmebaのSPIのAPIはmebd HAL準拠のAPIとして提供される。
  • SPIマスタとSPIスレーブの両方をサポート

準備

SPIのAPI

  • ROM内蔵HALのAPIとmbed halのAPIとmbed 拡張halのAPIがあります。
  • ROM内蔵HALは情報が不足しているのでよくわかりません。
  • mbed拡張HALは今回のSDK環境に入っていないので、また別の機会に説明します。
  • mbed halのSPIについて説明していきます。

mbed HAL SPI

void spi_init         (spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel);
void spi_free         (spi_t *obj);
void spi_format       (spi_t *obj, int bits, int mode, int slave);
void spi_frequency    (spi_t *obj, int hz);
int  spi_master_write (spi_t *obj, int value);
int  spi_slave_receive(spi_t *obj);
int  spi_slave_read   (spi_t *obj);
void spi_slave_write  (spi_t *obj, int value);
int  spi_busy         (spi_t *obj);

spi_init()

  • SPIの初期化、4つの端子 MOSI MISO SCLK CSを設定する。

spi_free()

  • SPIの解放。 端子割り当てが解放されるっぽい。

spi_format()

  • bits 1転送単位のbit幅を指定、通常は8
  • mode 0-3のSPIモードを設定
  • slave 0ならマスター、1ならslave

spi_frequency()

  • SPIマスターの場合に、SPICLKの周波数を設定する。 SPIブロックに供給されているクロックの分周器の設定。

spi_master_write()

  • SPIマスター動作時に使う valueをSPIスレーブに書き込み、読み込んだ値を戻り値として返す。
  • 1転送単位ごとに、自動的にCSが無効→有効→無効となります。 マルチ転送したい場合は、CSを別途GPIOで制御が必要。

spi_slave_reeive()

  • SPIスレーブ動作時に使う 受信バッファにデータがあるか確認する 0:データなし、0以外:データあり

spi_slave_read()

  • SPIスレーブ動作時に使う 受信バッファを読みだし、値を戻り値として返す。

spi_slave_write()

  • SPIスレーブ動作時に使う 送信バッファにvalueを設定する。

spi_busy()

  • SPIを使用中かどうか確認する。0:空いてる 0以外:使用中

サンプルコード

  • SPIマスタの動作を確認してみたときのコードです。
  • CSがLowになり、SPIクロックが送信され、8バイトのデータが送信されることを確認しました。
#define SPI0_MOSI  PC_2
#define SPI0_MISO  PC_3
#define SPI0_SCLK  PC_1
#define SPI0_CS    PC_0

    spi_t spi_master;

    spi_init(&spi_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
    spi_format(&spi_master, 8, 0 , 0);
    spi_frequency(&spi_master, 20*1000*1000);

    spi_master_write(&spi_master, c);

Ameba の SPI の HWについて

その他

  • spi_frequency(20000000)と20MHzを設定した場合の実際のクロックをロジアナで測定したところ5MHzでした。
    • 内部のバスクロックを分周しているので、元のバスクロックが低いのか、SPIの分周を設定しているレジスタ baudrのsckdvの設定が正しくないのかもしれません。
    • 調べてみたところ、baudrのsckdvが8に設定されており、40/8 = 5MHzになっていました。
    DiagPrintf("SSI0 SCKDV %x\r\n", HAL_READ16(SSI0_REG_BASE, REG_DW_SSI_BAUDR));

を実行すると

SSI0 SCKDV 8

と表示されました。

* 下記のコードをしたらbaudrのsckdvが2となり 20MHzで動くようになりました。SDKのlib_platform.aに含まれているspi_freq()に問題があるようです。

    PHAL_SSI_ADAPTOR pHalSsiAdaptor;
    PHAL_SSI_OP pHalSsiOp;

    pHalSsiAdaptor = &pspi->spi_adp;
    pHalSsiOp = &pspi->spi_op;

    pHalSsiAdaptor->ClockDivider = 2;
    pHalSsiOp->HalSsiInit(pHalSsiAdaptor);
  • 上記で説明したAPIはポーリング動作のようです。
    • 割り込みやDMAを使ったAPIがmed拡張APIで定義されいます。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1