VoCore2: Online!

vocore2.raw 3

VoCore2 is now on indiegogo.com again 🙂 https://igg.me/at/vocore2

Compared with VoCore v1, we added a beautiful shell(the picture is only a 3d print sample, final shell is much much better) and more features, also improved the LuCI interface to make it easier to use. Hope everyone will like it, same as usual, fully open sourced. 🙂

Why are we using the White PCB?

Many curious people have asked me such question (PS: we did not kill any cat yet). This is always a little secret of VoCore, but today I will talk. It is not only about its looks better, also it is part of quality control.

PCB mainly has six colors, green, blue, red, yellow, white, black. (the truth is you can choose any RGB 24bits color you like, somebody even choose purple)

Most of the factories love black and green, that is because the first pass yield around 95% ~ 98%, the not good ones will send back to workers and repair, during the repairing, the pcb boards have to be heated to 260C again, green and black pcb is good but white pcb will change to light yellow one.

Most repaired ones are good, but the quality might come low. Sn after heat and heat again will partly become SnO2, SnO2 is not conductor and have a high chance broken the connection.

So we decide we only ship the first pass VoCore to users, and use white PCB to make it easy to check every VoCore we shipped is first class quality.

PS: another fact is I am lazy, keep them 100% good rate so I can have more time on bed but not shipping the packages again and again. :p

VoCore2: Current Progress

Last month, I spend a lot of time on DMA and ALSA driver, fight with the noise, optimized every feature(I also made a fork on github.com/vonger, welcome everyone).

Really sorry for the delay, but my only target is to make it to the best I could, not the cost or the deadline.

PS: I heard many companies even big company, they just make their products usable but not extreme, because there are deadline, market, pressure from investor, lack of professional engineer etc…They are telling me, the end user do not know the much tech, so who care…

But I want VoCore2 not only to be the tiny computer but also the best router, the best embed wireless platform, if I can not make it to what I want, why waste the time? There are thousands of such boards already.

Now I am still looking for possible flaw on VoCore2, once I am happy about the sample, it will go to production process. It should be very soon 🙂

Ethernet Transfer Speed: >= 95Mbps(iperf3), maximized.
Wireless 802.11n Transfer Speed: >= 100Mbps(iperf3), maximized too. —- Most routers same test condition only reach around 90Mbps.
USB Transfer Speed: maximized.
SDXC(SD card) Transfer Speed: maximized.
The Power Consume: 75mA.



VoCore2: Process

Almost there 🙂 Just finish DMA driver and I2S
driver, committed two patch to my github.

(clone and checkout VoCore2, update feeds, then it will be ready to compile.)

PS: I planed to reuse exists dma/i2s code for mt7620/mt7621, but none of them are real compatible with mt7628… 🙁

It is really hard work for Linux kernel develop. Code is a simple part, but understanding Linux arch is really a time-cost work(also every linux kernel has some slightly difference). I learned a lot from reading the source of linux, and really love the flash wisdom between the line of the code.

I am going to do:
audio codec driver: this driver for the dock part, codec wm8988 or es8388.

spi dma driver: current spi driver just works but without dma the transfer is slow and takes full cpu time. There is some example in linux kernel source such as spi-ep93xx.c. Write this driver will be skillful, need to understand DMA arch and SPI arch.

clock driver: standard linux kernel should have clock driver for every device on the bus, current openwrt driver just like a “hack”, using fixed clock frequency in the source. If we want our code in real linux kernel(is that LEDE going to do?) must follow their rules.

VoCore2 Beta: Wifi Driver

Hello every beta tester, current openwrt(or lede) default wifi driver is not very well.
My test result of iperf is around 12Mbps.

Thanks to nobblepepper test result:

1. With the image(mtk driver) that came on VoCore2 I get:
$ iperf -c -t 30 -f m
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-30.0 sec   191 MBytes  53.4 Mbits/sec
$ iperf -c -t 30 -f m
[  3] local port 39644 connected with port
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-30.0 sec   212 MBytes  59.3 Mbits/sec

2. With lede with mt76 driver I get:
$ iperf -c -t 30 -f m
[  3] local port 39712 connected with port
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-30.0 sec  44.5 MBytes  12.4 Mbits/sec
$ iperf -c -t 30 -f m
[  3] local port 39713 connected with port
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-30.0 sec  38.4 MBytes  10.7 Mbits/sec

3. When I disable cal_free data like this (which gave me BIG
improvements in speed on MiWiFi and Linkit7688)

I get:
$ iperf -c -t 30 -f m
[  3] local port 39775 connected with port
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-30.7 sec  7.75 MBytes  2.12 Mbits/sec
$ iperf -c -t 30 -f m
[  3] local port 39776 connected with port
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-30.5 sec  7.00 MBytes  1.92 Mbits/sec

