diff --git a/ports/psoc6/machine_i2s.c b/ports/psoc6/machine_i2s.c index 98d37f1c9b272..a0947202d9fe3 100644 --- a/ports/psoc6/machine_i2s.c +++ b/ports/psoc6/machine_i2s.c @@ -31,13 +31,14 @@ cyhal_clock_t hf0_clock; // 1. memory use (smaller buffer size desirable to reduce memory footprint) // 2. interrupt frequency (larger buffer size desirable to reduce interrupt frequency) // The sizeof 1/2 of the DMA buffer must be evenly divisible by the cache line size of 32 bytes. -#define SIZEOF_DMA_BUFFER_IN_BYTES (256) -#define SIZEOF_HALF_DMA_BUFFER_IN_BYTES (SIZEOF_DMA_BUFFER_IN_BYTES / 2) +#define SIZEOF_DMA_BUFFER (256) +#define SIZEOF_HALF_DMA_BUFFER (SIZEOF_DMA_BUFFER / 2) +#define SIZEOF_HALF_DMA_BUFFER_IN_BYTES (SIZEOF_HALF_DMA_BUFFER * sizeof(uint32_t)) // TODO: For non-blocking mode, to avoid underflow/overflow, sample data is written/read to/from the ring buffer at a rate faster // than the DMA transfer rate #define NON_BLOCKING_RATE_MULTIPLIER (4) -#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER_IN_BYTES * NON_BLOCKING_RATE_MULTIPLIER) +#define SIZEOF_NON_BLOCKING_COPY_IN_BYTES (SIZEOF_HALF_DMA_BUFFER * NON_BLOCKING_RATE_MULTIPLIER) typedef enum { RX, @@ -60,7 +61,7 @@ typedef struct _machine_i2s_obj_t { int32_t ibuf; mp_obj_t callback_for_non_blocking; io_mode_t io_mode; - uint32_t dma_buffer[SIZEOF_DMA_BUFFER_IN_BYTES]; + uint32_t dma_buffer[SIZEOF_DMA_BUFFER]; uint32_t *dma_active_buf_p; uint32_t *dma_idle_buf_p; ring_buf_t ring_buffer; @@ -173,12 +174,12 @@ static inline bool i2s_dma_is_rx_complete(cyhal_i2s_event_t event) { } static inline void i2s_dma_rx(machine_i2s_obj_t *self) { - cy_rslt_t result = cyhal_i2s_read_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER_IN_BYTES); + cy_rslt_t result = cyhal_i2s_read_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER); i2s_assert_raise_val("I2S DMA read failed with return code %lx !", result); } static inline void i2s_dma_tx(machine_i2s_obj_t *self) { - cy_rslt_t result = cyhal_i2s_write_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER_IN_BYTES); + cy_rslt_t result = cyhal_i2s_write_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER); i2s_assert_raise_val("I2S DMA write configure failed with return code %lx !", result); } @@ -189,12 +190,12 @@ static void i2s_dma_from_dmabuf_to_ringbuf(machine_i2s_obj_t *self) { uint8_t dma_sample_size_in_bytes = (self->bits == 16? 2 : 4) * (self->format == STEREO ? 2: 1); uint8_t *dma_buff_p = (uint8_t *)self->dma_idle_buf_p; - uint32_t num_bytes_needed_from_ringbuf = SIZEOF_HALF_DMA_BUFFER_IN_BYTES * (I2S_RX_FRAME_SIZE_IN_BYTES / dma_sample_size_in_bytes); + uint32_t num_bytes_needed_from_ringbuf = SIZEOF_HALF_DMA_BUFFER * (I2S_RX_FRAME_SIZE_IN_BYTES / dma_sample_size_in_bytes); // when space exists, copy samples into ring buffer if (ringbuf_available_space(&self->ring_buffer) >= num_bytes_needed_from_ringbuf) { uint8_t f_index = get_frame_mapping_index(self->bits, self->format); - for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES; i += dma_sample_size_in_bytes) { + for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER; i += dma_sample_size_in_bytes) { for (uint8_t j = 0; I2S_RX_FRAME_SIZE_IN_BYTES; j++) { int8_t r_to_a_mapping = i2s_frame_map[f_index][i]; if (r_to_a_mapping != -1) { @@ -212,24 +213,24 @@ static void i2s_dma_from_ringbuf_to_dmabuf(machine_i2s_obj_t *self) { if (ringbuf_available_data(&self->ring_buffer) >= SIZEOF_HALF_DMA_BUFFER_IN_BYTES) { uint8_t *dma_buffer_p = (uint8_t *)self->dma_idle_buf_p; // Mono samples duplicate the sample in the right channel - if (self->mode == MONO) { - uint8_t bytes_per_sample = (self->bits == 16? 2 : 4); - for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES * sizeof(uint32_t); i += (2 * bytes_per_sample)) { - for (uint8_t b = 0; b < bytes_per_sample; b++) { - ringbuf_pop(&self->ring_buffer, &dma_buffer_p[i + b]); - dma_buffer_p[i + b + 2 * bytes_per_sample] = dma_buffer_p[i + b]; - } - } - } else if (self->mode == STEREO) { - for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES * sizeof(uint32_t); i++) { - ringbuf_pop(&self->ring_buffer, &dma_buffer_p[i]); - } + // if (self->mode == MONO) { + // uint8_t bytes_per_sample = (self->bits == 16? 2 : 4); + // for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER * sizeof(uint32_t); i += (2 * bytes_per_sample)) { + // for (uint8_t b = 0; b < bytes_per_sample; b++) { + // ringbuf_pop(&self->ring_buffer, &dma_buffer_p[i + b]); + // dma_buffer_p[i + b + 2 * bytes_per_sample] = dma_buffer_p[i + b]; + // } + // } + // } else if (self->mode == STEREO) { + for (uint32_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES; i++) { + ringbuf_pop(&self->ring_buffer, &dma_buffer_p[i]); } + // } } } static void fill_app_buffer(machine_i2s_obj_t *self) { - for (uint16_t i = 0; i < SIZEOF_HALF_DMA_BUFFER_IN_BYTES; i++) + for (uint16_t i = 0; i < SIZEOF_HALF_DMA_BUFFER; i++) { // uint32_t value = i | (i + 1) << 8 | (i + 2) << 16 | (i + 3) << 24; // self->dma_idle_buf_p[i] = value; @@ -324,7 +325,7 @@ static void i2s_dma_irq_configure(machine_i2s_obj_t *self) { } static void i2s_dma_rx_init(machine_i2s_obj_t *self) { - cy_rslt_t result = cyhal_i2s_read_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER_IN_BYTES); + cy_rslt_t result = cyhal_i2s_read_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER); i2s_assert_raise_val("I2S DMA read configure failed with return code %lx !", result); result = cyhal_i2s_start_rx(&self->i2s_obj); @@ -332,7 +333,7 @@ static void i2s_dma_rx_init(machine_i2s_obj_t *self) { } static void i2s_dma_tx_init(machine_i2s_obj_t *self) { - cy_rslt_t result = cyhal_i2s_write_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER_IN_BYTES); + cy_rslt_t result = cyhal_i2s_write_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER); i2s_assert_raise_val("I2S DMA write configure failed with return code %lx !", result); result = cyhal_i2s_start_tx(&self->i2s_obj); @@ -341,7 +342,7 @@ static void i2s_dma_tx_init(machine_i2s_obj_t *self) { static inline void i2s_dma_init_buff(machine_i2s_obj_t *self) { self->dma_active_buf_p = self->dma_buffer; - self->dma_idle_buf_p = &self->dma_buffer[SIZEOF_HALF_DMA_BUFFER_IN_BYTES]; + self->dma_idle_buf_p = &self->dma_buffer[SIZEOF_HALF_DMA_BUFFER]; } static void i2s_dma_init(machine_i2s_obj_t *self) { @@ -424,6 +425,7 @@ static void mp_machine_i2s_init_helper(machine_i2s_obj_t *self, mp_arg_val_t *ar self->callback_for_non_blocking = MP_OBJ_NULL; self->io_mode = BLOCKING; + // // i2s_clock_configure(); //Need to be in synch with user configurable clocks if (clock_set == 0) { clock_init(); cyhal_system_delay_ms(1); @@ -432,8 +434,6 @@ static void mp_machine_i2s_init_helper(machine_i2s_obj_t *self, mp_arg_val_t *ar // // TODO: with all inputs validated make the objects of the i2s object. // // TODO: then make the i2s object - // // i2s_clock_configure(); - i2s_init(self, &audio_clock); i2s_dma_irq_configure(self); i2s_dma_init(self);