This file manages the USB device firmware upgrade.
Definition in file usb_dfu.c.
#include "conf_usb.h"
#include <avr32/io.h>
#include <stddef.h>
#include <string.h>
#include "compiler.h"
#include "pm.h"
#include "flashc.h"
#include "usb_drv.h"
#include "usb_task.h"
#include "usb_descriptors.h"
#include "usb_dfu.h"
#include "boot.h"
#include "conf_isp.h"
#include "isp.h"
Go to the source code of this file.
Data Structures | |
union | address_t |
Defines | |
#define | AVR32_FLASH_SIZE 0x00080000 |
#define | CMD_BLANK_CHECK 0x01 |
#define | CMD_ERASE 0x00 |
#define | CMD_ERASE_ARG_CHIP 0xFF |
#define | CMD_GRP_DNLOAD 0x01 |
#define | CMD_GRP_EXEC 0x04 |
#define | CMD_GRP_SELECT 0x06 |
#define | CMD_GRP_UPLOAD 0x03 |
#define | CMD_PROGRAM_START 0x00 |
#define | CMD_READ_MEMORY 0x00 |
#define | CMD_SELECT_MEMORY 0x03 |
#define | CMD_SELECT_MEMORY_ARG_PAGE 0x01 |
#define | CMD_SELECT_MEMORY_ARG_UNIT 0x00 |
#define | CMD_START_APPLI 0x03 |
#define | CMD_START_APPLI_ARG_NO_RESET 0x01 |
#define | CMD_START_APPLI_ARG_RESET 0x00 |
#define | ISP_ID0_ADDRESS 0x01 |
#define | ISP_ID1_ADDRESS 0x02 |
#define | ISP_INF_ITEM_COUNT (ISP_ID1_ADDRESS + 1) |
#define | ISP_VERSION_ADDRESS 0x00 |
#define | MEM_BOOTLOADER 0x04 |
#define | MEM_CONFIGURATION 0x03 |
#define | MEM_COUNT (MEM_USER + 1) |
#define | MEM_EEPROM 0x01 |
#define | MEM_FLASH 0x00 |
#define | MEM_SECURITY 0x02 |
#define | MEM_SIGNATURE 0x05 |
#define | MEM_USER 0x06 |
#define | POLYNOMIAL (ISP_CFG1_CRC8_POLYNOMIAL << 7) |
Calculates the CRC-8-CCITT. | |
#define | PRODUCT_FAMILY_ID_ADDRESS 0x01 |
#define | PRODUCT_ID_ADDRESS 0x02 |
#define | PRODUCT_INF_ITEM_COUNT (PRODUCT_REVISION_ADDRESS + 1) |
#define | PRODUCT_MANUFACTURER_ID_ADDRESS 0x00 |
#define | PRODUCT_REVISION_ADDRESS 0x03 |
#define | dfu_format_dfu_to_mcu_data(width, data) ((TPASTE2(U, width))(data)) |
#define | Dfu_format_dfu_to_mcu_data(width, data) ((TPASTE2(U, width))(data)) |
#define | dfu_format_mcu_to_dfu_data(width, data) ((TPASTE2(U, width))(data)) |
#define | Dfu_format_mcu_to_dfu_data(width, data) ((TPASTE2(U, width))(data)) |
Convert 16-, 32- or 64-bit data between MCU and Atmel-DFU endianisms. | |
Functions | |
static U8 | Crc8 (U8 inCrc, U8 inData) |
static void | erase_check_mem (void) |
static void | force_isp (Bool force) |
static Bool | get_and_check_mem_range (void) |
static Bool | is_isp_forced (void) |
static void | mem_bootloader_read (void *dst, U32 src, size_t nbytes) |
static void | mem_configuration_read (void *dst, U32 src, size_t nbytes) |
static void | mem_configuration_write (U32 dst, const void *src, size_t nbytes) |
static void | mem_flash_read (void *dst, U32 src, size_t nbytes) |
static void | mem_flash_write (U32 dst, const void *src, size_t nbytes) |
static void | mem_security_read (void *dst, U32 src, size_t nbytes) |
static void | mem_security_write (U32 dst, const void *src, size_t nbytes) |
static void | mem_signature_read (void *dst, U32 src, size_t nbytes) |
static void | mem_user_read (void *dst, U32 src, size_t nbytes) |
static void | mem_user_write (U32 dst, const void *src, size_t nbytes) |
static void | read_mem (void) |
Bool | usb_dfu_dnload (void) |
Management of the DFU_DNLOAD requests. | |
void | usb_dfu_init (void) |
static void | usb_dfu_stop (void) |
Bool | usb_dfu_upload (void) |
Management of the DFU_UPLOAD requests. | |
static void | write_mem (void) |
static void | write_word_to_user_page (int offset, U32 value) |
write a Word at a 32bit offset in the Flash user page. | |
Variables | |
static U8 | cmd = CMD_START_APPLI |
static U8 | cmd_group = CMD_GRP_EXEC |
static U32 | data_bytes |
static U8 | dfu_frame [DFU_FRAME_LENGTH] |
static U8 | dfu_status = STATUS_OK |
static address_t | end_address |
static const U8 | ISP_INF [ISP_INF_ITEM_COUNT] |
static S32 | length |
static U8 | memory = MEM_FLASH |
struct { | |
void(* read )(void *dst, U32 src, size_t nbytes) | |
void(* write )(U32 dst, const void *src, size_t nbytes) | |
} | MEMORY_ACCESS [MEM_COUNT] |
static address_t | MEMORY_END_ADDRESS [MEM_COUNT] |
static const U8 | MEMORY_ERASE_VALUE [MEM_COUNT] |
static U8 | PRODUCT_INF [PRODUCT_INF_ITEM_COUNT] |
static Bool | security_active = TRUE |
static address_t | start_address |
U8 | usb_dfu_state = STATE_dfuIDLE |
U8 | usb_dfu_status = STATUS_OK |
#define AVR32_FLASH_SIZE 0x00080000 |
#define dfu_format_dfu_to_mcu_data | ( | width, | |||
data | ) | ((TPASTE2(U, width))(data)) |
#define Dfu_format_dfu_to_mcu_data | ( | width, | |||
data | ) | ((TPASTE2(U, width))(data)) |
#define dfu_format_mcu_to_dfu_data | ( | width, | |||
data | ) | ((TPASTE2(U, width))(data)) |
#define Dfu_format_mcu_to_dfu_data | ( | width, | |||
data | ) | ((TPASTE2(U, width))(data)) |
#define POLYNOMIAL (ISP_CFG1_CRC8_POLYNOMIAL << 7) |
#define PRODUCT_INF_ITEM_COUNT (PRODUCT_REVISION_ADDRESS + 1) |
static U8 Crc8 | ( | U8 | inCrc, | |
U8 | inData | |||
) | [static] |
Definition at line 358 of file usb_dfu.c.
References POLYNOMIAL.
Referenced by force_isp().
00359 { 00360 int i; 00361 U16 data; 00362 00363 data = inCrc ^ inData; 00364 data <<= 8; 00365 00366 for ( i = 0; i < 8; i++ ) 00367 { 00368 if (( data & 0x8000 ) != 0 ) 00369 { 00370 data = data ^ POLYNOMIAL; 00371 } 00372 data = data << 1; 00373 } 00374 return (unsigned char)( data >> 8 ); 00375 } // Crc8
static void erase_check_mem | ( | void | ) | [static] |
Definition at line 490 of file usb_dfu.c.
References DFU_FRAME_LENGTH, address_t::long_address, MEMORY_ACCESS, and STATUS_errCHECK_ERASED.
00491 { 00492 U8 *frame; 00493 U32 frame_bytes; 00494 00495 while (data_bytes) 00496 { 00497 frame = dfu_frame; 00498 frame_bytes = min(data_bytes, DFU_FRAME_LENGTH); 00499 data_bytes -= frame_bytes; 00500 00501 MEMORY_ACCESS[memory].read(frame, start_address.long_address, frame_bytes); 00502 00503 while (frame_bytes--) 00504 { 00505 if (*frame++ != MEMORY_ERASE_VALUE[memory]) 00506 { 00507 dfu_status = STATUS_errCHECK_ERASED; 00508 return; 00509 } 00510 start_address.long_address++; 00511 } 00512 } 00513 }
static void force_isp | ( | Bool | force | ) | [static] |
Definition at line 382 of file usb_dfu.c.
References Crc8(), ISP_CFG1, ISP_CFG1_CRC8_MASK, ISP_CFG1_CRC8_OFFSET, ISP_CFG1_FORCE_MASK, ISP_CFG1_FORCE_OFFSET, ISP_CFG1_OFFSET, and write_word_to_user_page().
00383 { 00384 U32 u32_tempo; 00385 U8 crc8 = 0; 00386 int i; 00387 00388 00389 // 1) Read the config word1 and set the ISP_FORCE bit to force. 00390 u32_tempo = (ISP_CFG1 & ~ISP_CFG1_FORCE_MASK) | ((force<<ISP_CFG1_FORCE_OFFSET) & ISP_CFG1_FORCE_MASK); 00391 00392 // 2) Compute the CRC8 and update the config word1 00393 for(i=24; i; i-=8) // Compute the CRC8 on the 3 upper Bytes of the word. 00394 crc8 = Crc8(crc8, u32_tempo>>i); 00395 u32_tempo = (u32_tempo & ~ISP_CFG1_CRC8_MASK) | ((crc8<<ISP_CFG1_CRC8_OFFSET) & ISP_CFG1_CRC8_MASK); 00396 00397 // 3) Write the config word1 00398 write_word_to_user_page(ISP_CFG1_OFFSET, u32_tempo); 00399 }
static Bool get_and_check_mem_range | ( | void | ) | [static] |
Definition at line 402 of file usb_dfu.c.
References dfu_format_dfu_to_mcu_data, address_t::long_address, address_t::page_offset, and STATUS_errADDRESS.
00403 { 00404 start_address.page_offset = Usb_read_endpoint_data(EP_CONTROL, 16); 00405 start_address.page_offset = dfu_format_dfu_to_mcu_data(16, start_address.page_offset); 00406 end_address.page_offset = Usb_read_endpoint_data(EP_CONTROL, 16); 00407 end_address.page_offset = dfu_format_dfu_to_mcu_data(16, end_address.page_offset); 00408 00409 if (end_address.long_address < start_address.long_address || 00410 end_address.long_address > MEMORY_END_ADDRESS[memory].long_address) 00411 { 00412 dfu_status = STATUS_errADDRESS; 00413 return FALSE; 00414 } 00415 00416 data_bytes = end_address.long_address - start_address.long_address + 1; 00417 return TRUE; 00418 }
static Bool is_isp_forced | ( | void | ) | [static] |
Definition at line 377 of file usb_dfu.c.
References ISP_CFG1, ISP_CFG1_FORCE_MASK, and ISP_CFG1_FORCE_OFFSET.
00378 { 00379 return((ISP_CFG1&ISP_CFG1_FORCE_MASK)>>ISP_CFG1_FORCE_OFFSET); 00380 }
static void mem_bootloader_read | ( | void * | dst, | |
U32 | src, | |||
size_t | nbytes | |||
) | [static] |
static void mem_configuration_read | ( | void * | dst, | |
U32 | src, | |||
size_t | nbytes | |||
) | [static] |
static void mem_configuration_write | ( | U32 | dst, | |
const void * | src, | |||
size_t | nbytes | |||
) | [static] |
static void mem_flash_read | ( | void * | dst, | |
U32 | src, | |||
size_t | nbytes | |||
) | [static] |
static void mem_flash_write | ( | U32 | dst, | |
const void * | src, | |||
size_t | nbytes | |||
) | [static] |
static void mem_security_read | ( | void * | dst, | |
U32 | src, | |||
size_t | nbytes | |||
) | [static] |
static void mem_security_write | ( | U32 | dst, | |
const void * | src, | |||
size_t | nbytes | |||
) | [static] |
Definition at line 440 of file usb_dfu.c.
00441 { 00442 if (nbytes && *(U8 *)src) 00443 { 00444 security_active = TRUE; 00445 flashc_activate_security_bit(); 00446 } 00447 }
static void mem_signature_read | ( | void * | dst, | |
U32 | src, | |||
size_t | nbytes | |||
) | [static] |
Definition at line 472 of file usb_dfu.c.
References PRODUCT_INF.
00473 { 00474 memcpy(dst, PRODUCT_INF + src, nbytes); 00475 }
static void mem_user_read | ( | void * | dst, | |
U32 | src, | |||
size_t | nbytes | |||
) | [static] |
static void mem_user_write | ( | U32 | dst, | |
const void * | src, | |||
size_t | nbytes | |||
) | [static] |
static void read_mem | ( | void | ) | [static] |
Definition at line 516 of file usb_dfu.c.
References DFU_FRAME_LENGTH, address_t::long_address, and MEMORY_ACCESS.
00517 { 00518 void *frame; 00519 U32 frame_bytes; 00520 00521 while (data_bytes) 00522 { 00523 frame = dfu_frame; 00524 frame_bytes = min(data_bytes, DFU_FRAME_LENGTH); 00525 data_bytes -= frame_bytes; 00526 00527 MEMORY_ACCESS[memory].read(frame, start_address.long_address, frame_bytes); 00528 start_address.long_address += frame_bytes; 00529 00530 while (frame_bytes) 00531 { 00532 while (!Is_usb_control_in_ready()); 00533 00534 Usb_reset_endpoint_fifo_access(EP_CONTROL); 00535 frame_bytes = usb_write_ep_txpacket(EP_CONTROL, frame, frame_bytes, (const void **)&frame); 00536 Usb_ack_control_in_ready_send(); 00537 } 00538 } 00539 }
Bool usb_dfu_dnload | ( | void | ) |
Management of the DFU_DNLOAD requests.
Definition at line 617 of file usb_dfu.c.
References boot_program(), CMD_BLANK_CHECK, CMD_ERASE, CMD_ERASE_ARG_CHIP, CMD_GRP_DNLOAD, CMD_GRP_EXEC, CMD_GRP_SELECT, CMD_GRP_UPLOAD, CMD_PROGRAM_START, CMD_READ_MEMORY, CMD_SELECT_MEMORY, CMD_SELECT_MEMORY_ARG_PAGE, CMD_SELECT_MEMORY_ARG_UNIT, CMD_START_APPLI, CMD_START_APPLI_ARG_NO_RESET, CMD_START_APPLI_ARG_RESET, erase_check_mem(), force_isp(), get_and_check_mem_range(), is_isp_forced(), address_t::long_address, MEM_BOOTLOADER, MEM_CONFIGURATION, MEM_EEPROM, MEM_FLASH, MEM_SECURITY, MEM_SIGNATURE, MEM_USER, MEMORY_ACCESS, address_t::page, read, STATUS_errADDRESS, STATUS_errCHECK_ERASED, STATUS_errSTALLEDPKT, STATUS_errVERIFY, STATUS_errWRITE, STATUS_OK, sys_clk_gen_stop(), usb_dfu_stop(), wait_10_ms(), write, and write_mem().
00618 { 00619 static U8 tmp_memory; 00620 static U16 tmp_page; 00621 00622 if (!is_isp_forced()) force_isp(TRUE); 00623 00624 dfu_status = STATUS_OK; 00625 00626 Usb_read_endpoint_data(EP_CONTROL, 16); // Dummy read: wValue. 00627 Usb_read_endpoint_data(EP_CONTROL, 16); // Dummy read: wIndex. 00628 length = Usb_read_endpoint_data(EP_CONTROL, 16); 00629 length = usb_format_usb_to_mcu_data(16, length); 00630 Usb_ack_setup_received_free(); 00631 00632 if (length) 00633 { 00634 while (!Is_usb_control_out_received()); 00635 Usb_reset_endpoint_fifo_access(EP_CONTROL); 00636 00637 cmd_group = Usb_read_endpoint_data(EP_CONTROL, 8); 00638 cmd = Usb_read_endpoint_data(EP_CONTROL, 8); 00639 switch (cmd_group) 00640 { 00641 case CMD_GRP_DNLOAD: 00642 if (security_active) 00643 { 00644 goto unsupported_request; 00645 } 00646 if (!get_and_check_mem_range()) break; 00647 if (!MEMORY_ACCESS[memory].write) 00648 { 00649 dfu_status = STATUS_errWRITE; 00650 break; 00651 } 00652 switch (cmd) 00653 { 00654 case CMD_PROGRAM_START: 00655 Usb_ack_control_out_received_free(); 00656 write_mem(); 00657 break; 00658 00659 default: 00660 goto unsupported_request; 00661 } 00662 break; 00663 00664 case CMD_GRP_UPLOAD: 00665 if (security_active) 00666 { 00667 goto unsupported_request; 00668 } 00669 if (!get_and_check_mem_range()) break; 00670 if (!MEMORY_ACCESS[memory].read) 00671 { 00672 dfu_status = STATUS_errVERIFY; 00673 break; 00674 } 00675 switch (cmd) 00676 { 00677 case CMD_READ_MEMORY: 00678 break; 00679 00680 case CMD_BLANK_CHECK: 00681 erase_check_mem(); 00682 break; 00683 00684 default: 00685 goto unsupported_request; 00686 } 00687 break; 00688 00689 case CMD_GRP_EXEC: 00690 switch (cmd) 00691 { 00692 case CMD_ERASE: 00693 switch (Usb_read_endpoint_data(EP_CONTROL, 8)) 00694 { 00695 case CMD_ERASE_ARG_CHIP: 00696 memory = MEM_FLASH; 00697 end_address.long_address = start_address.long_address = 0; 00698 flashc_lock_all_regions(FALSE); 00699 flashc_erase_all_pages(FALSE); 00700 security_active = FALSE; 00701 break; 00702 00703 default: 00704 goto unsupported_request; 00705 } 00706 break; 00707 00708 case CMD_START_APPLI: 00709 switch (Usb_read_endpoint_data(EP_CONTROL, 8)) 00710 { 00711 case CMD_START_APPLI_ARG_RESET: 00712 usb_dfu_stop(); 00713 Disable_global_interrupt(); 00714 AVR32_WDT.ctrl = AVR32_WDT_CTRL_EN_MASK | 00715 (10 << AVR32_WDT_CTRL_PSEL_OFFSET) | 00716 (AVR32_WDT_KEY_VALUE << AVR32_WDT_CTRL_KEY_OFFSET); 00717 AVR32_WDT.ctrl = AVR32_WDT_CTRL_EN_MASK | 00718 (10 << AVR32_WDT_CTRL_PSEL_OFFSET) | 00719 ((~AVR32_WDT_KEY_VALUE << AVR32_WDT_CTRL_KEY_OFFSET) & AVR32_WDT_CTRL_KEY_MASK); 00720 while (1); 00721 00722 case CMD_START_APPLI_ARG_NO_RESET: 00723 usb_dfu_stop(); 00724 sys_clk_gen_stop(); 00725 wait_10_ms(); 00726 boot_program(); 00727 break; 00728 00729 default: 00730 goto unsupported_request; 00731 } 00732 break; 00733 00734 default: 00735 goto unsupported_request; 00736 } 00737 break; 00738 00739 case CMD_GRP_SELECT: 00740 if (security_active) 00741 { 00742 goto unsupported_request; 00743 } 00744 switch (cmd) 00745 { 00746 case CMD_SELECT_MEMORY: 00747 switch (Usb_read_endpoint_data(EP_CONTROL, 8)) 00748 { 00749 case CMD_SELECT_MEMORY_ARG_UNIT: 00750 switch (tmp_memory = Usb_read_endpoint_data(EP_CONTROL, 8)) 00751 { 00752 case MEM_FLASH: 00753 case MEM_EEPROM: 00754 case MEM_SECURITY: 00755 case MEM_CONFIGURATION: 00756 case MEM_BOOTLOADER: 00757 case MEM_SIGNATURE: 00758 case MEM_USER: 00759 memory = tmp_memory; 00760 end_address.long_address = start_address.long_address = 0; 00761 break; 00762 00763 default: 00764 dfu_status = STATUS_errADDRESS; 00765 } 00766 break; 00767 00768 case CMD_SELECT_MEMORY_ARG_PAGE: 00769 MSB(tmp_page) = Usb_read_endpoint_data(EP_CONTROL, 8); 00770 LSB(tmp_page) = Usb_read_endpoint_data(EP_CONTROL, 8); 00771 if (tmp_page <= MEMORY_END_ADDRESS[memory].page) 00772 { 00773 end_address.page = start_address.page = tmp_page; 00774 } 00775 else dfu_status = STATUS_errADDRESS; 00776 break; 00777 00778 default: 00779 goto unsupported_request; 00780 } 00781 break; 00782 00783 default: 00784 goto unsupported_request; 00785 } 00786 break; 00787 00788 default: 00789 unsupported_request: 00790 dfu_status = STATUS_errSTALLEDPKT; 00791 } 00792 00793 Usb_ack_control_out_received_free(); 00794 } 00795 00796 usb_dfu_status = dfu_status; 00797 if (usb_dfu_status != STATUS_OK && 00798 usb_dfu_status != STATUS_errCHECK_ERASED) return FALSE; 00799 00800 Usb_ack_control_in_ready_send(); 00801 while (!Is_usb_control_in_ready()); 00802 return TRUE; 00803 }
void usb_dfu_init | ( | void | ) |
Definition at line 581 of file usb_dfu.c.
References address_t::long_address, MEM_FLASH, PRODUCT_ID_ADDRESS, PRODUCT_INF, and PRODUCT_REVISION_ADDRESS.
00582 { 00583 PRODUCT_INF[PRODUCT_ID_ADDRESS] = 00584 Rd_bitfield(Get_system_register(AVR32_CONFIG0), AVR32_CONFIG0_PROCESSORID_MASK); 00585 PRODUCT_INF[PRODUCT_REVISION_ADDRESS] = 00586 Rd_bitfield(Get_system_register(AVR32_CONFIG0), AVR32_CONFIG0_PROCESSORREVISION_MASK); 00587 00588 MEMORY_END_ADDRESS[MEM_FLASH].long_address = flashc_get_flash_size() - 1; 00589 00590 security_active = flashc_is_security_bit_active(); 00591 }
static void usb_dfu_stop | ( | void | ) | [static] |
Definition at line 594 of file usb_dfu.c.
References force_isp().
00595 { 00596 force_isp(FALSE); 00597 00598 Usb_ack_control_out_received_free(); 00599 Usb_ack_control_in_ready_send(); 00600 00601 while (!Is_usb_setup_received()); 00602 Usb_ack_setup_received_free(); 00603 Usb_ack_control_in_ready_send(); 00604 00605 while (!Is_usb_control_in_ready()); 00606 00607 Disable_global_interrupt(); 00608 Usb_disable(); 00609 (void)Is_usb_enabled(); 00610 Enable_global_interrupt(); 00611 Usb_disable_otg_pad(); 00612 }
Bool usb_dfu_upload | ( | void | ) |
Management of the DFU_UPLOAD requests.
Definition at line 808 of file usb_dfu.c.
References CMD_BLANK_CHECK, CMD_GRP_UPLOAD, CMD_READ_MEMORY, dfu_format_mcu_to_dfu_data, address_t::page_offset, read_mem(), STATUS_errCHECK_ERASED, STATUS_errSTALLEDPKT, and STATUS_OK.
00809 { 00810 Usb_ack_setup_received_free(); 00811 Usb_reset_endpoint_fifo_access(EP_CONTROL); 00812 00813 if (cmd_group == CMD_GRP_UPLOAD && 00814 (dfu_status == STATUS_OK || 00815 dfu_status == STATUS_errCHECK_ERASED)) 00816 { 00817 switch (cmd) 00818 { 00819 case CMD_READ_MEMORY: 00820 read_mem(); 00821 break; 00822 00823 case CMD_BLANK_CHECK: 00824 Usb_write_endpoint_data(EP_CONTROL, 16, dfu_format_mcu_to_dfu_data(16, start_address.page_offset)); 00825 break; 00826 00827 default: 00828 goto unsupported_request; 00829 } 00830 } 00831 else 00832 { 00833 unsupported_request: 00834 dfu_status = STATUS_errSTALLEDPKT; 00835 } 00836 00837 usb_dfu_status = dfu_status; 00838 if (usb_dfu_status != STATUS_OK && 00839 usb_dfu_status != STATUS_errCHECK_ERASED) return FALSE; 00840 00841 if (Usb_byte_count(EP_CONTROL)) Usb_ack_control_in_ready_send(); 00842 while (!Is_usb_control_out_received()); 00843 Usb_ack_control_out_received_free(); 00844 return TRUE; 00845 }
static void write_mem | ( | void | ) | [static] |
Definition at line 542 of file usb_dfu.c.
References DFU_FRAME_LENGTH, EP_CONTROL_LENGTH, address_t::long_address, and MEMORY_ACCESS.
00543 { 00544 void *frame; 00545 U32 frame_bytes, unaligned_frame_bytes; 00546 00547 data_bytes += Get_align(start_address.long_address, EP_CONTROL_LENGTH); 00548 length -= EP_CONTROL_LENGTH + Align_up(data_bytes, EP_CONTROL_LENGTH); 00549 00550 while (data_bytes) 00551 { 00552 frame = dfu_frame; 00553 frame_bytes = min(data_bytes, DFU_FRAME_LENGTH); 00554 unaligned_frame_bytes = frame_bytes - Get_align(start_address.long_address, EP_CONTROL_LENGTH); 00555 data_bytes -= frame_bytes; 00556 00557 while (frame_bytes) 00558 { 00559 while (!Is_usb_control_out_received()); 00560 00561 Usb_reset_endpoint_fifo_access(EP_CONTROL); 00562 frame_bytes = usb_read_ep_rxpacket(EP_CONTROL, frame, frame_bytes, &frame); 00563 Usb_ack_control_out_received_free(); 00564 } 00565 00566 MEMORY_ACCESS[memory].write(start_address.long_address, 00567 dfu_frame + Get_align(start_address.long_address, EP_CONTROL_LENGTH), 00568 unaligned_frame_bytes); 00569 start_address.long_address += unaligned_frame_bytes; 00570 } 00571 00572 while (length > 0) 00573 { 00574 while (!Is_usb_control_out_received()); 00575 Usb_ack_control_out_received_free(); 00576 length -= EP_CONTROL_LENGTH; 00577 } 00578 }
static void write_word_to_user_page | ( | int | offset, | |
U32 | value | |||
) | [static] |
write a Word at a 32bit offset in the Flash user page.
offset | 32bits offset in the flash user page | |
value | value to write to the flash user page |
Definition at line 320 of file usb_dfu.c.
Referenced by force_isp().
00321 { 00322 int i; 00323 Union32 flash_word; 00324 volatile U32 *pu32_flash_ptr = (U32 *)AVR32_FLASHC_USER_PAGE_ADDRESS; 00325 00326 // 1) Clear the page buffer 00327 flashc_clear_page_buffer(); 00328 00329 // 2) Update the page buffer accordingly 00330 // 2.1) Copy the page to update into the page buffer 00331 // 2.2) Update a Word at offset 00332 for(i = 0; i < AVR32_FLASHC_USER_PAGE_SIZE; i += sizeof(U32)) 00333 { 00334 flash_word.u32 = *pu32_flash_ptr; 00335 if(i == offset) 00336 flash_word.u32 = value; 00337 *pu32_flash_ptr++ = flash_word.u32; 00338 } 00339 00340 // 3) Erase the current user page 00341 flashc_erase_user_page(FALSE); 00342 00343 // 4) Write the new user page content 00344 flashc_write_user_page(); 00345 }
U32 data_bytes [static] |
U8 dfu_status = STATUS_OK [static] |
address_t end_address [static] |
const U8 ISP_INF[ISP_INF_ITEM_COUNT] [static] |
struct { ... } MEMORY_ACCESS[MEM_COUNT] [static] |
address_t MEMORY_END_ADDRESS[MEM_COUNT] [static] |
const U8 MEMORY_ERASE_VALUE[MEM_COUNT] [static] |
U8 PRODUCT_INF[PRODUCT_INF_ITEM_COUNT] [static] |
Initial value:
void(* read)(void *dst, U32 src, size_t nbytes) |
Bool security_active = TRUE [static] |
address_t start_address [static] |
U8 usb_dfu_state = STATE_dfuIDLE |
U8 usb_dfu_status = STATUS_OK |
void(* write)(U32 dst, const void *src, size_t nbytes) |