Here is a firmware from mtk openwrt, wifi works very well.
default password is 12345678

This firmware is only for one antenna. I disabled another one.
It is easy to enable by update factory setting section. update 0x0034 of factory setting to 0x3422(old should be 0x3411)

Why you can NOT BUY RaspberryPi Zero Anywhere?


The answer is simple: the price is much lower than its cost. 🙂

Currently in market 256MB DDR2 cost around 3~4USD, but RPi Zero have 512M DDR2(price should be over 5USD), Broadcom do not make DDR2, they have to buy it from somewhere else, even they can make it to 2.5USD, the other costs still over 2.5USD. 🙂

The total cost is impossible to lower than 5USD.
It is a good advertising, but we have to forget it, it won’t product anymore.

PS: … Hope I am wrong. :p

VoCore2: Beta Open NOW!!

VoCore2 Beta open NOW!!!

Thanks to all the VoCore contributors, without you VoCore is just an unknown project. In everyone’s help and support, VoCore grows up and it almost reaches its second version!

Couple days ago, we reach our final target: Lower power(< 0.5watt when low data transfer), Max signal output(>19.5dbm peak), Two antennas slots, 30+ GPIOs. DSC01786

Now, we are looking for people join us to test and develop its drivers for openwrt.

This beta, we have four versions, named v212a, v212b, v212c, v212d. Release version will be picked from one of the four, this time we have fixed all hardware bugs we found. 🙂

It is now at http://vocore.io/store, please be notified, this beta version is ONLY for developers, because we still have many drivers and softwares are not finished for this board; not suggested for beginners; the more developer, the better the further release version(and beginners might find too many bugs let your crash 🙂

The price for now is 50.00USD, include around 20.00USD for DHL shipping and 30.00USD for two VoCore2 beta version. 30USD for VoCore2 will be fully REFUNDED* for beta CODE CONTRIBUTORS**.
* also discount for final version vocore/dock, it is used to avoid abuse free beta.
** contribute vocore2 related patchesto openwrt.org or other contribute.

We only have around 100pcs are making in SMT factory now, so hurry up. 🙂

Questions please submit to forum.vocore.io, VoCore2 section. My workmate will also open a Skype/Facebook group for faster reply.

Possible changes for final release version(we are still discussing)
1. memory 64MB -> 128MB.
2. 2x U.FL slot -> on board antenna + 1x U.FL slot.
3. board color green -> white.


1. What is the final release version price?
VoCore2 price has a high chance to be same as current VoCore(20USD).

2. Will it have a dock version?
Yes, we want to make the price lower and even include a beautiful shell.

3. When will it release?
We plan to release it in two months, this depends on the beta test process, also if we have lucky on mass production.

Thanks to openwrt team again, their latest version works quite well on VoCore2.

Now I can have a happy time on developing SPI-GDMA driver, just hitting keys, much easier than using electric iron & heat gun. :p

PS: hardware part finally finished, I spent more than 1600 hours, hope them worth it 🙂

VoCore2: New Features

Coming soon, this June 🙂

## Interfaces:

1. export all GPIOs. (around 30)
2. export 3x UARTs.
3. export 1x I2C.
4. export 1x I2S.
5. export 1x reference clock.
6. export 1x USB 2.0.
7. export 1x PCIe 1.1
8. export 1x high speed SPI (max to 40Mbps)
9. export 2x antenna (UL.F) for 802.11n (max to 300Mbps)
10. input 3.6~6.0V, output 1.8V, 3.3V.
11. export 2x 10/100 ethernet port.
12. export 1x SDXC (allow high speed SD/TF card)
13. export 1x SPI slave
14. export 2x PWM (hardware PWM)

## Parameters:

* CPU: 580MHz MIPS.
* RAM: 64MB/128MB.(two versions, bigger memory special for who love python 🙂 )
* NORMAL POWER CONSUME: 74mA/5V (wifi on, no data transfer)
* PEAK POWER CONSUME: 233mA/5V (max speed cpu and wireless)

## Compare with VoCore v1.0:

* faster cpu speed.
* bigger RAM.
* lower power consume.
* better wifi signal.
* more interfaces.

We are busy on preparing the mass production, fixing & updating necessary drivers; preorder chips; prepare test process for factory; product the beta version…etc, many works left to do.
Planing stop making VoCore at May, focus on better version VoCore2.
Once June released the mass production, we will focus on software part. Anyway, VoCore is always a geek’s toy.

VoCore2: UART2 for openwrt

