Making use of TC channel 3(TC2) in Atmel studio

hi everyone!

my name is taehyung, in south korea..
i have a problem in my project short pulse generate.

#include "asf.h"
#include "conf_board.h"
#include "conf_clock.h"

#define STRING_EOL    "\r"
#define STRING_HEADER "--TC capture waveform Example --\r\n" \
		"-- "BOARD_NAME " --\r\n" \
		"-- Compiled: "__DATE__ " "__TIME__ " --"STRING_EOL

#define TC_CAPTURE_TIMER_SELECTION TC_CMR_TCCLKS_TIMER_CLOCK3

#define TC_CHANNEL_6	6
#define TC_CHANNEL_7	7
#define TC_CHANNEL_8	8

struct waveconfig_t {
	/** Internal clock signals selection. */
	uint32_t ul_intclock;
	/** Waveform frequency (in Hz). */
	uint16_t us_frequency;
	/** Duty cycle in percent (positive).*/
	uint16_t us_dutycycle;
};

/** TC waveform configurations */
static const struct waveconfig_t gc_waveconfig[] = {
	{TC_CMR_TCCLKS_TIMER_CLOCK4, 178, 30},
	{TC_CMR_TCCLKS_TIMER_CLOCK3, 375, 50},
	{TC_CMR_TCCLKS_TIMER_CLOCK3, 800, 75},
	{TC_CMR_TCCLKS_TIMER_CLOCK2, 1000, 80},
	{TC_CMR_TCCLKS_TIMER_CLOCK2, 4000, 55}
};

#if (SAM4L)
/* The first one is meaningless */
static const uint32_t divisors[5] = { 0, 2, 8, 32, 128};
#else
/* The last one is meaningless */
static const uint32_t divisors[5] = { 2, 8, 32, 128, 0};
#endif

/** Current wave configuration*/
static uint8_t gs_uc_configuration = 0;

/** Number of available wave configurations */
const uint8_t gc_uc_nbconfig = sizeof(gc_waveconfig)
		/ sizeof(struct waveconfig_t);

/** Capture status*/
static uint32_t gs_ul_captured_pulses;
static uint32_t gs_ul_captured_ra;
static uint32_t gs_ul_captured_rb;

/**
 * \brief Display the user menu on the UART.
 */
static void display_menu(void)
{
	uint8_t i;
	puts("\n\rMenu :\n\r"
			"------\n\r"
			"  Output waveform property:\r");
	for (i = 0; i < gc_uc_nbconfig; i++) {
		printf("  %d: Set Frequency = %4u Hz, Duty Cycle = %2u%%\n\r", i,
				(unsigned int)gc_waveconfig[i].us_frequency,
				(unsigned int)gc_waveconfig[i].us_dutycycle);
	}
	printf("  -------------------------------------------\n\r"
			"  c: Capture waveform from TC%d channel %d\n\r"
			"  s: Stop capture and display captured informations \n\r"
			"  h: Display menu \n\r"
			"------\n\r\r", TC_PERIPHERAL,TC_CHANNEL_CAPTURE);
}

/**
 * \brief Configure TC TC_CHANNEL_WAVEFORM in waveform operating mode.
 */
static void tc_waveform_initialize(void)
{
	uint32_t ra, rc;

	/* Configure the PMC to enable the TC module. */
	sysclk_enable_peripheral_clock(ID_TC6);

	/* Init TC to waveform mode. */
	tc_init(TC2, TC_CHANNEL_8,
			/* Waveform Clock Selection */
			gc_waveconfig[gs_uc_configuration].ul_intclock
			| TC_CMR_WAVE /* Waveform mode is enabled */
			| TC_CMR_ACPA_SET /* RA Compare Effect: set */
			| TC_CMR_ACPC_CLEAR /* RC Compare Effect: clear */
			| TC_CMR_CPCTRG /* UP mode with automatic trigger on RC Compare */
	);

	/* Configure waveform frequency and duty cycle. */
	rc = (sysclk_get_peripheral_bus_hz(TC2) /
			divisors[gc_waveconfig[gs_uc_configuration].ul_intclock]) /
			gc_waveconfig[gs_uc_configuration].us_frequency;
	tc_write_rc(TC2, TC_CHANNEL_8, rc);
	ra = (100 - gc_waveconfig[gs_uc_configuration].us_dutycycle) * rc / 100;
	tc_write_ra(TC2, TC_CHANNEL_8, ra);

	/* Enable TC TC_CHANNEL_WAVEFORM. */
	tc_start(TC2, TC_CHANNEL_8);
	printf("Start waveform: Frequency = %d Hz,Duty Cycle = %2d%%\n\r",
			gc_waveconfig[gs_uc_configuration].us_frequency,
			gc_waveconfig[gs_uc_configuration].us_dutycycle);
}

