Example #1
0
/*! \brief Initializes the MCU system clocks.
 */
static void init_sys_clocks(void)
{
    // Switch to OSC0 to speed up the booting
    pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);

    // Start oscillator1
    pm_enable_osc1_crystal(&AVR32_PM, FOSC1);
    //
    pm_enable_clk1(&AVR32_PM, OSC1_STARTUP);

    // Set PLL0 (fed from OSC1 = 11.2896 MHz) to 112.896 MHz
    // We use OSC1 since we need a correct master clock for the SSC module to generate
    // the correct sample rate
    pm_pll_setup(&AVR32_PM, 0,  // pll.
                 SYS_CLOCK_PLL_MUL-1,   // mul.
                 1,   // div.
                 1,   // osc.
                 16); // lockcount.

    // Set PLL operating range and divider (fpll = fvco/2)
    // -> PLL0 output = 62.0928 MHz
    pm_pll_set_option(&AVR32_PM, 0, // pll.
                      1,  // pll_freq.
                      1,  // pll_div2.
                      0); // pll_wbwdisable.

    // start PLL0 and wait for the lock
    pm_pll_enable(&AVR32_PM, 0);
    pm_wait_for_pll0_locked(&AVR32_PM);
    // Set all peripheral clocks torun at master clock rate
    pm_cksel(&AVR32_PM,
             0,   // pbadiv.
             0,   // pbasel.
             0,   // pbbdiv.
             0,   // pbbsel.
             0,   // hsbdiv.
             0);  // hsbsel.

    // Set one waitstate for the flash
    flashc_set_wait_state(1);

    // Switch to PLL0 as the master clock
    pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCCTRL_MCSEL_PLL0);

#if (defined USB_RESYNC_METHOD) && (USB_RESYNC_METHOD == USB_RESYNC_METHOD_EXT_CLOCK_SYNTHESIZER)
    // Holds frequencies parameters
    g_fcpu_hz = g_fhsb_hz = g_fpba_hz = g_fpbb_hz = FMCK_HZ(11289600);
#endif

#if (defined __GNUC__) && (defined __AVR32__)
    // Give the used PBA clock frequency to Newlib, so it can work properly.
    set_cpu_hz(FPBA_HZ);
#endif
    init_usb_clock();
    init_codec_gclk();
}
Example #2
0
/*
 * Low-level initialization routine called during startup, before the main
 * function.
 * This version comes in replacement to the default one provided by the Newlib
 * add-ons library.
 * Newlib add-ons' _init_startup only calls init_exceptions, but Newlib add-ons'
 * exception vectors are not compatible with the SCALL management in the current
 * FreeRTOS port. More low-level initializations are besides added here.
 */
