I successful managed to make a software UART without using the USI module and its interrupts.
The AVR code examples on Atmel and avrfreaks just do not work in either simulation or a real device so I got some help and made this soft UART.
Using Proteus I can send messages and receive them on my terminal window on a PC, I can send a character '1' to the Proteus simulation and it turns on an LED pin fine.
When I program the ATTiny861 I can receive messages at 9600bps perfectly but the interrupt procedure never ever fires, it should fire once on startup and then wait while CPU is idle for bit change on PIN.
int main(int argc, char **argv)
{
USICR = 0; // Disable USI.
MCUCR |= (0<<ISC00);
MCUCR |= (0<<ISC01);
GIFR = (1<<PCIF); // Clear pin change interrupt flag.
DDRA = 0xFE;
PORTA |= (1<<PA0); //int. Pull-up an PA1
PINA = 0x00;
PCMSK0 |= (1<<PCINT0);
GIMSK |= (1<<PCIE0);
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
MCUCR = (1<<SE) | (0<<SM1) | (0<<SM0); // Enable Sleepmode: Idle
while(1){
//send some startup messages ..
sei();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
}
}
ISR(PCINT_vect) // interrupt for change in porta0
{
// pin change interrupt handler
GIMSK &= ~(1<<PCIE0);
if (!( PINA & (1<<PA0) ))
{
static char chr;
get_char(&serial_pins, serial_pin_in, &chr);
RxData = chr;
}
PCMSK0 |= (1<<PCINT0); // tell pin change mask to listen to pin0
GIMSK |= (1<<PCIE0); // enable PCINT interrupt in the general interrupt mask of the porta
GIFR = (1<<PCIF); // Clear pin change interrupt flag.
static char message[] PROGMEM = " INTERRUPTED MESSAGE ";
put_flash_string(&serial_port, serial_pin_out, (PGM_P) message);
}
I have other libraries and code segments loaded and I know the put_flash_string function works fine. If i take out sleep_mode it will dump messages into the terminal, I can delay it and it also works. But for some unknown reason on my hardware ATTiny861 it just will not interrupt.
I have been looking at this code for two weeks now and I really need some help. Atmel as you might guess is just vague and not really helpful. I'm not sure what to check any more and why the Proteus simulation works and not my hardware.
Best Answer
It's not really possible to give you a definitive explanation of why your device "works" in simulation but not in hardware based on the information provided. I will offer some suggestions though.
The bit time at 9600 baud is about 100 microseconds. Depending on your clock speed and your clock fuse settings I wonder if you could be blowing this budget? Have you tried with lower baud rate settings (e.g. 300 baud)? Can you tell us how you are clocking the chip? If you're using an external crystal (and you probably should be for UART operation) then the start up time is at best 16000 clock cycles!
Aside: This is obviously not related to your problem, but a useful macro provided by avrlibc is _BV(x) which can be used instead of (1 << x)