日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

I/O芯片扩展开发

發布時間:2023/12/9 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 I/O芯片扩展开发 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

QCA9563外接I/O擴展芯片

  • 概述
  • 實現
  • 總結

概述

CPU上的GPIO口特別有限,所以想著給現有的單板做一個I/O擴展。方案是QCA9563通過I2C,外接MCP23017,可以外出16路I/O口。配置I/O口為固定方向,8個為一組,一組輸出一組輸入。

實現

剛開始打算直接通過QCA9563自帶的I2C口控制器進行控制MCP23017芯片,但是在開發的過程中才發現沒有I2C控制器驅動代碼??赡苡捎谶@款芯片太新了,開源代碼還沒有適配,最后想著用GPIO模擬I2C的方式進行控制的。

  • 首先選中GPIO模擬I2C驅動部分
  • 注冊I2C設備static struct ath79_i2c_platform_data ath79_i2c_pdata = { .sda_pin = 5,//選中的GPIO口,串行數據線 .scl_pin = 6,//選中的GPIO口,串行時鐘線 .udelay = 5, .timeout = 100, .sda_is_open_drain = 1, .scl_is_open_drain = 1, }; static struct resource ath79_i2c_resources[] = {{.flags = IORESOURCE_MEM,.start = AR71XX_GPIO_BASE,.end = AR71XX_GPIO_BASE + AR71XX_GPIO_SIZE - 1,},{.start = ATH79_MISC_IRQ(8),.end = ATH79_MISC_IRQ(8),.flags = IORESOURCE_IRQ,}, }; static struct platform_device ath79_i2c_device = {.name = "i2c-gpio",.id = -1,.resource = ath79_i2c_resources,.num_resources = ARRAY_SIZE(ath79_i2c_resources),.dev = {.platform_data = &ath79_i2c_pdata}, }; platform_device_register(&ath79_i2c_device); 驅動跑起來之后,會創建一個i2c設備/dev/i2c-0.
  • 應用層開發
    提供讀寫接口:#define MCP23017_ADDRESS 0x20 /* mcp23017 address 通過查手冊和硬件走線即可確定*/ //通過/dev/i2c-0設備進行讀 int mcp23017_read(unsigned char regaddr, unsigned char *value) {int ret = 0;/* read data from mcp23017 *//* we used to start singnal */memset(buf1, 0, sizeof(buf1));memset(buf2, 0, sizeof(buf2));i2c_data.nmsgs = 2;i2c_data.msgs[0].len = 1;i2c_data.msgs[0].addr = MCP23017_ADDRESS;i2c_data.msgs[0].flags = 0; /* write */i2c_data.msgs[0].buf = buf1;buf1[0] = regaddr; /* regaddr */i2c_data.msgs[1].len = 1; /* test read twice ,2 */i2c_data.msgs[1].addr = 0x20;i2c_data.msgs[1].flags = I2C_M_RD;i2c_data.msgs[1].buf = buf2; /* read buff */ret = ioctl (i2c_fd, I2C_RDWR, (unsigned long)&i2c_data);if (ret < 0){ #ifdef IOEXTEND_DEBUGprint_file("[%s %d]ioctl read error\n", __FILE__, __LINE__); #endifreturn RET_ERR;}*value = buf2[0]; #ifdef IOEXTEND_DEBUGprint_file("[%s %d]%s value:0x%2x\n", __FILE__, __LINE__, register_to_string[regaddr], buf2[0]); #endifreturn RET_OK; } //通過/dev/i2c-0設備進行寫 int mcp23017_write(unsigned char regaddr, unsigned char value) {int ret = 0;/* write data to mcp23017 */i2c_data.nmsgs = 1;i2c_data.msgs[0].len = 2;i2c_data.msgs[0].addr = MCP23017_ADDRESS; /* 0100 A2A1A0 R/W 7-bit i2c addresses */i2c_data.msgs[0].flags = 0; /* write */i2c_data.msgs[0].buf = buf1;buf1[0] = regaddr; /* regaddr*/buf1[1] = value; /* write value */ret = ioctl (i2c_fd, I2C_RDWR, (unsigned long)&i2c_data);if (ret < 0){ #ifdef IOEXTEND_DEBUGprint_file("[%s %d]ioctl read error\n", __FILE__, __LINE__); #endifreturn RET_ERR;}return RET_OK; } //初始化/dev/i2c-0 int mcp23017_init() {i2c_fd = open("/dev/i2c-0", O_RDWR);if (i2c_fd < 0){ #ifdef IOEXTEND_DEBUGprint_file("[%s %d]Error on opening the /dev/i2c-0 file i2c_fd:%d\n", __FILE__, __LINE__, i2c_fd); #endifreturn RET_ERR;}ioctl(i2c_fd, I2C_TIMEOUT, 2);ioctl(i2c_fd, I2C_RETRIES, 1);i2c_data.nmsgs = 2;i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs * sizeof(struct i2c_msg));if (!i2c_data.msgs){ #ifdef IOEXTEND_DEBUGprint_file("[%s %d]Memory alloc error\n", __FILE__, __LINE__); #endifclose(i2c_fd);return RET_ERR;}mcp23017_write(REG_IODIRA, 0x00); /* out put module */mcp23017_write(REG_IODIRB, 0xff); /* in put module */mcp23017_write(REG_GPIOA, 0xff);return RET_OK; }
  • 總結

    通過read、write接口就可以控制MCP23017芯片,如果想要實時獲取芯片上的狀態,需要把芯片上的中斷引腳解出來,根據中斷來讀。或者采用輪詢模式進行讀狀態。

    總結

    以上是生活随笔為你收集整理的I/O芯片扩展开发的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。