下面是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。