Still having problems with serial driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@10 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
e3f52bbeb4
commit
808d6e3b33
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,8 +795,11 @@ static ssize_t up_write(struct file *filep, const char *buffer, size_t buflen)
|
||||
if (dev->xmit.head != dev->xmit.tail)
|
||||
{
|
||||
up_xmitchars(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;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -1063,9 +973,40 @@ static int up_open(struct file *filep)
|
||||
/* Start up serial port */
|
||||
|
||||
if (++dev->open_count == 1)
|
||||
{
|
||||
int flags = irqsave();
|
||||
|
||||
/* If this is the console, then the UART has already
|
||||
* been initialized.
|
||||
*/
|
||||
|
||||
if (!dev->isconsole)
|
||||
{
|
||||
up_uartsetup(dev);
|
||||
ret = up_portstartup(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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user