Browse Source

Fix some Teensy-LC compiler errors

dds
PaulStoffregen 9 years ago
parent
commit
14fd8f907b
6 changed files with 108 additions and 11 deletions
  1. +4
    -0
      analyze_fft1024.cpp
  2. +6
    -1
      input_adc.cpp
  3. +40
    -8
      mixer.cpp
  4. +18
    -0
      mixer.h
  5. +6
    -2
      output_i2s.cpp
  6. +34
    -0
      utility/dspinst.h

+ 4
- 0
analyze_fft1024.cpp View File

@@ -61,6 +61,7 @@ void AudioAnalyzeFFT1024::update(void)
block = receiveReadOnly();
if (!block) return;

#if defined(KINETISK)
switch (state) {
case 0:
blocklist[0] = block;
@@ -122,6 +123,9 @@ void AudioAnalyzeFFT1024::update(void)
state = 4;
break;
}
#else
release(block);
#endif
}



+ 6
- 1
input_adc.cpp View File

@@ -53,6 +53,7 @@ void AudioInputAnalog::init(uint8_t pin)
dc_average = sum >> 10;

// set the programmable delay block to trigger the ADC at 44.1 kHz
#if defined(KINETISK)
if (!(SIM_SCGC6 & SIM_SCGC6_PDB)
|| (PDB0_SC & PDB_CONFIG) != PDB_CONFIG
|| PDB0_MOD != PDB_PERIOD
@@ -65,12 +66,13 @@ void AudioInputAnalog::init(uint8_t pin)
PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG;
PDB0_CH0C1 = 0x0101;
}
#endif
// enable the ADC for hardware trigger and DMA
ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN;

// set up a DMA channel to store the ADC data
dma.begin(true);
#if defined(KINETISK)
dma.TCD->SADDR = &ADC0_RA;
dma.TCD->SOFF = 0;
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
@@ -82,6 +84,7 @@ void AudioInputAnalog::init(uint8_t pin)
dma.TCD->DLASTSGA = -sizeof(analog_rx_buffer);
dma.TCD->BITER_ELINKNO = sizeof(analog_rx_buffer) / 2;
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
#endif
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC0);
update_responsibility = update_setup();
dma.enable();
@@ -96,7 +99,9 @@ void AudioInputAnalog::isr(void)
uint16_t *dest_left;
audio_block_t *left;

#if defined(KINETISK)
daddr = (uint32_t)(dma.TCD->DADDR);
#endif
dma.clearInterrupt();

if (daddr < (uint32_t)analog_rx_buffer + sizeof(analog_rx_buffer) / 2) {

+ 40
- 8
mixer.cpp View File

@@ -27,7 +27,10 @@
#include "mixer.h"
#include "utility/dspinst.h"

void applyGain(int16_t *data, int32_t mult)
#if defined(KINETISK)
#define MULTI_UNITYGAIN 65536

static void applyGain(int16_t *data, int32_t mult)
{
uint32_t *p = (uint32_t *)data;
const uint32_t *end = (uint32_t *)(data + AUDIO_BLOCK_SAMPLES);
@@ -38,19 +41,17 @@ void applyGain(int16_t *data, int32_t mult)
int32_t val2 = signed_multiply_32x16t(mult, tmp32);
val1 = signed_saturate_rshift(val1, 16, 0);
val2 = signed_saturate_rshift(val2, 16, 0);
*p++ = pack_16x16(val2, val1);
*p++ = pack_16b_16b(val2, val1);
} while (p < end);
}

// page 133

void applyGainThenAdd(int16_t *data, const int16_t *in, int32_t mult)
static void applyGainThenAdd(int16_t *data, const int16_t *in, int32_t mult)
{
uint32_t *dst = (uint32_t *)data;
const uint32_t *src = (uint32_t *)in;
const uint32_t *end = (uint32_t *)(data + AUDIO_BLOCK_SAMPLES);

if (mult == 65536) {
if (mult == MULTI_UNITYGAIN) {
do {
uint32_t tmp32 = *dst;
*dst++ = signed_add_16_and_16(tmp32, *src++);
@@ -64,13 +65,44 @@ void applyGainThenAdd(int16_t *data, const int16_t *in, int32_t mult)
int32_t val2 = signed_multiply_32x16t(mult, tmp32);
val1 = signed_saturate_rshift(val1, 16, 0);
val2 = signed_saturate_rshift(val2, 16, 0);
tmp32 = pack_16x16(val2, val1);
tmp32 = pack_16b_16b(val2, val1);
uint32_t tmp32b = *dst;
*dst++ = signed_add_16_and_16(tmp32, tmp32b);
} while (dst < end);
}
}

#elif defined(KINETISL)
#define MULTI_UNITYGAIN 256

static void applyGain(int16_t *data, int32_t mult)
{
const int16_t *end = data + AUDIO_BLOCK_SAMPLES;

do {
int32_t val = *data * mult;
*data++ = signed_saturate_rshift(val, 16, 0);
} while (data < end);
}

static void applyGainThenAdd(int16_t *dst, const int16_t *src, int32_t mult)
{
const int16_t *end = dst + AUDIO_BLOCK_SAMPLES;

if (mult == MULTI_UNITYGAIN) {
do {
int32_t val = *dst + *src++;
*dst++ = signed_saturate_rshift(val, 16, 0);
} while (dst < end);
} else {
do {
int32_t val = *dst + ((*src++ * mult) >> 8); // overflow possible??
*dst++ = signed_saturate_rshift(val, 16, 0);
} while (dst < end);
}
}

#endif

void AudioMixer4::update(void)
{
@@ -82,7 +114,7 @@ void AudioMixer4::update(void)
out = receiveWritable(channel);
if (out) {
int32_t mult = multiplier[channel];
if (mult != 65536) applyGain(out->data, mult);
if (mult != MULTI_UNITYGAIN) applyGain(out->data, mult);
}
} else {
in = receiveReadOnly(channel);

+ 18
- 0
mixer.h View File

@@ -31,6 +31,7 @@

class AudioMixer4 : public AudioStream
{
#if defined(KINETISK)
public:
AudioMixer4(void) : AudioStream(4, inputQueueArray) {
for (int i=0; i<4; i++) multiplier[i] = 65536;
@@ -45,6 +46,23 @@ public:
private:
int32_t multiplier[4];
audio_block_t *inputQueueArray[4];

#elif defined(KINETISL)
public:
AudioMixer4(void) : AudioStream(4, inputQueueArray) {
for (int i=0; i<4; i++) multiplier[i] = 256;
}
virtual void update(void);
void gain(unsigned int channel, float gain) {
if (channel >= 4) return;
if (gain > 127.0f) gain = 127.0f;
else if (gain < 0.0f) gain = 0.0f;
multiplier[channel] = gain * 256.0f; // TODO: proper roundoff?
}
private:
int16_t multiplier[4];
audio_block_t *inputQueueArray[4];
#endif
};

#endif

+ 6
- 2
output_i2s.cpp View File

@@ -47,6 +47,7 @@ void AudioOutputI2S::begin(void)
config_i2s();
CORE_PIN22_CONFIG = PORT_PCR_MUX(6); // pin 22, PTC1, I2S0_TXD0

#if defined(KINETISK)
dma.TCD->SADDR = i2s_tx_buffer;
dma.TCD->SOFF = 2;
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
@@ -58,6 +59,7 @@ void AudioOutputI2S::begin(void)
dma.TCD->DLASTSGA = 0;
dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
#endif
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX);
update_responsibility = update_setup();
dma.enable();
@@ -74,7 +76,9 @@ void AudioOutputI2S::isr(void)
audio_block_t *block;
uint32_t saddr, offset;

#if defined(KINETISK)
saddr = (uint32_t)(dma.TCD->SADDR);
#endif
dma.clearInterrupt();
if (saddr < (uint32_t)i2s_tx_buffer + sizeof(i2s_tx_buffer) / 2) {
// DMA is transmitting the first half of the buffer
@@ -276,7 +280,7 @@ void AudioOutputI2Sslave::begin(void)

AudioOutputI2Sslave::config_i2s();
CORE_PIN22_CONFIG = PORT_PCR_MUX(6); // pin 22, PTC1, I2S0_TXD0
#if defined(KINETISK)
dma.TCD->SADDR = i2s_tx_buffer;
dma.TCD->SOFF = 2;
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
@@ -288,7 +292,7 @@ void AudioOutputI2Sslave::begin(void)
dma.TCD->DLASTSGA = 0;
dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
#endif
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX);
update_responsibility = update_setup();
dma.enable();

+ 34
- 0
utility/dspinst.h View File

@@ -33,27 +33,47 @@
static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift) __attribute__((always_inline, unused));
static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift)
{
#if defined(KINETISK)
int32_t out;
asm volatile("ssat %0, %1, %2, asr %3" : "=r" (out) : "I" (bits), "r" (val), "I" (rshift));
return out;
#elif defined(KINETISL)
int32_t out, max;
out = val >> rshift;
max = 1 << (bits - 1);
if (out >= 0) {
if (out > max - 1) out = max - 1;
} else {
if (out < -max) out = -max;
}
return out;
#endif
}

