You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/08/10 03:22:43 UTC
[incubator-nuttx] branch master updated: s32k1xx:LPI2C Add DMA support
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 32c4bdb7a6 s32k1xx:LPI2C Add DMA support
32c4bdb7a6 is described below
commit 32c4bdb7a67d621083cd0a70c0de1653dce0e79a
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Mon Aug 1 10:11:15 2022 -0700
s32k1xx:LPI2C Add DMA support
---
arch/arm/src/s32k1xx/Kconfig | 63 ++++
arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h | 60 +--
arch/arm/src/s32k1xx/s32k1xx_lpi2c.c | 509 +++++++++++++++++++++++++-
3 files changed, 598 insertions(+), 34 deletions(-)
diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig
index a011e6002c..5da747b11b 100644
--- a/arch/arm/src/s32k1xx/Kconfig
+++ b/arch/arm/src/s32k1xx/Kconfig
@@ -641,6 +641,58 @@ config S32K1XX_LPSPI_HWPCS
endmenu # LPSPI Configuration
+menu "LPI2C Configuration"
+ depends on S32K1XX_LPI2C
+
+config S32K1XX_LPI2C_DMA
+ bool "I2C DMA Support"
+ default n
+ depends on S32K1XX_LPI2C && S32K1XX_EDMA && !I2C_POLLED
+ ---help---
+ This option enables the DMA for I2C transfers.
+ Note: The user can define CONFIG_I2C_DMAPRIO: a custom priority value
+ for the I2C dma streams, else the default priority level is set to
+ medium.
+
+config S32K1XX_LPI2C_DMA_MAXMSG
+ int "Maximum number messages that will be DMAed"
+ default 8
+ depends on S32K1XX_LPI2C_DMA
+ ---help---
+ This option set the mumber of mesg that can be in a transfer.
+ It is used to allocate space for the 16 bit LPI2C commands
+ that will be DMA-ed to the LPI2C device.
+
+config S32K1XX_LPI2C_DYNTIMEO
+ bool "Use dynamic timeouts"
+ default n
+ depends on S32K1XX_LPI2C
+
+config S32K1XX_LPI2C_DYNTIMEO_USECPERBYTE
+ int "Timeout Microseconds per Byte"
+ default 500
+ depends on S32K1XX_LPI2C_DYNTIMEO
+
+config S32K1XX_LPI2C_DYNTIMEO_STARTSTOP
+ int "Timeout for Start/Stop (Milliseconds)"
+ default 1000
+ depends on S32K1XX_LPI2C_DYNTIMEO
+
+config S32K1XX_LPI2C_TIMEOSEC
+ int "Timeout seconds"
+ default 0
+ depends on S32K1XX_LPI2C
+
+config S32K1XX_LPI2C_TIMEOMS
+ int "Timeout Milliseconds"
+ default 500
+ depends on S32K1XX_LPI2C && !S32K1XX_LPI2C_DYNTIMEO
+
+config S32K1XX_LPI2C_TIMEOTICKS
+ int "Timeout for Done and Stop (ticks)"
+ default 500
+ depends on S32K1XX_LPI2C && !S32K1XX_LPI2C_DYNTIMEO
+
menu "LPI2C0 Master Configuration"
depends on S32K1XX_LPI2C0
@@ -648,6 +700,11 @@ config LPI2C0_BUSYIDLE
int "Bus idle timeout period in clock cycles"
default 0
+config LPI2C0_DMA
+ bool "Enable DMA for I2C0"
+ default n
+ depends on S32K1XX_LPI2C_DMA
+
config LPI2C0_FILTSCL
int "I2C master digital glitch filters for SCL input in clock cycles"
default 0
@@ -678,6 +735,11 @@ endmenu # LPI2C0 Slave Configuration
menu "LPI2C1 Master Configuration"
depends on S32K1XX_LPI2C1
+config LPI2C1_DMA
+ bool "Enable DMA for I2C1"
+ default n
+ depends on S32K1XX_LPI2C_DMA
+
config LPI2C1_BUSYIDLE
int "Bus idle timeout period in clock cycles"
default 0
@@ -708,6 +770,7 @@ config LPI2C1_SLAVE_BUS
the LPI2C master. These pins need to be defined in the board.h.
endmenu # LPI2C1 Slave Configuration
+endmenu # LPI2C Configuration
menu "Ethernet Configuration"
depends on S32K1XX_ENET
diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h
index b9740b7ccc..dbdc70255a 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h
@@ -239,7 +239,7 @@
/* LPI2C Master Config Register 1 */
#define LPI2C_MCFGR1_PRESCALE_MASK (7 << 0) /* Clock Prescaler Bit Mask */
-# define LPI2C_MCFGR1_PRESCALE(n) (n & LPI2C_MCFGR1_PRESCALE_MASK)
+# define LPI2C_MCFGR1_PRESCALE(n) ((n) & LPI2C_MCFGR1_PRESCALE_MASK)
# define LPI2C_MCFGR1_PRESCALE_1 (0)
# define LPI2C_MCFGR1_PRESCALE_2 (1)
# define LPI2C_MCFGR1_PRESCALE_4 (2)
@@ -254,7 +254,7 @@
/* Bits 15-11 Reserved */
#define LPI2C_MCFGR1_MATCFG_SHIFT (16)
#define LPI2C_MCFGR1_MATCFG_MASK (7 << LPI2C_MCFGR1_MATCFG_SHIFT) /* Match Configuration Bit Mask */
-# define LPI2C_MCFGR1_MATCFG(n) ((n << LPI2C_MCFGR1_MATCFG_SHIFT) & LPI2C_MCFGR1_MATCFG_MASK)
+# define LPI2C_MCFGR1_MATCFG(n) (((n) << LPI2C_MCFGR1_MATCFG_SHIFT) & LPI2C_MCFGR1_MATCFG_MASK)
# define LPI2C_MCFGR1_MATCFG_DISABLE (0 << LPI2C_MCFGR1_MATCFG_SHIFT)
/* LPI2C_MCFG1_MATCFG = 001b Reserved */
# define LPI2C_MCFGR1_MATCFG2 (2 << LPI2C_MCFGR1_MATCFG_SHIFT)
@@ -266,7 +266,7 @@
/* Bits 23-19 Reserved */
#define LPI2C_MCFGR1_PINCFG_SHIFT (24)
#define LPI2C_MCFGR1_PINCFG_MASK (7 << LPI2C_MCFGR1_PINCFG_SHIFT) /* Pin Configuration Bit Mask */
-# define LPI2C_MCFGR1_PINCFG(n) ((n << LPI2C_MCFGR1_PINCFG_SHIFT) & LPI2C_MCFGR1_PINCFG_MASK)
+# define LPI2C_MCFGR1_PINCFG(n) (((n) << LPI2C_MCFGR1_PINCFG_SHIFT) & LPI2C_MCFGR1_PINCFG_MASK)
# define LPI2C_MCFGR1_PINCFG0 (0 << LPI2C_MCFGR1_PINCFG_SHIFT)
# define LPI2C_MCFGR1_PINCFG1 (1 << LPI2C_MCFGR1_PINCFG_SHIFT)
# define LPI2C_MCFGR1_PINCFG2 (2 << LPI2C_MCFGR1_PINCFG_SHIFT)
@@ -281,17 +281,17 @@
#define LPI2C_MCFG2_BUSIDLE_MASK (0xfff << 0) /* Bus Idle Timeout Period in Clock Cycles */
#define LPI2C_MCFG2_BUSIDLE_DISABLE (0)
-# define LPI2C_MCFG2_BUSIDLE(n) (n & LPI2C_MCFG2_BUSIDLE_MASK)
+# define LPI2C_MCFG2_BUSIDLE(n) ((n) & LPI2C_MCFG2_BUSIDLE_MASK)
/* Bits 15-12 Reserved */
#define LPI2C_MCFG2_FILTSCL_SHIFT (16)
#define LPI2C_MCFG2_FILTSCL_MASK (15 << LPI2C_MCFG2_FILTSCL_SHIFT) /* Glitch Filter SCL */
#define LPI2C_MCFG2_FILTSCL_DISABLE (0 << LPI2C_MCFG2_FILTSCL_SHIFT)
-# define LPI2C_MCFG2_FILTSCL_CYCLES(n) ((n << LPI2C_MCFG2_FILTSCL_SHIFT) & LPI2C_MCFG2_FILTSCL_MASK)
+# define LPI2C_MCFG2_FILTSCL_CYCLES(n) (((n) << LPI2C_MCFG2_FILTSCL_SHIFT) & LPI2C_MCFG2_FILTSCL_MASK)
/* Bits 23-20 Reserved */
#define LPI2C_MCFG2_FILTSDA_SHIFT (24)
#define LPI2C_MCFG2_FILTSDA_MASK (15 << LPI2C_MCFG2_FILTSDA_SHIFT) /* Glitch Filter SDA */
#define LPI2C_MCFG2_FILTSDA_DISABLE (0 << LPI2C_MCFG2_FILTSDA_SHIFT)
-# define LPI2C_MCFG2_FILTSDA_CYCLES(n) ((n << LPI2C_MCFG2_FILTSDA_SHIFT) & LPI2C_MCFG2_FILTSDA_MASK)
+# define LPI2C_MCFG2_FILTSDA_CYCLES(n) (((n) << LPI2C_MCFG2_FILTSDA_SHIFT) & LPI2C_MCFG2_FILTSDA_MASK)
/* Bits 31-28 Reserved */
/* LPI2C Master Config Register 3 */
@@ -299,56 +299,56 @@
/* Bits 7-0 Reserved */
#define LPI2C_MCFG3_PINLOW_SHIFT (8)
#define LPI2C_MCFG3_PINLOW_MASK (0xfff << LPI2C_MCFG3_PINLOW_SHIFT) /* Configure The Pin Low Timeout in Clock Cycles */
-# define LPI2C_MCFG3_PINLOW_CYCLES(n) ((n << LPI2C_MCFG3_PINLOW_SHIFT) & LPI2C_MCFG3_PINLOW_MASK)
+# define LPI2C_MCFG3_PINLOW_CYCLES(n) (((n) << LPI2C_MCFG3_PINLOW_SHIFT) & LPI2C_MCFG3_PINLOW_MASK)
/* Bits 31-20 Reserved */
/* LPI2C Master Data Match Register */
#define LPI2C_MDMR_MATCH0_SHIFT (0)
#define LPI2C_MDMR_MATCH0_MASK (0xff << LPI2C_MDMR_MATCH0_SHIFT) /* Match 0 Value */
-# define LPI2C_MDMR_MATCH0(n) ((n << LPI2C_MDMR_MATCH0_SHIFT) & LPI2C_MDMR_MATCH0_MASK)
+# define LPI2C_MDMR_MATCH0(n) (((n) << LPI2C_MDMR_MATCH0_SHIFT) & LPI2C_MDMR_MATCH0_MASK)
/* Bits 15-8 Reserved */
#define LPI2C_MDMR_MATCH1_SHIFT (16)
#define LPI2C_MDMR_MATCH1_MASK (0xff << LPI2C_MDMR_MATCH1_SHIFT) /* Match 1 Value */
-# define LPI2C_MDMR_MATCH1(n) ((n << LPI2C_MDMR_MATCH1_SHIFT) & LPI2C_MDMR_MATCH1_MASK)
+# define LPI2C_MDMR_MATCH1(n) (((n) << LPI2C_MDMR_MATCH1_SHIFT) & LPI2C_MDMR_MATCH1_MASK)
/* Bits 31-24 Reserved */
/* LPI2C Master Clock Configuration Register 0 */
#define LPI2C_MCCR0_CLKLO_SHIFT (0)
#define LPI2C_MCCR0_CLKLO_MASK (0x3f << LPI2C_MCCR0_CLKLO_SHIFT) /* Clock Low Period */
-# define LPI2C_MCCR0_CLKLO(n) ((n << LPI2C_MCCR0_CLKLO_SHIFT) & LPI2C_MCCR0_CLKLO_MASK)
+# define LPI2C_MCCR0_CLKLO(n) (((n) << LPI2C_MCCR0_CLKLO_SHIFT) & LPI2C_MCCR0_CLKLO_MASK)
/* Bits 7-6 Reserved */
#define LPI2C_MCCR0_CLKHI_SHIFT (8)
#define LPI2C_MCCR0_CLKHI_MASK (0x3f << LPI2C_MCCR0_CLKHI_SHIFT) /* Clock High Period */
-# define LPI2C_MCCR0_CLKHI(n) ((n << LPI2C_MCCR0_CLKHI_SHIFT) & LPI2C_MCCR0_CLKHI_MASK)
+# define LPI2C_MCCR0_CLKHI(n) (((n) << LPI2C_MCCR0_CLKHI_SHIFT) & LPI2C_MCCR0_CLKHI_MASK)
/* Bits 15-14 Reserved */
#define LPI2C_MCCR0_SETHOLD_SHIFT (16)
#define LPI2C_MCCR0_SETHOLD_MASK (0x3f << LPI2C_MCCR0_SETHOLD_SHIFT) /* Setup Hold Delay */
-# define LPI2C_MCCR0_SETHOLD(n) ((n << LPI2C_MCCR0_SETHOLD_SHIFT) & LPI2C_MCCR0_SETHOLD_MASK)
+# define LPI2C_MCCR0_SETHOLD(n) (((n) << LPI2C_MCCR0_SETHOLD_SHIFT) & LPI2C_MCCR0_SETHOLD_MASK)
/* Bits 23-22 Reserved */
#define LPI2C_MCCR0_DATAVD_SHIFT (24)
#define LPI2C_MCCR0_DATAVD_MASK (0x3f << LPI2C_MCCR0_DATAVD_SHIFT) /* Setup Hold Delay */
-# define LPI2C_MCCR0_DATAVD(n) ((n << LPI2C_MCCR0_DATAVD_SHIFT) & LPI2C_MCCR0_DATAVD_MASK)
+# define LPI2C_MCCR0_DATAVD(n) (((n) << LPI2C_MCCR0_DATAVD_SHIFT) & LPI2C_MCCR0_DATAVD_MASK)
/* Bits 31-30 Reserved */
/* LPI2C Master Clock Configuration Register 1 */
#define LPI2C_MCCR1_CLKLO_SHIFT (0)
#define LPI2C_MCCR1_CLKLO_MASK (0x3f << LPI2C_MCCR1_CLKLO_SHIFT) /* Clock Low Period */
-# define LPI2C_MCCR1_CLKLO(n) ((n << LPI2C_MCCR1_CLKLO_SHIFT) & LPI2C_MCCR1_CLKLO_MASK)
+# define LPI2C_MCCR1_CLKLO(n) (((n) << LPI2C_MCCR1_CLKLO_SHIFT) & LPI2C_MCCR1_CLKLO_MASK)
/* Bits 7-6 Reserved */
#define LPI2C_MCCR1_CLKHI_SHIFT (8)
#define LPI2C_MCCR1_CLKHI_MASK (0x3f << LPI2C_MCCR1_CLKHI_SHIFT) /* Clock High Period */
-# define LPI2C_MCCR1_CLKHI(n) ((n << LPI2C_MCCR1_CLKHI_SHIFT) & LPI2C_MCCR1_CLKHI_MASK)
+# define LPI2C_MCCR1_CLKHI(n) (((n) << LPI2C_MCCR1_CLKHI_SHIFT) & LPI2C_MCCR1_CLKHI_MASK)
/* Bits 15-14 Reserved */
#define LPI2C_MCCR1_SETHOLD_SHIFT (16)
#define LPI2C_MCCR1_SETHOLD_MASK (0x3f << LPI2C_MCCR1_SETHOLD_SHIFT) /* Setup Hold Delay */
-# define LPI2C_MCCR1_SETHOLD(n) ((n << LPI2C_MCCR1_SETHOLD_SHIFT) & LPI2C_MCCR1_SETHOLD_MASK)
+# define LPI2C_MCCR1_SETHOLD(n) (((n) << LPI2C_MCCR1_SETHOLD_SHIFT) & LPI2C_MCCR1_SETHOLD_MASK)
/* Bits 23-22 Reserved */
#define LPI2C_MCCR1_DATAVD_SHIFT (24)
#define LPI2C_MCCR1_DATAVD_MASK (0x3f << LPI2C_MCCR1_DATAVD_SHIFT) /* Setup Hold Delay */
-# define LPI2C_MCCR1_DATAVD(n) ((n << LPI2C_MCCR1_DATAVD_SHIFT) & LPI2C_MCCR1_DATAVD_MASK)
+# define LPI2C_MCCR1_DATAVD(n) (((n) << LPI2C_MCCR1_DATAVD_SHIFT) & LPI2C_MCCR1_DATAVD_MASK)
/* Bits 31-30 Reserved */
/* LPI2C Master FIFO Control Register */
@@ -356,13 +356,13 @@
#define LPI2C_MFCR_TXWATER_SHIFT (0)
#define LPI2C_MFCR_TXWATER_MASK (3 << LPI2C_MFCR_TXWATER_SHIFT) /* Transmit FIFO Watermark*/
-# define LPI2C_MFCR_TXWATER(n) ((n << LPI2C_MFCR_TXWATER_SHIFT) & LPI2C_MFCR_TXWATER_MASK) /* Transmit FIFO Watermark*/
+# define LPI2C_MFCR_TXWATER(n) (((n) << LPI2C_MFCR_TXWATER_SHIFT) & LPI2C_MFCR_TXWATER_MASK) /* Transmit FIFO Watermark*/
/* Bits 15-2 Reserved */
#define LPI2C_MFCR_RXWATER_SHIFT (16)
#define LPI2C_MFCR_RXWATER_MASK (3 << LPI2C_MFCR_RXWATER_SHIFT) /* Receive FIFO Watermark */
-# define LPI2C_MFCR_RXWATER(n) ((n << LPI2C_MFCR_RXWATER_SHIFT) & LPI2C_MFCR_RXWATER_MASK) /* Transmit FIFO Watermark*/
+# define LPI2C_MFCR_RXWATER(n) (((n) << LPI2C_MFCR_RXWATER_SHIFT) & LPI2C_MFCR_RXWATER_MASK) /* Transmit FIFO Watermark*/
/* Bits 31-18 Reserved */
@@ -381,10 +381,10 @@
#define LPI2C_MTDR_DATA_SHIFT (0)
#define LPI2C_MTDR_DATA_MASK (0xff << LPI2C_MTDR_DATA_SHIFT) /* Transmit Data */
-# define LPI2C_MTDR_DATA(n) (n & LPI2C_MTDR_DATA_MASK)
+# define LPI2C_MTDR_DATA(n) ((n) & LPI2C_MTDR_DATA_MASK)
#define LPI2C_MTDR_CMD_SHIFT (8)
#define LPI2C_MTDR_CMD_MASK (7 << LPI2C_MTDR_CMD_SHIFT) /* Command Data */
-# define LPI2C_MTDR_CMD(n) ((n << LPI2C_MTDR_CMD_SHIFT) & LPI2C_MTDR_CMD_MASK)
+# define LPI2C_MTDR_CMD(n) (((n) << LPI2C_MTDR_CMD_SHIFT) & LPI2C_MTDR_CMD_MASK)
# define LPI2C_MTDR_CMD_TXD (0 << LPI2C_MTDR_CMD_SHIFT)
# define LPI2C_MTDR_CMD_RXD (1 << LPI2C_MTDR_CMD_SHIFT)
# define LPI2C_MTDR_CMD_STOP (2 << LPI2C_MTDR_CMD_SHIFT)
@@ -478,7 +478,7 @@
/* Bits 15-14 Reserved */
#define LPI2C_SCFG1_ADDRCFG_SHIFT (16)
#define LPI2C_SCFG1_ADDRCFG_MASK (7 << LPI2C_SCFG1_ADDRCFG_SHIFT) /* Address Configuration Bit Mask */
-# define LPI2C_SCFG1_ADDRCFG(n) ((n << LPI2C_SCFG1_ADDRCFG_SHIFT) & LPI2C_SCFG1_ADDRCFG_MASK)
+# define LPI2C_SCFG1_ADDRCFG(n) (((n) << LPI2C_SCFG1_ADDRCFG_SHIFT) & LPI2C_SCFG1_ADDRCFG_MASK)
# define LPI2C_SCFG1_ADDRCFG0 (0 << LPI2C_SCFG1_ADDRCFG_SHIFT)
# define LPI2C_SCFG1_ADDRCFG1 (2 << LPI2C_SCFG1_ADDRCFG_SHIFT)
# define LPI2C_SCFG1_ADDRCFG2 (2 << LPI2C_SCFG1_ADDRCFG_SHIFT)
@@ -492,21 +492,21 @@
/* LPI2C Slave Configuration Register 2 */
#define LPI2C_SCFG2_CLKHOLD_MASK (15 << 0) /* Clock Hold Time */
-# define LPI2C_SCFG2_CLKHOLD(n) (n & LPI2C_SCFG2_CLKHOLD_MASK)
+# define LPI2C_SCFG2_CLKHOLD(n) ((n) & LPI2C_SCFG2_CLKHOLD_MASK)
/* Bits 7-4 Reserved */
#define LPI2C_SCFG2_DATAVD_SHIFT (8)
#define LPI2C_SCFG2_DATAVD_MASK (0x3f << LPI2C_SCFG2_DATAVD_SHIFT) /* Data Valid Delay */
-# define LPI2C_SCFG2_DATAVD(n) ((n << LPI2C_SCFG2_DATAVD_SHIFT) & LPI2C_SCFG2_DATAVD_MASK)
+# define LPI2C_SCFG2_DATAVD(n) (((n) << LPI2C_SCFG2_DATAVD_SHIFT) & LPI2C_SCFG2_DATAVD_MASK)
/* Bits 15-14 Reserved */
#define LPI2C_SCFG2_FILTSCL_SHIFT (16)
#define LPI2C_SCFG2_FILTSCL_MASK (15 << LPI2C_SCFG2_FILTSCL_SHIFT) /* Glitch Filter SCL */
#define LPI2C_SCFG2_FILTSCL_DISABLE (0 << LPI2C_SCFG2_FILTSCL_SHIFT)
-# define LPI2C_SCFG2_FILTSCL_CYCLES(n) ((n << LPI2C_SCFG2_FILTSCL_SHIFT) & LPI2C_SCFG2_FILTSCL_MASK)
+# define LPI2C_SCFG2_FILTSCL_CYCLES(n) (((n) << LPI2C_SCFG2_FILTSCL_SHIFT) & LPI2C_SCFG2_FILTSCL_MASK)
/* Bits 23-20 Reserved */
#define LPI2C_SCFG2_FILTSDA_SHIFT (24)
#define LPI2C_SCFG2_FILTSDA_MASK (15 << LPI2C_SCFG2_FILTSDA_SHIFT) /* Glitch Filter SDA */
#define LPI2C_SCFG2_FILTSDA_DISABLE (0 << LPI2C_SCFG2_FILTSDA_SHIFT)
-# define LPI2C_SCFG2_FILTSDA_CYCLES(n) ((n << LPI2C_SCFG2_FILTSDA_SHIFT) & LPI2C_SCFG2_FILTSDA_MASK)
+# define LPI2C_SCFG2_FILTSDA_CYCLES(n) (((n) << LPI2C_SCFG2_FILTSDA_SHIFT) & LPI2C_SCFG2_FILTSDA_MASK)
/* Bits 31-28 Reserved */
/* LPI2C Slave Address Match Register */
@@ -514,11 +514,11 @@
/* Bit 0 Reserved */
#define LPI2C_SAMR_ADDR0_SHIFT (1)
#define LPI2C_SAMR_ADDR0_MASK (0x3ff << LPI2C_SAMR_ADDR0_SHIFT) /* Address 0 Value */
-# define LPI2C_SAMR_ADDR0(n) ((n << LPI2C_SAMR_ADDR0_SHIFT) & LPI2C_SAMR_ADDR0_MASK)
+# define LPI2C_SAMR_ADDR0(n) (((n) << LPI2C_SAMR_ADDR0_SHIFT) & LPI2C_SAMR_ADDR0_MASK)
/* Bits 16-11 Reserved */
#define LPI2C_SAMR_ADDR1_SHIFT (17)
#define LPI2C_SAMR_ADDR1_MASK (0x3ff << LPI2C_SAMR_ADDR1_SHIFT) /* Address 1 Value */
-# define LPI2C_SAMR_ADDR1(n) ((n << LPI2C_SAMR_ADDR1_SHIFT) & LPI2C_SAMR_ADDR1_MASK)
+# define LPI2C_SAMR_ADDR1(n) (((n) << LPI2C_SAMR_ADDR1_SHIFT) & LPI2C_SAMR_ADDR1_MASK)
/* Bits 31-27 Reserved */
/* LPI2C Slave Address Status Register */
@@ -538,14 +538,14 @@
#define LPI2C_STDR_DATA_SHIFT (0)
#define LPI2C_STDR_DATA_MASK (0xff << LPI2C_STDR_DATA_SHIFT) /* Transmit Data */
-# define LPI2C_STDR_DATA(n) ((n << LPI2C_STDR_DATA_SHIFT) & LPI2C_STDR_DATA_MASK)
+# define LPI2C_STDR_DATA(n) (((n) << LPI2C_STDR_DATA_SHIFT) & LPI2C_STDR_DATA_MASK)
/* Bits 31-8 Reserved */
/* LPI2C Slave Receive Data Register */
#define LPI2C_SRDR_DATA_SHIFT (0)
#define LPI2C_SRDR_DATA_MASK (0xff << LPI2C_SRDR_DATA_SHIFT) /* Receive Data */
-# define LPI2C_SRDR_DATA(n) ((n << LPI2C_SRDR_DATA_SHIFT) & LPI2C_SRDR_DATA_MASK)
+# define LPI2C_SRDR_DATA(n) (((n) << LPI2C_SRDR_DATA_SHIFT) & LPI2C_SRDR_DATA_MASK)
/* Bits 8-31 Reserved */
#endif /* __ARCH_ARM_SRC_S32K1XX_HARDWARE_S32K1XX_LPI2C_H */
diff --git a/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c b/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
index 1a900fc724..cccfa6f150 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
@@ -43,7 +43,9 @@
#include <arch/irq.h>
#include "arm_internal.h"
+#include "s32k1xx_edma.h"
#include "s32k1xx_pin.h"
+#include "hardware/s32k1xx_dmamux.h"
#include "hardware/s32k1xx_pinmux.h"
#include "s32k1xx_lpi2c.h"
#include "s32k1xx_periphclocks.h"
@@ -163,6 +165,10 @@ struct s32k1xx_lpi2c_config_s
#ifndef CONFIG_I2C_POLLED
uint32_t irq; /* Event IRQ */
#endif
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+ uint32_t dma_rxreqsrc; /* DMA mux rx source */
+ uint32_t dma_txreqsrc; /* DMA mux tx source */
+#endif
};
/* I2C Device Private Data */
@@ -202,6 +208,11 @@ struct s32k1xx_lpi2c_priv_s
struct s32k1xx_trace_s trace[CONFIG_I2C_NTRACE];
#endif
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+ DMACH_HANDLE rxdma; /* rx DMA handle */
+ DMACH_HANDLE txdma; /* tx DMA handle */
+ uint16_t cmnds[CONFIG_S32K1XX_LPI2C_DMA_MAXMSG]; /* Commands */
+#endif
uint32_t status; /* End of transfer SR2|SR1 status */
};
@@ -273,6 +284,13 @@ static int s32k1xx_lpi2c_transfer(struct i2c_master_s *dev,
static int s32k1xx_lpi2c_reset(struct i2c_master_s *dev);
#endif
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static void s32k1xx_rxdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+ int result);
+static void s32k1xx_txdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+ int result);
+#endif
+
/****************************************************************************
* Private Data
****************************************************************************/
@@ -318,6 +336,10 @@ static const struct s32k1xx_lpi2c_config_s s32k1xx_lpi2c0_config =
#ifndef CONFIG_I2C_POLLED
.irq = S32K1XX_IRQ_LPI2C0M,
#endif
+#ifdef CONFIG_LPI2C0_DMA
+ .dma_rxreqsrc = S32K1XX_DMACHAN_LPI2C0_RX,
+ .dma_txreqsrc = S32K1XX_DMACHAN_LPI2C0_TX,
+#endif
};
static struct s32k1xx_lpi2c_priv_s s32k1xx_lpi2c0_priv =
@@ -348,6 +370,10 @@ static const struct s32k1xx_lpi2c_config_s s32k1xx_lpi2c1_config =
#ifndef CONFIG_I2C_POLLED
.irq = S32K1XX_IRQ_LPI2C1M,
#endif
+#ifdef CONFIG_LPI2C1_DMA
+ .dma_rxreqsrc = S32K1XX_DMACHAN_LPI2C1_RX,
+ .dma_txreqsrc = S32K1XX_DMACHAN_LPI2C1_TX,
+#endif
};
static struct s32k1xx_lpi2c_priv_s s32k1xx_lpi2c1_priv =
@@ -478,13 +504,17 @@ s32k1xx_lpi2c_sem_waitdone(struct s32k1xx_lpi2c_priv_s *priv)
flags = enter_critical_section();
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+ if (priv->rxdma == NULL && priv->txdma == NULL)
+ {
+#endif
/* Enable Interrupts when master mode */
if (priv->config->mode == LPI2C_MASTER)
{
if ((priv->flags & I2C_M_READ) != 0)
{
- regval = LPI2C_MIER_TDIE | LPI2C_MIER_RDIE | LPI2C_MIER_NDIE | \
+ regval = LPI2C_MIER_TDIE | LPI2C_MIER_RDIE | LPI2C_MIER_NDIE |
LPI2C_MIER_ALIE | LPI2C_MIER_SDIE;
s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MIER_OFFSET, regval);
}
@@ -507,7 +537,10 @@ s32k1xx_lpi2c_sem_waitdone(struct s32k1xx_lpi2c_priv_s *priv)
* are currently disabled but will be temporarily re-enabled below when
* nxsem_tickwait_uninterruptible() sleeps.
*/
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+ }
+#endif
priv->intstate = INTSTATE_WAITING;
do
{
@@ -755,6 +788,112 @@ s32k1xx_lpi2c_sem_destroy(struct s32k1xx_lpi2c_priv_s *priv)
#endif
}
+/****************************************************************************
+ * Name: s32k1xx_rxdma_callback
+ *
+ * Description:
+ * This function performs the next I2C operation
+ *
+ ****************************************************************************/
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static void s32k1xx_rxdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+ int result)
+{
+ struct s32k1xx_lpi2c_priv_s *priv = (struct s32k1xx_lpi2c_priv_s *)arg;
+
+ s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MIER_OFFSET, 0,
+ LPI2C_MIER_SDIE);
+
+ if (result != OK)
+ {
+ priv->status = s32k1xx_lpi2c_getstatus(priv);
+
+ if ((priv->status & LPI2C_MSR_ERROR_MASK) != 0)
+ {
+ i2cerr("ERROR: MSR: status: 0x0%" PRIx32 "\n", priv->status);
+
+ s32k1xx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+
+ /* Clear the TX and RX FIFOs */
+
+ s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCR_OFFSET, 0,
+ LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+ /* Clear the error */
+
+ s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MSR_OFFSET,
+ (priv->status & (LPI2C_MSR_NDF |
+ LPI2C_MSR_ALF |
+ LPI2C_MSR_FEF |
+ LPI2C_MSR_PLTF)));
+
+ if (priv->intstate == INTSTATE_WAITING)
+ {
+ /* inform the thread that transfer is complete
+ * and wake it up
+ */
+
+ priv->intstate = INTSTATE_DONE;
+ nxsem_post(&priv->sem_isr);
+ }
+ }
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_txdma_callback
+ *
+ * Description:
+ * This function performs the next I2C operation
+ *
+ ****************************************************************************/
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static void s32k1xx_txdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+ int result)
+{
+ struct s32k1xx_lpi2c_priv_s *priv = (struct s32k1xx_lpi2c_priv_s *)arg;
+
+ s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MIER_OFFSET, 0,
+ LPI2C_MIER_SDIE);
+
+ if (result != OK)
+ {
+ priv->status = s32k1xx_lpi2c_getstatus(priv);
+
+ if ((priv->status & LPI2C_MSR_ERROR_MASK) != 0)
+ {
+ i2cerr("ERROR: MSR: status: 0x0%" PRIx32 "\n", priv->status);
+
+ s32k1xx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+
+ /* Clear the TX and RX FIFOs */
+
+ s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCR_OFFSET, 0,
+ LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+ /* Clear the error */
+
+ s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MSR_OFFSET,
+ (priv->status & (LPI2C_MSR_NDF |
+ LPI2C_MSR_ALF |
+ LPI2C_MSR_FEF |
+ LPI2C_MSR_PLTF)));
+
+ if (priv->intstate == INTSTATE_WAITING)
+ {
+ /* inform the thread that transfer is complete
+ * and wake it up
+ */
+
+ priv->intstate = INTSTATE_DONE;
+ nxsem_post(&priv->sem_isr);
+ }
+ }
+ }
+}
+#endif
+
/****************************************************************************
* Name: s32k1xx_lpi2c_trace*
*
@@ -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(struct s32k1xx_lpi2c_priv_s *priv)
+{
+ return s32k1xx_lpi2c_getreg(priv, S32K1XX_LPI2C_MIER_OFFSET);
+}
+
/****************************************************************************
* Name: s32k1xx_lpi2c_isr_process
*
@@ -1154,7 +1307,87 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
{
uint32_t status = s32k1xx_lpi2c_getstatus(priv);
- /* Check for new trace setup */
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+ uint32_t current_status = status;
+
+ /* Condition the status with only the enabled interrupts */
+
+ status &= s32k1xx_lpi2c_getenabledints(priv);
+
+ if (priv->rxdma != NULL || priv->txdma != NULL)
+ {
+ /* End of packet or Stop */
+
+ if ((status & (LPI2C_MSR_SDF | LPI2C_MSR_EPF)) != 0)
+ {
+ s32k1xx_lpi2c_traceevent(priv, I2CEVENT_STOP, 0);
+
+ /* Acknowledge End of packet or Stop */
+
+ s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MSR_OFFSET, status &
+ (LPI2C_MSR_SDF |
+ LPI2C_MSR_EPF));
+ }
+
+ /* Is there an Error condition */
+
+ if (current_status & LPI2C_MSR_ERROR_MASK)
+ {
+ s32k1xx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+
+ /* Shutdown DMA */
+
+ if (priv->rxdma != NULL)
+ {
+ s32k1xx_dmach_stop(priv->rxdma);
+ }
+
+ if (priv->txdma != NULL)
+ {
+ s32k1xx_dmach_stop(priv->txdma);
+ }
+
+ /* Clear the TX and RX FIFOs */
+
+ s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCR_OFFSET, 0,
+ LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+ /* Clear the error */
+
+ s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MSR_OFFSET,
+ (current_status & (LPI2C_MSR_NDF |
+ LPI2C_MSR_ALF |
+ LPI2C_MSR_FEF)));
+
+ /* Return the full error status */
+
+ status = current_status;
+ }
+
+ /* Mark that this transaction stopped */
+
+ priv->msgv = NULL;
+ priv->msgc = 0;
+ priv->dcnt = -1;
+
+ if (priv->intstate == INTSTATE_WAITING)
+ {
+ /* Update Status once at the end */
+
+ priv->status = status;
+
+ /* inform the thread that transfer is complete
+ * and wake it up
+ */
+
+ priv->intstate = INTSTATE_DONE;
+ nxsem_post(&priv->sem_isr);
+ }
+
+ return OK;
+ }
+
+#endif /* Check for new trace setup */
s32k1xx_lpi2c_tracenew(priv, status);
@@ -1297,8 +1530,8 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
* and wake it up
*/
- nxsem_post(&priv->sem_isr);
priv->intstate = INTSTATE_DONE;
+ nxsem_post(&priv->sem_isr);
}
#else
priv->status = status;
@@ -1350,8 +1583,8 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
* and wake it up
*/
- nxsem_post(&priv->sem_isr);
priv->intstate = INTSTATE_DONE;
+ nxsem_post(&priv->sem_isr);
}
#else
priv->status = status;
@@ -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(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(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(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(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);
+
+ /* Form chains of tcd to process the messages */
+
+ for (m = 0; m < priv->msgc; m++)
+ {
+ ncmds = 0;
+ priv->flags = priv->msgv[m].flags;
+
+ /* Form a command list */
+
+ ccmnd = &priv->cmnds[ntotcmds];
+
+ ncmds = s32k1xx_lpi2c_form_command_list(priv, &priv->msgv[m],
+ ntotcmds);
+
+ /* Have commands for this message ? */
+
+ if (ncmds != 0)
+ {
+ /* Build up a TCD with the command from this message */
+
+ s32k1xx_lpi2c_dma_command_configure(priv, ccmnd, ncmds - ntotcmds);
+
+ ntotcmds += ncmds;
+
+ DEBUGASSERT(ntotcmds < CONFIG_S32K1XX_LPI2C_DMA_MAXMSG);
+
+ s32k1xx_lpi2c_dma_data_configure(priv, &priv->msgv[m]);
+ }
+ }
+
+ s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MIER_OFFSET,
+ LPI2C_MIER_NDIE | LPI2C_MIER_ALIE |
+ LPI2C_MIER_PLTIE | LPI2C_MIER_FEIE);
+
+ s32k1xx_dmach_start(priv->rxdma, s32k1xx_rxdma_callback, (void *)priv);
+ s32k1xx_dmach_start(priv->txdma, s32k1xx_txdma_callback, (void *)priv);
+
+ s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MDER_OFFSET, 0,
+ LPI2C_MDER_TDDE | LPI2C_MDER_RDDE);
+ return OK;
+}
+#endif
+
/****************************************************************************
* Name: s32k1xx_lpi2c_transfer
*
@@ -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 != NULL)
+ {
+ s32k1xx_dmach_stop(priv->rxdma);
+ }
+
+ if (priv->txdma != NULL)
+ {
+ s32k1xx_dmach_stop(priv->txdma);
+ }
+
+#endif
ret = -ETIMEDOUT;
i2cerr("ERROR: Timed out: MCR: status: 0x%" PRIx32 "\n", priv->status);
@@ -1787,6 +2256,22 @@ struct i2c_master_s *s32k1xx_i2cbus_initialize(int port)
{
s32k1xx_lpi2c_sem_init(priv);
s32k1xx_lpi2c_init(priv);
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+ if (priv->config->dma_txreqsrc != 0)
+ {
+ priv->txdma = s32k1xx_dmach_alloc(priv->config->dma_txreqsrc |
+ DMAMUX_CHCFG_ENBL, 0);
+ DEBUGASSERT(priv->txdma != NULL);
+ }
+
+ if (priv->config->dma_rxreqsrc != 0)
+ {
+ priv->rxdma = s32k1xx_dmach_alloc(priv->config->dma_rxreqsrc |
+ DMAMUX_CHCFG_ENBL, 0);
+ DEBUGASSERT(priv->rxdma != NULL);
+ }
+#endif
}
leave_critical_section(flags);
@@ -1828,6 +2313,22 @@ int s32k1xx_i2cbus_uninitialize(struct i2c_master_s *dev)
/* Disable power and other HW resource (GPIO's) */
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+ if (priv->rxdma != NULL)
+ {
+ s32k1xx_dmach_stop(priv->rxdma);
+ s32k1xx_dmach_free(priv->rxdma);
+ priv->rxdma = NULL;
+ }
+
+ if (priv->txdma != NULL)
+ {
+ s32k1xx_dmach_stop(priv->txdma);
+ s32k1xx_dmach_free(priv->txdma);
+ priv->txdma = NULL;
+ }
+#endif
+
s32k1xx_lpi2c_deinit(priv);
/* Release unused resources */