void AudioOutputI2S2::isr(void) { int16_t *dest, *dc; audio_block_t *blockL, *blockR; uint32_t saddr, offsetL, offsetR; saddr = (uint32_t)(dma.TCD->SADDR); dma.clearInterrupt(); if (saddr < (uint32_t)i2s2_tx_buffer + sizeof(i2s2_tx_buffer) / 2) { // DMA is transmitting the first half of the buffer // so we must fill the second half dest = (int16_t *)&i2s2_tx_buffer[AUDIO_BLOCK_SAMPLES/2]; if (AudioOutputI2S2::update_responsibility) AudioStream::update_all(); } else { // DMA is transmitting the second half of the buffer // so we must fill the first half dest = (int16_t *)i2s2_tx_buffer; } blockL = AudioOutputI2S2::block_left_1st; blockR = AudioOutputI2S2::block_right_1st; offsetL = AudioOutputI2S2::block_left_offset; offsetR = AudioOutputI2S2::block_right_offset; if (blockL && blockR) { memcpy_tointerleaveLR(dest, blockL->data + offsetL, blockR->data + offsetR); offsetL += AUDIO_BLOCK_SAMPLES / 2; offsetR += AUDIO_BLOCK_SAMPLES / 2; } else if (blockL) { memcpy_tointerleaveL(dest, blockL->data + offsetL); offsetL += AUDIO_BLOCK_SAMPLES / 2; } else if (blockR) { memcpy_tointerleaveR(dest, blockR->data + offsetR); offsetR += AUDIO_BLOCK_SAMPLES / 2; } else { memset(dest,0,AUDIO_BLOCK_SAMPLES * 2); } #if IMXRT_CACHE_ENABLED >= 2 arm_dcache_flush_delete(dest, sizeof(i2s2_tx_buffer) / 2 ); #endif if (offsetL < AUDIO_BLOCK_SAMPLES) { AudioOutputI2S2::block_left_offset = offsetL; } else { AudioOutputI2S2::block_left_offset = 0; AudioStream::release(blockL); AudioOutputI2S2::block_left_1st = AudioOutputI2S2::block_left_2nd; AudioOutputI2S2::block_left_2nd = NULL; } if (offsetR < AUDIO_BLOCK_SAMPLES) { AudioOutputI2S2::block_right_offset = offsetR; } else { AudioOutputI2S2::block_right_offset = 0; AudioStream::release(blockR); AudioOutputI2S2::block_right_1st = AudioOutputI2S2::block_right_2nd; AudioOutputI2S2::block_right_2nd = NULL; } }
void AudioOutputI2S::isr(void) { #if defined(KINETISK) int16_t *dest; audio_block_t *blockL, *blockR; uint32_t saddr, offsetL, offsetR; saddr = (uint32_t)(dma.TCD->SADDR); dma.clearInterrupt(); if (saddr < (uint32_t)i2s_tx_buffer + sizeof(i2s_tx_buffer) / 2) { // DMA is transmitting the first half of the buffer // so we must fill the second half dest = (int16_t *)&i2s_tx_buffer[AUDIO_BLOCK_SAMPLES/2]; if (AudioOutputI2S::update_responsibility) AudioStream::update_all(); } else { // DMA is transmitting the second half of the buffer // so we must fill the first half dest = (int16_t *)i2s_tx_buffer; } blockL = AudioOutputI2S::block_left_1st; blockR = AudioOutputI2S::block_right_1st; offsetL = AudioOutputI2S::block_left_offset; offsetR = AudioOutputI2S::block_right_offset; if (blockL && blockR) { memcpy_tointerleaveLR(dest, blockL->data + offsetL, blockR->data + offsetR); offsetL += AUDIO_BLOCK_SAMPLES / 2; offsetR += AUDIO_BLOCK_SAMPLES / 2; } else if (blockL) { memcpy_tointerleaveL(dest, blockL->data + offsetL); offsetL += AUDIO_BLOCK_SAMPLES / 2; } else if (blockR) { memcpy_tointerleaveR(dest, blockR->data + offsetR); offsetR += AUDIO_BLOCK_SAMPLES / 2; } else { memset(dest,0,AUDIO_BLOCK_SAMPLES * 2); return; } if (offsetL < AUDIO_BLOCK_SAMPLES) { AudioOutputI2S::block_left_offset = offsetL; } else { AudioOutputI2S::block_left_offset = 0; AudioStream::release(blockL); AudioOutputI2S::block_left_1st = AudioOutputI2S::block_left_2nd; AudioOutputI2S::block_left_2nd = NULL; } if (offsetR < AUDIO_BLOCK_SAMPLES) { AudioOutputI2S::block_right_offset = offsetR; } else { AudioOutputI2S::block_right_offset = 0; AudioStream::release(blockR); AudioOutputI2S::block_right_1st = AudioOutputI2S::block_right_2nd; AudioOutputI2S::block_right_2nd = NULL; } #else const int16_t *src, *end; int16_t *dest; audio_block_t *block; uint32_t saddr, offset; saddr = (uint32_t)(dma.CFG->SAR); dma.clearInterrupt(); if (saddr < (uint32_t)i2s_tx_buffer + sizeof(i2s_tx_buffer) / 2) { // DMA is transmitting the first half of the buffer // so we must fill the second half dest = (int16_t *)&i2s_tx_buffer[AUDIO_BLOCK_SAMPLES/2]; end = (int16_t *)&i2s_tx_buffer[AUDIO_BLOCK_SAMPLES]; if (AudioOutputI2S::update_responsibility) AudioStream::update_all(); } else { // DMA is transmitting the second half of the buffer // so we must fill the first half dest = (int16_t *)i2s_tx_buffer; end = (int16_t *)&i2s_tx_buffer[AUDIO_BLOCK_SAMPLES/2]; } block = AudioOutputI2S::block_left_1st; if (block) { offset = AudioOutputI2S::block_left_offset; src = &block->data[offset]; do { *dest = *src++; dest += 2; } while (dest < end); offset += AUDIO_BLOCK_SAMPLES/2; if (offset < AUDIO_BLOCK_SAMPLES) { AudioOutputI2S::block_left_offset = offset; } else { AudioOutputI2S::block_left_offset = 0; AudioStream::release(block); AudioOutputI2S::block_left_1st = AudioOutputI2S::block_left_2nd; AudioOutputI2S::block_left_2nd = NULL; } } else { do { *dest = 0; dest += 2; } while (dest < end); } dest -= AUDIO_BLOCK_SAMPLES - 1; block = AudioOutputI2S::block_right_1st; if (block) { offset = AudioOutputI2S::block_right_offset; src = &block->data[offset]; do { *dest = *src++; dest += 2; } while (dest < end); offset += AUDIO_BLOCK_SAMPLES/2; if (offset < AUDIO_BLOCK_SAMPLES) { AudioOutputI2S::block_right_offset = offset; } else { AudioOutputI2S::block_right_offset = 0; AudioStream::release(block); AudioOutputI2S::block_right_1st = AudioOutputI2S::block_right_2nd; AudioOutputI2S::block_right_2nd = NULL; } } else { do { *dest = 0; dest += 2; } while (dest < end); } #endif }