00001
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <avr32/io.h>
00049 #include <stddef.h>
00050 #include "compiler.h"
00051 #include "flashc.h"
00052
00053
00056
00057
00058 typedef union
00059 {
00060 unsigned long fcr;
00061 avr32_flashc_fcr_t FCR;
00062 } u_avr32_flashc_fcr_t;
00063
00064 typedef union
00065 {
00066 unsigned long fcmd;
00067 avr32_flashc_fcmd_t FCMD;
00068 } u_avr32_flashc_fcmd_t;
00069
00071
00072
00075
00076
00077
00078 unsigned int flashc_get_flash_size(void)
00079 {
00080 #if (defined AVR32_FLASHC_300_H_INCLUDED)
00081 static const unsigned int FLASH_SIZE[1 << AVR32_FLASHC_PR_FSZ_SIZE] =
00082 {
00083 32 << 10,
00084 64 << 10,
00085 128 << 10,
00086 256 << 10,
00087 384 << 10,
00088 512 << 10,
00089 768 << 10,
00090 1024 << 10
00091 };
00092 return FLASH_SIZE[(AVR32_FLASHC.pr & AVR32_FLASHC_PR_FSZ_MASK) >> AVR32_FLASHC_PR_FSZ_OFFSET];
00093 #else
00094 static const unsigned int FLASH_SIZE[1 << AVR32_FLASHC_FSR_FSZ_SIZE] =
00095 {
00096 32 << 10,
00097 64 << 10,
00098 128 << 10,
00099 256 << 10,
00100 384 << 10,
00101 512 << 10,
00102 768 << 10,
00103 1024 << 10
00104 };
00105 return FLASH_SIZE[(AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FSZ_MASK) >> AVR32_FLASHC_FSR_FSZ_OFFSET];
00106 #endif
00107 }
00108
00109
00110 unsigned int flashc_get_page_count(void)
00111 {
00112 return flashc_get_flash_size() / AVR32_FLASHC_PAGE_SIZE;
00113 }
00114
00115
00116 unsigned int flashc_get_page_count_per_region(void)
00117 {
00118 return flashc_get_page_count() / AVR32_FLASHC_REGIONS;
00119 }
00120
00121
00122 unsigned int flashc_get_page_region(int page_number)
00123 {
00124 return ((page_number >= 0) ? page_number : flashc_get_page_number()) / flashc_get_page_count_per_region();
00125 }
00126
00127
00128 unsigned int flashc_get_region_first_page_number(unsigned int region)
00129 {
00130 return region * flashc_get_page_count_per_region();
00131 }
00132
00133
00135
00136
00139
00140
00141
00142 unsigned int flashc_get_wait_state(void)
00143 {
00144 return (AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_FWS_MASK) >> AVR32_FLASHC_FCR_FWS_OFFSET;
00145 }
00146
00147
00148 void flashc_set_wait_state(unsigned int wait_state)
00149 {
00150 u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
00151 u_avr32_flashc_fcr.FCR.fws = wait_state;
00152 AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
00153 }
00154
00155
00156 Bool flashc_is_ready_int_enabled(void)
00157 {
00158 return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_FRDY_MASK) != 0);
00159 }
00160
00161
00162 void flashc_enable_ready_int(Bool enable)
00163 {
00164 u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
00165 u_avr32_flashc_fcr.FCR.frdy = (enable != FALSE);
00166 AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
00167 }
00168
00169
00170 Bool flashc_is_lock_error_int_enabled(void)
00171 {
00172 return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_LOCKE_MASK) != 0);
00173 }
00174
00175
00176 void flashc_enable_lock_error_int(Bool enable)
00177 {
00178 u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
00179 u_avr32_flashc_fcr.FCR.locke = (enable != FALSE);
00180 AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
00181 }
00182
00183
00184 Bool flashc_is_prog_error_int_enabled(void)
00185 {
00186 return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_PROGE_MASK) != 0);
00187 }
00188
00189
00190 void flashc_enable_prog_error_int(Bool enable)
00191 {
00192 u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr};
00193 u_avr32_flashc_fcr.FCR.proge = (enable != FALSE);
00194 AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr;
00195 }
00196
00197
00199
00200
00203
00204
00205
00206 Bool flashc_is_ready(void)
00207 {
00208 return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FRDY_MASK) != 0);
00209 }
00210
00211
00212 void flashc_default_wait_until_ready(void)
00213 {
00214 while (!flashc_is_ready());
00215 }
00216
00217
00218 void (*volatile flashc_wait_until_ready)(void) = flashc_default_wait_until_ready;
00219
00220
00231 static unsigned int flashc_get_error_status(void)
00232 {
00233 return AVR32_FLASHC.fsr & (AVR32_FLASHC_FSR_LOCKE_MASK |
00234 AVR32_FLASHC_FSR_PROGE_MASK);
00235 }
00236
00237
00242 static unsigned int flashc_error_status = 0;
00243
00244
00245 Bool flashc_is_lock_error(void)
00246 {
00247 return ((flashc_error_status & AVR32_FLASHC_FSR_LOCKE_MASK) != 0);
00248 }
00249
00250
00251 Bool flashc_is_programming_error(void)
00252 {
00253 return ((flashc_error_status & AVR32_FLASHC_FSR_PROGE_MASK) != 0);
00254 }
00255
00256
00258
00259
00262
00263
00264
00265 unsigned int flashc_get_command(void)
00266 {
00267 return (AVR32_FLASHC.fcmd & AVR32_FLASHC_FCMD_CMD_MASK) >> AVR32_FLASHC_FCMD_CMD_OFFSET;
00268 }
00269
00270
00271 unsigned int flashc_get_page_number(void)
00272 {
00273 return (AVR32_FLASHC.fcmd & AVR32_FLASHC_FCMD_PAGEN_MASK) >> AVR32_FLASHC_FCMD_PAGEN_OFFSET;
00274 }
00275
00276
00277 void flashc_issue_command(unsigned int command, int page_number)
00278 {
00279 u_avr32_flashc_fcmd_t u_avr32_flashc_fcmd;
00280 flashc_wait_until_ready();
00281 u_avr32_flashc_fcmd.fcmd = AVR32_FLASHC.fcmd;
00282 u_avr32_flashc_fcmd.FCMD.cmd = command;
00283 if (page_number >= 0) u_avr32_flashc_fcmd.FCMD.pagen = page_number;
00284 u_avr32_flashc_fcmd.FCMD.key = AVR32_FLASHC_FCMD_KEY_KEY;
00285 AVR32_FLASHC.fcmd = u_avr32_flashc_fcmd.fcmd;
00286 flashc_error_status = flashc_get_error_status();
00287 flashc_wait_until_ready();
00288 }
00289
00290
00292
00293
00296
00297
00298
00299 void flashc_no_operation(void)
00300 {
00301 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_NOP, -1);
00302 }
00303
00304
00305 void flashc_erase_all(void)
00306 {
00307 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EA, -1);
00308 }
00309
00310
00312
00313
00316
00317
00318
00319 Bool flashc_is_security_bit_active(void)
00320 {
00321 return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_SECURITY_MASK) != 0);
00322 }
00323
00324
00325 void flashc_activate_security_bit(void)
00326 {
00327 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_SSB, -1);
00328 }
00329
00330
00331 unsigned int flashc_get_bootloader_protected_size(void)
00332 {
00333 unsigned int bootprot = (1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1 -
00334 flashc_read_gp_fuse_bitfield(AVR32_FLASHC_FGPFRLO_BOOTPROT_OFFSET,
00335 AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE);
00336 return (bootprot) ? AVR32_FLASHC_PAGE_SIZE << bootprot : 0;
00337 }
00338
00339
00340 unsigned int flashc_set_bootloader_protected_size(unsigned int bootprot_size)
00341 {
00342 flashc_set_gp_fuse_bitfield(AVR32_FLASHC_FGPFRLO_BOOTPROT_OFFSET,
00343 AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE,
00344 (1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1 -
00345 ((bootprot_size) ?
00346 32 - clz((((min(max(bootprot_size, AVR32_FLASHC_PAGE_SIZE << 1),
00347 AVR32_FLASHC_PAGE_SIZE <<
00348 ((1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1)) +
00349 AVR32_FLASHC_PAGE_SIZE - 1) /
00350 AVR32_FLASHC_PAGE_SIZE) << 1) - 1) - 1 :
00351 0));
00352 return flashc_get_bootloader_protected_size();
00353 }
00354
00355
00356 Bool flashc_is_external_privileged_fetch_locked(void)
00357 {
00358 return (!flashc_read_gp_fuse_bit(AVR32_FLASHC_FGPFRLO_EPFL_OFFSET));
00359 }
00360
00361
00362 void flashc_lock_external_privileged_fetch(Bool lock)
00363 {
00364 flashc_set_gp_fuse_bit(AVR32_FLASHC_FGPFRLO_EPFL_OFFSET, !lock);
00365 }
00366
00367
00368 Bool flashc_is_page_region_locked(int page_number)
00369 {
00370 return flashc_is_region_locked(flashc_get_page_region(page_number));
00371 }
00372
00373
00374 Bool flashc_is_region_locked(unsigned int region)
00375 {
00376 return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_LOCK0_MASK << (region & (AVR32_FLASHC_REGIONS - 1))) != 0);
00377 }
00378
00379
00380 void flashc_lock_page_region(int page_number, Bool lock)
00381 {
00382 flashc_issue_command((lock) ? AVR32_FLASHC_FCMD_CMD_LP : AVR32_FLASHC_FCMD_CMD_UP, page_number);
00383 }
00384
00385
00386 void flashc_lock_region(unsigned int region, Bool lock)
00387 {
00388 flashc_lock_page_region(flashc_get_region_first_page_number(region), lock);
00389 }
00390
00391
00392 void flashc_lock_all_regions(Bool lock)
00393 {
00394 unsigned int error_status = 0;
00395 unsigned int region = AVR32_FLASHC_REGIONS;
00396 while (region)
00397 {
00398 flashc_lock_region(--region, lock);
00399 error_status |= flashc_error_status;
00400 }
00401 flashc_error_status = error_status;
00402 }
00403
00404
00406
00407
00410
00411
00412
00413 Bool flashc_read_gp_fuse_bit(unsigned int gp_fuse_bit)
00414 {
00415 return ((flashc_read_all_gp_fuses() & 1ULL << (gp_fuse_bit & 0x3F)) != 0);
00416 }
00417
00418
00419 U64 flashc_read_gp_fuse_bitfield(unsigned int pos, unsigned int width)
00420 {
00421 return flashc_read_all_gp_fuses() >> (pos & 0x3F) & ((1ULL << min(width, 64)) - 1);
00422 }
00423
00424
00425 U8 flashc_read_gp_fuse_byte(unsigned int gp_fuse_byte)
00426 {
00427 return flashc_read_all_gp_fuses() >> ((gp_fuse_byte & 0x07) << 3);
00428 }
00429
00430
00431 U64 flashc_read_all_gp_fuses(void)
00432 {
00433 return AVR32_FLASHC.fgpfrlo | (U64)AVR32_FLASHC.fgpfrhi << 32;
00434 }
00435
00436
00437 Bool flashc_erase_gp_fuse_bit(unsigned int gp_fuse_bit, Bool check)
00438 {
00439 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EGPB, gp_fuse_bit & 0x3F);
00440 return (check) ? flashc_read_gp_fuse_bit(gp_fuse_bit) : TRUE;
00441 }
00442
00443
00444 Bool flashc_erase_gp_fuse_bitfield(unsigned int pos, unsigned int width, Bool check)
00445 {
00446 unsigned int error_status = 0;
00447 unsigned int gp_fuse_bit;
00448 pos &= 0x3F;
00449 width = min(width, 64);
00450 for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++)
00451 {
00452 flashc_erase_gp_fuse_bit(gp_fuse_bit, FALSE);
00453 error_status |= flashc_error_status;
00454 }
00455 flashc_error_status = error_status;
00456 return (check) ? (flashc_read_gp_fuse_bitfield(pos, width) == (1ULL << width) - 1) : TRUE;
00457 }
00458
00459
00460 Bool flashc_erase_gp_fuse_byte(unsigned int gp_fuse_byte, Bool check)
00461 {
00462 unsigned int error_status;
00463 unsigned int current_gp_fuse_byte;
00464 U64 value = flashc_read_all_gp_fuses();
00465 flashc_erase_all_gp_fuses(FALSE);
00466 error_status = flashc_error_status;
00467 for (current_gp_fuse_byte = 0; current_gp_fuse_byte < 8; current_gp_fuse_byte++, value >>= 8)
00468 {
00469 if (current_gp_fuse_byte != gp_fuse_byte)
00470 {
00471 flashc_write_gp_fuse_byte(current_gp_fuse_byte, value);
00472 error_status |= flashc_error_status;
00473 }
00474 }
00475 flashc_error_status = error_status;
00476 return (check) ? (flashc_read_gp_fuse_byte(gp_fuse_byte) == 0xFF) : TRUE;
00477 }
00478
00479
00480 Bool flashc_erase_all_gp_fuses(Bool check)
00481 {
00482 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EAGPF, -1);
00483 return (check) ? (flashc_read_all_gp_fuses() == 0xFFFFFFFFFFFFFFFFULL) : TRUE;
00484 }
00485
00486
00487 void flashc_write_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value)
00488 {
00489 if (!value)
00490 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WGPB, gp_fuse_bit & 0x3F);
00491 }
00492
00493
00494 void flashc_write_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value)
00495 {
00496 unsigned int error_status = 0;
00497 unsigned int gp_fuse_bit;
00498 pos &= 0x3F;
00499 width = min(width, 64);
00500 for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++, value >>= 1)
00501 {
00502 flashc_write_gp_fuse_bit(gp_fuse_bit, value & 0x01);
00503 error_status |= flashc_error_status;
00504 }
00505 flashc_error_status = error_status;
00506 }
00507
00508
00509 void flashc_write_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value)
00510 {
00511 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_PGPFB, (gp_fuse_byte & 0x07) | value << 3);
00512 }
00513
00514
00515 void flashc_write_all_gp_fuses(U64 value)
00516 {
00517 unsigned int error_status = 0;
00518 unsigned int gp_fuse_byte;
00519 for (gp_fuse_byte = 0; gp_fuse_byte < 8; gp_fuse_byte++, value >>= 8)
00520 {
00521 flashc_write_gp_fuse_byte(gp_fuse_byte, value);
00522 error_status |= flashc_error_status;
00523 }
00524 flashc_error_status = error_status;
00525 }
00526
00527
00528 void flashc_set_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value)
00529 {
00530 if (value)
00531 flashc_erase_gp_fuse_bit(gp_fuse_bit, FALSE);
00532 else
00533 flashc_write_gp_fuse_bit(gp_fuse_bit, FALSE);
00534 }
00535
00536
00537 void flashc_set_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value)
00538 {
00539 unsigned int error_status = 0;
00540 unsigned int gp_fuse_bit;
00541 pos &= 0x3F;
00542 width = min(width, 64);
00543 for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++, value >>= 1)
00544 {
00545 flashc_set_gp_fuse_bit(gp_fuse_bit, value & 0x01);
00546 error_status |= flashc_error_status;
00547 }
00548 flashc_error_status = error_status;
00549 }
00550
00551
00552 void flashc_set_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value)
00553 {
00554 unsigned int error_status;
00555 switch (value)
00556 {
00557 case 0xFF:
00558 flashc_erase_gp_fuse_byte(gp_fuse_byte, FALSE);
00559 break;
00560 case 0x00:
00561 flashc_write_gp_fuse_byte(gp_fuse_byte, 0x00);
00562 break;
00563 default:
00564 flashc_erase_gp_fuse_byte(gp_fuse_byte, FALSE);
00565 error_status = flashc_error_status;
00566 flashc_write_gp_fuse_byte(gp_fuse_byte, value);
00567 flashc_error_status |= error_status;
00568 }
00569 }
00570
00571
00572 void flashc_set_all_gp_fuses(U64 value)
00573 {
00574 unsigned int error_status;
00575 switch (value)
00576 {
00577 case 0xFFFFFFFFFFFFFFFFULL:
00578 flashc_erase_all_gp_fuses(FALSE);
00579 break;
00580 case 0x0000000000000000ULL:
00581 flashc_write_all_gp_fuses(0x0000000000000000ULL);
00582 break;
00583 default:
00584 flashc_erase_all_gp_fuses(FALSE);
00585 error_status = flashc_error_status;
00586 flashc_write_all_gp_fuses(value);
00587 flashc_error_status |= error_status;
00588 }
00589 }
00590
00591
00593
00594
00597
00598
00599
00600 void flashc_clear_page_buffer(void)
00601 {
00602 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_CPB, -1);
00603 }
00604
00605
00606 Bool flashc_is_page_erased(void)
00607 {
00608 return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_QPRR_MASK) != 0);
00609 }
00610
00611
00612 Bool flashc_quick_page_read(int page_number)
00613 {
00614 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPR, page_number);
00615 return flashc_is_page_erased();
00616 }
00617
00618
00619 Bool flashc_erase_page(int page_number, Bool check)
00620 {
00621 Bool page_erased = TRUE;
00622 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EP, page_number);
00623 if (check)
00624 {
00625 unsigned int error_status = flashc_error_status;
00626 page_erased = flashc_quick_page_read(-1);
00627 flashc_error_status |= error_status;
00628 }
00629 return page_erased;
00630 }
00631
00632
00633 Bool flashc_erase_all_pages(Bool check)
00634 {
00635 Bool all_pages_erased = TRUE;
00636 unsigned int error_status = 0;
00637 unsigned int page_number = flashc_get_page_count();
00638 while (page_number)
00639 {
00640 all_pages_erased &= flashc_erase_page(--page_number, check);
00641 error_status |= flashc_error_status;
00642 }
00643 flashc_error_status = error_status;
00644 return all_pages_erased;
00645 }
00646
00647
00648 void flashc_write_page(int page_number)
00649 {
00650 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WP, page_number);
00651 }
00652
00653
00654 Bool flashc_quick_user_page_read(void)
00655 {
00656 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPRUP, -1);
00657 return flashc_is_page_erased();
00658 }
00659
00660
00661 Bool flashc_erase_user_page(Bool check)
00662 {
00663 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EUP, -1);
00664 return (check) ? flashc_quick_user_page_read() : TRUE;
00665 }
00666
00667
00668 void flashc_write_user_page(void)
00669 {
00670 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WUP, -1);
00671 }
00672
00673
00674 volatile void *flashc_memset8(volatile void *dst, U8 src, size_t nbytes, Bool erase)
00675 {
00676 return flashc_memset16(dst, src | (U16)src << 8, nbytes, erase);
00677 }
00678
00679
00680 volatile void *flashc_memset16(volatile void *dst, U16 src, size_t nbytes, Bool erase)
00681 {
00682 return flashc_memset32(dst, src | (U32)src << 16, nbytes, erase);
00683 }
00684
00685
00686 volatile void *flashc_memset32(volatile void *dst, U32 src, size_t nbytes, Bool erase)
00687 {
00688 return flashc_memset64(dst, src | (U64)src << 32, nbytes, erase);
00689 }
00690
00691
00692 volatile void *flashc_memset64(volatile void *dst, U64 src, size_t nbytes, Bool erase)
00693 {
00694
00695 UnionCVPtr flash_array_end;
00696 UnionVPtr dest;
00697 Union64 source = {0};
00698 StructCVPtr dest_end;
00699 UnionCVPtr flash_page_source_end;
00700 Bool incomplete_flash_page_end;
00701 Union64 flash_dword;
00702 UnionVPtr tmp;
00703 unsigned int error_status = 0;
00704 unsigned int i;
00705
00706
00707 flash_array_end.u8ptr = AVR32_FLASH + flashc_get_flash_size();
00708 dest.u8ptr = dst;
00709 for (i = (Get_align((U32)dest.u8ptr, sizeof(U64)) - 1) & (sizeof(U64) - 1);
00710 src; i = (i - 1) & (sizeof(U64) - 1))
00711 {
00712 source.u8[i] = src;
00713 src >>= 8;
00714 }
00715 dest_end.u8ptr = dest.u8ptr + nbytes;
00716
00717
00718 if (dest.u8ptr < AVR32_FLASH)
00719 {
00720 dest.u8ptr = AVR32_FLASH;
00721 }
00722 else if (flash_array_end.u8ptr <= dest.u8ptr && dest.u8ptr < AVR32_FLASHC_USER_PAGE)
00723 {
00724 dest.u8ptr = AVR32_FLASHC_USER_PAGE;
00725 }
00726
00727
00728 if (dest_end.u8ptr > AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE)
00729 {
00730 dest_end.u8ptr = AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE;
00731 }
00732 else if (AVR32_FLASHC_USER_PAGE >= dest_end.u8ptr && dest_end.u8ptr > flash_array_end.u8ptr)
00733 {
00734 dest_end.u8ptr = flash_array_end.u8ptr;
00735 }
00736
00737
00738 dest_end.u16ptr = (U16 *)Align_down((U32)dest_end.u8ptr, sizeof(U16));
00739 dest_end.u32ptr = (U32 *)Align_down((U32)dest_end.u16ptr, sizeof(U32));
00740 dest_end.u64ptr = (U64 *)Align_down((U32)dest_end.u32ptr, sizeof(U64));
00741
00742
00743 while (dest.u8ptr < dest_end.u8ptr)
00744 {
00745
00746 flashc_clear_page_buffer();
00747 error_status |= flashc_error_status;
00748
00749
00750 flash_page_source_end.u64ptr =
00751 (U64 *)min((U32)dest_end.u64ptr,
00752 Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) + AVR32_FLASHC_PAGE_SIZE);
00753
00754
00755 incomplete_flash_page_end = (Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) >=
00756 Align_down((U32)dest_end.u8ptr, AVR32_FLASHC_PAGE_SIZE));
00757
00758
00759 flash_dword.u64 = source.u64;
00760
00761
00762 if (!Test_align((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE))
00763 {
00764
00765
00766
00767
00768 for (tmp.u8ptr = (U8 *)Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE);
00769 tmp.u64ptr < (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64));
00770 tmp.u64ptr++)
00771 *tmp.u64ptr = *tmp.u64ptr;
00772
00773
00774 if (!Test_align((U32)dest.u8ptr, sizeof(U64)))
00775 {
00776
00777
00778
00779
00780
00781 for (i = 0; i < Get_align((U32)dest.u8ptr, sizeof(U64)); i++)
00782 flash_dword.u8[i] = *tmp.u8ptr++;
00783
00784
00785 dest.u64ptr = (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64));
00786
00787
00788 if (dest.u64ptr < dest_end.u64ptr)
00789 {
00790
00791 *dest.u64ptr++ = flash_dword.u64;
00792 flash_dword.u64 = source.u64;
00793 }
00794 }
00795 }
00796
00797
00798 for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--)
00799 *dest.u64ptr++ = source.u64;
00800
00801
00802 if (incomplete_flash_page_end)
00803 {
00804
00805
00806
00807 {
00808 tmp.u8ptr = (volatile U8 *)dest_end.u8ptr;
00809
00810
00811 if (!Test_align((U32)dest_end.u8ptr, sizeof(U64)))
00812 {
00813
00814 for (i = Get_align((U32)dest_end.u8ptr, sizeof(U64)); i < sizeof(U64); i++)
00815 flash_dword.u8[i] = *tmp.u8ptr++;
00816
00817
00818 *dest.u64ptr++ = flash_dword.u64;
00819 }
00820
00821
00822 for (; !Test_align((U32)tmp.u64ptr, AVR32_FLASHC_PAGE_SIZE); tmp.u64ptr++)
00823 *tmp.u64ptr = *tmp.u64ptr;
00824 }
00825 }
00826
00827
00828 if (dest.u8ptr <= AVR32_FLASHC_USER_PAGE)
00829 {
00830
00831 if (erase)
00832 {
00833 flashc_erase_page(-1, FALSE);
00834 error_status |= flashc_error_status;
00835 }
00836 flashc_write_page(-1);
00837 error_status |= flashc_error_status;
00838
00839
00840 if (dest.u8ptr >= flash_array_end.u8ptr)
00841 dest.u8ptr = AVR32_FLASHC_USER_PAGE;
00842 }
00843
00844 else
00845 {
00846
00847 if (erase)
00848 {
00849 flashc_erase_user_page(FALSE);
00850 error_status |= flashc_error_status;
00851 }
00852 flashc_write_user_page();
00853 error_status |= flashc_error_status;
00854 }
00855 }
00856
00857
00858 flashc_error_status = error_status;
00859
00860
00861 return dst;
00862 }
00863
00864
00865 volatile void *flashc_memcpy(volatile void *dst, const void *src, size_t nbytes, Bool erase)
00866 {
00867
00868 UnionCVPtr flash_array_end;
00869 UnionVPtr dest;
00870 UnionCPtr source;
00871 StructCVPtr dest_end;
00872 UnionCVPtr flash_page_source_end;
00873 Bool incomplete_flash_page_end;
00874 Union64 flash_dword;
00875 Bool flash_dword_pending = FALSE;
00876 UnionVPtr tmp;
00877 unsigned int error_status = 0;
00878 unsigned int i, j;
00879
00880
00881 flash_array_end.u8ptr = AVR32_FLASH + flashc_get_flash_size();
00882 dest.u8ptr = dst;
00883 source.u8ptr = src;
00884 dest_end.u8ptr = dest.u8ptr + nbytes;
00885
00886
00887 if (dest.u8ptr < AVR32_FLASH)
00888 {
00889 source.u8ptr += AVR32_FLASH - dest.u8ptr;
00890 dest.u8ptr = AVR32_FLASH;
00891 }
00892 else if (flash_array_end.u8ptr <= dest.u8ptr && dest.u8ptr < AVR32_FLASHC_USER_PAGE)
00893 {
00894 source.u8ptr += AVR32_FLASHC_USER_PAGE - dest.u8ptr;
00895 dest.u8ptr = AVR32_FLASHC_USER_PAGE;
00896 }
00897
00898
00899 if (dest_end.u8ptr > AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE)
00900 {
00901 dest_end.u8ptr = AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE;
00902 }
00903 else if (AVR32_FLASHC_USER_PAGE >= dest_end.u8ptr && dest_end.u8ptr > flash_array_end.u8ptr)
00904 {
00905 dest_end.u8ptr = flash_array_end.u8ptr;
00906 }
00907
00908
00909 dest_end.u16ptr = (U16 *)Align_down((U32)dest_end.u8ptr, sizeof(U16));
00910 dest_end.u32ptr = (U32 *)Align_down((U32)dest_end.u16ptr, sizeof(U32));
00911 dest_end.u64ptr = (U64 *)Align_down((U32)dest_end.u32ptr, sizeof(U64));
00912
00913
00914 while (dest.u8ptr < dest_end.u8ptr)
00915 {
00916
00917 flashc_clear_page_buffer();
00918 error_status |= flashc_error_status;
00919
00920
00921 flash_page_source_end.u64ptr =
00922 (U64 *)min((U32)dest_end.u64ptr,
00923 Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) + AVR32_FLASHC_PAGE_SIZE);
00924
00925
00926 incomplete_flash_page_end = (Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) >=
00927 Align_down((U32)dest_end.u8ptr, AVR32_FLASHC_PAGE_SIZE));
00928
00929
00930 if (!Test_align((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE))
00931 {
00932
00933
00934
00935
00936 for (tmp.u8ptr = (U8 *)Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE);
00937 tmp.u64ptr < (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64));
00938 tmp.u64ptr++)
00939 *tmp.u64ptr = *tmp.u64ptr;
00940
00941
00942 if (!Test_align((U32)dest.u8ptr, sizeof(U64)))
00943 {
00944
00945
00946
00947
00948
00949 for (i = 0; i < Get_align((U32)dest.u8ptr, sizeof(U64)); i++)
00950 flash_dword.u8[i] = *tmp.u8ptr++;
00951
00952
00953 for (; i < sizeof(U64); i++)
00954 flash_dword.u8[i] = *source.u8ptr++;
00955
00956
00957 dest.u64ptr = (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64));
00958
00959
00960 if (dest.u64ptr < dest_end.u64ptr)
00961 {
00962
00963 *dest.u64ptr++ = flash_dword.u64;
00964 }
00965
00966
00967 else flash_dword_pending = TRUE;
00968 }
00969 }
00970
00971
00972
00973 switch (Get_align((U32)source.u8ptr, sizeof(U32)))
00974 {
00975 case 0:
00976 for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--)
00977 *dest.u64ptr++ = *source.u64ptr++;
00978 break;
00979
00980 case sizeof(U16):
00981 for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--)
00982 {
00983 for (j = 0; j < sizeof(U64) / sizeof(U16); j++) flash_dword.u16[j] = *source.u16ptr++;
00984 *dest.u64ptr++ = flash_dword.u64;
00985 }
00986 break;
00987
00988 default:
00989 for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--)
00990 {
00991 for (j = 0; j < sizeof(U64); j++) flash_dword.u8[j] = *source.u8ptr++;
00992 *dest.u64ptr++ = flash_dword.u64;
00993 }
00994 }
00995
00996
00997 if (incomplete_flash_page_end)
00998 {
00999
01000 if (flash_dword_pending) i = Get_align((U32)dest_end.u8ptr, sizeof(U64));
01001
01002 else
01003 {
01004
01005 for (i = 0; i < Get_align((U32)dest_end.u8ptr, sizeof(U64)); i++)
01006 flash_dword.u8[i] = *source.u8ptr++;
01007 }
01008
01009
01010
01011
01012 {
01013 tmp.u8ptr = (volatile U8 *)dest_end.u8ptr;
01014
01015
01016 if (!Test_align((U32)dest_end.u8ptr, sizeof(U64)))
01017 {
01018
01019 for (; i < sizeof(U64); i++)
01020 flash_dword.u8[i] = *tmp.u8ptr++;
01021
01022
01023 *dest.u64ptr++ = flash_dword.u64;
01024 }
01025
01026
01027 for (; !Test_align((U32)tmp.u64ptr, AVR32_FLASHC_PAGE_SIZE); tmp.u64ptr++)
01028 *tmp.u64ptr = *tmp.u64ptr;
01029 }
01030 }
01031
01032
01033 if (dest.u8ptr <= AVR32_FLASHC_USER_PAGE)
01034 {
01035
01036 if (erase)
01037 {
01038 flashc_erase_page(-1, FALSE);
01039 error_status |= flashc_error_status;
01040 }
01041 flashc_write_page(-1);
01042 error_status |= flashc_error_status;
01043
01044
01045 if (dest.u8ptr >= flash_array_end.u8ptr)
01046 {
01047 source.u8ptr += AVR32_FLASHC_USER_PAGE - dest.u8ptr;
01048 dest.u8ptr = AVR32_FLASHC_USER_PAGE;
01049 }
01050 }
01051
01052 else
01053 {
01054
01055 if (erase)
01056 {
01057 flashc_erase_user_page(FALSE);
01058 error_status |= flashc_error_status;
01059 }
01060 flashc_write_user_page();
01061 error_status |= flashc_error_status;
01062 }
01063 }
01064
01065
01066 flashc_error_status = error_status;
01067
01068
01069 return dst;
01070 }
01071
01072
01073 #if UC3C
01074 void flashc_set_flash_waitstate_and_readmode(unsigned long cpu_f_hz)
01075 {
01077 #undef AVR32_FLASHC_FWS_0_MAX_FREQ
01078 #undef AVR32_FLASHC_FWS_1_MAX_FREQ
01079 #undef AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ
01080 #undef AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ
01081 #define AVR32_FLASHC_FWS_0_MAX_FREQ 33000000
01082 #define AVR32_FLASHC_FWS_1_MAX_FREQ 66000000
01083 #define AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ 33000000
01084 #define AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ 72000000
01085
01086
01087
01088 if(cpu_f_hz > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ)
01089 {
01090
01091 flashc_set_wait_state(1);
01092 if(cpu_f_hz <= AVR32_FLASHC_FWS_1_MAX_FREQ)
01093 {
01094
01095 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1);
01096 }
01097 else
01098 {
01099
01100 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1);
01101 }
01102 }
01103 else
01104 {
01105
01106 flashc_set_wait_state(0);
01107
01108
01109 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1);
01110
01111 }
01112 }
01113 #endif // UC3C device-specific implementation
01114