WR841 - I2C Sensoren

TL;DR: Es sollte noch GPIO2 verwendbar sein, dieser ist jedoch zumindest auf der v9 PCB nicht auf ein Lötpad o.ä. rausgeführt.

Lange Version:

Ich habe mich den GPIO Thema mal eher von der theoretischen Seite genähert als mit dem Messgerät, sprich über das Datenblatt. Das Datenblatt für den in meinem WR841v9 verwendeten QCA9533 habe ich zwar nicht gefunden, aber dafür gibt es das vom QCA9531 nach bisschen Sucherei im Netz (s.u.). Ich unterstelle einfachmal die SoCs sind weitgehend identisch.

Laut Datenblatt S.45 hat der 9531/9533 18 GPIOs. Sieben gehen laut Code (mach-tl-wr841n-v9.c) für LEDs drauf. Zwei für die Buttons. Zwei fürs UART. Zwei hat bereits Tobias gefunden. 7+2+2+2=13. Fehlen also 5.

Schauen wir uns daher mal an, wie die Ports nach dem Booten der v9 mit nem nackten Chaos Calmer geschaltet sind. Dazu guggen wir mit io direkt in die entsprechenden Config Register und guggen dann im Datenblatt nach was Sache ist.

io hab ich nicht auf die schnelle für CC gefunden, aber das von AA tuts auch:

root@OpenWrt:~# wget http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/packages/io_1_ar71xx.ipk
root@OpenWrt:~# opkg install io_1_ar71xx.ipk 
Installing io (1) to root...
Configuring io.

Sweet. Nun brauchen wir noch die relevanten Registeradressen und die Infos um den Registerinhalt zu interpretieren.

Wir wälzen das Datenblatt: Tabelle 7-5 auf S.107 gibt uns die Registeradressen der Pin Konfiguration (= welcher Function Block gemultiplext ist) Tabelle 3-9 GPIO Output Select Values auf S. 47 listet auf welcher Funktionsblöcke welchen „Multiplex Value“ hat, spricht mit was der Pin verbunden wird. Davon gib’s 127 Stück (nicht alle belegt) und es wird 1 Byte pro Pin im Konfigregister benötigt. Die Registerbreite ist 4 Byte, es werden 4 Pins in einem Register konfiguriert/abgelegt.

Beispiel: Konfigtregister GPIO_OUT_FUNCTION2 konfiguriert die GPIO Pins 8, 9, 10, und 11 und hat die Adresse 0x18040034. Wir fragen also 4 Byte an dieser Adresse ab:

root@OpenWrt:~# io -4 0x18040034
18040034:  00160000

Die Beschreibung des Registers ist: MUX values for GPIO[11:8]., also steht GPIO Pin 11 vorne. Wir zerschnippeln 00160000 byte-weise und schlagen den Wert (Achtung hex!) in Tabelle 3-9 (Achtung dez!) nach.
Ist der Wert 0x00, wird statt Tabelle 3-9 die „Default Function“ verwendet. Diese finden wir ebenfalls in der Beschreibung des Registers.

Wir erhalten:

GPIO8: 0x00 -> SPI_MISO
GPIO9: 0x00 -> UART0_SIN
GPIO10: 0x16 -> UART0_SOUT
GPIO11: 0x00 -> Reserved < --- dazu später mehr

Okay, das bestätigt das komische Verhalten, wenn man an GPIO8 wackelt: Am SPI hängt ja der Flash und wir funken ihm in den Output (MISO) 8)

Der Rest ist Fleissarbeit. Wir wiederholen das Datenblatt-wälzen für alle GPIO_OUT_FUNCTION*-Register.

Außerdem wissen wir die Pins an denen die LEDs und die Buttons hängen aus dem Quelltext (mach-tl-wr841n-v9.c):

#define TL_WR841NV9_GPIO_LED_WLAN    13
...
#define TL_WR841NV9_GPIO_BTN_WIFI    17

Wir können uns noch anschauen ob ein GPIO als Input oder als Output konfiguriert ist. Das verwenden wir als Plausibilitätscheck: LEDs sollten Output und Buttons Input sein.
Wir fragen das Register GPIO Output Enable (GPIO_OE) an Adresse 0x18040000, welches festlegt ob ein GPIO ein Input oder ein Output ist.
Die Beschreibung sagt: zum Registerinhalt: Per bit output enable, where bit [22] sets GPIO22, bit [21] sets GPIO21, bit [20] sets GPIO20, and so on. 0=Output, 1=Input.

root@OpenWrt:~# io -4 0x18040000
18040000:  00021303

Diesen Wert (00021303) zerlegen wir also bit-weise, ich hab das unten mal an als „In,In,Out,Out“ rangeschrieben wenn in der GPIO Gruppe die ersten beiden Pins Input und die letzten beiden Output sind.

