/* ****************sci11a.c******** Interrupting I/O routines to serial port for the MC68HC11EVB This example accompanies the book "Embedded Microcomputer Systems: Real Time Interfacing", Brooks-Cole, copyright (c) 2000, Jonathan W. Valvano 7/6/99 Interface between the TExaS simulator running a MC68HC11 EVB with ICC11 freeware compiler TExaS Copyright 1999 by Jonathan W. Valvano for more information about ICC11 see http://www.imagecraft.com You may use this file without restrictions Modified from software by University of Texas students Charlie Gough and Matt Hawk */ #include "SCI11.h" #include "HC11.h" #include "RxFifo.h" #include "TxFifo.h" /*-----------------------InitSCI---------------------------- Initalize SCI This RITUAL is executed once Inputs: none Outputs: none */ void InitSCI(void){ RxInitFifo(); TxInitFifo(); SCCR1=0; /* bit value meaning 4 0 M, 1 start, 8 data, 1 stop 3 0 WAKE, wake by idle (not used) */ SCCR2=0x2c; /* enable SCI */ /* bit value meaning 7 0 TIE, no transmit interrupts on TDRE 6 0 TCIE, no transmit interrupts on TC 5 1 RIE, enable receive interrupts on RDRF 4 0 ILIE, no interrupts on idle 3 1 TE, enable transmitter 2 1 RE, enable receiver 1 0 RWU, no receiver wakeup 0 0 SBK, no send break */ BAUD=0; /* baud rate=125000 bps */ asm(" cli"); /* enable interrupts */ } /*-----------------------InChar---------------------------- Input one character from SCI terminal Inputs: none Outputs: ASCII character */ char InChar(void){ char letter; while (RxGetFifo(&letter) == 0){}; return(letter); } /*-----------------------OutChar---------------------------- Output one character to SCI terminal Inputs: ASCII character Outputs: none */ void OutChar(char data){ TxPutFifo(data); SCCR2=0xAC; /* arm TDRE */ } /*---------------------RDRFHandler--------------------------- called on RDRF set */ void RDRFHandler(void){ RxPutFifo(SCDR); } /*---------------------TDREHandler--------------------------- called on TDRE set */ void TDREHandler(void){ char letter; if(TxGetFifo(&letter)) SCDR=letter; else SCCR2=0x2c; /* disarm TDRE */ } /*---------------------SciHandler--------------------------- called on TDRE and RDRF ***warning**** highest level interrupt program should be so simple it doesn't push things on the stack this inconvenience is only for the freeware compiler */ void SciHandler(void){ if(SCSR&RDRF) RDRFHandler(); if(SCSR&TDRE) TDREHandler(); asm(" rti"); } /*-------------------------InStatus-------------------------- Checks if new input is ready, TRUE if new input is ready */ unsigned char InStatus(void) { return(SCSR & RDRF);} /*-----------------------OutStatus---------------------------- Checks if output data buffer is empty, TRUE if empty */ unsigned char OutStatus(void) { return(SCSR & TDRE);} /*--------------------UpCase------------------------------- converts lowercase to uppercase char by subtracting $20 from lowercase ASCII to make uppercase ASCII */ char UpCase(char character) { return (character>='a' && character<='z')?character-0x20:character;} /*----------------------InUDec------------------------------- InUDec accepts ASCII input in unsigned decimal format and converts to a 16 bit unsigned number with a maximum value of 65535 If you enter a number above 65535, it will truncate without reporting the error Backspace will remove last digit typed */ unsigned int InUDec(void){ unsigned number=0, length=0; unsigned char character; while ((character=InChar())!=CR) /* accepts until carriage return input */ /* The next line checks that the input is a digit, 0-9. If the character is not 0-9, it is ignored and not echoed */ if(character>='0' && character<='9' ) { number=10*number+character-'0'; /* this line overflows if above 65535 */ length++; OutChar(character);} /* If the input is a backspace, then the return number is changed and a backspace is outputted to the screen */ else if (character==BS && length){ number/=10; length--; OutChar(character);} return number; } /*----------------------------InSDec----------------------------- InSDec accepts ASCII input in signed decimal format and converts to a signed 16 bit number with an absolute value up to 32767 If you enter a number above 32767 o below -32767, it will truncate without reporting the error Backspace will remove last digit typed */ int InSDec(void) { int number=0, sign=1; /* sign flag 1=positive 0=negative */ unsigned length=0; unsigned char character; while ((character=InChar())!=CR) /* Check for carriage return */ { if (!length) /* + or - only valid as first char */ { if (character=='-') { sign=-1; length++; OutChar('-'); /*if - inputted, sign is negative */ } else if (character=='+') { length++; OutChar('+'); /*if + inputted, sign is positive */ } } /* The next line checks that the input is a digit, 0-9 If the character is not 0-9, it is ignored and not echoed */ if (character>='0' && character<='9' ) { number=number*10+character-'0'; /* this line overflows if above 32767 */ length++; OutChar(character); } /* If the input is a backspace, then the return number is changed and a backspace is outputted to the screen. If the backspace erases a minus, then sign is reset to positive */ else if (character==BS && length) { number/=10; length--; if (!length) sign=1; OutChar(BS); } } return sign*number; } /*-----------------------OutUDec-------------------------------------- Output a 16 bit number in unsigned decimal format Variable format 1 to 5 digits with no space before or after This function uses recursion to convert a decimal number of unspecified length as an ASCII string */ void OutUDec(unsigned int number) { if (number>=10) { OutUDec(number/10); OutUDec(number%10); } else OutChar(number+'0'); } /*----------------------OutSDec--------------------------------------- Output a 16 bit number in signed decimal format Variable format (optional sign)1 to 5 digits with no space before or after This function checks if the input parameter is negative, If the number is negative, then 1) it outputs a "-", 2) negates the number and 3) outputs it with OutUDec. Otherwise, it just calls OutUDec (i.e., no "+" sign) */ void OutSDec(int number) { if (number<0){ number=-number; OutChar('-');} OutUDec(number); } /*---------------------InUHex---------------------------------------- InUHex accepts ASCII input in unsigned hexadecimal (base 16) format No '$' or '0x' need be entered, just the 1 to 4 hex digits It will convert lower case a-f to uppercase A-F and converts to a 16 bit unsigned number with a maximum value of FFFF If you enter a number above FFFF, it will truncate without reporting the error Backspace will remove last digit typed */ unsigned int InUHex(void) { unsigned number=0, digit, length=0; unsigned char character; while ((character=UpCase(InChar()))!=CR){ digit=0x10; /* assume bad */ if (character>='0' && character<='9') digit=character-'0'; else if (character>='A' && character<='F') digit=character-'A'+0xA; /* If the character is not 0-9 or A-F, it is ignored and not echoed */ if (digit<=0xF ) { number=number*0x10+digit; length++; OutChar(character);} /* Backspace outputted and return value changed if a backspace is inputted */ else if (character==BS && length){ number/=0x10; length--; OutChar(character);} } return number; } /*--------------------------OutUHex---------------------------- Output a 16 bit number in unsigned hexadecimal format Variable format 1 to 4 digits with no space before or after This function uses recursion to convert the number of unspecified length as an ASCII string */ void OutUHex(unsigned number) { if (number>=0x10) { OutUHex(number/0x10); OutUHex(number%0x10); } else if (number<0xA) OutChar(number+'0'); else OutChar(number-0xA+'A'); } /*------------------------Instring------------------------ This function accepts ASCII characters from the serial port and adds them to a string until a carriage return is inputted or until max length of the string is reached. It echoes each character as it is inputted. If a backspace is inputted, the string is modified and the backspace is echoed InString terminates the string with a null character */ void InString(char *string, unsigned int max) { unsigned length=0; unsigned char character; while ((character=InChar())!=CR) { if (character==BS && length) { string--; length--; OutChar(BS); } else if (length