Hi,
I'm trying to implement SPI with USI in attiny26 but no success...
I adapted the code from Atmel's application note 319 and now it's like this:
#ifdef __AVR_ATtiny26__ #define USI_PORT PORTB #define USI_PIN PINB #define USI_DDR DDRB #define USI_SCK PINB2 //!< USI clock I/O pin. #define USI_MISO PINB1 //!< USI data input pin. #define USI_MOSI PINB0 //!< USI data output pin. #define TC1_PRESCALER_VALUE 256 //!< Must be 1, 8, 64, 256 or 1024. #define TC1_COMPARE_VALUE 5 //!< Must be 0 to 255. Minimum 31 with prescaler CLK/1. /* Prescaler value converted to bit settings. */ #if TC1_PRESCALER_VALUE == 1 #define TC1_PS_SETTING (1<<CS00) #elif TC1_PRESCALER_VALUE == 8 #define TC1_PS_SETTING (1<<CS01) #elif TC1_PRESCALER_VALUE == 64 #define TC1_PS_SETTING (1<<CS01)|(1<<CS00) #elif TC1_PRESCALER_VALUE == 256 #define TC1_PS_SETTING (1<<CS02) #elif TC1_PRESCALER_VALUE == 1024 #define TC1_PS_SETTING (1<<CS02)|(1<<CS00) #else #error Invalid T/C1 prescaler setting. #endif #endif #define bool char #define false 0 #define true !false void SPI_init( char spi_mode); bool SPI_trade( unsigned char byte); ISR(TIMER1_CMPB_vect) { TCCR1B = 0; USICR |= (1<<USITC); DDRA |= 0xff; PORTA = USISR; //check status register _delay_ms(500); TCCR1B = (1<<CTC1) | (1<<PSR1) | TC1_PS_SETTING; } ISR(USI_OVF_vect) { // Master must now disable the compare match interrupt // to prevent more USI counter clocks. if( spiX_status.masterMode == 1 ) { TIMSK &= ~(1<<OCIE1B); } // Update flags and clear USI counter USISR = (1<<USIOIF); spiX_status.transferComplete = 1; // Copy USIDR to buffer to prevent overwrite on next transfer. storedUSIDR = USIDR; DDRB |= _BV(6); PORTB |= _BV(6); } void SPI_init( char spi_mode) { USI_DDR |= (1<<USI_MOSI) | (1<<USI_SCK); // Outputs. USI_DDR &= ~(1<<USI_MISO); // Inputs. USI_PORT |= (1<<USI_MISO); // Pull-ups. // Configure USI to 3-wire master mode with overflow interrupt. USICR = (1<<USIOIE) | (1<<USIWM0) | (1<<USICS1) | (spi_mode<<USICS0) | (1<<USICLK); USISR = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|(0x0<<USICNT0); // Enable 'Clear Timer on Compare match' and init prescaler. TCCR1B = (1<<CTC1) | (1<<PSR1) | TC1_PS_SETTING; // Init Output Compare Register. OCR1C = TC1_COMPARE_VALUE; OCR1B = TC1_COMPARE_VALUE; // Init driver status register. spiX_status.masterMode = 1; spiX_status.transferComplete = 0; spiX_status.writeCollision = 0; storedUSIDR = 0; } bool SPI_trade( unsigned char byte) { // Check if transmission in progress, // i.e. USI counter unequal to zero. if( (USISR & 0x0F) != 0 ) { // Indicate write collision and return. spiX_status.writeCollision = 1; return false; } // Reinit flags. spiX_status.transferComplete = 0; spiX_status.writeCollision = 0; // Put data in USI data register. USIDR = byte; // Master should now enable compare match interrupts. if( spiX_status.masterMode == 1 ) { TIFR |= (1<<OCF1B); // Clear compare match flag. TIMSK |= (1<<OCIE1B); //interrupção do timer } return true; } /**** main: *****/ int main( void) { SPI_init(0); //modo 0 sei(); SPI_trade(0x55); asm("loop: rjmp loop"::); }
I forwarded USISR to PORTA and strangely the flags keep changing from 1-0 0-1 :S
And the MOSI line is always zero...
Would appreciate any help.
Thanks