Openwrt中MT7628/MT7688的全部GPIO複用配置及常用介面DTS配置總結
Openwrt的不同版本中關於MT7628,MT7688的GPIO配置,存在或多或少的一些小問題
下面將以MT7628AN為基礎,介紹其全部的GPIO功能複用配置,以及需要注意的地方
MT76x8一個就47個可作為GPIO引腳,如下
關於其全部的功能複用表可以參考MTK官方的開發demo版Linkit
在這全部的引腳中,需要特別注意的是:
1. 網口模式,因為MTK的設計,一共5個網口,要麼全部作為普通網口使用,要麼只有一個網口(Port0),沒有中間選項;
因此,如果需要用到UART2,SDCARD等功能時,系統只剩一個P0網口可用,這也是MTK所宣傳的IOT模式
2. SPI介面,datasheet介紹可以作為GPIO使用,但是因為大多系統都接了SPI NOR Flash,因此其不能設定為GPIO模式;而SPI_CS1另一個SPI片選腳,倒是不受影響,可作為GPIO
3. 關於GPIO/GPO的描述,比如I2C的兩個腳是GPO,但經實際測試,描述為GPO的其實可以作為輸入使用
關於DTS配置,其主要參考arch/mips/ralink/mt7620.c檔案
static struct rt2880_pmx_group mt7628an_pinmux_data[] = { GRP_G("pwm1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_PWM1), GRP_G("pwm0", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_PWM0), GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_UART2), GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_UART1), GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_I2C), GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK), GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST), GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT), GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI), GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_SDMODE), GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_UART0), GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_I2S), GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_CS1), GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_SPIS), GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_GPIO), GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_WLED_AN) }
在DTS檔案中,填寫對應的name和func名字就可以,如:
pinctrl {
state_default: pinctrl0 {
gpio {
ralink,group = "gpio","wled_an", "i2s", "refclk", "perst", "wdt", "spi cs1";
ralink,function = "gpio";
};
}
常用介面及功能配置如下:
UART1開啟:
[email protected] {
status = "okay";
};
SPI_CS1 開啟,使用系統spi控制器,注意pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>,配置CS1為SPI_CS1功能,同時應該去掉pinctrl0中"spi cs1"的GPIO複用
[email protected] {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
[email protected] {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spidev";
reg = <1 0>;
spi-max-frequency = <40000000>;
};
}
GPIO模擬SPI配置,如:使用I2S的複用腳0-3,注意先配置I2S為GPIO模式
spi-gpio {
compatible = "spi-gpio";
#address-cells = <0x1>;
cs-gpios = <&gpio0 2 0>;
gpio-sck = <&gpio0 0 0>;
gpio-mosi = <&gpio0 3 0>;
gpio-miso = <&gpio0 1 0>;
num-chipselects = <1>;
[email protected] {
#address-cells = <0x1>;
compatible = "spidev";
spi-max-frequency = <10000000>;
reg = <0>;
};
};
I2C的RTC時鐘配置,以PCF8563為例,注意reg地址的問題,pcf8563地址是0x51,常用的ds1307是0x68
[email protected] {
status = "okay";
[email protected] {
compatible = "nxp,pcf8563";
reg = <0x51>;
};
};
LED配置參考,注意MT76x8有兩組GPIO,GPIO0對應0-31,GPIO1對應32-46
gpio-leds {
compatible = "gpio-leds";
modpwr {
label = "modpwr";
gpios = <&gpio1 8 1>;
};
modrst {
label = "modrst";
gpios = <&gpio1 4 0>;
};
heart {
label = "heart";
gpios = <&gpio1 6 1>;
};
}
lable對應執行系統中/sys/class/leds/lable/brightness 的lable名字
gpios = <&gpio1 8 1>; 表示GPIO1組,8 表示 32+8 即GPIO40,1表示低電平有效,即預設輸出高電平
按鍵配置參考,
gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <20>;
vccin {
label = "BTN_0";
gpios = <&gpio0 6 0>;
linux,code = <0x100>;
};
reset {
label = "reset";
gpios = <&gpio1 7 1>;
linux,code = <0x198>;
};
};
poll-interval 表示輸入檢測消抖時間,label對應於執行系統中/etc/rc.button/lable,即按鍵後對應的執行指令碼檔案,如上述配置,系統中應該存在reset和BTN_0兩個指令碼, gpios同LED說明
linux,code = <0x198>; 對應input.h的巨集定義值,配合驅動檔案gpio-button-hotplug.c中的相關配置,如:
static struct bh_map button_map[] = {
BH_MAP(BTN_0, "BTN_0"),
BH_MAP(BTN_1, "BTN_1"),
BH_MAP(BTN_2, "BTN_2"),
BH_MAP(BTN_3, "BTN_3"),
BH_MAP(BTN_4, "BTN_4"),
BH_MAP(BTN_5, "BTN_5"),
BH_MAP(BTN_6, "BTN_6"),
BH_MAP(BTN_7, "BTN_7"),
BH_MAP(BTN_8, "BTN_8"),
BH_MAP(BTN_9, "BTN_9"),
BH_MAP(KEY_POWER, "power"),
BH_MAP(KEY_RESTART, "reset"),
BH_MAP(KEY_RFKILL, "rfkill"),
BH_MAP(KEY_WPS_BUTTON, "wps"),
BH_MAP(KEY_WIMAX, "wwan"),
};
其原理是gpio-button-hotplug驅動會檢測按鍵事件,然後通過netlionk方式廣播出來,proc會一直監測事件,觸發hotplug,進而執行到相關reset等指令碼,熱拔插事件也是此類方式,具體不再詳細介紹,本文主要介紹引腳複用配置
另,還需注意的是,配置了相關引腳功能後,還需在kernel中開啟相關驅動模組以及選擇相關的應用才能正常使用
到此,常用介面基本介紹完畢
下面大概提一下不同openwrt版本中的程式碼錯誤,以下只貼出正確的code,各位看客有功能錯誤的各自根據自己的現有版本對比修正即可
1. 看門狗dts 地址錯誤,位置:target/linux/ramips/dts/mt7628an.dtsi
watchdog: [email protected] {
compatible = "ralink,mt7628an-wdt", "mediatek,mt7621-wdt";
reg = <0x100 0x30>;
resets = <&rstctrl 8>;
reset-names = "wdt";
interrupt-parent = <&intc>;
interrupts = <24>;
};
根據DataSheet,watchdog的偏移地址應該是100
同時,如果需要自行喂狗的話,注意先關閉proc程序中自動喂狗功能
2. REFCLK,PERST的配置錯誤,位置arch/mips/ralink/mt7620.c,原來的reclk和perst引腳配置反了
static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 37, 1) };
static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) };
3. PHY 0-4的LED不能作為GPIO的問題,參考補丁檔案:
--- a/arch/mips/ralink/mt7620.c 2018-09-04 17:14:33.000000000 +0800
+++ b/arch/mips/ralink/mt7620.c 2018-04-09 08:28:51.000000000 +0800
@@ -138,8 +138,8 @@
FUNC("i2c", 0, 4, 2),
};
-static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) };
-static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) };
+static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 37, 1) };
+static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) };
static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) };
static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
@@ -185,23 +185,50 @@
FUNC("gpio", 0, 11, 1),
};
-static struct rt2880_pmx_func wled_kn_grp_mt7628[] = {
- FUNC("rsvd", 3, 35, 1),
- FUNC("rsvd", 2, 35, 1),
- FUNC("gpio", 1, 35, 1),
- FUNC("wled_kn", 0, 35, 1),
+struct rt2880_pmx_func wled_an_grp_mt7628[] = {
+ FUNC("rsvd", 3, 44, 1),
+ FUNC("rsvd", 2, 44, 1),
+ FUNC("gpio", 1, 44, 1),
+ FUNC("wled_an", 0,44, 1),
+};
+
+static struct rt2880_pmx_func ephy_p0_grp_mt7628[] = {
+ FUNC("rsvd", 3, 43, 1),
+ FUNC("rsvd", 2, 43, 1),
+ FUNC("gpio", 1, 43, 1),
+ FUNC("ephy", 0, 43, 1),
+};
+
+static struct rt2880_pmx_func ephy_p1_grp_mt7628[] = {
+ FUNC("rsvd", 3, 42, 1),
+ FUNC("rsvd", 2, 42, 1),
+ FUNC("gpio", 1, 42, 1),
+ FUNC("ephy", 0, 42, 1),
+};
+static struct rt2880_pmx_func ephy_p2_grp_mt7628[] = {
+ FUNC("rsvd", 3, 41, 1),
+ FUNC("rsvd", 2, 41, 1),
+ FUNC("gpio", 1, 41, 1),
+ FUNC("ephy", 0, 41, 1),
+};
+static struct rt2880_pmx_func ephy_p3_grp_mt7628[] = {
+ FUNC("rsvd", 3, 40, 1),
+ FUNC("rsvd", 2, 40, 1),
+ FUNC("gpio", 1, 40, 1),
+ FUNC("ephy", 0, 40, 1),
+};
+static struct rt2880_pmx_func ephy_p4_grp_mt7628[] = {
+ FUNC("rsvd", 3, 39, 1),
+ FUNC("rsvd", 2, 39, 1),
+ FUNC("gpio", 1, 39, 1),
+ FUNC("ephy", 0, 39, 1),
};
-
-static struct rt2880_pmx_func wled_an_grp_mt7628[] = {
- FUNC("rsvd", 3, 44, 1),
- FUNC("rsvd", 2, 44, 1),
- FUNC("gpio", 1, 44, 1),
- FUNC("wled_an", 0, 44, 1),
-};
-
#define MT7628_GPIO_MODE_MASK 0x3
-
-#define MT7628_GPIO_MODE_WLED_KN 48
+#define MT7628_GPIO_MODE_EPHY_P4 42
+#define MT7628_GPIO_MODE_EPHY_P3 40
+#define MT7628_GPIO_MODE_EPHY_P2 38
+#define MT7628_GPIO_MODE_EPHY_P1 36
+#define MT7628_GPIO_MODE_EPHY_P0 34
#define MT7628_GPIO_MODE_WLED_AN 32
#define MT7628_GPIO_MODE_PWM1 30
#define MT7628_GPIO_MODE_PWM0 28
@@ -236,7 +263,12 @@
GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_SPIS),
GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_GPIO),
GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_WLED_AN),
- GRP_G("wled_kn", wled_kn_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_WLED_KN),
+ GRP_G("ephy_p0", ephy_p0_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P0),
+ GRP_G("ephy_p1", ephy_p1_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P1),
+ GRP_G("ephy_p2", ephy_p2_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P2),
+ GRP_G("ephy_p3", ephy_p3_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P3),
+ GRP_G("ephy_p4", ephy_p4_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P4),
+
{ 0 }
};
相關推薦
Openwrt中MT7628/MT7688的全部GPIO複用配置及常用介面DTS配置總結
Openwrt的不同版本中關於MT7628,MT7688的GPIO配置,存在或多或少的一些小問題 下面將以MT7628AN為基礎,介紹其全部的GPIO功能複用配置,以及需要注意的地方 MT76x8一個就47個可作為GPIO引腳,如下 關於其全部的功能複用表可以
GPIO複用引腳的釋放及gpio-leds的註冊
一:根據mt7620 datasheet中GPIO pin share schemes和WRTnode gpio引腳特徵,可以用來自定義的gpio引腳如以下標註所示: GPIO pin share schemes 注:紅色框裡的是結合WRTnode的介面引數得
Java NIO中的Selector和IO複用
Selection的概念和意義 Selector(選擇器)是Java NIO中能夠檢測一到多個NIO通道,並能夠知曉通道是否為諸如讀寫事件做好準備的元件。這樣,一個單獨的執行緒可以管理多個channel,從而管理多個網路連線。 在《Java NIO》一書裡介
Ubuntu中網路配置interfaces與介面網路配置NetworkManager
【Server版本】 在Ubuntu Server版本中,因為只存有命令列模式,所以要想進行網路引數設定,只能通過修改 /etc/network/interfaces 。具體設定方法如下: (1) Ubuntu Server 修改 IP地址 開啟 /etc/network/
sublime安裝、配置及常用外掛(陸續補全中~)
一、安裝sublime text3 網址:http://www.sublimetext.com/3 註冊碼:(sublime Text3漢化和啟用註冊碼) ----- BEGIN LICENSE ----- sgbteam Single User License E
Idea中maven的配置及常用的maven命令
maven配置幾個問題 記錄一下在Idea中配置maven遇到的幾個問題: 1. 看到網上說maven模板載入(模板列表)非常慢,網上給出的方案是改變配置:“VM options for importer:”框中改為:-Xmx 1024m。但是我改之
OSI物理層中通訊方式的總結之通道複用技術
[百科上這樣描述]“複用”是一種將若干個彼此獨立的訊號,合併為一個可在同一通道上同時傳輸的複合訊號的方法。 比如,傳輸的語音訊號的頻譜一般在300~3400Hz內,為了使若干個這種訊號能在同一通道上傳輸,可以把它們的頻譜調製到不同的頻段,合併在一起而不致相互影響,並能在接收端彼此分離
mac ffmpeg 中的錄製命令和分解與複用命令
mac中螢幕錄製命令: ffmpeg -f avfoundation -i 1 -r 30 out.yuv -f 指定使用 avfoundation 採集資料。 -i 指定從哪兒採集資料,它是一個檔案索引號。在我的MAC上,1代表桌面。 -r 指定幀率。按ffmpeg官方文
多路複用IO模型中的select和epoll
多路複用IO模型中的select和epoll 一,前提知識——檔案描述符fd 1、檔案描述符簡介 首先從檔案描述符開始講起。因為,對於核心而言,所有開啟的檔案都是通過檔案描述符引用的。那麼檔案描述符到底是什麼? 檔案描述符(file descriptor)通常是一個小的非負整
vue-router中關於元件複用頁面不重新整理的問題
業務描述: 當前頁面是一個帶引數的頁面,如下: 頁面下方有tab,點選其一個的跳轉路由是: 由此,發現問題,地址改變了,但是頁面資料沒有重新整理。 查閱後,此情況屬於元件複用的情況。 解決方法: 通過watch監聽路由變化: watch: { '
在vue中封裝可複用的元件
本次封裝的元件以toast元件為例 以前使用移動端ui外掛時,通過一句程式碼比如 $.toast( ‘ 需要顯示的內容 ’ ),從而在頁面上展示這段文字,並在一定時間後消失。 現在我們也嘗試自己封裝toast元件。 準備工作:vue-cli腳手架工程 先看一下涉及到的檔案目錄截圖:
php中類的繼承與程式碼複用
/** * 類的繼承 * 1. 繼承是為了程式碼複用 * 2. php只支援單繼承 * 3. 父類也叫超類,基類,子類也叫派生類 */ //宣告一個父類 class ParentClass{ public $name; protected $cour
MVP中Presenter複用的思考
MVP模式早已經不是什麼新鮮詞了,這裡不再贅述。最近在重構程式碼的過程中,發現了一件及其痛苦的事情:很多時候,model層在應用中是很薄的,大多數的業務邏輯都在Presenter層,但是由於模版 程式碼,Activity(View)->P是一一對應繫結的關
波分複用OADM在本地網中的應用
城域波分和長途波分由於應用場合不同和需求不同導致在結構上也有所差別。長途波分注重超長距離傳送和減少電中繼數量,大量採用全部波長上下的背靠背的OTM方式,雖然成本較高但是同昂貴的電中繼相比運營商容易接受其價格。但是本地網內一般距離都不會很長,在200~400
STM32(9) GPIO口複用功能實現(正點原子) QQ群860099671
一個GPIO口可以 複用成內部外設的功能引腳,這裡我們利用PA9\PA10設定為UART1來舉例。 IO口對應的複用功能需要查表來確定。這個表在晶片手冊 下面這個圖講解了GPIO口的複用原理 上圖右邊左圖是複用器(AFRL(31:0)、AFRH(31:0)),要
STM32的GPIO的複用功能和重對映功能
1、複用功能:內建外設是與I/O口共用引出管腳(不同的功能對應同一管腳) STM32 所有內建外設的外部引腳都是與標準GPIO引腳複用的,如果有多個複用功能模組對應同一個引腳,只能使能其中之一,其它模組保持非使能狀態。 2、重對映功能:複用功能的引出腳可以通過重對映,
網路程式設計中I/O複用select的用法
網路程式設計select的用法 select使用流程圖 在網路程式設計中需要新增的程式碼行以及意義 例程 參考文獻及部落格 注:本文對select函式、相關引數及結構體不做解釋 select使用流程
angular中 modal模態框(可複用)
可複用的 (普通的在function中找) : 點選事件之後的函式 $rootScope.confirm = function(content, okFn, cancelFn) { var
猜數遊戲的程式碼和實驗文件中的說明,為了增加程式碼的複用性,將猜數字遊戲封裝為函式GuessSecret(maxtimes),將允許猜數字的最大次數maxtimes作為引數。在呼叫GuessSecret時
from random import * def GuessSecret(maxtimes): n=0; x = 0 secret = randint(0, 100)
在io複用中把監聽套接字設為非阻塞
往往在select 或 epoll 中把 listen_socket 設定為非阻塞 O_NONBLOCK 原因是出在 accept 上, 比如有這麼一個客戶端 : RST客戶端 當這個select或epoll 的伺服器非常繁忙時, 有這麼一個一連線就斷開的客戶端,