SMBus 協議


下面是SMBus協議的概要。它適用於協議的所有版本(1.0、1.1和2.0)。在本文的最后對某些協議特性進行了簡要描述,這些特性是本軟件包不支持的。

有些適配器只理解SMBus(系統管理總線)協議,它是I2C協議的一個子集。幸運的是,許多設備只使用相同的子集,這使得將它們放在SMBus上成為可能。

如果您為某個I2C設備編寫驅動程序,請在可能的情況下嘗試使用SMBus命令(如果設備只使用I2C協議的子集)。這樣就可以在SMBus適配器 和 I2C適配器上都使用同一個設備驅動程序(SMBus命令集在I2C適配器上自動轉換為I2C,但是在大多數純SMBus適配器上根本無法處理普通的I2C命令)。

下面是SMBus協議操作的列表,以及執行這些操作的函數。注意,SMBus協議規范中使用的名稱通常與這些函數名稱不匹配。對於傳遞單個數據字節的一些操作,使用SMBus協議操作名稱的函數執行完全不同的協議操作。

每個事務類型對應一個功能標志。在調用事務函數之前,設備驅動程序應該總是檢查(只檢查一次)相應的功能標志,以確保底層I2C適配器支持所涉及的事務。

符號注解

S

Start 條件

P

Stop 條件

Rd/Wr (1 bit)

讀/寫位。Read等於1, Write等於0。

A, NA (1 bit)

確認(ACK)和不確認(NACK)位

Addr (7 bits)

I2C 7位地址。注意,這可以像往常一樣進行擴展,以獲得10位I2C地址。

Comm (8 bits)

命令字節,通常選擇設備上的寄存器。

Data (8 bits)

一個普通數據字節。有時,對於16位數據寫DataLow, DataHigh。

Count (8 bits)

包含塊操作長度的數據字節。

[..]

由I2C設備發送的數據,而不是由主機適配器(adapter)發送的數據。

SMBus快速命令

這將在Rd/Wr位的位置發送一個位到設備:

S Addr Rd/Wr [A] P

功能flag: I2C_FUNC_SMBUS_QUICK

SMBus接收字節

由 i2c_smbus_read_byte() 實現。

它從設備中讀取單個字節,而不指定設備寄存器。有些設備非常簡單,這個接口就足夠了;對於其他人來說,如果您想讀取與前一個SMBus命令中相同的寄存器,則它是一種簡寫:

S Addr Rd [A] [Data] NA P

功能flag: I2C_FUNC_SMBUS_READ_BYTE

API分析:

s32 i2c_smbus_read_byte(const struct i2c_client *client)

SMBus“接收字節”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。

描述

  這將執行SMBus“接收字節”協議,返回負errno 或者 從設備接收的字節。

SMBus發送字節

由 i2c_smbus_write_byte() 實現。

此操作與接收字節相反:它向設備發送單個字節。

S Addr Wr [A] Data [A] P

功能flag:I2C_FUNC_SMBUS_WRITE_BYTE

API分析:

s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value);

SMBus“發送字節”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 value:要發送的字節

描述

  這將執行SMBus的“發送字節”協議,返回負errno 或者 成功時返回0。

 SMBus讀取字節

由 i2c_smbus_read_byte_data() 實現。

它從一個設備,從一個指定的寄存器中讀取一個字節。寄存器是通過Comm字節指定的:

S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P

功能flag:I2C_FUNC_SMBUS_READ_BYTE_DATA

API分析:

s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)

SMBus“讀字節”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 command從機字節解釋(一般為slave的寄存器地址)。

描述

  這將執行SMBus“讀字節”協議,出錯時返回負errno,否則返回從設備接收的數據字節。

SMBus讀字

由 i2c_smbus_read_word_data() 實現。

這個操作很像讀字節;同樣,數據從設備中讀取,從通過Comm字節指定的指定寄存器中讀取。但這一次,數據是一個完整的字(16位):

S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P

