VoCore2 + Bluetooth

Recently a lot of chip shortage, really makes me headache. πŸ™‚

This is a bluetooth module works with VoCore2, it is based on CSR8510.

PS: Qualcomm is really a suck company. I can not get any documentation from them but have to find some leak ones online…

Lucky thing, this CSR8510 is almost working out of box. No idea what that EEPROM used to do, I just use an empty EEPROM, this device still work normally.

So connect it to VoCore2 USB host port, then remember install bluez-daemon in VoCore2, it just works.

We can use hciconfig / hciconfig hci0 to show this device.

And to make it work, call hciconfig hci0 up

Or scan nearby device by hcitool scan

Or ping the nearby device to make sure everything is normal: l2ping xx:xx:xx:C1:58:C2

Finally. here it is πŸ™‚

the little device πŸ™‚

MT76: Learning…3

Finally my patch has into main branch of mt76 πŸ™‚ now we have stable official supported wireless driver, and ADHOC, MESH are default supported too.

My patch link is here: https://github.com/openwrt/mt76/pull/426

Thanks the admin, make it in better format: https://github.com/openwrt/mt76/commit/97e65131440ccae916e76323251b80cafdfc9006

Next blog, I will try mesh and adhoc mode, check if they work.

Be Careful when Buy from lcsc.com

When I make samples, I prefer lcsc.com(or szlcsc.com) for a long time, but now, I can not recommend it anymore, because buy from them are pretty risky.

PS: for mass production, normally we directly order from parts factory, not such provider.

First Story

Around 2 years ago, 2017, I was working on POE version of VoCore2, I used a SMT electrolytic capacitor (22uF, 63V). From its datasheet, max allowed temperature is 260C 10seconds, but after my standard reflow(260C 6 seconds), 80% of that caps were become “popcorn”… lucky me, not exploded.

I contacted their sales and they sent me the replacement — even the total value was just 2USD but I spent over 5 hours to fix the samples — I was still happy.

Second Story

Just a few days ago, I bought some parts from them again. The BOM list was pretty long and I made a mistake, I chose wrong type of a SIM card slot because they really looks same…I found it out only when I received them. I contacted szlcsc.com in first time, hoped they can replace them, but guess what? They refused! Because they said they have rules that they refuse return parts even the package is not opened and not used at all.

That was a big surprise for me. And wrong parts are useless for me, it is a waste…

PS: its type is C99403, SIM-01A, 70pcs, if you want it, just contact me, I will send them to you free, just need postage πŸ™‚

I still negotiate with them. This is not fair, in any country of the world. We all make mistakes, if we can not return wrong package, who dare to buy from internet?

So finally, if you use lcsc.com too, just be very careful, because they do not allow return package even the package is not opened.

I am pretty unhappy with them this time, because there is no warning show on their site from begin to end. Even now, I still can not find such warning or rule on their site. Somebody told me that is really in their site somewhere but in a pretty small font…^_^?

Anyway, for such chip provider, just be careful and careful. You can not make any mistake when you put your order on them. I paid the school fee and now I know. πŸ™‚

VoCore2: OpenWrt 19.07.3 Firmware

Now official OpenWrt 19.07.3 firmware released.

Link: http://vonger.cn/misc/vocore2/20200811.19073.bin (For VoCore2)

Link: http://vonger.cn/misc/vocore2/20200812.19073.bin (For VoCore2 Ultimate)

Different is VoCore2 Ultimate has embed SD card driver, for VoCore2 do not have SD card slot, it will show a lot of junk message to the system log.

Embed software:

  • LuCI
  • mem (for /dev/mem access)

Support interface:

  • SD Card (V2U)
  • Ethernet
  • WiFi
  • I2C
  • I2S
  • GPIO
  • Reference Clock
  • SPI
  • USB 2.0 HS Host

MT76: Learning…2

After read the mt76 source code, I find the source code miss eerpom 0x34 setting (not a real eeprom, just flash factory partition), and 0x34 is used to choose antenna number…

So fix is pretty simple:

--- a/mt7603/init.c
+++ b/mt7603/init.c
@@ -277,6 +277,9 @@ mt7603_init_hardware(struct mt7603_dev *dev)
        if (ret < 0)
                return ret;
