Wednesday, March 30, 2011

TCM8230MD Breakout

The TCM8230MD is a tiny camera from Toshiba theoretically capable of outputting 640x480@30FPS! This post is to document my experience with this devilish cam. 

This is my second breakout board for the camera, this one is designed to be connected as a module to another board and doesn't use a crystal oscillator for the clock, I'm using one of the PWM channels instead. However, the older breakout is still in the repo. Both boards were designed with eagle and fabricated at BatchPCB.
The camera has an I2C interface for configuring its registers. A few basic registers must be set for the camera to start outputting frames. Mainly, 0x02 sets the FPS and 0x03 sets the image size/mode and enables the camera.

Next step, is reading frame data, the camera has three interrupt lines, VD, HD and DCLK, when VD is asserted a new frame is ready, each HD edge indicates a new scanline is available, finally, while HD is high each DCLK edge indicates a valid byte on the parallel port.

I enable VD initially and when VD is triggered only then HD is enabled in the IRQ handler. On each HD interrupt the whole scan line is read in a loop inserting some nop's to sync with DCLK. Finally, the whole frame is sent using DMA to the OLED screen.

Eagle files
hg clone

Read more ...

Tuesday, March 29, 2011

Binary Counters

Binary counters can be used for a variety of things from time keeping to generating/measuring frequencies. Today, we will talk about the concepts behind binary counters using an atmega328 for practice.

Let's start with a simple 4-bit counter based on JK flip-flops. A JK flip-flop has the following truth table:

J K Qt+1 State
0 0 Qt No change
0 1 0 Clear
1 0 1 Set
1 1 Qt` Complement

Where Qt is the current output Qt+1 is the output after the next clock edge.

The idea behind it is quite simple, the output of each flip-flop is feed to one input of an AND gate (the other input is the enable signal) so at the next raising-edge of the clock JKn is complemented only if all the least significant JKs are set/high and this is basically how you count in binary.

The following is a snapshot of the counter, I paused the simulation at the count of 3, at the next rising-edge of the clock the first three flip-flops are complemented output of the counter becomes 100b.
The last AND gate is the carry bit it can be used to extend the counter or even as an interrupt, note that the JK flip-flop inputs are connected  this is practically equivalent to a T flip-flop, so it's also possible to use a T flip-flop for the same counter.

The next counter is slightly more complex. It's a 4-bit counter with parallel load and synchronous clear:

It's basically the same counter with the addition of a couple of subcircuits, we could see how this counter works using boolean algebra to evaluate J and K and comparing the results with the JK truth table:

J  = ICL + CLE
K = C + ICL + CLE

Enable Load Clear
Input Output
0 0 0  J=0, K=0 No change
1 0 0  J=1, K=1 Complement
1 0 1  J=0, K=1 Clear
1 1 0 J=I,  K=I Load

AVR Timer/Counter
The atmega328 has 2 8-bit timers and 1 16-bit timer.  We will use Timer/Counter2 to generate a 1Hz square wave. That is, the event of the line going from low to high and then low again occurs once per second, so we need to switch the line state every 500ms.

First, set the clock source (prescalar) in  TCCR2. Setting the prescalar to 0 disables the timer, 1 means no prescaling, any other value will divide the system clock into smaller frequencies, e.g. assuming a clock frequency of 16Mhz and a 1:1024 prescalar the clock frequency is
f  = 16Mhz / 1024 = 15.6Khz
And the period is
T = 1/15.6Khz = 64us
Next we need to set the Output Compare Register (OCR2). The value contained in this register is continuously compared with the counter value, when the counter matches this value it will trigger an interrupt. If we load OCR2 with 250 the counter will will match this value every 16ms
250 * 64us = 16.0ms

Finally, we need to set the compare match interrupt enable flag in TIMSK. Given the clock frequency, 31 interrupts, roughly speaking, are needed for 500ms to pass. The following example demonstrates using TIMER2:
    if (ticks++ == 31) { 
      ticks = 0;

void main()
      * f = 16Mhz / 1024 = 15.6Khz
      * p = 1/f
      * p = 1/15.6Khz = 64us
      * interrupt every = 250 * 64us = 16.0ms
      * round(500 / 16) = 31 interrupts
    TCCR2B = 0;            /*choose timer clock source, 0 = timer disabled*/
    TCCR2A = ((1<<WGM21)|~(1<<WGM20));/*CTC mode WGM22:0 = 2*/
    TCNT2  = 0;            /*clear timer*/
    OCR2A  = 250;          /*load output compare register with 255*/
    TIFR2  |= (1<<OCF2A);  /*Clear compare match flag*/    
    TIMSK2 |= (1<<OCIE2A); /*enable compare match interrupt*/
    TCCR2B = ((1<<CS22)|(1<<CS21)|(1<<CS20));/*1:1024 prescalar*/
Using a logic analyzer to sample the signal, we should see something like the following snapshot:

atmega328 datasheet 
Computer System Architecture-Morris Mano 
Read more ...