You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2022/07/18 15:46:03 UTC

[GitHub] [incubator-nuttx] onegray commented on a diff in pull request #6537: drivers/ipcc: add Inter Processor Communication driver

onegray commented on code in PR #6537:
URL: https://github.com/apache/incubator-nuttx/pull/6537#discussion_r923527130


##########
arch/arm/src/stm32wl5/stm32wl5_ipcc.c:
##########
@@ -0,0 +1,801 @@
+/****************************************************************************
+ * arch/arm/src/stm32wl5/stm32wl5_ipcc.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/ipcc.h>
+#include <nuttx/irq.h>
+
+#include <arm_internal.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <arch/stm32wl5/stm32wl5xxx_cpu1_irq.h>
+#include "hardware/stm32wl5_ipcc.h"
+#include "stm32wl5.h"
+#include "stm32wl5_ipcc.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure describes tx or rx of single channel in memory */
+
+struct stm32wl5_ipcc_chan_mem_s
+{
+  unsigned len; /* Number of valid bytes in data[] */
+  char data[];  /* Data in IPCC memory */
+};
+
+/* Internal stm32wl5 ipcc structure describing channel state. */
+
+struct stm32wl5_ipcc_s
+{
+  /* Pointer to API connecting upper and lower half of the driver */
+
+  struct ipcc_lower_s *ipcc;
+
+  /* Physical memory address where second CPU will write data for us,
+   * we will be reading from this memory.
+   */
+
+  char *rxmem;
+
+  /* Maximum length of data that rxmem can hold. It is size of the
+   * reserved space for rxmem minus sizeof(stm32wl5_ipcc_chan_mem_s.len)
+   */
+
+  unsigned rxlen;
+
+#if CONFIG_IPCC_BUFFERED
+  /* Number of bytes copied from IPCC memory to buffer. Can be less than
+   * stm32wl5_ipcc_chan_mem_s.len after copy operation when buffer is full.
+   * Value can persist between multiple ISR and stm32wl5_ipcc_buffer_data()
+   * calls, until all data from IPCC memory is successfully buffered.
+   */
+
+  unsigned rxcopied;
+#endif
+
+  /* Physical memory address where we will write data for the second
+   * CPU to read.
+   */
+
+  char *txmem;
+
+  /* Maximum length of data that txmem can hold. It is size of the
+   * reserved space for txmem minus sizeof(stm32wl5_ipcc_chan_mem_s.len)
+   */
+
+  unsigned txlen;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t stm32wl5_ipcc_read(struct ipcc_lower_s *ipcc,
+                                  char *buffer, size_t buflen);
+static ssize_t stm32wl5_ipcc_write(struct ipcc_lower_s *ipcc,
+                                   const char *buffer, size_t buflen);
+static ssize_t stm32wl5_ipcc_buffer_data(struct ipcc_lower_s *ipcc,
+                                         struct circbuf_s *rxbuf);
+static ssize_t stm32wl5_ipcc_copy_to_buffer(int chan,
+                                            struct circbuf_s *rxbuf);
+static int     stm32wl5_ipcc_rx_isr(int irq, void *context, void *arg);
+static int     stm32wl5_ipcc_tx_isr(int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct stm32wl5_ipcc_s g_ipccpriv[IPCC_NCHAN] =
+{
+  /* Channel 1 is always enabled when IPCC is enabled */
+
+    {
+      .rxmem = (char *)(IPCC_CHAN1_START),
+      .rxlen = IPCC_CHAN1_RX_SIZE - sizeof(unsigned),
+      .txmem = (char *)(IPCC_CHAN1_START + IPCC_CHAN1_RX_SIZE),
+      .txlen = IPCC_CHAN1_TX_SIZE - sizeof(unsigned)
+    }
+
+#if IPCC_CHAN2
+    ,
+    {
+      .rxmem = (char *)(IPCC_CHAN2_START),
+      .rxlen = IPCC_CHAN2_RX_SIZE - sizeof(unsigned),
+      .txmem = (char *)(IPCC_CHAN2_START + IPCC_CHAN2_RX_SIZE),
+      .txlen = IPCC_CHAN2_TX_SIZE - sizeof(unsigned)
+    }
+#endif
+
+#if IPCC_CHAN3
+    ,
+    {
+      .rxmem = (char *)(IPCC_CHAN3_START),
+      .rxlen = IPCC_CHAN3_RX_SIZE - sizeof(unsigned),
+      .txmem = (char *)(IPCC_CHAN3_START + IPCC_CHAN3_RX_SIZE),
+      .txlen = IPCC_CHAN3_TX_SIZE - sizeof(unsigned)
+    }
+#endif
+
+#if IPCC_CHAN4
+    ,
+    {
+      .rxmem = (char *)(IPCC_CHAN4_START),
+      .rxlen = IPCC_CHAN4_RX_SIZE - sizeof(unsigned),
+      .txmem = (char *)(IPCC_CHAN4_START + IPCC_CHAN4_RX_SIZE),
+      .txlen = IPCC_CHAN4_TX_SIZE - sizeof(unsigned)
+    }
+#endif
+
+#if IPCC_CHAN5
+    ,
+    {
+      .rxmem = (char *)(IPCC_CHAN5_START),
+      .rxlen = IPCC_CHAN5_RX_SIZE - sizeof(unsigned),
+      .txmem = (char *)(IPCC_CHAN5_START + IPCC_CHAN5_RX_SIZE),
+      .txlen = IPCC_CHAN5_TX_SIZE - sizeof(unsigned)
+    }
+#endif
+
+#if IPCC_CHAN6
+    ,
+    {
+      .rxmem = (char *)(IPCC_CHAN6_START),
+      .rxlen = IPCC_CHAN6_RX_SIZE - sizeof(unsigned),
+      .txmem = (char *)(IPCC_CHAN6_START + IPCC_CHAN6_RX_SIZE),
+      .txlen = IPCC_CHAN6_TX_SIZE - sizeof(unsigned)
+    }
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32wl5_ipcc_tx_isr
+ *
+ * Description:
+ *   IPCC TX interrupt service routine. This interrupt is called when
+ *   second CPU read all data from IPCC TX memory and we are free to
+ *   write new data to that memory.
+ *
+ *   For buffered IPCC, we will immediately write data from buffer to
+ *   IPCC memory and notify second CPU. Also blocked writer will be
+ *   notified that there is free space on tx buffer.
+ *
+ *   For unbuffered IPCC, we won't copy anything but only notify blocked
+ *   writers that IPCC TX memory is free.
+ *
+ * Input Parameters:
+ *   irq - Number of IRQ that generated interrupt
+ *   context - Interrupt register state save info (architecture-specific)
+ *   arg - user data (not used by us)
+ *
+ * Returned Value:
+ *   Always OK
+ *
+ * Assumptions/Limitations:
+ *
+ ****************************************************************************/
+
+static int stm32wl5_ipcc_tx_isr(int irq, void *context, void *arg)
+{
+  int chan;
+  size_t nwritten;
+  uint32_t mr;
+  uint32_t sr;
+  uint32_t status;
+  struct stm32wl5_ipcc_s *priv;
+  struct stm32wl5_ipcc_chan_mem_s *txmem;
+
+  (void)context;
+  (void)arg;
+  (void)irq;
+
+  /* Disable TX interrupt, we don't want two "threads" to concurently
+   * modify circbuffers as we don't use any guard to them
+   */
+
+  up_disable_irq(STM32WL5_IRQ_IPCC_C1_TX_IT);
+
+  mr = getreg32(STM32WL5_IPCC_C1MR) >> STM32WL5_IPCC_TX_SHIFT;
+  sr = getreg32(STM32WL5_IPCC_C1TOC2SR);
+
+  /* Consider only channels that have tx memory free and are unmasked */
+
+  status = sr | mr;

Review Comment:
   Looks like you are expecting `AND` logic, but the written is `OR`. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org