/**
 * \brief Configure TC TC_CHANNEL_CAPTURE in capture operating mode.
 */
static void tc_capture_initialize(void)
{
	/* Configure the PMC to enable the TC module */
	sysclk_enable_peripheral_clock(ID_TC_CAPTURE);

	/* Init TC to capture mode. */
	tc_init(TC, TC_CHANNEL_CAPTURE,
			TC_CAPTURE_TIMER_SELECTION /* Clock Selection */
			| TC_CMR_LDRA_RISING /* RA Loading: rising edge of TIOA */
			| TC_CMR_LDRB_FALLING /* RB Loading: falling edge of TIOA */
			| TC_CMR_ABETRG /* External Trigger: TIOA */
			| TC_CMR_ETRGEDG_FALLING /* External Trigger Edge: Falling edge */
	);
}

/**
 * \brief Interrupt handler for the TC TC_CHANNEL_CAPTURE
 */
void TC_Handler(void)
{
	if ((tc_get_status(TC, TC_CHANNEL_CAPTURE) & TC_SR_LDRBS) == TC_SR_LDRBS) {
		gs_ul_captured_pulses++;
		gs_ul_captured_ra = tc_read_ra(TC, TC_CHANNEL_CAPTURE);
		gs_ul_captured_rb = tc_read_rb(TC, TC_CHANNEL_CAPTURE);
	}
}

/**
 *  Configure UART console.
 */
static void configure_console(void)
{
	const usart_serial_options_t uart_serial_options = {
		.baudrate = CONF_UART_BAUDRATE,
#ifdef CONF_UART_CHAR_LENGTH
		.charlength = CONF_UART_CHAR_LENGTH,
#endif
		.paritytype = CONF_UART_PARITY,
#ifdef CONF_UART_STOP_BITS
		.stopbits = CONF_UART_STOP_BITS,
#endif
	};

	/* Configure console UART. */
	stdio_serial_init(CONF_UART, &uart_serial_options);
}

/**
 * \brief Application entry point for tc_capture_waveform example.
 *
 * \return Unused (ANSI-C compatibility).
 */

uint32_t tc_read_cmr(Tc *p_tc, uint32_t ul_channel)
{
	Assert(ul_channel <
	(sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));

	return p_tc->TC_CHANNEL[ul_channel].TC_CMR;
}

