Creating a Laserprojector

Hello blog, just want to post a update on my latest project,

Building a laser projector from scratch.

Im interested in waveforms and the connection between sound and the visual aspect, so thats why I started to investigate how to build a laser-projector.

For this I am using a galvano scanner with a mirror connected to a driverboard that supports the ILDA standard. For laser source i am just using a 40mw laserpointer.
By connecting the audio output from the soundcard on my computer I am able to generate waveforms that controls the galvano scanner. Left channel for x-axis, and right channel for y-axis.
The software is in c++ using the alsalib on Ubuntu Linux. The sourcecode is in early stage, but I will release it in the future.

My goal is to generate fractal patterns and 3d geometry, for now I have just played around and this is the result far.

Stay tuned.

Simple fix if the wandboard fails do detect the hdmi-resolution (edid)

I had a problem that the wandboard did not recognize the resolution of my Sony 1600×1200 TFT display.
This issue seems to be on all screens I’ve tested when I used a HDMI-DVI converter.

By editing the file /etc/X11/xorg.conf you can set the resolution manually.
At the bottom of the file, you got a section thats called “Screen”

Change this to somthing like this, and change “Modes” to the resolution of your screen.

Section "Screen"
        Identifier      "Default Screen"
        Device          "Configured Monitor"
        Monitor         "i.MX Accelerated Framebuffer Device"
        DefaultDepth    24
        DefaultFbBpp    32
        SubSection "Display"
                  Modes "1600x1200"
         EndSubSection
EndSection

Just a tip, Hope it can come in handy 🙂
Take care & thanks for passing by…

How to overclock the Wandboard cpu (Freescale i.mx.6)

Hello every-one!
The blog has been pretty passive, time to change it with a new overclocking tutorial.
This time I have a Wandboard in my hand. Wand board is a really nice opensource ARM cortex A9 SOM development board, with a i.mx 6 SOC and 1 GB RAM. My version is equipped with a duallite module @ 1000Mhz.

Somthing that I really like is overclocking and pushing the barriers, so here is how you do it!
This soc has speed fuses that tells the kernel which clock frequency the cpu shall have. It is possible change this fuses, but this is inverversible, so we do it by modifying the kernel instead.
By looking into /arch/arm/mach-mx6/cpu_op-mx6 in the kernel, we find the frequency-tables. at the bottom we find the function: void mx6_cpu_op_init(void)

By removing the check of the fuse bit and manually set the freqency we are on our way.
Make it look somthing like this:

void mx6_cpu_op_init(void)
{
        arm_max_freq = CPU_AT_1_2GHz;
        printk(KERN_INFO "arm_max_freq=%sn", (arm_max_freq == CPU_AT_1_2GHz) ?
                "1.2GHz" : ((arm_max_freq == CPU_AT_1GHz) ? "1GHz" : "800MHz"));
        get_cpu_op = mx6_get_cpu_op;
        set_num_cpu_op = mx6_set_num_cpu_op;
        get_dvfs_core_op = mx6_get_dvfs_core_table;
}

For now I had some instability issues. It seemed that the powersupply and LDO-voltage was dropping too much so I had to turn the LDO off. By turning this of it made some different in temperature thought, about 2-3 degrees warmer.

In the same folder you have the file mx6_anatop_regulator.c. This file holds the LDO-regulator functions and the one we want to disable is the set_voltage() function.
So by making this function empty, the set_voltage() does not change the voltage.
Make it look somthing like this:

static int set_voltage(struct anatop_regulator *sreg, int uv)
{   
     return 0;
}

Then make the new kernel and dd it to the flashmemory, be careful which disk you are writing too.

sudo make CROSS_COMPILE="arm-linux-gnueabi-" ARCH="arm" -j4 uImage
sudo dd if=arch/arm/boot/uImage of=/dev/DISK bs=1M seek=1
sync

Okay, we are almost there. Now the voltages are too low at default values from u-boot. This will not work. We have to turn the voltage to the maximum by disabling the voltage-regulation. We do this by set the Digital Regulator Core Register (PMU_REG_CORE).
You find this register documented in the reference manual at page 4493-4495.

By setting the REG0_TARG REG1_TARG REG2_TARG to 11111 == Power FET switched full on. No regulation.
We do this by modifying the u-boot/board/wandboard/wandboard.c
Make it look somthing like this.

int board_init(void)
{
    /* address of boot parameters */
    gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
    int reg;
    reg = 0x7C3E1F;     
    writel(reg, ANATOP_BASE_ADDR + HW_ANADIG_REG_CORE);
 
    return 0;
}

I had some problem with the bootlogo locking up my system in the beginning, so I disabled this by editing u-boot/include/configs/wandboard.h
and commented out the code below.