Wir mischen alles Zusammen und erhalten:

GPIO Function 0 (GPIO_OUT_FUNCTION0) MUX values for GPIO[3:0]:
root@OpenWrt:~# io -4 0x1804002C
1804002c:  00000000 
GPIO0: 0x00 -> TCK ?  -> Bereits gefunden von Tobias
GPIO1: 0x00 -> TDI ?   -> Bereits gefunden von Tobias
GPIO2: 0x00 -> TDO ?  
GPIO3: 0x00 -> TMS ?   -> TL_WR841NV9_GPIO_LED_QSS
Input/Output? GPIO3:0 Out,Out,In,In

GPIO Function 1 (GPIO_OUT_FUNCTION1) MUX values for GPIO[7:4]:
root@OpenWrt:~# io -4 0x18040030
18040030:  0c080900
GPIO4: 0x00 -> CLK_OBS4 ?   -> TL_WR841NV9_GPIO_LED_WAN
GPIO5: 0x09 -> SPI_CS_0
GPIO6: 0x08 -> SPI_CLK
GPIO7: 0x0c -> SPI_MOSI
Input/Output?  GPIO7:4 Out,Out,Out,Out 

GPIO Function 2 (GPIO_OUT_FUNCTION2) MUX values for GPIO[11:8]:
# io -4 0x18040034
18040034:  00160000
GPIO8: 0x00 -> SPI_MISO
GPIO9: 0x00 -> UART0_SIN
GPIO10: 0x16 -> UART0_SOUT
GPIO11: 0x00 -> Reserved  -> TL_WR841NV9_GPIO_LED_LAN4
Input/Output? GPIO11:8 Out,Out,In,In

GPIO Function 3 (GPIO_OUT_FUNCTION3) MUX values for GPIO[15:12]:
root@OpenWrt:~# io -4 0x18040038
18040038:  00000000
GPIO12: 0x00 -> Reserved   -> TL_WR841NV9_GPIO_BTN_RESET (input)
GPIO13: 0x00 -> Reserved   -> TL_WR841NV9_GPIO_LED_WLAN
GPIO14: 0x00 -> Reserved   -> TL_WR841NV9_GPIO_LED_LAN3
GPIO15: 0x00 -> Reserved   -> TL_WR841NV9_GPIO_LED_LAN2
Input/Output?  GPIO15:12 Out, Out, Out, In

GPIO Function 4 (GPIO_OUT_FUNCTION4) MUX values for GPIO[19:16]. <--- sic!!
# io -4 0x1804003C
1804003c:  00000100
GPIO16: 0x00 -> Reserved   -> TL_WR841NV9_GPIO_LED_LAN1
GPIO17: 0x01 -> SYS_RST_L   -> TL_WR841NV9_GPIO_BTN_WIFI  (input)
Input/Output?  GPIO17:16: Out, In

Wir sehen also: Neben den 7 für die LEDs, 2 für die Buttons werden 2 fürs UART, werden 4 fürs SPI verwendet. 2 ex-JTAG die von Tobias gefunden wurden. Macht 17 GPIOs. Der letzte, bisher noch nicht gefundene GPIO ist GPIO2. Dieser sollte so wie GPIO0 und GPIO1 verwendbar sein.

Der Wert für GPIO17 ist mir etwas unklar.

Leider scheint er zumindest auf dem v9er PCB nicht rausgeführt zu sein. Man beachte die Lücke in den Leiterbahnen zwischen C146, C164 und dem SoC. Immerhin liegt er auf einem QFN Pin in der vorderen Reihe (also falls jemand fit mit dem Lötkolben ist … :smile: )

Hier noch paar Allgemeine Pitfalls:

  • Bootstrap: Manchmal legen die GPIO Pins Bootoptionen fest, das sog. Bootstrap. Sollte man auf jeden Fall checken bevor man Anfängt die Wiederstande vom PCB zu kratzen.
  • JTAG: Bei den GPIOs an denen das JTAG hängt muss idR das JTAG erst abgeschaltet werden. Bei Chaos Calmer ist das Flag zum deaktiveren (DISABLE_JTAG) in Register GPIO_FUNCTION erfreulicherweise bereits gesetzt. Sollte man aber idR auch erstmal gegenchecken.

Soweit bisher. Vielleicht mag ja jemand mit einer v8, v10 und v11 die GPIO Config mal gegenchecken :wink:
VG
Robert

p.s.: Sorry, dafür das wir jetzt soweit vom eigentlichen Thema (I2C) abgekommen sind :frowning:

p.p.s.: Man beachte die Benennung von Pad B42 und B49: USB_DP und USB_DM:wink:

Quellen / Ressourcen

Datenblätter gibs hier:

Register auslesen (Beispiel):

Bild der Platine v9:

5 „Gefällt mir“