/************************************************************************/ /* */ /* Serial_Interface.c -- Allows interface - computer <-> AVR */ /* */ /************************************************************************/ /* Author: Chris Keeser */ /* Revision History: */ /* created: (ChrisK) 7/1/05 */ /************************************************************************/ #include "Serial_interface.h" int main(void) { // prepares RS232 port InitHardwareRS232(); while(1) { if(fStringWaiting == STRING_WAITING) // if there is a message waiting, do something with it { ExecuteCommand((char *) szCommand); ResetCommand(); } } } /* ------------------------------------------------------------ */ /*** InitHardware ** ** Synopsis: InitiHardware() ** ** Parameters: none ** ** Return Value: none ** ** Errors: none ** ** Description: calibrates the internal osc for reliable ** serial transmission and reception, properly sets up the ** serial hardware for transmission and reception ** enables the recieve interrupt. ** */ /* ------------------------------------------------------------ */ void InitHardwareRS232(void) { // disable interrupts cli(); /*Reads the oscal value stored in eeprom and calibrates the internal oscillator */ OSCCAL = eeprom_read_byte(EEPROM_OSCCAL_ADDRESS); /* set up hardware serial port 1 mode: asynchronous buad rate: 57600 parity: none data bits: 8 stop bits: 1 read the data sheet for more information about these registers */ #ifdef USART_ONE UCSR1A = 0; UCSR1C = 0; UCSR1C = ( 1 << UCSZ11 | 1 << UCSZ10 ); UBRR1H = 0; UBRR1L = 7; // enable serial TX and RX anb RX interrupt UCSR1B = 0; UCSR1B = ( 1 << RXCIE1 | 1 << TXEN1 | 1 << RXEN1 ); #endif #ifdef USART_ZERO UCSR0A = 0; UCSR0C = 0; UCSR0C = ( 1 << UCSZ01 | 1 << UCSZ00 ); UBRR0H = 0; UBRR0L = 7; // enable serial TX and RX anb RX interrupt UCSR0B = 0; UCSR0B = ( 1 << RXCIE0 | 1 << TXEN0 | 1 << RXEN0 ); #endif // enable interrupts sei(); return; } /* ------------------------------------------------------------ */ /*** tx_byte ** ** Synopsis: tx_byte(char) ** ** Parameters: a byte value to be sent via the serial port ** ** Return Value: none ** ** Errors: none ** ** Description: transmits 1 byte serially, returns when ** the transmission is complete ** */ /* ------------------------------------------------------------ */ void tx_byte(char Character) { // load the tx buffer #ifdef USART_ONE UDR1 = Character; #endif #ifdef USART_ZERO UDR0 = Character; #endif #ifdef USART_ONE // wait for the transmission to complete while( ( UCSR1A & ( 1 << TXC1 ) ) == 0 ) { } // clear the tx complete flag UCSR1A |= ( 1 << TXC1 ); #endif #ifdef USART_ZERO // wait for the transmission to complete while( ( UCSR0A & ( 1 << TXC0 ) ) == 0 ) { } // clear the tx complete flag UCSR0A |= ( 1 << TXC0 ); #endif return; } void tx_string(char * szMessage) { uint8_t i = 0; while(szMessage[i] != 0) { tx_byte(szMessage[i]); i++; _delay_loop_2(TX_DELAY); } // send carriage return and line feed tx_byte(10); _delay_loop_2(TX_DELAY); tx_byte(13); } /* ------------------------------------------------------------ */ /*** DeleteChar ** ** Synopsis: DeleteChar ** ** Parameters: none ** ** Return Value: none ** ** Errors: none ** ** Description: Deletes the last character sent from the ** terminal */ /* ------------------------------------------------------------ */ void DeleteChar(void) { // send a backspace tx_byte(8); _delay_loop_2(TX_DELAY); // send a space tx_byte(32); _delay_loop_2(TX_DELAY); // send a backspace tx_byte(8); } /* ------------------------------------------------------------ */ /*** ResetCommand ** ** Synopsis: ResetCommand ** ** Parameters: none ** ** Return Value: none ** ** Errors: none ** ** Description: Clears the string waiting flag, and ** destroys the szCommand. ** */ /* ------------------------------------------------------------ */ void ResetCommand(void) { szCommand[0] = 0; // clear the string buffer fStringWaiting = NO_STRING_WAITING; return; } // converts a max 8 character string of // '1's and '0's into a byte value BYTE sz_to_int(char * sz) { BYTE bReceived; BYTE cbConv; BYTE i; // inform user of operation //tx_string("Please Enter Data: prefix b->Binary, x->Hex, none->decimal"); // initialize BYTE value bReceived = 0; cbConv = strlen(sz); // identify hex, decimal or binary if(sz[0] == 'x' || sz[0] == 'X') { for(i = 0; i < 2; i ++) { if(cbConv > 1) { switch(sz[i+1]) { case 'f': case 'F': bReceived += 15 << (4 * ((cbConv - 2) - i)); break; case 'e': case 'E': bReceived += 14 << (4 * ((cbConv - 2) - i)); break; case 'd': case 'D': bReceived += 13 << (4 * ((cbConv - 2) - i)); break; case 'c': case 'C': bReceived += 12 << (4 * ((cbConv - 2) - i)); break; case 'b': case 'B': bReceived += 11 << (4 * ((cbConv - 2) - i)); break; case 'a': case 'A': bReceived += 10 << (4 * ((cbConv - 2) - i)); break; case '9': bReceived += 9 << (4 * ((cbConv - 2) - i)); break; case '8': bReceived += 8 << (4 * ((cbConv - 2) - i)); break; case '7': bReceived += 7 << (4 * ((cbConv - 2) - i)); break; case '6': bReceived += 6 << (4 * ((cbConv - 2) - i)); break; case '5': bReceived += 5 << (4 * ((cbConv - 2) - i)); break; case '4': bReceived += 4 << (4 * ((cbConv - 2) - i)); break; case '3': bReceived += 3 << (4 * ((cbConv - 2) - i)); break; case '2': bReceived += 2 << (4 * ((cbConv - 2) - i)); break; case '1': bReceived += 1 << (4 * ((cbConv - 2) - i)); break; default: break; } } } } else if(sz[0] == 'b' || sz[0] == 'B') { for(i = 0; i < cbConv ; i ++) { if(sz[i] == '1') { bReceived |= 1 << ((cbConv - 1) - i); } } } else { bReceived = (BYTE) atoi(sz); } return bReceived; } /***************************************************************/ // Interrupt Routines /* ------------------------------------------------------------ */ /*** ** ** Synopsis: usart serial recieve interrupt handler ** ** Parameters: none ** ** Return Value: none ** ** Errors: none ** ** Description: when the hardware USART succesfully recieves ** a byte, it writes it into a recieve buffer and checks for the ** terminator. it will set the string waiting flag if there is a ** new and complete command waiting in szCommand ** */ /* ------------------------------------------------------------ */ #ifdef USART_ONE SIGNAL(SIG_UART1_RECV) { static uint8_t i; char garbage; // is a byte is recieved, we have to read it // if there is already a string waiting, we must throw the // char away to exit the interrupt if(fStringWaiting != STRING_WAITING) // command has been read, ready to recieve a new command { szCommand[i] = UDR1; // write the byte into the string buffer // if the character recieved is a backspace if(szCommand[i] == 8) { DeleteChar(); // i will not be incremented, so the backspace will be overwritten // but we also want to delete the last character before the backspace if( i != 0 ) { i--; } } else if(((szCommand[i] == 10 || szCommand[i] == 13 ) || i == (MAX_GET - 1)) && i != 0) // if the last byte recieved is the terminator { // signal the main loop that a message is waiting szCommand[i] = 0; // append the 0 if it is not allready there. fStringWaiting = STRING_WAITING; i = 0; // reset the index to be ready for the next string // send carriage return and line feed tx_byte(10); _delay_loop_2(TX_DELAY); tx_byte(13); } else { // echo typed character back to the terminal tx_byte(szCommand[i]); i++; } } else { // read UDR garbage = UDR1; // send the Not Ready code; if(garbage == 10 || garbage == 13) { } else { tx_string("Device Busy"); } } return; } #endif #ifdef USART_ZERO SIGNAL(SIG_UART0_RECV) { static uint8_t i; char garbage; // is a byte is recieved, we have to read it // if there is already a string waiting, we must throw the // char away to exit the interrupt if(fStringWaiting != STRING_WAITING) // command has been read, ready to recieve a new command { szCommand[i] = UDR0; // write the byte into the string buffer // if the character recieved is a backspace if(szCommand[i] == 8) { DeleteChar(); // i will not be incremented, so the backspace will be overwritten // but we also want to delete the last character before the backspace if( i != 0 ) { i--; } } else if(((szCommand[i] == 10 || szCommand[i] == 13 ) || i == (MAX_GET - 1)) && i != 0) // if the last byte recieved is the terminator { // signal the main loop that a message is waiting szCommand[i] = 0; // append the 0 if it is not allready there. fStringWaiting = STRING_WAITING; i = 0; // reset the index to be ready for the next string // send carriage return and line feed tx_byte(10); _delay_loop_2(TX_DELAY); tx_byte(13); } else { // echo typed character back to the terminal tx_byte(szCommand[i]); i++; } } else { // read UDR garbage = UDR0; // send the Not Ready code; if(garbage == 10 || garbage == 13) { } else { tx_string("Device Busy"); } } return; } #endif