Selaa lähdekoodia

Merge remote-tracking branch 'upstream/master'

dds
awalch6679 4 vuotta sitten
vanhempi
commit
0ef86b456c
18 muutettua tiedostoa jossa 288 lisäystä ja 40 poistoa
  1. +1
    -1
      control_sgtl5000.cpp
  2. +39
    -0
      examples/HardwareTesting/PassThroughADCtoI2S/PassThroughADCtoI2S.ino
  3. +1
    -1
      gui/index.html
  4. +227
    -16
      input_adc.cpp
  5. +0
    -1
      input_adc.h
  6. +2
    -2
      input_adcs.cpp
  7. +2
    -4
      input_i2s.cpp
  8. +4
    -4
      input_i2s2.cpp
  9. +1
    -1
      input_i2s_hex.cpp
  10. +1
    -1
      input_i2s_quad.cpp
  11. +1
    -1
      input_pdm.cpp
  12. +1
    -1
      output_adat.cpp
  13. +1
    -1
      output_dac.cpp
  14. +1
    -1
      output_dacs.cpp
  15. +1
    -0
      output_i2s.cpp
  16. +2
    -2
      output_pt8211.cpp
  17. +2
    -2
      output_pt8211_2.cpp
  18. +1
    -1
      output_pwm.cpp

+ 1
- 1
control_sgtl5000.cpp Näytä tiedosto

@@ -531,7 +531,7 @@ bool AudioControlSGTL5000::enable(void)
delay(400);
write(CHIP_LINE_OUT_VOL, 0x1D1D); // default approx 1.3 volts peak-to-peak
write(CHIP_CLK_CTRL, 0x0004); // 44.1 kHz, 256*Fs
write(CHIP_I2S_CTRL, 0x0130); // SCLK=32*Fs, 16bit, I2S format
write(CHIP_I2S_CTRL, 0x0030); // SCLK=64*Fs, 16bit, I2S format
// default signal routing is ok?
write(CHIP_SSS_CTRL, 0x0010); // ADC->I2S, I2S->DAC
write(CHIP_ADCDAC_CTRL, 0x0000); // disable dac mute

+ 39
- 0
examples/HardwareTesting/PassThroughADCtoI2S/PassThroughADCtoI2S.ino Näytä tiedosto