int main(void)
{
	uint8_t key;
	uint16_t frequence, dutycycle;

	/* Initialize the SAM system */
	sysclk_init();
	board_init();

	/* Initialize the console uart */
	configure_console();

	/* Output example information */
	printf("-- TC capture waveform Example --\r\n");
	printf("-- %s\n\r", BOARD_NAME);
	printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);

	/* Configure PIO Pins for TC */
	ioport_set_pin_mode(PIO_PD7_IDX, IOPORT_MODE_MUX_B);
	/* Disable IO to enable peripheral mode) */
	ioport_disable_pin(PIO_PD7_IDX);
	ioport_set_pin_mode(PIN_TC_CAPTURE, PIN_TC_CAPTURE_MUX);
	/* Disable IO to enable peripheral mode) */
	ioport_disable_pin(PIN_TC_CAPTURE);

	/* Configure TC TC_CHANNEL_WAVEFORM as waveform operating mode */
	printf("Configure TC%d channel %d as waveform operating mode \n\r",
			TC_PERIPHERAL, TC_CHANNEL_WAVEFORM);
	tc_waveform_initialize();
        
	/* Configure TC TC_CHANNEL_CAPTURE as capture operating mode */
	printf("Configure TC%d channel %d as capture operating mode \n\r",
			TC_PERIPHERAL, TC_CHANNEL_CAPTURE);
	tc_capture_initialize();

	/* Configure TC interrupts for TC TC_CHANNEL_CAPTURE only */
	NVIC_DisableIRQ(TC_IRQn);
	NVIC_ClearPendingIRQ(TC_IRQn);
	NVIC_SetPriority(TC_IRQn, 0);
	NVIC_EnableIRQ(TC_IRQn);

	/* Display menu */
	display_menu();
	
	printf("check register : %x %x %x \n\r", tc_read_ra(TC2, TC_CHANNEL_6), tc_read_rc(TC2, TC_CHANNEL_6), tc_read_cmr(TC2, TC_CHANNEL_6));
	
	while (1) {
		scanf("%c", (char *)&key);

		switch (key) {
		case 'h':
			display_menu();
			break;

		case 's':
			if (gs_ul_captured_pulses) {
				tc_disable_interrupt(TC, TC_CHANNEL_CAPTURE, TC_IDR_LDRBS);
				printf("Captured %u pulses from TC%d channel %d, RA = %u, RB = %u \n\r",
						(unsigned)gs_ul_captured_pulses, TC_PERIPHERAL,
						TC_CHANNEL_CAPTURE,	(unsigned)gs_ul_captured_ra,
						(unsigned)gs_ul_captured_rb);
				frequence = (sysclk_get_peripheral_bus_hz(TC) /
						divisors[TC_CAPTURE_TIMER_SELECTION]) /
						gs_ul_captured_rb;
				dutycycle
					= (gs_ul_captured_rb - gs_ul_captured_ra) * 100 /
						gs_ul_captured_rb;
				printf("Captured wave frequency = %d Hz, Duty cycle = %d%% \n\r",
						frequence, dutycycle);

				gs_ul_captured_pulses = 0;
				gs_ul_captured_ra = 0;
				gs_ul_captured_rb = 0;
			} else {
				puts("No waveform has been captured\r");
			}

			puts("\n\rPress 'h' to display menu\r");
			break;

		case 'c':
			puts("Start capture, press 's' to stop \r");
			tc_enable_interrupt(TC, TC_CHANNEL_CAPTURE, TC_IER_LDRBS);
			/* Start the timer counter on TC TC_CHANNEL_CAPTURE */
			tc_start(TC, TC_CHANNEL_CAPTURE);
			break;

		default:
			/* Set waveform configuration #n */
			if ((key >= '0') && (key <= ('0' + gc_uc_nbconfig - 1))) {
				if (!gs_ul_captured_pulses) {
					gs_uc_configuration = key - '0';
					tc_waveform_initialize();
				} else {
					puts("Capturing ... , press 's' to stop capture first \r");
				}
			}

			break;
		}
	}
}

the code above is example TC_TC_CAPTURE_WAVEFORM_EXAMPLE offered form atmel studio..

already i succeed using tc_channel 0~tc_channel 2 included in TC0

according to the manual ATSAM3X8E support TC0 and TC2 .

so first, i change code simply only regarded tc_waveforms. but the tc_channel 6~8 are naver work. ??

if you are expert and know solvation ... please reply for me.. thank you!

As far as I know, each TC got 3 channels. So 3x3=9 channels total. Take a look at the datasheet.

thancks Gericom for your reply..

i already know that... i'm using ATSAM3X8E.. TC1 only operable in ATSAM3X8H chip ..
becouse TC1 assigned PIO_PE .... so ATSAM3X8E only support TC0 and TC2..

in the example project include waveform and wave capture function..

so i try simply change only waveform function

// original code in main function and header files...
//in "conf_board.h"
/** Use TC Peripheral 0 **/
#define TC  TC0
#define TC_PERIPHERAL  0

/** Configure TC0 channel 1 as waveform output. **/
#define TC_CHANNEL_WAVEFORM 1
#define ID_TC_WAVEFORM      ID_TC1
#define PIN_TC_WAVEFORM     PIN_TC0_TIOA1
#define PIN_TC_WAVEFORM_MUX PIN_TC0_TIOA1_MUX
/////////////////////////////////////////////////////////

//in "arduino_due_x.h"
#define PIN_TC0_TIOA1           (PIO_PA2_IDX)
#define PIN_TC0_TIOA1_MUX       (IOPORT_MODE_MUX_A)
#define PIN_TC0_TIOA1_FLAGS     (PIO_PERIPH_A | PIO_DEFAULT)

#define PIN_TC0_TIOA1_PIO     PIOA
#define PIN_TC0_TIOA1_MASK    PIO_PA2
#define PIN_TC0_TIOA1_ID      ID_PIOA
#define PIN_TC0_TIOA1_TYPE    PIO_PERIPH_A
#define PIN_TC0_TIOA1_ATTR    PIO_DEFAULT
///////////////////////////////////////

// original example firle tc_capture_waveform_example.c
static void tc_waveform_initialize(void)
{
	uint32_t ra, rc;

	/* Configure the PMC to enable the TC module. */
	sysclk_enable_peripheral_clock(ID_TC_WAVEFORM);

	/* Init TC to waveform mode. */
	tc_init(TC, TC_CHANNEL_WAVEFORM,
			/* Waveform Clock Selection */
			gc_waveconfig[gs_uc_configuration].ul_intclock
			| TC_CMR_WAVE /* Waveform mode is enabled */
			| TC_CMR_ACPA_SET /* RA Compare Effect: set */
			| TC_CMR_ACPC_CLEAR /* RC Compare Effect: clear */
			| TC_CMR_CPCTRG /* UP mode with automatic trigger on RC Compare */
	);

	/* Configure waveform frequency and duty cycle. */
	rc = (sysclk_get_peripheral_bus_hz(TC) /
			divisors[gc_waveconfig[gs_uc_configuration].ul_intclock]) /
			gc_waveconfig[gs_uc_configuration].us_frequency;
	tc_write_rc(TC, TC_CHANNEL_WAVEFORM, rc);
	ra = (100 - gc_waveconfig[gs_uc_configuration].us_dutycycle) * rc / 100;
	tc_write_ra(TC, TC_CHANNEL_WAVEFORM, ra);

	/* Enable TC TC_CHANNEL_WAVEFORM. */
	tc_start(TC, TC_CHANNEL_WAVEFORM);
	printf("Start waveform: Frequency = %d Hz,Duty Cycle = %2d%%\n\r",
			gc_waveconfig[gs_uc_configuration].us_frequency,
			gc_waveconfig[gs_uc_configuration].us_dutycycle);
}
/////////////// in main funtion///////////
int main(void)
{
.
.
.

/* Configure PIO Pins for TC */
	ioport_set_pin_mode(PIO_PD7_IDX, IOPORT_MODE_MUX_B);
	/* Disable IO to enable peripheral mode) */
	ioport_disable_pin(PIO_PD7_IDX);

.
.
.

	tc_waveform_initialize();

i changed and added as below

#define TC_CHANNEL_6	6
#define TC_CHANNEL_7	7
#define TC_CHANNEL_8	8

.
.
.

static void tc_waveform_initialize(void)
{
	uint32_t ra, rc;

	/* Configure the PMC to enable the TC module. */
	sysclk_enable_peripheral_clock(ID_TC6);

	/* Init TC to waveform mode. */
	tc_init(TC2, TC_CHANNEL_6,
			/* Waveform Clock Selection */
			gc_waveconfig[gs_uc_configuration].ul_intclock
			| TC_CMR_WAVE /* Waveform mode is enabled */
			| TC_CMR_ACPA_SET /* RA Compare Effect: set */
			| TC_CMR_ACPC_CLEAR /* RC Compare Effect: clear */
			| TC_CMR_CPCTRG /* UP mode with automatic trigger on RC Compare */
	);

	/* Configure waveform frequency and duty cycle. */
	rc = (sysclk_get_peripheral_bus_hz(TC2) /
			divisors[gc_waveconfig[gs_uc_configuration].ul_intclock]) /
			gc_waveconfig[gs_uc_configuration].us_frequency;
	tc_write_rc(TC2, TC_CHANNEL_6, rc);
	ra = (100 - gc_waveconfig[gs_uc_configuration].us_dutycycle) * rc / 100;
	tc_write_ra(TC2, TC_CHANNEL_6, ra);

	/* Enable TC TC_CHANNEL_WAVEFORM. */
	tc_start(TC2, TC_CHANNEL_6);
	printf("Start waveform: Frequency = %d Hz,Duty Cycle = %2d%%\n\r",
			gc_waveconfig[gs_uc_configuration].us_frequency,
			gc_waveconfig[gs_uc_configuration].us_dutycycle);
}


/////////////// in main funtion///////////
int main(void)
{
.
.
.

/* Configure PIO Pins for TC */
	ioport_set_pin_mode(PIO_PC25_IDX, IOPORT_MODE_MUX_B);
	/* Disable IO to enable peripheral mode) */
	ioport_disable_pin(PIO_PC25_IDX);

.
.
.

	tc_waveform_initialize();

i think this coding is enough to make waveform in the port C25

i don't no why do not work this function..

if someone fine what's wrong... please answer for me .. thanks~

You can use TC1 for timer interrupts on sam3x8e, but not for pin related things.