今天接到客戶的來信告知某產品I2C通訊有問題,於是乎測試了這個產品,下指令讓其做動作都正確無誤,蝦密,要求回傳一些裝置的資訊卻都不對.

客戶是用USB-ISS去測試,手上剛好有USB2I2C這個東西(當時買這玩意兒,真是對的決定,"不在乎天長地久,只在乎想要就有”).兩者看起來相當類似,都是用廠商軟體提供的Dll送信息給USBI2C這玩意兒,再靠這個裝置去產生I2C訊號去和目的裝置溝通.

 

                  images  

                  USB2I2C

 

賓果,我的結局跟廠商提供的結果類似,人客阿我知道你的tone.

I2C靠的就是SCL(時間頻率)SDA(資料),兩者間的變化去相互溝通imagesCA7OP3XW  

 

因此又區分為Master(主裝置, 發號施令)Slave(僕裝置,一口令一動作,不能直接打小報告,要皇帝昭曰時才能報告)兩種,都是由MasterSlave發號施令(下命令或一問一答),Slave無法直接呼叫Master.因此Master呼叫Slave做動作或是讀狀態,有時Slave動作太慢,就需要有個延遲時間.

 

好禮加在,當時拿到USB2I2C時就用C#寫了一些程式(之前的文章有貼完整的程式碼),剛好有寫到時間延遲的功能,於是心裡相當得意的想,~~嘿應該沒問題了.測試的結果當然是不行.可以的話也就沒這篇文章了.

測試程式:(C#開發,可用UCB,USB2I2C,8051… 來送指令)

將指令藉由RS232(UART)方式輸入給8051開發板,開發板再將其轉成I2C格式與裝置溝通.

B3-1       

GUI操作

 

 

只好拿出上我們上一代玉女掌門人Hello Kitty 留下來的法寶,邏輯分析儀.

     la_c1604          

                    邏輯分析儀

於是接上了邏輯分析儀去分析訊息傳送的圖形,發現SDA腳位傳送是對的.SCK也是對的.

USB2I2C-1  

靠直覺告訴我SDA是沒問題的,因此SDA應該屏除在外,就剩下SCLMasterSlave之間存在著我們不知道的秘密.

此時SCLMaster Slave三者的關係,如野火燎原般越演越烈,究竟這三者是命運的安排,還是情感的糾結,或是另有隱情?真相到底是什麼,讓我們繼續看下去.

靠廠商提供的DLL已經無法解決這個問題了,還好櫻櫻美代子那時候使用8051開發板來練習組合語言並寫了一支韌體(之前的文章有貼整個程式碼).

 

8051開發板(AT89S52): 

DSCN5784-1-1  

好處:不需燒錄工具,經開發軟體編譯成HEX,即可使用燒錄軟體寫入Flash.

缺點:不能線上Debug,都要用猜的,真的是曠日廢時.

 

燒錄程式(本來想自己寫,但是模擬板使用了一顆PIC18F2455USB溝通晶片,它的資料約430,只好先放下,等有朝一日再來練了).

 B2-1  

燒錄程式介面(廠商提供)

 

於是拿出AT89S52開發板來模擬I2C,這個MCU硬體並未支援I2C,所以當時開發時只能使用GPIO其中的的兩隻腳未來模擬I2C,接上了這個模擬板再略為修改一下韌體控制.經過了一天的廝殺,終於得到了跟上面一樣的結果,歐賣尬.

 

只好轉向估狗大神拜求,經過大神的敦敦教誨發現了 clock stretch 這個課題.也讓我回憶起,當時輕狂年少的我,某日拿到一本武功秘笈拼命苦練時,其中的要訣無法融會貫通,又怕硬練會造成像歐陽鋒一樣無法抹滅的傷害,再次拿起武功秘笈微處理機/單晶片 組合語言教學範本”,翻到 13- I2C 串列通訊與即時時鐘之應用,某一頁中提到當一個位元組傳完,而接收器也回傳ACK訊號後,如果接收器需要一段儲存收到位元組資料的時間,則可以利用控制SCL腳位為低電位方式,SCL維持在低電位直到收訊者可以接收下一個位元組為止.’

沒錯指的就是這裡了,原來真的是可以倒立的,與之前學到的概念,SCL都是由Master來控制,有所出入,無奈此秘笈沒提任何的姿勢(知識),如何實做這一段程式,只好訴諸自己,想想辦法囉.

                 book1                      

              武功秘笈(還好不是花十元買到的如來神掌)

 

拿出一堆雞絲,架好產品,接上邏輯分析儀,開始一步一步模擬.真的讓我看到了SCL拉低電位好久才升高電位.也應證了上面的說法,那該如何解決這個問題?

 AT89S52-NoDelay1-1  

藍色框框就是Master時間未到已經在收資料

使用輪詢(Polling)的模式來偵測SCL這個腳位,當其由低電位變高電位時,再與其溝通.可是怎麼測SCL都不會變為高電位,持續保持低電位,此時李組長眉頭一皺,發現事情並不單純.

 AT89S52-NoReply1-1  

無情的SCL一去不回了

 

事情發生至今也有一些時間了,既然自動偵測目前沒有辦法解決,山不轉路轉,路不轉,我們自己轉,只好使用傳統延遲的方法(NOP.NOP..),自己慢慢加減延長時間.硬是把它完成了.

 

1.再送出Read訊號後要延遲等待時間.

 B1-1  

完整的傳送接收圖,A-ACK就是 SCL 下拉為低電位的時間

 

2.在回傳每個位元組之間亦須延遲等待時間.

B6-1   

接收每個位元組之間等待的時間(D-ACK)

 

再次回到使用自動補捉SCL升為高電壓的時間點,與同是商討後,再次使用輪詢方式,再詢問前Master先將SCL拉為高電壓後再去偵測SCL腳位,這招果然有效.

 AT89S51-AutoCheck2-1  

終於見到署光了,你可以再靠近一點.

 AT89S51-AutoDetail-1  

挖例哩,黃色框框這邊怎麼不一樣,因為輪詢前把SCL先提升為高電位,導致資料錯位了.

8051依舊無法自動去偵測SCL腳位電壓由低變到高,換了其他的腳位去做測試結果更糟糕,或許其他腳位為了測試其他元件可能串聯或並聯某些電阻,進而影響到了SCL的頻率導致結果一整個大失誤.

或許在不久的將來,因緣際會或仙人指點,還是撿到九陽神經,那麼我就會再寫一篇測試文,讓我們一齊來期待吧.

 

因為手上又有另一塊模擬板,MCUARM LPC2103,這一個MCU是有硬體支援I2C不知道他能否自動偵測SCL這個腳位?

 DSCN5785-1           

國父說知難行易,因此在寫一下韌體試試就知道結果了.

花了兩天時間將韌體寫完.也得到了測試結果.

果然不負眾望,MCU的硬體可以自動偵測SCL腳位的高低.

與上面用NOP方式互相比較可以得到正確的延遲時間.

 

 B4-1  

完整的傳送接收圖,A_ACK就是 SCL 下拉為低電位時間(更精準)

 B5-1  

 

接收每個位元組之間等待的時間(DACK)

 

 

Anyway.

上面再寫甚麼完全看不懂,沒關係.

以下才是重點.

假使我們下了指令”0x92,0x8D” 要求回傳 3個位元組的資料.

0x92是位址,0x8D要求回傳裝置的資料.

 B7-1  

圖中

1.第一個橘色(0x49,bit7 –bit1)和深粉紅(0,bit0),這兩個合併就是0x92.這是告訴所有連結在線路上的裝置(Slave,可以多個),聽到請答有.

2.再來的粉紅就跟最後的粉紅都一樣是A-ACK(A:Address),Slave答有,表示有收到0x92,A-ACK告訴Master收到了位址資料.

3.綠色的0x8D.

4.淺綠的D-ACK(D:Data),告訴Master我有收到資料.

5.咖啡色的Stop,就是Master告知Slave停止傳輸.

6.淺藍色的Start,表示第二道指令開始了.(呼叫Slave丟資料).步驟1之前應該有個Start,因為圖放不下了,因此沒出現.否則還要有個步驟0來送Start.

7.再次傳Slave位址,但與第一步驟不同在於藍色的Read(1,bit0),因此橘色混合藍色就變成0x93,

8.被呼叫端再次答有,並且把SCL下拉.為何要下拉.當然是沒辦法馬上給你資料.

下拉SCL告知你要忍耐.在不久的將來,他會再回來.

 

 B8-1  

  1. 經過了煎熬(換算成人類世界的時間約3,因為花3天的時間確認真正原因)
  2. 綠色的0xC1就是Slave送給Master的資料.
  3. 淺綠的D-ACK就是Master告知Slave已經收到資料了,可以放馬過來.

結果卻挨了一槍,這邊SCL又再度被Slave給拉低了.

  1. 收資料.
  2. 再一槍.
  3. 收資料.
  4. 綠色D-NACKMaster告知Slave不要再送了,如果三聲槍響武昌革命就要起義了.
  5. 褐色Stop Master停止了所有通信.

 

上述是使用MCU硬體不支援I2C,只能用GPIO腳位去模擬I2C的分解步驟.

如使用MCU硬體支援I2C就沒上述問題,他的硬體會自動幫你偵測SCL是否被拉低,如果有就等到他回復到高電位.

根據查詢的結果,得到MicroChip是支援將SCL拉成低電位功能的MCU之一.

拉低電位的壞處就是,萬一拉低電位者回不來了,當在那邊,那你那一串裝置都不要想要在做任何事了.因為SCL永遠都是低電位.

arrow
arrow
    全站熱搜

    linear 發表在 痞客邦 留言(2) 人氣()