X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/8f6b4ddf764c3a54e42d00a7502c82c5c3e71b1c..d0db78432fc02bacbd57cc9f15eb05b4e56981cb:/Bootloaders/CDC/BootloaderCDC.c diff --git a/Bootloaders/CDC/BootloaderCDC.c b/Bootloaders/CDC/BootloaderCDC.c index cb2672c75..d875b842d 100644 --- a/Bootloaders/CDC/BootloaderCDC.c +++ b/Bootloaders/CDC/BootloaderCDC.c @@ -43,10 +43,10 @@ * current encoding options, including baud rate, character format, parity mode and total number of * bits in each data chunk. */ -CDC_Line_Coding_t LineCoding = { BaudRateBPS: 9600, - CharFormat: OneStopBit, - ParityType: Parity_None, - DataBits: 8 }; +CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600, + .CharFormat = OneStopBit, + .ParityType = Parity_None, + .DataBits = 8 }; /** Current address counter. This stores the current address of the FLASH or EEPROM as set by the host, * and is used when reading or writing to the AVRs memory (either FLASH or EEPROM depending on the issued @@ -67,6 +67,26 @@ bool RunBootloader = true; */ int main(void) { + /* Setup hardware required for the bootloader */ + SetupHardware(); + + while (RunBootloader) + { + CDC_Task(); + USB_USBTask(); + } + + /* Reset all configured hardware to their default states for the user app */ + ResetHardware(); + + /* Start the user application */ + AppPtr_t AppStartPtr = (AppPtr_t)0x0000; + AppStartPtr(); +} + +/** Configures all hardware required for the bootloader. */ +void SetupHardware(void) +{ /* Disable watchdog if enabled by bootloader/fuses */ MCUSR &= ~(1 << WDRF); wdt_disable(); @@ -80,18 +100,11 @@ int main(void) /* Initialize USB Subsystem */ USB_Init(); +} - while (RunBootloader) - { - USB_USBTask(); - CDC_Task(); - } - - Endpoint_SelectEndpoint(CDC_TX_EPNUM); - - /* Wait until any pending transmissions have completed before shutting down */ - while (!(Endpoint_IsINReady())); - +/** Resets all configured hardware required for the bootloader back to their original states. */ +void ResetHardware(void) +{ /* Shut down the USB subsystem */ USB_ShutDown(); @@ -99,27 +112,14 @@ int main(void) MCUCR = (1 << IVCE); MCUCR = 0; - /* Reset any used hardware ports back to their defaults */ - PORTD = 0; - DDRD = 0; - - #if defined(PORTE) - PORTE = 0; - DDRE = 0; - #endif - /* Re-enable RWW section */ boot_rww_enable(); - - /* Start the user application */ - AppPtr_t AppStartPtr = (AppPtr_t)0x0000; - AppStartPtr(); } /** Event handler for the USB_Disconnect event. This indicates that the bootloader should exit and the user * application started. */ -EVENT_HANDLER(USB_Disconnect) +void EVENT_USB_Disconnect(void) { /* Upon disconnection, run user application */ RunBootloader = false; @@ -128,7 +128,7 @@ EVENT_HANDLER(USB_Disconnect) /** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready * to relay data to and from the attached USB host. */ -EVENT_HANDLER(USB_ConfigurationChanged) +void EVENT_USB_ConfigurationChanged(void) { /* Setup CDC Notification, Rx and Tx Endpoints */ Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, @@ -148,57 +148,55 @@ EVENT_HANDLER(USB_ConfigurationChanged) * control requests that are not handled internally by the USB library, so that they can be handled appropriately * for the application. */ -EVENT_HANDLER(USB_UnhandledControlPacket) +void EVENT_USB_UnhandledControlPacket(void) { uint8_t* LineCodingData = (uint8_t*)&LineCoding; - Endpoint_Discard_Word(); - /* Process CDC specific control requests */ - switch (bRequest) + switch (USB_ControlRequest.bRequest) { case REQ_GetLineEncoding: - if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { - Endpoint_ClearControlSETUP(); + Endpoint_ClearSETUP(); for (uint8_t i = 0; i < sizeof(LineCoding); i++) Endpoint_Write_Byte(*(LineCodingData++)); - Endpoint_ClearControlIN(); + Endpoint_ClearIN(); /* Acknowledge status stage */ while (!(Endpoint_IsOUTReceived())); - Endpoint_ClearControlOUT(); + Endpoint_ClearOUT(); } break; case REQ_SetLineEncoding: - if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { - Endpoint_ClearControlSETUP(); + Endpoint_ClearSETUP(); while (!(Endpoint_IsOUTReceived())); for (uint8_t i = 0; i < sizeof(LineCoding); i++) *(LineCodingData++) = Endpoint_Read_Byte(); - Endpoint_ClearControlOUT(); + Endpoint_ClearOUT(); /* Acknowledge status stage */ while (!(Endpoint_IsINReady())); - Endpoint_ClearControlIN(); + Endpoint_ClearIN(); } break; case REQ_SetControlLineState: - if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { - Endpoint_ClearControlSETUP(); + Endpoint_ClearSETUP(); /* Acknowledge status stage */ while (!(Endpoint_IsINReady())); - Endpoint_ClearControlIN(); + Endpoint_ClearIN(); } break; @@ -208,7 +206,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket) /** Reads or writes a block of EEPROM or FLASH memory to or from the appropriate CDC data endpoint, depending * on the AVR910 protocol command issued. * - * \param Command Single character AVR910 protocol command indicating what memory operation to perform + * \param[in] Command Single character AVR910 protocol command indicating what memory operation to perform */ static void ReadWriteMemoryBlock(const uint8_t Command) { @@ -250,7 +248,7 @@ static void ReadWriteMemoryBlock(const uint8_t Command) else { /* Read the next FLASH byte from the current FLASH page */ - #if defined(RAMPZ) + #if (FLASHEND > 0xFFFF) WriteNextResponseByte(pgm_read_byte_far(CurrAddress | HighByte)); #else WriteNextResponseByte(pgm_read_byte(CurrAddress | HighByte)); @@ -345,14 +343,14 @@ static uint8_t FetchNextCommandByte(void) /** Writes the next response byte to the CDC data IN endpoint, and sends the endpoint back if needed to free up the * bank when full ready for the next byte in the packet to the host. * - * \param Response Next response byte to send to the host + * \param[in] Response Next response byte to send to the host */ static void WriteNextResponseByte(const uint8_t Response) { /* Select the IN endpoint so that the next data byte can be written */ Endpoint_SelectEndpoint(CDC_TX_EPNUM); - /* If OUT endpoint empty, clear it and wait for the next packet from the host */ + /* If IN endpoint full, clear it and wait util ready for the next packet to the host */ if (!(Endpoint_IsReadWriteAllowed())) { Endpoint_ClearIN(); @@ -366,7 +364,7 @@ static void WriteNextResponseByte(const uint8_t Response) /** Task to read in AVR910 commands from the CDC data OUT endpoint, process them, perform the required actions * and send the appropriate response back to the host. */ -TASK(CDC_Task) +void CDC_Task(void) { /* Select the OUT endpoint */ Endpoint_SelectEndpoint(CDC_RX_EPNUM); @@ -426,9 +424,9 @@ TASK(CDC_Task) } else if (Command == 's') { - WriteNextResponseByte(SIGNATURE_0); - WriteNextResponseByte(SIGNATURE_1); - WriteNextResponseByte(SIGNATURE_2); + WriteNextResponseByte(AVR_SIGNATURE_3); + WriteNextResponseByte(AVR_SIGNATURE_2); + WriteNextResponseByte(AVR_SIGNATURE_1); } else if (Command == 'b') { @@ -515,7 +513,7 @@ TASK(CDC_Task) } else if (Command == 'R') { - #if defined(RAMPZ) + #if (FLASHEND > 0xFFFF) uint16_t ProgramWord = pgm_read_word_far(CurrAddress); #else uint16_t ProgramWord = pgm_read_word(CurrAddress); @@ -568,6 +566,9 @@ TASK(CDC_Task) while (!(Endpoint_IsINReady())); Endpoint_ClearIN(); } + + /* Wait until the data has been sent to the host */ + while (!(Endpoint_IsINReady())); /* Select the OUT endpoint */ Endpoint_SelectEndpoint(CDC_RX_EPNUM);