VoCore: I2S Sound Card WM8960G 3

Now, I will output some data from I2S data line.

For simple, we do not enable any interrupt, and do not use DMA. Just put some data out.
Screen Shot 2015-06-18 at 19.15.11

We fill the register with a test data, for example 0x12345678.(This output is just noise, real sound data should be get from your wav file.)
Then enable I2S by the following command

Prepare LRCLK and BCLK.

./mems 0x60 0x00400098
./mems 0xa00 0x81004040
./mems 0xa24 0x0E
./mems 0xa20 0x800000aa

Put some DATA into I2S data wire.

./mems 0xa10 0x12345678

Watch the output from Logic Analyzer.


Looks like everything is alright.

Next, we should setup the I2C, to make WM8960G play the noise. :)

First make sure you have i2c-tools, we need command “i2cset”
WM8960G i2c interface is not standard i2c(if there is any standard :) ) For most i2c chip, it is address(7bit) + write/read(1bit) + register address(8bit) + register data(8bit), so command “i2cdump” will work on such chip. Unfortunately, WM8960G is not such chip :P. Its I2C format is address(7bit) + write(1bit, write only) + register address(7bit) + register data(9bit), so we must calculate such register before we use it.

Once you setup this, WM8960 is ready to work. Check WM8960G datasheet for more details about the values.

i2cset -y 0 0x1a 0x1e 0x00
i2cset -y 0 0x1a 0x0e 0x02
i2cset -y 0 0x1a 0x08 0x05
i2cset -y 0 0x1a 0x68 0x07
i2cset -y 0 0x1a 0x6a 0x86
i2cset -y 0 0x1a 0x6c 0xc2
i2cset -y 0 0x1a 0x6e 0x26
i2cset -y 0 0x1a 0x32 0xc0
i2cset -y 0 0x1a 0x35 0xe1
i2cset -y 0 0x1a 0x5e 0x0c
i2cset -y 0 0x1a 0x45 0x00
i2cset -y 0 0x1a 0x4b 0x00
i2cset -y 0 0x1a 0x0a 0x00
i2cset -y 0 0x1a 0x05 0xf8
i2cset -y 0 0x1a 0x07 0xf8

Once you put data into register 0xa10, the headphone(left headphone connect to HP_L and GND, right headphone connect to HP_R and GND) will output some noise. The sound might be loud, be careful :)

If you write a simple app make it read from wav file and keep filling the register 0xa10, there will be some “music” out.

The “music” will not at good quality, due to the FIFO in RT5350 might overflow or underflow.

We must use DMA to make the music be played smoothly, but that is much much harder:

1. DMA have to enable DMA-I2S hardware interrupt, but that interrupt(id:7?) is already taken by openwrt, directly request interrupt will fail.
2. Interrupt must be used in kernel mode, so mems/memv will not work anymore, we can not peacefully play the code in user mode, but must write some “dangerous” code in kernel mode. :)

Next blog will be hard for new learner. Need strong linux kernel develop knowledge.

VoCore: I2S Sound Card WM8960G 2

Its time to make I2S work.

I2S contains three wires for sound:
BCLK: bit clock, basic clock for the data.
LRCLK: left channel/right channel clock.
DATA: used to send data.

My target is to enable BCLK and LRCLK, in I2S master mode.

For simple, I did not have to write a driver but directly write to register by mmap /dev/mem.

Here is a small application to make it easy.
Source Code: mems.c, memv.c
mems is used to set register, memv is used to view register.
PS: I guess there already exists tons of such tools, but I am too lazy to search, just five minutes work. :D

Compile the source code and upload them to VoCore.

First, we should set pinmux, to make the pinmux from GPIO mode to I2S + GPIO mode.
From RT5350 datasheet, its register is 0x0060.
use memv to get it current value:

memv 0x0060 4


# ./memv 0x0060 4
offset: 0x10000060, size: 0x00000004
ADDR    : +0 +1 +2 +3 +4 +5 +6 +7  +8 +9 +A +B +C +D +E +F    0123456789ABCDEF
00000000: 9C 00 40 00                                         ..@.

so it is 0x0040009C = 0000 0000 0100 0000 0000 0000 1001 1100 in binary.
4:2 bit are 111, it means UARTF_SHARE_MODE is all GPIO.
check datasheet again, I2S + GPIO is 110, so we update it to 0000 0000 0100 0000 0000 0000 1001 1000 = 0x00400098

