1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-19 09:42:11 +03: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" #include "Audio.h"
@ -49,9 +58,9 @@ void AudioClass::begin(uint32_t sampleRate) {
// Configure Timer Counter to trigger DAC // Configure Timer Counter to trigger DAC
// -------------------------------------- // --------------------------------------
pmc_enable_periph_clk(ID_TC0); pmc_enable_periph_clk(ID_TC1);
TC_Configure(TC0, 1, TC_Configure(TC0, 1,
TC_CMR_TCCLKS_TIMER_CLOCK2 | TC_CMR_TCCLKS_TIMER_CLOCK2 | // Clock at MCR/8
TC_CMR_WAVE | // Waveform mode TC_CMR_WAVE | // Waveform mode
TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC
TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR); TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR);
@ -60,8 +69,20 @@ void AudioClass::begin(uint32_t sampleRate) {
TC_SetRC(TC0, 1, TC); TC_SetRC(TC0, 1, TC);
TC_Start(TC0, 1); TC_Start(TC0, 1);
// Configure clock source for DAC (1 = TC0 Output Chan. 1) // Configure clock source for DAC (2 = TC0 Output Chan. 1)
dacc_set_trigger(dac, 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() { void AudioClass::end() {
@ -70,11 +91,10 @@ void AudioClass::end() {
dacc_disable_channel(dac, 1); 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 // Try the first PDC buffer
if ((dac->DACC_TCR == 0) && (dac->DACC_TNCR == 0)) { 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_TCR = size;
dac->DACC_PTCR = DACC_PTCR_TXTEN; dac->DACC_PTCR = DACC_PTCR_TXTEN;
return size; return size;
@ -82,7 +102,7 @@ size_t AudioClass::write(const uint8_t *buffer, size_t size) {
// Try the second PDC buffer // Try the second PDC buffer
if (dac->DACC_TNCR == 0) { 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_TNCR = size;
dac->DACC_PTCR = DACC_PTCR_TXTEN; dac->DACC_PTCR = DACC_PTCR_TXTEN;
return size; return size;
@ -92,6 +112,22 @@ size_t AudioClass::write(const uint8_t *buffer, size_t size) {
return 0; 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); AudioClass Audio(DACC_INTERFACE, DACC_INTERFACE_ID);
//void DACC_IrqHandler(void) { //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 #ifndef AUDIO_H
#define AUDIO_H #define AUDIO_H
#include "Arduino.h" #include "Arduino.h"
//#include <inttypes.h>
#include "Print.h" #include "Print.h"
class AudioClass : public Print { class AudioClass : public Print {
@ -11,10 +20,19 @@ public:
void begin(uint32_t sampleRate); void begin(uint32_t sampleRate);
void end(); void end();
virtual size_t write(uint8_t c) { write(&c, 1); }; virtual size_t write(uint8_t c) { /* not implemented */ };
virtual size_t write(const uint8_t *buffer, size_t size); 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: private:
uint32_t buffer0[1024];
uint32_t buffer1[1024];
int currentBuffer;
uint32_t *cook(const uint32_t *buffer, size_t size);
Dacc *dac; Dacc *dac;
uint32_t dacId; uint32_t dacId;
}; };