adc_driver.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include "hardware/adc.h"
  2. #include "hardware/irq.h"
  3. #include "pico/multicore.h"
  4. #include "hardware/clocks.h"
  5. #include "adrs2040U_i2c.h"
  6. #define ADC_BUFF_SIZE 0x100
  7. // MUTEX
  8. auto_init_mutex(adcbuff_mutex);
  9. static volatile int read_p;
  10. static volatile int write_p;
  11. static volatile uint16_t adc_buffer[ADC_BUFF_SIZE];
  12. static void adc_interrupt(void)
  13. {
  14. while(! adc_fifo_is_empty()) {
  15. mutex_enter_blocking(&adcbuff_mutex);
  16. adc_buffer[write_p] = adc_fifo_get() & 0xFFF;
  17. write_p = (write_p + 1) & (ADC_BUFF_SIZE - 1);
  18. mutex_exit(&adcbuff_mutex);
  19. }
  20. };
  21. class ADC_Driver {
  22. private:
  23. int sample_rate = 1000; // サンプリングレート
  24. uint32_t adc_clk; // ADCクロック
  25. uint8_t adc_pin; // 使用するADCピン番号
  26. uint8_t adc_channel; // ADCチャンネル番号
  27. public:
  28. ADC_Driver(uint8_t p = 26, uint8_t c = 0) : adc_pin(p), adc_channel(c)
  29. {
  30. read_p = write_p = 0;
  31. sample_rate = 1000;
  32. adc_init();
  33. adc_gpio_init(adc_pin);
  34. adc_select_input(adc_channel);
  35. adc_fifo_setup(true, false, 1, true, false);
  36. // ADCサンプリングクロック設定
  37. adc_clk = clock_get_hz(clk_adc);
  38. adc_set_clkdiv(adc_clk/sample_rate);
  39. // ADC割り込み
  40. irq_set_exclusive_handler(ADC_IRQ_FIFO, adc_interrupt);
  41. irq_set_enabled(ADC_IRQ_FIFO, true);
  42. run(false);
  43. };
  44. int get_sample_rate(void)
  45. {
  46. return sample_rate;
  47. };
  48. void set_sample_rate(int rate)
  49. {
  50. sample_rate = rate;
  51. adc_set_clkdiv(adc_clk/sample_rate);
  52. };
  53. bool is_empty(void)
  54. {
  55. return (read_p == write_p);
  56. };
  57. int get_value(void)
  58. {
  59. int wp, rv;
  60. mutex_enter_blocking(&adcbuff_mutex);
  61. wp = write_p;
  62. if(read_p != wp) {
  63. rv = adc_buffer[read_p];
  64. read_p = (read_p + 1) & (ADC_BUFF_SIZE - 1);
  65. }
  66. else
  67. rv = -1;
  68. mutex_exit(&adcbuff_mutex);
  69. return rv;
  70. };
  71. uint8_t count(void)
  72. {
  73. uint8_t r;
  74. mutex_enter_blocking(&adcbuff_mutex);
  75. r = write_p - read_p;
  76. mutex_exit(&adcbuff_mutex);
  77. return r;
  78. }
  79. void run(bool r)
  80. {
  81. adc_irq_set_enabled(r);
  82. adc_run(r);
  83. if(r == false) {
  84. read_p = write_p = 0;
  85. }
  86. };
  87. };