#ifndef _ADC_DRIVER_HPP_ #define _ADC_DRIVER_HPP_ 1 #include "hardware/adc.h" #include "hardware/irq.h" #include "pico/multicore.h" #include "hardware/clocks.h" #include "adrs2040U_i2c.h" #define ADC_BUFF_SIZE 0x100 // MUTEX auto_init_mutex(adcbuff_mutex); static volatile int read_p; static volatile int write_p; static volatile uint16_t adc_buffer[ADC_BUFF_SIZE]; static void adc_interrupt(void) { while(! adc_fifo_is_empty()) { mutex_enter_blocking(&adcbuff_mutex); adc_buffer[write_p] = adc_fifo_get() & 0xFFF; write_p = (write_p + 1) & (ADC_BUFF_SIZE - 1); mutex_exit(&adcbuff_mutex); } }; class ADC_Driver { private: int sample_rate = 1000; // サンプリングレート uint32_t adc_clk; // ADCクロック uint8_t adc_pin; // 使用するADCピン番号 uint8_t adc_channel; // ADCチャンネル番号 public: ADC_Driver(uint8_t p = 26, uint8_t c = 0) : adc_pin(p), adc_channel(c) { read_p = write_p = 0; sample_rate = 1000; adc_init(); adc_gpio_init(adc_pin); adc_select_input(adc_channel); adc_fifo_setup(true, false, 1, true, false); // ADCサンプリングクロック設定 adc_clk = clock_get_hz(clk_adc); adc_set_clkdiv(adc_clk/sample_rate); // ADC割り込み irq_set_exclusive_handler(ADC_IRQ_FIFO, adc_interrupt); irq_set_enabled(ADC_IRQ_FIFO, true); run(false); }; int get_sample_rate(void) { return sample_rate; }; void set_sample_rate(int rate) { sample_rate = rate; adc_set_clkdiv(adc_clk/sample_rate); }; bool is_empty(void) { return (read_p == write_p); }; int get_value(void) { int wp, rv; mutex_enter_blocking(&adcbuff_mutex); wp = write_p; if(read_p != wp) { rv = adc_buffer[read_p]; read_p = (read_p + 1) & (ADC_BUFF_SIZE - 1); } else rv = -1; mutex_exit(&adcbuff_mutex); return rv; }; uint8_t count(void) { uint8_t r; mutex_enter_blocking(&adcbuff_mutex); r = write_p - read_p; mutex_exit(&adcbuff_mutex); return r; } void run(bool r) { adc_irq_set_enabled(r); adc_run(r); if(r == false) { read_p = write_p = 0; } }; }; #endif