DPF hacking part three

March 17th, 2012

Sorry, sorry, sorry.

Time flies! We had the full standalone firmware running for a while, but just didn’t get around to publish it.
It’s nice to see that plenty of people are actually using this hack on their linux powered sat receivers, dreamboxes, etc.
Less nice to see, that people do mods, but don’t contribute back. Didn’t exactly motivate us to release the most recent fun stuff. But anyhow, we give it another go by kicking out another 0.200 developer release. This contains the raw framework only. No games, and no fun stuff. Although one most wanted feature comes with it: no more waiting for the device to go in bluescreen mode to be ready for lcd4linux.

Here’s a package with the ready built firmware:

http://tech.section5.ch/files/dpf-ax_bin_0.200devel.zip

If you have successfully managed to get the hack to run on one of your DPFs, then you’ll likely be able to determine your DPF type (blue, white, etc.).  If you don’t, you’ll have to do some trial & error. Just flash the entire .bin image to your DPF using ProgSPI.exe or restore.py. For detailed instructions, there are various readme files in the source distribution.

To obtain these utilities or checkout the current source, see links in DPF hacking part two

VNC on DPF

VNC DPF client demo

There’s some fun stuff in the next box, really. The 1.0 firmware will have support for a full remote display based on the VNC protocol. For efficiency, the 1.0 protocol will not be compatible with the current SCSI command emulation. So for all programmers: Don’t access the DPF direct

ly, if you want to use future versions. Use the dpflib only!

 

Last but not least: You’re always welcome to throw in a few bucks, not to cover expenses, but you know, just the symbolic thing counts. We’ll add your email to the notification list for new stuff – if you like. Just insert the word “subscribe” somewhere in the comment.


One last note: We’ve come across a few pre-flashed Pearl units sold on ebay for a 3x price. Guys, that simply is lame. If we wanted to make money, we’d have done that way earlier.

New ICEbear light hardware

March 7th, 2012

After getting many requests for the ‘old’ ICEbear light which was announced to head end of life a long time ago, I’ve decided to give it another spin.

The focus this time will be on cheap production. As you might know, the ICEbear is not a mass product, and it has been rather expensive to get it manufactured, because the focus was on a specific developer community only. Other significant costs are due to the efforts that have gone into the software, testing with many boards, and the direct support of customers.

Unfortunately, it has turned out, that a few folks on the web have made clones of the hardware and happily use the software without a license. What can one do about it? Force users to go through registration procedures? Nah. We like to keep it simple. If the hardware can be manufactured cheaper and the support costs are stripped off, we can still maintain the quality as people were used to.

So the next ICEbear Light is planned as follows:

  • Completely outsourced manufacture and distribution
  • Really no extended support. We won’t write your drivers and board supply packages as free add-ons.
  • It will be cheap, and you’re on your own with it. If it doesn’t work for your hardware out of the box, you haven’t lost much money. And you can still do a lot with the freely available Opensource tools.

Enough talking, here’s a snapshot. It might not be the final picture, still thinking about minor improvements. But you can count on the form factor.

ICEbear Light photos

ICEbear Light V2

VHDL simulation remote display

September 28th, 2011

In the previous article we described the netpp server enhancements to our GHDL based simulation to feed data to a FIFO. So we had condemned that extra thread being a slave listening to commands. But what if the GHDL-Simulation would be a netpp master?

Inspired by Yann Guidons framebuffer example at http://ygdes.com/GHDL/, the thought came up: why not hack a netpp client and use the existing ‘display’ device server (which we use for our intelligent camera remote display). What performance would it have?

For this, we extended our libnetpp.vhdl bindings by a few functions:

  • function device_open(id: string) return netpphandle_t — Opens a connection to a netpp (remote) device
  • function initfb(dev: netpphandle_t; x: integer; y: integer; buftype: integer) return framebuffer_t — Initialize virtual frame buffer from device
  • procedure setfb(fb: framebuffer_t; data: pixarray_t) — transfer data to framebuffer

Not to forget the cleanup functions device_close() and releasefb().

With this little functionality, we are running a little YUV color coded display as shown below:

Framebuffer output

It is very slow as  we keep repeatedly filling the YUV (more precisely UYVY interleaved data) using a clock sensitive process. We thus get a framerate of about 1fps – but it works!

Find the current code here:

http://section5.ch/downloads/ghdlex-0.03eval.tgz

Asynchronous remote simulation using GHDL

September 26th, 2011

Simulation is daily business for hardware developers, you can’t get things running right by just staring at your VHDL code (unless you’re a real genius).

There are various commercial tools out there which did the job so far: MentorGraphics, Xilinx isim, and many more, the limit mostly being your wallet.

We’re not cutting edge chip designers, so we used to work with the stuff that comes for free with the standard FPGA toolchains. However, these tools – as all proprietary stuff – confront you with limitations sooner or later. Moreover, VHDL testbench coding is a very tedious task when you need to cover all test scenarios. Sooner or later you’ll want to interface with some real world stuff, means: the program that should work with the hardware should first and likewise be able to talk to the simulation.

The interfacing

Ok, so we have a program written in say, C – and a hardware description. How do we marry them? Searching for solutions, it turns out that the OpenSource GHDL simulation package is an ideal candidate for these kind of experiments. It implements the VHPI-Interface, allowing to integrate C routines into your VHDL simulation. Its implementation is not too well documented, but hey, being able to read the source code compensates that, doesn’t it?

So, we can call C routines from our simulation. But that means: The VHDL side is the master, or rather: It implements the main loop. This way, we can’t run an independent and fully asynchronous C procedure from the outside – YET.

Assume we want to build up some kind of communication between a program and a HDL core through a FIFO. We’d set up two FIFOs really..one for Simulation to C, and one for the reverse direction. To run asynchronously, we could spawn the C routine into a separate thread, fill/empty the FIFO in a clock sensitive process from within the simulation (respecting data buffer availability) and run a fully dynamic simulation. Would that work? Turns out it does. Let’s have a look at the routine below.


mainclock:
	process    -- clock process for clk
	begin
		thread_init; -- Initialize external thread

		wait for OFFSET;
		clockloop : loop
			u_ifclk <= '0';
			wait for (PERIOD - (PERIOD * DUTY_CYCLE));
			u_ifclk <= '1';
			wait for (PERIOD * DUTY_CYCLE);
			if finish = '1' then
				print(output, "TERMINATED");
				u_ifclk <= 'X';
				wait;
			end if;
		end loop clockloop;
	end process;

Before we actually start the clock, we initialize the external thread which runs our C test routine. Inside another, clock sensitive process, we call the simulation interface of our little C library, for example, the FIFO emptier. Of course we can keep things much simpler and just query a bunch of pins (e.g. button states). We’ll get to the detailed VHPI interfacing later.

Going “virtual”

The previous method still has some drawbacks: We have to write a specific thread for all our asynchronous, functionality specific C events. This is not too nice. Why can’t we just use a typical program that talks a UART protocol, for example, and reroute this into our simulation?

Well, you expected that: yes we can. Turns out there is another nice application for our netpp library (which we have used a lot for remote stuff). Inside the thread, we just fire up a netpp server listening on a TCP port and connect to it from our program. We can use a very simple server for a raw protocol, or use the netpp protocol to remote-control various simulation properties (pins, timing, stop conditions, etc).

This way, we are interactively communicating with our simulation for example through a python script with the FIFO:


import time
import netpp

dev = netpp.connect("localhost")
r = dev.sync()

r.EnablePin.set(1) # arm input in the simulation
r.Fifo.set(QUERY_FRAME) # Send query frame command sequence
frame = r.Fifo.get() # Fetch frame

hexdump(frame) # Dump frame data

Timing considerations

