123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- #include <stdio.h>
- #include "pico/stdlib.h"
- #include "hardware/dma.h"
- #include "hardware/adc.h"
- #include "hardware/clocks.h"
- #include "hardware/pwm.h"
- #define LED_PIN PICO_DEFAULT_LED_PIN // LED
- uint slice_num;
- #define ADC0_PIN ADC_BASE_PIN
- #define ADC1_PIN (ADC_BASE_PIN+1)
- #define ADC2_PIN (ADC_BASE_PIN+2)
- #define ADC_VREF 3.3f
- #define ADC_SAMPLE_CLKS 96
- #define SAMPLE_RATE 1000
- typedef enum {
- adc_input0,
- adc_input1,
- adc_input2,
- adc_input3,
- adc_input4,
- } _adc_input_t;
- #define RW_BUFFER_SIZE 256
- int adc_dma_ch;
- volatile static uint8_t rw_buffer[2][RW_BUFFER_SIZE];
- volatile static int write_buf_selector = 0;
- void adc_dma_irq_handler(void)
- {
- // 割り込みフラグクリア
- dma_channel_acknowledge_irq0(adc_dma_ch);
- write_buf_selector ^= 1;
- // DMA転送を再トリガー
- dma_channel_set_write_addr(adc_dma_ch, rw_buffer[write_buf_selector], false);
- dma_channel_set_trans_count(adc_dma_ch, RW_BUFFER_SIZE, true);
- }
- void pwm_irq_handler(void)
- {
- static int counter = 0;
- static int read_buf_selector = 1;
- pwm_clear_irq(slice_num);
- pwm_set_gpio_level(LED_PIN, (uint16_t)rw_buffer[read_buf_selector][counter++]);
- if(counter > RW_BUFFER_SIZE) {
- read_buf_selector = write_buf_selector ^ 1;
- counter = 0;
- }
- }
- int main()
- {
- stdio_init_all();
- float adc_div, pwm_div;
- gpio_set_function(LED_PIN, GPIO_FUNC_PWM);
- pwm_config c = pwm_get_default_config();
- pwm_div = clock_get_hz(clk_sys) / SAMPLE_RATE / RW_BUFFER_SIZE;
- pwm_config_set_clkdiv(&c, pwm_div);
- pwm_config_set_wrap(&c, RW_BUFFER_SIZE);
- slice_num = pwm_gpio_to_slice_num(LED_PIN);
- pwm_init(slice_num, &c, false);
- pwm_set_gpio_level(LED_PIN, 0xFF );
- // PWM IRQ
- pwm_clear_irq(slice_num);
- pwm_set_irq_enabled(slice_num, true);
- irq_set_exclusive_handler(PWM_DEFAULT_IRQ_NUM(), pwm_irq_handler);
- irq_set_enabled(PWM_DEFAULT_IRQ_NUM(), true);
- // ADCの設定
- adc_init();
- adc_gpio_init(ADC0_PIN);
- // ADC FIFOの設定
- adc_fifo_setup(
- true, // FIFOを有効化するならtrue
- true, // DREQを有効化するならtrue
- 1, // DREQ、IRQを発生させるFIFOエントリ数
- false, // 最上位ビットをエラーフラグにするならtrue
- true // バイトシフトするならtrue
- );
- // ADCクロック分周比
- adc_div = (float)clock_get_hz(clk_adc) / (float)ADC_SAMPLE_CLKS / SAMPLE_RATE;
- adc_set_clkdiv(adc_div);
- printf("adc_div = %f\n", adc_div);
- adc_dma_ch = dma_claim_unused_channel(true);
- dma_channel_config dma_conf = dma_channel_get_default_config(adc_dma_ch);
- channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_8);
- channel_config_set_read_increment(&dma_conf, false);
- channel_config_set_write_increment(&dma_conf, true);
- channel_config_set_dreq(&dma_conf, DREQ_ADC);
- // DMAチャネル設定
- dma_channel_configure(
- adc_dma_ch,
- &dma_conf,
- (rw_buffer[0]), // 書き込み先はRW_BUFFER
- &adc_hw->fifo, // 読み出し元はRW_BUFFER
- RW_BUFFER_SIZE, // 転送回数
- false // 開始しない
- );
- dma_channel_set_irq0_enabled(adc_dma_ch, true);
- irq_set_exclusive_handler(DMA_IRQ_0, adc_dma_irq_handler);
- irq_set_enabled(DMA_IRQ_0, true);
- dma_channel_start(adc_dma_ch);
- adc_run(true);
- pwm_set_enabled(slice_num, true);
- while (true) {
- tight_loop_contents();
- }
- }
|