/* Framebuffer and LCD */
/*#define CONFIG_CMD_HDMIDETECT
#define CONFIG_VIDEO
#define CONFIG_VIDEO_IPUV3
#define CONFIG_CFB_CONSOLE
#define CONFIG_VGA_AS_SINGLE_DEVICE
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_BMP_24BPP
#if defined(CONFIG_BMP_24BPP) 
#define CONFIG_BPP_BYTES 4
#elif defined(CONFIG_BMP_8BPP)
#define CONFIG_BPP_BYTES 1
#endif 
#define CONFIG_VIDEO_XRES 720
#define CONFIG_VIDEO_YRES 480
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE         (CONFIG_VIDEO_XRES * CONFIG_VIDEO_YRES * CONFIG_BPP_BYTES + 1024+ 100)
#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SPLASH_SCREEN
#define CONFIG_SPLASH_IS_IN_MMC
#define CONFIG_CMD_BMP
#define CONFIG_VIDEO_LOGO
#define CONFIG_IPUV3_CLK 260000000
#define CONFIG_SYS_DCACHE_OFF
*/

Now compile the bootloader:

sudo make CROSS_COMPILE="arm-linux-gnueabi-" ARCH="arm" wandboard_dl -j4
sudo dd if=u-boot.imx of=/dev/sdc bs=1k seek=1

Pooowoowooww! So now we are there. I was able to boot it stable at 1200Mhz. Whoho! 🙂

Here we have some benchmark results:

Wandboard@1000Mhz


RAM size:     834 MB,  # CPU hardware threads:   2
RAM usage:    425 MB,  # Benchmark threads:      2
 
Dict        Compressing          |        Decompressing
      Speed Usage    R/U Rating  |    Speed Usage    R/U Rating
       KB/s     %   MIPS   MIPS  |     KB/s     %   MIPS   MIPS
 
22:     564   141    389    548  |    12812   200    578   1156
23:     560   143    398    570  |    12698   200    582   1162

Wandboard@1200Mhz

RAM size:     834 MB,  # CPU hardware threads:   2
RAM usage:    425 MB,  # Benchmark threads:      2
 
Dict        Compressing          |        Decompressing
      Speed Usage    R/U Rating  |    Speed Usage    R/U Rating
       KB/s     %   MIPS   MIPS  |     KB/s     %   MIPS   MIPS
 
22:     819   147    543    797  |    19548   200    883   1765
23:     829   150    561    845  |    19365   200    887   1773

You find the kernel-source at http://www.wandboard.org
And the reference manual at Freescales website

Remember that you do this at your own risk. I cant guarantee that it wont damage anything.

Enjoy, feel free to ask questions and comments… and remember to have fun 😀
Peace!

How to overclock the Beaglebone MPU

I was curious if it was possible to overclock the MPU of the beaglebone and, of course it was. 🙂 So here is how I did it. (And be careful, overclocking may damage your beaglebone)

At first i tried to overclock the MPU by manually set the MPU registers. The registers who controls the MPU-freqency is CM_DIV_M2_DPLL_MPU and CM_CLKSEL_DPLL_MPU.

The ADPLLS calculates the MPU clock by following formula:

CLKINP * [1 / (N+1)] * [M] * [1/M2]

CLKINP is the source input-clock, 24.
N is the divider in CM_CLKSEL_DPLL_MPU
M is the multiplier in CM_CLKSEL_DPLL_MPU
M2 is the divider in CM_DIV_M2_DPLL_MPU

Below is the main-function of my program bclock.

int main(int argc, char **argv)
{
	Dpll_mpu* dpll_mpu = malloc(sizeof(Dpll_mpu));
	int fd = open("/dev/mem", O_RDWR); 
	int i;
	if (fd < 0) {
		perror("Could not open file \n");
		return 1;
	}
	
	uint8_t *map; 
	map = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, OFFSET);
	if (map == MAP_FAILED) {
		perror("mmap failed");
		return 1;
	}
	
	get_dpll_mpu(dpll_mpu, map);
	
	if (argc == 1) {
		printf("Usage:  %s [OPTION...]\n  -N, set N-divider\n  -M, set M-multiplier\n \
 -M2, set M2-divider\n", argv[0]);

		get_dpll_mpu(dpll_mpu, map);
		printf("\nCurrent settnings \n-----------------\n");
		print_dpll_mpu(dpll_mpu);
		printf("\nCalculated by formula CLKINP * [1 / (N+1)] * [M]  * [1/M2]\n\n");
	}
	else {
		for (i = 1; i < argc; i+=2)
		{
			if (argc != i+1) {
				if (strcmp(argv[i],"-N") ==  0)
					if (atoi(argv[i+1]) > 0 && atoi(argv[i+1]) <= 0x7f)
						dpll_mpu-> N_divider = atoi(argv[i+1]);
				if (strcmp(argv[i],"-M") == 0)
					if (atoi(argv[i+1]) > 0 && atoi(argv[i+1]) <= 0x3ff)
						dpll_mpu-> M_multiplier = atoi(argv[i+1]);
				if (strcmp(argv[i],"-M2") == 0)
					if (atoi(argv[i+1]) > 0 && atoi(argv[i+1]) <= 0x1f)
						dpll_mpu-> M2_divider = atoi(argv[i+1]);
			}
		}
		
		set_dpll(dpll_mpu,map);
		get_dpll_mpu(dpll_mpu, map);
		print_dpll_mpu(dpll_mpu);
		
	}
	munmap(map, SIZE);	
	close(fd);
	
	free(dpll_mpu);
	return 0;
}

