Forráskód Böngészése

[bsp] frdm-mcxn947 增加dac驱动 (#8667)

ShaquilleLiu 1 éve
szülő
commit
99dafb1fef

+ 3 - 0
bsp/nxp/mcx/mcxn/Libraries/drivers/SConscript

@@ -25,6 +25,9 @@ if  GetDepend('BSP_USING_I2C'):
 if  GetDepend('BSP_USING_ADC'):
     src += ['drv_adc.c']
 
+if  GetDepend('BSP_USING_DAC'):
+    src += ['drv_dac.c']
+
 if  GetDepend('BSP_USING_HWTIMER'):
     src += ['drv_hwtimer.c']
 

+ 154 - 0
bsp/nxp/mcx/mcxn/Libraries/drivers/drv_dac.c

@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2024-03-24     Oxlm         first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "fsl_dac.h"
+#include "fsl_dac14.h"
+
+#ifdef RT_USING_DAC
+
+// #define DRV_DEBUG
+#define DBG_TAG "drv.dac"
+#ifdef DRV_DEBUG
+#define DBG_LVL DBG_LOG
+#else
+#define DBG_LVL DBG_INFO
+#endif /* DRV_DEBUG */
+#include <rtdbg.h>
+
+struct mcx_dac {
+  struct rt_dac_device mcxn_dac_device;
+  LPDAC_Type *dac_base;
+  clock_attach_id_t clock_attach_id;
+  clock_div_name_t clock_div_name;
+  uint8_t clock_div;
+  uint8_t referenceVoltageSource; /* kDAC_ReferenceVoltageSourceAlt1, VREFH reference pin */
+  uint8_t SOC_CNTRL_BIT;
+  char *name;
+};
+
+static struct mcx_dac mcx_dac_obj[] = {
+#ifdef BSP_USING_DAC0
+    {
+        .dac_base               = DAC0,
+        .clock_attach_id        = kFRO_HF_to_DAC0,
+        .clock_div_name         = kCLOCK_DivDac0Clk,
+        .clock_div              = 1u,
+        .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1,
+        .SOC_CNTRL_BIT          = 4,
+        .name                   = "dac0",
+    },
+#endif
+#ifdef BSP_USING_DAC1
+    {
+        .dac_base               = DAC1,
+        .clock_attach_id        = kFRO_HF_to_DAC1,
+        .clock_div_name         = kCLOCK_DivDac1Clk,
+        .clock_div              = 1u,
+        .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1,
+        .SOC_CNTRL_BIT          = 5,
+        .name                   = "dac1",
+    },
+#endif
+#ifdef BSP_USING_DAC2
+    {
+        .dac_base               = DAC2,
+        .clock_attach_id        = kFRO_HF_to_DAC2,
+        .clock_div_name         = kCLOCK_DivDac2Clk,
+        .clock_div              = 1u,
+        .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1,
+        .SOC_CNTRL_BIT          = 6,
+        .name                   = "dac2",
+    },
+#endif
+
+};
+
+rt_err_t mcxn_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel) {
+  RT_ASSERT(device != RT_NULL);
+  struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data;
+
+  if (dac->dac_base == DAC2) {
+    DAC14_Deinit(dac->dac_base);
+  } else {
+    DAC_Deinit(dac->dac_base);
+  }
+  return RT_EOK;
+}
+
+rt_err_t mcxn_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel) {
+  RT_ASSERT(device != RT_NULL);
+  struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data;
+  dac_config_t dacConfigStruct;
+  dac14_config_t dac14ConfigStruct;
+
+  if (dac->dac_base == DAC2) {
+    DAC14_GetDefaultConfig(&dac14ConfigStruct);
+    dac14ConfigStruct.enableOpampBuffer = true;
+    dac14ConfigStruct.enableDAC         = true;
+    DAC14_Init(dac->dac_base, &dac14ConfigStruct);
+  } else {
+    DAC_GetDefaultConfig(&dacConfigStruct);
+    dacConfigStruct.referenceVoltageSource = dac->referenceVoltageSource;
+    DAC_Init(dac->dac_base, &dacConfigStruct);
+    DAC_Enable(dac->dac_base, RT_TRUE);
+  }
+
+  return RT_EOK;
+}
+
+rt_err_t mcxn_dac_write(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value) {
+  RT_ASSERT(device != RT_NULL);
+  struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data;
+
+  if (dac->dac_base == DAC2) {
+    if (*value > 0x3FFFU) {
+      *value = 0x3FFFU;
+    }
+    DAC14_SetData(dac->dac_base, *value);
+  } else {
+    if (*value > 0xFFFU) {
+      *value = 0xFFFU;
+    }
+    DAC_SetData(dac->dac_base, *value);
+  }
+  return RT_EOK;
+}
+
+struct rt_dac_ops mcxn_dac_ops = {
+    .disabled = mcxn_dac_disabled,
+    .enabled  = mcxn_dac_enabled,
+    .convert  = mcxn_dac_write,
+};
+
+static int mcxn_dac_init(void) {
+  int i;
+  int dac_num = sizeof(mcx_dac_obj) / sizeof(struct mcx_dac);
+
+  for (i = 0; i < dac_num; i++) {
+    CLOCK_SetClkDiv(mcx_dac_obj[i].clock_div_name, mcx_dac_obj[i].clock_div);
+    CLOCK_AttachClk(mcx_dac_obj[i].clock_attach_id);
+
+    SPC0->ACTIVE_CFG1 |= 0x01;  // Enable VREF
+    SPC0->ACTIVE_CFG1 |= (0x01 << mcx_dac_obj[i].SOC_CNTRL_BIT);
+
+    if (RT_EOK != rt_hw_dac_register(&mcx_dac_obj[i].mcxn_dac_device, mcx_dac_obj[i].name, &mcxn_dac_ops,
+                                     (void *)(mcx_dac_obj + i))) {
+      LOG_E("%s register failed", mcx_dac_obj[i].name);
+      return -RT_ERROR;
+    }
+  }
+
+  return RT_EOK;
+}
+INIT_DEVICE_EXPORT(mcxn_dac_init);
+
+#endif

