drv_adc.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. * 2022-07-04 Rbb666 first version
  9. */
  10. #include "drv_config.h"
  11. #if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2)
  12. /*#define DRV_DEBUG*/
  13. #define LOG_TAG "drv.adc"
  14. #include <drv_log.h>
  15. static struct ifx_adc ifx_adc_obj[] =
  16. {
  17. #ifdef BSP_USING_ADC1
  18. ADC1_CONFIG,
  19. #endif
  20. };
  21. static rt_err_t ifx_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
  22. {
  23. cyhal_adc_channel_t *adc_ch;
  24. cy_rslt_t result;
  25. RT_ASSERT(device != RT_NULL);
  26. adc_ch = device->parent.user_data;
  27. const cyhal_adc_channel_config_t channel_config =
  28. {
  29. .enable_averaging = false, /* Disable averaging for channel*/
  30. .min_acquisition_ns = 1000, /* Minimum acquisition time set to 1us*/
  31. .enabled = enabled /* Sample this channel when ADC performs a scan*/
  32. };
  33. if (enabled)
  34. {
  35. result = cyhal_adc_init(&adc_obj, adc_gpio[channel], NULL);
  36. if (result != RT_EOK)
  37. {
  38. LOG_E("ADC initialization failed. Error: %u\n", result);
  39. return -RT_ENOSYS;
  40. }
  41. result = cyhal_adc_channel_init_diff(adc_ch, &adc_obj, adc_gpio[channel],
  42. CYHAL_ADC_VNEG, &channel_config);
  43. if (result != RT_EOK)
  44. {
  45. LOG_E("ADC single ended channel initialization failed. Error: %u\n", result);
  46. return -RT_ENOSYS;
  47. }
  48. /* Update ADC configuration */
  49. result = cyhal_adc_configure(&adc_obj, &adc_config);
  50. if (result != RT_EOK)
  51. {
  52. rt_kprintf("ADC configuration update failed. Error: %u\n", result);
  53. return -RT_ENOSYS;
  54. }
  55. }
  56. else
  57. {
  58. cyhal_adc_channel_free(adc_ch);
  59. cyhal_adc_free(&adc_obj);
  60. }
  61. return RT_EOK;
  62. }
  63. static rt_err_t ifx_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
  64. {
  65. cyhal_adc_channel_t *adc_ch;
  66. RT_ASSERT(device != RT_NULL);
  67. adc_ch = device->parent.user_data;
  68. channel = adc_ch->channel_idx;
  69. *value = cyhal_adc_read(adc_ch);
  70. return RT_EOK;
  71. }
  72. static const struct rt_adc_ops at_adc_ops =
  73. {
  74. .enabled = ifx_adc_enabled,
  75. .convert = ifx_get_adc_value,
  76. };
  77. static int rt_hw_adc_init(void)
  78. {
  79. int result = RT_EOK;
  80. int i = 0;
  81. for (i = 0; i < sizeof(ifx_adc_obj) / sizeof(ifx_adc_obj[0]); i++)
  82. {
  83. /* register ADC device */
  84. if (rt_hw_adc_register(&ifx_adc_obj[i].ifx_adc_device, ifx_adc_obj[i].name, &at_adc_ops, ifx_adc_obj[i].adc_ch) == RT_EOK)
  85. {
  86. LOG_D("%s register success", ifx_adc_obj[i].name);
  87. }
  88. else
  89. {
  90. LOG_E("%s register failed", ifx_adc_obj[i].name);
  91. result = -RT_ERROR;
  92. }
  93. }
  94. return result;
  95. }
  96. INIT_BOARD_EXPORT(rt_hw_adc_init);
  97. #endif /* BSP_USING_ADC */