+       if (((u8*)dev->mphy.eeprom.data)[MT_EE_NIC_CONF_0] == 0x11)
+               dev->mphy.antenna_mask = 1;
        ret = mt7603_dma_init(dev);
        if (ret)
                return ret;

Once we find 0x34(MT_EE_NIC_CONF_0) is 0x11, force the driver use one antenna. That’s all.

Now after over 1 hour test, this mt76 driver is working very well and stably at >= 52Mbps 1T1R.

MT76: Learning…

Develop on a chip like MT7628 is full of adventure…For new version of firmware I plan to use opensource MT76 driver instead of MT7628 driver. Weird thing is MT76 works well on some devices, but not well on some others, include VoCore2.

I guess it is antenna issue, because for normal WIFI4 routers default has two antennas works at same time for 300Mbps, 802.11n mode; but for VoCore2, default antenna 2 is disabled to save power and avoid cross talk when no second antenna attached.

Thanks to github MT76 contributors, I have some clues to fix this: https://github.com/openwrt/mt76/issues/423

After apply that patch, change mt76-2020-03-10-08054d5a/mt7603/init.c line 538

- dev->mt76.antenna_mask = 1;
+ dev->mt76.antenna_mask = 3;

I get a good result, 5minute no disconnect anymore.

[  5] 297.00-298.00 sec  6.31 MBytes  52.9 Mbits/sec                  
[  5] 298.00-299.00 sec  6.38 MBytes  53.5 Mbits/sec                  
[  5] 299.00-300.00 sec  6.41 MBytes  53.7 Mbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-300.00 sec  1.75 GBytes  50.2 Mbits/sec                  sender
[  5]   0.00-300.07 sec  1.75 GBytes  50.2 Mbits/sec                  receiver
It stay at MCS Index: 7, do not jump to MCS Index: 15, so the two antennas will not crosstalk to each other, now we have stable result.

So this should be the solution, just need test more. Currently we store 1T1R and 2T2R parameter to factory setting partition in flash, so there are two ways, one is to add factory setting patch to change it, another is to add DTS setting patch to change it, emm, which way is better? hard choice.

To be continue…

VoCore2 + Touch + LVGL DEMO

LVGL new demo looks better

Here is the compressed firmware link http://vonger.cn/misc/screen/20200628.touch.bin.xz, upgrade then it is able to work directly πŸ™‚ Just need two files to work, one is the fbusb.ko driver for touch and USB data transfer, another is /root/demo which is the littlevgl demo application.

New Screen with touch API is simpler, please check https://vocore.io/screen.html for more details.

VoCore2 SPI: full duplex

mt7628a has a wafer/silicon bug on SPI, we can not use its SPI in full duplex mode, but we can use bitbang for that mode. For some device do not support half-duplex, maybe this is the only way.

To enable bitbang on VoCore2, we need to modify Linux kernel code, VOCORE2.DTS and kernel setting.

Setup Kernel Setting

  1. call “make kernel_menuconfig”
  2. In menu, select “Device Drivers” => “SPI Support” => <*> Β  GPIO-based bitbanging SPI Master


This file is in target/linux/ramips/dts, example of the DTS. We need to set the driver to “spi-gpio” and pinctrl set the pins to GPIO mode.


#include "VOCORE2.dtsi"

#include <dt-bindings/gpio/gpio.h>

