#include #include "pico/stdlib.h" #include "hardware/dma.h" #include "hardware/pwm.h" #include "hardware/clocks.h" #define AUDIO_OUT_PIN 2 __asm(\ ".section \".rodata\" \n" ".balign 4\n" ".global _audio_data\n" ".global _audio_data_len\n" "_audio_data:\n" ".incbin \"test12.raw\"\n" ".set _audio_data_len, . - _audio_data\n" ".section \".text\"\n" ); extern const uint8_t _audio_data[]; extern uint32_t _audio_data_len[]; uint slice_num = 0; int dma_ch = 0; int main() { stdio_init_all(); printf("audio_data_len = %d\n", _audio_data_len); // サンプリング周波数の都合でシステムクロックを // 125MHzに切り替える set_sys_clock_khz(125000, true); // PWM出力ピン gpio_set_function(AUDIO_OUT_PIN, GPIO_FUNC_PWM); // スライス番号 slice_num = pwm_gpio_to_slice_num(AUDIO_OUT_PIN); // PWMの設定 pwm_config pwm_conf = pwm_get_default_config(); pwm_config_set_wrap(&pwm_conf, 4095); // PWM周波数15.259kHz pwm_config_set_clkdiv(&pwm_conf, 2.0f); // 62.5MHz pwm_init(slice_num, &pwm_conf, false); // DMAの設定 dma_ch = dma_claim_unused_channel(true); dma_channel_config dma_conf = dma_channel_get_default_config(dma_ch); // 粒度は16bit中の下位12bit channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_16); // 送り出しはメモリ channel_config_set_read_increment(&dma_conf, true); // 受け側はDMAのCCレジスタ channel_config_set_write_increment(&dma_conf, false); // DREQを設定 channel_config_set_dreq(&dma_conf, pwm_get_dreq(slice_num)); // DMAチャネル設定 dma_channel_configure( dma_ch, &dma_conf, (uint16_t *)&pwm_hw->slice[slice_num].cc+2, // 書き込み先はCCレジスタ (uint8_t *)_audio_data, // 読み出し元は12bitオーディオデータ (uint)_audio_data_len, // 転送回数 false // 開始しない ); // PWMを開始 pwm_set_enabled(slice_num, true); // DMA転送を開始 dma_channel_start(dma_ch); // DMAが完了するのを待つ dma_channel_wait_for_finish_blocking(dma_ch); // 再生終了 pwm_set_enabled(slice_num, false); while (true) { tight_loop_contents(); } }