@@ -27,6 +27,8 @@ | |||
#include "analyze_tonedetect.h" | |||
#include "utility/dspinst.h" | |||
#if defined(KINETISK) | |||
static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) __attribute__((always_inline)); | |||
static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) | |||
{ | |||
@@ -148,11 +150,21 @@ AudioAnalyzeToneDetect::operator bool() | |||
trigger = (uint32_t)len * thresh; | |||
trigger = multiply_32x32_rshift32(trigger, trigger); | |||
Serial.printf("bool: power=%d, trig=%d\n", power, trigger); | |||
//Serial.printf("bool: power=%d, trig=%d\n", power, trigger); | |||
return (power >= trigger); | |||
// TODO: this should really remember if it's retuned true previously, | |||
// so it can give a single true response each time a tone is seen. | |||
} | |||
#elif defined(KINETISL) | |||
void AudioAnalyzeToneDetect::update(void) | |||
{ | |||
audio_block_t *block; | |||
block = receiveReadOnly(); | |||
if (block) release(block); | |||
} | |||
#endif | |||
@@ -28,6 +28,7 @@ | |||
void AudioEffectMultiply::update(void) | |||
{ | |||
#if defined(KINETISK) | |||
audio_block_t *blocka, *blockb; | |||
uint32_t *pa, *pb, *end; | |||
uint32_t a12, a34; //, a56, a78; | |||
@@ -75,5 +76,14 @@ void AudioEffectMultiply::update(void) | |||
transmit(blocka); | |||
release(blocka); | |||
release(blockb); | |||
#elif defined(KINETISL) | |||
audio_block_t *block; | |||
block = receiveReadOnly(0); | |||
if (block) release(block); | |||
block = receiveReadOnly(1); | |||
if (block) release(block); | |||
#endif | |||
} | |||
@@ -27,6 +27,8 @@ | |||
#include "filter_biquad.h" | |||
#include "utility/dspinst.h" | |||
#if defined(KINETISK) | |||
void AudioFilterBiquad::update(void) | |||
{ | |||
audio_block_t *block; | |||
@@ -63,7 +65,7 @@ void AudioFilterBiquad::update(void) | |||
sum = signed_multiply_accumulate_32x16b(sum, a1, out2); | |||
sum = signed_multiply_accumulate_32x16t(sum, a2, aprev); | |||
bprev = in2; | |||
aprev = pack_16x16( | |||
aprev = pack_16b_16b( | |||
signed_saturate_rshift(sum, 16, 14), out2); | |||
sum &= 0x3FFF; | |||
bprev = in2; | |||
@@ -94,3 +96,15 @@ void AudioFilterBiquad::setCoefficients(uint32_t stage, const int *coefficients) | |||
*dest &= 0x80000000; | |||
__enable_irq(); | |||
} | |||
#elif defined(KINETISL) | |||
void AudioFilterBiquad::update(void) | |||
{ | |||
audio_block_t *block; | |||
block = receiveReadOnly(); | |||
if (block) release(block); | |||
} | |||
#endif |
@@ -45,6 +45,8 @@ | |||
// no audible difference. | |||
//#define IMPROVE_EXPONENTIAL_ACCURACY | |||
#if defined(KINETISK) | |||
void AudioFilterStateVariable::update_fixed(const int16_t *in, | |||
int16_t *lp, int16_t *bp, int16_t *hp) | |||
{ | |||
@@ -221,3 +223,17 @@ void AudioFilterStateVariable::update(void) | |||
return; | |||
} | |||
#elif defined(KINETISL) | |||
void AudioFilterStateVariable::update(void) | |||
{ | |||
audio_block_t *block; | |||
block = receiveReadOnly(0); | |||
if (block) release(block); | |||
block = receiveReadOnly(1); | |||
if (block) release(block); | |||
} | |||
#endif | |||
@@ -46,7 +46,7 @@ void AudioInputI2S::begin(void) | |||
AudioOutputI2S::config_i2s(); | |||
CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 | |||
#if defined(KINETISK) | |||
dma.TCD->SADDR = &I2S0_RDR0; | |||
dma.TCD->SOFF = 0; | |||
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | |||
@@ -58,7 +58,7 @@ void AudioInputI2S::begin(void) | |||
dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer); | |||
dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2; | |||
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | |||
#endif | |||
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX); | |||
update_responsibility = update_setup(); | |||
dma.enable(); | |||
@@ -76,7 +76,9 @@ void AudioInputI2S::isr(void) | |||
audio_block_t *left, *right; | |||
//digitalWriteFast(3, HIGH); | |||
#if defined(KINETISK) | |||
daddr = (uint32_t)(dma.TCD->DADDR); | |||
#endif | |||
dma.clearInterrupt(); | |||
if (daddr < (uint32_t)i2s_rx_buffer + sizeof(i2s_rx_buffer) / 2) { | |||
@@ -179,7 +181,7 @@ void AudioInputI2Sslave::begin(void) | |||
AudioOutputI2Sslave::config_i2s(); | |||
CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 | |||
#if defined(KINETISK) | |||
dma.TCD->SADDR = &I2S0_RDR0; | |||
dma.TCD->SOFF = 0; | |||
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | |||
@@ -191,7 +193,7 @@ void AudioInputI2Sslave::begin(void) | |||
dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer); | |||
dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2; | |||
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | |||
#endif | |||
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX); | |||
update_responsibility = update_setup(); | |||
dma.enable(); |
@@ -38,6 +38,8 @@ DMAChannel AudioOutputPWM::dma(false); | |||
// TODO: this code assumes F_BUS is 48 MHz. | |||
// supporting other speeds is not easy, but should be done someday | |||
#if defined(KINETISK) | |||
void AudioOutputPWM::begin(void) | |||
{ | |||
dma.begin(true); // Allocate the DMA channel first | |||
@@ -188,5 +190,13 @@ void AudioOutputPWM::isr(void) | |||
// biter = sizeof(buffer) / 8 (no minor loop linking) | |||
#elif defined(KINETISL) | |||
void AudioOutputPWM::update(void) | |||
{ | |||
audio_block_t *block; | |||
block = receiveReadOnly(); | |||
if (block) release(block); | |||
} | |||
#endif |
@@ -25,6 +25,8 @@ | |||
#include "output_spdif.h" | |||
#if defined(KINETISK) | |||
#define PREAMBLE_B (0xE8) //11101000 | |||
#define PREAMBLE_M (0xE2) //11100010 | |||
#define PREAMBLE_W (0xE4) //11100100 | |||
@@ -356,3 +358,18 @@ void AudioOutputSPDIF::config_SPDIF(void) | |||
// CORE_PIN11_CONFIG = PORT_PCR_MUX(6); // pin 11, PTC6, I2S0_MCLK | |||
#endif | |||
} | |||
#elif defined(KINETISL) | |||
void AudioOutputSPDIF::update(void) | |||
{ | |||
audio_block_t *block; | |||
block = receiveReadOnly(0); // input 0 = left channel | |||
if (block) release(block); | |||
block = receiveReadOnly(1); // input 1 = right channel | |||
if (block) release(block); | |||
} | |||
#endif |
@@ -51,8 +51,11 @@ void AudioSynthWaveformSine::update(void) | |||
scale = (ph >> 8) & 0xFFFF; | |||
val2 *= scale; | |||
val1 *= 0xFFFF - scale; | |||
//block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16; | |||
#if defined(KINETISK) | |||
block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude); | |||
#elif defined(KINETISL) | |||
block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16; | |||
#endif | |||
ph += inc; | |||
} | |||
phase_accumulator = ph; | |||
@@ -65,6 +68,8 @@ void AudioSynthWaveformSine::update(void) | |||
} | |||
#if defined(KINETISK) | |||
void AudioSynthWaveformSineModulated::update(void) | |||
{ | |||
audio_block_t *block, *modinput; | |||
@@ -127,4 +132,15 @@ void AudioSynthWaveformSineModulated::update(void) | |||
release(block); | |||
} | |||
#elif defined(KINETISL) | |||
void AudioSynthWaveformSineModulated::update(void) | |||
{ | |||
audio_block_t *block; | |||
block = receiveReadOnly(); | |||
if (block) release(block); | |||
} | |||
#endif | |||
@@ -44,6 +44,7 @@ void AudioSynthNoiseWhite::update(void) | |||
end = p + AUDIO_BLOCK_SAMPLES/2; | |||
lo = seed; | |||
do { | |||
#if defined(KINETISK) | |||
hi = multiply_16bx16t(16807, lo); // 16807 * (lo >> 16) | |||
lo = 16807 * (lo & 0xFFFF); | |||
lo += (hi & 0x7FFF) << 16; | |||
@@ -72,6 +73,22 @@ void AudioSynthNoiseWhite::update(void) | |||
val2 = pack_16b_16b(n2, n1); | |||
*p++ = val1; | |||
*p++ = val2; | |||
#elif defined(KINETISL) | |||
hi = 16807 * (lo >> 16); | |||
lo = 16807 * (lo & 0xFFFF); | |||
lo += (hi & 0x7FFF) << 16; | |||
lo += hi >> 15; | |||
lo = (lo & 0x7FFFFFFF) + (lo >> 31); | |||
n1 = signed_multiply_32x16b(gain, lo); | |||
hi = 16807 * (lo >> 16); | |||
lo = 16807 * (lo & 0xFFFF); | |||
lo += (hi & 0x7FFF) << 16; | |||
lo += hi >> 15; | |||
lo = (lo & 0x7FFFFFFF) + (lo >> 31); | |||
n2 = signed_multiply_32x16b(gain, lo); | |||
val1 = pack_16b_16b(n2, n1); | |||
*p++ = val1; | |||
#endif | |||
} while (p < end); | |||
seed = lo; | |||
transmit(block); |