/*! \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(); }
/* * 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; }
/*! \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; }
/*! \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 }
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; }
/* * 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 }