VoCam264: Perfect now!

DSC01774

After 12 failed versions, finally I made it.

Pure Video Quality: every detail, just that clean.
Low Power Consumption: h264 mode <= 0.75w(1080p/25fps); MJPG <= 0.7w Small size: 20mm only.
High Compress: 1080p/25fps, 300~600KB/s
Embed Microphone: 8KHz, sound record.
USB 2.0 Interface: directly connect to VoCore or PC, no driver requested(mjpeg).
Lens: 2.8mm 130°

lens

Stable Temperature: -10~35℃ (1080p/15fps, 0.75watt)
Max Operation Temperature: 45℃
Max: 1080p, 30fps(this is not good for CMOS, might cause permanently damage)
WARNING: over 45℃ might cause permanently damage to CMOS, suggest use it in room under 35C(heat sink is necessary).

I spend over 1000 hours on this little thing, once I even think it is impossible: I can not avoid noise from DCDC effects the video quality; I can not lower the power consumption; I can not reduce the heat; I can not… but everything has passed, THERE IT IS.

This is a real challenge. 😀 What next?

PS: we did not compose the heat sink and lens.

Fix VoCore can not show AP when STA not working in AP+STA

Recently I am trying to fix a issue that most people had already known it: if you setting up VoCore into AP+STA mode to connect to your home router(or any router else), once your changed your home router password or you bring VoCore to another place that it can not find your home router AP signal ,VoCore will failed to create its “VoCore-XXXXXX” AP hot point.
(Is Chinglish the most popular language on internet? 😀 Hope you can understand what I am saying upper)
The problem is you will not able to connect to VoCore through wireless if you bring your VoCore-in-AP+STA-mode to another place.

Last time I introduce a script writing by LiZhuohuan, but it has some limit, it is not clever enough, it only change your VoCore from AP+STA to AP when it detect VoCore can not connect to your home router, but once your VoCore back to your home, it can not recover it, you have to set AP+STA back manually, and the script keep running every 10~30 seconds, that takes power. So I write this little tool do all magically.

Install:
Copy vocoremon to /bin/vocoremon
Add one line into /etc/rc.local:
/bin/vocoremon 20 >> /tmp/vocore.log &
That’s ALL.

Every time VoCore boot up, it will run vocoremon, if AP+STA is normal, quit itself, else vocoremon makes VoCore run in AP mode. When next time boot, vocoremon find your STA back to normal, it will quit AP mode and make VoCore run back into AP+STA mode.
So once you install vocoremon, do not have to take USB2TTL anymore, VoCore are able to create its AP hot point anywhere, any setting.

I tested it, works normal in my home, but I know the situation is complex, it has a low chance not working, I open the source code into https://github.com/Vonger/vocoremon.git, hope everybody could update it make it better.

The bin file can be download here. http://vonger.cn/upload/tools/vocoremon

VoCore: Power Save Test => Turn off WIFI + Ethernet

Just want to know, in standby mode, how much power will VoCore consume.
It is very interesting, if we shutdown ethernet, VoCore current consume will low to 0.1A(0.5watt), if we shut down wifi, how much power will it consume?

First, call script http://vonger.cn/?p=1880, shutdown the ethernet.
Then, power off wifi.(add “option disabled 1” to /etc/config/wireless)

The result of RT5350 is really out of my imagination.

Here is the picture and the truth:
C055C8FE9731D0D9009E90ABBF3B4AD9

1h20m, but only 80mAh!(Three hours is around 200mAh)

That means it consumes ONLY 70mAh every hour, a small Li-battery(2000mAh) will able to make it work over a day!

VoCore is not sleeping, we can enable the wifi or ethernet anytime in 3 seconds through UART.

Same test for VoCore2: standby power consume is around 63mAh…Emm, this result is not much better, but fair, 580MHz vs 360MHz. Looks like it is the chip limit.

VoCore2: In Process

890827487

Tested system and IO, everything works fine. Now just needs to make the antenna better. 🙂 Hopefully it can be released in this year.

VoCore: Save Some Power(1.0w => 0.6watt)

