每個 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。
使用流程
- 可設定速度 spi -> max_speed_hz = 400000; spi_setup(spi);
- spi_message_init() 初始化 struct spi_message。
- 設定 spi_transfer,以寫為例提供了 tx_buf。
- spi_message_add_tail() 將 spi_transfer 加到 spi_message。
- spi_sync() 把 spi_message 傳出去。
參考
- Linux include/linux/spi/spi.h
- 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。