12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- #include <stdio.h>
- #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();
- }
- }
|