mems 0x0060 0x00400098

Note: change 4:2 but keep all other bits.

Then, setup I2S register, update PLL to make BCLK output correct clock.
Set LRCLK to 44100Hz, so BCLK = 44100Hz x 16bits x 2channels = 1411200Hz
From datasheet FreqOut = FreqIn *(1/2) *{1 / [DIVINT+DIVCOMP/(512)]}, FreqOut = 1.4112M, FreqIn = 40M.
So DIVINT = 0x0E, DIVCOMP = 0x58, and PLL clock bit enable.

mems 0x0a20 0x80000058
memv 0x0a24 0x0000000E

Final, enable I2S, view its output.

memv 0x0a00 0x81004040

The result looks pretty well :)
If you do not have a logic analyzer, a voltmeter is a simple replacement. If the I2S BCLK and LRCLK output is about 1.65V(3.3V/2), that means I2S circle in VoCore is working.

Next blog I will talk about how to output some real sound data through I2S.

VoCore: I2S Sound Card WM8960G

Just finished wifi speaker by using WM8960G on VoCore(RT5350F) I will put the process day by day as usual. :)

Here is the sch/layout for WM8960G, I left a lot of space for 0ohm, make it easy for debug.
XTAL should be 12MHz oscillator.
Note: one mistake in the sch, I forget to export SPKVDD1, it have to be jump wire connected to SPKVDD2.

Two layers PCB board, cost about 20USD for 5 pieces.

PS: my first choice is ALC5626 from realtek, but their tech support is so stupid! I can not get even its datasheet. They said I have to sign a NDA and contact their distributor, but their phone no answer and email no reply…I will never use realtek chip anymore. Chinese semiconductor company especially Taiwan semiconductor company should be open to developper. Cirrus.com is a very good company, I can easily find everything I need on their website, and its driver code is already in linux master source code. :D

VoCam264: New Process



VoCam264 sample has done, but I have to say this size is impossible for h264 camera. :'(

I handled the signal, handled the noise, but can not handle the heat :D
It works well at start, but after two or three minutes, the CMOS will go over 50C(about 55C, env 25C, set it up to 720p h264), even with heat sink. That heat will slightly effect the quality of video, I can not accept that flaw.

…the only thing make me happy is it works well if h264 resolution < 800×600 :D and the power consume is around 0.54watt, looks fair.

New plan will double PCB size, 12x24mm, move CMOS away from top of h264 encode chip, that will keep it under 35C, so in bad situation(env 40C), it will still have good quality.

VoCore: I2C / AD Convert

It is time to write something :)
My choice is I2C on VoCore, due to it is necessary for AD convert chip, my board main chip is PCF8591T.
In VoCore forum, somebody have tried that already, happens to use the same chip, that really helps a lot.
Here is the link:


This is my PFC8591T test board:

Directly connect to VoCore:

BOARD VCC -> VoCore 3.3V
BOARD SDA -> VoCore G#01/I2C_SD

Note: Please download the latest manual, old one have bug about i2c pins. http://vonger.cn/upload/vocore.manual.pdf

My connection:

Important Note: I2C should have pull up resistors on SCL and SDA, but for simple, I did not use it, my current PFC8591T just works well, but it is not guaranteed, in other case, MUST connect with pull-up resistors.

ssh to VoCore, check if /dev/i2c-0 exists.
If not, check if you have installed all i2c model(call lsmod | grep i2c)
kmod_i2c_core, kmod_i2c_dev and kmod_i2c_ralink

If there still no /dev/i2c-0. call insmod i2c-dev
(Still not there? Try to compile and upload firmware again, might be driver version issue, old driver might not work)

Option: we can install i2c-tools to test i2c.
Current openwrt package, it has been removed.
We can find it in old packages for 14.07.



Call i2cdetect -r 0
You will get this:

root@OpenWrt:~# i2cdetect -r 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0 using receive byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                    

That 48 is HEX, it is equal 1001000b, that is PCF8591T address code, so this device is normal.

Let’s try more. :) The code on forum just works, compile it and transfer it to VoCore.(Looks like we are using same board too, so I do not need to change a line :D )

root@OpenWrt:/tmp# ./pcf8591
Light:245 Temp:216 X:148 Potmeter:120

My compiled app: pcf8591

VoCore: RC servo