Now uboot part works, we need to make openwrt serial also output to UART2.

PS: weird issue, I find /dev/mem gone…is Linux 4.4.6 removed it?

My code based on trunk@49094. It is a develop openwrt version also contains many bugs. 🙂 If my code works please help me commit to openwrt.

If we do not modify anything, just flash uboot firmware to VoCore2, the serial log will end here.

U-Boot 1.1.3 (Mar 28 2016 - 22:54:05)

Board: Ralink APSoC DRAM:  64 MB
relocate_code Pointer at: 83fb8000
Software System Reset Occurred
flash manufacture id: c8, device id 40 18
find flash: GD25Q128C
*** Warning - bad CRC, using default environment

Ralink UBoot Version:
ASIC 7628_MP (Port5<->None)
DRAM component: 512 Mbits DDR, width 16
DRAM bus: 16 bit
Total memory: 64 MBytes
Flash component: SPI Flash
Date:Mar 28 2016  Time:22:54:05
icache: sets:512, ways:4, linesz:32 ,total:65536
dcache: sets:256, ways:4, linesz:32 ,total:32768 

 ##### The CPU freq = 575 MHZ #### 
 estimate memory size =64 Mbytes
RESET MT7628 PHY!!!!!!
Please choose the operation: 
   1: Load system code to SDRAM via TFTP. 
   2: Load system code then write to Flash via TFTP. 
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial. 
   9: Load Boot Loader code then write to Flash via TFTP. 
3: System Boot system code via Flash.
## Booting image at bc050000 ...
   Image Name:   MIPS OpenWrt Linux-4.4.6
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    1270118 Bytes =  1.2 MB
   Load Address: 80000000
   Entry Point:  80000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
No initrd
## Transferring control to Linux (at address 80000000) ...
## Giving linux memsize in MB, 64

Starting kernel ...

[    0.000000] Linux version 4.4.6 (vocore@ubuntu) (gcc version 5.3.0 (OpenWrt GCC 5.3.0 r49094) ) #7 Fri Apr 1 18:35:11 UTC 2016
[    0.000000] Board has DDR2
[    0.000000] Analog PMU set to hw control
[    0.000000] Digital PMU set to hw control
[    0.000000] SoC Type: MediaTek MT7628AN ver:1 eco:2
[    0.000000] bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 00019655 (MIPS 24KEc)
[    0.000000] MIPS: machine is VoCore2 64MB
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 04000000 @ 00000000 (usable)
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
[    0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
[    0.000000] Primary data cache 32kB, 4-way, PIPT, no aliases, linesize 32 bytes
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
[    0.000000] Kernel command line: console=ttyS0,57600 rootfstype=squashfs,jffs2
[    0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Writing ErrCtl register=00073670
[    0.000000] Readback ErrCtl register=00073670
[    0.000000] Memory: 60844K/65536K available (2859K kernel code, 132K rwdata, 692K rodata, 148K init, 195K bss, 4692K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:256
[    0.000000] intc: using register map from devicetree
[    0.000000] add clock for 10000d00.uart1, rate = 40000000
[    0.000000] add clock for 10000e00.uart2, rate = 40000000
[    0.000000] add clock for cpu, rate = 580000000
[    0.000000] add clock for 10000100.timer, rate = 40000000
[    0.000000] add clock for 10000120.watchdog, rate = 40000000
[    0.000000] add clock for 10000b00.spi, rate = 193333333
[    0.000000] add clock for 10000b40.spi, rate = 193333333
[    0.000000] add clock for 10000c00.uartlite, rate = 40000000
[    0.000000] add clock for 10180000.wmac, rate = 40000000
[    0.000000] CPU Clock: 580MHz
[    0.000000] clocksource_probe: no matching clocksources found
[    0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 6590553264 ns
[    0.000011] sched_clock: 32 bits at 290MHz, resolution 3ns, wraps every 7405115902ns
[    0.015349] Calibrating delay loop... 385.84 BogoMIPS (lpj=1929216)
[    0.080520] pid_max: default: 32768 minimum: 301
[    0.089782] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.102736] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.122279] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.141778] pinctrl core: initialized pinctrl subsystem
[    0.152723] NET: Registered protocol family 16
[    0.179323] mt7621_gpio 10000600.gpio: registering 32 gpios
[    0.190412] mt7621_gpio 10000600.gpio: registering 32 gpios
[    0.201416] mt7621_gpio 10000600.gpio: registering 32 gpios
[    0.213941] clocksource: Switched to clocksource MIPS
[    0.225338] NET: Registered protocol family 2
[    0.234765] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.248470] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.260983] TCP: Hash tables configured (established 1024 bind 1024)
[    0.273632] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.285086] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.297732] NET: Registered protocol family 1
[    0.307657] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.338516] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.349983] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.372014] io scheduler noop registered
[    0.379693] io scheduler deadline registered (default)
[    0.390672] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[    0.404112] rt2880-pinmux pinctrl: invalid group "spis" for function "pwm"
[    0.417827] console [ttyS0] disabled
[    0.424820] 10000e00.uart2: ttyS0 at MMIO 0x10000e00 (irq = 30, base_baud = 2500000) is a 16550A
[    0.442151] console [ttyS0] enabled
[    0.442151] console [ttyS0] enabled
[    0.455889] bootconsole [early0] disabled
[    0.455889] bootconsole [early0] disabled
[    0.473336] spi-mt7621 10000b00.spi: sys_freq: 193333333
[    0.487529] m25p80 spi32766.0: using chunked io (size=32)
[    0.498290] m25p80 spi32766.0: gd25q128 (16384 Kbytes)
[    0.508501] 4 ofpart partitions found on MTD device spi32766.0
[    0.520053] Creating 4 MTD partitions on "spi32766.0":
[    0.530233] 0x000000000000-0x000000030000 : "u-boot"
[    0.541846] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.554307] 0x000000040000-0x000000050000 : "factory"
[    0.566168] 0x000000050000-0x000000800000 : "firmware"
[    0.603038] 2 uimage-fw partitions found on MTD device firmware
[    0.614797] 0x000000050000-0x0000001861a6 : "kernel"
[    0.626261] 0x0000001861a6-0x000000800000 : "rootfs"
[    0.637985] mtd: device 5 (rootfs) set to be root filesystem
[    0.649351] 1 squashfs-split partitions found on MTD device rootfs
[    0.661606] 0x000000370000-0x000000800000 : "rootfs_data"
[    0.683669] rt3050-esw 10110000.esw: link changed 0x00
[    0.695347] mtk_soc_eth 10100000.ethernet: generated random MAC address fe:67:bf:04:9d:38
[    0.712449] mtk_soc_eth 10100000.ethernet eth0: mediatek frame engine at 0xb0100000, irq 5
[    0.729378] mt7621_wdt 10000120.watchdog: Initialized
[    0.740958] NET: Registered protocol family 10
[    0.753409] NET: Registered protocol family 17
[    0.762371] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this.
[    0.787379] 8021q: 802.1Q VLAN Support v1.8

