int main(void)
{
	enum sleepmgr_mode      current_sleep_mode = SLEEPMGR_ACTIVE;
	uint32_t                ast_counter = 0;

	/*
	 * Initialize the synchronous clock system to the default configuration
	 * set in conf_clock.h.
	 * \note All non-essential peripheral clocks are initially disabled.
	 */
	sysclk_init();

	/*
	 * Initialize the resources used by this example to the default
	 * configuration set in conf_board.h
	 */
	board_init();

	/*
	 * Turn the activity status LED on to inform the user that the device
	 * is active.
	 */
	gpio_set_pin_low(LED_ACTIVITY_STATUS_PIN);

	/*
	 * Configure pin change interrupt for asynchronous wake-up (required to
	 * wake up from the STATIC sleep mode) and enable the EIC clock.
	 *
	 * First, enable the clock for the EIC module.
	 */
	sysclk_enable_pba_module(SYSCLK_EIC);
	/*
	 * Map the interrupt line to the GPIO pin with the right peripheral
	 * function.
	 */
	gpio_enable_module_pin(WAKE_BUTTON_EIC_PIN, WAKE_BUTTON_EIC_FUNCTION);
	/*
	 * Enable the internal pull-up resistor on that pin (because the EIC is
	 * configured such that the interrupt will trigger on low-level, see
	 * eic_options.eic_level).
	 */
	gpio_enable_pin_pull_up(WAKE_BUTTON_EIC_PIN);
	// Init the EIC controller with the options
	eic_init(&AVR32_EIC, &eic_options, sizeof(eic_options) /
			sizeof(eic_options_t));
	// Enable External Interrupt Controller Line
	eic_enable_line(&AVR32_EIC, WAKE_BUTTON_EIC_LINE);

	// Enable the AST clock.
	sysclk_enable_pba_module(SYSCLK_AST);
	// Initialize the AST in Counter mode
	ast_init_counter(&AVR32_AST, AST_OSC_RC, AST_PSEL_RC_1_76HZ,
			ast_counter);
	/*
	 * Configure the AST to wake up the CPU when the counter reaches the
	 * selected alarm0 value.
	 */
	AVR32_AST.WER.alarm0 = 1;
	// Enable the AST
	ast_enable(&AVR32_AST);

	// Initialize the sleep manager, lock initial mode.
	sleepmgr_init();
	sleepmgr_lock_mode(current_sleep_mode);

	while (1) {
		ast_counter = ast_get_counter_value(&AVR32_AST);
		// disable alarm 0
		ast_disable_alarm0(&AVR32_AST);
		// Set Alarm to current time + (6/1.76) seconds
		ast_counter += 6;
		ast_set_alarm0_value(&AVR32_AST, ast_counter);
		// Enable alarm 0
		ast_enable_alarm0(&AVR32_AST);

		/*
		 * Turn the activity status LED off to inform the user that the
		 * device is in a sleep mode.
		 */
		gpio_set_pin_high(LED_ACTIVITY_STATUS_PIN);

		/*
		 * Go to sleep in the deepest allowed sleep mode (i.e. no
		 * deeper than the currently locked sleep mode).
		 */
		sleepmgr_enter_sleep();

		/*
		 * Turn the activity status LED on to inform the user that the
		 * device is active.
		 */
		gpio_set_pin_low(LED_ACTIVITY_STATUS_PIN);

		// After wake up, clear the Alarm0
		AVR32_AST.SCR.alarm0 = 1;

		// Unlock the current sleep mode.
		sleepmgr_unlock_mode(current_sleep_mode);

		// Add a 3s delay
		cpu_delay_ms(3000, sysclk_get_cpu_hz());

		// Clear the External Interrupt Line (in case it was raised).
		eic_clear_interrupt_line(&AVR32_EIC, WAKE_BUTTON_EIC_LINE);

		// Lock the next sleep mode.
		++current_sleep_mode;
		if ((current_sleep_mode >= SLEEPMGR_NR_OF_MODES)
#if UC3L && (BOARD == UC3L_EK)
		/* Note concerning the SHUTDOWN sleep mode: the shutdown sleep
		 * mode can only be used when the UC3L supply mode is the 3.3V
		 * Supply Mode with 1.8V Regulated I/O Lines. That is not how
		 * the UC3L is powered on the ATUC3L-EK so the SHUTDOWN mode
		 * cannot be used on this board. Thus we skip this sleep mode
		 * in this example for this board.
		 */
			|| (current_sleep_mode == SLEEPMGR_SHUTDOWN)
#endif
			) {
			current_sleep_mode = SLEEPMGR_ACTIVE;
		}

		sleepmgr_lock_mode(current_sleep_mode);
	}
}
Example #2
0
/*!
 * \brief main function : do init and loop (poll if configured so)
 */
