X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/5a4def747897c1c6ffbe465506d846c7c686d3e9..0019fbd1294ccc9ecb0ac4ddb5d8c71efcf9597f:/Bootloaders/DFU/BootloaderDFU.c?ds=sidebyside diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c index d7bec1f46..717c934e5 100644 --- a/Bootloaders/DFU/BootloaderDFU.c +++ b/Bootloaders/DFU/BootloaderDFU.c @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2010. + Copyright (C) Dean Camera, 2011. dean [at] fourwalledcubicle [dot] com - www.fourwalledcubicle.com + www.lufa-lib.org */ /* - Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -38,59 +38,59 @@ /** Flag to indicate if the bootloader is currently running in secure mode, disallowing memory operations * other than erase. This is initially set to the value set by SECURE_MODE, and cleared by the bootloader - * once a memory erase has completed. + * once a memory erase has completed in a bootloader session. */ -bool IsSecure = SECURE_MODE; +static bool IsSecure = SECURE_MODE; /** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run * via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application * jumped to via an indirect jump to location 0x0000 (or other location specified by the host). */ -bool RunBootloader = true; +static bool RunBootloader = true; /** Flag to indicate if the bootloader is waiting to exit. When the host requests the bootloader to exit and * jump to the application address it specifies, it sends two sequential commands which must be properly * acknowledged. Upon reception of the first the RunBootloader flag is cleared and the WaitForExit flag is set, * causing the bootloader to wait for the final exit command before shutting down. */ -bool WaitForExit = false; +static bool WaitForExit = false; /** Current DFU state machine state, one of the values in the DFU_State_t enum. */ -uint8_t DFU_State = dfuIDLE; +static uint8_t DFU_State = dfuIDLE; /** Status code of the last executed DFU command. This is set to one of the values in the DFU_Status_t enum after * each operation, and returned to the host when a Get Status DFU request is issued. */ -uint8_t DFU_Status = OK; +static uint8_t DFU_Status = OK; /** Data containing the DFU command sent from the host. */ -DFU_Command_t SentCommand; +static DFU_Command_t SentCommand; /** Response to the last issued Read Data DFU command. Unlike other DFU commands, the read command * requires a single byte response from the bootloader containing the read data when the next DFU_UPLOAD command * is issued by the host. */ -uint8_t ResponseByte; +static uint8_t ResponseByte; /** Pointer to the start of the user application. By default this is 0x0000 (the reset vector), however the host * may specify an alternate address when issuing the application soft-start command. */ -AppPtr_t AppStartPtr = (AppPtr_t)0x0000; +static AppPtr_t AppStartPtr = (AppPtr_t)0x0000; /** 64-bit flash page number. This is concatenated with the current 16-bit address on USB AVRs containing more than * 64KB of flash memory. */ -uint8_t Flash64KBPage = 0; +static uint8_t Flash64KBPage = 0; /** Memory start address, indicating the current address in the memory being addressed (either FLASH or EEPROM * depending on the issued command from the host). */ -uint16_t StartAddr = 0x0000; +static uint16_t StartAddr = 0x0000; /** Memory end address, indicating the end address to read to/write from in the memory being addressed (either FLASH * of EEPROM depending on the issued command from the host). */ -uint16_t EndAddr = 0x0000; +static uint16_t EndAddr = 0x0000; /** Main program entry point. This routine configures the hardware required by the bootloader, then continuously @@ -102,6 +102,23 @@ int main(void) /* Configure hardware required by the bootloader */ SetupHardware(); + #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) + /* Disable JTAG debugging */ + MCUCR |= (1 << JTD); + MCUCR |= (1 << JTD); + + /* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */ + PORTF |= (1 << 4); + _delay_ms(10); + + /* If the TCK pin is not jumpered to ground, start the user application instead */ + RunBootloader = (!(PINF & (1 << 4))); + + /* Re-enable JTAG debugging */ + MCUCR &= ~(1 << JTD); + MCUCR &= ~(1 << JTD); + #endif + /* Enable global interrupts so that the USB stack can function */ sei(); @@ -138,25 +155,32 @@ void SetupHardware(void) void ResetHardware(void) { /* Shut down the USB subsystem */ - USB_ShutDown(); + USB_Disable(); /* Relocate the interrupt vector table back to the application section */ MCUCR = (1 << IVCE); MCUCR = 0; } -/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific - * control requests that are not handled internally by the USB library (including the DFU commands, which are - * all issued via the control endpoint), so that they can be handled appropriately for the application. +/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to + * the device from the USB host before passing along unhandled control requests to the library for processing + * internally. */ -void EVENT_USB_Device_UnhandledControlRequest(void) +void EVENT_USB_Device_ControlRequest(void) { /* Get the size of the command and data from the wLength value */ SentCommand.DataSize = USB_ControlRequest.wLength; + + /* Ignore any requests that aren't directed to the DFU interface */ + if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) != + (REQTYPE_CLASS | REQREC_INTERFACE)) + { + return; + } switch (USB_ControlRequest.bRequest) { - case REQ_DFU_DNLOAD: + case DFU_REQ_DNLOAD: Endpoint_ClearSETUP(); /* Check if bootloader is waiting to terminate */ @@ -309,7 +333,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void) Endpoint_ClearStatusStage(); break; - case REQ_DFU_UPLOAD: + case DFU_REQ_UPLOAD: Endpoint_ClearSETUP(); while (!(Endpoint_IsINReady())) @@ -408,7 +432,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void) Endpoint_ClearStatusStage(); break; - case REQ_DFU_GETSTATUS: + case DFU_REQ_GETSTATUS: Endpoint_ClearSETUP(); /* Write 8-bit status value */ @@ -428,7 +452,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void) Endpoint_ClearStatusStage(); break; - case REQ_DFU_CLRSTATUS: + case DFU_REQ_CLRSTATUS: Endpoint_ClearSETUP(); /* Reset the status value variable to the default OK status */ @@ -436,7 +460,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void) Endpoint_ClearStatusStage(); break; - case REQ_DFU_GETSTATE: + case DFU_REQ_GETSTATE: Endpoint_ClearSETUP(); /* Write the current device state to the endpoint */ @@ -446,7 +470,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void) Endpoint_ClearStatusStage(); break; - case REQ_DFU_ABORT: + case DFU_REQ_ABORT: Endpoint_ClearSETUP(); /* Reset the current state variable to the default idle state */