ATTiny 461A USI SPI slave config

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey everyone, I'm having a strange issue that's driving me crazy, and I can't seem to solve it. I'm setting up an SPI interface to an ATTiny461A, which has some registers that the master might want to read or write.

The SPI module setup is as follows.

//set DO as an output
DDRB |= (1 << DDR_MISO);
//Enable SPI Module, SPI mode 0, external clock, 4-bit counter on both edges
USICR = (1<<USIOIE) | (1<<USIWM0) | (0<<USIWM1) |	(1<<USICS1) | (0<<USICS0) | (0<<USICLK);
SPI.command = 0xFE; //no command

The code need to support multi-byte read/writes, which is why the no command bit is there. If the first bit is set, it's a write, if not it's a read.

ISR (USI_OVF_vect)
{

//this is the first byte
if(SPI.command == 0xFE)
{
	SPI.command = USIBR;
	//read in the command and determine !r/w
	if(SPI.command & 0x80)
	{
		//write operation
		//set pointer to the first register
		SPI.current_address = registers.magic_value+(SPI.command&0x80);
	}
	else
	{
		//read operation
		SPI.current_address =  registers.magic_value+SPI.command;
	}

}
else
{
	SPI.command = USIBR;
	if((SPI.command) & 0x80)
	{
		//write operation
		//write the value to the register in question
		*(SPI.current_address) = SPI.command;
		//increment address for next byte
		(SPI.current_address)++;
	}
	else
	{
		//read operation
		(SPI.current_address)++;
		USIDR = *SPI.current_address;
	}
}

//clear the interrupt flag
USISR = (1 << USISIF);
}

The problem I'm having is that if I output and monitor what comes in, the value in USIBR is almost always incorrect. If I clock in 0 in the first byte, the USIBR reports it as 0x01 while the USIDR reports it as 0. I've tried just reading the USIDR, but for some reason if I read the USIDR instead of the USIBR, when the master clocks in the next byte I get another interrupts after a couple clock cycles.

Any ideas as to what I'm doing wrong?
Thanks