int main(void)
{
	char temp[20];
	char *ptemp;
	uint32_t ast_alarm;

	static const gpio_map_t USART_GPIO_MAP = {
		{EXAMPLE_USART_RX_PIN, EXAMPLE_USART_RX_FUNCTION},
		{EXAMPLE_USART_TX_PIN, EXAMPLE_USART_TX_FUNCTION}
	};

	/* USART options */
	static const usart_options_t USART_OPTIONS = {
		.baudrate     = 57600,
		.charlength   = 8,
		.paritytype   = USART_NO_PARITY,
		.stopbits     = USART_1_STOPBIT,
		.channelmode  = 0
	};

#if BOARD == UC3L_EK
	scif_osc32_opt_t opt = {
		/* 2-pin Crystal connected to XIN32/XOUT32 and high current
		 * mode. */
		SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR,
		/* oscillator startup time */
		AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC,
		/* select alternate xin32_2 and xout32_2 for 32kHz crystal
		 * oscillator */
		true,
		/* disable the 1kHz output */
		false,
		/* enable the 32kHz output */
		true
	};
#else
	scif_osc32_opt_t opt;
	opt.mode = SCIF_OSC_MODE_2PIN_CRYSTAL;
	opt.startup = AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC;
#endif

#if BOARD == UC3L_EK

	/*
	 * Note: on the AT32UC3L-EK board, there is no crystal/external clock
	 * connected to the OSC0 pinout XIN0/XOUT0. We shall then program the
	 * DFLL and switch the main clock source to the DFLL.
	 */
	pcl_configure_clocks(&pcl_dfll_freq_param);

	/*
	 * Note: since it is dynamically computing the appropriate field values
	 * of the configuration registers from the parameters structure, this
	 * function is not optimal in terms of code size. For a code size
	 * optimal solution, it is better to create a new function from
	 * pcl_configure_clocks_dfll0() and modify it to use preprocessor
	 * computation from pre-defined target frequencies.
	 */
#else
	pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);
#endif

	/* Start OSC_32KHZ */
	scif_start_osc32(&opt, true);

	/* Assign GPIO pins to USART0. */
	gpio_enable_module(USART_GPIO_MAP,
			sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0]));

	/* Initialize USART in RS232 mode */
	usart_init_rs232(EXAMPLE_USART, &USART_OPTIONS, FPBA);

	/* Welcome sentence // 2-pin Crystal and high current mode. */
	/* Crystal is connected to XIN32/XOUT32. */
	usart_write_line(EXAMPLE_USART, "\x1B[2J\x1B[H\r\nATMEL\r\n");
	usart_write_line(EXAMPLE_USART, "AVR32 UC3 - AST example 2\r\n");
	usart_write_line(EXAMPLE_USART,
			"AST 32 KHz oscillator counter example.\r\n");
	usart_write_line(EXAMPLE_USART,
			"Alarm0 wakeup from static sleep mode every second.\r\n");

	/* Using counter mode and set it to 0 */
	unsigned long ast_counter = 0;

	/* Initialize the AST */
	if (!ast_init_counter(&AVR32_AST,
			AST_OSC_32KHZ, AST_PSEL_32KHZ_1HZ, ast_counter)) {
		usart_write_line(EXAMPLE_USART,
				"Error initializing the AST\r\n");
		while (1) {
		}
	}

	/* Alarm 0 sends a wakeup signal to the Power manager */
	ast_enable_alarm_async_wakeup(&AVR32_AST, 0);

	/* Enable the AST */
	ast_enable(&AVR32_AST);

	while (1) {
		/* disable alarm 0 */
		ast_disable_alarm0(&AVR32_AST);

		/* ast_init_counter Set Alarm to current time+30 seconds */
		ast_alarm = ast_counter + 1;
		ast_set_alarm0_value(&AVR32_AST, ast_alarm);

		/* Enable alarm 0 */
		ast_enable_alarm0(&AVR32_AST);

		/*
		 * Precautions when entering a sleep mode
		 * Modules communicating with external circuits should normally
		 * be disabled before entering a sleep mode that will stop the
		 * module operation.
		 * Make sure the USART dumps the last message completely before
		 * turning it off.
		 */
		while (!usart_tx_empty(EXAMPLE_USART)) {
		}
		pcl_disable_module(EXAMPLE_USART_CLOCK_MASK);

		/*
		 * Since we're going into a sleep mode deeper than IDLE, all HSB
		 * masters must be stopped before entering the sleep mode.
		 * Note: since we're not using the PDCA, we don't have to stop
		 *it.
		 */

		/*
		 * If there is a chance that any PB write operations are
		 *incomplete,
		 * the CPU should perform a read operation from any register on
		 *the
		 * PB bus before executing the sleep instruction.
		 */
		AVR32_INTC.ipr[0];  /* Dummy read */

		/* Go into static sleep mode */
		SLEEP(AVR32_PM_SMODE_STATIC);

		/* We're out of the static sleep mode now => re-enable the USART
		 * module */
		pcl_enable_module(EXAMPLE_USART_CLOCK_MASK);

		/* After wake up, clear the Alarm0 */
		ast_clear_alarm_status_flag(&AVR32_AST, 0);

		/* Toggle Led0 */
		gpio_tgl_gpio_pin(LED0_GPIO);

		/* Set cursor to the position (1; 6) */
		usart_write_line(EXAMPLE_USART, "\x1B[6;1H");
		ast_counter = ast_get_counter_value(&AVR32_AST);
		usart_write_line(EXAMPLE_USART, "Timer: ");
		ptemp = print_i(temp, ast_counter);
		usart_write_line(EXAMPLE_USART, ptemp);
		usart_write_line(EXAMPLE_USART, " sec ");
	}
}