When running this for hours, you might realize that your simulation setup takes a lot of CPU time. Or when you’re plotting wave data, you might end up with huge wave files with a lot of “idle data”. Why is that? Remember that your simulation does not run ‘real time’. It simulates your entire clocked architecture just as fast as it can. If you have a fast machine and a not too complex design, chances are that the simulation actually has a shorter runtime that its actual realtime duration.

So for our clock main loop, we’d very likely have to insert some wait states and put the main clock process to sleep for a few µs. Well, now we’d like to introduce the resource which has taught us quite a bit on how to play with the VHPI interface: Yann Guidons GHDL extensions. Have a look at the GHDL/clk/ code. Taking this one step further, we enhance our netpp server with the Clock.Start and Clock.Stop properties so we can halt the simulation if we are idling.

Dirty little VHPI details

Little words have been lost about exactly how it’s done. Yanns examples show how to pass integers around, but not std_logic_vectors. However, this is very simple: they are just character arrays. However, as we know, a std_logic has not just 0 and 1 states, there are some more (X, U, Z, ..)

Let’s have a look at our FIFO interfacing code. We have prototyped the routine sim_fifo_io() in VHDL as follows:


        procedure fifo_io(
                din: inout fdata;
                flags : inout flag_t
        );
        attribute foreign of fifo_io : procedure is
                "VHPIDIRECT sim_fifo_io";

The attribute statement registers the routine as externally callable through the VHPI interface. On the C side, our interface looks like:

void sim_fifo_io(char *in, char *out, char *flag);

The char arrays just have the length of the std_logic_vector from the VHDL definition. But there is one important thing: the LSB/MSB order is not respected in the indexing order of the array. So, if you have a definition for flag_t like ‘subtype flag_t is unsigned(3 downto 0)’, flag(3) (VHDL) will correspond to flag[0] in C. If you address single elements, it might be wise to reorder them or not use a std_logic_vector. See also Yanns ’bouton’ example.

Conclusion and more ideas

So with this enhancement we are able to:

  • Make a C program talk to a simulation – remotely!
  • Allow the same C program to run on real hardware without modifications
  • Trigger certain events (those nasty ones that occur in one out of 10000) and monitor them selectively
  • Script our entire simulation using Python

Well, there’s certainly more to it. A talented JAVA hacker could probably design a virtual FPGA board with buttons and 7 segment displays without much effort. A good starting point might be the OpenSource goJTAG application (for which we hacked an experimental virtual JTAG adapter that speaks to our simulation over netpp). Interested? Let us know!

Update: More of a stepwise approach is shown at http://www.fpgarelated.com/showarticle/20.php

Another update: Find my presentation and paper for the Embedded World 2012 trade show here:

In circuit emulation for the ZPU

August 30th, 2011

So, you’ve been getting used to JTAG for debugging CPUs and funky reverse engineering, haven’t you?

Let’s move to something more constructive. The ZPU softcore has been out for a while. It’s intriguingly simple to use and is really saving on resources. Moreover, it has a fully functional toolchain, simulator and debugger. So why not take this on to the hardware?

The shopping list:

  1. A Test Access Port implementation (TAP)
  2. A piece of software wrapping all the gdb command primitives
  3. A JTAG adapter

The TAP

Lets summarize again on the functionality we expect from a debug port. We want to:

  1. Stop CPU, resume
  2. Single step through code
  3. Read and write PC, SP and other registers
  4. Access Memory (program memory, stack, I/O)
  5. Set software breakpoints in the code

So, the ZPU needs a breakpoint instruction. Well, it does have one! Just that it hasn’t been handled (apart from the simulation) until now. What else is missing? Basically, the EMULATION state. Emulation or to be really precise, In Circuit Emulation (not to mix up with the emulated instructions inside the ZPU) is the standard method to test a CPU in real world, by interrupting its normal execution and feeding instructions via the Debug Port or better: TAP. After the CPU core has executed the so emulated instruction, it returns to emulation mode as long as the emulation bit is set. Leaving emulation again requires an instruction, we just use the same breakpoint instruction (0×00) for this. If the emulation bit is no longer set, the ZPU continues its normal operation, otherwise it executes the next instruction and returns to emulation mode.

