//! [setup]
void configure_gclock_generator(void)
{
//! [setup_1]
	struct system_gclk_gen_config gclock_gen_conf;
//! [setup_1]
//! [setup_2]
	system_gclk_gen_get_config_defaults(&gclock_gen_conf);
//! [setup_2]

#if (SAML21)
//! [setup_3]
	gclock_gen_conf.source_clock    = SYSTEM_CLOCK_SOURCE_OSC16M;
	gclock_gen_conf.division_factor = 128;
//! [setup_3]
#else
//! [setup_3]
	gclock_gen_conf.source_clock    = SYSTEM_CLOCK_SOURCE_OSC8M;
	gclock_gen_conf.division_factor = 128;
//! [setup_3]
#endif

//! [setup_4]
	system_gclk_gen_set_config(GCLK_GENERATOR_1, &gclock_gen_conf);
//! [setup_4]

//! [setup_5]
	system_gclk_gen_enable(GCLK_GENERATOR_1);
//! [setup_5]
}
int main(void)
{
//! [main]
	/* Configure the external 32KHz oscillator */
//! [config_extosc32k_main]
	configure_extosc32k();
//! [config_extosc32k_main]

	/* Enable the external 32KHz oscillator */
//! [enable_extosc32k_main]
	enum status_code osc32k_status =
			system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K);

	if (osc32k_status != STATUS_OK) {
		/* Error enabling the clock source */
	}
//! [enable_extosc32k_main]

	/* Configure the DFLL in open loop mode using default values */
//! [config_dfll_main]
	configure_dfll_open_loop();
//! [config_dfll_main]

	/* Enable the DFLL oscillator */
//! [enable_dfll_main]
	enum status_code dfll_status =
			system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL);

	if (dfll_status != STATUS_OK) {
		/* Error enabling the clock source */
	}
//! [enable_dfll_main]

	/* Configure flash wait states before switching to high frequency clock */
//! [set_sys_wait_states]
	system_flash_set_waitstates(2);
//! [set_sys_wait_states]

	/* Change system clock to DFLL */
//! [set_sys_clk_src]
	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;
	system_gclk_gen_set_config(GCLK_GENERATOR_0, &config_gclock_gen);
//! [set_sys_clk_src]
//! [main]

	while (true) {

	}
}
/** Configures and starts the DFLL in closed loop mode with the given reference
 *  generator.
 *
 *  \param[in]  source_generator  Reference generator to use for the DFLL
 */
static void init_dfll(
		const enum system_clock_source source_generator)
{
	struct system_gclk_gen_config cpu_clock_conf;
	system_gclk_gen_get_config_defaults(&cpu_clock_conf);
	cpu_clock_conf.output_enable = ENABLE_CPU_CLOCK_OUT;

	/* Switch to OSC8M/OSC16M while the DFLL is being reconfigured */
#if SAML21
	cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC16M;
#else
	cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC8M;
#endif
	system_gclk_gen_set_config(GCLK_GENERATOR_0, &cpu_clock_conf);

	/* Turn off DFLL before adjusting its configuration */
	system_clock_source_disable(SYSTEM_CLOCK_SOURCE_DFLL);

	/* Configure DFLL reference clock, use raw register write to
	 * force-configure the channel even if the currently selected generator
	 * clock has failed */
#if SAML21
        GCLK->PCHCTRL[SYSCTRL_GCLK_ID_DFLL48].reg = GCLK_PCHCTRL_GEN(source_generator);      
#else
	GCLK->CLKCTRL.reg =
			GCLK_CLKCTRL_ID(SYSCTRL_GCLK_ID_DFLL48) |
			GCLK_CLKCTRL_GEN(source_generator);
#endif
	system_gclk_chan_enable(SYSCTRL_GCLK_ID_DFLL48);

	/* Configure DFLL */
	struct system_clock_source_dfll_config config_dfll;
	system_clock_source_dfll_get_config_defaults(&config_dfll);
	config_dfll.on_demand = false;
	config_dfll.loop_mode = SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED;
	config_dfll.multiply_factor =
			(48000000UL / system_gclk_chan_get_hz(SYSCTRL_GCLK_ID_DFLL48));
	system_clock_source_dfll_set_config(&config_dfll);

	/* Restart DFLL */
	system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL);
	while (system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_DFLL) == false) {
		/* Wait for DFLL to be stable before switch back */
	}

	/* Switch back to the DFLL as the CPU clock source */
	cpu_clock_conf.source_clock = SYSTEM_CLOCK_SOURCE_DFLL;
	system_gclk_gen_set_config(GCLK_GENERATOR_0, &cpu_clock_conf);
};
/** Initializes the XOSC32K crystal failure detector, and starts it.
 *
 *  \param[in]  ok_callback    Callback function to run upon XOSC32K operational
 *  \param[in]  fail_callback  Callback function to run upon XOSC32K failure
 */
