linux gpio模擬i2c的使用/用GPIO模擬I2C匯流排-3
這個結構專門用於資料傳輸相關的addr為I2C裝置地址,flags為一些標誌位,len為資料的長度,buf為資料。這裡巨集定義的一些標誌還是需要了解一下。
I2C_M_TEN表示10位裝置地址
I2C_M_RD讀標誌
I2C_M_NOSTART無起始訊號標誌
I2C_M_IGNORE_NAK忽略應答訊號標誌
回到for,這裡的num代表有幾個struct i2c_msg,進入for語句,接下來是個if語句,判斷這個裝置是否定義了I2C_M_NOSTART標誌,這個標誌主要用於寫操作時,不必重新發送起始訊號和裝置地址,但是對於讀操作就不同了,要呼叫i2c_repstart這個函式去重新發送起始訊號,呼叫bit_doAddress
- static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
- {
- unsigned short flags = msg->flags;
- unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
- unsigned char addr;
- int ret, retries;
- retries = nak_ok ? 0 : i2c_adap->retries;
- if (flags & I2C_M_TEN) {
- /* a ten bit address */
- addr = 0xf0 | ((msg->addr >> 7) & 0x03);
- bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
- /* try extended address code...*/
- ret = try_address(i2c_adap, addr, retries);
- if ((ret != 1) && !nak_ok) {
- dev_err(&i2c_adap->dev,
- "died at extended address code\n");
- return -EREMOTEIO;
- }
- /* the remaining 8 bit address */
- ret = i2c_outb(i2c_adap, msg->addr & 0x7f);
- if ((ret != 1) && !nak_ok) {
- /* the chip did not ack / xmission error occurred */
- dev_err(&i2c_adap->dev, "died at 2nd address code\n");
- return -EREMOTEIO;
- }
- if (flags & I2C_M_RD) {
- bit_dbg(3, &i2c_adap->dev, "emitting repeated "
- "start condition\n");
- i2c_repstart(adap);
- /* okay, now switch into reading mode */
- addr |= 0x01;
- ret = try_address(i2c_adap, addr, retries);
- if ((ret != 1) && !nak_ok) {
- dev_err(&i2c_adap->dev,
- "died at repeated address code\n");
- return -EREMOTEIO;
- }
- }
- } else { /* normal 7bit address */
- addr = msg->addr << 1;
- if (flags & I2C_M_RD)
- addr |= 1;
- if (flags & I2C_M_REV_DIR_ADDR)
- addr ^= 1;
- ret = try_address(i2c_adap, addr, retries);
- if ((ret != 1) && !nak_ok)
- return -ENXIO;
- }
- return 0;
- }
- 1. static int try_address(struct i2c_adapter *i2c_adap,
- 2. unsigned char addr, int retries)
- 3. {
- 4. struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
- 5. int i, ret = 0;
- 6.
- 7. for (i = 0; i <= retries; i++) {
- 8. ret = i2c_outb(i2c_adap, addr);
- 9. if (ret == 1 || i == retries)
- 10. break;
- 11. bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
- 12. i2c_stop(adap);
- 13. udelay(adap->udelay);
- 14. yield();
- 15. bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
- 16. i2c_start(adap);
- 17. }
- 18. if (i && ret)
- 19. bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "
- 20. "0x%02x: %s\n", i + 1,
- 21. addr & 1 ? "read from" : "write to", addr >> 1,
- 22. ret == 1 ? "success" : "failed, timeout?");
- 23. return ret;
- 24. }
最主要的就是呼叫i2c_outb傳送一個位元組,retries為重複次數,看前面adap->retries= 3;
如果傳送失敗,也就是裝置沒有給出應答訊號,那就傳送停止訊號,傳送起始訊號,再發送這個地址位元組,這就叫retries。來看這個具體的i2c_outb函式
[html] view plaincopyprint?- 1. static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
- 2. {
- 3. int i;
- 4. int sb;
- 5. int ack;
- 6. struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
- 7.
- 8. /* assert: scl is low */
- 9. for (i = 7; i >= 0; i--) {
- 10. sb = (c >> i) & 1;
- 11. setsda(adap, sb);
- 12. udelay((adap->udelay + 1) / 2);
- 13. if (sclhi(adap) <0) { /* timed out */
- 14. bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
- 15. "timeout at bit #%d\n", (int)c, i);
- 16. return -ETIMEDOUT;
- 17. }
- 18. /* FIXME do arbitration here:
- 19. * if (sb && !getsda(adap)) -> ouch! Get out of here.
- 20. *
- 21. * Report a unique code, so higher level code can retry
- 22. * the whole (combined) message and *NOT* issue STOP.
- 23. */
- 24. scllo(adap);
- 25. }
- 26. sdahi(adap);
- 27. if (sclhi(adap) <0) { /* timeout */
- 28. bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
- 29. "timeout at ack\n", (int)c);
- 30. return -ETIMEDOUT;
- 31. }
- 32.
- 33. /* read ack: SDA should be pulled down by slave, or it may
- 34. * NAK (usually to report problems with the data we wrote).
- 35. */
- 36. ack = !getsda(adap); /* ack: sda is pulled low -> success */
- 37. bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c,
- 38. ack ? "A" : "NA");
- 39.
- 40. scllo(adap);
- 41. return ack;
- 42. /* assert: scl is low (sda undef) */
- 43. }
這個函式有兩個引數,一個是structi2c_adapter代表I2C主機,一個是傳送的位元組資料。那麼I2C是怎樣將一個位元組資料傳送出去的呢,那再來看看協議。
首先是傳送位元組資料的最高位,在時鐘為高電平期間將一位資料傳送出去,最後是傳送位元組資料的最低位。傳送完成之後,我們需要一個ACK訊號,要不然我怎麼知道傳送成功沒有,ACK訊號就是在第九個時鐘週期時資料線為低,所以在一個位元組資料傳送完成後,還要將資料線拉高,我們看程式中就是這一句sdahi(adap);等待這個ACK訊號的到來,這樣一個位元組資料就傳送完成。
回到bit_xfer函式中,前面只是將裝置地址位元組傳送出去了,那麼接下來就是該傳送資料了。
注意:這裡的資料包括操作裝置的基地址
如果是讀則呼叫readbytes函式去讀,如果是寫則呼叫sendbytes去寫,先看readbytes函式
[html] view plaincopyprint?- 1. static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
- 2. {
- 3. int inval;
- 4. int rdcount = 0; /* counts bytes read */
- 5. unsigned char *temp = msg->buf;
- 6. int count = msg->len;
- 7. const unsigned flags = msg->flags;
- 8.
- 9. while (count > 0) {
-
10. inval
相關推薦
linux gpio模擬i2c的使用/用GPIO模擬I2C匯流排-3
這個結構專門用於資料傳輸相關的addr為I2C裝置地址,flags為一些標誌位,len為資料的長度,buf為資料。這裡巨集定義的一些標誌還是需要了解一下。 I2C_M_TEN表示10位裝置地址 I2C_M_RD讀標誌 I2C_M_NOSTART無起始訊號標誌 I2
Linux下用文件IO的方式操作GPIO(/sys/class/gpio)(轉)
char include clu wro linux fcntl sysfs 查看 printf 通過sysfs方式控制GPIO,先訪問/sys/class/gpio目錄,向export文件寫入GPIO編號,使得該GPIO的操作接口從內核空間暴露到用戶空間,GPIO的操作接
Linux內核調用I2C驅動_以MPU6050為例
匹配 獲取 inux error: sdn git alt 說明 時鐘 Linux內核調用I2C驅動_以MPU6050為例 0. 導語 最近一段時間都在惡補數據結構和C++,加上導師的事情比較多,Linux內核驅動的學習進程總是被阻礙、不過,十一假期終於沒有人打擾,有這個奢
USB轉CAN匯流排介面卡/分析儀 模組 相容USB-I2C/SPI/GPIO/UART/ADC
名稱:緯圖Ginkgo USB-CAN匯流排介面卡品牌:ViewTool/緯圖型號:VTG202A 典型應用:- 通過USB介面實現對CAN匯流排網路的傳送和接收 - CAN網路資料採集、資料分析 - USB介面轉CAN網路介面 - CAN程式除錯,延長CAN匯流排的網路通訊長度 - 工業現場C
用qemu模擬i386的linux核心,用於核心學習
安裝 apt-get install qemu 下載http://kernel.org/ 這裡也測試過4.5版本,但是無法啟動 wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.7.4.tar.bz2 tar
用Fiddler模擬低速網絡環境(弱網)
鏈接 一位 enter 所有 通過 repl rscript uic 限制 原文鏈接:http://caibaojian.com/fiddler.html 有時候寬頻網路用習慣了… 在開發的過程就比較少去考慮最佳化的問題… 但當有人反應說「你的網頁好慢」 甚至當網路速度慢,
用ES5模擬實現ES6中的Map類
fun 遍歷 false 創建 per 映射 .get script 實例 ECMAScript6原生實現了Map類,即我們所說的字典,字典和集合很像,不過集合是以值值得形式存儲元素,字典則是以鍵值的形式存儲元素。字典也叫映射。 1. 創建一個字典 function M
PostMan模擬Post請求時 模擬用戶登錄狀態
測試 .com cnblogs post請求 技術 head com post 調試 1.打開Chrome 登錄要測試的網站 2.打開開發者調試工具,點開NetWork,復制Cookie 3.將整段Cookie復制到PostMan的Headers裏 4.大功告成!可以開
pythonGUI編程用Canvas模擬畫板
idt paint create -1 tkinter png height width ges 代碼如下: from tkinter import * import webbrowser root = Tk() w = Canvas(root,width=400,h
用chrome模擬微信瀏覽器訪問需要OAuth2.0網頁授權的頁面
mil col cnblogs bre letter 型號 默認 刷新 build 現在很流行微信網頁小遊戲,用html5制作的小遊戲移過來,可以放到微信瀏覽器中打開,關鍵是可以做成微信分享朋友圈的形式,大大提高遊戲的傳播,增強好友的遊戲互動。 微信瀏覽器中打開網頁遊戲效
用Fiddler模擬低速網絡環境【轉】
正在 www. itl rdl pro 存檔 url 資源 wid 原文鏈接:http://caibaojian.com/fiddler.html 我們為什麽要限速 限速對於web前端研發是非常重要的,由於開發者的機器一般配置都很高,並且是在localhost下來調試程
用RGBD模擬激光雷達數據:depthimage_to_laserscan
功能 ati github 雷達 ack div color back continue 參考:http://wiki.ros.org/depthimage_to_laserscanhttps://github.com/ros-perception/depthimage_t
【作業】用棧模擬dfs
模擬 clu AD string crt code warnings style cin 題意:一個迷宮,起點到終點的路徑,不用遞歸。 題解: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include
編寫一個模擬註冊用戶和驗證用戶登陸的程序
一個 input bsp BE 不存在 == code AS ges import hashlib import loggin User_pass = {‘11‘:‘ e1942a04175fdbe80e7fea0c40f7bf54‘} def get_md5(self):
自己用ul模擬實現下拉多選框,
ogg point shee index ati ref -m order nowrap 模擬實現下拉多選框 效果如下 <!DOCTYPE html> <html lang="en"> <head> <meta char
PTS模擬海量用戶訪問,助力懂球帝應對日增百萬用戶
應對 ima 訪問量 image 實現 tex 流量 col 客戶 摘要: 零門檻上手,可達千萬TPS的施壓能力,全球首家支持實時調速的能力,流量仿真能力全行業領先。 今年夏天刷遍各大社交網絡的除了世界杯期間的黑馬頻出、英雄遲暮、老帥離別、新人輩出,還有那一張張讓你禁不住轉
vue專案用json模擬資料
基於node和express 1,先寫一個json檔案,例如data.json { seller:[ ....... ], goods: [ ...... ] } 2,自dev-server裡寫 var appData=requir
用postman模擬ajax傳送json資料的筆記
header是這個: 但是你後臺,你知道嗎,用request.getParameter("sysName");是接受不到的, 因為json串在requset的body中。如果不用@RequsetBody註解,那就要寫方法從流中讀取引數。 public static String getRequ
Linux應用層直接操作GPIO
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
山科java實驗4-2 用HashMap模擬一個網上購物車。
用HashMap模擬一個網上購物車。要求:從鍵盤輸入n本書的名稱、單價、購買數量,將這些資訊存入一個HashMap,然後將該HashMap作為引數呼叫方法getSum(HashMap books),該方法用於計算書的總價並返回。【說明:鍵盤輸入可使用Scanner類】 package 作業2