It would be better to post your code between code tags </>
When you want to output audio thru DAC0/DAC1, forget analogwrite() function.
DACC direct register programing plus a PDC DMA is a much better solution. A timer Counter triggers DAC conversions at a precise pace (a PWM Event Line 0 or 1 could trigger DAC conversions as well).
An example sketch to output a sine wave on both DACs:
/***********************************************************************************/
/* DAC0 and DAC1 output of a sin wave - Frequency of sin = 44.1 KHz / sinsize */
/***********************************************************************************/
const uint32_t sinsize = 256 ; // Size of buffer must be a power of 2
uint32_t sinus[2][sinsize];
volatile uint32_t bufn;
void dac_setup () {
PMC->PMC_PCER1 = PMC_PCER1_PID38; // DACC power ON
DACC->DACC_CR = DACC_CR_SWRST ; // Reset DACC
DACC->DACC_MR = DACC_MR_TRGEN_EN // Hardware trigger select
| DACC_MR_TRGSEL(0b011) // Trigger by TIOA2
| DACC_MR_TAG_EN // enable TAG to set channel in CDR
| DACC_MR_WORD_WORD // write to both channels
| DACC_MR_REFRESH (1)
| DACC_MR_STARTUP_8
| DACC_MR_MAXS;
DACC->DACC_IER |= DACC_IER_TXBUFE; // Interrupt used by PDC DMA
DACC->DACC_ACR = DACC_ACR_IBCTLCH0(0b10)
| DACC_ACR_IBCTLCH1(0b10)
| DACC_ACR_IBCTLDACCORE(0b01);
NVIC_EnableIRQ(DACC_IRQn); // Enable DACC interrupt
DACC->DACC_CHER = DACC_CHER_CH0 // enable channel 0 = DAC0
| DACC_CHER_CH1; // enable channel 1 = DAC1
/************* configure PDC/DMA for DAC *******************/
DACC->DACC_TPR = (uint32_t)sinus[0]; // DMA buffer
DACC->DACC_TCR = sinsize;
DACC->DACC_TNPR = (uint32_t)sinus[1]; // next DMA buffer (circular buffer)
DACC->DACC_TNCR = sinsize;
bufn = 1;
DACC->DACC_PTCR = DACC_PTCR_TXTEN; // Enable PDC Transmit channel request
}
void DACC_Handler() {
uint32_t status = DACC->DACC_ISR; // Read and save DAC status register
if (status & DACC_ISR_TXBUFE) { // move DMA pointer to next buffer
bufn = (bufn + 1) & 1;
DACC->DACC_TNPR = (uint32_t)sinus[bufn];
DACC->DACC_TNCR = sinsize;
}
}
void tc_setup() {
PMC->PMC_PCER0 |= PMC_PCER0_PID29; // TC2 power ON : Timer Counter 0 channel 2 IS TC2
TC0->TC_CHANNEL[2].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK2 // MCK/8, clk on rising edge
| TC_CMR_WAVE // Waveform mode
| TC_CMR_WAVSEL_UP_RC // UP mode with automatic trigger on RC Compare
| TC_CMR_ACPA_CLEAR // Clear TIOA2 on RA compare match
| TC_CMR_ACPC_SET; // Set TIOA2 on RC compare match
TC0->TC_CHANNEL[2].TC_RC = 238; //<********************* Frequency = (Mck/8)/TC_RC = 44.1 MHz
TC0->TC_CHANNEL[2].TC_RA = 40; //<******************** Any Duty cycle in between 1 and TC_RC
TC0->TC_CHANNEL[2].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC2 counter and enable
}
void setup() {
for(int i = 0; i < sinsize; i++)
{
uint32_t chsel = (0<<12) | (1<<28); // LSB on DAC0, MSB on DAC1 !!
sinus[0][i] = 2047*sinf(i * 2 * PI/sinsize) + 2047; // 0 < sinus [i] < 4096
sinus[1][i] = sinus[0][i] |= sinus[0][i] <<16 | chsel; // two buffers formated
// MSB [31:16]on channel 1
// LSB [15:0] on chanel 0
}
tc_setup();
dac_setup();
}
void loop() {
}