int _init_startup(void)
{
	/* Import the Exception Vector Base Address. */
	extern void _evba;

	#if configHEAP_INIT
		extern void __heap_start__;
		extern void __heap_end__;
		portBASE_TYPE *pxMem;
	#endif

	/* Load the Exception Vector Base Address in the corresponding system register. */
	Set_system_register( AVR32_EVBA, ( int ) &_evba );

	/* Enable exceptions. */
	ENABLE_ALL_EXCEPTIONS();

	/* Initialize interrupt handling. */
	INTC_init_interrupts();

	#if configHEAP_INIT

		/* Initialize the heap used by malloc. */
		for( pxMem = &__heap_start__; pxMem < ( portBASE_TYPE * )&__heap_end__; )
		{
			*pxMem++ = 0xA5A5A5A5;
		}

	#endif

	/* Give the used PBA clock frequency to Newlib, so it can work properly. */
	set_cpu_hz( configPBA_CLOCK_HZ );

	/* Code section present if and only if the debug trace is activated. */
	#if configDBG
	{
		static const gpio_map_t DBG_USART_GPIO_MAP =
		{
			{ configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION },
			{ configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION }
		};

		/* Initialize the USART used for the debug trace with the configured parameters. */
		set_usart_base( ( void * ) configDBG_USART );
		gpio_enable_module( DBG_USART_GPIO_MAP,
		                    sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
		usart_init( configDBG_USART_BAUDRATE );
	}
	#endif

  // Don't-care value for GCC.
  return 1;
}
Example #3
0
/*! \brief Low-level initialization routine called during startup, before the
 *         main function.
 *
 * This version comes in replacement to the default one provided by the Newlib
 * add-ons library.
 * Newlib add-ons' _init_startup only calls init_exceptions, but Newlib add-ons'
 * exception and interrupt vectors are defined in the same section and Newlib
 * add-ons' interrupt vectors are not compatible with the interrupt management
 * of the INTC module.
 * More low-level initializations are besides added here.
 */
int _init_startup(void)
{
  // Import the Exception Vector Base Address.
  extern void _evba;

  // Load the Exception Vector Base Address in the corresponding system register.
  Set_system_register(AVR32_EVBA, (int)&_evba);

  // Enable exceptions.
  Enable_global_exception();

  // Initialize interrupt handling.
  INTC_init_interrupts();

  // Give the used CPU clock frequency to Newlib, so it can work properly.
  set_cpu_hz(pcl_freq_param.pba_f);

  // Initialize the USART used for the debug trace with the configured parameters.
  set_usart_base( ( void * ) DBG_USART );

  // Don't-care value for GCC.
  return 1;
}
Example #4
0
/*! \brief Main function. Execution starts here.
 *
 * \retval 42 Fatal error.
 */
int main(void)
{
  // Configure system clocks.
  if (pcl_configure_clocks(&pcl_freq_param) != PASS)
    return 42;

  // Initialize usart comm
  init_dbg_rs232(pcl_freq_param.pba_f);

#ifndef FREERTOS_USED
# if (defined __GNUC__)
  // Give the used CPU clock frequency to Newlib, so it can work properly.
  set_cpu_hz(pcl_freq_param.pba_f);
# endif
#endif

  // Initialize USB clock.
  pcl_configure_usb_clock();

  // Initialize USB task
  usb_task_init();

  // Display a welcome banner on USART
  printf("                                                       ......       ......     \r\n");
  printf("       IIIIII  IIIII        IIII   IIIIIIIIIII      IIIIIIIIIII. .IIIIIIIIII.  \r\n");
  printf("      IIIIIII   IIIII      IIIII  IIIIIIIIIIIII     IIIIIIIIIIII..IIIIIIIIIII. \r\n");
  printf("     IIIIIIIII  IIIII     IIIII   IIIII   IIIII     I.      IIIII.:.     IIIII \r\n");
  printf("     IIII IIIII  IIIII    IIII   IIIII    IIIII            .IIII.        IIIII \r\n");
  printf("    IIIII  IIII   IIII   IIIII  IIIIIIIIIIIIII         IIIIIIII          IIII. \r\n");
  printf("    IIII   IIIII  IIIII IIIII   IIIIIIIIIIIII          IIIIIIII.       .IIII:  \r\n");
  printf("   IIIII    IIIII  IIIIIIIII   IIIIIIIIIII                 .IIIII     IIIII.   \r\n");
  printf("  IIIIIIIIIIIIIII   IIIIIIII   IIIII IIIII                  .IIII   .IIII:     \r\n");
  printf("  IIIIIIIIIIIIIIII  IIIIIII   IIIII   IIII         II:.    .IIIII .IIIII.      \r\n");
  printf(" IIIII        IIIII  IIIIII  IIIII    IIIII        IIIIIIIIIIIII.IIIIIIIIIIIIII\r\n");
  printf(" IIIII        IIIII  IIIII   IIIII    IIIII        :IIIIIIIIII.  IIIIIIIIIIIIII\r\n");
  printf("                      III                                                      \r\n");
  printf("                       II                                                      \r\n");

#if USB_DEVICE_FEATURE == true
  // Initialize device CDC USB task
  device_cdc_task_init();
#endif
#if USB_HOST_FEATURE == true
  // Initialize host CDC USB task
  host_cdc_task_init();
#endif

#ifdef FREERTOS_USED
  // Start OS scheduler
  vTaskStartScheduler();
  portDBG_TRACE("FreeRTOS returned.");
  return 42;
#else
  // No OS here. Need to call each task in round-robin mode.
  while (true)
  {
    usb_task();
  #if USB_DEVICE_FEATURE == true
    device_cdc_task();
  #endif
  #if USB_HOST_FEATURE == true
    host_cdc_task();
  #endif
  }
#endif  // FREERTOS_USED
}
Example #5
0
int pm_configure_clocks(pm_freq_param_t *param)
{
  // Supported frequencies:
  // Fosc0 mul div PLL div2_en cpu_f pba_f   Comment
  //  12   15   1  192     1     12    12
  //  12    9   3   40     1     20    20    PLL out of spec
  //  12   15   1  192     1     24    12
  //  12    9   1  120     1     30    15
  //  12    9   3   40     0     40    20    PLL out of spec
  //  12   15   1  192     1     48    12
  //  12   15   1  192     1     48    24
  //  12    8   1  108     1     54    27
  //  12    9   1  120     1     60    15
  //  12    9   1  120     1     60    30
  //  12   10   1  132     1     66    16.5
  //
  unsigned long in_cpu_f  = param->cpu_f;
  unsigned long in_osc0_f = param->osc0_f;
  unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0;
  unsigned long pll_freq, rest;
  Bool b_div2_pba, b_div2_cpu;

  // Switch to external Oscillator 0
  pm_switch_to_osc0(&AVR32_PM, in_osc0_f, param->osc0_startup);

  // Start with CPU freq config
  if (in_cpu_f == in_osc0_f)
  {
    param->cpu_f = in_osc0_f;
    param->pba_f = in_osc0_f;
    return PM_FREQ_STATUS_OK;
  }
  else if (in_cpu_f < in_osc0_f)
  {
    // TBD
  }

  rest = in_cpu_f % in_osc0_f;

  for (div = 1; div < 32; div++)
  {
    if ((div * rest) % in_osc0_f == 0)
      break;
  }
  if (div == 32)
    return PM_FREQ_STATUS_FAIL;

  mul = (in_cpu_f * div) / in_osc0_f;

  if (mul > PM_MAX_MUL)
    return PM_FREQ_STATUS_FAIL;

  // export 2power from PLL div to div2_cpu
  while (!(div % 2))
  {
    div /= 2;
    div2_cpu++;
  }

  // Here we know the mul and div parameter of the PLL config.
  // . Check out if the PLL has a valid in_cpu_f.
  // . Try to have for the PLL frequency (VCO output) the highest possible value
  //   to reduce jitter.
  while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ)
  {
    if (2 * mul > PM_MAX_MUL)
      break;
    mul *= 2;
    div2_cpu++;
  }

  if (div2_cpu != 0)
  {
    div2_cpu--;
    div2_en = 1;
  }

  pll_freq = in_osc0_f * mul / (div * (1 << div2_en));

  // Update real CPU Frequency
  param->cpu_f = pll_freq / (1 << div2_cpu);
  mul--;

  pm_pll_setup(&AVR32_PM
  , 0   // pll
  , mul // mul
  , div // div
  , 0   // osc
  , 16  // lockcount
  );

  pm_pll_set_option(&AVR32_PM
  , 0 // pll
  // PLL clock is lower than 160MHz: need to set pllopt.
  , (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0 // pll_freq
  , div2_en // pll_div2
  , 0 // pll_wbwdisable
  );

  rest = pll_freq;
  while (rest > AVR32_PM_PBA_MAX_FREQ ||
         rest != param->pba_f)
  {
    div2_pba++;
    rest = pll_freq / (1 << div2_pba);
    if (rest < param->pba_f)
      break;
  }

  // Update real PBA Frequency
  param->pba_f = pll_freq / (1 << div2_pba);

#if __GNUC__
  set_cpu_hz(param->pba_f);
#endif

  // Enable PLL0
  pm_pll_enable(&AVR32_PM, 0);

  // Wait for PLL0 locked
  pm_wait_for_pll0_locked(&AVR32_PM);

  if (div2_cpu)
  {
    b_div2_cpu = TRUE;
    div2_cpu--;
  }
  else
    b_div2_cpu = FALSE;

  if (div2_pba)
  {
    b_div2_pba = TRUE;
    div2_pba--;
  }
  else
    b_div2_pba = FALSE;

  pm_cksel(&AVR32_PM
  , b_div2_pba, div2_pba // PBA
  , b_div2_cpu, div2_cpu // PBB
  , b_div2_cpu, div2_cpu // HSB
  );

  if (param->cpu_f > AVR32_FLASHC_FWS_0_MAX_FREQ)
  {
    flashc_set_wait_state(1);
#if (defined AVR32_FLASHC_210_H_INCLUDED)
    if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ)
      flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1);
    else
      flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1);
