系列文章目錄
第三章 DW_i2c功能及使用流程介紹
文章目錄
前言
一、功能介紹
1.1 i2c寫操作:
1.1.1 詳細(xì)flow介紹
1.2 i2c讀操作:
1.2.1 詳細(xì)flow介紹
二、軟件流程介紹
2.1 定義WDT中斷服務(wù)子程序
2.2 定義main函數(shù)
三、總結(jié)
前言
? ? ?按照i2c的協(xié)議,i2c的時鐘由master方提供,master可以向slave發(fā)送數(shù)據(jù),也可以向slave請求數(shù)據(jù)。對應(yīng)的slave既可以接收來自master發(fā)送的數(shù)據(jù),也可以響應(yīng)master請求數(shù)據(jù)。關(guān)于i2c協(xié)議,后續(xù)我們會單獨(dú)講解里面的細(xì)節(jié)和注意事項(xiàng),這里我們主要接收使用過程中的一些基本配置flow。
一、功能介紹
? ? ? ?這里簡單介紹一下i2c讀寫過程涉及到flow:
1.1 i2c寫操作:
1.1.1 詳細(xì)flow介紹
step1:首先master發(fā)起i2c start,即在sclk高電平拉低sda;
step2:發(fā)送slave設(shè)備地址,與之通信,這個設(shè)備地址按照協(xié)議可以是7bit,也可以是10bit,這里介紹最簡單的7bit模式。
step3:緊接著發(fā)送一個bit的寫控制位,表示當(dāng)前傳輸為一筆寫操作。
step4:然后后續(xù)跟著兩個byte的數(shù)據(jù),這兩個byte數(shù)據(jù)一般用于軟件解析命令用,通常情況下收發(fā)雙方可以利用這兩個byte自定義一些私有協(xié)議,比如最簡單的就是兩個純粹的mem地址0x1000,表示master即將向0x1000地址寫數(shù)據(jù),因此后續(xù)master發(fā)送過來的Data,需要軟件將其搬運(yùn)到系統(tǒng)mem 0x1000地址去。當(dāng)然也可以將這兩個byte拆分成多個不同的命令,方便系統(tǒng)靈活運(yùn)用。
step5:然后是發(fā)送過來的真正的payload數(shù)據(jù)
step6:當(dāng)master完成數(shù)據(jù)寫傳輸后,發(fā)送stop,即在scl的高電平拉高sda,結(jié)束當(dāng)前傳輸。
1.2 i2c讀操作:
1.2.1 詳細(xì)flow介紹
step1:首先master發(fā)起i2c start,即在sclk高電平拉低sda;
step2:發(fā)送slave設(shè)備地址,與之通信,這個設(shè)備地址按照協(xié)議可以是7bit,也可以是10bit,這里介紹最簡單的7bit模式。
step3:緊接著發(fā)送一個bit的寫控制位,表示當(dāng)前傳輸為一筆寫操作。
step4:然后后續(xù)跟著兩個byte的數(shù)據(jù),這兩個byte數(shù)據(jù)一般用于軟件解析命令用,通常情況下收發(fā)雙方可以利用這兩個byte自定義一些私有協(xié)議,比如最簡單的就是兩個純粹的mem地址0x1000,表示master即將向0x1000地址寫數(shù)據(jù),因此后續(xù)master發(fā)送過來的Data,需要軟件將其搬運(yùn)到系統(tǒng)mem 0x1000地址去。當(dāng)然也可以將這兩個byte拆分成多個不同的命令,方便系統(tǒng)靈活運(yùn)用。
step5:這里master發(fā)送了一個re_start操作,即在scl的高電平拉低了sda,而并非發(fā)送payload數(shù)據(jù),這里其實(shí)是一個讀的轉(zhuǎn)身,當(dāng)slave接收到re_start時,會認(rèn)為master其實(shí)想讀數(shù)據(jù),訪問的數(shù)據(jù)地址體現(xiàn)在2byte信息里。因此,此時軟件需要從內(nèi)存地址里取數(shù)據(jù)并加載到i2c tx fifo中;
step6:按照協(xié)議重新發(fā)送設(shè)備地址以及R控制bit,這里配合step5供軟件解析讀過程。
step7:slave會根據(jù)軟件填寫的tx fifo值,把數(shù)據(jù)發(fā)送出去。
step8:當(dāng)master接收完數(shù)據(jù)后,發(fā)送stop,即在scl的高電平拉高sda,結(jié)束當(dāng)前傳輸。
二、軟件流程介紹
2.1 定義WDT中斷服務(wù)子程序
中斷handler定義:
int dw_i2c_int_handler()
{
int rdata;
rdata = REG32(I2C_INTR_STAT); //read intr status
//judge which intr bit trigger
if((rdata & 0x1) == 0x1) //rx_under
{
rdata = REG32(I2C_CLR_RX_UNDER); //read clear
}
else if((rdata & 0x2) == 0x2) //rx_over
{
rdata = REG32(I2C_CLR_RX_OVER); //read clear
}
else if((rdata & 0x4) == 0x4) //rx_full
{
rdata = REG32(I2C_DATA_CMD); //read recv data
}
else if((rdata & 0x8) == 0x8) //tx_over
{
rdata = REG32(I2C_CLR_TX_OVER); //read clear
}
else if((rdata & 0x10) == 0x10) //tx_empty
{
REG32(I2C_DATA_CMD) = 0x12; //cpu initial data into tx fifo
}
else if((rdata & 0x20) == 0x20) //rd_req
{
REG32(I2C_CLR_RD_REQ); //clr stop
REG32(I2C_DATA_CMD) = 0x12; //cpu initial data into tx fifo
}
else if((rdata & 0x40) == 0x40) //tx_abrt
{
rdata = REG32(I2C_CLR_TX_ABRT); //read clear
}
else if((rdata & 0x80) == 0x80) //rx_done
{
rdata = REG32(I2C_CLR_RX_DONE); //read clear
}
else if((rdata & 0x100) == 0x100) //activity
{
rdata = REG32(I2C_CLR_ACTIVITY); //read clear
}
else if((rdata & 0x200) == 0x200) //stop_det
{
REG32(I2C_CLR_STOP_DET); //clr stop
}
}
? ? ?這里是一個通用的中斷handler,大家可以根據(jù)注釋以及datasheet上的描述對此進(jìn)行擴(kuò)展,比如有些軟件需要在tm_empty中斷發(fā)生的時候CPU填寫數(shù)據(jù),以及fifo full中斷的時候CPU需求將數(shù)據(jù)取走等等。具體還要根據(jù)實(shí)際應(yīng)用情況來做擴(kuò)展。
? ? 當(dāng)然,對于EDA驗(yàn)證來說,這里相對來說更靈活,可以根據(jù)驗(yàn)證環(huán)境情況來自定義中斷handler。
2.2 定義main函數(shù)
?main函數(shù)
int main()
{
CLK_DW_I2C_EN; //打開i2c模塊的時鐘使能,根據(jù)設(shè)計(jì)需求
//may be i2c share gpio with module, this cfg can be used
GPIO_FUNC_SEL_I2C; //配置gpio功能為DW_I2C
set_irq_vector(NVIC_NUM_DW_I2C, (int)dw_i2c_int_handler); //配置中斷服務(wù)向量
__nds32_enable_int(NVIC_NUM_DW_I2C); //使能CPU中斷
//dw i2c initial
REG32(I2C_ENABLE) = 0x0; //在配置i2c之前一定要先disable i2c_en
REG32(I2C_SDA_HOLD) = 0x5; //可選,具體參考datasheet描述
REG32(I2C_FS_SPKEN) = 0x2; //濾除毛刺的深度,建議根據(jù)需求配置
REG32(I2C_TX_TL) = 0x4; //tx fifo水線
REG32(I2C_RX_TL) = 0x4; /rx fifo水線
REG32(I2C_CON) = (REG32(I2C_CON) & 0xFFFFFF80) | 0x65); //master mode and 400k
REG32(I2C_FS_SCL_HCNT) = 0x6; //scl高電平寬度配置,根據(jù)需求修改
REG32(I2C_FS_SCL_LCNT) = 0x6; //scl低電平寬度配置,根據(jù)需求修改
REG32(I2C_ENABLE) = 0x1; //使能i2c
//填寫tx fifo數(shù)據(jù),硬件會自動將數(shù)據(jù)發(fā)送出去,這里填數(shù)據(jù)也可以放到int_handler中
REG32(I2C_DATA_CMD) = 0x12;
REG32(I2C_DATA_CMD) = 0x34;
REG32(I2C_DATA_CMD) = 0x56;
......
while(發(fā)送中斷完成);
}
? ? ?上述main函數(shù)中,本文詳細(xì)介紹了DW_i2c的初始化流程,里面的步驟基本上是必不可少的,當(dāng)然,有一些配置可以根據(jù)實(shí)際情況進(jìn)行調(diào)整,同時,如果使用i2c的更多功能,還需要大家自行添加相關(guān)寄存器配置。
三、總結(jié)
? ? ? 這里只是介紹了master發(fā)送的相關(guān)case配置,實(shí)際上DW_I2C可以配置為master/slave模式,且兩個模式可以分別支持收發(fā),即理論上來收還有其他三種case,master收數(shù)據(jù),slave發(fā)數(shù)據(jù)以及slave收數(shù)據(jù)。在實(shí)際設(shè)計(jì)case時,關(guān)于數(shù)據(jù)的收發(fā)可以靈活調(diào)整,借助每個中斷來進(jìn)行同步收發(fā)是一個比較好的編碼風(fēng)格。這里為了讓大家更容易理解,因此設(shè)計(jì)的case簡單化了。文章來源:http://www.zghlxwxcb.cn/news/detail-774271.html
? ? ? 在實(shí)際驗(yàn)證過程中,不僅僅要根據(jù)需求設(shè)計(jì)嚴(yán)謹(jǐn)?shù)腸ase,還要同時控制收發(fā)雙方的驅(qū)動程序,以及添加數(shù)據(jù)的自動化checker,這樣后期在大量回歸測試時,可以更快的完成回歸測試。文章來源地址http://www.zghlxwxcb.cn/news/detail-774271.html
到了這里,關(guān)于SOC系統(tǒng)經(jīng)典IP介紹以及使用方法說明之dw_i2c的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!