drv_adc.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. * 2021-09-27 fzxhub the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "board.h"
  13. #include "drv_adc.h"
  14. #ifdef RT_USING_ADC
  15. #ifdef BSP_USING_ADC
  16. struct lpc_adc
  17. {
  18. LPC_ADC_TypeDef *ADC;
  19. };
  20. /*
  21. * channel:0-7
  22. */
  23. static rt_err_t lpc_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
  24. {
  25. struct lpc_adc *adc;
  26. RT_ASSERT(device != RT_NULL);
  27. adc = (struct lpc_adc *)device->parent.user_data;
  28. //enabled ADC
  29. if(enabled == RT_FALSE) adc->ADC->CR &= ~(1<<21);
  30. else adc->ADC->CR |= (1<<21);
  31. //Select the channel
  32. adc->ADC->CR |= (1<<channel);
  33. return RT_EOK;
  34. }
  35. static rt_err_t lpc_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
  36. {
  37. rt_uint32_t data;
  38. struct lpc_adc *adc;
  39. RT_ASSERT(device != RT_NULL);
  40. adc = (struct lpc_adc *)device->parent.user_data;
  41. adc->ADC->CR = (LPC_ADC->CR & 0x00FFFF00) | (1<<channel) | (1 << 24);
  42. while ((adc->ADC->GDR & 0x80000000) == 0);
  43. adc->ADC->CR = adc->ADC->CR | (1 << 24);
  44. while ((adc->ADC->GDR & 0x80000000) == 0);
  45. data = adc->ADC->GDR;
  46. data = (data >> 4) & 0xFFF;
  47. *value = data;
  48. return RT_EOK;
  49. }
  50. static const struct rt_adc_ops lpc_adc_ops =
  51. {
  52. lpc_adc_enabled,
  53. lpc_adc_convert,
  54. };
  55. struct lpc_adc lpc_adc0 =
  56. {
  57. LPC_ADC,
  58. };
  59. struct rt_adc_device adc0;
  60. int rt_hw_adc_init(void)
  61. {
  62. rt_err_t ret = RT_EOK;
  63. struct lpc_adc *adc;
  64. adc = &lpc_adc0;
  65. adc0.ops = &lpc_adc_ops;
  66. adc0.parent.user_data = adc;
  67. //ADC port
  68. LPC_IOCON->P0_23 = 0x01; //ADC0[0]
  69. LPC_IOCON->P0_24 = 0x01; //ADC0[1]
  70. LPC_IOCON->P0_25 = 0x01; //ADC0[2]
  71. LPC_IOCON->P0_26 = 0x01; //ADC0[3]
  72. LPC_IOCON->P1_30 = 0x03; //ADC0[4]
  73. LPC_IOCON->P1_31 = 0x03; //ADC0[5]
  74. LPC_IOCON->P0_12 = 0x03; //ADC0[6]
  75. LPC_IOCON->P0_13 = 0x03; //ADC0[7]
  76. //clock
  77. LPC_SC->PCONP |= (1U << 12);
  78. //config
  79. LPC_ADC->CR = 0;
  80. LPC_ADC->CR = (1 << 0)| // SEL
  81. ((PeripheralClock / 1000000 - 1) << 8) | // CLKDIV = Fpclk / 1000000 - 1
  82. (0 << 16)| // BURST
  83. (0 << 17)| // CLKS
  84. (1 << 21)| // PDN
  85. (0 << 22)| // TEST1
  86. (1 << 24)| // START
  87. (0 << 27); // EDGE
  88. //waiting
  89. while ((LPC_ADC->GDR & 0x80000000) == 0);
  90. ret = rt_hw_adc_register(&adc0,"adc0",&lpc_adc_ops,adc);
  91. return ret;
  92. }
  93. INIT_BOARD_EXPORT(rt_hw_adc_init);
  94. #endif /* BSP_USING_ADC */
  95. #endif /* RT_USING_ADC */