Configuration for PWM Capture

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I have some basic knowledge about C and assembler programming, but I'm totally

new to ARM-Controllers and never did such 'complex' stuff I do now. I'm using the ASF

although I read it's not that good.

However I'm using a SAMD21 XPLAINED for programming and could need some help

with the PWM Capture.

 

So I have an external PWM signal I want to connect to my controller and determine

the frequency with a fairly good accuracy.

First suggestion was to multiplex the signal to the timer, detect on edge and let the

timer/counter count until next edge and then calculate the frequency.

Is this the best(only) solution ? I read somebody did connect his pwm signal as XOSC and used this

as the generic clock for his TC, calculated the pwm's frequency every 1s for example, is this a good idea ?

 

At the moment I'm struggling with the execution. I configured the source clock to 48MHz(I think) as well

as the timer in 32 bit mode.

Then I tried to get a clue on how I multiplex the signal to the TC. Here I tried to use the example event system driver.

I took example code and altered it to what i thought would work for me, but it didn't.

Then I thought i have to use the external interrupt driver because my signal is external and should

cause an immediate interrupt and let the TC start counting, here I did try the same like with the

event system driver, but it didn't work.

 

Now before i try some 'crazy' stuff I wanted to first ask for advice.

Which configurations do I need, the last thought was maybe both - external interrupt and event system - ?

Can i multiplex then an EXTINT to the TC, is that a good thought ?

Do i have to use a specific pin ? The docu of the d21 on page 21 shows multiplexing tables where you can see

peripheral functions, you can multiplex, on a pin. Is this maybe what i have to look at when deciding which pin I choose ?

 

Sry for so much text and thx for any help and suggestions.

 

My code is just some config, I mentioned above:

#include <asf.h>

//Prototypes
void configure_extosc32k(void);
void configure_dfll_open_loop(void);
void configure_port_pins(void);

#define PORTA PORT->Group[0]
#define PORTB PORT->Group[1]

// MAIN-FUNKTION
int main (void)
{
	// Board-Init
	system_init();

	// Global Interrupt Enable
	system_interrupt_enable_global();

	// CLOCK-CONFIG

	/* Configure the external 32KHz oscillator */
	configure_extosc32k();

	/* Enable ext. 32KHz oscillator */
	enum status_code osc32k_status = system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K);
	if (osc32k_status != STATUS_OK) {
		/* Error enabling the clock source */
	}

	/* Configure DFLL in open loop mode with default values */
	configure_dfll_open_loop();

	/* Enable DFLL oscillator */
	enum status_code dfll_status = system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL);

	if (dfll_status != STATUS_OK) {
		/* Error enabling clock source */
	}
	/* Configure flash wait states before switching to high frequency clock */
	system_flash_set_waitstates(2);

	/* Change system clock to DFLL */
	struct system_gclk_gen_config config_gclock_gen;
	system_gclk_gen_get_config_defaults(&config_gclock_gen);
	config_gclock_gen.source_clock    = SYSTEM_CLOCK_SOURCE_DFLL;
	config_gclock_gen.division_factor = 1;
	config_gclock_gen.output_enable = 1;
	system_gclk_gen_set_config(GCLK_GENERATOR_0, &config_gclock_gen);

	// PORT-CONFIG

	configure_port_pins();

	// COUNTER-CONFIG

	// Config-struct for TC
	struct tc_config config_tc;

	// Default-Config for TC
	tc_get_config_defaults(&config_tc);

	// set TC on 32-Bit MAX. size
	config_tc.counter_size		= TC_COUNTER_SIZE_32BIT;
	config_tc.wave_generation	= TC_WAVE_GENERATION_NORMAL_FREQ;
	config_tc.clock_source		= GCLK_GENERATOR_0;
	config_tc.clock_prescaler	= TC_CLOCK_PRESCALER_DIV1;

	// Module-struct
	struct tc_module tc;

	// TC initialize/enable
	tc_init(&tc, TC4, &config_tc);
	tc_enable(&tc);

	// TC-Start
	tc_start_counter(&tc);

	/* Insert application code here, after the board has been initialized. */

	while (true) {
		bool pin_state = port_pin_get_input_level(PIN_PB22);
		port_pin_set_output_level(LED_0_PIN, !pin_state);
	}

	while (1)
	{

	}
}

// FUNCTIONS
void configure_extosc32k(void)
{
	struct system_clock_source_xosc32k_config config_ext32k;
	system_clock_source_xosc32k_get_config_defaults(&config_ext32k);

	config_ext32k.startup_time = SYSTEM_XOSC32K_STARTUP_4096;

	system_clock_source_xosc32k_set_config(&config_ext32k);
}

void configure_dfll_open_loop(void)
{
	struct system_clock_source_dfll_config config_dfll;
	system_clock_source_dfll_get_config_defaults(&config_dfll);

	system_clock_source_dfll_set_config(&config_dfll);
}

void configure_port_pins(void)
{
	struct port_config config_port_pin;
	port_get_config_defaults(&config_port_pin);
	config_port_pin.direction  = PORT_PIN_DIR_INPUT;
	config_port_pin.input_pull = PORT_PIN_PULL_UP;
	port_pin_set_config(PIN_PB22, &config_port_pin);
	config_port_pin.direction = PORT_PIN_DIR_OUTPUT;
	port_pin_set_config(LED_0_PIN, &config_port_pin);
}