diff --git a/drivers/rpmsg/rpmsg_port.c b/drivers/rpmsg/rpmsg_port.c index be8c6789b7..2b4e92ca4d 100644 --- a/drivers/rpmsg/rpmsg_port.c +++ b/drivers/rpmsg/rpmsg_port.c @@ -752,20 +752,10 @@ int rpmsg_port_register(FAR struct rpmsg_port_s *port, void rpmsg_port_unregister(FAR struct rpmsg_port_s *port) { - FAR struct rpmsg_port_header_s *hdr; char name[64]; snprintf(name, sizeof(name), "/dev/rpmsg/%s", port->cpuname); rpmsg_unregister(name, &port->rpmsg); rpmsg_device_destory(&port->rpmsg); - while ((hdr = rpmsg_port_queue_get_buffer(&port->txq, false)) != NULL) - { - rpmsg_port_queue_return_buffer(&port->txq, hdr); - } - - while ((hdr = rpmsg_port_queue_get_buffer(&port->rxq, false)) != NULL) - { - rpmsg_port_queue_return_buffer(&port->rxq, hdr); - } } diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c index 0877b24eb0..1961372621 100644 --- a/drivers/rpmsg/rpmsg_port_spi.c +++ b/drivers/rpmsg/rpmsg_port_spi.c @@ -45,8 +45,6 @@ # define rpmsg_port_spi_crc16(hdr) 0 #endif -#define RPMSG_SPI_PORT_UNCONNECTED UINT16_MAX - /**************************************************************************** * Private Types ****************************************************************************/ @@ -83,6 +81,7 @@ struct rpmsg_port_spi_s FAR struct rpmsg_port_header_s *rxhdr; rpmsg_port_rx_cb_t rxcb; + bool connected; /* Used for flow control */ @@ -115,6 +114,25 @@ static const struct rpmsg_port_ops_s g_rpmsg_port_spi_ops = * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: rpmsg_port_spi_drop_packets + ****************************************************************************/ + +static void rpmsg_port_spi_drop_packets(FAR struct rpmsg_port_spi_s *rpspi) +{ + FAR struct rpmsg_port_header_s *hdr; + + while (!!(hdr = rpmsg_port_queue_get_buffer(&rpspi->port.txq, false))) + { + rpmsg_port_queue_return_buffer(&rpspi->port.txq, hdr); + } + + while (!!(hdr = rpmsg_port_queue_get_buffer(&rpspi->port.rxq, false))) + { + rpmsg_port_queue_return_buffer(&rpspi->port.rxq, hdr); + } +} + /**************************************************************************** * Name: rpmsg_port_spi_notify_tx_ready ****************************************************************************/ @@ -124,7 +142,14 @@ static void rpmsg_port_spi_notify_tx_ready(FAR struct rpmsg_port_s *port) FAR struct rpmsg_port_spi_s *rpspi = container_of(port, struct rpmsg_port_spi_s, port); - IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 1); + if (rpspi->connected) + { + IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 1); + } + else + { + rpmsg_port_spi_drop_packets(rpspi); + } } /**************************************************************************** @@ -162,11 +187,11 @@ static void rpmsg_port_spi_register_cb(FAR struct rpmsg_port_s *port, static void rpmsg_port_spi_complete_handler(FAR void *arg) { FAR struct rpmsg_port_spi_s *rpspi = arg; - uint16_t avail = rpspi->rxhdr->avail; SPI_SELECT(rpspi->spi, rpspi->devid, false); - rpmsginfo("received cmd:%u avail:%u\n", rpspi->rxhdr->cmd, avail); + rpmsginfo("received cmd:%u avail:%u\n", + rpspi->rxhdr->cmd, rpspi->rxhdr->avail); if (rpspi->txhdr != NULL) { @@ -190,10 +215,24 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg) * connect req data packet has been received. */ - if (rpspi->txavail == RPMSG_SPI_PORT_UNCONNECTED && - rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_CONNECT) + if (!rpspi->connected) { - return; + if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_CONNECT) + { + return; + } + + rpspi->txavail = rpspi->rxhdr->avail; + rpspi->connected = true; + } + else + { + rpspi->txavail = rpspi->rxhdr->avail; + if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_CONNECT) + { + rpspi->connected = false; + rpmsg_port_spi_drop_packets(rpspi); + } } if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_AVAIL) @@ -204,15 +243,8 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg) DEBUGASSERT(rpspi->rxhdr != NULL); } - /* Do nothing when two sides are not connected. */ - - if (rpspi->txavail == RPMSG_SPI_PORT_UNCONNECTED) - { - return; - } - - rpspi->txavail = avail; - if (rpspi->txavail > 0 && rpmsg_port_queue_nused(&rpspi->port.txq) > 0) + if (rpspi->connected && + rpspi->txavail > 0 && rpmsg_port_queue_nused(&rpspi->port.txq) > 0) { IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 1); } @@ -232,7 +264,7 @@ static int rpmsg_port_spi_sreq_handler(FAR struct ioexpander_dev_s *dev, IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 0); - if (rpspi->txavail == RPMSG_SPI_PORT_UNCONNECTED) + if (!rpspi->connected) { txhdr = rpspi->cmdhdr; txhdr->cmd = RPMSG_PORT_SPI_CMD_CONNECT; @@ -305,14 +337,13 @@ rpmsg_port_spi_process_packet(FAR struct rpmsg_port_spi_s *rpspi, switch (rxhdr->cmd) { case RPMSG_PORT_SPI_CMD_CONNECT: - if (rpspi->txavail != RPMSG_SPI_PORT_UNCONNECTED) + if (!rpspi->connected) { rpmsg_port_unregister(&rpspi->port); - rpspi->txavail = RPMSG_SPI_PORT_UNCONNECTED; + rpmsg_port_spi_connect(rpspi); } else { - rpspi->txavail = rxhdr->avail; rpmsg_port_register(&rpspi->port, (FAR const char *)(rxhdr + 1)); } @@ -507,7 +538,6 @@ rpmsg_port_spi_initialize(FAR const struct rpmsg_port_config_s *cfg, &rpspi->port.rxq, true); DEBUGASSERT(rpspi->cmdhdr != NULL && rpspi->rxhdr != NULL); - rpspi->txavail = RPMSG_SPI_PORT_UNCONNECTED; rpspi->rxthres = rpmsg_port_queue_navail(&rpspi->port.rxq) * CONFIG_RPMSG_PORT_SPI_RX_THRESHOLD / 100; diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c b/drivers/rpmsg/rpmsg_port_spi_slave.c index 148f9f1833..da2679a08e 100644 --- a/drivers/rpmsg/rpmsg_port_spi_slave.c +++ b/drivers/rpmsg/rpmsg_port_spi_slave.c @@ -46,8 +46,6 @@ # define rpmsg_port_spi_crc16(hdr) 0 #endif -#define RPMSG_SPI_PORT_UNCONNECTED UINT16_MAX - /**************************************************************************** * Private Types ****************************************************************************/ @@ -81,6 +79,7 @@ struct rpmsg_port_spi_s FAR struct rpmsg_port_header_s *rxhdr; rpmsg_port_rx_cb_t rxcb; + bool connected; /* Used for flow control */ @@ -135,6 +134,25 @@ static const struct spi_slave_devops_s g_rpmsg_port_spi_slave_ops = * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: rpmsg_port_spi_drop_packets + ****************************************************************************/ + +static void rpmsg_port_spi_drop_packets(FAR struct rpmsg_port_spi_s *rpspi) +{ + FAR struct rpmsg_port_header_s *hdr; + + while (!!(hdr = rpmsg_port_queue_get_buffer(&rpspi->port.txq, false))) + { + rpmsg_port_queue_return_buffer(&rpspi->port.txq, hdr); + } + + while (!!(hdr = rpmsg_port_queue_get_buffer(&rpspi->port.rxq, false))) + { + rpmsg_port_queue_return_buffer(&rpspi->port.rxq, hdr); + } +} + /**************************************************************************** * Name: rpmsg_port_spi_exchange ****************************************************************************/ @@ -148,7 +166,7 @@ void rpmsg_port_spi_exchange(FAR struct rpmsg_port_spi_s *rpspi) return; } - if (rpspi->txavail == RPMSG_SPI_PORT_UNCONNECTED) + if (!rpspi->connected) { txhdr = rpspi->cmdhdr; txhdr->cmd = RPMSG_PORT_SPI_CMD_CONNECT; @@ -190,7 +208,14 @@ static void rpmsg_port_spi_notify_tx_ready(FAR struct rpmsg_port_s *port) FAR struct rpmsg_port_spi_s *rpspi = container_of(port, struct rpmsg_port_spi_s, port); - rpmsg_port_spi_exchange(rpspi); + if (rpspi->connected) + { + rpmsg_port_spi_exchange(rpspi); + } + else + { + rpmsg_port_spi_drop_packets(rpspi); + } } /**************************************************************************** @@ -275,13 +300,12 @@ static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev, { FAR struct rpmsg_port_spi_s *rpspi = container_of(dev, struct rpmsg_port_spi_s, spislv); - uint16_t avail; IOEXP_WRITEPIN(rpspi->ioe, rpspi->sreq, 0); SPIS_CTRLR_QPOLL(rpspi->spictrlr); - avail = rpspi->rxhdr->avail; - rpmsginfo("received cmd:%u avail:%u\n", rpspi->rxhdr->cmd, avail); + rpmsginfo("received cmd:%u avail:%u\n", + rpspi->rxhdr->cmd, rpspi->rxhdr->avail); if (rpspi->txhdr != NULL) { @@ -305,10 +329,24 @@ static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev, * connect req data packet has been received. */ - if (rpspi->txavail == RPMSG_SPI_PORT_UNCONNECTED && - rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_CONNECT) + if (!rpspi->connected) { - return; + if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_CONNECT) + { + return; + } + + rpspi->txavail = rpspi->rxhdr->avail; + rpspi->connected = true; + } + else + { + rpspi->txavail = rpspi->rxhdr->avail; + if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_CONNECT) + { + rpspi->connected = false; + rpmsg_port_spi_drop_packets(rpspi); + } } if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_AVAIL) @@ -319,15 +357,6 @@ static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev, DEBUGASSERT(rpspi->rxhdr != NULL); } - /* Do nothing when two sides are not connected. */ - - if (rpspi->txavail == RPMSG_SPI_PORT_UNCONNECTED) - { - return; - } - - rpspi->txavail = avail; - out: if (atomic_exchange(&rpspi->transferring, 0) > 1 || (rpspi->txavail > 0 && rpmsg_port_queue_nused(&rpspi->port.txq) > 0)) @@ -336,44 +365,6 @@ out: } } -/**************************************************************************** - * Name: rpmsg_port_spi_process_packet - ****************************************************************************/ - -static void -rpmsg_port_spi_process_packet(FAR struct rpmsg_port_spi_s *rpspi, - FAR struct rpmsg_port_header_s *rxhdr) -{ - rpmsginfo("received cmd: %u avail: %u", rxhdr->cmd, rxhdr->avail); - - switch (rxhdr->cmd) - { - case RPMSG_PORT_SPI_CMD_CONNECT: - if (rpspi->txavail != RPMSG_SPI_PORT_UNCONNECTED) - { - rpmsg_port_unregister(&rpspi->port); - rpspi->txavail = RPMSG_SPI_PORT_UNCONNECTED; - } - else - { - rpspi->txavail = rxhdr->avail; - rpmsg_port_register(&rpspi->port, (FAR const char *)(rxhdr + 1)); - } - - rpmsg_port_queue_return_buffer(&rpspi->port.rxq, rxhdr); - break; - - case RPMSG_PORT_SPI_CMD_DATA: - rpspi->rxcb(&rpspi->port, rxhdr); - break; - - default: - rpmsgerr("received a unexpected frame, dropped\n"); - rpmsg_port_queue_return_buffer(&rpspi->port.rxq, rxhdr); - break; - } -} - /**************************************************************************** * Name: rpmsg_port_spi_mreq_handler ****************************************************************************/ @@ -392,18 +383,45 @@ static int rpmsg_port_spi_mreq_handler(FAR struct ioexpander_dev_s *dev, * Name: rpmsg_port_spi_connect ****************************************************************************/ -static void rpmsg_port_spi_connect(FAR struct rpmsg_port_spi_s *rpspi) +static inline void rpmsg_port_spi_connect(FAR struct rpmsg_port_spi_s *rpspi) { - bool val; + rpmsg_port_spi_mreq_handler(NULL, 0, rpspi); +} - IOEXP_READPIN(rpspi->ioe, rpspi->mreq, &val); - if (val) +/**************************************************************************** + * Name: rpmsg_port_spi_process_packet + ****************************************************************************/ + +static void +rpmsg_port_spi_process_packet(FAR struct rpmsg_port_spi_s *rpspi, + FAR struct rpmsg_port_header_s *rxhdr) +{ + rpmsginfo("received cmd: %u avail: %u", rxhdr->cmd, rxhdr->avail); + + switch (rxhdr->cmd) { - rpmsg_port_spi_mreq_handler(NULL, 0, rpspi); - } - else - { - IOEXP_WRITEPIN(rpspi->ioe, rpspi->sreq, 1); + case RPMSG_PORT_SPI_CMD_CONNECT: + if (!rpspi->connected) + { + rpmsg_port_unregister(&rpspi->port); + rpmsg_port_spi_connect(rpspi); + } + else + { + rpmsg_port_register(&rpspi->port, (FAR const char *)(rxhdr + 1)); + } + + rpmsg_port_queue_return_buffer(&rpspi->port.rxq, rxhdr); + break; + + case RPMSG_PORT_SPI_CMD_DATA: + rpspi->rxcb(&rpspi->port, rxhdr); + break; + + default: + rpmsgerr("received a unexpected frame, dropped\n"); + rpmsg_port_queue_return_buffer(&rpspi->port.rxq, rxhdr); + break; } } @@ -578,7 +596,6 @@ rpmsg_port_spi_slave_initialize(FAR const struct rpmsg_port_config_s *cfg, &rpspi->port.rxq, true); DEBUGASSERT(rpspi->cmdhdr != NULL && rpspi->rxhdr != NULL); - rpspi->txavail = RPMSG_SPI_PORT_UNCONNECTED; rpspi->rxthres = rpmsg_port_queue_navail(&rpspi->port.rxq) * CONFIG_RPMSG_PORT_SPI_RX_THRESHOLD / 100;