From: Erik M. <er...@us...> - 2002-01-03 16:07:21
|
Update of /cvsroot/blob/blob/src/lib In directory usw-pr-cvs1:/tmp/cvs-serv2589/src/lib Modified Files: command.c error.c init.c serial-sa11x0.c serial.c terminal.c util.c Log Message: The serial port driver rewrite, part two. This looks quite intrusive, but it's not that large: - rewrite src/lib/serial.c to use the low level serial driver - change semantics for SerialInputByte() and SerialOutputByte(), so rename them to serial_read() and serial_write(). this makes the patch huge - add new INIT_LEVEL for driver selection (has to be done before hardware initialisation) - add machine specific files for all architectures in diag - clean up odds and ends. Index: command.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/command.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- command.c 2001/12/19 19:03:45 1.8 +++ command.c 2002/01/03 16:07:18 1.9 @@ -130,7 +130,7 @@ SerialOutputDec(i); SerialOutputString("] = "); SerialOutputString(argv[i]); - SerialOutputByte('\n'); + serial_write('\n'); } #endif } @@ -153,7 +153,7 @@ printerrprefix(); SerialOutputString(__FUNCTION__ "(): Address = 0x"); SerialOutputHex((u32)cmd); - SerialOutputByte('\n'); + serial_write('\n'); #endif return -EMAGIC; } @@ -203,7 +203,7 @@ printerrprefix(); SerialOutputString(__FUNCTION__ "(): Address = 0x"); SerialOutputHex((u32)cmd); - SerialOutputByte('\n'); + serial_write('\n'); #endif return -EMAGIC; @@ -280,7 +280,7 @@ int __attribute__((weak)) GetCommand(char *command, int len, int timeout) { u32 startTime, currentTime; - char c; + int c; int i; int numRead; int maxRead = len - 1; @@ -291,7 +291,7 @@ for(numRead = 0, i = 0; numRead < maxRead;) { /* try to get a byte from the serial port */ - while(!SerialInputByte(&c)) { + while(serial_poll() != 0) { currentTime = TimerGetTime(); /* check timeout value */ @@ -303,11 +303,21 @@ } } + c = serial_read(); + + /* check for errors */ + if(c < 0) { + command[i++] = '\0'; + serial_write('\n'); + printerror(c, "can't read command"); + return c; + } + if((c == '\r') || (c == '\n')) { command[i++] = '\0'; /* print newline */ - SerialOutputByte('\n'); + serial_write('\n'); return(numRead); } else if(c == '\b') { /* FIXME: is this backspace? */ if(i > 0) { @@ -321,7 +331,7 @@ numRead++; /* print character */ - SerialOutputByte(c); + serial_write(c); } } Index: error.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/error.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- error.c 2002/01/02 01:21:41 1.5 +++ error.c 2002/01/03 16:07:18 1.6 @@ -87,5 +87,5 @@ SerialOutputString(s); } - SerialOutputByte('\n'); + serial_write('\n'); } Index: init.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/init.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- init.c 2001/10/07 19:34:17 1.2 +++ init.c 2002/01/03 16:07:18 1.3 @@ -53,7 +53,7 @@ printerrprefix(); SerialOutputString("Address = 0x"); SerialOutputHex((u32)item); - SerialOutputByte('\n'); + serial_write('\n'); #endif return; } Index: serial-sa11x0.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/serial-sa11x0.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- serial-sa11x0.c 2002/01/02 01:18:57 1.1 +++ serial-sa11x0.c 2002/01/03 16:07:18 1.2 @@ -73,7 +73,7 @@ /* flush serial input queue. returns 0 on success or negative error * number otherwise */ -static int sa11x0_serial_flush_in(void) +static int sa11x0_serial_flush_input(void) { volatile u32 tmp; @@ -94,7 +94,7 @@ /* flush output queue. returns 0 on success or negative error number * otherwise */ -static int sa11x0_serial_flush_out(void) +static int sa11x0_serial_flush_output(void) { /* wait until the transmitter is no longer busy */ while(SerialUTSR1 & UTSR1_TBY) { @@ -153,7 +153,7 @@ Ser1SDCR0 = SDCR0_UART; #endif - sa11x0_serial_flush_out(); + sa11x0_serial_flush_output(); /* switch receiver and transmitter off */ SerialUTCR3 = 0x00; @@ -240,6 +240,6 @@ read: sa11x0_serial_read, write: sa11x0_serial_write, poll: sa11x0_serial_poll, - flush_in: sa11x0_serial_flush_in, - flush_out: sa11x0_serial_flush_out + flush_input: sa11x0_serial_flush_input, + flush_output: sa11x0_serial_flush_output }; Index: serial.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/serial.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- serial.c 2002/01/02 01:18:57 1.5 +++ serial.c 2002/01/03 16:07:18 1.6 @@ -37,86 +37,76 @@ #include <blob/arch.h> +#include <blob/errno.h> #include <blob/led.h> #include <blob/sa1100.h> #include <blob/serial.h> #include <blob/time.h> + + serial_driver_t *serial_driver; -/* - * Initialise the serial port with the given baudrate. The settings - * are always 8 data bits, no parity, 1 stop bit, no start bits. - * + + +/* initialise serial port at the request baudrate. returns 0 on + * success, or a negative error number on failure */ -void SerialInit(eBauds baudrate) +int serial_init(serial_baud_t baudrate) { - /* Theory of operations: - * - Flush the output buffer - * - switch receiver and transmitter off - * - clear all sticky bits in control register 3 - * - set the port to sensible defaults (no break, no interrupts, - * no parity, 8 databits, 1 stopbit, transmitter and receiver - * enabled - * - set the baudrate to the requested value - * - turn the receiver and transmitter back on - */ - -#if defined USE_SERIAL1 - /* select UART use for serial port 1 */ - Ser1SDCR0 = SDCR0_UART; - - while(Ser1UTSR1 & UTSR1_TBY) { +#ifdef BLOB_DEBUG + if(serial_driver == NULL) { + /* we can't print anything over here, so just return + * an error and hope the developer will figure out. + */ + return -ERANGE; } +#endif - Ser1UTCR3 = 0x00; - Ser1UTSR0 = 0xff; - Ser1UTCR0 = ( UTCR0_1StpBit | UTCR0_8BitData ); - Ser1UTCR1 = 0; - Ser1UTCR2 = (u32)baudrate; - Ser1UTCR3 = ( UTCR3_RXE | UTCR3_TXE ); -#elif defined USE_SERIAL3 - while(Ser3UTSR1 & UTSR1_TBY) { - } + return serial_driver->init(baudrate); +} - Ser3UTCR3 = 0x00; - Ser3UTSR0 = 0xff; - Ser3UTCR0 = ( UTCR0_1StpBit | UTCR0_8BitData ); - Ser3UTCR1 = 0; - Ser3UTCR2 = (u32)baudrate; - Ser3UTCR3 = ( UTCR3_RXE | UTCR3_TXE ); -#else -#error "Configuration error: No serial port used at all!" -#endif + + + +/* read one character from the serial port. return character (between + * 0 and 255) on success, or negative error number on failure. this + * function is blocking */ +int serial_read(void) +{ + return serial_driver->read(); } -/* - * Output a single byte to the serial port. +/* write character to serial port. return 0 on success, or negative + * error number on failure. this function is blocking */ -void SerialOutputByte(const char c) +int serial_write(int c) { -#if defined USE_SERIAL1 - /* wait for room in the tx FIFO */ - while((Ser1UTSR0 & UTSR0_TFS) == 0) ; + int rv; - Ser1UTDR = c; -#elif defined USE_SERIAL3 - /* wait for room in the tx FIFO */ - while((Ser3UTSR0 & UTSR0_TFS) == 0) ; + rv = serial_driver->write(c); + + /* if \n, also do \r */ + if(c == '\n') + rv = serial_driver->write('\r'); - Ser3UTDR = c; -#else -#error "Configuration error: No serial port used at all!" -#endif + return rv; +} - /* If \n, also do \r */ - if(c == '\n') - SerialOutputByte('\r'); + + + +/* check if there is a character available to read. returns 1 if there + * is a character available, 0 if not, and negative error number on + * failure */ +int serial_poll(void) +{ + return serial_driver->poll(); } @@ -125,11 +115,10 @@ /* * Write a null terminated string to the serial port. */ -void SerialOutputString(const char *s) { - +void SerialOutputString(const char *s) +{ while(*s != 0) - SerialOutputByte(*s++); - + serial_write(*s++); } /* SerialOutputString */ @@ -153,7 +142,7 @@ else c += '0'; - SerialOutputByte(c); + serial_write(c); } } @@ -181,7 +170,7 @@ leading_zero = 0; if(leading_zero == 0) - SerialOutputByte((char)(result) + '0'); + serial_write((char)(result) + '0'); } } @@ -197,58 +186,13 @@ void SerialOutputBlock(const char *buf, int bufsize) { while(bufsize--) - SerialOutputByte(*buf++); + serial_write(*buf++); } /* - * Read a single byte from the serial port. Returns 1 on success, 0 - * otherwise. When the function is succesfull, the character read is - * written into its argument c. - */ -int SerialInputByte(char *c) -{ -#if defined USE_SERIAL1 - if(Ser1UTSR1 & UTSR1_RNE) { - int err = Ser1UTSR1 & (UTSR1_PRE | UTSR1_FRE | UTSR1_ROR); - *c = (char)Ser1UTDR; -#elif defined USE_SERIAL3 - if(Ser3UTSR1 & UTSR1_RNE) { - int err = Ser3UTSR1 & (UTSR1_PRE | UTSR1_FRE | UTSR1_ROR); - *c = (char)Ser3UTDR; -#else -#error "Configuration error: No serial port at all" -#endif - - /* If you're lucky, you should be able to use this as - * debug information ;-) -- Erik - */ - if(err & UTSR1_PRE) - SerialOutputByte('@'); - else if(err & UTSR1_FRE) - SerialOutputByte('#'); - else if(err & UTSR1_ROR) - SerialOutputByte('$'); - - /* We currently only care about framing and parity errors */ - if((err & (UTSR1_PRE | UTSR1_FRE)) != 0) { - return SerialInputByte(c); - } else { - led_toggle(); - return(1); - } - } else { - /* no bit ready */ - return(0); - } -} /* SerialInputByte */ - - - - -/* * read a string with maximum length len from the serial port * using a timeout of timeout seconds * @@ -259,7 +203,7 @@ int SerialInputString(char *s, const int len, const int timeout) { u32 startTime, currentTime; - char c; + int c; int i; int numRead; int skipNewline = 1; @@ -269,7 +213,7 @@ for(numRead = 0, i = 0; numRead < maxRead;) { /* try to get a byte from the serial port */ - while(!SerialInputByte(&c)) { + while(serial_poll() == 0) { currentTime = TimerGetTime(); /* check timeout value */ @@ -281,6 +225,14 @@ } } + c = serial_read(); + + /* check for errors */ + if(c < 0) { + s[i++] = '\0'; + return c; + } + /* eat newline characters at start of string */ if((skipNewline == 1) && (c != '\r') && (c != '\n')) skipNewline = 0; @@ -290,7 +242,7 @@ s[i++] = '\0'; return(numRead); } else { - s[i++] = c; + s[i++] = (char)c; numRead++; } } @@ -310,7 +262,7 @@ int SerialInputBlock(char *buf, int bufsize, const int timeout) { u32 startTime, currentTime; - char c; + int c; int i; int numRead; int maxRead = bufsize; @@ -319,7 +271,7 @@ for(numRead = 0, i = 0; numRead < maxRead;) { /* try to get a byte from the serial port */ - while(!SerialInputByte(&c)) { + while(serial_poll() == 0) { currentTime = TimerGetTime(); /* check timeout value */ @@ -330,6 +282,12 @@ } } + c = serial_read(); + + /* check for errors */ + if(c < 0) + return c; + buf[i++] = c; numRead ++; } Index: terminal.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/terminal.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- terminal.c 2001/10/07 22:36:11 1.4 +++ terminal.c 2002/01/03 16:07:18 1.5 @@ -45,7 +45,7 @@ SerialOutputString(" c"); for(i = 0; i < 100; i++) - SerialOutputByte('\n'); + serial_write('\n'); SerialOutputString("c"); Index: util.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/util.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- util.c 2001/10/07 22:58:56 1.3 +++ util.c 2002/01/03 16:07:18 1.4 @@ -51,12 +51,12 @@ SerialOutputHex((int)src); SerialOutputString(" to 0x"); SerialOutputHex((int)dest); - SerialOutputByte('\n'); + serial_write('\n'); #endif while(numWords--) { if((numWords & 0xffff) == 0x0) - SerialOutputByte('.'); + serial_write('.'); *dest++ = *src++; } |