2021年9月26日 星期日

Linux SPI

每個 SPI Bus 都有控制器,其控制器驅動程式是 SPI master controller driver。而 SPI Bus 上週邊的驅動程式稱為 SPI protocol driver,存取是靠傳 SPI 訊息 (struct spi_message) 對特定 Bus 依序完成,每個 SPI 訊息由一個或以上 struct spi_transfer 組成,主要成員是 tx_buf 和 rx_buf 放要傳或收的資料。

spi_async() 是最底層的存取函數,執行 spi_master 的 transfer,可在任何 context (包括 irq handler)  執行,完成後 callback complete。

spi_sync() 則將 spi_async() 加以包裝,並等候 complete。另外 spi_write()、spi_read()、spi_write_then_read() 等,使用 spi_sync() 進行 SPI 存取。

送交 spi_message 的程式需要管理好記憶體,將每個沒用到的欄位清為 0 以相容將來 API 更新,送交後忽略直到 completion callback。

使用流程

  1. 可設定速度 spi -> max_speed_hz = 400000; spi_setup(spi);
  2. spi_message_init() 初始化 struct spi_message。
  3. 設定 spi_transfer,以寫為例提供了 tx_buf。
  4. spi_message_add_tail() 將 spi_transfer 加到 spi_message。
  5. spi_sync() 把 spi_message 傳出去。

參考

  1. Linux include/linux/spi/spi.h
  2. https://ithelp.ithome.com.tw/articles/10247656

Linux Documentation/spi/spi-summary

int // 0 成功,負數 errno status code
spi_write_then_read(
    struct spi_device * spi, // sip device
    const void *txbuf, unsigned n_tx,
    void *rxbuf, unsigned n_rx);

SPI 同步寫入 n_tx bytes txbuf,然後讀取 n_rx bytes (最大?) 到 rxbuf。txbuf 和 rxbuf 不需要 dma-safe。只能用在能 sleep 的 context。參數都會複製到小 buffer,考慮移植性不要超過 32 bytes。Performance-sensitive 或 bulk transfer code 應該使用 dma-safe buffers 的 spi_{async,sync}()。

spi_write_and_read()

        struct spi_transfer     t = {
                        .tx_buf         = buf,
                        .rx_buf         = buf,
                        .len            = len,
                };
        struct spi_message      m;

        spi_message_init(&m);
        spi_message_add_tail(&t, &m);
        return spi_sync(spi, &m);

 spi_write_then_read()

  • https://ithelp.ithome.com.tw/articles/10247182
  • 現成的驅動程式:spidev。

沒有留言:

張貼留言

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...