static void init_xosc32k_fail_detector(
		const tc_callback_t ok_callback,
		const tc_callback_t fail_callback)
{
	/* TC pairs share the same clock, ensure reference and crystal timers use
	 * different clocks */
	Assert(Abs(_tc_get_inst_index(CONF_TC_OSC32K) -
			_tc_get_inst_index(CONF_TC_XOSC32K)) >= 2);

	/* The crystal detection cycle count must be less than the reference cycle
	 * count, so that the reference timer is periodically reset before expiry */
	Assert(CRYSTAL_RESET_CYCLES < CRYSTAL_FAIL_CYCLES);

	/* Must use different clock generators for the crystal and reference, must
	 * not be CPU generator 0 */
	Assert(GCLK_GENERATOR_XOSC32K != GCLK_GENERATOR_OSC32K);
	Assert(GCLK_GENERATOR_XOSC32K != GCLK_GENERATOR_0);
	Assert(GCLK_GENERATOR_OSC32K  != GCLK_GENERATOR_0);

	/* Configure and enable the XOSC32K GCLK generator */
	struct system_gclk_gen_config xosc32k_gen_conf;
	system_gclk_gen_get_config_defaults(&xosc32k_gen_conf);
	xosc32k_gen_conf.source_clock = SYSTEM_CLOCK_SOURCE_XOSC32K;
	system_gclk_gen_set_config(GCLK_GENERATOR_XOSC32K, &xosc32k_gen_conf);
	system_gclk_gen_enable(GCLK_GENERATOR_XOSC32K);

	/* Configure and enable the reference clock GCLK generator */
	struct system_gclk_gen_config ref_gen_conf;
	system_gclk_gen_get_config_defaults(&ref_gen_conf);
	ref_gen_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC32K;
	system_gclk_gen_set_config(GCLK_GENERATOR_OSC32K, &ref_gen_conf);
	system_gclk_gen_enable(GCLK_GENERATOR_OSC32K);

	/* Set up crystal counter - when target count elapses, trigger event */
	struct tc_config tc_xosc32k_conf;
	tc_get_config_defaults(&tc_xosc32k_conf);
	tc_xosc32k_conf.clock_source = GCLK_GENERATOR_XOSC32K;
	tc_xosc32k_conf.counter_16_bit.compare_capture_channel[0] =
			CRYSTAL_RESET_CYCLES;
	tc_xosc32k_conf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;
	tc_init(&tc_xosc32k, CONF_TC_XOSC32K, &tc_xosc32k_conf);

	/* Set up reference counter - when event received, restart */
	struct tc_config tc_osc32k_conf;
	tc_get_config_defaults(&tc_osc32k_conf);
	tc_osc32k_conf.clock_source = GCLK_GENERATOR_OSC32K;
	tc_osc32k_conf.counter_16_bit.compare_capture_channel[0] =
			CRYSTAL_FAIL_CYCLES;
	tc_osc32k_conf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;
	tc_init(&tc_osc32k, CONF_TC_OSC32K, &tc_osc32k_conf);

	/* Configure event channel and link it to the xosc32k counter */
	struct events_config config;
	struct events_resource event;
	events_get_config_defaults(&config);
	config.edge_detect  = EVENTS_EDGE_DETECT_NONE;
	config.generator    = CONF_EVENT_GENERATOR_ID;
	config.path         = EVENTS_PATH_ASYNCHRONOUS;
	events_allocate(&event, &config);
	/* Configure event user and link it to the osc32k counter */
	events_attach_user(&event, CONF_EVENT_USED_ID);

	/* Enable event generation for crystal counter */
	struct tc_events tc_xosc32k_events = { .generate_event_on_overflow = true };
	tc_enable_events(&tc_xosc32k, &tc_xosc32k_events);

	/* Enable event reception for reference counter */
	struct tc_events tc_osc32k_events = { .on_event_perform_action = true };
	tc_osc32k_events.event_action = TC_EVENT_ACTION_RETRIGGER;
	tc_enable_events(&tc_osc32k, &tc_osc32k_events);

	/* Enable overflow callback for the crystal counter - if crystal count
	 * has been reached, crystal is operational */
	tc_register_callback(&tc_xosc32k, ok_callback, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc_xosc32k, TC_CALLBACK_CC_CHANNEL0);

	/* Enable compare callback for the reference counter - if reference count
	 * has been reached, crystal has failed */
	tc_register_callback(&tc_osc32k, fail_callback, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc_osc32k, TC_CALLBACK_CC_CHANNEL0);

	/* Start both crystal and reference counters */
	tc_enable(&tc_xosc32k);
	tc_enable(&tc_osc32k);
}

