void flashc_set_flash_waitstate_and_readmode(unsigned long cpu_f_hz) { //! Device-specific data #undef AVR32_FLASHC_FWS_0_MAX_FREQ #undef AVR32_FLASHC_FWS_1_MAX_FREQ #undef AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ #undef AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ #define AVR32_FLASHC_FWS_0_MAX_FREQ 33000000 #define AVR32_FLASHC_FWS_1_MAX_FREQ 66000000 #define AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ 33000000 #define AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ 72000000 // These defines are missing from or wrong in the toolchain header files uc3cxxx.h // Put a Bugzilla if (cpu_f_hz > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ) { // > 33MHz // Set a wait-state flashc_set_wait_state(1); if (cpu_f_hz <= AVR32_FLASHC_FWS_1_MAX_FREQ) { // <= 66MHz and >33Mhz // Disable the high-speed read mode. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); } else { // > 66Mhz // Enable the high-speed read mode. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1); } } else { // <= 33 MHz // Disable wait-state flashc_set_wait_state(0); // Disable the high-speed read mode. flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); } }
Bool flashc_erase_page (int page_number, Bool check) { Bool page_erased = TRUE; #ifdef DEBUG_FLASHC { unsigned char text[20]; CI_LocalPrintf ("Erase page :"); itoa ((unsigned int) page_number, text); CI_LocalPrintf (text); CI_LocalPrintf (" - Pagebuffer = "); itoa ((unsigned int) flashc_get_page_number (), text); CI_LocalPrintf (text); CI_LocalPrintf ("\n\r"); } #endif flashc_issue_command (AVR32_FLASHC_FCMD_CMD_EP, page_number); if (check) { unsigned int error_status = flashc_error_status; page_erased = flashc_quick_page_read (-1); flashc_error_status |= error_status; } return page_erased; }
bool flashc_erase_page(int page_number, bool check) { bool page_erased = true; flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EP, page_number); if (check) { unsigned int error_status = flashc_error_status; page_erased = flashc_quick_page_read(-1); flashc_error_status |= error_status; } return page_erased; }
bool flashc_erase_user_page(bool check) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EUP, -1); return (check) ? flashc_quick_user_page_read() : true; }
bool flashc_quick_user_page_read(void) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPRUP, -1); return flashc_is_page_erased(); }
void flashc_write_page(int page_number) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WP, page_number); }
bool flashc_quick_page_read(int page_number) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPR, page_number); return flashc_is_page_erased(); }
void flashc_clear_page_buffer(void) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_CPB, -1); }
void flashc_write_gp_fuse_bit(unsigned int gp_fuse_bit, bool value) { if (!value) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WGPB, gp_fuse_bit & 0x3F); } }
bool flashc_erase_all_gp_fuses(bool check) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EAGPF, -1); return (check) ? (flashc_read_all_gp_fuses() == 0xFFFFFFFFFFFFFFFFULL) : true; }
bool flashc_erase_gp_fuse_bit(unsigned int gp_fuse_bit, bool check) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EGPB, gp_fuse_bit & 0x3F); return (check) ? flashc_read_gp_fuse_bit(gp_fuse_bit) : true; }
void flashc_lock_page_region(int page_number, bool lock) { flashc_issue_command((lock) ? AVR32_FLASHC_FCMD_CMD_LP : AVR32_FLASHC_FCMD_CMD_UP, page_number); }
void flashc_activate_security_bit(void) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_SSB, -1); }
void flashc_erase_all(void) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EA, -1); }
void flashc_no_operation(void) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_NOP, -1); }
void flashc_write_user_page(void) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WUP, -1); }
void flashc_write_gp_fuse_byte(unsigned int gp_fuse_byte, uint8_t value) { flashc_issue_command(AVR32_FLASHC_FCMD_CMD_PGPFB, (gp_fuse_byte & 0x07) | value << 3); }
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); // 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; }