+ 21 - 0
bsp/nxp/mcx/mcxn/frdm-mcxn947/board/Kconfig

@@ -107,6 +107,27 @@ menu "On-chip Peripheral Drivers"
 
             endif
 
+    menuconfig BSP_USING_DAC
+        config BSP_USING_DAC
+            bool "Enable DAC Channel"
+            select RT_USING_DAC
+            default y
+
+            if BSP_USING_DAC
+                config BSP_USING_DAC0
+                    bool "Enable DAC0 Channel"
+                    default n
+
+                config BSP_USING_DAC1
+                    bool "Enable DAC1 Channel"
+                    default n
+
+                config BSP_USING_DAC2
+                    bool "Enable DAC2 Channel"
+                    default n
+
+            endif
+
     config BSP_USING_SDIO
         bool "Enable SDIO SD Card Interface"
         select RT_USING_SDIO

+ 4 - 0
bsp/nxp/mcx/mcxn/frdm-mcxn947/board/MCUX_Config/board/pin_mux.c

@@ -32,6 +32,10 @@ void BOARD_InitBootPins(void)
     PORT1->PCR[16]  = PORT_PCR_MUX(2) | PORT_PCR_PS(0) | PORT_PCR_PE(1) | PORT_PCR_IBE(1);     /* FC5_UART */
     PORT1->PCR[17]  = PORT_PCR_MUX(2) | PORT_PCR_PS(0) | PORT_PCR_PE(1) | PORT_PCR_IBE(1);     /* FC5_UART */
 
+    /* DAC */
+    // PORT4->PCR[2] = PORT_PCR_MUX(0) | PORT_PCR_PS(0) | PORT_PCR_PE(0) | PORT_PCR_IBE(0); /* DAC0 */
+    // PORT4->PCR[3] = PORT_PCR_MUX(0) | PORT_PCR_PS(0) | PORT_PCR_PE(0) | PORT_PCR_IBE(0); /* DAC1 */
+
     /* MCX_RST UART */
     PORT4->PCR[2]  = PORT_PCR_MUX(2) | PORT_PCR_PS(0) | PORT_PCR_PE(1) | PORT_PCR_IBE(1);     /* FC2_UART */
     PORT4->PCR[3]  = PORT_PCR_MUX(2) | PORT_PCR_PS(0) | PORT_PCR_PE(1) | PORT_PCR_IBE(1);     /* FC2_UART */