diff --git a/ports/psoc6/machine_i2s.c b/ports/psoc6/machine_i2s.c index c2bcd036a9cad..98d37f1c9b272 100644 --- a/ports/psoc6/machine_i2s.c +++ b/ports/psoc6/machine_i2s.c @@ -172,60 +172,41 @@ static inline bool i2s_dma_is_rx_complete(cyhal_i2s_event_t event) { return 0u != (event & CYHAL_I2S_ASYNC_RX_COMPLETE); } -// static inline void i2s_dma_rx(machine_i2s_obj_t *self) { -// cy_rslt_t result = cyhal_i2s_read_async(&self->i2s_obj, self->dma_buffer + self->dma_active_half_index, SIZEOF_HALF_DMA_BUFFER_IN_BYTES); -// i2s_assert_raise_val("I2S DMA read failed with return code %lx !", result); -// } +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); + 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); i2s_assert_raise_val("I2S DMA write configure failed with return code %lx !", result); } -// static inline void i2s_dma_swap_active_dmabuf(machine_i2s_obj_t *self) { -// uint8_t active_half_index = self->dma_active_half_index; -// if (active_half_index == 0) { -// self->dma_active_half_index = SIZEOF_HALF_DMA_BUFFER_IN_BYTES; -// } else if (active_half_index == SIZEOF_HALF_DMA_BUFFER_IN_BYTES) { -// self->dma_active_half_index = 0; -// } -// } - -// static inline uint8_t *i2s_get_dma_idle_buffer(machine_i2s_obj_t *self) { -// if (self->dma_active_half_index == 0) { -// return &(self->dma_buffer[SIZEOF_HALF_DMA_BUFFER_IN_BYTES]); -// } else if (self->dma_active_half_index == SIZEOF_HALF_DMA_BUFFER_IN_BYTES) { -// return &(self->dma_buffer[0]); -// } else { -// return 0; // should never get here. -// } -// } - -// static void i2s_dma_from_dmabuf_to_ringbuf(machine_i2s_obj_t *self) { - -// // TODO: convert to format of 8 bytes dma to comply with extmod -// // little-endian but consider the channel width in bits, and the word bits (sample resolution) - -// uint8_t dma_sample_size_in_bytes = (self->bits == 16? 2 : 4) * (self->format == STEREO ? 2: 1); -// uint8_t *dma_buff_p = i2s_get_dma_idle_buffer(self); -// uint32_t num_bytes_needed_from_ringbuf = SIZEOF_HALF_DMA_BUFFER_IN_BYTES * (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 (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) { -// ringbuf_push(&self->ring_buffer, dma_buff_p[j]); -// } else { // r_a_mapping == -1 -// ringbuf_push(&self->ring_buffer, 0); -// } -// } -// dma_buff_p += dma_sample_size_in_bytes; -// } -// } -// } +static void i2s_dma_from_dmabuf_to_ringbuf(machine_i2s_obj_t *self) { + + // TODO: convert to format of 8 bytes dma to comply with extmod + // little-endian but consider the channel width in bits, and the word bits (sample resolution) + + 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); + + // 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 (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) { + ringbuf_push(&self->ring_buffer, dma_buff_p[j]); + } else { // r_a_mapping == -1 + ringbuf_push(&self->ring_buffer, 0); + } + } + dma_buff_p += dma_sample_size_in_bytes; + } + } +} 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) { @@ -278,30 +259,17 @@ static void i2s_dma_tx_event_process(machine_i2s_obj_t *self, cyhal_i2s_event_t } } -// static void i2s_dma_tx_event_process(machine_i2s_obj_t *self, cyhal_i2s_event_t event) { -// if (i2s_dma_is_tx_complete(event)) { -// if ((self->io_mode == NON_BLOCKING) && (self->non_blocking_descriptor.copy_in_progress)) { -// copy_appbuf_to_ringbuf_non_blocking(self); -// } - -// i2s_dma_swap_active_dmabuf(self); -// i2s_dma_tx(self); -// i2s_dma_from_ringbuf_to_dmabuf(self); -// } -// } - -// static void i2s_dma_rx_event_process(machine_i2s_obj_t *self, cyhal_i2s_event_t event) { -// if (i2s_dma_is_rx_complete(event)) { -// i2s_dma_swap_active_dmabuf(self); -// i2s_dma_rx(self); -// i2s_dma_from_dmabuf_to_ringbuf(self); - -// if ((self->io_mode == NON_BLOCKING) && (self->non_blocking_descriptor.copy_in_progress)) { -// fill_appbuf_from_ringbuf_non_blocking(self); -// } -// } -// } +static void i2s_dma_rx_event_process(machine_i2s_obj_t *self, cyhal_i2s_event_t event) { + if (i2s_dma_is_rx_complete(event)) { + i2s_dma_swap_active_dmabuf(self); + i2s_dma_rx(self); + i2s_dma_from_dmabuf_to_ringbuf(self); + if ((self->io_mode == NON_BLOCKING) && (self->non_blocking_descriptor.copy_in_progress)) { + fill_appbuf_from_ringbuf_non_blocking(self); + } + } +} static void i2s_dma_irq_handler(void *arg, cyhal_i2s_event_t event) { machine_i2s_obj_t *self = (machine_i2s_obj_t *)arg; @@ -310,7 +278,7 @@ static void i2s_dma_irq_handler(void *arg, cyhal_i2s_event_t event) { if (self->mode == TX) { i2s_dma_event_process_func = i2s_dma_tx_event_process; } else if (self->mode == RX) { - // i2s_dma_event_process_func = i2s_dma_rx_event_process; + i2s_dma_event_process_func = i2s_dma_rx_event_process; } i2s_dma_event_process_func(self, event); @@ -356,8 +324,6 @@ static void i2s_dma_irq_configure(machine_i2s_obj_t *self) { } static void i2s_dma_rx_init(machine_i2s_obj_t *self) { - // self->dma_active_half_index = 0; // Initially use the first half of the buffer - cy_rslt_t result = cyhal_i2s_read_async(&self->i2s_obj, self->dma_active_buf_p, SIZEOF_HALF_DMA_BUFFER_IN_BYTES); i2s_assert_raise_val("I2S DMA read configure failed with return code %lx !", result);