2014-10-04 145 views
0

我想了解下面的代碼片段從i2c-mpc.c I2C控制器。這段代碼片段是如何工作在I2C控制器

https://github.com/torvalds/linux/blob/master/drivers/i2c/busses/i2c-mpc.c#L440

static int mpc_write(struct mpc_i2c *i2c, int target, 
      const u8 *data, int length, int restart) 
{ 

    int i, result; 
    unsigned timeout = i2c->adap.timeout; 
    u32 flags = restart ? CCR_RSTA : 0; 

    /* Start as master */ 
    writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags); 
    /* Write target byte */ 
    writeb((target << 1), i2c->base + MPC_I2C_DR); 

    result = i2c_wait(i2c, timeout, 1); 
    if (result < 0) 
     return result; 

    for (i = 0; i < length; i++) { 
     /* Write data byte */ 
     writeb(data[i], i2c->base + MPC_I2C_DR); 

     result = i2c_wait(i2c, timeout, 1); 
     if (result < 0) 
      return result; 
    } 

    return 0; 
} 

任何人都可以請點我確切是我們正在做的第440行writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);

是它的全部四個寄存器越來越設置到值1,究竟是什麼標誌varibales包含?

+3

請不要用 '***',以確定有問題的路線 - 它給貢獻者噩夢。 – 2014-10-04 13:44:29

+1

它或運算四位爲標誌並將結果寫入到控制寄存器。應該有一個包含文件標識「CCR_MIEN」等位掩碼,並且控制器用戶手冊應解釋在硬件了每個位控制。 – 2014-10-04 13:48:16

+1

對於寄存器描述:看到MPC107 PCI橋/內存 控制器用戶手冊,頁408個http://cache.freescale.com/files/32bit/doc/ref_manual/MPC107UM.pdf – 2014-10-04 19:40:05

回答

2

如果你想寫不可讀和不可維護的代碼(例如在ucontroller代碼經常發現),那麼有問題的聲明可以寫成:

if (restart) 
    CCR = 0xF4; 
else 
    CCR = 0xF0; 

但對於每一個可讀和可維護的代碼使用的符號名控制外設寄存器中的位(或字段/選項)。
所以對於CCR寄存器,駕駛員在直線限定這些符號45:50:

#define CCR_MEN 0x80 
#define CCR_MIEN 0x40 
#define CCR_MSTA 0x20 
#define CCR_MTX 0x10 
#define CCR_TXAK 0x08 
#define CCR_RSTA 0x04 

標準的做法是使用一個助記符寄存器作爲前綴,並重新使用硬件名稱(如在發現數據表)爲每個控制位名稱的其餘部分。
因此,函數中的第二個參數是四個常量和一個將產生0xF4或0xF0的變量的按位或運算,具體取決於傳遞的參數重新啓動的值。


注意* NIX內核(即結構良好的代碼),通常定義存儲器映射外設寄存器一樣簡單地址,並使用一個函數(或宏)來執行寫(或讀)操作,不像ucontroller代碼通常使用賦值語句的方式。該約定避免了重載寄存器名稱,以便仍然可以執行地址運算。
例如,驅動程序定義的寄存器中的驅動程序的控制寄存器

#define MPC_I2C_CR 0x08 

然後writeccr(定義)偏移寫入CCR寄存器是

static inline void writeccr(struct mpc_i2c *i2c, u32 x) 
{ 
    writeb(x, i2c->base + MPC_I2C_CR); 
} 

基地變量將包含外圍寄存器映射到的虛擬地址使用ioremap()呼叫與物理地址範圍。
而ucontroller代碼通常只是取消引用(物理)地址:

#define CCR (volatile u8 *)0x000003008 

究竟標誌varibales包含?

在行437的聲明和初始化:

u32 flags = restart ? CCR_RSTA : 0; 

相當於

u32 flags; 
if (restart != 0) { 
    flags = 0x04; /* CCR_RSTA */ 
} else { 
    flags = 0; 
} 
+0

感謝@sawdust爲您詳細的迴應這一點,我真的想知道什麼是第440行的結果,是將所有參與寄存器的推崇位在一條語句。 – 2014-10-05 05:14:08

+0

我已經回答了。你需要再次閱讀我的答案。根據傳遞的參數**重新啓動**的值,行440將分配0xF4或0xF0到控制寄存器。沒有*「所有涉及的寄存器」*,只有一個**控制寄存器**。 – sawdust 2014-10-05 06:19:49

+0

哦,對不起,我沒有得到它更早,再次感謝一次。 – 2014-10-05 06:25:31