/** Main application entry point. */
int main(void)
{
	system_init();

	system_flash_set_waitstates(2);

	init_osc32k();
	init_xosc32k();
	init_xosc32k_fail_detector(
			xosc32k_ok_callback, xosc32k_fail_callback);

#if ENABLE_CPU_CLOCK_OUT == true
	/* Configure a GPIO pin as the CPU clock output */
	struct system_pinmux_config clk_out_pin;
	system_pinmux_get_config_defaults(&clk_out_pin);
	clk_out_pin.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
	clk_out_pin.mux_position = CONF_CLOCK_PIN_MUX;
	system_pinmux_pin_set_config(CONF_CLOCK_PIN_OUT, &clk_out_pin);
#endif

	for (;;) {
		static bool old_run_osc = true;
		bool new_run_osc =
				(port_pin_get_input_level(BUTTON_0_PIN) == BUTTON_0_INACTIVE);

		/* Check if the XOSC32K needs to be started or stopped when the board
		 * button is pressed or released */
		if (new_run_osc != old_run_osc) {
			if (new_run_osc) {
				system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K);
				while(!system_clock_source_is_ready(
						SYSTEM_CLOCK_SOURCE_XOSC32K));
			}
			else {
				system_clock_source_disable(SYSTEM_CLOCK_SOURCE_XOSC32K);
			}

			old_run_osc = new_run_osc;
		}
	}
}
Example #5
0
void serial_data_handler(void)
{
	if (data_length == 0) {
		/* No data to process, read the stream IO */
		//rx_index = 0;
		data_length = sio2host_rx(data, 156); /* @ToDo 20 ?,
		                                                   * different
		                                                 * values for
		                                                   * USB and
		                                                   * UART ? */
		
		
	} else { /* Data has been received, process the data */
		printf("Receiving file..\n");
		data_length--;
		rx_index++;
		if(rx_index ==99)
		{
			printf("Received File!!!!!!!!!!\n");
		}
	}
#endif
void configure_gclock_generator(void)
{
	//! [setup_1]
	struct system_gclk_gen_config gclock_gen_conf;
	//! [setup_1]
	//! [setup_2]
	system_gclk_gen_get_config_defaults(&gclock_gen_conf);
	//! [setup_2]

	//! [setup_3]
	gclock_gen_conf.source_clock    = SYSTEM_CLOCK_SOURCE_ULP32K;
	gclock_gen_conf.division_factor = 128;
	//! [setup_3]
	//! [setup_4]
	system_gclk_gen_set_config(GCLK_GENERATOR_4, &gclock_gen_conf);
	//! [setup_4]

	//! [setup_5]
	system_gclk_gen_enable(GCLK_GENERATOR_4);
	//! [setup_5]
}


/*---------------------------------------------------------------------------*/
static void
set_link_addr(void)
{
  linkaddr_t addr;
  unsigned int i;

  memset(&addr, 0, sizeof(linkaddr_t));
#if UIP_CONF_IPV6
#if SAMR21
  memcpy(addr.u8, eui64, sizeof(addr.u8));
#else 
  memcpy(addr.u8, node_mac, sizeof(addr.u8));
#endif
#else   /* UIP_CONF_IPV6 */
  if(node_id == 0) {
    for(i = 0; i < sizeof(linkaddr_t); ++i) {
#if SAMR21
      addr.u8[i] = eui64 [7 - i];
#else
	    addr.u8[i] = node_mac [7 - i];
#endif
    }
  } else {
    addr.u8[0] = node_id & 0xff;
    addr.u8[1] = node_id >> 8;
  }
#endif  /* UIP_CONF_IPV6 */
  linkaddr_set_node_addr(&addr);
  printf("Link layer addr ");
  for(i = 0; i < sizeof(addr.u8) - 1; i++) {
    printf("%u:", addr.u8[i]);
  }
  printf("%u, ", addr.u8[i]);
  for(i = 0; i < sizeof(addr.u8) - 1; i++) {
    printf("%02x:", addr.u8[i]);
  }
  printf("%02x\n", addr.u8[i]);
}