/** * Copyright 2022 Colin Lam, Ploopy Corporation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * SPECIAL THANKS TO: * @miketeachman (github.com/miketeachman) * @jimmo (github.com/jimmo) * @dlech (github.com/dlech) * for their exceptional work on the I2S library for the rp2 port of the * Micropython project (github.com/micropython/micropython). */ #ifndef I2S_H #define I2S_H #include "pico/stdlib.h" #include "hardware/pio.h" #include "ringbuf.h" #define SAMPLES_PER_FRAME 2 #define PIO_INSTRUCTIONS_PER_BIT 2 #define RINGBUF_LEN_IN_BYTES 16384 #define I2S_NUM_DMA_CHANNELS 2 #define SIZEOF_DMA_BUFFER_IN_BYTES 768 #define SIZEOF_HALF_DMA_BUFFER_IN_BYTES (SIZEOF_DMA_BUFFER_IN_BYTES / 2) typedef enum { GP_INPUT = 0, GP_OUTPUT = 1 } gpio_dir_t; typedef struct _i2s_obj_t { uint sck_pin; uint ws_pin; uint sd_pin; PIO pio; uint8_t sm; float sampling_rate; const pio_program_t *pio_program; uint prog_offset; int dma_channel[I2S_NUM_DMA_CHANNELS]; uint8_t dma_buffer[SIZEOF_DMA_BUFFER_IN_BYTES]; ring_buf_t ring_buffer; } i2s_obj_t; extern i2s_obj_t i2s_write_obj; void i2s_write_init(i2s_obj_t *); uint i2s_stream_write(i2s_obj_t *, const uint8_t *, uint); void dma_irq_handler(uint8_t); void dma_irq_write_handler(void); void gpio_init_i2s(PIO, uint8_t, uint, uint8_t, gpio_dir_t); void dma_configure(i2s_obj_t *); uint8_t *dma_get_buffer(i2s_obj_t *, uint); void feed_dma(i2s_obj_t *, uint8_t *); uint32_t copy_userbuf_to_ringbuf(i2s_obj_t *, const uint8_t *, uint); #endif