Some users are asking about save power on VoCore, it is easy to do.

1. Download this simple tool: mems(or compile mmio)

2. scp this mems to VoCore.

3. make it executable.

chmod +x mems

4. call the following command to save power by shutting down ethernet 0~3.

./mems 0x101100c0 0x08002000
./mems 0x101100c0 0x08002001
./mems 0x101100c0 0x08002002
./mems 0x101100c0 0x08002003

4.b. if you want to power on ethernet 0~3, just call the following command:

mems 0x101100c0 0x00002000
mems 0x101100c0 0x00002001
mems 0x101100c0 0x00002002
mems 0x101100c0 0x00002003

From datasheet, this register(0x101100c0) is used to send message to internal registers, so we can use it to save power by closing ethernet ports that we do not use.
PS: better to call the command once VoCore boot up or it might fail.

VoCore OpenWrt Interrupts

We can get current activated interrupt list by cat /proc/interrupts

root@OpenWrt:/# cat /proc/interrupts
           CPU0       
  5:        220      MIPS 5  10100000.ethernet
  6:     101471      MIPS 6  rt2800_wmac
  7:     117075      MIPS 7  timer
  9:          0      INTC 1  10000100.timer
 20:         30      INTC 12 serial
 25:          1      INTC 17 esw
 26:          1      INTC 18 ehci_hcd:usb1, ohci_hcd:usb2
ERR:          0

It is IRQ id/Count/Type/hardware IRQ id/dev_name(request_irq) from left to right. (Old linux version do not have IRQ hardware id)
From datasheet, we need IRQ10 for I2S. From the list, it is free, that is a good news, that means if we call request_irq, it will success.(I will try this in next blog, looks like openwrt is not using same way mapping interrupts as ralink sdk, have to read more openwrt base code)
If IRQ10 already be taken by other driver, that is a terrible IRQ conflict…

In path_to_linux/linux/include/interrupts.h, we can get request_irq define(might not same file in different linux version):
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}

request_irq is easy to use, that means once the interrupt happens, the function in handle will be called.
So once we get data from I2S buffer or the data in I2S buffer is used out, the interrupt will be called and notify us to fill the buffer. We do not have to check the register in a loop, that makes the CPU relax.

In DMA mode, GDMA gets data from memory to I2S buffer once the interrupt is trigged, CPU does not have to deal the interrupt anymore, it has more free time to do other work, in another word, IO speed is great improved.

For more information, just search online about DMA and IRQ, there are many blogs explain how they work.

What next?
Request IRQ10 from system, and make a demo check if the interrupt are able to trigger once the I2S buffer is out.

PS: This blog is a challenge to my English. 😀

VoCore & Camera: 2015.7.30

Recently we are busy on new VoCore, I call it VoCore2, it has greatly improved in lower power consume, lower heat, faster cpu speed, more ram, even has two antennas are able to work same time in different channel(maybe perfect for mesh net? :p) and many other new features such as SDXC support, hardware PWM, faster SPI through DMA, but still SAME ONE INCH(25mm). We will public all its features about in butt of August after everything is confirmed, and batch production about early of 2016, it should be enough time to learn & play VoCore v1.0 first. 😀
vocore2
(Guess the chip? Hoho~)

Another news is the H264 camera finally passed my test(summer env 50C, works well for a week). We update the chip from 720p to 1080p/30fps(1.7mm lens), BOM cost is doubled but I think it is very worth. Developing the little evil thing almost killed me. I have to increase the PCB size to 20mm x 20mm and attach a heatsink, I think I have made it to the very best, there is no way to make it even 1mm smaller. (If you have a big enough mouth, it can be used as endoscopy
🙂 )

Tomorrow I will continue to update the I2S & WM8960G driver. Before I write something about the DMA driver, we must be very clear about interrupt for Linux. Obviously, I am not a good teacher, I will try my best to make it as simple as possible. 😀

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.

[)ATH8H]}}EZ}P$@W06NJ)I

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. 😀

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

result:

# ./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 🙂
i2s
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.
sch
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.
WM8960.asc

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. 😀