usb_dfu.c File Reference


Detailed Description

Management of the USB device firmware upgrade.

This file manages the USB device firmware upgrade.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

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 Documentation

#define AVR32_FLASH_SIZE   0x00080000

#define CMD_BLANK_CHECK   0x01

Definition at line 104 of file usb_dfu.c.

#define CMD_ERASE   0x00

Definition at line 107 of file usb_dfu.c.

#define CMD_ERASE_ARG_CHIP   0xFF

Definition at line 114 of file usb_dfu.c.

#define CMD_GRP_DNLOAD   0x01

Definition at line 94 of file usb_dfu.c.

#define CMD_GRP_EXEC   0x04

Definition at line 96 of file usb_dfu.c.

#define CMD_GRP_SELECT   0x06

Definition at line 97 of file usb_dfu.c.

#define CMD_GRP_UPLOAD   0x03

Definition at line 95 of file usb_dfu.c.

#define CMD_PROGRAM_START   0x00

Definition at line 100 of file usb_dfu.c.

#define CMD_READ_MEMORY   0x00

Definition at line 103 of file usb_dfu.c.

#define CMD_SELECT_MEMORY   0x03

Definition at line 111 of file usb_dfu.c.

#define CMD_SELECT_MEMORY_ARG_PAGE   0x01

Definition at line 122 of file usb_dfu.c.

#define CMD_SELECT_MEMORY_ARG_UNIT   0x00

Definition at line 121 of file usb_dfu.c.

#define CMD_START_APPLI   0x03

Definition at line 108 of file usb_dfu.c.

#define CMD_START_APPLI_ARG_NO_RESET   0x01

Definition at line 118 of file usb_dfu.c.

#define CMD_START_APPLI_ARG_RESET   0x00

Definition at line 117 of file usb_dfu.c.

#define dfu_format_dfu_to_mcu_data ( width,
data   )     ((TPASTE2(U, width))(data))

Definition at line 88 of file usb_dfu.c.

#define Dfu_format_dfu_to_mcu_data ( width,
data   )     ((TPASTE2(U, width))(data))

Definition at line 86 of file usb_dfu.c.

#define dfu_format_mcu_to_dfu_data ( width,
data   )     ((TPASTE2(U, width))(data))

Definition at line 87 of file usb_dfu.c.

#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.

Depending on MCU endianism, swap or not data bytes.

Parameters:
width Data width in bits: 16, 32 or 64
data 16-, 32- or 64-bit data to format
Returns:
Formatted 16-, 32- or 64-bit data

Definition at line 85 of file usb_dfu.c.

#define ISP_ID0_ADDRESS   0x01

Definition at line 147 of file usb_dfu.c.

#define ISP_ID1_ADDRESS   0x02

Definition at line 148 of file usb_dfu.c.

#define ISP_INF_ITEM_COUNT   (ISP_ID1_ADDRESS + 1)

Definition at line 151 of file usb_dfu.c.

#define ISP_VERSION_ADDRESS   0x00

Definition at line 146 of file usb_dfu.c.

#define MEM_BOOTLOADER   0x04

Definition at line 129 of file usb_dfu.c.

#define MEM_CONFIGURATION   0x03

Definition at line 128 of file usb_dfu.c.

#define MEM_COUNT   (MEM_USER + 1)

Definition at line 134 of file usb_dfu.c.

#define MEM_EEPROM   0x01

Definition at line 126 of file usb_dfu.c.

#define MEM_FLASH   0x00

Definition at line 125 of file usb_dfu.c.

#define MEM_SECURITY   0x02

Definition at line 127 of file usb_dfu.c.

#define MEM_SIGNATURE   0x05

Definition at line 130 of file usb_dfu.c.

#define MEM_USER   0x06

Definition at line 131 of file usb_dfu.c.

#define POLYNOMIAL   (ISP_CFG1_CRC8_POLYNOMIAL << 7)

Calculates the CRC-8-CCITT.

CRC-8-CCITT is defined to be x^8 + x^2 + x + 1

To use this function use the following template:

crc = Crc8( crc, data );

Definition at line 357 of file usb_dfu.c.

Referenced by Crc8().

#define PRODUCT_FAMILY_ID_ADDRESS   0x01

Definition at line 138 of file usb_dfu.c.

#define PRODUCT_ID_ADDRESS   0x02

Definition at line 139 of file usb_dfu.c.

#define PRODUCT_INF_ITEM_COUNT   (PRODUCT_REVISION_ADDRESS + 1)

Definition at line 143 of file usb_dfu.c.

