mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-01 05:51:36 +08:00
Merge commit '049c93446561c6ad3e59183c139f3916230ddee5' into nuttx-merge-5596
This merges NuttX 6.25 with one post-release bugfix.
This commit is contained in:
@@ -3,6 +3,14 @@
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
config DISABLE_POLL
|
||||
bool "Disable driver poll interfaces"
|
||||
default n
|
||||
---help---
|
||||
The sizes of drivers can be reduced if the poll() method is not
|
||||
supported. If you do not use poll() or select(), then you can
|
||||
select DISABLE_POLL to reduce the code footprint by a small amount.
|
||||
|
||||
config DEV_NULL
|
||||
bool "Enable /dev/null"
|
||||
default y
|
||||
|
||||
@@ -495,14 +495,14 @@ static void mio283qt2_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npi
|
||||
{
|
||||
int i, j;
|
||||
|
||||
lib_rawprintf("\n%s:\n", msg);
|
||||
syslog("\n%s:\n", msg);
|
||||
for (i = 0; i < npixels; i += 16)
|
||||
{
|
||||
up_putc(' ');
|
||||
lib_rawprintf(" ");
|
||||
syslog(" ");
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
lib_rawprintf(" %04x", *run++);
|
||||
syslog(" %04x", *run++);
|
||||
}
|
||||
up_putc('\n');
|
||||
}
|
||||
|
||||
@@ -497,14 +497,14 @@ static void ssd1289_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixe
|
||||
{
|
||||
int i, j;
|
||||
|
||||
lib_rawprintf("\n%s:\n", msg);
|
||||
syslog("\n%s:\n", msg);
|
||||
for (i = 0; i < npixels; i += 16)
|
||||
{
|
||||
up_putc(' ');
|
||||
lib_rawprintf(" ");
|
||||
syslog(" ");
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
lib_rawprintf(" %04x", *run++);
|
||||
syslog(" %04x", *run++);
|
||||
}
|
||||
up_putc('\n');
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ static ssize_t loop_write(FAR struct inode *inode, const unsigned char *buffer,
|
||||
size_t start_sector, unsigned int nsectors)
|
||||
{
|
||||
FAR struct loop_struct_s *dev;
|
||||
size_t nbyteswritten;
|
||||
ssize_t nbyteswritten;
|
||||
off_t offset;
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
/* This needs to match the logic in include/debug.h */
|
||||
|
||||
#ifdef CONFIG_CPP_HAVE_VARARGS
|
||||
# define message(format, arg...) lib_rawprintf(format, ##arg)
|
||||
# define message(format, arg...) syslog(format, ##arg)
|
||||
#else
|
||||
# define message lib_rawprintf
|
||||
# define message syslog
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/mmcsd/mmcsd_spi.c
|
||||
*
|
||||
* Copyright (C) 2008-2010, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008-2010, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -409,10 +409,14 @@ static uint32_t mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Wait until the card is not busy */
|
||||
/* Wait until the card is not busy. Some SD cards will not enter the IDLE
|
||||
* state until CMD0 is sent for the first time, switching the card to SPI
|
||||
* mode. Having a pull-up resistor on MISO may avoid this problem, but
|
||||
* this check makes it work also without the pull-up.
|
||||
*/
|
||||
|
||||
ret = mmcsd_waitready(slot);
|
||||
if (ret != OK)
|
||||
if (ret != OK && cmd != &g_cmd0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -691,14 +691,16 @@ FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev)
|
||||
kfree(priv);
|
||||
priv = NULL;
|
||||
}
|
||||
|
||||
/* Unprotect all sectors */
|
||||
else
|
||||
{
|
||||
/* Unprotect all sectors */
|
||||
|
||||
at25_writeenable(priv);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
|
||||
(void)SPI_SEND(priv->dev, AT25_WRSR);
|
||||
(void)SPI_SEND(priv->dev, AT25_SR_UNPROT);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
|
||||
at25_writeenable(priv);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
|
||||
(void)SPI_SEND(priv->dev, AT25_WRSR);
|
||||
(void)SPI_SEND(priv->dev, AT25_SR_UNPROT);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the implementation-specific state structure as the MTD device */
|
||||
|
||||
@@ -179,10 +179,10 @@
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
#ifdef CONFIG_ENC28J60_REGDEBUG
|
||||
# define enc_wrdump(a,v) lib_lowprintf("ENC28J60: %02x<-%02x\n", a, v);
|
||||
# define enc_rddump(a,v) lib_lowprintf("ENC28J60: %02x->%02x\n", a, v);
|
||||
# define enc_cmddump(c) lib_lowprintf("ENC28J60: CMD: %02x\n", c);
|
||||
# define enc_bmdump(c,b,s) lib_lowprintf("ENC28J60: CMD: %02x buffer: %p length: %d\n", c,b,s);
|
||||
# define enc_wrdump(a,v) lowsyslog("ENC28J60: %02x<-%02x\n", a, v);
|
||||
# define enc_rddump(a,v) lowsyslog("ENC28J60: %02x->%02x\n", a, v);
|
||||
# define enc_cmddump(c) lowsyslog("ENC28J60: CMD: %02x\n", c);
|
||||
# define enc_bmdump(c,b,s) lowsyslog("ENC28J60: CMD: %02x buffer: %p length: %d\n", c,b,s);
|
||||
#else
|
||||
# define enc_wrdump(a,v)
|
||||
# define enc_rddump(a,v)
|
||||
@@ -773,56 +773,56 @@ static int enc_waitbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg,
|
||||
#if 0 /* Sometimes useful */
|
||||
static void enc_rxdump(FAR struct enc_driver_s *priv)
|
||||
{
|
||||
lib_lowprintf("Rx Registers:\n");
|
||||
lib_lowprintf(" EIE: %02x EIR: %02x\n",
|
||||
enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR));
|
||||
lib_lowprintf(" ESTAT: %02x ECON1: %02x ECON2: %02x\n",
|
||||
enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1),
|
||||
enc_rdgreg(priv, ENC_ECON2));
|
||||
lib_lowprintf(" ERXST: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXSTH), enc_rdbreg(priv, ENC_ERXSTL));
|
||||
lib_lowprintf(" ERXND: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXNDH), enc_rdbreg(priv, ENC_ERXNDL));
|
||||
lib_lowprintf(" ERXRDPT: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXRDPTH), enc_rdbreg(priv, ENC_ERXRDPTL));
|
||||
lib_lowprintf(" ERXFCON: %02x EPKTCNT: %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXFCON), enc_rdbreg(priv, ENC_EPKTCNT));
|
||||
lib_lowprintf(" MACON1: %02x MACON3: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3));
|
||||
lib_lowprintf(" MAMXFL: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
|
||||
lib_lowprintf(" MAADR: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
enc_rdbreg(priv, ENC_MAADR1), enc_rdbreg(priv, ENC_MAADR2),
|
||||
enc_rdbreg(priv, ENC_MAADR3), enc_rdbreg(priv, ENC_MAADR4),
|
||||
enc_rdbreg(priv, ENC_MAADR5), enc_rdbreg(priv, ENC_MAADR6));
|
||||
lowsyslog("Rx Registers:\n");
|
||||
lowsyslog(" EIE: %02x EIR: %02x\n",
|
||||
enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR));
|
||||
lowsyslog(" ESTAT: %02x ECON1: %02x ECON2: %02x\n",
|
||||
enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1),
|
||||
enc_rdgreg(priv, ENC_ECON2));
|
||||
lowsyslog(" ERXST: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXSTH), enc_rdbreg(priv, ENC_ERXSTL));
|
||||
lowsyslog(" ERXND: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXNDH), enc_rdbreg(priv, ENC_ERXNDL));
|
||||
lowsyslog(" ERXRDPT: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXRDPTH), enc_rdbreg(priv, ENC_ERXRDPTL));
|
||||
lowsyslog(" ERXFCON: %02x EPKTCNT: %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXFCON), enc_rdbreg(priv, ENC_EPKTCNT));
|
||||
lowsyslog(" MACON1: %02x MACON3: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3));
|
||||
lowsyslog(" MAMXFL: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
|
||||
lowsyslog(" MAADR: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
enc_rdbreg(priv, ENC_MAADR1), enc_rdbreg(priv, ENC_MAADR2),
|
||||
enc_rdbreg(priv, ENC_MAADR3), enc_rdbreg(priv, ENC_MAADR4),
|
||||
enc_rdbreg(priv, ENC_MAADR5), enc_rdbreg(priv, ENC_MAADR6));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 /* Sometimes useful */
|
||||
static void enc_txdump(FAR struct enc_driver_s *priv)
|
||||
{
|
||||
lib_lowprintf("Tx Registers:\n");
|
||||
lib_lowprintf(" EIE: %02x EIR: %02x ESTAT: %02x\n",
|
||||
enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR),);
|
||||
lib_lowprintf(" ESTAT: %02x ECON1: %02x\n",
|
||||
enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1));
|
||||
lib_lowprintf(" ETXST: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ETXSTH), enc_rdbreg(priv, ENC_ETXSTL));
|
||||
lib_lowprintf(" ETXND: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ETXNDH), enc_rdbreg(priv, ENC_ETXNDL));
|
||||
lib_lowprintf(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
|
||||
enc_rdbreg(priv, ENC_MACON4));
|
||||
lib_lowprintf(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
|
||||
enc_rdbreg(priv, ENC_MACON4));
|
||||
lib_lowprintf(" MABBIPG: %02x MAIPG %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MABBIPG), enc_rdbreg(priv, ENC_MAIPGH),
|
||||
enc_rdbreg(priv, ENC_MAIPGL));
|
||||
lib_lowprintf(" MACLCON1: %02x MACLCON2: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACLCON1), enc_rdbreg(priv, ENC_MACLCON2));
|
||||
lib_lowprintf(" MAMXFL: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
|
||||
lowsyslog("Tx Registers:\n");
|
||||
lowsyslog(" EIE: %02x EIR: %02x ESTAT: %02x\n",
|
||||
enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR),);
|
||||
lowsyslog(" ESTAT: %02x ECON1: %02x\n",
|
||||
enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1));
|
||||
lowsyslog(" ETXST: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ETXSTH), enc_rdbreg(priv, ENC_ETXSTL));
|
||||
lowsyslog(" ETXND: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ETXNDH), enc_rdbreg(priv, ENC_ETXNDL));
|
||||
lowsyslog(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
|
||||
enc_rdbreg(priv, ENC_MACON4));
|
||||
lowsyslog(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
|
||||
enc_rdbreg(priv, ENC_MACON4));
|
||||
lowsyslog(" MABBIPG: %02x MAIPG %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MABBIPG), enc_rdbreg(priv, ENC_MAIPGH),
|
||||
enc_rdbreg(priv, ENC_MAIPGL));
|
||||
lowsyslog(" MACLCON1: %02x MACLCON2: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACLCON1), enc_rdbreg(priv, ENC_MACLCON2));
|
||||
lowsyslog(" MAMXFL: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ config DEV_LOWCONSOLE
|
||||
---help---
|
||||
Use the simple, low-level, write-only serial console driver (minimal support)
|
||||
|
||||
config SERIAL_REMOVABLE
|
||||
bool
|
||||
|
||||
config 16550_UART
|
||||
bool "16550 UART Chip support"
|
||||
default n
|
||||
|
||||
+206
-15
@@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* drivers/serial/serial.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -158,7 +158,11 @@ static void uart_pollnotify(FAR uart_dev_t *dev, pollevent_t eventset)
|
||||
struct pollfd *fds = dev->fds[i];
|
||||
if (fds)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
fds->revents |= ((fds->events | (POLLERR|POLLHUP)) & eventset);
|
||||
#else
|
||||
fds->revents |= (fds->events & eventset);
|
||||
#endif
|
||||
if (fds->revents != 0)
|
||||
{
|
||||
fvdbg("Report events: %02x\n", fds->revents);
|
||||
@@ -208,18 +212,40 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch)
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
dev->xmitwaiting = true;
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if the removable device is no longer connected while we
|
||||
* have interrupts off. We do not want the transition to occur
|
||||
* as a race condition before we begin the wait.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
irqrestore(flags);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
/* Wait for some characters to be sent from the buffer with the TX
|
||||
* interrupt enabled. When the TX interrupt is enabled, uart_xmitchars
|
||||
* should execute and remove some of the data from the TX buffer.
|
||||
*/
|
||||
|
||||
dev->xmitwaiting = true;
|
||||
uart_enabletxint(dev);
|
||||
ret = uart_takesem(&dev->xmitsem, true);
|
||||
uart_disabletxint(dev);
|
||||
irqrestore(flags);
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if the removable device was disconnected while we were
|
||||
* waiting.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
/* Check if we were awakened by signal. */
|
||||
|
||||
if (ret < 0)
|
||||
@@ -288,6 +314,17 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t
|
||||
|
||||
if (up_interrupt_context() || getpid() == 0)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* If the removable device is no longer connected, refuse to write to
|
||||
* the device.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* up_putc() will be used to generate the output in a busy-wait loop.
|
||||
* up_putc() is only available for the console device.
|
||||
*/
|
||||
@@ -317,6 +354,20 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* If the removable device is no longer connected, refuse to write to the
|
||||
* device. This check occurs after taking the xmit.sem because the
|
||||
* disconnection event might have occurred while we were waiting for
|
||||
* access to the transmit buffers.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
uart_givesem(&dev->xmit.sem);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Loop while we still have data to copy to the transmit buffer.
|
||||
* we add data to the head of the buffer; uart_xmitchars takes the
|
||||
* data from the end of the buffer.
|
||||
@@ -392,9 +443,13 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t
|
||||
|
||||
uart_givesem(&dev->xmit.sem);
|
||||
|
||||
/* Were we interrupted by a signal? That should be the only condition that
|
||||
* uart_putxmitchar() should return an error.
|
||||
*/
|
||||
/* uart_putxmitchar() might return an error under one of two
|
||||
* conditions: (1) The wait for buffer space might have been
|
||||
* interrupted by a signal (ret should be -EINTR), or (2) if
|
||||
* CONFIG_SERIAL_REMOVABLE is defined, then uart_putxmitchar()
|
||||
* might also return if the serial device was disconnected
|
||||
* (wtih -ENOTCONN).
|
||||
*/
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -413,11 +468,11 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No data was transferred. Return -EINTR. The VFS layer will
|
||||
* set the errno value appropriately).
|
||||
/* No data was transferred. Return the negated error. The VFS layer
|
||||
* will set the errno value appropriately).
|
||||
*/
|
||||
|
||||
nread = -EINTR;
|
||||
nread = -ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,6 +513,22 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
||||
|
||||
while (recvd < buflen)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* If the removable device is no longer connected, refuse to read any
|
||||
* further from the device.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
if (recvd == 0)
|
||||
{
|
||||
recvd = -ENOTCONN;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if there is more data to return in the circular buffer.
|
||||
* NOTE: Rx interrupt handling logic may aynchronously increment
|
||||
* the head index but must not modify the tail index. The tail
|
||||
@@ -548,6 +619,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
||||
{
|
||||
recvd = -EAGAIN;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#else
|
||||
@@ -599,20 +671,41 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
dev->recvwaiting = true;
|
||||
uart_enablerxint(dev);
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if the removable device is no longer connected while
|
||||
* we have interrupts off. We do not want the transition to
|
||||
* occur as a race condition before we begin the wait.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
uart_enablerxint(dev);
|
||||
irqrestore(flags);
|
||||
ret = -ENOTCONN;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* Now wait with the Rx interrupt re-enabled. NuttX will
|
||||
* automatically re-enable global interrupts when this thread
|
||||
* goes to sleep.
|
||||
*/
|
||||
|
||||
dev->recvwaiting = true;
|
||||
uart_enablerxint(dev);
|
||||
ret = uart_takesem(&dev->recvsem, true);
|
||||
irqrestore(flags);
|
||||
|
||||
/* Was a signal received while waiting for data to be received? */
|
||||
/* Was a signal received while waiting for data to be
|
||||
* received? Was a removable device disconnected while
|
||||
* we were waiting?
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
if (ret < 0 || dev->disconnected)
|
||||
#else
|
||||
if (ret < 0)
|
||||
#endif
|
||||
{
|
||||
/* POSIX requires that we return after a signal is received.
|
||||
* If some bytes were read, we need to return the number of bytes
|
||||
@@ -626,7 +719,11 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
||||
* set the errno value appropriately.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
recvd = dev->disconnected ? -ENOTCONN : -EINTR;
|
||||
#else
|
||||
recvd = -EINTR;
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -852,12 +949,12 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
|
||||
|
||||
if (ndx != dev->xmit.tail)
|
||||
{
|
||||
eventset |= POLLOUT;
|
||||
eventset |= (fds->events & POLLOUT);
|
||||
}
|
||||
|
||||
uart_givesem(&dev->xmit.sem);
|
||||
|
||||
/* Check if the receive buffer is empty
|
||||
/* Check if the receive buffer is empty.
|
||||
*
|
||||
* Get exclusive access to the recv buffer indices. NOTE: that we do not
|
||||
* let this wait be interrupted by a signal (we probably should, but that
|
||||
@@ -867,11 +964,20 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
|
||||
(void)uart_takesem(&dev->recv.sem, false);
|
||||
if (dev->recv.head != dev->recv.tail)
|
||||
{
|
||||
eventset |= POLLIN;
|
||||
eventset |= (fds->events & POLLIN);
|
||||
}
|
||||
|
||||
uart_givesem(&dev->recv.sem);
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if a removable device has been disconnected. */
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
eventset |= (POLLERR|POLLHUP);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (eventset)
|
||||
{
|
||||
uart_pollnotify(dev, eventset);
|
||||
@@ -971,6 +1077,7 @@ static int uart_close(FAR struct file *filep)
|
||||
{
|
||||
uart_shutdown(dev); /* Disable the UART */
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
|
||||
uart_givesem(&dev->closesem);
|
||||
@@ -1004,6 +1111,19 @@ static int uart_open(FAR struct file *filep)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* If the removable device is no longer connected, refuse to open the
|
||||
* device. We check this after obtaining the close semaphore because
|
||||
* we might have been waiting when the device was disconnected.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
ret = -ENOTCONN;
|
||||
goto errout_with_sem;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start up serial port */
|
||||
/* Increment the count of references to the device. */
|
||||
|
||||
@@ -1145,10 +1265,12 @@ int uart_register(FAR const char *path, FAR uart_dev_t *dev)
|
||||
|
||||
void uart_datareceived(FAR uart_dev_t *dev)
|
||||
{
|
||||
/* Awaken any awaiting read() operations */
|
||||
/* Is there a thread waiting for read data? */
|
||||
|
||||
if (dev->recvwaiting)
|
||||
{
|
||||
/* Yes... wake it up */
|
||||
|
||||
dev->recvwaiting = false;
|
||||
(void)sem_post(&dev->recvsem);
|
||||
}
|
||||
@@ -1172,8 +1294,12 @@ void uart_datareceived(FAR uart_dev_t *dev)
|
||||
|
||||
void uart_datasent(FAR uart_dev_t *dev)
|
||||
{
|
||||
/* Is there a thread waiting for space in xmit.buffer? */
|
||||
|
||||
if (dev->xmitwaiting)
|
||||
{
|
||||
/* Yes... wake it up */
|
||||
|
||||
dev->xmitwaiting = false;
|
||||
(void)sem_post(&dev->xmitsem);
|
||||
}
|
||||
@@ -1183,4 +1309,69 @@ void uart_datasent(FAR uart_dev_t *dev)
|
||||
uart_pollnotify(dev, POLLOUT);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: uart_connected
|
||||
*
|
||||
* Description:
|
||||
* Serial devices (like USB serial) can be removed. In that case, the "upper
|
||||
* half" serial driver must be informed that there is no longer a valid serial
|
||||
* channel associated with the driver.
|
||||
*
|
||||
* In this case, the driver will terminate all pending transfers wint ENOTCONN and
|
||||
* will refuse all further transactions while the "lower half" is disconnected.
|
||||
* The driver will continue to be registered, but will be in an unusable state.
|
||||
*
|
||||
* Conversely, the "upper half" serial driver needs to know when the serial
|
||||
* device is reconnected so that it can resume normal operations.
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* This function may be called from an interrupt handler.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
void uart_connected(FAR uart_dev_t *dev, bool connected)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Is the device disconnected? */
|
||||
|
||||
flags = irqsave();
|
||||
dev->disconnected = !connected;
|
||||
if (!connected)
|
||||
{
|
||||
/* Yes.. wake up all waiting threads. Each thread should detect the
|
||||
* disconnection and return the ENOTCONN error.
|
||||
*/
|
||||
|
||||
/* Is there a thread waiting for space in xmit.buffer? */
|
||||
|
||||
if (dev->xmitwaiting)
|
||||
{
|
||||
/* Yes... wake it up */
|
||||
|
||||
dev->xmitwaiting = false;
|
||||
(void)sem_post(&dev->xmitsem);
|
||||
}
|
||||
|
||||
/* Is there a thread waiting for read data? */
|
||||
|
||||
if (dev->recvwaiting)
|
||||
{
|
||||
/* Yes... wake it up */
|
||||
|
||||
dev->recvwaiting = false;
|
||||
(void)sem_post(&dev->recvsem);
|
||||
}
|
||||
|
||||
/* Notify all poll/select waiters that and hangup occurred */
|
||||
|
||||
uart_pollnotify(dev, (POLLERR|POLLHUP));
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -726,10 +726,10 @@ int ramlog_sysloginit(void)
|
||||
*
|
||||
* Description:
|
||||
* This is the low-level system logging interface. The debugging/syslogging
|
||||
* interfaces are lib_rawprintf() and lib_lowprinf(). The difference is
|
||||
* the lib_rawprintf() writes to fd=1 (stdout) and lib_lowprintf() uses
|
||||
* interfaces are syslog() and lowsyslog(). The difference is that
|
||||
* the syslog() internface writes to fd=1 (stdout) whereas lowsyslog() uses
|
||||
* a lower level interface that works from interrupt handlers. This
|
||||
* function is a a low-level interface used to implement lib_lowprintf()
|
||||
* function is a a low-level interface used to implement lowsyslog()
|
||||
* when CONFIG_RAMLOG_SYSLOG=y and CONFIG_SYSLOG=y
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@@ -148,12 +148,21 @@ config COMPOSITE_VERSIONNO
|
||||
endif
|
||||
|
||||
menuconfig PL2303
|
||||
bool "Emulates the Prolific PL2303 serial/USB converter"
|
||||
bool "Prolific PL2303 serial/USB converter emulation"
|
||||
default n
|
||||
select SERIAL_REMOVABLE
|
||||
---help---
|
||||
This logic emulates the Prolific PL2303 serial/USB converter
|
||||
|
||||
if PL2303
|
||||
|
||||
config PL2303_CONSOLE
|
||||
bool "PL2303 console device"
|
||||
default n
|
||||
---help---
|
||||
Register the USB device as /dev/console so that is will be used
|
||||
as the console device.
|
||||
|
||||
config PL2303_EPINTIN
|
||||
int "Logical endpoint numbers"
|
||||
default 1
|
||||
@@ -208,18 +217,27 @@ config PL2303_VENDORSTR
|
||||
|
||||
config PL2303_PRODUCTSTR
|
||||
string "Product string"
|
||||
default "USBdev Serial"
|
||||
default "PL2303 Emulation"
|
||||
endif
|
||||
|
||||
menuconfig CDCACM
|
||||
bool "USB Modem (CDC ACM) support"
|
||||
default n
|
||||
select SERIAL_REMOVABLE
|
||||
---help---
|
||||
Enables USB Modem (CDC ACM) support
|
||||
|
||||
if CDCACM
|
||||
|
||||
config CDCACM_CONSOLE
|
||||
bool "CDC/ACM console device"
|
||||
default n
|
||||
---help---
|
||||
Register the USB device as /dev/console so that is will be used
|
||||
as the console device.
|
||||
|
||||
config CDCACM_COMPOSITE
|
||||
bool "CDCACM composite support"
|
||||
bool "CDC/ACM composite support"
|
||||
default n
|
||||
depends on USBDEV_COMPOSITE
|
||||
---help---
|
||||
@@ -256,10 +274,10 @@ config CDCACM_EP0MAXPACKET
|
||||
|
||||
config CDCACM_EPINTIN
|
||||
int "Hardware endpoint that supports interrupt IN operation"
|
||||
default 2
|
||||
default 1
|
||||
---help---
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
interrupt IN operation. Default 2.
|
||||
interrupt IN operation. Default 1.
|
||||
|
||||
config CDCACM_EPINTIN_FSSIZE
|
||||
int "Endpoint in full speed size"
|
||||
@@ -277,10 +295,10 @@ config CDCACM_EPINTIN_HSSIZE
|
||||
|
||||
config CDCACM_EPBULKOUT
|
||||
int "Endpoint bulk out"
|
||||
default 0
|
||||
default 3
|
||||
---help---
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
bulk OUT operation
|
||||
bulk OUT operation. Default: 3
|
||||
|
||||
config CDCACM_EPBULKOUT_FSSIZE
|
||||
int "Endpoint bulk out full speed size"
|
||||
@@ -298,10 +316,10 @@ config CDCACM_EPBULKOUT_HSSIZE
|
||||
|
||||
config CDCACM_EPBULKIN
|
||||
int "Endpoint bulk in"
|
||||
default 0
|
||||
default 2
|
||||
---help---
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
bulk IN operation
|
||||
bulk IN operation. Default: 2
|
||||
|
||||
config CDCACM_EPBULKIN_FSSIZE
|
||||
int "Endpoint bulk in full speed size"
|
||||
@@ -336,7 +354,7 @@ config CDCACM_RXBUFSIZE
|
||||
Size of the serial receive/transmit buffers
|
||||
|
||||
config CDCACM_TXBUFSIZE
|
||||
bool "Transmit buffer size"
|
||||
int "Transmit buffer size"
|
||||
default 256
|
||||
---help---
|
||||
Size of the serial receive/transmit buffers
|
||||
@@ -364,7 +382,7 @@ config CDCACM_VENDORSTR
|
||||
|
||||
config CDCACM_PRODUCTSTR
|
||||
string "Product string"
|
||||
default "USBdev Serial"
|
||||
default "CDC/ACM Serial"
|
||||
endif
|
||||
|
||||
menuconfig USBMSC
|
||||
@@ -479,8 +497,8 @@ config USBMSC_PRODUCTID
|
||||
default 0x00
|
||||
|
||||
config USBMSC_PRODUCTSTR
|
||||
string "Mass stroage product string"
|
||||
default "Mass stroage"
|
||||
string "Mass storage product string"
|
||||
default "Mass Storage"
|
||||
|
||||
config USBMSC_VERSIONNO
|
||||
hex "USB MSC Version Number"
|
||||
|
||||
+127
-10
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/usbdev/cdcacm.c
|
||||
*
|
||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -188,6 +188,12 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
size_t outlen);
|
||||
static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void cdcacm_suspend(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
static void cdcacm_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
#endif
|
||||
|
||||
/* UART Operations **********************************************************/
|
||||
|
||||
@@ -211,8 +217,13 @@ static const struct usbdevclass_driverops_s g_driverops =
|
||||
cdcacm_unbind, /* unbind */
|
||||
cdcacm_setup, /* setup */
|
||||
cdcacm_disconnect, /* disconnect */
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
cdcacm_suspend, /* suspend */
|
||||
cdcacm_resume, /* resume */
|
||||
#else
|
||||
NULL, /* suspend */
|
||||
NULL, /* resume */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Serial port **************************************************************/
|
||||
@@ -570,6 +581,14 @@ static void cdcacm_resetconfig(FAR struct cdcacm_dev_s *priv)
|
||||
|
||||
priv->config = CDCACM_CONFIGIDNONE;
|
||||
|
||||
/* Inform the "upper half" driver that there is no (functional) USB
|
||||
* connection.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, false);
|
||||
#endif
|
||||
|
||||
/* Disable endpoints. This should force completion of all pending
|
||||
* transfers.
|
||||
*/
|
||||
@@ -731,10 +750,20 @@ static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv, uint8_t config)
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
priv->nrdq++;
|
||||
}
|
||||
|
||||
/* We are successfully configured */
|
||||
|
||||
priv->config = config;
|
||||
|
||||
/* Inform the "upper half" driver that we are "open for business" */
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, true);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
@@ -823,6 +852,7 @@ static void cdcacm_rdcomplete(FAR struct usbdev_ep_s *ep,
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-req->result);
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
@@ -932,6 +962,7 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
priv->ctrlreq->callback = cdcacm_ep0incomplete;
|
||||
|
||||
/* Pre-allocate all endpoints... the endpoints will not be functional
|
||||
@@ -1575,12 +1606,20 @@ static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reset the configuration */
|
||||
/* Inform the "upper half serial driver that we have lost the USB serial
|
||||
* connection.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, false);
|
||||
#endif
|
||||
|
||||
/* Reset the configuration */
|
||||
|
||||
cdcacm_resetconfig(priv);
|
||||
|
||||
/* Clear out all data in the circular buffer */
|
||||
/* Clear out all outgoing data in the circular buffer */
|
||||
|
||||
priv->serdev.xmit.head = 0;
|
||||
priv->serdev.xmit.tail = 0;
|
||||
@@ -1595,6 +1634,79 @@ static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_suspend
|
||||
*
|
||||
* Description:
|
||||
* Handle the USB suspend event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void cdcacm_suspend(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
|
||||
usbtrace(TRACE_CLASSSUSPEND, 0);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!driver || !dev)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
|
||||
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
|
||||
|
||||
/* And let the "upper half" driver now that we are suspended */
|
||||
|
||||
uart_connected(&priv->serdev, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_resume
|
||||
*
|
||||
* Description:
|
||||
* Handle the USB resume event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void cdcacm_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
|
||||
usbtrace(TRACE_CLASSRESUME, 0);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!driver || !dev)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
|
||||
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
|
||||
|
||||
/* Are we still configured? */
|
||||
|
||||
if (priv->config != CDCACM_CONFIGIDNONE)
|
||||
{
|
||||
/* Yes.. let the "upper half" know that have resumed */
|
||||
|
||||
uart_connected(&priv->serdev, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Serial Device Methods
|
||||
****************************************************************************/
|
||||
@@ -2045,12 +2157,17 @@ int cdcacm_classobject(int minor, FAR struct usbdevclass_driver_s **classdev)
|
||||
|
||||
/* Initialize the serial driver sub-structure */
|
||||
|
||||
priv->serdev.recv.size = CONFIG_CDCACM_RXBUFSIZE;
|
||||
priv->serdev.recv.buffer = priv->rxbuffer;
|
||||
priv->serdev.xmit.size = CONFIG_CDCACM_TXBUFSIZE;
|
||||
priv->serdev.xmit.buffer = priv->txbuffer;
|
||||
priv->serdev.ops = &g_uartops;
|
||||
priv->serdev.priv = priv;
|
||||
/* The initial state is disconnected */
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
priv->serdev.disconnected = true;
|
||||
#endif
|
||||
priv->serdev.recv.size = CONFIG_CDCACM_RXBUFSIZE;
|
||||
priv->serdev.recv.buffer = priv->rxbuffer;
|
||||
priv->serdev.xmit.size = CONFIG_CDCACM_TXBUFSIZE;
|
||||
priv->serdev.xmit.buffer = priv->txbuffer;
|
||||
priv->serdev.ops = &g_uartops;
|
||||
priv->serdev.priv = priv;
|
||||
|
||||
/* Initialize the USB class driver structure */
|
||||
|
||||
@@ -2148,7 +2265,7 @@ int cdcacm_initialize(int minor, FAR void **handle)
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. This function is used
|
||||
* internally by the USB composite driver to unitialized the CDC/ACM
|
||||
* internally by the USB composite driver to unitialize the CDC/ACM
|
||||
* driver. This same interface is available (with an untyped input
|
||||
* parameter) when the CDC/ACM driver is used standalone.
|
||||
*
|
||||
|
||||
@@ -343,6 +343,12 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
size_t outlen);
|
||||
static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
static void usbclass_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
#endif
|
||||
|
||||
/* Serial port *************************************************************/
|
||||
|
||||
@@ -366,8 +372,13 @@ static const struct usbdevclass_driverops_s g_driverops =
|
||||
usbclass_unbind, /* unbind */
|
||||
usbclass_setup, /* setup */
|
||||
usbclass_disconnect, /* disconnect */
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
usbclass_suspend, /* suspend */
|
||||
usbclass_resume, /* resume */
|
||||
#else
|
||||
NULL, /* suspend */
|
||||
NULL, /* resume */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Serial port *************************************************************/
|
||||
@@ -983,6 +994,14 @@ static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv)
|
||||
|
||||
priv->config = PL2303_CONFIGIDNONE;
|
||||
|
||||
/* Inform the "upper half" driver that there is no (functional) USB
|
||||
* connection.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, false);
|
||||
#endif
|
||||
|
||||
/* Disable endpoints. This should force completion of all pending
|
||||
* transfers.
|
||||
*/
|
||||
@@ -1112,10 +1131,20 @@ static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config)
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
priv->nrdq++;
|
||||
}
|
||||
|
||||
/* We are successfully configured */
|
||||
|
||||
priv->config = config;
|
||||
|
||||
/* Inform the "upper half" driver that we are "open for business" */
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, true);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
@@ -1844,12 +1873,20 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reset the configuration */
|
||||
/* Inform the "upper half serial driver that we have lost the USB serial
|
||||
* connection.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, false);
|
||||
#endif
|
||||
|
||||
/* Reset the configuration */
|
||||
|
||||
usbclass_resetconfig(priv);
|
||||
|
||||
/* Clear out all data in the circular buffer */
|
||||
/* Clear out all outgoing data in the circular buffer */
|
||||
|
||||
priv->serdev.xmit.head = 0;
|
||||
priv->serdev.xmit.tail = 0;
|
||||
@@ -1862,6 +1899,79 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
DEV_CONNECT(dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbclass_suspend
|
||||
*
|
||||
* Description:
|
||||
* Handle the USB suspend event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
|
||||
usbtrace(TRACE_CLASSSUSPEND, 0);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!driver || !dev)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
|
||||
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
|
||||
|
||||
/* And let the "upper half" driver now that we are suspended */
|
||||
|
||||
uart_connected(&priv->serdev, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbclass_resume
|
||||
*
|
||||
* Description:
|
||||
* Handle the USB resume event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void usbclass_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
|
||||
usbtrace(TRACE_CLASSRESUME, 0);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!driver || !dev)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
|
||||
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
|
||||
|
||||
/* Are we still configured? */
|
||||
|
||||
if (priv->config != PL2303_CONFIGIDNONE)
|
||||
{
|
||||
/* Yes.. let the "upper half" know that have resumed */
|
||||
|
||||
uart_connected(&priv->serdev, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Serial Device Methods
|
||||
****************************************************************************/
|
||||
@@ -2185,12 +2295,15 @@ int usbdev_serialinitialize(int minor)
|
||||
|
||||
/* Initialize the serial driver sub-structure */
|
||||
|
||||
priv->serdev.recv.size = CONFIG_PL2303_RXBUFSIZE;
|
||||
priv->serdev.recv.buffer = priv->rxbuffer;
|
||||
priv->serdev.xmit.size = CONFIG_PL2303_TXBUFSIZE;
|
||||
priv->serdev.xmit.buffer = priv->txbuffer;
|
||||
priv->serdev.ops = &g_uartops;
|
||||
priv->serdev.priv = priv;
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
priv->serdev.disconnected = true;
|
||||
#endif
|
||||
priv->serdev.recv.size = CONFIG_PL2303_RXBUFSIZE;
|
||||
priv->serdev.recv.buffer = priv->rxbuffer;
|
||||
priv->serdev.xmit.size = CONFIG_PL2303_TXBUFSIZE;
|
||||
priv->serdev.xmit.buffer = priv->txbuffer;
|
||||
priv->serdev.ops = &g_uartops;
|
||||
priv->serdev.priv = priv;
|
||||
|
||||
/* Initialize the USB class driver structure */
|
||||
|
||||
|
||||
@@ -168,9 +168,9 @@ void usbtrace(uint16_t event, uint16_t value)
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Just print the data using lib_lowprintf */
|
||||
/* Just print the data using lowsyslog */
|
||||
|
||||
usbtrace_trprintf((trprintf_t)lib_lowprintf, event, value);
|
||||
usbtrace_trprintf((trprintf_t)lowsyslog, event, value);
|
||||
#endif
|
||||
}
|
||||
irqrestore(flags);
|
||||
|
||||
@@ -199,9 +199,9 @@
|
||||
#ifdef CONFIG_CPP_HAVE_VARARGS
|
||||
# ifdef CONFIG_DEBUG
|
||||
# ifdef CONFIG_ARCH_LOWPUTC
|
||||
# define dbgprintf(format, arg...) lib_lowprintf(format, ##arg)
|
||||
# define dbgprintf(format, arg...) lowsyslog(format, ##arg)
|
||||
# else
|
||||
# define dbgprintf(format, arg...) lib_rawprintf(format, ##arg)
|
||||
# define dbgprintf(format, arg...) syslog(format, ##arg)
|
||||
# endif
|
||||
# else
|
||||
# define dbgprintf(x...)
|
||||
@@ -209,9 +209,9 @@
|
||||
#else
|
||||
# ifdef CONFIG_DEBUG
|
||||
# ifdef CONFIG_ARCH_LOWPUTC
|
||||
# define dbgprintf lib_lowprintf
|
||||
# define dbgprintf lowsyslog
|
||||
# else
|
||||
# define dbgprintf lib_rawprintf
|
||||
# define dbgprintf syslog
|
||||
# endif
|
||||
# else
|
||||
# define dbgprintf (void)
|
||||
|
||||
Reference in New Issue
Block a user