pkarashchenko commented on code in PR #6821:
URL: https://github.com/apache/incubator-nuttx/pull/6821#discussion_r941390650


##########
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c:
##########
@@ -1142,6 +1281,20 @@ s32k1xx_lpi2c_getstatus(struct s32k1xx_lpi2c_priv_s 
*priv)
   return s32k1xx_lpi2c_getreg(priv, S32K1XX_LPI2C_MSR_OFFSET);
 }
 
+/****************************************************************************
+ * Name: imxrt_lpi2c_getenabledints
+ *
+ * Description:
+ *   Get 32-bit status
+ *
+ ****************************************************************************/
+
+static inline uint32_t
+s32k1xx_lpi2c_getenabledints(FAR struct s32k1xx_lpi2c_priv_s *priv)

Review Comment:
   ```suggestion
   s32k1xx_lpi2c_getenabledints(struct s32k1xx_lpi2c_priv_s *priv)
   ```



##########
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c:
##########
@@ -1491,6 +1724,223 @@ static int s32k1xx_lpi2c_deinit(struct 
s32k1xx_lpi2c_priv_s *priv)
  * Device Driver Operations
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_command_configure
+ *
+ * Description:
+ *   Create a command TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int
+s32k1xx_lpi2c_dma_command_configure(FAR struct s32k1xx_lpi2c_priv_s

Review Comment:
   ```suggestion
   s32k1xx_lpi2c_dma_command_configure(struct s32k1xx_lpi2c_priv_s
   ```



##########
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c:
##########
@@ -1491,6 +1724,223 @@ static int s32k1xx_lpi2c_deinit(struct 
s32k1xx_lpi2c_priv_s *priv)
  * Device Driver Operations
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_command_configure
+ *
+ * Description:
+ *   Create a command TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int
+s32k1xx_lpi2c_dma_command_configure(FAR struct s32k1xx_lpi2c_priv_s
+                                    *priv, uint16_t *ccmd,
+                                     uint32_t ncmd)
+{
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.saddr  = (uint32_t) ccmd;
+  config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+  config.soff   = sizeof(uint16_t);
+  config.doff   = 0;
+  config.iter   = 1;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_16BIT;
+  config.dsize  = EDMA_16BIT;
+  config.nbytes = sizeof(uint16_t) * ncmd;
+
+  up_clean_dcache((uintptr_t)config.saddr,
+                  (uintptr_t)config.saddr + config.nbytes);
+
+  return s32k1xx_dmach_xfrsetup(priv->txdma, &config);
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_data_configure
+ *
+ * Description:
+ *   Create a data TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_dma_data_configure(FAR struct s32k1xx_lpi2c_priv_s
+                                              *priv,
+                                              struct i2c_msg_s *msg)
+{
+  DMACH_HANDLE dma;
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.iter   = msg->length;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_8BIT;
+  config.dsize  = EDMA_8BIT;
+  config.nbytes = sizeof(msg->buffer[0]);
+
+  if (msg->flags & I2C_M_READ)
+    {
+      dma           = priv->rxdma;
+      config.saddr  = priv->config->base + S32K1XX_LPI2C_MRDR_OFFSET;
+      config.daddr  = (uint32_t) msg->buffer;
+      config.soff   = 0;
+      config.doff   = sizeof(msg->buffer[0]);
+      up_invalidate_dcache((uintptr_t)msg->buffer,
+                           (uintptr_t)msg->buffer + msg->length);
+    }
+  else
+    {
+      dma           = priv->txdma;
+      config.saddr  = (uint32_t) msg->buffer;
+      config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+      config.soff   = sizeof(msg->buffer[0]);
+      config.doff   = 0;
+      up_clean_dcache((uintptr_t)msg->buffer,
+                      (uintptr_t)msg->buffer + msg->length);
+    }
+
+  return s32k1xx_dmach_xfrsetup(dma, &config) ? 0 : msg->length;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_configure_dma_transfer
+ *
+ * Description:
+ *   DMA based I2C transfer function
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_form_command_list(FAR struct s32k1xx_lpi2c_priv_s

Review Comment:
   ```suggestion
   static int s32k1xx_lpi2c_form_command_list(struct s32k1xx_lpi2c_priv_s
   ```



##########
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c:
##########
@@ -1491,6 +1724,223 @@ static int s32k1xx_lpi2c_deinit(struct 
s32k1xx_lpi2c_priv_s *priv)
  * Device Driver Operations
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_command_configure
+ *
+ * Description:
+ *   Create a command TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int
+s32k1xx_lpi2c_dma_command_configure(FAR struct s32k1xx_lpi2c_priv_s
+                                    *priv, uint16_t *ccmd,
+                                     uint32_t ncmd)
+{
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.saddr  = (uint32_t) ccmd;
+  config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+  config.soff   = sizeof(uint16_t);
+  config.doff   = 0;
+  config.iter   = 1;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_16BIT;
+  config.dsize  = EDMA_16BIT;
+  config.nbytes = sizeof(uint16_t) * ncmd;
+
+  up_clean_dcache((uintptr_t)config.saddr,
+                  (uintptr_t)config.saddr + config.nbytes);
+
+  return s32k1xx_dmach_xfrsetup(priv->txdma, &config);
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_data_configure
+ *
+ * Description:
+ *   Create a data TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_dma_data_configure(FAR struct s32k1xx_lpi2c_priv_s
+                                              *priv,
+                                              struct i2c_msg_s *msg)
+{
+  DMACH_HANDLE dma;
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.iter   = msg->length;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_8BIT;
+  config.dsize  = EDMA_8BIT;
+  config.nbytes = sizeof(msg->buffer[0]);
+
+  if (msg->flags & I2C_M_READ)
+    {
+      dma           = priv->rxdma;
+      config.saddr  = priv->config->base + S32K1XX_LPI2C_MRDR_OFFSET;
+      config.daddr  = (uint32_t) msg->buffer;
+      config.soff   = 0;
+      config.doff   = sizeof(msg->buffer[0]);
+      up_invalidate_dcache((uintptr_t)msg->buffer,
+                           (uintptr_t)msg->buffer + msg->length);
+    }
+  else
+    {
+      dma           = priv->txdma;
+      config.saddr  = (uint32_t) msg->buffer;
+      config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+      config.soff   = sizeof(msg->buffer[0]);
+      config.doff   = 0;
+      up_clean_dcache((uintptr_t)msg->buffer,
+                      (uintptr_t)msg->buffer + msg->length);
+    }
+
+  return s32k1xx_dmach_xfrsetup(dma, &config) ? 0 : msg->length;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_configure_dma_transfer
+ *
+ * Description:
+ *   DMA based I2C transfer function
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_form_command_list(FAR struct s32k1xx_lpi2c_priv_s
+                                              *priv, struct i2c_msg_s *msg,
+                                              int ncmds)
+{
+  ssize_t length = 0;
+
+  if (priv->flags & I2C_M_NOSTART)
+    {
+      if (priv->flags & I2C_M_READ)
+        {
+          /* No start read operation */
+
+          priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                 LPI2C_MTDR_DATA(msg->length - 1);
+        }
+    }
+  else
+    {
+      /* A start based read or write operation */
+
+      /* Create bus address with R/W */
+
+      uint16_t badd = (priv->flags & I2C_M_READ) ? I2C_READADDR8(msg->addr) :
+                                                   I2C_WRITEADDR8(msg->addr);
+
+      priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_START | LPI2C_MTDR_DATA(badd);
+
+      if (badd & I2C_READBIT)
+        {
+          length =  msg->length;
+          while (length)
+            {
+              if (length > 256u)
+                {
+                  priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                         LPI2C_MTDR_DATA(256u - 1);
+                  length -= 256u;
+                }
+              else
+                {
+                  priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                         LPI2C_MTDR_DATA(length - 1);
+                  length = 0;
+                }
+            }
+        }
+    }
+
+  return ncmds;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_transfer
+ *
+ * Description:
+ *   DMA based I2C transfer function
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_dma_transfer(FAR struct s32k1xx_lpi2c_priv_s *priv)

Review Comment:
   ```suggestion
   static int s32k1xx_lpi2c_dma_transfer(struct s32k1xx_lpi2c_priv_s *priv)
   ```



##########
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c:
##########
@@ -1491,6 +1724,223 @@ static int s32k1xx_lpi2c_deinit(struct 
s32k1xx_lpi2c_priv_s *priv)
  * Device Driver Operations
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_command_configure
+ *
+ * Description:
+ *   Create a command TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int
+s32k1xx_lpi2c_dma_command_configure(FAR struct s32k1xx_lpi2c_priv_s
+                                    *priv, uint16_t *ccmd,
+                                     uint32_t ncmd)
+{
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.saddr  = (uint32_t) ccmd;
+  config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+  config.soff   = sizeof(uint16_t);
+  config.doff   = 0;
+  config.iter   = 1;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_16BIT;
+  config.dsize  = EDMA_16BIT;
+  config.nbytes = sizeof(uint16_t) * ncmd;
+
+  up_clean_dcache((uintptr_t)config.saddr,
+                  (uintptr_t)config.saddr + config.nbytes);
+
+  return s32k1xx_dmach_xfrsetup(priv->txdma, &config);
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_data_configure
+ *
+ * Description:
+ *   Create a data TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_dma_data_configure(FAR struct s32k1xx_lpi2c_priv_s

Review Comment:
   ```suggestion
   static int s32k1xx_lpi2c_dma_data_configure(struct s32k1xx_lpi2c_priv_s
   ```



##########
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c:
##########
@@ -1548,8 +1998,27 @@ static int s32k1xx_lpi2c_transfer(struct i2c_master_s 
*dev,
    * the BUSY flag.
    */
 
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+  if (priv->rxdma || priv->txdma)
+    {
+      s32k1xx_lpi2c_dma_transfer(priv);
+    }
+#endif
+
   if (s32k1xx_lpi2c_sem_waitdone(priv) < 0)
     {
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+      if (priv->rxdma)

Review Comment:
   ```suggestion
         if (priv->rxdma != NULL)
   ```



##########
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c:
##########
@@ -1548,8 +1998,27 @@ static int s32k1xx_lpi2c_transfer(struct i2c_master_s 
*dev,
    * the BUSY flag.
    */
 
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+  if (priv->rxdma || priv->txdma)
+    {
+      s32k1xx_lpi2c_dma_transfer(priv);
+    }
+#endif
+
   if (s32k1xx_lpi2c_sem_waitdone(priv) < 0)
     {
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+      if (priv->rxdma)
+        {
+          s32k1xx_dmach_stop(priv->rxdma);
+        }
+
+      if (priv->txdma)

Review Comment:
   ```suggestion
         if (priv->txdma != NULL)
   ```



##########
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c:
##########
@@ -1491,6 +1724,223 @@ static int s32k1xx_lpi2c_deinit(struct 
s32k1xx_lpi2c_priv_s *priv)
  * Device Driver Operations
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_command_configure
+ *
+ * Description:
+ *   Create a command TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int
+s32k1xx_lpi2c_dma_command_configure(FAR struct s32k1xx_lpi2c_priv_s
+                                    *priv, uint16_t *ccmd,
+                                     uint32_t ncmd)
+{
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.saddr  = (uint32_t) ccmd;
+  config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+  config.soff   = sizeof(uint16_t);
+  config.doff   = 0;
+  config.iter   = 1;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_16BIT;
+  config.dsize  = EDMA_16BIT;
+  config.nbytes = sizeof(uint16_t) * ncmd;
+
+  up_clean_dcache((uintptr_t)config.saddr,
+                  (uintptr_t)config.saddr + config.nbytes);
+
+  return s32k1xx_dmach_xfrsetup(priv->txdma, &config);
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_data_configure
+ *
+ * Description:
+ *   Create a data TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_dma_data_configure(FAR struct s32k1xx_lpi2c_priv_s
+                                              *priv,
+                                              struct i2c_msg_s *msg)
+{
+  DMACH_HANDLE dma;
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.iter   = msg->length;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_8BIT;
+  config.dsize  = EDMA_8BIT;
+  config.nbytes = sizeof(msg->buffer[0]);
+
+  if (msg->flags & I2C_M_READ)
+    {
+      dma           = priv->rxdma;
+      config.saddr  = priv->config->base + S32K1XX_LPI2C_MRDR_OFFSET;
+      config.daddr  = (uint32_t) msg->buffer;
+      config.soff   = 0;
+      config.doff   = sizeof(msg->buffer[0]);
+      up_invalidate_dcache((uintptr_t)msg->buffer,
+                           (uintptr_t)msg->buffer + msg->length);
+    }
+  else
+    {
+      dma           = priv->txdma;
+      config.saddr  = (uint32_t) msg->buffer;
+      config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+      config.soff   = sizeof(msg->buffer[0]);
+      config.doff   = 0;
+      up_clean_dcache((uintptr_t)msg->buffer,
+                      (uintptr_t)msg->buffer + msg->length);
+    }
+
+  return s32k1xx_dmach_xfrsetup(dma, &config) ? 0 : msg->length;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_configure_dma_transfer
+ *
+ * Description:
+ *   DMA based I2C transfer function
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_form_command_list(FAR struct s32k1xx_lpi2c_priv_s
+                                              *priv, struct i2c_msg_s *msg,
+                                              int ncmds)
+{
+  ssize_t length = 0;
+
+  if (priv->flags & I2C_M_NOSTART)
+    {
+      if (priv->flags & I2C_M_READ)
+        {
+          /* No start read operation */
+
+          priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                 LPI2C_MTDR_DATA(msg->length - 1);
+        }
+    }
+  else
+    {
+      /* A start based read or write operation */
+
+      /* Create bus address with R/W */
+
+      uint16_t badd = (priv->flags & I2C_M_READ) ? I2C_READADDR8(msg->addr) :
+                                                   I2C_WRITEADDR8(msg->addr);
+
+      priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_START | LPI2C_MTDR_DATA(badd);
+
+      if (badd & I2C_READBIT)
+        {
+          length =  msg->length;
+          while (length)
+            {
+              if (length > 256u)
+                {
+                  priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                         LPI2C_MTDR_DATA(256u - 1);
+                  length -= 256u;
+                }
+              else
+                {
+                  priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                         LPI2C_MTDR_DATA(length - 1);
+                  length = 0;
+                }
+            }
+        }
+    }
+
+  return ncmds;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_transfer
+ *
+ * Description:
+ *   DMA based I2C transfer function
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_dma_transfer(FAR struct s32k1xx_lpi2c_priv_s *priv)
+{
+  int m;
+  int ntotcmds = 0;
+  int ncmds = 0;
+  uint16_t *ccmnd = NULL;
+
+  /* Disable Interrupts */
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MIER_OFFSET,
+                            LPI2C_MIER_RDIE | LPI2C_MIER_TDIE, 0);
+
+  /* Disable DMA */
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MDER_OFFSET, LPI2C_MDER_TDDE |
+                                                       LPI2C_MDER_RDDE, 0);
+
+  /* Turn off auto_stop option */
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCFGR1_OFFSET, 0,
+                        LPI2C_MCFGR1_IGNACK | LPI2C_MCFGR1_AUTOSTOP);

Review Comment:
   ```suggestion
     s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCFGR1_OFFSET, 0,
                             LPI2C_MCFGR1_IGNACK | LPI2C_MCFGR1_AUTOSTOP);
   ```



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to