You can overclock the MPU from userspace by writing to the mapped registers. This is what my software bclock does. Try it out and tell me what you think.
Below is the output when running the program.

./bclock
Usage: ./bclock [OPTION...]
-N, set N-divider
-M, set M-multiplier
-M2, set M2-divider

Current settnings
-----------------
CLKINP = 24
N_divider = 2
M_multiplier = 130
M2_divider = 1

MPU frequency = 1040.00 Mhz

Calculated by formula CLKINP * [1 / (N+1)] * [M] * [1/M2]

If you are using cpu-frequency scaling, cpufreq module will overwrite the settnings generated by bclock. You can disable the frequency scaling by set the minimum frequency to maxfrequency, like,
cpufreq-set -d 720Mhz
You can also change the scaling frequencies by modifying the kernelcode in /arch/arm/mach-omap2/opp3xxx_data.c and change the am33xx_opp_def_list structure to the desired frequencies and recompile the kernel. I bought a small heatsink to spead the heat, and so far ive run my MPU at 1040 Mhz successfully.

So does the overclock make any difference? Yes indeed! 🙂
When I’m running 7-Zip benchmark (7zr b) I get the following results:

Orginal @ 720Mhz

Dict        Compressing          |        Decompressing
      Speed Usage    R/U Rating  |    Speed Usage    R/U Rating
       KB/s     %   MIPS   MIPS  |     KB/s     %   MIPS   MIPS

22:     279   100    272    271  |     5442   100    491    491
23:     272   100    277    277  |     5365   100    491    491
24:     263   100    283    283  |     5286   100    490    490
----------------------------------------------------------------
Avr:          100    277    277               100    491    491
Tot:          100    384    384

Overclocked @ 1040Mhz

Dict        Compressing          |        Decompressing
      Speed Usage    R/U Rating  |    Speed Usage    R/U Rating
       KB/s     %   MIPS   MIPS  |     KB/s     %   MIPS   MIPS

22:     356   100    346    346  |     7578   100    684    684
23:     346   100    353    353  |     7451   100    682    682
24:     334   100    360    359  |     7318   100    679    679
----------------------------------------------------------------
Avr:          100    353    353               100    682    681
Tot:          100    517    517 

Be careful, and happy overclocking 🙂
Get the source-code @ gitub.org
Kernel source: AM335x_04_06 04_06_00_08 kernel
TI AM335x Ref Manual

How to make LED-display driver – Beaglebone

I have been playing around with the beaglebone for a while, and the latest project was to make a driver for my 7SEG-LED display using the GPIO ports.
I’m trying to learn more about kernel programming so i made a kernel-module for this task. Its also possible to make a driver like this in userspace, using exported variables in sysfs.

So at first I tried to figure out how to manage the mux configuration from the kernel. Sins the functions in mux.h is’nt exported, i wrote my own routine to set the mux-registers. The function uses the pin_mux structure and set the mux-registers to mux-mode 7 (GPIO).

static int setup_pin_mux(void)
{
	void* adress;
	int i;
	if (request_mem_region(AM33XX_CONTROL_PADCONF_MUX_PBASE, AM33XX_CONTROL_PADCONF_MUX_SIZE,"MuxMem") == NULL)
			printk("Error requesting mem reqion MUX_PBASE\n");

	adress = (void *)ioremap (AM33XX_CONTROL_PADCONF_MUX_PBASE,AM33XX_CONTROL_PADCONF_MUX_SIZE);

	if (adress == NULL)
	{
		printk("Error ioremap: MUX_PBASE\n");
		return -1;
	}

	for (i = 0; pin_mux[i].reg_offset != OMAP_MUX_TERMINATOR; i++)
			iowrite16(pin_mux[i].value, adress+pin_mux[i].reg_offset);

	iounmap(adress);
	release_mem_region(AM33XX_CONTROL_PADCONF_MUX_PBASE,AM33XX_CONTROL_PADCONF_MUX_SIZE);

	return 0;
}