// computes ((a[31:0] * b[15:0]) >> 16)
static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b)
{
#if defined(KINETISK)
int32_t out;
asm volatile("smulwb %0, %1, %2" : "=r" (out) : "r" (a), "r" (b));
return out;
#elif defined(KINETISL)
return ((int64_t)a * (int16_t)(b & 0xFFFF)) >> 16;
#endif
}

// computes ((a[31:0] * b[31:16]) >> 16)
static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b) __attribute__((always_inline, unused));
static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b)
{
#if defined(KINETISK)
int32_t out;
asm volatile("smulwt %0, %1, %2" : "=r" (out) : "r" (a), "r" (b));
return out;
#elif defined(KINETISL)
return ((int64_t)a * (int16_t)(b >> 16)) >> 16;
#endif
}

// computes (((int64_t)a[31:0] * (int64_t)b[31:0]) >> 32)
@@ -97,30 +117,43 @@ static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int3
static inline uint32_t pack_16t_16t(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline uint32_t pack_16t_16t(int32_t a, int32_t b)
{
#if defined(KINETISK)
int32_t out;
asm volatile("pkhtb %0, %1, %2, asr #16" : "=r" (out) : "r" (a), "r" (b));
return out;
#elif defined(KINETISL)
return (a & 0xFFFF0000) | ((uint32_t)b >> 16);
#endif
}

// computes (a[31:16] | b[15:0])
static inline uint32_t pack_16t_16b(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline uint32_t pack_16t_16b(int32_t a, int32_t b)
{
#if defined(KINETISK)
int32_t out;
asm volatile("pkhtb %0, %1, %2" : "=r" (out) : "r" (a), "r" (b));
return out;
#elif defined(KINETISL)
return (a & 0xFFFF0000) | (b & 0x0000FFFF);
#endif
}

// computes ((a[15:0] << 16) | b[15:0])
static inline uint32_t pack_16b_16b(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline uint32_t pack_16b_16b(int32_t a, int32_t b)
{
#if defined(KINETISK)
int32_t out;
asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r" (out) : "r" (b), "r" (a));
return out;
#elif defined(KINETISL)
return (a << 16) | (b & 0x0000FFFF);
#endif
}

// computes ((a[15:0] << 16) | b[15:0])
/*
static inline uint32_t pack_16x16(int32_t a, int32_t b) __attribute__((always_inline, unused));
static inline uint32_t pack_16x16(int32_t a, int32_t b)
{
@@ -128,6 +161,7 @@ static inline uint32_t pack_16x16(int32_t a, int32_t b)
asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r" (out) : "r" (b), "r" (a));
return out;
}
*/

// computes (((a[31:16] + b[31:16]) << 16) | (a[15:0 + b[15:0]))
static inline uint32_t signed_add_16_and_16(uint32_t a, uint32_t b) __attribute__((always_inline, unused));

Loading…
Cancel
Save