Help!!! How to write to display of Xmega A3BU xplained.

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello everyone,

I want to write the value of a double on the display of my xmega A3BU xplained. Can this line work?


count=count+0.0000001
dist=count*340.29
printf(dist);

I wrote this on the avr studio 4. It seems that it doesnt not recognises printf ?

Please help! thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Where is the rest of the code?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include "avr/board.h"
#include "avr/adc_driver.h"
#include 
#include 
#include 
#include "avr/dma_driver.h"
#include "avr/adc_driver.h"
#include "avr/dac_driver.h"
#include "avr/clksys_driver.h"
#include "avr/avr_compiler.h"
#include "avr/tc_driver.h"
#include "util/delay.h"


#define SINE_WAVE_LOW_RES  20



#define DMA_CHANNEL_0  &DMA.CH0

#define DAC DACB
#define ADC ADCB  //xmega A3BU uses portB for ADC and DAC right?

#define DMA_REPEAT_FOREVER 0
// 2MHz, 20/40 Samples, dividend of 200 gives 500Hz/250Hz
#define TIMER_C0_PERIOD 64

long double count =0, dist;


uint16_t SineWaveLowRes [SINE_WAVE_LOW_RES] =
{
    0x7FF, 0xA78, 0xCB2, 0xE77, 0xF9A,
    0xFFF, 0xF9A, 0xE77, 0xCB2, 0xA78,
    0x7FF, 0x586, 0x34C, 0x187, 0x064,
    0x000, 0x064, 0x187, 0x34C, 0x586
};





void ADC_CalibrationValues_Load(ADC_t * adc)
{
        if(&ADCA == adc){
                 /* Get ADCACAL0 from production signature . */
                adc->CALL = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL0_offset );
                adc->CALH = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL1_offset );
        }else {
                /* Get ADCBCAL0 from production signature  */
                adc->CALL = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCBCAL0_offset );
                adc->CALH = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCBCAL1_offset );
        }
}

uint8_t SP_ReadCalibrationByte( uint8_t index )
{
        uint8_t result;
        /* Load the NVM Command register to read the calibration row. */
        NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
        result = pgm_read_byte(index);
        /* Clean up NVM Command register. */
        NVM_CMD = NVM_CMD_NO_OPERATION_gc;
        return result;
}

void ADC_Wait_8MHz(ADC_t * adc)
{
        /* Store old prescaler value. */
        uint8_t prescaler_val = adc->PRESCALER;
        /* Set prescaler value to minimum value. */
        adc->PRESCALER = ADC_PRESCALER_DIV4_gc;
        /* Wait 4*COMMON_MODE_CYCLES for common mode to settle. */
        delay_us(4*COMMON_MODE_CYCLES);
        /* Set prescaler to old value*/
        adc->PRESCALER = prescaler_val;
}

//======================================================


void clock_32MHz_RC(void) 
{ 
    // Enable 32MHz internal RC oscillator 
    OSC.CTRL |= OSC_RC32MEN_bm; 
    // Wait until it's stable 
    while ((OSC.STATUS & OSC_RC32MRDY_bm) == 0) 
        ; 
    // Select 32MHz RC as clock source, unlock first 
    CCP = CCP_IOREG_gc; 
    CLK.CTRL = CLK_SCLKSEL_RC32M_gc; 
    // Disable 2MHz RC-oscillator 
    OSC.CTRL &= ~OSC_RC2MEN_bm; 
} 

void DMA_Setup( DMA_CH_t * dmaChannel,
                const void * src,
                void * dest,
                int16_t blockSize,
                uint8_t repeatCount )
{
    DMA_Enable();


    DMA_SetupBlock(
	dmaChannel,
	src,
	DMA_CH_SRCRELOAD_BLOCK_gc,
	DMA_CH_SRCDIR_INC_gc,
	dest,
	DMA_CH_DESTRELOAD_BURST_gc,
	DMA_CH_DESTDIR_INC_gc,
	blockSize,
	DMA_CH_BURSTLEN_2BYTE_gc,
	repeatCount,
	true
	);

    // Timer Overflow will trigger DMA
//    DMA_SetTriggerSource( dmaChannel, 0x40 );
    // Event0 trigger
    DMA_SetTriggerSource( dmaChannel, DMA_CH_TRIGSRC_EVSYS_CH0_gc );
    DMA_EnableSingleShot( dmaChannel );
}