#endif
  }
  else
  {
    flashc_set_wait_state(0);
#if (defined AVR32_FLASHC_210_H_INCLUDED)
    if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ)
      flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1);
    else
      flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1);
#endif
  }

  pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCCTRL_MCSEL_PLL0);

  return PM_FREQ_STATUS_OK;
}
Example #6
0
/*
 * Low-level initialization routine called during startup, before the main
 * function.
 * This version comes in replacement to the default one provided by Newlib.
 * Newlib's _init_startup only calls init_exceptions, but Newlib's exception
 * vectors are not compatible with the SCALL management in the current FreeRTOS
 * port. More low-level initializations are besides added here.
 */
void _init_startup(void)
{
	/* Import the Exception Vector Base Address. */
	extern void _evba;

	#if configHEAP_INIT
		extern void __heap_start__;
		extern void __heap_end__;
		portBASE_TYPE *pxMem;
	#endif

	/* Load the Exception Vector Base Address in the corresponding system register. */
	Set_system_register( AVR32_EVBA, ( int ) &_evba );

	/* Enable exceptions. */
	ENABLE_ALL_EXCEPTIONS();

	/* Initialize interrupt handling. */
	INTC_init_interrupts();

	#if configHEAP_INIT

		/* Initialize the heap used by malloc. */
		for( pxMem = &__heap_start__; pxMem < ( portBASE_TYPE * )&__heap_end__; )
		{
			*pxMem++ = 0xA5A5A5A5;
		}

	#endif

	/* Give the used CPU clock frequency to Newlib, so it can work properly. */
	set_cpu_hz( configCPU_CLOCK_HZ );
	
    // Input and output parameters when initializing PM clocks using pm_configure_clocks().
	pm_freq_param_t clkParams = {
		configCPU_CLOCK_HZ, // unsigned long cpu_f;
		configPBA_CLOCK_HZ, // unsigned long pba_f; ! PBA frequency (input/output argument).
		FOSC0, // unsigned long osc0_f; ! Oscillator 0's external crystal(or external clock) frequency (board dependant) (input argument).
		OSC0_STARTUP // unsigned long osc0_startup; ! Oscillator 0's external crystal(or external clock) startup time: AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC (input argument).
	};

	pm_configure_clocks(&clkParams);
    
	/* Code section present if and only if the debug trace is activated. */
	#if configDBG
	{
		static const gpio_map_t DBG_USART_GPIO_MAP =
		{
			{ configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION },
			{ configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION }
		};

		/* Initialize the USART used for the debug trace with the configured parameters. */
		set_usart_base( ( void * ) configDBG_USART );
		gpio_enable_module( DBG_USART_GPIO_MAP,
		                    sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
		usart_init( configDBG_USART_BAUDRATE );
    
        /*const usart_options_t USART_OPTIONS =
        {
            configDBG_USART_BAUDRATE,	// baudrate
            8, 					        // charlength
            USART_NO_PARITY, 	        // paritytype
            USART_1_STOPBIT, 	        // stopbits
            USART_NORMAL_CHMODE         // channelmode
        };
        
        usart_init_rs232(configDBG_USART, &USART_OPTIONS, configPBA_CLOCK_HZ);*/
	}
	#endif
}