1
0
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:
Cristian Maglie 2012-06-18 01:53:53 +02:00
parent edd2fdd023
commit 6695518cff
2 changed files with 67 additions and 13 deletions

View File

@ -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) {

View File

@ -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;
};