//===============================================================

uint16_t ADC_ResultCh_GetWord_Unsigned(ADC_CH_t * adc_ch, uint8_t offset)
{
        uint16_t answer;
        /* Clear interrupt flag.*/
        adc_ch->INTFLAGS = ADC_CH_CHIF_bm;
        /* Return result register contents*/
        answer = adc_ch->RES - offset;
        return answer;
}

uint16_t ADC_ResultCh_GetWord(ADC_CH_t * adc_ch)
{
        /* Clear interrupt flag.*/
        adc_ch->INTFLAGS = ADC_CH_CHIF_bm;
        /* Return result register contents*/
        return adc_ch->RES;;
}

uint8_t ADC_Offset_Get_Unsigned(ADC_t * adc, ADC_CH_t *ch, bool oversampling)
{
    if (oversampling)
    {
      uint16_t offset=0;
      for (int i=0; i<4; i++)
      {
        /* Do one conversion to find offset. */
        ADC_Ch_Conversion_Start(ch);
   
        do{
        }while(!ADC_Ch_Conversion_Complete(ch));
        offset += ADC_ResultCh_GetWord_Unsigned(ch, 0x00);
      }
      return ((uint8_t)(offset>>2));
    }
    else
    {       
      uint8_t offset=0;
     
      /* Do one conversion to find offset. */
      ADC_Ch_Conversion_Start(ch);
 
      do{
      }while(!ADC_Ch_Conversion_Complete(ch));
      offset = (uint8_t)ADC_ResultCh_GetWord(ch);
     
      return offset;
    }
}



volatile uint16_t ADC_result; 


int main( void ) 
{ 
	
   //counter start
   while(count<10)
   {
   delay_ns(100);
   count=count+0.0000001;
   //===================

   // Variable for use when we read the result from an ADC channel 
   int8_t offset; 
    
   /* Move stored calibration values to ADC A */ 
   //ADC_CalibrationValues_Load(&ADCA); 

   /* Set up ADC A to have signed conversion mode and 12 bit resolution. */ 
   ADC_ConvMode_and_Resolution_Config(&ADC, ADC_ConvMode_Unsigned, ADC_RESOLUTION_12BIT_gc); 

   // The ADC has different voltage reference options, controlled by the REFSEL bits in the 
   // REFCTRL register. Here the internal reference is selected 
   ADC_Reference_Config(&ADC, ADC_REFSEL_VCC_gc); 

   // The clock into the ADC decide the maximum sample rate and the conversion time, and 
   // this is controlled by the PRESCALER bits in the PRESCALER register. Here, the 
   // Peripheral Clock is divided by 32 ( gives 62.5 KSPS with 2Mhz clock ) 
   ADC_Prescaler_Config(&ADC, ADC_PRESCALER_DIV8_gc); 

   // The used Virtual Channel (CH0) must be set in the correct mode 
   // In this task we will use single ended input, so this mode is selected 

   /* Setup channel 0 to have differential input. */ 
   ADC_Ch_InputMode_and_Gain_Config(&ADC.CH0, 
                                    ADC_CH_INPUTMODE_DIFF_gc, 
                                    ADC_CH_GAIN_1X_gc); 

   // Setting up the which pins to convert. 
   // Note that the negative pin is connected to ground 
   ADC_Ch_InputMux_Config(&ADC.CH0, ADC_CH_MUXPOS_PIN1_gc, ADC_CH_MUXNEG_PIN0_gc); 

   ADC_FreeRunning_Enable(&ADC);

   // Before the ADC can be used it must be enabled 
   ADC_Enable(&ADC); 

   // Wait until the ADC is ready 
   ADC_Wait_8MHz(&ADC); 

   // In the while(1) loop, a conversion is started on CH0 and the result is output on PORTE  

   /* Get offset value for ADC A.  */ 
   offset = ADC_Offset_Get_Unsigned(&ADC, &(ADC.CH0), true); 
   
    
   //Read the ADC forever... 
   while (1) { 	

      // Start a single conversion 
      ADC_Ch_Conversion_Start(&ADC.CH0); 

      // Wait for the conversion to complete 
      while (1) { 
       //Start a single conversion 
      ADC_Ch_Conversion_Start(&ADC.CH0); 
       
      // Wait for the conversion to complete 
      while(!ADC_Ch_Conversion_Complete(&ADC.CH0)); 
	  
       
      // Get the result 
      ADC_result = ADC_ResultCh_GetWord_Unsigned(&ADC.CH0, offset);




	  		if(ADC_result<0xA00) //less than 1v
	  		{



clock_32MHz_RC();


    // Use event instead of overflow interrupt
    EVSYS.CH0MUX = EVSYS_CHMUX_TCC0_OVF_gc;

    DMA_Setup(DMA_CHANNEL_0, SineWaveLowRes, (void *) &DAC.CH0DATA, SINE_WAVE_LOW_RES * 2, DMA_REPEAT_FOREVER);

   
    DAC_SingleChannel_Enable(
	&DAC,
	DAC_REFSEL_AVCC_gc,
	false
	);

    DMA_EnableChannel( DMA_CHANNEL_0 );

    // Enable medium interrupt level in PMIC and enable global interrupts.
    PMIC.CTRL |= PMIC_MEDLVLEN_bm;
    sei();

    TCC0.PER = TIMER_C0_PERIOD;
    // Enable Timer C0, prescaler div1 means Main Clock (2MHz).
    TCC0.CTRLA = ( TCC0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV1_gc;

			}
	
	  		else
	  		{
			dist=count*340.29;
			printf(dist);
			break;
			}





    }


 
	   		}
	   
          
      
}
	  
    
}


 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Its actually a code convertered from xmega 128A1 for A3BU.

I now have two errors while buidling, 1st one is this :

   /* Setup channel 0 to have differential input. */ 
   ADC_Ch_InputMode_and_Gain_Config(&ADC.CH0, 
                                 ADC_CH_INPUTMODE_DIFF_gc, 
                                    ADC_CH_GAIN_1X_gc);

it says ADC_CH_GAINFAC_gm undeclared. This dint happen when I build it for the xmega128A1 xplained. Am I missing something?

Second error is printf. it says implicit declaration of function prinf.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Second error is printf.
And where did you include stdio.h in your code to use printf? :wink:

Also to use floats you need to use the floating point libraries.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you! but this worked for Xmega 128 A1 xplained

   /* Setup channel 0 to have differential input. */ 
   ADC_Ch_InputMode_and_Gain_Config(&ADC.CH0, 
                                 ADC_CH_INPUTMODE_DIFF_gc, 
                                    ADC_CH_GAIN_1X_gc);

wondering why does it have an error here? Any advice?

Hm and also could you recommend me a floating point library? math.h does that work? thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The demo application for the A3BU explained is available in ASF and in Atmel Studio 6.x. In the ASF directory structure you can also find the low level drivers for the st7565r controller used by the display. The low level drivers don't use anything from ASF.

There is also a library announced a couple of weeks ago in this forum. Did you try that? It's this post by the way.

And this is a forum, so please ask questions in the forum. Not in PM.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Hm and also could you recommend me a floating point library? math.h does that work? thank you!

The only choice you get about math library is between libgcc.a and libm.a. Both use

It used to be the case that you had to explicitly use -lm to make sure libm.a was used because otherwise you got the default (inferior!) math support from libgcc.a but the most recent compiler/linker issues now automatically adds -lm at the end of the link. So to use FP just #include and call the functions and it should link with the best FP support available.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
but the most recent compiler/linker issues now automatically adds -lm
Quote:
I wrote this on the avr studio 4.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you all for the response, I am trying on the link that snigelen posted. I am currently using studio 4, hope it works.