Mikrotik RB750 r2 series POE

Not working, all i get are a tone of responses like this.

}
{
  action: "raw_send",
  tx: "0x40 0x00 0x19 0x81",
  rx: "0x00 0x00 0x00 0x00"
}
{
  action: "raw_send",
  tx: "0x48 0x00 0x19 0x50",
  rx: "0x00 0x00 0x00 0x00"
}
{
  action: "raw_send",
  tx: "0x40 0x00 0x1A 0x80",
  rx: "0x00 0x00 0x00 0x00"
}
{
  action: "raw_send",
  tx: "0x48 0x00 0x1A 0x93",
  rx: "0x00 0x00 0x00 0x00"
}

rx is always zero.... :frowning:

Let's start in order.

echo 0 > /sys/class/gpio/gpio14/value
mtpoe_ctrl --action=raw_send --raw_hex_val="AC 53 00 00"

What returns?

Ok, here we go....

root@OpenWrt:~# echo 0 > /sys/class/gpio/gpio14/value
root@OpenWrt:~# mtpoe_ctrl --action=raw_send --raw_hex_val="AC 53 00 00"
{
  action: "raw_send",
  tx: "0xAC 0x53 0x00 0x00",
  rx: "0x00 0x00 0x00 0x00"
}

This is bad. ATtiny does not even go into programming mode. There can be several reasons: microcontroller hardware malfunction or a set previously value of the fuse bits that prohibit reprogramming.

Hm,I am gotta try the avrdude way tommorow.
And, I am sure that they have programming pins on one of the headers.
Mikrotik usually always leave stuff like that for production programming

avrdude does not help. Lets see https://github.com/SpenceKonde/ATTinyCore/blob/master/avr/avrdude.conf

Search for string: "ATtiny461"
pgm_enable          = "1 0 1 0  1 1 0 0   0 1 0 1  0 0 1 1",
"x x x x x x x x x x x x x x x x";

"1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1" this is "AC 53" - Programming Enable.

In response, the microcontroller should respond "0x00 0x00 0x53 0x00"

The ATtiny461a programming is carried out via the SPI bus at a LOW level on the GPIO 14. There are no other options.

If I were you, I'd look for where to buy a new chip, solder it instead of the old and try to program it using the above script.

And on my test PowerBox after the commands:

echo 0 > /sys/class/gpio/gpio14/value
mtpoe_ctrl --action=raw_send --raw_hex_val="AC 53 00 00"

I get what I need in return: 0x00 0x00 0x53 0x00

It could easily bee that lock bit was set and SPI or HVP programming wont work

Yes. And also because of the fuse bits, the microcontroller can use the external clock source that is missing.

@adron I finally got some fresh Attiny461-s, I will replace the not working one in a day or two and then try flashing the firmware using your mtpoe_ctrl package.

Do I have to use you script linked above?

Hello. No, I not tested http://hosting.yapic.net/lede/attiny_write.sh.txt
I do not want to turn the device into a brick.

Just finished a rework of the mtpoe_ctrl to support the Mikrotik's PoE(gigabit) version 3. Checked on the RB960PGS device.

A RB960pgs, unlike the RB750UPr2, has version 3 PoE, implemented on the ATMega ATSAMD20J15 microcontroller. The communication protocol is slightly different.

At this moment, I checked a workage of the mtpoe_ctrl on the following devices:
RB750UPr2
RB750P-PBr2
RB960PGS

1 Like

Awesome job, I will give your script a go since POE already does not work and I got 5 new Attiny-s.
Have you had a POEv4 device yet?

I have a CRS328 switch that has 3 POE PCB-s and 3 POEv4 controllers.
Completely forgot to not which MCU does it use

Hello. I've never heard of the PoE version 4. Are you sure that it exists?
Inside the RouterOS squashfs, too, there is nothing like that:

# pwd
/tmp/23/squashfs-root/lib/modules/3.3.5/misc
# ls -l ./*poe*
-rw-r--r-- 1 root root  7608 ноя 27 16:24 ./poe_simple.ko
-rw-r--r-- 1 root root  7620 ноя 27 16:24 ./poeupdate.ko
-rw-r--r-- 1 root root  8212 ноя 27 16:24 ./poe_v2.ko
-rw-r--r-- 1 root root 18228 ноя 27 16:24 ./poe_v3.ko

Unfortunately, I do not have a CRS328.

Oh. You are right. If we look at routeros-arm then we see this:

-rw-r--r-- 1 root root  8084 ноя 12 13:35 ./poe_simple.ko
-rw-r--r-- 1 root root 21620 ноя 12 13:35 ./poe_v4.ko

I am sure as I jailbroke CRS328-24P-4S+RM and there are 3 POE v4 devices registered on SPI0.4, SPI0.5 and SPI0.6

I forgot to check which MCU is used, altough I doubt that MCU use matters really.
What was the difference between v2 and v3?

CRS328 is perfect candidate for OpenWRT as the switch used also has a ARMv7 CPU and is fully upstreamed.
There are only 2 issues, POE and fans are registered via kmod and controller with a STM8 MCU.
Also, they have multiple hwmon devices measuring voltage and current for both 24V and 58V ranges but only total coming from PSU

Sorry for reviving this old thread ^^'
I got my hands on an RB5009UPr and activated the spidev for the PoE controller but it is also a v4 device.
Did you two make any progress on PoE v4 support or do I have to get out ghidra myself to reverse the poe_v4.ko?