/ {
	compatible = "vocore,vocore2", "mediatek,mt7628an-soc";
	model = "VoCore2";

	gpio-leds {
		compatible = "gpio-leds";

		status {
			label = "vocore2:fuchsia:status";
			gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;

	spi1: spi-gpio {
		status = "okay";

		compatible = "spi-gpio";

		gpio-sck = <&gpio0 7 1>;
        	gpio-miso = <&gpio0 9 1>;
        	gpio-mosi = <&gpio0 8 1>;

        	cs-gpios = <&gpio0 10 1>, <&gpio0 6 1>;
        	num-chipselects = <2>;

&pinctrl {
        state_default: pinctrl0 {
                spi {
                        ralink,group = "spi";
                        ralink,function = "gpio";
                spi_cs1 {
                        ralink,group = "spi cs1";
                        ralink,function = "gpio";

&i2c {
	status = "okay";

&spi1 {
	m25p80@0 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <10000000>;
		m25p,chunked-io = <32>;

		partition@0 {
			label = "u-boot";
			reg = <0x0 0x30000>;

		partition@30000 {
			label = "u-boot-env";
			reg = <0x30000 0x10000>;

		factory: partition@40000 {
			label = "factory";
			reg = <0x40000 0x10000>;

		partition@50000 {
			label = "firmware";
			reg = <0x50000 0xfb0000>;

	spidev@1 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "rohm,dh2228fv";
		reg = <1>;
		spi-max-frequency = <10000000>;

Patch Linux spi-gpio.c

This is because CS1 pins has a default pull low resistor. If we do not patch it, CS1 will be low at startup, conflict with the flash driver who use CS0. So we must at startup setup CS1 pin to output and value to high.

                if (!SPI_N_CHIPSEL)
                        spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT;
                        for (i = 0; i < SPI_N_CHIPSEL; i++) {
                                status = of_get_named_gpio(np, "cs-gpios", i);
                                if (status < 0) {
                                                "invalid cs-gpios property\n");
                                        goto gpio_free;
                                spi_gpio->cs_gpios[i] = status;

+                               gpio_request(status, dev_name(&pdev->dev));
+                               gpio_direction_output(status, 1);
+                               gpio_free(status);

        spi_gpio->bitbang.master = master;
        spi_gpio->bitbang.chipselect = spi_gpio_chipselect;

That is all πŸ™‚ Now the firmware is able to support SPI device in full duplex mode.

Submit patch for OpenWrt on Github

Git is good, but for beginner like me, always feeling no way to give the first bite. I am confused about fork, branch, signed-off-by, push, merge and many other commands, maybe it is pretty clear for the clever boys but not for me. Thanks to adrianschmutzler comment at https://github.com/openwrt/openwrt/pull/3022, I start to understand how it works.


  1. click the “Fork” button on github.com/openwrt/openwrt
  2. goto your forked openwrt, click on “Clone or download”, get the address and clone to your local.
  3. make the change on your local source code.
  4. setup your name and email on your local by command git config –global user.email xxxx@xxxxx.xxx and git config –global user.name “your name”
  5. submit your change by command “git commit -s“, remember to keep that Signed-off-By line and add the reason of the changes to comment.
  6. push the commit by command “git push origin
  7. finally, go to github, create a merge request.

Signed-Off-By is just a text line in the comment to tell other who submit that patch, I am confused about that a long time, I thought it is added by some magic :p

PS: In old good time I only use git init, git commit and git clone. Now good new day comes.

VoCore2: OpenWrt 19.07.2

Recently I try latest stable version openwrt, looks like the open source MT76 driver is much stable and fast now.

iperf3 -c
Connecting to host, port 5201
[  5] local port 60121 connected to port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  5.33 MBytes  44.7 Mbits/sec                  
[  5]   1.00-2.00   sec  5.50 MBytes  46.1 Mbits/sec                  
[  5]   2.00-3.00   sec  5.34 MBytes  44.7 Mbits/sec                  
[  5]   3.00-4.00   sec  4.67 MBytes  39.3 Mbits/sec                  
[  5]   4.00-5.00   sec  5.47 MBytes  45.8 Mbits/sec                  
[  5]   5.00-6.00   sec  5.03 MBytes  42.3 Mbits/sec                  
[  5]   6.00-7.00   sec  4.93 MBytes  41.3 Mbits/sec                  
[  5]   7.00-8.00   sec  5.07 MBytes  42.6 Mbits/sec                  
[  5]   8.00-9.00   sec  4.95 MBytes  41.5 Mbits/sec                  
[  5]   9.00-10.00  sec  5.13 MBytes  43.0 Mbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  51.4 MBytes  43.1 Mbits/sec                  sender
[  5]   0.00-10.09  sec  51.3 MBytes  42.7 Mbits/sec                  receiver

iperf Done.

This is good πŸ™‚ Next firmware will base on this driver and I do not have to patch it anymore.