最近客戶在使用i.MX RT1010的I2C作為從機(jī)設(shè)備與主機(jī)通訊,使用了時(shí)鐘延展的功能(clock stretching)。在開發(fā)過程中遇到了一些小煩惱和小細(xì)節(jié),在此呢,也寫下一篇文檔予以總結(jié)。
什么是時(shí)鐘延展
首先,簡單介紹一下什么是時(shí)鐘延展。時(shí)鐘延展是指從機(jī)通過將SCL拉低以暫停數(shù)據(jù)傳輸?shù)囊粋€(gè)過程,在暫停過程中,從機(jī)可以有更多的時(shí)間處理接收到的數(shù)據(jù),或者準(zhǔn)備即將發(fā)送的數(shù)據(jù)。在相關(guān)的處理和準(zhǔn)備完成之后,將交出SCL的控制權(quán),主機(jī)繼續(xù)控制SCL的節(jié)奏進(jìn)行數(shù)據(jù)的收發(fā)。換句話說,時(shí)鐘延展是從機(jī)跟不上主機(jī)的速度,讓老司機(jī)等等它,啊不,是讓主機(jī)等等它的操作。
時(shí)鐘延展通常分為兩種,一種是字節(jié)級(jí)(byte)的時(shí)鐘延展,一種是比特級(jí)(bit)的時(shí)鐘延展。字節(jié)級(jí)的時(shí)鐘延展是按照字節(jié)為單位開展,每一個(gè)字節(jié)收發(fā)結(jié)束之后啟動(dòng)。比特級(jí)則是每個(gè)數(shù)據(jù)bit都進(jìn)行延展,強(qiáng)行讓master慢下來。
在查閱相關(guān)資料的過程中發(fā)現(xiàn),并不是所有的I2C從機(jī)設(shè)備都支持時(shí)鐘延展,例如I2C的傳感器,部分存儲(chǔ)設(shè)備;也并不是所有的主機(jī)設(shè)備也支持時(shí)鐘延展,例如使用IO口模擬實(shí)現(xiàn)的I2C或者是FPGA上實(shí)現(xiàn)的I2C。因此在使用之前,需要檢查器件自身是否支持時(shí)鐘延展。
四種時(shí)鐘延展功能
在我們i.MX RT1010上總共支持4種字節(jié)級(jí)的時(shí)鐘延展:
下面我們將對(duì)這四種時(shí)鐘延展的功能進(jìn)行簡要介紹,以下介紹均為從機(jī)視角。
延展功能1:收完地址等一等
在從機(jī)接收完主機(jī)發(fā)送的地址信息后,且AVF 置位,則此時(shí)從機(jī)獲得SCL的控制權(quán),開始持續(xù)拉低SCL開啟時(shí)鐘延展。那么什么時(shí)候結(jié)束呢,從硬件狀態(tài)機(jī)的角度看,當(dāng)AVF bit被清除,時(shí)鐘延展結(jié)束,主機(jī)獲得SCL的控制權(quán)。
舉個(gè)例子,用我們SDK工程在接收到地址信息后強(qiáng)行延時(shí)500us再去清除AVF bit, 看看波形是怎樣的:
從圖中可以看到,兩次時(shí)鐘間隔約491us,基本上與500us的預(yù)期相匹配。并不是完美的500us的原因是,延時(shí)函數(shù)沒有使用定時(shí)器精確延時(shí)。
延展功能2:發(fā)送之前等一等
在從機(jī)接收到主機(jī)的地址信息和讀指令后,TDF將會(huì)置位,則此時(shí)從機(jī)獲得SCL的控制權(quán)。同樣是在清除TDF bit之后,主機(jī)再次獲得SCL的控制權(quán)。在這個(gè)過程中,從機(jī)可以根據(jù)主機(jī)發(fā)送的信息,把要發(fā)送的數(shù)據(jù)準(zhǔn)備好,再釋放SCL的控制權(quán)。同樣舉個(gè)例子,再清除TDF bit 之前等一等,這次等的長一點(diǎn)800us。
延展功能3:接收之前等一等
在從機(jī)接收到數(shù)據(jù)之后,RDF會(huì)置位,此時(shí)從機(jī)會(huì)獲得SCL的控制權(quán)。同樣是在清除TDF bit之后,主機(jī)再次獲得SCL的控制權(quán)。拉個(gè)波形看看,在清標(biāo)志位前拉個(gè)1000us的延時(shí),波形如下圖所示。
延展功能4:手動(dòng)回ACK
這里是指,當(dāng)主機(jī)把數(shù)據(jù)(地址信息或者數(shù)據(jù)信息)發(fā)送給從機(jī)后,在傳送完第八個(gè)bit(或者說是第八個(gè)時(shí)鐘)之后,從機(jī)即獲得了SCL的控制權(quán)限,在此時(shí)需要手動(dòng)向STAR寄存器中最后一位寫0或者1,以向主機(jī)反饋ACK 或者NACK。在寫0之前,我們?cè)黾右粋€(gè)500us的延時(shí),地址信息的波形見下圖,可以看到第八個(gè)和第九個(gè)CLK時(shí)鐘的間隔被拉長。
從機(jī)接收數(shù)據(jù)的信息見下圖,同樣可以看到,第八個(gè)和第九個(gè)的時(shí)鐘被拉長了。
時(shí)鐘延展的時(shí)序要求
在使用時(shí)鐘延展的功能后,同樣不能忽略的一個(gè)要點(diǎn)是要滿足I2C的AC timing,即數(shù)據(jù)的建立時(shí)間和保持時(shí)間。對(duì)于不同的工作速度,I2C對(duì)于這兩個(gè)參數(shù)的時(shí)間要求也是不同的,下圖為I2C的規(guī)范上的截圖。
對(duì)于i.MX RT1010來說,我們?cè)陂_啟時(shí)鐘延展功能后需要對(duì)下面的兩個(gè)參數(shù)進(jìn)行設(shè)置,以滿足I2C的timing要求。
CLKHOLD: I2C的數(shù)據(jù)的建立時(shí)間,需要根據(jù)不同的通訊速度進(jìn)行設(shè)置。
DATAVD: I2C的數(shù)據(jù)保持時(shí)間,通常來看保持為0即可。
如果不能正確設(shè)置CLKHOLD的時(shí)間會(huì)怎樣呢?
造成時(shí)序混亂,當(dāng)SCL的驅(qū)動(dòng)能力較強(qiáng),且SDA的負(fù)載較重的時(shí)候,甚至?xí)餝CL上升的比SDA速度快,那么想一下I2C的停止條件,當(dāng)SCL處于高電平時(shí),SDA拉高。那么就會(huì)讓總線停止傳輸,除此以外,可能還會(huì)有其他的未知問題發(fā)生。
其次,關(guān)于CLKHOLD時(shí)間的計(jì)算,目前的驅(qū)動(dòng)程序是有些小問題的。因此建議徒手?jǐn)]寄存器,自己把想要的數(shù)值填寫到CLKHOLD寄存器內(nèi)。對(duì)于具體的時(shí)間,計(jì)算公式如下:
t =(CLKHOLD + 3) * Tclk
這里的Tclk是指I2C的functional clock的周期。因此,真正的建立時(shí)間,是CLKHOLD的數(shù)值和I2C 的輸入時(shí)鐘頻率共同作用的結(jié)果。
哦對(duì)了,如何使能時(shí)鐘延展功能?
如果你喜歡寄存器操作,那么可以在SCFGR1寄存器中的bit[3:0]直接開啟對(duì)應(yīng)的功能:
如果你習(xí)慣SDK操作,那么在這個(gè)結(jié)構(gòu)體里把對(duì)應(yīng)的功能寫true吧:
來源:恩智浦MCU加油站
審核編輯:湯梓紅
-
FPGA
+關(guān)注
關(guān)注
1629文章
21729瀏覽量
603009 -
時(shí)鐘
+關(guān)注
關(guān)注
10文章
1733瀏覽量
131451 -
I2C
+關(guān)注
關(guān)注
28文章
1484瀏覽量
123620 -
SCL
+關(guān)注
關(guān)注
1文章
239瀏覽量
17057
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論