GL-MT300N-V2 how to use/enable I2C or I2C/RX1/TX1 pins as gpio

Hello, i’m trying to use some pins as gpio on GL-MT300N-V2 but i can’t use I2C_SCLK (gpio4) and I2C_SD (gpio5).
if i do:
echo 4 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio4/direction
echo 0 > /sys/class/gpio/gpio4/value
echo 1 > /sys/class/gpio/gpio4/value
there is no error, but using a multimeter/volt-meter the value never change.
using the same code to control leds (gpio 42,43,44) work (after you do rmmod leds-gpio).
With this code i can’t use gpio45 and 46 (rx1, tx1), again, no error but the value using a multimeter never change.
I can use rx1 and tx1 using /dev/ttyS1 and also use /dev/ttyS0 they just work.
if i use an oscilloscope i can see that the value change for a moment by doing echo AAAAAAA > /dev/ttyS1

for i2c I followed this guide:

now i’m trying this: insmod i2c-gpio-custom bus0=0,5,4
there is no error, not even in dmesg, but it just doesn’t work, the pin value never change.
do i need some other package??
i2cdetect doesn’t detect anything and it’s super fast (<1 second to finish the command)
i have tested this on two random gpio numbers and i2cdetect doesn’t detect anything but it’s quite slow (about 1 second per address).

my goal:
-using i2c pins as i2c
-using rx1,tx1 as normal gpio: set output and manually set high/low.

on the official website there is a pinout:

while here there is a different one (for the gpio), this seems wrong:
https://openwrt.org/toh/gl-inet/gl.inet_gl-mt300n_v2

i’m using this firmware (openwrt, not oem):
http://downloads.openwrt.org/releases/18.06.1/targets/ramips/mt76x8/openwrt-18.06.1-ramips-mt76x8-gl-mt300n-v2-squashfs-sysupgrade.bin

Hardware specifications say:
DIY Features UART, 4GPIOs, 3.3V; 5V power port
but they also say:
The pins on the left side can be actually used for Ethernet port or EMMC. They cannot be used as GPIO.
but i don’t get why i can’t use as normal gpio… if i can’t use as gpio i want to use them as i2c; in the pinout photo and printed on the board it say “I2C” so it should be possible…

1 Like

If you want to use I2C and UART pin, you have to build the firmware by yourself. If you use the official OpenWRT buildroot. Please modify the dts file target/linux/ramips/dts/GL-MT300N-V2.dts.

Append those lines to dts file.

&i2c {
	status = "okay";
};

Configure uart1 to GPIO.

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "wdt", "gpio", "wled_an", "p0led_an", "p1led_an", "i2s", "uart1";
			ralink,function = "gpio";
		};
	};
};

Please rebuild the firmware after modifying.

The modified dts file is in the attachment.

GL-MT300N-V2.zip (1.0 KB)

1 Like

Hello, I am very new to this and want to do the same as the OP.
I was hoping for some guidance on how to ‘rebuild the firmware’ as well as the commands to copy the .dts file over to the router over ssh.
Again sorry for the super simply question i am very new routers and building firmware.
Would appreciate any help
Thanks

OpenWrt 23.05.4 uses the DTS file attached to this post, but I2C doesn't appear to work on the GL-MT300N-V2. The pins appear to be configured for I2C, but

root@cove2:~# cat /sys/kernel/debug/pinctrl/pinctrl-ralink-pinmux/pinmux-pins
Pinmux settings per pin
Format: pin (name): mux_owner gpio_owner hog?
pin 0 (io0): pinctrl (GPIO UNCLAIMED) function gpio group i2s
pin 1 (io1): pinctrl (GPIO UNCLAIMED) function gpio group i2s
pin 2 (io2): pinctrl (GPIO UNCLAIMED) function gpio group i2s
pin 3 (io3): pinctrl (GPIO UNCLAIMED) function gpio group i2s
pin 4 (io4): pinctrl (GPIO UNCLAIMED) function gpio group i2c
pin 5 (io5): pinctrl (GPIO UNCLAIMED) function gpio group i2c
...
i2cdetect reports an error:

i2cdetect 0
Error: Could not open file /dev/i2c-0' or /dev/i2c/0': No such file or directory
root@cove2:~#

Looking in /dev, no i2c

root@cove2:~# ls /dev
bus gpiochip0 kmsg mtd1 mtd3 mtd5 mtdblock0 mtdblock4 port random stdout ttyS10 ttyS14 ttyS4 ttyS8 watchdog0
console gpiochip1 log mtd1ro mtd3ro mtd5ro mtdblock1 mtdblock5 ppp shm tty ttyS11 ttyS15 ttyS5 ttyS9 zero
fd gpiochip2 mtd0 mtd2 mtd4 mtd6 mtdblock2 mtdblock6 ptmx stderr ttyS0 ttyS12 ttyS2 ttyS6 urandom
full hwrng mtd0ro mtd2ro mtd4ro mtd6ro mtdblock3 null pts stdin ttyS1 ttyS13 ttyS3 ttyS7 watchdog
root@cove2:~#

I've installed all the modules that seem relevant

  • i2c-tools
  • kmod-i2c-algo-bit
  • kmod-i2c-core
  • kmod-i2c-smbus
  • libi2c
  • gpio-sysfs
  • gpiod-tools
  • kmod-gpio-button-hotblug
  • kmod-i2c-gpio
  • kmod-leds-gpio
  • libgpiod
  • libugpio

I've got a known good temperature sensor board based on a MCP9809 that I'd like to get working from the Mango. I don't have a logic analyzer, but I do have other microcontrollers, a multimeter, and assorted LEDs, etc.

I've googled the heck out of this and I'm stumped. Any help?

I was wrong about the DTS file being identical. The one from the post generated build errors, but I grabbed the I2C related parts and now I have i2cdetect working.

Here is the diff:

corbett@nao:~/git/openwrt$ git diff
diff --git a/target/linux/ramips/dts/mt7628an_glinet_gl-mt300n-v2.dts b/target/linux/ramips/dts/mt7628an_glinet_gl-mt300n-v2.dts
index a3ce8cc592..d9e0e14760 100644
--- a/target/linux/ramips/dts/mt7628an_glinet_gl-mt300n-v2.dts
+++ b/target/linux/ramips/dts/mt7628an_glinet_gl-mt300n-v2.dts
@@ -75,7 +75,7 @@
 
 &state_default {
        gpio {
-               groups = "wdt", "gpio", "wled_an", "p0led_an", "p1led_an", "i2s", "i2c";
+               groups = "wdt", "gpio", "wled_an", "p0led_an", "p1led_an", "i2s";
                function = "gpio";
        };
 };
@@ -135,6 +135,18 @@
        status = "okay";
 };
 
+&ehci {
+       status = "okay";
+};
+
+&ohci {
+       status = "okay";
+};
+
+&i2c {
+       status = "okay";
+};
+
 &factory {
        compatible = "nvmem-cells";
        #address-cells = <1>;
corbett@nao:~/git/openwrt$

I've got temperature readings from an I2C sensor working. Here's a quick Bash script for fetching the temperature over ssh using i2cget. This script does the minimum work on OpenWrt and decodes the temperature on a host that runs Bash and presumably can do something useful with the temperature like adding it to a dashboard.

#! /usr/bin/env bash

# Abort on nonzero exitstatus.
set -o errexit

# Abort on unbound variable.
set -o nounset

# Don't hide errors within pipes.
set -o pipefail

# Split on newlines and tabs (but not on spaces)
IFS=$'\t\n'

SCRIPT_NAME=$(basename "${0}")

SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
readonly SCRIPT_NAME SCRIPT_DIR

DEVICE_USER=root
DEVICE_IP=192.168.1.6

main() {
  # check_args "${@}"
  if [ $# -ne 0 ]; then
    echo -e "Usage: $SCRIPT_NAME\n\nFetches the temperature an OpenWrt device"
    exit 2
  fi

  # Get four bytes from an I2C temperature sensor attached to an OpenWrt device
  # A successful response is two hexadecimal bytes.
  # Bit 13 is the sign of the temperature with 0 indicating positive.
  # Bits 5-12 are the integer portion of the temperature in Celcius.
  # Bits 1-4 are the fractional portion of the temperature in Celcius.
  TRAW=`ssh ${DEVICE_USER}@${DEVICE_IP} -C i2cget -y 0 0x18 5 i 2`

  # Remove 0x prefixes from both numbers
  T2=${TRAW//"0x"/}

  # Remove the space between the numbers
  T3=${T2//" "/}

  # Keep the last three digits
  T4=${T3:1}

  # Convert the temperature to Fahrenheit, discarding the fraction
  TF=$(( $(printf "%d\n" 0x${T4}) / 16 * 9 / 5 + 32))

  # Get the hexadecimal digit containing the sign
  SIGN=${T3:0:1}

  # Convert it to decimal
  SIGN2=$(printf "%d" 0x${SIGN})

  # The sign is the bottom bit.
  SIGN3=$((SIGN2 % 2))

  # If sign3 is 0, empty string else negative sign
  SIGN4=${SIGN3/0/}
  SIGN5=${SIGN4/1/-}

  echo "${SIGN5}${TF}°F"
}

main "${@}"