drv_adc.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024/02/22 flyingcys first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "drv_adc.h"
  13. #define DBG_LEVEL DBG_LOG
  14. #include <rtdbg.h>
  15. #define LOG_TAG "DRV.ADC"
  16. struct cvi_adc_dev
  17. {
  18. struct rt_adc_device device;
  19. const char *name;
  20. rt_ubase_t base;
  21. };
  22. static struct cvi_adc_dev adc_dev_config[] =
  23. {
  24. {
  25. .name = "adc1",
  26. .base = SARADC_BASE
  27. },
  28. };
  29. static rt_err_t _adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
  30. {
  31. struct cvi_adc_dev *adc_dev = (struct cvi_adc_dev *)device->parent.user_data;
  32. uint32_t value;
  33. RT_ASSERT(adc_dev != RT_NULL);
  34. if (channel > SARADC_CH_MAX)
  35. return -RT_EINVAL;
  36. if (enabled)
  37. {
  38. //set channel
  39. cvi_set_saradc_ctrl(adc_dev->base, (rt_uint32_t)channel << (SARADC_CTRL_SEL_POS + 1));
  40. //set saradc clock cycle
  41. cvi_set_cyc(adc_dev->base);
  42. //start
  43. cvi_set_saradc_ctrl(adc_dev->base, SARADC_CTRL_START);
  44. LOG_D("enable saradc...");
  45. }
  46. else
  47. {
  48. cvi_reset_saradc_ctrl(adc_dev->base, (rt_uint32_t)channel << (SARADC_CTRL_SEL_POS + 1));
  49. LOG_D("disable saradc...");
  50. }
  51. return RT_EOK;
  52. }
  53. static rt_err_t _adc_convert(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
  54. {
  55. struct cvi_adc_dev *adc_dev = (struct cvi_adc_dev *)device->parent.user_data;
  56. rt_uint32_t result;
  57. rt_uint32_t cnt = 0;
  58. RT_ASSERT(adc_dev != RT_NULL);
  59. if (channel > SARADC_CH_MAX)
  60. return -RT_EINVAL;
  61. while (cvi_get_saradc_status(adc_dev->base) & SARADC_STATUS_BUSY)
  62. {
  63. rt_thread_delay(10);
  64. LOG_D("wait saradc ready");
  65. cnt ++;
  66. if (cnt > 100)
  67. return -RT_ETIMEOUT;
  68. }
  69. result = mmio_read_32(adc_dev->base + SARADC_RESULT(channel - 1));
  70. if (result & SARADC_RESULT_VALID)
  71. {
  72. *value = result & SARADC_RESULT_MASK;
  73. LOG_D("saradc channel %d value: %04x", channel, *value);
  74. }
  75. else
  76. {
  77. LOG_E("saradc channel %d read failed. result:0x%04x", channel, result);
  78. return -RT_ERROR;
  79. }
  80. return RT_EOK;
  81. }
  82. static const struct rt_adc_ops _adc_ops =
  83. {
  84. .enabled = _adc_enabled,
  85. .convert = _adc_convert,
  86. };
  87. int rt_hw_adc_init(void)
  88. {
  89. rt_uint8_t i;
  90. for (i = 0; i < sizeof(adc_dev_config) / sizeof(adc_dev_config[0]); i ++)
  91. {
  92. if (rt_hw_adc_register(&adc_dev_config[i].device, adc_dev_config[i].name, &_adc_ops, &adc_dev_config[i]) != RT_EOK)
  93. {
  94. LOG_E("%s register failed!", adc_dev_config[i].name);
  95. return -RT_ERROR;
  96. }
  97. }
  98. return RT_EOK;
  99. }
  100. INIT_BOARD_EXPORT(rt_hw_adc_init);