功能flag:I2C_FUNC_SMBUS_READ_WORD_DATA

注意,函數i2c_smbus_read_word_swap()可用於讀取兩個數據字節相反的情況(不符合SMBus,但非常流行)。

API分析:

s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command)

SMBus“讀字”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 command從機字節解釋(一般為slave的寄存器地址)。

描述

  這執行SMBus“read word”協議,返回負errno 或 設備接收到的16位無符號“word”。

SMBus寫字節

由 i2c_smbus_write_byte_data() 實現。

這將一個字節寫入一個設備,一個指定的寄存器。寄存器是通過Comm字節指定的。這與讀字節操作相反。

S Addr Wr [A] Comm [A] Data [A] P

功能flag:I2C_FUNC_SMBUS_WRITE_BYTE_DATA

API分析:

s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value)

SMBus“寫字節”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 command從機字節解釋(一般為slave的寄存器地址)。
  • u8 value:將要被寫入的字節數據

描述

  這將執行SMBus的“寫字節”協議,出錯時返回負errno, 或者成功時返回0。

SMBus寫字

由 i2c_smbus_write_word_data() 實現。

這與Read Word操作相反。16位的數據被寫入設備,通過Comm字節指定的指定寄存器:

S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P

功能flag:I2C_FUNC_SMBUS_WRITE_WORD_DATA

注意,函數i2c_smbus_write_word_swap()可用於兩個數據字節相反方向的寫操作(不符合SMBus,但非常流行)。

API分析:

s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, u16 value)

SMBus“寫字”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 command從機字節解釋(一般為slave的寄存器地址)。
  • u16 value:將要被寫入的16位的"word"

描述

  這將執行SMBus“write word”協議,出錯時返回負errno,成功時返回0.

SMBus進程調用

這個命令選擇一個設備寄存器(通過Comm字節),向它發送16位數據,並返回讀取的16位數據:

S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
                             S Addr Rd [A] [DataLow] A [DataHigh] NA P

功能flag: I2C_FUNC_SMBUS_PROC_CALL

SMBus塊讀取

由 i2c_smbus_read_block_data() 實現。

該命令從設備中讀取最多32字節的塊,從通過Comm字節指定的指定寄存器中讀取。數據量由設備在Count字節中指定。

S Addr Wr [A] Comm [A]
           S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P

功能flag: I2C_FUNC_SMBUS_READ_BLOCK_DATA

API分析:

s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, u8 *values)

SMBus“塊讀”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 command從機字節解釋(一般為slave的寄存器地址)。
  • u8 *values數據將被讀入的字節數組;大到足以容納從slave返回的數據。SMBus最多允許32個字節。

描述

  這將執行SMBus“block read”協議,返回負errno,否則返回從slave響應中的數據字節數。

注意,使用這個函數需要客戶機的適配器支持I2C_FUNC_SMBUS_READ_BLOCK_DATA功能。不是所有的適配器驅動程序都支持這一點;它通過I2C消息傳遞的仿真依賴於特定的機制(I2C_M_RECV_LEN),可能沒有被實現。

SMBus塊寫入

由 i2c_smbus_write_block_data() 實現。

與Block Read命令相反,該命令將至多32字節寫入設備,寫入通過Comm字節指定的指定寄存器。數據量在Count字節中指定。

S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P

功能 flag: I2C_FUNC_SMBUS_WRITE_BLOCK_DATA

API分析:

s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values);

SMBus“塊寫入”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 command從機字節解釋(一般為slave的寄存器地址)。
  • u8 length: 數據塊大小,SMBus最多允許32個字節
  • const u8 *values將被寫入的字節數組。

描述

  這將執行SMBus的“塊寫”協議,出錯時返回負errno,成功時返回0。

SMBus塊寫-塊讀進程調用

SMBus塊寫-塊讀進程調用是在規范的2.0版本中引入的。

這個命令選擇一個設備寄存器(通過Comm字節),發送1到31字節的數據給它,並返回1到31字節的數據:

S Addr Wr [A] Comm [A] Count [A] Data [A] ...
                             S Addr Rd [A] [Count] A [Data] ... A P

功能 flag: I2C_FUNC_SMBUS_BLOCK_PROC_CALL

SMBus主機通知

該命令從作為主設備的SMBus設備發送到作為從設備的SMBus主機。它的形式與Write Word相同,只是command代碼被發信號設備的地址所代替。

[S] [HostAddr] [Wr] A [DevAddr] A [DataLow] A [DataHigh] A [P]

在Linux內核中,這是通過以下方式實現的:

  • 支持SMBus Host Notify的I2C總線驅動應該報告I2C_FUNC_SMBUS_HOST_NOTIFY。
  • I2C總線驅動通過調用i2c_handle_smbus_host_notify()來觸發SMBus Host Notify。
  • 可以觸發SMBus主機通知的設備的I2C驅動程序將有 client->irq 分配給Host Notify IRQ,如果沒有其他人指定其他的。

目前沒有從客戶端檢索數據參數的方法。

包錯誤檢查(PEC)

數據包錯誤檢查在規范的1.1版本中被引入。

在終止STOP之前,PEC將CRC-8錯誤檢查字節添加到使用它的傳輸中。

地址解析協議(ARP)

地址解析協議是在規范的2.0版本中引入的。它是一個使用上述消息的高層協議。

ARP協議增加了設備枚舉和動態地址分配功能。所有ARP通信使用從地址0x61,並需要PEC校驗和。

SMBus Alert

SMBus Alert是在規范的1.0版本中引入的。

SMBus警報協議允許多個SMBus從設備共享SMBus主服務器上的單個中斷管腳,同時仍然允許主服務器知道哪個從服務器觸發了中斷。

在Linux內核中,是通過以下方式實現的:

  • 支持SMBus告警的I2C總線驅動應該調用i2c_new_smbus_alert_device()來安裝SMBus告警支持。
  • 可以觸發SMBus警報的設備的I2C驅動程序應該實現可選的alert()回調。

I2C塊事務

下面的I2C塊事務類似於SMBus塊讀和寫操作,只是它們沒有Count(即 S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P 中的Count)字節。它們由SMBus層支持,為了完整起見,這里對它們進行了描述,但它們不是由SMBus規范定義的。

I2C塊事務不限制傳輸的字節數,但SMBus層設置了32字節的限制。

I2C塊讀取

由 i2c_smbus_read_i2c_block_data() 實現。

這個命令從設備中讀取一個字節塊,從指定的寄存器(通過Comm字節指定)中讀取:

S Addr Wr [A] Comm [A]
           S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P

功能 flag: I2C_FUNC_SMBUS_READ_I2C_BLOCK

API分析:

s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command, u8 length, u8 *values)

i2c“塊讀”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 command從機字節解釋(一般為slave的寄存器地址)。
  • u8 length: 要讀取的字節數。
  • u8 *values:存放讀取的數據的字節數組。

描述

  這將執行i2c “block read”協議,返回負errno,否則返回從slave中讀取的數據字節數。

I2C塊寫入

由 i2c_smbus_write_i2c_block_data() 實現。

與Block Read命令相反,該命令將字節寫入設備,寫入通過Comm字節指定的指定寄存器。注意,命令長度為0、2或更多字節是受支持的,因為它們與數據沒有區別。

S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P

功能 flag: I2C_FUNC_SMBUS_WRITE_I2C_BLOCK

API分析:

s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values)

i2c “塊寫入”協議。

參數

  • const struct i2c_client *client: 從設備客戶端指針。
  • u8 command從機字節解釋(一般為slave的寄存器地址)。
  • u8 length: 將要寫入的數據塊大小
  • const u8 *values:將被寫入的字節數組。

描述

   這將執行i2c的“塊寫”協議,出錯時返回負errno,成功時返回0。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM