mirror of
https://github.com/arduino/Arduino.git
synced 2025-02-18 12:54:25 +01:00
Audio library: improved DMA transfers. Stereo output.
This commit is contained in:
parent
edd2fdd023
commit
6695518cff
@ -1,3 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2012 by Cristian Maglie <c.maglie@bug.st>
|
||||
* Audio library for Arduino Due.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of either the GNU General Public License version 2
|
||||
* or the GNU Lesser General Public License version 2.1, both as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "Audio.h"
|
||||
|
||||
@ -49,19 +58,31 @@ void AudioClass::begin(uint32_t sampleRate) {
|
||||
|
||||
// Configure Timer Counter to trigger DAC
|
||||
// --------------------------------------
|
||||
pmc_enable_periph_clk(ID_TC0);
|
||||
pmc_enable_periph_clk(ID_TC1);
|
||||
TC_Configure(TC0, 1,
|
||||
TC_CMR_TCCLKS_TIMER_CLOCK2 |
|
||||
TC_CMR_WAVE | // Waveform mode
|
||||
TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC
|
||||
TC_CMR_TCCLKS_TIMER_CLOCK2 | // Clock at MCR/8
|
||||
TC_CMR_WAVE | // Waveform mode
|
||||
TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC
|
||||
TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR);
|
||||
const uint32_t TC = VARIANT_MCK / 8 / sampleRate;
|
||||
TC_SetRA(TC0, 1, TC / 2);
|
||||
TC_SetRC(TC0, 1, TC);
|
||||
TC_Start(TC0, 1);
|
||||
|
||||
// Configure clock source for DAC (1 = TC0 Output Chan. 1)
|
||||
dacc_set_trigger(dac, 1);
|
||||
// Configure clock source for DAC (2 = TC0 Output Chan. 1)
|
||||
dacc_set_trigger(dac, 2);
|
||||
|
||||
// Configure pins
|
||||
PIO_Configure(g_APinDescription[DA0].pPort,
|
||||
g_APinDescription[DA0].ulPinType,
|
||||
g_APinDescription[DA0].ulPin,
|
||||
g_APinDescription[DA0].ulPinConfiguration);
|
||||
PIO_Configure(g_APinDescription[DA1].pPort,
|
||||
g_APinDescription[DA1].ulPinType,
|
||||
g_APinDescription[DA1].ulPin,
|
||||
g_APinDescription[DA1].ulPinConfiguration);
|
||||
|
||||
currentBuffer = 0;
|
||||
}
|
||||
|
||||
void AudioClass::end() {
|
||||
@ -70,11 +91,10 @@ void AudioClass::end() {
|
||||
dacc_disable_channel(dac, 1);
|
||||
}
|
||||
|
||||
size_t AudioClass::write(const uint8_t *buffer, size_t size) {
|
||||
|
||||
size_t AudioClass::write(const uint32_t *buffer, size_t size) {
|
||||
// Try the first PDC buffer
|
||||
if ((dac->DACC_TCR == 0) && (dac->DACC_TNCR == 0)) {
|
||||
dac->DACC_TPR = (uint32_t) buffer;
|
||||
dac->DACC_TPR = (uint32_t) cook(buffer, size);
|
||||
dac->DACC_TCR = size;
|
||||
dac->DACC_PTCR = DACC_PTCR_TXTEN;
|
||||
return size;
|
||||
@ -82,7 +102,7 @@ size_t AudioClass::write(const uint8_t *buffer, size_t size) {
|
||||
|
||||
// Try the second PDC buffer
|
||||
if (dac->DACC_TNCR == 0) {
|
||||
dac->DACC_TNPR = (uint32_t) buffer;
|
||||
dac->DACC_TNPR = (uint32_t) cook(buffer, size);
|
||||
dac->DACC_TNCR = size;
|
||||
dac->DACC_PTCR = DACC_PTCR_TXTEN;
|
||||
return size;
|
||||
@ -92,6 +112,22 @@ size_t AudioClass::write(const uint8_t *buffer, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t *AudioClass::cook(const uint32_t *buffer, size_t size) {
|
||||
if (currentBuffer == 0) {
|
||||
// Use buffer0
|
||||
for (int i = 0; i < size; i++)
|
||||
buffer0[i] = buffer[i] | 0x10000000;
|
||||
currentBuffer = 1;
|
||||
return buffer0;
|
||||
} else {
|
||||
// Use buffer1
|
||||
for (int i = 0; i < size; i++)
|
||||
buffer1[i] = buffer[i] | 0x10000000;
|
||||
currentBuffer = 0;
|
||||
return buffer1;
|
||||
}
|
||||
}
|
||||
|
||||
AudioClass Audio(DACC_INTERFACE, DACC_INTERFACE_ID);
|
||||
|
||||
//void DACC_IrqHandler(void) {
|
||||
|
@ -1,8 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2012 by Cristian Maglie <c.maglie@bug.st>
|
||||
* Audio library for Arduino Due.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of either the GNU General Public License version 2
|
||||
* or the GNU Lesser General Public License version 2.1, both as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
#include "Arduino.h"
|
||||
//#include <inttypes.h>
|
||||
#include "Print.h"
|
||||
|
||||
class AudioClass : public Print {
|
||||
@ -11,10 +20,19 @@ public:
|
||||
void begin(uint32_t sampleRate);
|
||||
void end();
|
||||
|
||||
virtual size_t write(uint8_t c) { write(&c, 1); };
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
virtual size_t write(uint8_t c) { /* not implemented */ };
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) { return write((uint32_t*) buffer, size/4) * 4; };
|
||||
virtual size_t write(const uint16_t *buffer, size_t size) { return write((uint32_t*) buffer, size/2) * 2; };
|
||||
virtual size_t write(const int16_t *buffer, size_t size) { return write((uint32_t*) buffer, size/2) * 2; };
|
||||
virtual size_t write(const uint32_t *buffer, size_t size);
|
||||
|
||||
private:
|
||||
uint32_t buffer0[1024];
|
||||
uint32_t buffer1[1024];
|
||||
int currentBuffer;
|
||||
|
||||
uint32_t *cook(const uint32_t *buffer, size_t size);
|
||||
|
||||
Dacc *dac;
|
||||
uint32_t dacId;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user