This way, we can achieve everything in a simple way – we just have to make sure to save all CPU states in order to avoid being too intrusive. Remember, it can be a nightmare when the program runs when the debug monitor is active, but crash when not in debug mode. Or worse, vice versa.

Being non-intrusive is a matter of the software. On the ZPU we are changing the stack during most of the operations, so we have to explicitely fix it up before returning from emulation.

Let’s summarize what we needed to implement for the TAP – in VHDL modules:

  • jtagx.vhl: The generic JTAG controller
  • tap.vhdl: The Test Access Port module, using the above JTAG controller. Other type of debug interfaces can be implemented, too

Between TAP and core (ZPU small), we have a bunch of signals and registers. These are merely:

  • emurequest: Request emulation mode (input, level sensitive)
  • emuexec: Execute emulated instruction (input, one clk wide pulse)
  • emuir: Emulation instruction register (input)
  • pc, sp, emudata: Program Counter, Stack pointer, Content at stack pointer (output)
  • state bits: What state is the CPU in?

To see in detail how these modules are linked with the core, see wb_core.vhdl.

Simulating the stuff

Before going into the hardware, we normally simulate things. This is reflected in the test bench hwdbg_small1_tb.vhd. Using the very useful trace module of the zealot ZPU variant, we can verify our architecture from the ZPU interface. Because we have used the TAP and JTAG side in other IP cores, we could safely omit them from the simulation.

Going to the hardware: Software test benches

Once we want to test everything on a real board (and run it over night), we need a JTAG adapter and some piece of software to run JTAG commands. We are using our own JTAG library based on the ICEbearPlus adapter, but any toolchain would do. So to test our primitives like “stop CPU”, “memory read/write”, etc. we just write a simple C program.

For example, the memory read function for 32 bit values, looks like:


uint32_t mem_read32(CONTROLLER jtag, uint32_t addr)
{
    REGISTER r;
    int q = jtag_queue(jtag, 0);
    scanchain_select(jtag, TAP_EMUIR);
    push_opcode(jtag, OPCODE_PUSHSP, EXEC);
    push_val32(jtag, addr);
    push_opcode(jtag, OPCODE_LOAD, EXEC);
    push_opcode(jtag, OPCODE_NOP, EXEC);
    scanchain_select(jtag, TAP_EMUDATA);
    scanchain_shiftout32(jtag, &r, UPDATE);
    scanchain_select(jtag, TAP_EMUIR);
    push_opcode(jtag, OPCODE_LOADSP | (LOADSP_INV ^ 0x01), EXEC);  // Execute Stack fixup
    push_opcode(jtag, OPCODE_POPSP, EXEC);
    push_opcode(jtag, OPCODE_NOP, EXEC);
    jtag_queue(jtag, q);
    return r;
}

Basically, our JTAG sequences are hidden in functions like scanchain_select(), or scanchain_shiftout32(). With all shifting functions, we hint what state we want to enter after shifting. Whenever we enter EXEC, the TAP pulses the emuexec pin for a clock cycle, so the command in the emuir register is executed by the CPU.

Implementing the debugger

Once we have a little library with all basic functionality together, we can start wrapping it with a gdbproxy backend. Wait, what’s gdbproxy? This is a tiny little server, listening on a TCP port and waiting for gdb remote commands. The only thing we have to do: translate a set of skeleton functions into the appropriate calls of our library (called zpuemu). Like we’ve done this for the Blackfin a long time ago, we added another zpu target.

Another approach would be to use openOCD, since it supports a large number of JTAG adapters. The porting exercise we leave to others for now.

A real debugging session

So, let’s debug some program. We are using an old Spartan3 starter kit, equipped with a bunch of useful LEDs, but the main reason is: There is an existing ZPU setup with some I/O, found here: Softcore_implementation_on_a_Spartan-3_FPGA. Thanks to the authors for providing this.

