drv_dac.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-03-24 Oxlm first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "fsl_dac.h"
  13. #include "fsl_dac14.h"
  14. #ifdef RT_USING_DAC
  15. // #define DRV_DEBUG
  16. #define DBG_TAG "drv.dac"
  17. #ifdef DRV_DEBUG
  18. #define DBG_LVL DBG_LOG
  19. #else
  20. #define DBG_LVL DBG_INFO
  21. #endif /* DRV_DEBUG */
  22. #include <rtdbg.h>
  23. struct mcx_dac {
  24. struct rt_dac_device mcxn_dac_device;
  25. LPDAC_Type *dac_base;
  26. clock_attach_id_t clock_attach_id;
  27. clock_div_name_t clock_div_name;
  28. uint8_t clock_div;
  29. uint8_t referenceVoltageSource; /* kDAC_ReferenceVoltageSourceAlt1, VREFH reference pin */
  30. uint8_t SOC_CNTRL_BIT;
  31. char *name;
  32. };
  33. static struct mcx_dac mcx_dac_obj[] = {
  34. #ifdef BSP_USING_DAC0
  35. {
  36. .dac_base = DAC0,
  37. .clock_attach_id = kFRO_HF_to_DAC0,
  38. .clock_div_name = kCLOCK_DivDac0Clk,
  39. .clock_div = 1u,
  40. .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1,
  41. .SOC_CNTRL_BIT = 4,
  42. .name = "dac0",
  43. },
  44. #endif
  45. #ifdef BSP_USING_DAC1
  46. {
  47. .dac_base = DAC1,
  48. .clock_attach_id = kFRO_HF_to_DAC1,
  49. .clock_div_name = kCLOCK_DivDac1Clk,
  50. .clock_div = 1u,
  51. .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1,
  52. .SOC_CNTRL_BIT = 5,
  53. .name = "dac1",
  54. },
  55. #endif
  56. #ifdef BSP_USING_DAC2
  57. {
  58. .dac_base = DAC2,
  59. .clock_attach_id = kFRO_HF_to_DAC2,
  60. .clock_div_name = kCLOCK_DivDac2Clk,
  61. .clock_div = 1u,
  62. .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1,
  63. .SOC_CNTRL_BIT = 6,
  64. .name = "dac2",
  65. },
  66. #endif
  67. };
  68. rt_err_t mcxn_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel) {
  69. RT_ASSERT(device != RT_NULL);
  70. struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data;
  71. if (dac->dac_base == DAC2) {
  72. DAC14_Deinit(dac->dac_base);
  73. } else {
  74. DAC_Deinit(dac->dac_base);
  75. }
  76. return RT_EOK;
  77. }
  78. rt_err_t mcxn_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel) {
  79. RT_ASSERT(device != RT_NULL);
  80. struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data;
  81. dac_config_t dacConfigStruct;
  82. dac14_config_t dac14ConfigStruct;
  83. if (dac->dac_base == DAC2) {
  84. DAC14_GetDefaultConfig(&dac14ConfigStruct);
  85. dac14ConfigStruct.enableOpampBuffer = true;
  86. dac14ConfigStruct.enableDAC = true;
  87. DAC14_Init(dac->dac_base, &dac14ConfigStruct);
  88. } else {
  89. DAC_GetDefaultConfig(&dacConfigStruct);
  90. dacConfigStruct.referenceVoltageSource = dac->referenceVoltageSource;
  91. DAC_Init(dac->dac_base, &dacConfigStruct);
  92. DAC_Enable(dac->dac_base, RT_TRUE);
  93. }
  94. return RT_EOK;
  95. }
  96. rt_err_t mcxn_dac_write(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value) {
  97. RT_ASSERT(device != RT_NULL);
  98. struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data;
  99. if (dac->dac_base == DAC2) {
  100. if (*value > 0x3FFFU) {
  101. *value = 0x3FFFU;
  102. }
  103. DAC14_SetData(dac->dac_base, *value);
  104. } else {
  105. if (*value > 0xFFFU) {
  106. *value = 0xFFFU;
  107. }
  108. DAC_SetData(dac->dac_base, *value);
  109. }
  110. return RT_EOK;
  111. }
  112. struct rt_dac_ops mcxn_dac_ops = {
  113. .disabled = mcxn_dac_disabled,
  114. .enabled = mcxn_dac_enabled,
  115. .convert = mcxn_dac_write,
  116. };
  117. static int mcxn_dac_init(void) {
  118. int i;
  119. int dac_num = sizeof(mcx_dac_obj) / sizeof(struct mcx_dac);
  120. for (i = 0; i < dac_num; i++) {
  121. CLOCK_SetClkDiv(mcx_dac_obj[i].clock_div_name, mcx_dac_obj[i].clock_div);
  122. CLOCK_AttachClk(mcx_dac_obj[i].clock_attach_id);
  123. SPC0->ACTIVE_CFG1 |= 0x01; // Enable VREF
  124. SPC0->ACTIVE_CFG1 |= (0x01 << mcx_dac_obj[i].SOC_CNTRL_BIT);
  125. if (RT_EOK != rt_hw_dac_register(&mcx_dac_obj[i].mcxn_dac_device, mcx_dac_obj[i].name, &mcxn_dac_ops,
  126. (void *)(mcx_dac_obj + i))) {
  127. LOG_E("%s register failed", mcx_dac_obj[i].name);
  128. return -RT_ERROR;
  129. }
  130. }
  131. return RT_EOK;
  132. }
  133. INIT_DEVICE_EXPORT(mcxn_dac_init);
  134. #endif