#define PRODUCT_MANUFACTURER_ID_ADDRESS   0x00

Definition at line 137 of file usb_dfu.c.

#define PRODUCT_REVISION_ADDRESS   0x03

Definition at line 140 of file usb_dfu.c.


Function Documentation

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]

Definition at line 466 of file usb_dfu.c.

References ISP_INF.

00467 {
00468   memcpy(dst, ISP_INF + src, nbytes);
00469 }

static void mem_configuration_read ( void *  dst,
U32  src,
size_t  nbytes 
) [static]

Definition at line 450 of file usb_dfu.c.

00451 {
00452   U8 *dest = dst;
00453   while (nbytes--)
00454     *dest++ = flashc_read_gp_fuse_bit(src++);
00455 }

static void mem_configuration_write ( U32  dst,
const void *  src,
size_t  nbytes 
) [static]

Definition at line 458 of file usb_dfu.c.

00459 {
00460   const U8 *source = src;
00461   while (nbytes--)
00462     flashc_set_gp_fuse_bit(dst++, *source++);
00463 }

static void mem_flash_read ( void *  dst,
U32  src,
size_t  nbytes 
) [static]

Definition at line 421 of file usb_dfu.c.

00422 {
00423   memcpy(dst, AVR32_FLASH + src, nbytes);
00424 }

static void mem_flash_write ( U32  dst,
const void *  src,
size_t  nbytes 
) [static]

Definition at line 427 of file usb_dfu.c.

00428 {
00429   flashc_memcpy(AVR32_FLASH + dst, src, nbytes, FALSE);
00430 }

static void mem_security_read ( void *  dst,
U32  src,
size_t  nbytes 
) [static]

Definition at line 433 of file usb_dfu.c.

00434 {
00435   if (nbytes)
00436     *(U8 *)dst = flashc_is_security_bit_active();
00437 }

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]

Definition at line 478 of file usb_dfu.c.

00479 {
00480   memcpy(dst, (U8 *)AVR32_FLASHC_USER_PAGE + src, nbytes);
00481 }

static void mem_user_write ( U32  dst,
const void *  src,
size_t  nbytes 
) [static]

Definition at line 484 of file usb_dfu.c.

00485 {
00486   flashc_memcpy(AVR32_FLASHC_USER_PAGE + dst, src, nbytes, TRUE);
00487 }

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.

Parameters:
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 }


Variable Documentation

U8 cmd = CMD_START_APPLI [static]

Definition at line 303 of file usb_dfu.c.

U8 cmd_group = CMD_GRP_EXEC [static]

Definition at line 302 of file usb_dfu.c.

U32 data_bytes [static]

Definition at line 307 of file usb_dfu.c.

U8 dfu_frame[DFU_FRAME_LENGTH] [static]

Definition at line 308 of file usb_dfu.c.

U8 dfu_status = STATUS_OK [static]

Definition at line 309 of file usb_dfu.c.

Definition at line 306 of file usb_dfu.c.

const U8 ISP_INF[ISP_INF_ITEM_COUNT] [static]

Initial value:

Definition at line 187 of file usb_dfu.c.

S32 length [static]

Definition at line 301 of file usb_dfu.c.

U8 memory = MEM_FLASH [static]

Definition at line 304 of file usb_dfu.c.

struct { ... } MEMORY_ACCESS[MEM_COUNT] [static]

address_t MEMORY_END_ADDRESS[MEM_COUNT] [static]

Definition at line 194 of file usb_dfu.c.

const U8 MEMORY_ERASE_VALUE[MEM_COUNT] [static]

Initial value:

{
  
  0xFF,

  
  0xFF,

  
  0x00,

  
  0x01,

  
  0x00,

  
  0x00,

  
  0xFF
}

Definition at line 276 of file usb_dfu.c.

U8 PRODUCT_INF[PRODUCT_INF_ITEM_COUNT] [static]

Initial value:

Definition at line 181 of file usb_dfu.c.

void(* read)(void *dst, U32 src, size_t nbytes)

Bool security_active = TRUE [static]

Definition at line 300 of file usb_dfu.c.

Definition at line 305 of file usb_dfu.c.

U8 usb_dfu_state = STATE_dfuIDLE

Definition at line 312 of file usb_dfu.c.

U8 usb_dfu_status = STATUS_OK

Definition at line 311 of file usb_dfu.c.

void(* write)(U32 dst, const void *src, size_t nbytes)


Generated on Fri Feb 19 02:32:46 2010 for AVR32 - USB DFU Example: ISP by  doxygen 1.5.5