From a41c2cb7410effe97dfdb12e72bfc32ac928a655 Mon Sep 17 00:00:00 2001 From: liaoao Date: Thu, 12 Dec 2024 17:31:58 +0800 Subject: [PATCH] rpmsg_port_spi: add support for peer's shutting down notify Shutdown mean peer's want to disconnect the connection untial peer want connect with local side again. After receive shutdown command, local will clear the state until reconnecting and clear the gpio status to avoid the leak current. Signed-off-by: liaoao --- drivers/rpmsg/rpmsg_port_spi.c | 39 ++++++++++++++++++++++----- drivers/rpmsg/rpmsg_port_spi_slave.c | 40 +++++++++++++++++++++++----- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c index 364633a6fae..d04ba9d613a 100644 --- a/drivers/rpmsg/rpmsg_port_spi.c +++ b/drivers/rpmsg/rpmsg_port_spi.c @@ -63,12 +63,14 @@ enum rpmsg_port_spi_cmd_e RPMSG_PORT_SPI_CMD_CONNECT = 0x01, RPMSG_PORT_SPI_CMD_AVAIL, RPMSG_PORT_SPI_CMD_DATA, + RPMSG_PORT_SPI_CMD_SHUTDOWN, }; enum rpmsg_port_spi_state_e { RPMSG_PORT_SPI_STATE_UNCONNECTED = 0x01, RPMSG_PORT_SPI_STATE_CONNECTING, + RPMSG_PORT_SPI_STATE_RECONNECTING, RPMSG_PORT_SPI_STATE_DISCONNECTING, RPMSG_PORT_SPI_STATE_CONNECTED, }; @@ -99,7 +101,7 @@ struct rpmsg_port_spi_s FAR struct rpmsg_port_header_s *rxhdr; rpmsg_port_rx_cb_t rxcb; - uint8_t state; + volatile uint8_t state; /* Used for flow control */ @@ -316,7 +318,7 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg) rpspi->txavail = rpspi->rxhdr->avail; if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_CONNECT) { - rpspi->state = RPMSG_PORT_SPI_STATE_DISCONNECTING; + rpspi->state = RPMSG_PORT_SPI_STATE_RECONNECTING; /* Drop all the unprocessed rxq buffer and pre-send txq buffer * when a reconnect request to be received. @@ -334,6 +336,12 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg) if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_AVAIL) { + if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_SHUTDOWN) + { + rpspi->state = RPMSG_PORT_SPI_STATE_DISCONNECTING; + rpmsg_port_spi_drop_packets(rpspi, RPMSG_PORT_SPI_DROP_ALL); + } + rpmsg_port_queue_add_buffer(&rpspi->port.rxq, rpspi->rxhdr); rpspi->rxhdr = rpmsg_port_queue_get_available_buffer( &rpspi->port.rxq, false); @@ -406,16 +414,26 @@ rpmsg_port_spi_process_packet(FAR struct rpmsg_port_spi_s *rpspi, switch (rxhdr->cmd) { case RPMSG_PORT_SPI_CMD_CONNECT: - if (rpspi->state == RPMSG_PORT_SPI_STATE_DISCONNECTING) + if (rpspi->state == RPMSG_PORT_SPI_STATE_RECONNECTING) { rpmsg_port_unregister(&rpspi->port); - /* Trigger a transmission for reconnection */ + /* Do not trigger the reconnect if a shut down cmd has been + * received during the unregister process + */ - rpspi->state = RPMSG_PORT_SPI_STATE_UNCONNECTED; - IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 1); + if (rpspi->state == RPMSG_PORT_SPI_STATE_RECONNECTING) + { + rpspi->state = RPMSG_PORT_SPI_STATE_UNCONNECTED; + IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 1); + } + else + { + rpspi->state = RPMSG_PORT_SPI_STATE_UNCONNECTED; + IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 0); + } } - else + else if (rpspi->state == RPMSG_PORT_SPI_STATE_CONNECTING) { rpspi->state = RPMSG_PORT_SPI_STATE_CONNECTED; rpmsg_port_register(&rpspi->port, (FAR const char *)(rxhdr + 1)); @@ -428,6 +446,13 @@ rpmsg_port_spi_process_packet(FAR struct rpmsg_port_spi_s *rpspi, rpspi->rxcb(&rpspi->port, rxhdr); break; + case RPMSG_PORT_SPI_CMD_SHUTDOWN: + rpmsg_port_unregister(&rpspi->port); + rpspi->state = RPMSG_PORT_SPI_STATE_UNCONNECTED; + IOEXP_WRITEPIN(rpspi->ioe, rpspi->mreq, 0); + rpmsg_port_queue_return_buffer(&rpspi->port.rxq, rxhdr); + break; + default: rpmsgerr("dropped an unexpected frame cmd: %u avail: %u\n", rxhdr->cmd, rxhdr->avail); diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c b/drivers/rpmsg/rpmsg_port_spi_slave.c index 1ae4cb5f313..bfb6a04bd3e 100644 --- a/drivers/rpmsg/rpmsg_port_spi_slave.c +++ b/drivers/rpmsg/rpmsg_port_spi_slave.c @@ -63,12 +63,14 @@ enum rpmsg_port_spi_cmd_e RPMSG_PORT_SPI_CMD_CONNECT = 0x01, RPMSG_PORT_SPI_CMD_AVAIL, RPMSG_PORT_SPI_CMD_DATA, + RPMSG_PORT_SPI_CMD_SHUTDOWN, }; enum rpmsg_port_spi_state_e { RPMSG_PORT_SPI_STATE_UNCONNECTED = 0x01, RPMSG_PORT_SPI_STATE_CONNECTING, + RPMSG_PORT_SPI_STATE_RECONNECTING, RPMSG_PORT_SPI_STATE_DISCONNECTING, RPMSG_PORT_SPI_STATE_CONNECTED, }; @@ -101,7 +103,7 @@ struct rpmsg_port_spi_s FAR struct rpmsg_port_header_s *rxhdr; rpmsg_port_rx_cb_t rxcb; - uint8_t state; + volatile uint8_t state; /* Used for flow control */ @@ -378,7 +380,7 @@ static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev, rpspi->txavail = rpspi->rxhdr->avail; if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_CONNECT) { - rpspi->state = RPMSG_PORT_SPI_STATE_DISCONNECTING; + rpspi->state = RPMSG_PORT_SPI_STATE_RECONNECTING; /* Drop all the unprocessed rxq buffer and pre-send txq buffer * when a reconnect request to be received. @@ -396,6 +398,12 @@ static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev, if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_AVAIL) { + if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_SHUTDOWN) + { + rpspi->state = RPMSG_PORT_SPI_STATE_DISCONNECTING; + rpmsg_port_spi_drop_packets(rpspi, RPMSG_PORT_SPI_DROP_ALL); + } + rpmsg_port_queue_add_buffer(&rpspi->port.rxq, rpspi->rxhdr); rpspi->rxhdr = rpmsg_port_queue_get_available_buffer( &rpspi->port.rxq, false); @@ -446,13 +454,26 @@ rpmsg_port_spi_process_packet(FAR struct rpmsg_port_spi_s *rpspi, switch (rxhdr->cmd) { case RPMSG_PORT_SPI_CMD_CONNECT: - if (rpspi->state == RPMSG_PORT_SPI_STATE_DISCONNECTING) + if (rpspi->state == RPMSG_PORT_SPI_STATE_RECONNECTING) { rpmsg_port_unregister(&rpspi->port); - rpspi->state = RPMSG_PORT_SPI_STATE_UNCONNECTED; - rpmsg_port_spi_connect(rpspi); + + /* Do not trigger the reconnect if a shut down cmd has been + * received during the unregister process + */ + + if (rpspi->state == RPMSG_PORT_SPI_STATE_RECONNECTING) + { + rpspi->state = RPMSG_PORT_SPI_STATE_UNCONNECTED; + rpmsg_port_spi_connect(rpspi); + } + else + { + rpspi->state = RPMSG_PORT_SPI_STATE_UNCONNECTED; + IOEXP_WRITEPIN(rpspi->ioe, rpspi->sreq, 0); + } } - else + else if (rpspi->state == RPMSG_PORT_SPI_STATE_CONNECTING) { rpspi->state = RPMSG_PORT_SPI_STATE_CONNECTED; rpmsg_port_register(&rpspi->port, (FAR const char *)(rxhdr + 1)); @@ -465,6 +486,13 @@ rpmsg_port_spi_process_packet(FAR struct rpmsg_port_spi_s *rpspi, rpspi->rxcb(&rpspi->port, rxhdr); break; + case RPMSG_PORT_SPI_CMD_SHUTDOWN: + rpmsg_port_unregister(&rpspi->port); + rpspi->state = RPMSG_PORT_SPI_STATE_UNCONNECTED; + IOEXP_WRITEPIN(rpspi->ioe, rpspi->sreq, 0); + rpmsg_port_queue_return_buffer(&rpspi->port.rxq, rxhdr); + break; + default: rpmsgerr("received a unexpected frame, dropped\n"); rpmsg_port_queue_return_buffer(&rpspi->port.rxq, rxhdr);