Now my fix( as dirty as always 😀 )
1. modify MIWIFI-NANO.dts(I did not create new VoCore2.dts to make test easier)

+++ b/target/linux/ramips/dts/MIWIFI-NANO.dts
@@ -3,11 +3,11 @@
 /include/ "mt7628an.dtsi"
 / {
-       compatible = "xiaomi,MiWifi Nano", "mediatek,mt7628an-soc";
-       model = "MiWiFi Nano";
+       compatible = "vocore2,vocore", "mediatek,mt7628an-soc";
+       model = "VoCore2 64MB";
        chosen {
-               bootargs = "console=ttyS0,115200";
+               bootargs = "console=ttyS0,57600";
        memory@0 {
@@ -18,7 +18,7 @@
        pinctrl {
                state_default: pinctrl0 {
                        gpio {
-                               ralink,group = "refclk", "wled", "gpio";
+                               ralink,group = "refclk", "gpio";
                                ralink,function = "gpio";
@@ -87,5 +87,13 @@
+               uart2@e00 {
+                        status = "okay";
+               };
+               pwm@5000 {
+                        status = "okay";
+               };
diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi
index e120e56..819ac82 100644
--- a/target/linux/ramips/dts/mt7628an.dtsi
+++ b/target/linux/ramips/dts/mt7628an.dtsi
@@ -170,6 +170,8 @@
                        pinctrl-names = "default";
                        pinctrl-0 = <&uart0_pins>;
+                       status = "disabled";
                uart1@d00 {
@@ -301,8 +303,8 @@
                uart2_pins: uart2 {
                        uart2 {
-                               ralink,group = "uart2";
-                               ralink,function = "uart2";
+                               ralink,group = "spis";
+                               ralink,function = "pwm";

2. modify /linux-4.4.6/arch/mips/ralink/mt7620.c:407

		ralink_clk_add("10000d00.uartlite", periph_rate);
		ralink_clk_add("10000e00.uartlite", periph_rate);

change to

		ralink_clk_add("10000d00.uart1", periph_rate);
		ralink_clk_add("10000e00.uart2", periph_rate);

This just works, but I do not think it is the best way. We should use ttyS2 in dts, but not ttyS0. I still need time to understand how pinctrl works. 🙂