In the image below you can see the Board with a bunch of PCBs stuck in. The ICEbear JTAG is connected to the expansion port, the big Coolrunner board behind is actually our ‘hacked’ Xilinx JTAG adapter, used to program the FPGA.

Spartan 3 board ZPU setup

What we had to do, is the swap the default ZPU implementation against the TAP-enhanced Zealot variant we used. Piece of cake.

gdbproxy sessionNow let’s start hacking. We fire up our gdbproxy server as shown above, it is sitting there and waiting on port 2000.

Then we compile a little program for the ZPU that lights up a few LEDs. Provided that a full ZPU GCC toolchain is installed, the debugging session is dead simple, if you know gdb. Let’s see:

strubi@gmuhl:~/src/vhdl/core/zealot$ zpu-elf-gdb main
GNU gdb 6.2.1
...
(gdb) target remote :2000
Remote debugging using :2000
0x000005b5 in delay (i=5) at main.c:16
16            for (j = 0; j < 1000; j++) {
(gdb) fin
Run till exit from #0  0x000005b5 in delay (i=5) at main.c:16
[New Thread 1]
[Switching to Thread 1]
0x0000063a in main () at main.c:39
39            delay(10);
(gdb) b delay
Breakpoint 1 at 0x57d: file main.c, line 13.
(gdb) c
Continuing.

Breakpoint 1, delay (i=1) at main.c:13
13    {
(gdb)

This works like you might be used to doing it in the simulator. But on real hardware!

Things to try for the future

Actually, you might wonder, why the heck do we need two JTAG adapters? Can’t it be simpler?

In fact, it can. We have used our FPGA vendor independent JTAG I/O, but you could use the Xilinx JTAG primitives for Boundary Scan.

However, as far as I can see, there are only two user defined JTAG instructions. So our current TAP would not work, you would have to tunnel our TAP sequences through the USER1 and USER2 IRs or invent another protocol, for example, by packing our TAP scanchains into the USERx registers. This is again left to implementers, we’d love to hear whether this works though.

Also, nobody forces you do use JTAG. You could just write a very simple interface to a uC and use the UART as debug interface port to the TAP.

So where do we go from here? Have a look at the recent experimental git branch via this link.

 

DPF hacking part two

April 13th, 2011

It turned out by some further hacking that we could run a bit more than just patched code bits on these little frames. This is the next step of development, where things are actually getting fun: Running our own firmware on the AX206 chip using the SDCC’s built in bank switching technique.

128x128 DPF firmware

128x128 DPF firmware

As seen in the image, we have a little slow scope running, using the built in ADC. It turns out, that this chip is quite good at power saving, once you activate all possible options to turn off various clocks. It can obviously run for weeks with just the real time clock running, waking up the chip every second, then for example doing something every 30 seconds, then putting it back to sleep.

Also, a few extra modes for lcd4linux were explored, like setting backlight intensity and orientation. On the 320×240 frames that are for example available here http://www.pearl.de/a-HPM1184-5618.shtml, we use the display in portrait mode as seen below.

240x320 USB display hack

240x320 USB display hack

This is not very pleasant to the average user, therefore this solution will need to mature a little before it is actually safe to release.

The full blown framework to build code for the DPFs using SDCC is published here:

https://sourceforge.net/projects/dpf-ax/

SVN access to the sources:

svn co https://dpf-ax.svn.sourceforge.net/svnroot/dpf-ax/trunk dpf-ax

UPDATE: The bootloading protocol is now decoded. Code can be loaded on bricked frames, find a flash update tool in the above repository. A brief intro how it works:

When the DPF goes into Bootloader mode (showing USB ID 1908:3318), it expects max. 64 byte size USB interrupt messages with a header and payload data. The header implements a simple Remote Procedure Call format through the bootload handler. Its format is as follows:

typedef struct {
	unsigned char len;
	unsigned char chk;
	unsigned char jmp[2];
	union {
		// Structures for various backends
		// The default memory loader:
		struct {
			unsigned char offset[2];
			unsigned char buf[BUFSIZE];
		} loader;
		struct {
			unsigned char opcode;
			unsigned char n;
			unsigned char buf[16];
		} spi;
	} u;
} UsbMsg;

Description

The ‘len’ byte specifies the full length of the USB packet. ‘chk’ is a checksum that is consecutively updated with every packet sent. The ‘jmp’ field contains the jump address of the handler that takes care of the attached data payload. For simple memory writing, the address of the internal ROM memory write routine is used. Once a program (for example flashing routines) is loaded into memory, it can be jumped into using this RPC scheme.

 

DPF hacking

January 13th, 2011

As some people avoid to get bored over christmas holidays, they tend to analyze presents like those cheap hongkong digital picture frames (DPF) that you normally give to your children so that they can lose it the next day.

Of course, other people always have kind of a similar idea, so it is not surprising that there are web pages describing internals of those undocumented devices.

However, the device I got is using another chip (AX206) than the already exploited st2205 based DPFs.
Since the AX206 has a 8051 instruction set, I had a sneak peak with my d52 disassembler. And it turned out, it was possible to have my own code run on the frame, without actually knowing anything about the environment. To access the internal flash, there are various tools listed at the site linked below. The DPF emulates a mass storage device over USB, vendor specific commands are used to do the standard SPI flash operations. The AX206 seems a powerful chip, and we were actually thinking on using it on a project, however there were too many unanswered open questions and the mass price (30k units) was not competitive considering the puzzling support. If a company buries a simple 8052 controller behind NDAs, the suspicion may arise that the chip has too many bugs.

Hacking a more or less unused vendor specific SCSI command in the DPF, I was able to make lcd4linux work with it:

lcd4linux on DPF

lcd4linux on DPF

Find more information on this Wiki:

http://picframe.spritesserver.nl/wiki/index.php/DPF_with_AppoTech_AX206

JPEG robot camera

June 11th, 2010

The PCB arrived 3 weeks ago, and finally, the time was found what should have been tried out long time ago.

Here’s the result. The tiny mobile type camera is able to deliver JPEGs from the sensor, that is, we can run our motion JPEG server on the popular SRV1 robot from http://www.surveyor.com.

The videos can just be watched in a browser or with mplayer. Still tweaking frame rates and PLL…

The board supports another VGA global shutter sensor with cheap webcam optics, as you can see from the unpopulated footprint. If things work as expected in theory, both sensors can be populated and selected via GPIOs, so they can be switched at runtime. The bigger problem is, to make the uClinux framework (which is about to be ported to the SRV1) acknowledge the dual head device. The current driver model does not really support that, so all sensor property control is happening in user space via the netpp (network property protocol) framework.

SRV1 JPEG camera

SRV1 JPEG camera

LeanXcam hacking

March 17th, 2010

The leanXcam has been out for a while now, finally I got my hands on a OEM module.

The first impressions:

  • Interesting 4 plane layout. The bypass caps are somewhat far away from the processor on the top side. Not sure if they are really useful that way..
  • Cheap optics, but they do the job
  • Plugging in Ethernet and Power, I was able to telnet into the beast at the default 192.168.1.10 within seconds and try the webserver. Nice!

Now, how to run our standalone netpp framework:

The JTAG (which we definitely need for bare metal, i.e. non uClinux development) wasn’t populated. The helpful folks at Supercomputing systems told me the specs of the somewhat unusual SMD header:

Farnell, Order #1421678

Keep in mind that pin 3 must be spare for the key.

So, after being set with JTAG, I plugged in one of the new ICEbearPlus units and run the flashloader:

flashload --info --driver=spi_flash.dxe

This is what we get:

Detected Device: BF-537(536) rev:3
Manufacturer        : Atmel
Device Type         : Dataflash 45DB321D
-------------------------------------------------------------------
 Driver title: SPI flash programmer (STM, Atmel)
 Description: AT45DB321D
 Manufacturer Code: 0x1f
 Device Code: 0x27
 Number of sectors: 0x41
 Number of regions: 0x3
 Bus width: 0x8
 Buffer size: 0x2000
 Flash size: 0x400000
-------------------------------------------------------------------

Cool, that worked from the spot. There is another flash on SPI select 5, i.e. found by flashloader via the –unit=4 option. Before starting to hack, it might be a good idea to save the flash images:

flashload --info --driver=spi_flash.dxe --unit=0 --dump leanx_0.img --size=0x400000

Downloading code

So now. We got this standalone shell code to try out stuff, lets see how the code from the pretty similar STAMP BF537 board can be ported. After a few modifications later, I seem to be able to talk to the shell via the bfpeek console (the bfpeek channel is a way to do stream I/O over JTAG without the need to attach a serial cable):

strubi@gmuhl:~/src/blackfin/shell/boards/LEANXCAM$ nc localhost 4000

/////////////////////////////////////////////////////////
// test shell // (c) 2004-2009, <hackfin-ät-section5.ch>  //
/////////////////////////////////////////////////////////

Board: LeanXcam BF537
>

Let’s see if we see something on the i2c bus:

> i
Detecting devices: 5c
done.

Right, that should be the i2c address of the MT9V032 sensor.

Let’s try grabbing a frame with the ‘v’ command – oops, timeout! Could it be that the sensor is in standby mode? I guess we’ll have to check the schematics now. And here we should emphasize: The leanXcam does not make a secret about its internals: The schematics are openly available (Why keep something a secret that isn’t really one?)

Nah, everything ok, the sensor should run. Giving it a few tries and running into the usual obscure core faults we remember: Random core faults mostly got to do with bad SDRAM! After revisiting the settings and fixing them, we see:

> v 3
Initializing video with 640x480
Video start
Process frame [0], 0 jiffies
Data error in frame 0
Process frame [1], 21 jiffies
Data error in frame 1
Process frame [0], 21 jiffies
Data error in frame 0
Video stop (9 frames received)
 (6 overrun)

Bingo. We lost 6 frames due to the output via the bfpeek channel that burns many CPU cycles, but that was to expect. We ignore the data error, because we didn’t yet enable the test pattern.

Well, this is kinda amazing. It does not happen so often that you plug in hardware of that sort and it works that smooth right away.

Thus, I can recommend the leanXcam to anyone who wants to get into serious image processing, be it uClinux or standalone.

Green laser surgery

January 3rd, 2010

I’ve obtained a Green laser module from DealExtreme (sku.26887) that was kinda broken on arrival, so it had to disintegrate for the sake of curiousity.
One plus of this module: It has a constant current driver. See the read back schematic here: laser driver schematic. The wires of the driver PCB were really weakly soldered, they came off after a turning the module around a few times. The quality of these modules are questionable, but what does one expect, at a price of roughly 8 USD.

Driver PCB

Driver PCB

Since the optics were rather misplaced, I had a look at the frequency doubler crystal. It seemed slightly broken as well, so I knocked it off. Note that one should never run the diode at full power without protection glass, even invisible light can harm the eyes. Nevertheless, you can see a very weak red glow when you run it at low power. Also, you can use a standard webcam with a lens without IR filter to estimate the light intensity coming out of the diode.

The potentiometer is used to set the maximum diode current. Don’t overdrive, the diode can die instantly. It has no built-in photodiode for feedback stabilization, but  the regulator circuit seems quite robust to voltage swings. Do not exceed 5V through,  the transistor will heat up. Since I don’t have the specs of the diode, I don’t know how long it will last under continuous load.

Laser diode

Laser diode

There’s more experimenting to come, like modification of the driver circuitry in order to modulate the laser with a low frequency. Still awaiting the next batch of lasers..

For further reference, I recommend the well known LaserFAQ at:

http://www.repairfaq.org/sam/laserfaq.htm