XMEGA DAC & DMA control for waveform generation

divgup's picture
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Type: 

Compiler/Assembler: 

/**
 * \file
 *
 * \brief AVR XMEGA Digital to Analog Converter Driver Example 1
 *
 * Copyright (C) 2010-2015 Atmel Corporation. All rights reserved.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \asf_license_stop
 *
 */
 // IC Used : ATMEGA 32A4u


#include "compiler.h"
#include "preprocessor.h"
#include "board.h"
#include "gpio.h"
#include "sysclk.h"
#include "sleepmgr.h"
#include "conf_usb.h"
#include "udc.h"
#include "udd.h"
#include "ui.h"
#include "math.h"
#include "nvm.h"
#include "tc.h"
#include "asf/xmega/drivers/dac/dac.h"
#include "asf/xmega/drivers/dma/dma.h"
#include <defines.h>
#include <stdio.h>
#include <stdlib.h>
#include <rvkbd4x4.h>
#include <avr/eeprom.h>
#include "ioport_compat.h"


#define SPEAKER_DAC             DACB
#define SPEAKER_DAC_CHANNEL DAC_CH1
//#define CONFIG_SLEEPMGR_ENABLE

#define DMA_CHANNEL     0

/** \brief Size of DMA buffers */


//! Rate at which DA conversions should be done.
#define RATE_OF_CONVERSION    100000

//! Number of samples in sample buffer.
#define NR_OF_SAMPLES         32
#define DMA_BUFFER_SIZE NR_OF_SAMPLES

uint16_t i;

//! Sample buffer with one period of a sine wave.
uint16_t sine[NR_OF_SAMPLES] = {
	32768, 35325, 37784, 40050, 42036, 43666, 44877, 45623,
	45875, 45623, 44877, 43666, 42036, 40050, 37784, 35325,
	32768, 30211, 27752, 25486, 23500, 21870, 20659, 19913,
	19661, 19913, 20659, 21870, 23500, 25486, 27752, 30211,
};

//
//ISR(TCC0_OVF_vect)
//{
	//
	////i++;
	//
//}

ISR(DMA_CH0_vect)
{
DMA.CH0.CTRLB|=0x10;
		DMA.CH0.CTRLA|=0x10;
		DMA.CH0.CTRLA|=0x80;	
	
	
}
static void configure_pins(void)
{
	/* Disable the digital part of the DAC output pin */

	ioport_configure_pin(DAC_CH1, IOPORT_DIR_OUTPUT |IOPORT_INPUT_DISABLE);
}

static void configure_dac()
{
	struct dac_config conf;
	//PORTB.DIR|=PIN2_bm|PIN3_bm;
	//PORTB.DIRCLR=0x00;
	//PORTB.DIRTGL=0x00;
	
	dac_read_configuration(&SPEAKER_DAC, &conf);

	/* Create configuration:
	 * - 1V from bandgap as reference, left adjusted channel value
	 * - one active DAC channel, no internal output
	 * - conversions triggered by event channel 0
	 * - 1 us conversion intervals
	 */
	dac_set_conversion_parameters(&conf, DAC_REF_AREFB, DAC_ADJ_LEFT);
	//dac_set_active_channel(&conf, SPEAKER_DAC_CHANNEL, DAC_CH1EN_bm);
	conf.ctrla=0x08;
	conf.ctrlb=0x22;
	conf.evctrl=0x00;
	//dac_set_conversion_trigger(&conf, SPEAKER_DAC_CHANNEL, 0);
	dac_write_configuration(&SPEAKER_DAC, &conf);
	dac_enable(&SPEAKER_DAC);
}
/*static void example_dma_transfer_done(enum dma_channel_status status)
{
	
	PORTD.OUTTGL=0x08;
}*/


void dma_out (unsigned short len, unsigned char rep)
{

	
	DMA.CTRL = 0;
	DMA.CTRL = DMA_RESET_bm;
	while ((DMA.CTRL & DMA_RESET_bm) != 0);
	// configure DMA controller
	DMA.CTRL = DMA_CH_ENABLE_bm |  DMA_DBUFMODE_CH01_gc;
	
	DMA.CH0.REPCNT = rep;
	DMA.CH0.CTRLB|=0x01;
	DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm;					// ADC result is 2 byte 12 bit word
	DMA.CH0.ADDRCTRL =	DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc |			// reload source after every burst
	DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc;	// reload dest after every transaction
	
		DMA.CH0.TRIGSRC = 0x26;//DMA_CH_TRIGSRC_TCC0_OVF_gc;
		DMA.CH0.TRFCNT = len;	// always the number of bytes, even if burst length > 1
	
		  DMA.CH0.SRCADDR0 = ((uint16_t)(&sine[0]) >> 0) & 0xFF;
		  DMA.CH0.SRCADDR1 = ((uint16_t)(&sine[0]) >>  8) & 0xFF;
		  DMA.CH0.SRCADDR2 =0;
		  
		  DMA.CH0.DESTADDR0 = ((uint16_t)(&DACB.CH1DATA) >> 0) & 0xFF;
		  DMA.CH0.DESTADDR1 = ((uint16_t)(&DACB.CH1DATA) >> 8) & 0xFF;
		  DMA.CH0.DESTADDR2 = 0;
	
	DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm;
	
	
}

static void dac_dma_timer()
{
	sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0);
	TCC0.PER = (sysclk_get_per_hz() / RATE_OF_CONVERSION) - 1;

	// Configure event channel 0 to generate events upon T/C overflow.
	sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS);
	EVSYS.CH0MUX = EVSYS_CHMUX_TCC0_OVF_gc;

	// Start the timer/counter.
	TCC0.CTRLA = TC_CLKSEL_DIV1_gc;
	//TCC0.INTCTRLA=0x01;

	configure_dac();
	dma_out(64,0);
}	

int main(void)
{
	
	//uint8_t           i = 0;
	PORTD.DIR=0x08;
	board_init();
	sysclk_init();
	sleepmgr_init();
	
	
	// Initialize the dac configuration.
	
	configure_pins();
	dac_dma_timer();
	
	
	// Configure timer/counter to generate events at sample rate.

			
	
	
	irq_initialize_vectors();
	cpu_irq_enable();
	/* Write samples to the DAC channel every time it is ready for new
	 * data, i.e., when it is done converting. Conversions are triggered by
	 * the timer/counter.
	 
	 */

	
	do {

	} while (1);
}