size_t DACClass::queueBuffer(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_TCR = size; dac->DACC_PTCR = DACC_PTCR_TXTEN; if (cb) dacc_enable_interrupt(dac, DACC_IER_ENDTX); return size; } // Try the second PDC buffer if (dac->DACC_TNCR == 0) { dac->DACC_TNPR = (uint32_t) buffer; dac->DACC_TNCR = size; dac->DACC_PTCR = DACC_PTCR_TXTEN; if (cb) dacc_enable_interrupt(dac, DACC_IER_ENDTX); return size; } // PDC buffers full, try again later... return 0; }
/** * \brief DACC configuration. */ static void dsp_configure_dacc(void) { pmc_enable_periph_clk(ID_DACC); /* * DACC setting * -Refresh Period = 1024*REFRESH/DACC Clock * -No max Speed Mode * -Startup time of 0 periods of DACClock */ dacc_set_timing(DACC, DACC_REFRESH, 0, DACC_MR_STARTUP_0); /* Set TIO Output of TC Channel 1 as trigger */ dacc_set_trigger(DACC,2); /* Set to half word transfer */ dacc_set_transfer_mode(DACC, DACC_MR_WORD_HALF); #if (SAM3S) || (SAM3XA) /* Set to No Sleep Mode and No Fast Wake Up Mode*/ dacc_set_power_save(DACC, 0, 0); #endif /* Select both left/right speaker channels. */ dacc_set_channel_selection(DACC, SPEAKER_CHANNEL_R); dacc_set_channel_selection(DACC, SPEAKER_CHANNEL_L); /* Enable DACC channels. */ dacc_enable_channel(DACC, SPEAKER_CHANNEL_R); dacc_enable_channel(DACC, SPEAKER_CHANNEL_L); /* Tag selection mode enabled. */ dacc_enable_flexible_selection(DACC); /* Get board DACC PDC base address. */ dacc_pdc = dacc_get_pdc_base(DACC); /* Enable DACC interrupt. */ dacc_enable_interrupt(DACC,DACC_IER_ENDTX); NVIC_SetPriority(DACC_IRQn, INT_PRIORITY_DACC); NVIC_EnableIRQ(DACC_IRQn); }