From 808d6e3b335f23ee4a961cd6918aeb876c42f022 Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 20 Feb 2007 12:52:27 +0000 Subject: [PATCH] Still having problems with serial driver git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@10 42af7a65-404d-4744-a932-0658087f49c3 --- arch/c5471/defconfig | 2 +- arch/c5471/include/serial.h | 3 +- arch/c5471/src/up_head.S | 7 +- arch/c5471/src/up_serial.c | 191 +++++++++++------------------------- 4 files changed, 65 insertions(+), 138 deletions(-) diff --git a/arch/c5471/defconfig b/arch/c5471/defconfig index 4b397e4056..488ea2e793 100644 --- a/arch/c5471/defconfig +++ b/arch/c5471/defconfig @@ -192,5 +192,5 @@ CONFIG_STACK_POINTER= CONFIG_PROC_STACK_SIZE=4096 CONFIG_PTHREAD_STACK_MIN=256 CONFIG_PTHREAD_STACK_DEFAULT=4096 -CONFIG_HEAP_BASE=(0x10300000+90*1024+4096) +CONFIG_HEAP_BASE=(0x10300000+90*1024+CONFIG_PROC_STACK_SIZE) CONFIG_HEAP_SIZE=(0x11000000-CONFIG_HEAP_BASE) diff --git a/arch/c5471/include/serial.h b/arch/c5471/include/serial.h index 7c0e5a4f0e..2202a6450f 100644 --- a/arch/c5471/include/serial.h +++ b/arch/c5471/include/serial.h @@ -48,8 +48,7 @@ #define TIOCSBRK 0x5401 /* BSD compatibility */ #define TIOCCBRK 0x5402 /* " " " " */ -#define TIOCSERCONFIG 0x5403 /* Reconfigure the port */ -#define TIOCSERGSTRUCT 0x5458 /* Get up_dev_t for port */ +#define TIOCSERGSTRUCT 0x5403 /* Get up_dev_t for port */ /************************************************************ * Private Data diff --git a/arch/c5471/src/up_head.S b/arch/c5471/src/up_head.S index 8d7fbec58e..e97a52dbd1 100644 --- a/arch/c5471/src/up_head.S +++ b/arch/c5471/src/up_head.S @@ -118,7 +118,12 @@ __start: b os_start - /* Variables */ + /* Variables: + * _sbss is the start of the BSS region (see ld.script) + * _ebss is the end of the BSS regsion (see ld.script) + * The idle task stack starts at the end of BSS and is + * of size CONFIG_PROC_STACK_SIZE + */ LC0: .long _sbss .long _ebss diff --git a/arch/c5471/src/up_serial.c b/arch/c5471/src/up_serial.c index 63fd5bbedd..25746da3f6 100644 --- a/arch/c5471/src/up_serial.c +++ b/arch/c5471/src/up_serial.c @@ -88,7 +88,6 @@ struct up_dev_s * registers */ unsigned int baud_base; /* Base baud for conversions */ unsigned int baud; /* Configured baud */ - int quotient; /* Quotient for configured baud */ ubyte xmit_fifo_size; /* Size of transmit FIFO */ ubyte irq; /* IRQ associated with * this UART */ @@ -102,6 +101,7 @@ struct up_dev_s * for space in xmit.buffer */ boolean recvwaiting; /* TRUE: User is waiting * for space in recv.buffer */ + boolean isconsole; /* TRUE: This is the serila console */ sem_t closesem; /* Looks out new opens while * close is in progress */ sem_t xmitsem; /* Used to wakeup user waiting @@ -214,9 +214,7 @@ static inline uint32 up_inserial(up_dev_t *dev, uint32 offset) return getreg32(dev->uartbase + offset); } -static inline void up_serialout(up_dev_t *dev, - uint32 offset, - uint32 value) +static inline void up_serialout(up_dev_t *dev, uint32 offset, uint32 value) { putreg32(value, dev->uartbase + offset); } @@ -255,16 +253,16 @@ static inline void up_enablerxint(up_dev_t *dev) up_serialout(dev, UART_IER_OFFS, dev->regs.ier); } -static inline void up_disableuartint(up_dev_t *dev, uint16 *msr) +static inline void up_disableuartint(up_dev_t *dev, uint16 *ier) { - *msr = dev->regs.ier & UART_IER_AllInts; + *ier = dev->regs.ier & UART_IER_AllInts; dev->regs.ier &= ~UART_IER_AllInts; up_serialout(dev, UART_IER_OFFS, dev->regs.ier); } -static inline void up_restoreuartint(up_dev_t *dev, uint16 msr) +static inline void up_restoreuartint(up_dev_t *dev, uint16 ier) { - dev->regs.ier |= msr & (UART_IER_RecvInt|UART_IER_XmitInt); + dev->regs.ier |= ier & (UART_IER_RecvInt|UART_IER_XmitInt); up_serialout(dev, UART_IER_OFFS, dev->regs.ier); } @@ -423,7 +421,7 @@ static inline ubyte up_txfifonotfull(up_dev_t *dev) return (up_inserial(dev, UART_SSR_OFFS) & UART_SSR_TXFULL) == 0; } -static inline void up_waitforxmtr(up_dev_t *dev) +static inline void up_waittxfifonotfull(up_dev_t *dev) { int tmp; for (tmp = 1000 ; tmp > 0 ; tmp--) @@ -554,7 +552,7 @@ static inline void up_recvchars(up_dev_t *dev) * up_write adds data to the head of the xmit buffer. */ -static inline void up_xmitchars(up_dev_t *dev) +static void up_xmitchars(up_dev_t *dev) { /* Send while we still have data & room in the fifo */ @@ -667,29 +665,9 @@ static int up_interrupt(int irq, struct xcptcontext *xcp) ************************************************************/ static void up_uartsetup(up_dev_t *dev) -{ - uint32 flags; - uint16 mrs; - - flags = irqsave(); - - up_saveregisters(dev); - up_disableuartint(dev, &mrs); - up_clearfifos(dev); - up_disablebreaks(dev); - up_settxtrigger(dev, UART_FCR_FTL); - up_setrxtrigger(dev, UART_FCR_FTL); - - irqrestore(flags); -} - -/************************************************************ - * up_cval - ************************************************************/ - -static unsigned int up_cval(up_dev_t *dev) { unsigned int cval; + uint16 mrs; if (dev->bits == 7) { @@ -714,67 +692,13 @@ static unsigned int up_cval(up_dev_t *dev) cval |= (UART_LCR_ParEn|UART_LCR_ParEven); } - return cval; -} - -/************************************************************ - * Name: up_portstartup - ************************************************************/ - -static int up_portstartup(up_dev_t *dev) -{ - uint32 flags; - unsigned cval = up_cval(dev); - int quotient = 0; - uint16 ier; - int ret = OK; - - flags = irqsave(); - + up_serialreset(dev); up_saveregisters(dev); - up_disableuartint(dev, &ier); + up_disableuartint(dev, &mrs); up_clearfifos(dev); up_disablebreaks(dev); - - /* Attache and enabled the IRQ */ - - ret = irq_attach(dev->irq, up_interrupt); - if (ret != OK) - { - goto errout; - } - - /* Mark the io buffers empty */ - - dev->xmit.head = 0; - dev->xmit.tail = 0; - dev->recv.head = 0; - dev->recv.tail = 0; - - /* And set the speed of the serial port */ - - /* Determine divisor based on baud rate */ - - if (dev->baud == 134) - { - /* Special case since 134 is really 134.5 */ - - quotient = (2*dev->baud_base / 269); - } - else if (dev->baud) - { - quotient = (dev->baud_base / dev->baud) - 1; - } - - /* If the quotient is zero, default to 9600 bps */ - - if (!quotient && dev->baud_base != dev->baud) - { - quotient = (dev->baud_base / 9600) - 1; - } - - /* Set up parity check flag */ - + up_settxtrigger(dev, UART_FCR_FTL); + up_setrxtrigger(dev, UART_FCR_FTL); up_setrate(dev, dev->baud); up_setmode(dev, cval); @@ -786,16 +710,6 @@ static int up_portstartup(up_dev_t *dev) { serial_disable_hw_flow_control(dev); } - - /* Finally, enable interrupts */ - - up_enable_irq(dev->irq); - up_enablerxint(dev); - ret = 0; - -errout: - irqrestore(flags); - return ret; } /************************************************************ @@ -881,7 +795,10 @@ static ssize_t up_write(struct file *filep, const char *buffer, size_t buflen) if (dev->xmit.head != dev->xmit.tail) { up_xmitchars(dev); - up_enabletxint(dev); + if (dev->xmit.head != dev->xmit.tail) + { + up_enabletxint(dev); + } } return ret; @@ -945,14 +862,6 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) switch (cmd) { - case TIOCSERCONFIG: - { - shutdown(dev); - up_uartsetup(dev); - ret = up_portstartup(dev); - } - break; - case TIOCSERGSTRUCT: { up_dev_t *user = (up_dev_t*)arg; @@ -1038,6 +947,7 @@ static int up_close(struct file *filep) shutdown(dev); up_givesem(&dev->closesem); + return OK; } /************************************************************ @@ -1064,8 +974,39 @@ static int up_open(struct file *filep) if (++dev->open_count == 1) { - up_uartsetup(dev); - ret = up_portstartup(dev); + int flags = irqsave(); + + /* If this is the console, then the UART has already + * been initialized. + */ + + if (!dev->isconsole) + { + up_uartsetup(dev); + } + + /* But, in any event, we do have to configure for + * interrupt driven mode of operation. + */ + + /* Attache and enabled the IRQ */ + + ret = irq_attach(dev->irq, up_interrupt); + if (ret == OK) + { + /* Mark the io buffers empty */ + + dev->xmit.head = 0; + dev->xmit.tail = 0; + dev->recv.head = 0; + dev->recv.tail = 0; + + /* Finally, enable interrupts */ + + up_enable_irq(dev->irq); + up_enablerxint(dev); + } + irqrestore(flags); } up_givesem(&dev->closesem); @@ -1094,26 +1035,6 @@ static void up_devinit(up_dev_t *dev, sem_init(&dev->recvsem, 0, 0); } -/************************************************************ - * Name: up_consoleinit - ************************************************************/ - -static void up_consoleinit(up_dev_t *dev) -{ - unsigned cval = up_cval(dev); - uint16 ier; - - up_serialreset(dev); - up_saveregisters(dev); - up_disableuartint(dev, &ier); - up_clearfifos(dev); - up_setrate(dev, dev->baud); - up_setmode(dev, cval); - up_delay(5); - - dev->open_count = 1; -} - /************************************************************ * Public Funtions ************************************************************/ @@ -1141,7 +1062,8 @@ void up_earlyserialinit(void) /* Configure the console for use now */ - up_consoleinit(&CONSOLE_DEV); + CONSOLE_DEV.isconsole = TRUE; + up_uartsetup(&CONSOLE_DEV); } /************************************************************ @@ -1174,7 +1096,7 @@ int up_putc(int ch) uint16 ier; up_disableuartint(&CONSOLE_DEV, &ier); - up_waitforxmtr(&CONSOLE_DEV); + up_waittxfifonotfull(&CONSOLE_DEV); up_outserialchar(&CONSOLE_DEV, ch); /* Check for LF */ @@ -1183,10 +1105,11 @@ int up_putc(int ch) { /* Add CR */ - up_waitforxmtr(&CONSOLE_DEV); + up_waittxfifonotfull(&CONSOLE_DEV); up_outserialchar(&CONSOLE_DEV, 13); } - up_waitforxmtr(&CONSOLE_DEV); + up_waittxfifonotfull(&CONSOLE_DEV); up_restoreuartint(&CONSOLE_DEV, ier); + return ch; }