Pololu Orangutan X2 User Manual
Page 5

{
__asm__ volatile (
"1: push r22" "\n\t"
" ldi r22, 4" "\n\t"
"2: dec r22" "\n\t"
" brne 2b" "\n\t"
" pop r22" "\n\t"
" sbiw %0, 1" "\n\t"
" brne 1b"
: "=w" ( microseconds )
: "0" ( microseconds )
);
}
unsigned char SPIReceive( unsigned char data ) // data is often a junk byte (e.g. 0)
{
if ( SPITransmitting )
while ( ! ( SPSR & ( 1 << SPIF ))) // wait for completion of
; // previous transmission
delay_us( 3 ); // give the mega168 time to prepare
// return data
SPDR = data; // start bidirectional transfer
while ( ! ( SPSR & ( 1 << SPIF ))) // wait for completion of
; // transaction
// reading SPCR and SPDR will clear SPIF, so we will use our global flag
// to indicate that this does not mean we are currently transmitting
SPITransmitting = 0;
return SPDR;
}
We can now put wrapper functions around these low-level SPI commands to communicate with the mega168. For
instance, here is a command for setting motor 1:
void setMotor1( int speed )
{
// first, we'll prepare our command byte
unsigned char command;
if ( speed > 255 )
speed = 255;
if ( speed < -255 )
speed = -255;
if ( speed >= 0 )
command = 136; // motor 1, forward
else
{
command = 138; // motor 1, reverse
speed = -speed;
}
// the MSB of the speed gets tacked onto the command byte
command |= ( (unsigned char) speed & 0x80 ) >> 7;
// now, send the command
SPITransmit( command );
SPITransmit( (unsigned char) speed & 0x7F );
}
Orangutan X2 Command Documentation v1.01
© 2001–2010 Pololu Corporation
2. ATmega644 SPI Configuration
Page 5 of 27