communication seems to be partly working:

root@OpenWrt:/sys/class/gpio# echo "40" > export
root@OpenWrt:/sys/class/gpio# cd gpio40/
root@OpenWrt:/sys/class/gpio/gpio40# echo out > direction
root@OpenWrt:/sys/class/gpio/gpio40# echo 1 > value 
root@OpenWrt:/sys/class/gpio/gpio40# mtpoe_ctrl --dev_file=/dev/spidev2.0 --poe_proto=3 --action=get_fw_ver --verbose
spi mode: 0
bits per word: 8
max speed: 2000000 Hz (2000 KHz)

tx: 41 00 00 9A 00 00 00 00 00 00 
rx: FF FF FF 41 00 00 67 67 67 67 
tx: 41 00 00 9A 00 00 00 00 00 00 
rx: CE 67 FF FF FF 41 40 4B 67 67 
{
  fw_version: 64.75
}
root@OpenWrt:/sys/class/gpio/gpio40# mtpoe_ctrl --dev_file=/dev/spidev2.0 --poe_proto=3 --action=get_voltage --verbose
spi mode: 0
bits per word: 8
max speed: 2000000 Hz (2000 KHz)

tx: 42 00 00 7E 00 00 00 00 00 00 
rx: CE 67 FF FF FF 42 13 A9 F4 F4 
{
  voltage: 50.33
}
root@OpenWrt:/sys/class/gpio/gpio40# mtpoe_ctrl --dev_file=/dev/spidev2.0 --poe_proto=3 --action=get_temperature --verbose
spi mode: 0
bits per word: 8
max speed: 2000000 Hz (2000 KHz)

tx: 43 00 00 D5 00 00 00 00 00 00 
rx: E8 F4 FF FF FF 43 02 D3 F1 F1 
{
  temperature: 28
}
root@OpenWrt:/sys/class/gpio/gpio40# mtpoe_ctrl --dev_file=/dev/spidev2.0 --poe_proto=3 --action=get_poe --verbose
spi mode: 0
bits per word: 8
max speed: 2000000 Hz (2000 KHz)

tx: 45 00 00 04 00 00 00 00 00 00 
rx: E2 F1 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
tx: 45 00 00 04 00 00 00 00 00 00 
rx: CC 66 FF FF FF 45 00 00 66 66 
{
  error: -101,
  err_descr: "Rx CRC error!: 0x4 vs 0x66, 0x66"
}

And for reference this is what I had to add to the DTS (using the current "master + master-5.15" patchset for the RB5009):

&cp0_pinctrl {
	cp0_spi1_pins: cp0-spi1-pins {
		// Mikrotik defines SPI1 with mpp50 as CS0 and then additionally sets mpp8 as CS for the PoE driver via GPIO. We just want the hardware to handle CS0 on mpp8
		marvell,pins = "mpp47", "mpp48", "mpp49", "mpp8";
		//marvell,pins = "mpp47", "mpp48", "mpp49", "mpp50";
		marvell,function = "spi1";
	};

	/*cp0_spi1_poe_cs_pins: cp0-spi1-poe-cs-pins {
		marvell,pins = "mpp8";
		marcell,function = "gpio";
	};*/
};

&cp0_spi1 {
	status = "okay";

	pinctrl-0 = <&cp0_spi1_pins>;
	pinctrl-names = "default";

	spidev@0 {
		compatible = "rohm,dh2228fv";
		//compatible = "linux,spidev";
		reg = <0>;
		spi-max-frequency = <2000000>;
	};
};
2 Likes

With the following patch, set_poe is working too for all 8 ports on the RB5009:

--- a/mtpoe_ctrl.h	2023-04-01 02:15:03.221613194 +0200
+++ b/mtpoe_ctrl.h	2023-04-01 02:15:11.878279985 +0200
@@ -6,7 +6,7 @@
 //ключ субконфига uci->network в котором находятся настройки PoE
 #define MTIK_POE_UCI_CONFIG_KEY "mtik_poe"
 //сколько всего PoE портов
-#define POE_PORTS_N 4
+#define POE_PORTS_N 8
 //где находится файл с board_name
 #define BOARD_NAME_FILE "/tmp/sysinfo/board_name"
 
@@ -78,7 +78,7 @@
   define_str_opt(poe_uci_config_key),
   define_int_opt(period, 0, 3600),
   define_flag_opt(verbose),
-  define_int_opt(port, 0, 3),
+  define_int_opt(port, 0, 7),
   define_int_opt(val, 0, 0xFFFF),
   define_flag_opt(version),
   define_str_opt(raw_hex_val),
--- a/mtpoe_ctrl.c	2023-04-01 02:18:21.894949422 +0200
+++ b/mtpoe_ctrl.c	2023-04-01 02:18:00.398282442 +0200
@@ -219,8 +219,8 @@
 	action для устанавки состояние определенного PoE порта
 */
 static void do_action_set_poe(void){
-	if(port < 0 || port > 3)
-		die_and_mess(-20, "port value must be 0..3");
+	if(port < 0 || port > 7)
+		die_and_mess(-20, "port value must be 0..7");
 	if(val < 0 || val > 2)
 		die_and_mess(-20, "PoE value must be 0..2");
 	__set_poe(port, val);

So only get_poe is not working when using the PoE v3 protocol.

2 Likes