/***************************************************************************** * * Copyright (C) 2003 Atmel Corporation * * File : USI_UART.c * Compiler : IAR EWAAVR 2.28a * Created : 18.07.2002 by JLL * Modified : 02-10-2003 by LTA * * Support mail : avr@atmel.com * * Supported devices : ATtiny26 - changing to support ATTiny2313 * * Application Note : AVR307 - Half duplex UART using the USI Interface * * Description : Functions for USI_UART_receiver and USI_UART_transmitter. * Uses Pin Change Interrupt to detect incomming signals. * * v1 - works on AT-Tiny2313 in Xmit mode only. Rx doesn't work. * Had to disable the Pin Change interupts to keep from crashing. * works with both 1-Mhz and 8-Mhz system clock. (with changes to config file) * ****************************************************************************/ #include #include #include #include "USI_UART_config.h" #define usi_DI PB5 #define usi_DO PB6 #define usi_SCL PB7 //********** USI UART Defines **********// #define DATA_BITS 8 #define START_BIT 1 #define STOP_BIT 1 #define HALF_FRAME 5 #define USI_COUNTER_MAX_COUNT 16 #define USI_COUNTER_SEED_TRANSMIT (USI_COUNTER_MAX_COUNT - HALF_FRAME) #define INTERRUPT_STARTUP_DELAY (0x11 / TIMER_PRESCALER) #define TIMER0_SEED (256 - ( (SYSTEM_CLOCK / BAUDRATE) / TIMER_PRESCALER )) #if ( (( (SYSTEM_CLOCK / BAUDRATE) / TIMER_PRESCALER ) * 3/2) > (256 - INTERRUPT_STARTUP_DELAY) ) #define INITIAL_TIMER0_SEED ( 256 - (( (SYSTEM_CLOCK / BAUDRATE) / TIMER_PRESCALER ) * 1/2) ) #define USI_COUNTER_SEED_RECEIVE ( USI_COUNTER_MAX_COUNT - (START_BIT + DATA_BITS) ) #else #define INITIAL_TIMER0_SEED ( 256 - (( (SYSTEM_CLOCK / BAUDRATE) / TIMER_PRESCALER ) * 3/2) ) #define USI_COUNTER_SEED_RECEIVE (USI_COUNTER_MAX_COUNT - DATA_BITS) #endif #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 ) #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK ) #error RX buffer size is not a power of 2 #endif #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 ) #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK ) #error TX buffer size is not a power of 2 #endif /* General defines */ #define TRUE 1 #define FALSE 0 //********** Static Variables **********// // __no_init __regvar static unsigned char USI_UART_TxData @ 15; // Tells the compiler to store the byte to be transmitted in register. static unsigned char USI_UART_TxData; static volatile unsigned char UART_RxHead; static volatile unsigned char UART_RxTail; static volatile unsigned char UART_TxHead; static volatile unsigned char UART_TxTail; static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE]; // UART buffers. Size is definable in the header file. static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE]; // =================================================================================================================================== static volatile union USI_UART_status // Status byte holding flags. { unsigned char status; struct { unsigned char ongoing_Transmission_From_Buffer:1; unsigned char ongoing_Transmission_Of_Package:1; unsigned char ongoing_Reception_Of_Package:1; unsigned char reception_Buffer_Overflow:1; unsigned char flag4:1; unsigned char flag5:1; unsigned char flag6:1; unsigned char flag7:1; }; } USI_UART_status = {0}; //********** USI_UART functions **********// // Reverses the order of bits in a byte. // I.e. MSB is swapped with LSB, etc. unsigned char Bit_Reverse( unsigned char x ) { x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa); x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc); x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0); return x; } // Flush the UART buffers. void USI_UART_Flush_Buffers( void ) { UART_RxTail = 0; UART_RxHead = 0; UART_TxTail = 0; UART_TxHead = 0; } // =================================================================================================================================== // Initialise USI for UART transmission. void USI_UART_Initialise_Transmitter( void ) { cli(); // disable interupts TCNT0 = 0x00; GTCCR = 1; // Reset the prescaler // TCCR0B = (0<> 2) | 0x80; // Copy (initial high state,) start-bit and 6 LSB of original data (6 MSB // of bit of bit reversed data). } // Else enter receive mode. else { USI_UART_status.ongoing_Transmission_From_Buffer = FALSE; TCCR0B = (0<