Sunday, 8 March 2009

sequel 3 to slave concepts

4. handling one wire protocol with master

First of all I post my document link again where you can find the complete analyse and code:

http://sites.google.com/site/guyvo67/

(LOWBP.PDF)

I was lucky to have my analyse on paper first to implement the state diagram. It was very helpful. To fully test the protocol I had to program the master as well. But I come back on that later on. I used the ICP ( input capturing ) on the AVR to measure my timings. Below you can see how the timer needs to be setup:

/*! ********************************************
SetTimerOneWire
Preparing TIMER 0 16 bit for one wire capture
no prescale --> counting unit = 1\F_CPU

minimum unit: 12.8 MHz 78ns

maximum units: 12.8 MHz 5,1ms

@note
16 bit writing first high than low value
16 bit reading first low than high value

************************************************/
void SetTimerOneWire (void)
{
/// TIMER 0 enable ICR mode in 16 bit
TCCR0A = _BV(TCW0) | _BV(ICEN0);

/// TIMER 0 prescale value no prescale
TCCR0B = _BV(CS00);

/// TIMER 0 interrupt mask ICR
TIMSK |= _BV(TICIE0);

/// TIMER 0 starting point
TCNT0H = 0x00;
TCNT0L = 0x00;
}

So the timer is set up to handle measurements between 78ns and 5,1ms. As I put my one wire timings between 10µs-1ms this is more than precise enough to do the job. The last code snippet I want to show you is that of the interrupt itself. It works very closely together with the state machine implementation but again please refer to the document to view to full master/salve implementation. In the interrupt routine we handle the input capture measurements depending on the edges. We evaluate the measured values with our defined timing constants known by slave as well as master. Depending on the value I assign a global value to an enumeration that will be later used by the state machine to make appropriate decisions. Also here very straightforward code:

ISR(TIMER0_CAPT_vect)
{
if ( bit_is_clear(PINA, PA4) )
{
TRIGPOSEDGE;
RESTARTTIM0;
onewirepulse = INTIMING;
}
else
{
TRIGNEGEDGE;
ICRVALUE(icp);
if ( icp < onewidth )
{
onewirepulse = ONEPULSE;
}
else if (icp < zerowidth )
{
onewirepulse = ZEROPULSE;
}
else if (icp < resetwidth )
{
onewirepulse = RESETPULSE;
}
else
{
onewirepulse = ERRORPULSE;
}
capinterrupt = SIGNALED;
}
}

To be honest this was the most difficult thing to program with respect to the slave concept. But I managed to write it and test it and it worked ! I will dive a little deeper on those tests when I write something about the master. The one wire is actually optional for this design but it gives a nice added value.

My next blog will cover the overall results of this dimmer design.

No comments: