ASF _adc_set_config() hangs forever on reg sync

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

Hi all,

I am on my first foray into Atmel devices, ARM devices and ASF, now I have a SAMD10 Xplained mini, that has a SAMD10D14 on it. So I am attempting a few basic test projects to get the lay of the land. I decided to start with a simple ADC project. But immediately I've run into a problem with one of the ASF functions that initialise the ADC simply hanging forever. I'm not sure if I've missed something out or what. I've been pouring over this for a day or two now but I'm going around in circles.

 

I started by creating a new GCC C ASF board project and using the ASF Wizard to add the ADC module to those already provided (generic board support driver, GPIO pin control driver & core system driver driver). My main.c consists of the following (apologies it seems this forum's code editor doesn't like to work):

 

#include <asf.h>

struct adc_config conf_adc;
struct adc_module adc_instance;

int main (void)

{

    /* Initialize all the system clocks, pm, global clock... */

    system_init();

    /* Configure voltage reference to use band gap */

    system_voltage_reference_enable(SYSTEM_VOLTAGE_REFERENCE_BANDGAP);

    /* ADC configuration */

    adc_get_config_defaults(&conf_adc);

    conf_adc.clock_source = GCLK_GENERATOR_1; /* 8MHz */

    conf_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV16; /* 512 kHz */

    conf_adc.reference = ADC_REFERENCE_INT1V; /* Internal 1v */

    conf_adc.positive_input = ADC_POSITIVE_INPUT_TEMP;

    conf_adc.negative_input = ADC_NEGATIVE_INPUT_GND;

    conf_adc.sample_length = 4; /* Samples = 4, Sample length = 4 */

    adc_init(&adc_instance, ADC, &conf_adc); // <----- This never returns!

    //ADC->AVGCTRL.reg = ADC_AVGCTRL_ADJRES(2) | ADC_AVGCTRL_SAMPLENUM_4;

    //adc_enable(&adc_instance);

    //...

 

The indicated line calls adc_init() from adc.c (ln 671, which itself calls _adc_set_config() (also in adc.c, ln 323). This latter function writes values to the ADC's registers to configure it.

 

About a third of the way in it starts using while loops to check for module synchronization, like:

 

    while (adc_is_syncing(module_inst)) { }

 

AFICT, there doesn't appear to be any correlation between what is being done by the surrounding code and where this checking starts. It does happen near access to registers that the datasheet mentions require synchronization. But then there are accesses to such registers before this (e.g. writing to CTRLA register on ln 364) that don't get this treatment and I don't see anything special in the intervening code that indicates why this should change?

 

Either way, the second one of these while loops (ln 543 in adc.h) just loops forever. Looking at the register value I can see that the STATUS.SYNCBUSY bit in question is indeed remaining at 1, instead of becoming 0 at some point. But I have no idea why. Is my setup preceding the ADC initialization, as shown above, incorrect or missing something?

 

Appreciate any help in this.

 

BR, T

This topic has a solution.
Last Edited: Fri. Nov 3, 2017 - 01:40 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Two and a bit days digging the datasheet to realise the generic clock generator was selected >.<

The following line from the code above: 

    conf_adc.clock_source = GCLK_GENERATOR_1; /* 8MHz */

Should have been:

    conf_adc.clock_source = GCLK_GENERATOR_0; /* 8MHz */

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

Struggled with exactly the same problem for three days!!! ....what makes this even more puzzling is if you load the "Example ASF Project" --ADC CONFIGURATIONS-- WORKS FINE  even though conf_adc.clock_source was set to GCLK_GENERATOR_1. I spent most of my time comparing the two projects with no avail. All I found was my ASF 'original' program freaked out when I try to set the CNTRLB register. What followed was the "stuck in sync" symptom.

Alas,

Thank you so much for this answer!!!!

Ed Wassung