Thanks to Ton Augustin(ton/at/augustin.com) provide this driver. :)
I do not have such device, so I did not do a full test. Hopefully this will help if you are using VoCore do similar project.

Source code/Usage/Firmware Download:

VoCore: AP+STA Switch

This blog is used to solve the problem: when we setup AP+STA mode but STA can not connect to host, it will cause AP fails to show itself.

The Reason:
AP+STA, its real name is Bridge Mode, it uses half bandwidth connect to AP and another half to STA. So AP/STA must in same channel. If the driver can not find STA host, it will not get the channel for AP, so AP in VoCore can not show.

First, scan STA connection state, if it fails to connect to STA, then force VoCore into AP mode. The benefit is obviously: we do not have to use TTL/ethernet to setup the config anymore, users are able to use wifi to update the configuration now.

The Script:
This script is from Zhuohuan Lee. It uses ubus to scan the STA state every 2~3 seconds. If STA fail, it will turn VoCore to AP mode. A nice script. :)

Download Here: fix_sta_ap.sh

PS: My idea is a script only run once after boot up, if STA do not work, make VoCore to AP mode, so we do not have to check every seconds.

Run it at startup.

root@OpenWrt:~# cat /etc/rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

/bin/sh /root/fix_sta_ap.sh > /dev/null &

exit 0


VoCam264: Now It WORKS :)

VoCam264 is only 12.5mm x 12.5mm x ?? standard USB h264 720p HD camera. Now it works!

春节快乐!It is Chinese New Year recently, I did not get a chance update this blog :D

Finally make the first version work normal.

Here is the ugly one :) Thanks to my jump-wire skill learned from developing VoCore.



The little one is a hot nuke when I connect it to USB, h264 encode is always hot. So release version will have a heat sink by default. I connect 12mm x 12mm x 3mm heat sink, works well, lower its temperature to about 42C, peace to use it.

Screen Shot 2015-02-23 at 22.46.39


I think this little heat sink is also good for VoCore RT5350, not cost much, about 5~8 cent.

I can not get its power consume due to if I did not connect USB D+/D-, it will go to standby mode by default, standby mode power consume should be lower than 5mA/5V.(it is 0.00A on my amperemeter) From its temperature, I guess its power consume is about 100mA ~ 150mA(0.6watt) when full speed working.

Now I should find a good lens for it. The CMOS chip is OV9712, any idea about good lens for it?(please email me,at,vonger.cn)

VoCore: AirPort with USB Sound Card


Important: DO NOT buy such USB sound card like mine, it can not work. From Jeremy, USB sound card with CM108 chip works normal.

Call make menuconfig, select
Kernel modules –> Sound Support –> kmod-sound-core, mod-usb-audio
Kernel modules –> USB Support –> kmod-usb-core, kmod-usb-ohci, kmod-usb2
Utilities –> alsa-utils
Multimedia –> shairport

First, to make it compile smoothly, we must install perl XML::Parser or openwrt will complain “checking for XML::Parser… configure: error: XML::Parser perl module is required for intltool”.

perl -MCPAN -e shell

this part, press return/enter until CPAN shows its command line.

But this XML::Parser library can not install on my MAC, it can not pass its test, so we have to call install without test, use “force install”.

In CPAN command line, call this command.

force install XML::Parser

Finally call make V=s.

Now if everything moves smoothly, you will get the system upgrade file, scp it to your VoCore or other openwrt device, call mtd -e firmware write xxxxxxx.bin to cover your old firmware.

Plugin the USB sound card, call shairport -a VoCoreAIR

My Mac find it successfully:
Screen Shot 2015-02-14 at 11.09.53

but unfortunately, my side get the following error, :(

ALSA lib confmisc.c:768:(parse_card) cannot find card '0'
ALSA lib conf.c:4259:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4259:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1251:(snd_func_refer) error evaluating name
ALSA lib conf.c:4259:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:4738:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM default
FATAL: Alsa initialization failed: unable to open pcm device: No such file or directory

Shutting down...

I think the sound card is not correctly supported…so the app can not find interface of the card.
(if the USB sound card works, it will light a red LED)
If you have any idea(I removed the register on this blog due to too much spam here :) ), please mail me/at/vonger.cn .

Special thanks to Alex Tsai provide the install instruction of shairport.

It is openwrt truck issue :) Once change to 14.07, everything works normal, Jeremy solution is perfect, works well.