@@ -0,0 +1,39 @@
/*
* A simple hardware test which receives audio on the A2 analog pin
* and sends it to the audio shield (I2S digital audio)
*
* This example code is in the public domain.
*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputAnalog adc1; //xy=197,73
AudioOutputI2S i2s1; //xy=375,85
AudioConnection patchCord1(adc1, 0, i2s1, 0);
AudioConnection patchCord2(adc1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=314,158
// GUItool: end automatically generated code


void setup() {
// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(12);

// Enable the audio shield
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
}

void loop() {
// Do nothing here. The Audio flows automatically

// When AudioInputAnalog is running, analogRead() must NOT be used.
}



+ 1
- 1
gui/index.html Näytä tiedosto

@@ -3236,7 +3236,7 @@ double s_freq = .0625;</p>
at altered speed. The grainLength is specified in milliseconds, up to
one third of the memory from begin();
</p>
<p class=func><span class=keyword>end</span>();</p>
<p class=func><span class=keyword>stop</span>();</p>
<p class=desc>Stop granual processing. The input signal is passed to the
output without any changes.
</p>

+ 227
- 16
input_adc.cpp Näytä tiedosto

@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/

#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__)
#if defined(KINETISK)
#include <Arduino.h>
#include "input_adc.h"
@@ -33,7 +33,7 @@

#define COEF_HPF_DCBLOCK (1048300<<10) // DC Removal filter coefficient in S1.30

DMAMEM static uint16_t analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint16_t analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputAnalog::block_left = NULL;
uint16_t AudioInputAnalog::block_offset = 0;
int32_t AudioInputAnalog::hpf_y1 = 0;
@@ -44,7 +44,7 @@ DMAChannel AudioInputAnalog::dma(false);

void AudioInputAnalog::init(uint8_t pin)
{
int32_t tmp;
int32_t tmp;

// Configure the ADC and run at least one software-triggered
// conversion. This completes the self calibration stuff and
@@ -57,15 +57,14 @@ void AudioInputAnalog::init(uint8_t pin)
analogReadAveraging(4);
#endif
// Note for review:
// Probably not useful to spin cycles here stabilizing
// since DC blocking is similar to te external analog filters
tmp = (uint16_t) analogRead(pin);
tmp = ( ((int32_t) tmp) << 14);
hpf_x1 = tmp; // With constant DC level x1 would be x0
hpf_y1 = 0; // Output will settle here when stable
// Probably not useful to spin cycles here stabilizing
// since DC blocking is similar to te external analog filters
tmp = (uint16_t) analogRead(pin);
tmp = ( ((int32_t) tmp) << 14);
hpf_x1 = tmp; // With constant DC level x1 would be x0
hpf_y1 = 0; // Output will settle here when stable

// 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
@@ -78,13 +77,11 @@ 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);
@@ -96,7 +93,6 @@ 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();
@@ -111,9 +107,7 @@ 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) {
@@ -213,4 +207,221 @@ void AudioInputAnalog::update(void)
transmit(out_left);
release(out_left);
}
#endif
#endif



#if defined(__IMXRT1062__)

#include <Arduino.h>
#include "input_adc.h"

extern "C" void xbar_connect(unsigned int input, unsigned int output);

#define FILTERLEN 15

DMAChannel AudioInputAnalog::dma(false);
// TODO: how much extra space is needed to avoid wrap-around timing? 200 seems a safe guess
static __attribute__((aligned(32))) uint16_t adc_buffer[AUDIO_BLOCK_SAMPLES*4+200];
static int16_t capture_buffer[AUDIO_BLOCK_SAMPLES*4+FILTERLEN];
// TODO: these big buffers should be in DMAMEM, rather than consuming precious DTCM

PROGMEM static const uint8_t adc2_pin_to_channel[] = {
7, // 0/A0 AD_B1_02
8, // 1/A1 AD_B1_03
12, // 2/A2 AD_B1_07
11, // 3/A3 AD_B1_06
6, // 4/A4 AD_B1_01
5, // 5/A5 AD_B1_00
15, // 6/A6 AD_B1_10
0, // 7/A7 AD_B1_11
13, // 8/A8 AD_B1_08
14, // 9/A9 AD_B1_09
255, // 10/A10 AD_B0_12 - only on ADC1, 1 - can't use for audio
255, // 11/A11 AD_B0_13 - only on ADC1, 2 - can't use for audio
3, // 12/A12 AD_B1_14
4, // 13/A13 AD_B1_15
7, // 14/A0 AD_B1_02
8, // 15/A1 AD_B1_03
12, // 16/A2 AD_B1_07
11, // 17/A3 AD_B1_06
6, // 18/A4 AD_B1_01
5, // 19/A5 AD_B1_00
15, // 20/A6 AD_B1_10
0, // 21/A7 AD_B1_11
13, // 22/A8 AD_B1_08
14, // 23/A9 AD_B1_09
255, // 24/A10 AD_B0_12 - only on ADC1, 1 - can't use for audio
255, // 25/A11 AD_B0_13 - only on ADC1, 2 - can't use for audio
3, // 26/A12 AD_B1_14 - only on ADC2, do not use analogRead()
4, // 27/A13 AD_B1_15 - only on ADC2, do not use analogRead()
#ifdef ARDUINO_TEENSY41
255, // 28
255, // 29
255, // 30
255, // 31
255, // 32
255, // 33
255, // 34
255, // 35
255, // 36
255, // 37
1, // 38/A14 AD_B1_12 - only on ADC2, do not use analogRead()
2, // 39/A15 AD_B1_13 - only on ADC2, do not use analogRead()
9, // 40/A16 AD_B1_04
10, // 41/A17 AD_B1_05
#endif
};

static const int16_t filter[FILTERLEN] = {
1449,
3676,
6137,
9966,
13387,
16896,
18951,
19957,
18951,
16896,
13387,
9966,
6137,
3676,
1449
};


void AudioInputAnalog::init(uint8_t pin)
{
if (pin >= sizeof(adc2_pin_to_channel)) return;
const uint8_t adc_channel = adc2_pin_to_channel[pin];
if (adc_channel == 255) return;

// configure a timer to trigger ADC
// TODO: sample rate should be slightly lower than 4X AUDIO_SAMPLE_RATE_EXACT
// linear interpolation is supposed to resample it to exactly 4X
// the sample rate, so we avoid artifacts boundaries between captures
const int comp1 = ((float)F_BUS_ACTUAL) / (AUDIO_SAMPLE_RATE_EXACT * 4.0f) / 2.0f + 0.5f;
TMR4_ENBL &= ~(1<<3);
TMR4_SCTRL3 = TMR_SCTRL_OEN | TMR_SCTRL_FORCE;
TMR4_CSCTRL3 = TMR_CSCTRL_CL1(1) | TMR_CSCTRL_TCF1EN;
TMR4_CNTR3 = 0;
TMR4_LOAD3 = 0;
TMR4_COMP13 = comp1;
TMR4_CMPLD13 = comp1;
TMR4_CTRL3 = TMR_CTRL_CM(1) | TMR_CTRL_PCS(8) | TMR_CTRL_LENGTH | TMR_CTRL_OUTMODE(3);
TMR4_DMA3 = TMR_DMA_CMPLD1DE;
TMR4_CNTR3 = 0;
TMR4_ENBL |= (1<<3);

// connect the timer output the ADC_ETC input
const int trigger = 4; // 0-3 for ADC1, 4-7 for ADC2
CCM_CCGR2 |= CCM_CCGR2_XBAR1(CCM_CCGR_ON);
xbar_connect(XBARA1_IN_QTIMER4_TIMER3, XBARA1_OUT_ADC_ETC_TRIG00 + trigger);

// turn on ADC_ETC and configure to receive trigger
if (ADC_ETC_CTRL & (ADC_ETC_CTRL_SOFTRST | ADC_ETC_CTRL_TSC_BYPASS)) {
ADC_ETC_CTRL = 0; // clears SOFTRST only
ADC_ETC_CTRL = 0; // clears TSC_BYPASS
}
ADC_ETC_CTRL |= ADC_ETC_CTRL_TRIG_ENABLE(1 << trigger) | ADC_ETC_CTRL_DMA_MODE_SEL;
ADC_ETC_DMA_CTRL |= ADC_ETC_DMA_CTRL_TRIQ_ENABLE(trigger);

// configure ADC_ETC trigger4 to make one ADC2 measurement on pin A2
const int len = 1;
IMXRT_ADC_ETC.TRIG[trigger].CTRL = ADC_ETC_TRIG_CTRL_TRIG_CHAIN(len - 1) |
ADC_ETC_TRIG_CTRL_TRIG_PRIORITY(7);
IMXRT_ADC_ETC.TRIG[trigger].CHAIN_1_0 = ADC_ETC_TRIG_CHAIN_HWTS0(1) |
ADC_ETC_TRIG_CHAIN_CSEL0(adc2_pin_to_channel[pin]) | ADC_ETC_TRIG_CHAIN_B2B0;

// set up ADC2 for 12 bit mode, hardware trigger
Serial.printf("ADC2_CFG = %08X\n", ADC2_CFG);
ADC2_CFG |= ADC_CFG_ADTRG;
ADC2_CFG = ADC_CFG_MODE(2) | ADC_CFG_ADSTS(3) | ADC_CFG_ADLSMP | ADC_CFG_ADTRG |
ADC_CFG_ADICLK(1) | ADC_CFG_ADIV(0) /*| ADC_CFG_ADHSC*/;
ADC2_GC &= ~ADC_GC_AVGE; // single sample, no averaging
ADC2_HC0 = ADC_HC_ADCH(16); // 16 = controlled by ADC_ETC

// use a DMA channel to capture ADC_ETC output
dma.begin();
dma.TCD->SADDR = &(IMXRT_ADC_ETC.TRIG[4].RESULT_1_0);
dma.TCD->SOFF = 0;
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
dma.TCD->NBYTES_MLNO = 2;
dma.TCD->SLAST = 0;
dma.TCD->DADDR = adc_buffer;
dma.TCD->DOFF = 2;
dma.TCD->CITER_ELINKNO = sizeof(adc_buffer) / 2;
dma.TCD->DLASTSGA = -sizeof(adc_buffer);
dma.TCD->BITER_ELINKNO = sizeof(adc_buffer) / 2;
dma.TCD->CSR = 0;
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC_ETC);
dma.enable();

// TODO: configure I2S1 to interrupt every 128 audio samples
}

static int16_t fir(const int16_t *data, const int16_t *impulse, int len)
{
int64_t sum=0;

while (len > 0) {
sum += *data++ * *impulse++; // TODO: optimize with DSP inst and filter symmetry
len --;
}
sum = sum >> 15; // TODO: adjust filter coefficients for proper gain, 12 to 16 bits
if (sum > 32767) return 32767;
if (sum < -32768) return -32768;
return sum;
}

void AudioInputAnalog::update(void)
{
audio_block_t *output=NULL;
output = allocate();
if (output == NULL) return;

uint16_t *p = (uint16_t *)dma.TCD->DADDR;
//int offset = p - adc_buffer;
//if (--offset < 0) offset = sizeof(adc_buffer) / 2 - 1;
//Serial.printf("offset = %4d, val = %4d\n", offset + 1, adc_buffer[offset]);

// copy adc buffer to capture buffer
// FIXME: this should be done from the I2S interrupt, for precise capture timing
const unsigned int capture_len = sizeof(capture_buffer) / 2;
for (unsigned int i=0; i < capture_len; i++) {
// TODO: linear interpolate to exactly 4X sample rate
if (--p < adc_buffer) p = adc_buffer + (sizeof(adc_buffer) / 2 - 1);

// remove DC offset
// TODO: very slow low pass filter for DC offset
int dc_offset = 550; // FIXME: quick kludge for testing!!

int n = (int)*p - dc_offset;
if (n > 4095) n = 4095;
if (n < -4095) n = -4095;

capture_buffer[i] = n;
}
//printbuf(capture_buffer, 8);

// low pass filter and subsample (this part belongs here)
int16_t *dest = output->data + AUDIO_BLOCK_SAMPLES - 1;
for (int i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
#if 1
// proper low-pass filter sounds pretty good
*dest-- = fir(capture_buffer + i * 4, filter, sizeof(filter)/2);
#else
// just averge 4 samples together, lower quality but much faster
*dest-- = capture_buffer[i * 4] + capture_buffer[i * 4 + 1]
+ capture_buffer[i * 4 + 2] + capture_buffer[i * 4 + 3];
#endif
}
transmit(output);
release(output);
}



#endif

+ 0
- 1
input_adc.h Näytä tiedosto

@@ -37,7 +37,6 @@ public:
AudioInputAnalog() : AudioStream(0, NULL) { init(A2); }
AudioInputAnalog(uint8_t pin) : AudioStream(0, NULL) { init(pin); }
virtual void update(void);
friend void dma_ch9_isr(void);
private:
static audio_block_t *block_left;
static uint16_t block_offset;

+ 2
- 2
input_adcs.cpp Näytä tiedosto

@@ -33,8 +33,8 @@

#define COEF_HPF_DCBLOCK (1048300<<10) // DC Removal filter coefficient in S1.30

DMAMEM static uint16_t left_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM static uint16_t right_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint16_t left_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint16_t right_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputAnalogStereo::block_left = NULL;
audio_block_t * AudioInputAnalogStereo::block_right = NULL;
uint16_t AudioInputAnalogStereo::offset_left = 0;

+ 2
- 4
input_i2s.cpp Näytä tiedosto

@@ -30,7 +30,7 @@
#include "input_i2s.h"
#include "output_i2s.h"

static uint32_t i2s_rx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_rx_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputI2S::block_left = NULL;
audio_block_t * AudioInputI2S::block_right = NULL;
uint16_t AudioInputI2S::block_offset = 0;
@@ -122,9 +122,7 @@ void AudioInputI2S::isr(void)
dest_left = &(left->data[offset]);
dest_right = &(right->data[offset]);
AudioInputI2S::block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
#if IMXRT_CACHE_ENABLED >=1
arm_dcache_delete(src, sizeof(i2s_rx_buffer) / 2);
#endif
arm_dcache_delete((void*)src, sizeof(i2s_rx_buffer) / 2);
do {
*dest_left++ = *src++;
*dest_right++ = *src++;

+ 4
- 4
input_i2s2.cpp Näytä tiedosto

@@ -30,7 +30,7 @@
#include "input_i2s2.h"
#include "output_i2s2.h"

static uint32_t i2s2_rx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s2_rx_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputI2S2::block_left = NULL;
audio_block_t * AudioInputI2S2::block_right = NULL;
uint16_t AudioInputI2S2::block_offset = 0;
@@ -102,9 +102,9 @@ void AudioInputI2S2::isr(void)
dest_left = &(left->data[offset]);
dest_right = &(right->data[offset]);
AudioInputI2S2::block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
#if IMXRT_CACHE_ENABLED >=1
arm_dcache_delete(src, sizeof(i2s_rx_buffer) / 2);
#endif
arm_dcache_delete((void*)src, sizeof(i2s2_rx_buffer) / 2);
do {
*dest_left++ = *src++;
*dest_right++ = *src++;

+ 1
- 1
input_i2s_hex.cpp Näytä tiedosto

@@ -112,7 +112,7 @@ void AudioInputI2SHex::isr(void)
if (block_ch1) {
offset = block_offset;
if (offset <= AUDIO_BLOCK_SAMPLES/2) {
arm_dcache_delete(src, sizeof(i2s_rx_buffer) / 2);
arm_dcache_delete((void*)src, sizeof(i2s_rx_buffer) / 2);
block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
dest1 = &(block_ch1->data[offset]);
dest2 = &(block_ch2->data[offset]);

+ 1
- 1
input_i2s_quad.cpp Näytä tiedosto

@@ -148,7 +148,7 @@ void AudioInputI2SQuad::isr(void)
if (block_ch1) {
offset = block_offset;
if (offset <= AUDIO_BLOCK_SAMPLES/2) {
arm_dcache_delete(src, sizeof(i2s_rx_buffer) / 2);
arm_dcache_delete((void*)src, sizeof(i2s_rx_buffer) / 2);
block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
dest1 = &(block_ch1->data[offset]);
dest2 = &(block_ch2->data[offset]);

+ 1
- 1
input_pdm.cpp Näytä tiedosto

@@ -52,7 +52,7 @@
// but its performance should be *much* better than the rapid passband rolloff
// of Cascaded Integrator Comb (CIC) or moving average filters.

DMAMEM static uint32_t pdm_buffer[AUDIO_BLOCK_SAMPLES*4];
DMAMEM __attribute__((aligned(32))) static uint32_t pdm_buffer[AUDIO_BLOCK_SAMPLES*4];
static uint32_t leftover[14];
audio_block_t * AudioInputPDM::block_left = NULL;
bool AudioInputPDM::update_responsibility = false;

+ 1
- 1
output_adat.cpp Näytä tiedosto

@@ -56,7 +56,7 @@ uint16_t AudioOutputADAT::ch8_offset = 0;
bool AudioOutputADAT::update_responsibility = false;
//uint32_t AudioOutputADAT::vucp = VUCP_VALID;

DMAMEM static uint32_t ADAT_tx_buffer[AUDIO_BLOCK_SAMPLES * 8]; //4 KB, AUDIO_BLOCK_SAMPLES is usually 128
DMAMEM __attribute__((aligned(32))) static uint32_t ADAT_tx_buffer[AUDIO_BLOCK_SAMPLES * 8]; //4 KB, AUDIO_BLOCK_SAMPLES is usually 128

DMAChannel AudioOutputADAT::dma(false);


+ 1
- 1
output_dac.cpp Näytä tiedosto

@@ -30,7 +30,7 @@

#if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)

DMAMEM static uint16_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
DMAMEM __attribute__((aligned(32))) static uint16_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
audio_block_t * AudioOutputAnalog::block_left_1st = NULL;
audio_block_t * AudioOutputAnalog::block_left_2nd = NULL;
bool AudioOutputAnalog::update_responsibility = false;

+ 1
- 1
output_dacs.cpp Näytä tiedosto

@@ -30,7 +30,7 @@

#if defined(__MK64FX512__) || defined(__MK66FX1M0__)

DMAMEM static uint32_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
DMAMEM __attribute__((aligned(32))) static uint32_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
audio_block_t * AudioOutputAnalogStereo::block_left_1st = NULL;
audio_block_t * AudioOutputAnalogStereo::block_left_2nd = NULL;
audio_block_t * AudioOutputAnalogStereo::block_right_1st = NULL;

+ 1
- 0
output_i2s.cpp Näytä tiedosto

@@ -475,6 +475,7 @@ void AudioOutputI2Sslave::begin(void)
dma.TCD->DLASTSGA = 0;
dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma.TCD->DADDR = (void *)((uint32_t)&I2S1_TDR0 + 2);
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI1_TX);
dma.enable();


+ 2
- 2
output_pt8211.cpp Näytä tiedosto

@@ -40,9 +40,9 @@ uint16_t AudioOutputPT8211::block_left_offset = 0;
uint16_t AudioOutputPT8211::block_right_offset = 0;
bool AudioOutputPT8211::update_responsibility = false;
#if defined(AUDIO_PT8211_OVERSAMPLING)
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES*4];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES*4];
#else
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
#endif
DMAChannel AudioOutputPT8211::dma(false);


+ 2
- 2
output_pt8211_2.cpp Näytä tiedosto

@@ -40,9 +40,9 @@ uint16_t AudioOutputPT8211_2::block_left_offset = 0;
uint16_t AudioOutputPT8211_2::block_right_offset = 0;
bool AudioOutputPT8211_2::update_responsibility = false;
#if defined(AUDIO_PT8211_OVERSAMPLING)
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES*4];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES*4];
#else
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
#endif
DMAChannel AudioOutputPT8211_2::dma(false);


+ 1
- 1
output_pwm.cpp Näytä tiedosto

@@ -213,7 +213,7 @@ extern uint8_t analog_write_res;
extern const struct _pwm_pin_info_struct pwm_pin_info[];
audio_block_t * AudioOutputPWM::block = NULL;
DMAMEM __attribute__((aligned(32))) static uint16_t pwm_tx_buffer[2][AUDIO_BLOCK_SAMPLES * 2];
DMAChannel AudioOutputPWM::dma[2](false);
DMAChannel AudioOutputPWM::dma[2];
_audio_info_flexpwm AudioOutputPWM::apins[2];

FLASHMEM

Loading…
Peruuta
Tallenna