Im using the GPIO ports at the P8 Expansion header. The LEDs are configurated as follow:

  • 3 LED1_1 – GPIO1_6
  • 4 LED1_2 – GPIO1_7
  • 5 LED1_3 – GPIO1_2
  • 6 LED1_4 – GPIO1_3
  • 7 LED1_5 – GPIO2_2
  • 8 LED1_6 – GPIO2_3
  • 9 LED1_7 – GPIO2_5
  • 10 LED1_8 – GPIO2_4
  • 11 LED2_1 – GPIO1_13
  • 12 LED2_2 – GPIO1_12
  • 13 LED2_3 – GPIO0_23
  • 14 LED2_4 – GPIO0_26
  • 15 LED2_5 – GPIO1_15
  • 16 LED2_6 – GPIO1_14
  • 17 LED2_7 – GPIO0_27
  • 18 LED2_8 – GPIO2_1
  • 19 LED1_SWITCH – GPIO0_22 (anode)
  • 20 LED2_SWITCH – GPIO1_31 (anode)

At the LED-display anode, ive put resistors at 480 Ohm, to get safe currents cause maximum output current is 8mA and input 6mA, according to  Gerald Coley. To calculate the resistor of the circuit you can use the formula: voltage – LED-voltage / LED-current.

The function display_number() sets the ledmask according to each number. So for example to display number 2, we set LED 1,2,4,5,7 to zero and LED1_SWITCH to 1.

You can display numbers by using the char-device. Either by writing ioctl command:  ioctl(fd,DISPLAY_SET, &output) or by writing directly to the char-device like “echo 20 > /dev/LED_display”

Right now im using the display to show the CPU-usage and it works great 🙂

To install the driver you run the load-script LED_display_load, and remove with LED_display_unload.

Get the source-code @ gitub.org

Feel free to ask questions and make comments!

Heatsink arrived to MK802

I bought a MK802 for a couple of weeks ago. It’s a really cool ARM-device that runs Linux. I’ve been running a Lubuntu-distro for a while and it works pretty decent. Of course I miss the hardware acceleration in X, and really holding my thumbs for the Limaproject.
Anyway. The allwinner A10 chip gets really hot! Compared to the TI-AM3359 overclocked to 920Mhz, it is still MUCH warmer. So to spread the heat i got a small heatsinks from Conrad.

The heatsink did the job, so now i’m not worried about heating issues anymore. Over and out!

Beaglebone rev A4 network-connection issue

I had some problem with my Beaglebone rev A4 board. The network connection didn’t work at boot, but when i rebooted the system after booting into Linux, it worked…? pretty strange… So i made a google search and found http://circuitco.com who had more information about the issue. It seemed like a hardware issue, and the only way to solve the problem, was to remove resistor R219.
“We are looking into a SW workaround, but right now the easiest solution is to pop off R219 on the back side of the board under the RJ45 connector”

Check out http://youtu.be/Ak30G-shiYY to find out where the resistor is located and how to remove it.

After I made this modification my Beaglebone worked like a dream. So now im happy again 🙂

The recipe for a silent, powerful and small computer

Last year, I got really tired of loud hard-drives and noisy fans. I decided to build a passively cooled computer (without fans :). I wanted it to be high-performance, small, energy efficient and completely silent.

This became the recipe:
Case: Morex T3500 (80W PS)

HDD: Intel 160GB G2 SSD

MEM: Corsair XMS3 8GB DDR3 PC10666 1333MHz

MOBO: MSI H61I-E35

CPU: Intel Core i3-2100

CPU Cooler: Thermal Right HR-2 Macho

PCH Cooler: Thermal Right HR-05 SLI/IFX

I got big heatsinks and a case with a external passive 80W powersupply. My thought was in the beginning to under-clock the Core-i3 to match the 2100T == 35W TDP, but sins it worked out pretty nice at the orginal frequency(3.1Ghz) I didn’t had too. A little bit of Ghetto-mod about this project, but I really wanted the heatsinks to be outside of the case for maximum cooling and performance. So had to modify it a littlebit 🙂

So whats the temperature?

It becomes pretty hot at full-load, but still good temperatures thought.
36C idle,
65C in usual full load. But with some prime-benchmarking-software ive got CPU temp over 70C. In normal condition, at normal usage, like running some virtual-machines, browsing the web, coding and such, the CPU never gets over 50 degrees.

This computer have been a Linux Server/Desktop computer for almost a year now, and I never had any stability or heating issues. But the project became a little bit more expensive thought.. cause when my computer became silent I noticed that my monitor had a nasty beeping sound, hehe.. so I had to replace it 🙂

I got a article about my project at sweclockers.com and fanlesstech.com