X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/38039765346c7441208dbcb3fd3cf8f13b7ced58..c20a94a4e84c89debf5e7109482ede708a694a0c:/Bootloaders/CDC/BootloaderCDC.c diff --git a/Bootloaders/CDC/BootloaderCDC.c b/Bootloaders/CDC/BootloaderCDC.c index 0add977ce..708ba359d 100644 --- a/Bootloaders/CDC/BootloaderCDC.c +++ b/Bootloaders/CDC/BootloaderCDC.c @@ -43,16 +43,16 @@ * 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 * command.) */ -uint16_t CurrAddress; +uint32_t CurrAddress; /** 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 @@ -90,7 +90,7 @@ int main(void) Endpoint_SelectEndpoint(CDC_TX_EPNUM); /* Wait until any pending transmissions have completed before shutting down */ - while (!(Endpoint_ReadWriteAllowed())); + while (!(Endpoint_IsINReady())); /* Shut down the USB subsystem */ USB_ShutDown(); @@ -152,53 +152,51 @@ EVENT_HANDLER(USB_UnhandledControlPacket) { 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_ClearSetupReceived(); + Endpoint_ClearSETUP(); for (uint8_t i = 0; i < sizeof(LineCoding); i++) Endpoint_Write_Byte(*(LineCodingData++)); - Endpoint_ClearSetupIN(); + Endpoint_ClearIN(); /* Acknowledge status stage */ - while (!(Endpoint_IsSetupOUTReceived())); - Endpoint_ClearSetupOUT(); + while (!(Endpoint_IsOUTReceived())); + 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_ClearSetupReceived(); + Endpoint_ClearSETUP(); - while (!(Endpoint_IsSetupOUTReceived())); + while (!(Endpoint_IsOUTReceived())); for (uint8_t i = 0; i < sizeof(LineCoding); i++) *(LineCodingData++) = Endpoint_Read_Byte(); - Endpoint_ClearSetupOUT(); + Endpoint_ClearOUT(); /* Acknowledge status stage */ - while (!(Endpoint_IsSetupINReady())); - Endpoint_ClearSetupIN(); + while (!(Endpoint_IsINReady())); + 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_ClearSetupReceived(); + Endpoint_ClearSETUP(); /* Acknowledge status stage */ - while (!(Endpoint_IsSetupINReady())); - Endpoint_ClearSetupIN(); + while (!(Endpoint_IsINReady())); + Endpoint_ClearIN(); } break; @@ -223,101 +221,101 @@ static void ReadWriteMemoryBlock(const uint8_t Command) MemoryType = FetchNextCommandByte(); - if ((MemoryType == 'E') || (MemoryType == 'F')) + if ((MemoryType != 'E') && (MemoryType != 'F')) { - /* Check if command is to read memory */ - if (Command == 'g') - { - /* Re-enable RWW section */ - boot_rww_enable(); + /* Send error byte back to the host */ + WriteNextResponseByte('?'); + + return; + } + + /* Check if command is to read memory */ + if (Command == 'g') + { + /* Re-enable RWW section */ + boot_rww_enable(); - while (BlockSize--) + while (BlockSize--) + { + if (MemoryType == 'E') { - if (MemoryType == 'E') - { - /* Read the next EEPROM byte into the endpoint */ - WriteNextResponseByte(eeprom_read_byte((uint8_t*)CurrAddress)); + /* Read the next EEPROM byte into the endpoint */ + WriteNextResponseByte(eeprom_read_byte((uint8_t*)(uint16_t)(CurrAddress >> 1))); - /* Increment the address counter after use */ - CurrAddress++; - } - else - { - /* Read the next FLASH byte from the current FLASH page */ - #if defined(RAMPZ) - WriteNextResponseByte(pgm_read_byte_far(((uint32_t)CurrAddress << 1) + HighByte)); - #else - WriteNextResponseByte(pgm_read_byte((CurrAddress << 1) + HighByte)); - #endif - - /* If both bytes in current word have been read, increment the address counter */ - if (HighByte) - CurrAddress++; - - HighByte ^= 1; - } + /* Increment the address counter after use */ + CurrAddress += 2; + } + else + { + /* Read the next FLASH byte from the current FLASH page */ + #if defined(RAMPZ) + WriteNextResponseByte(pgm_read_byte_far(CurrAddress | HighByte)); + #else + WriteNextResponseByte(pgm_read_byte(CurrAddress | HighByte)); + #endif + + /* If both bytes in current word have been read, increment the address counter */ + if (HighByte) + CurrAddress += 2; + + HighByte = !HighByte; } } - else + } + else + { + uint32_t PageStartAddress = CurrAddress; + + if (MemoryType == 'F') + { + boot_page_erase(PageStartAddress); + boot_spm_busy_wait(); + } + + while (BlockSize--) { - uint32_t PageStartAddress = ((uint32_t)CurrAddress << 1); - if (MemoryType == 'F') - { - boot_page_erase(PageStartAddress); - boot_spm_busy_wait(); - } - - while (BlockSize--) - { - if (MemoryType == 'E') + { + /* If both bytes in current word have been written, increment the address counter */ + if (HighByte) { - /* Write the next EEPROM byte from the endpoint */ - eeprom_write_byte((uint8_t*)CurrAddress, FetchNextCommandByte()); + /* Write the next FLASH word to the current FLASH page */ + boot_page_fill(CurrAddress, ((FetchNextCommandByte() << 8) | LowByte)); /* Increment the address counter after use */ - CurrAddress++; + CurrAddress += 2; + + HighByte = false; } else - { - /* If both bytes in current word have been written, increment the address counter */ - if (HighByte) - { - /* Write the next FLASH word to the current FLASH page */ - boot_page_fill(((uint32_t)CurrAddress << 1), ((FetchNextCommandByte() << 8) | LowByte)); - - HighByte = false; - - /* Increment the address counter after use */ - CurrAddress++; - } - else - { - LowByte = FetchNextCommandByte(); - - HighByte = true; - } + { + LowByte = FetchNextCommandByte(); + + HighByte = true; } } - - /* If in FLASH programming mode, commit the page after writing */ - if (MemoryType == 'F') + else { - /* Commit the flash page to memory */ - boot_page_write(PageStartAddress); - - /* Wait until write operation has completed */ - boot_spm_busy_wait(); + /* Write the next EEPROM byte from the endpoint */ + eeprom_write_byte((uint8_t*)(uint16_t)(CurrAddress >> 1), FetchNextCommandByte()); + + /* Increment the address counter after use */ + CurrAddress += 2; } - - /* Send response byte back to the host */ - WriteNextResponseByte('\r'); } - } - else - { - /* Send error byte back to the host */ - WriteNextResponseByte('?'); + + /* If in FLASH programming mode, commit the page after writing */ + if (MemoryType == 'F') + { + /* Commit the flash page to memory */ + boot_page_write(PageStartAddress); + + /* Wait until write operation has completed */ + boot_spm_busy_wait(); + } + + /* Send response byte back to the host */ + WriteNextResponseByte('\r'); } } @@ -332,10 +330,10 @@ static uint8_t FetchNextCommandByte(void) Endpoint_SelectEndpoint(CDC_RX_EPNUM); /* If OUT endpoint empty, clear it and wait for the next packet from the host */ - if (!(Endpoint_ReadWriteAllowed())) + while (!(Endpoint_IsReadWriteAllowed())) { - Endpoint_ClearCurrentBank(); - while (!(Endpoint_ReadWriteAllowed())); + Endpoint_ClearOUT(); + while (!(Endpoint_IsOUTReceived())); } /* Fetch the next byte from the OUT endpoint */ @@ -353,10 +351,10 @@ static void WriteNextResponseByte(const uint8_t Response) Endpoint_SelectEndpoint(CDC_TX_EPNUM); /* If OUT endpoint empty, clear it and wait for the next packet from the host */ - if (!(Endpoint_ReadWriteAllowed())) + if (!(Endpoint_IsReadWriteAllowed())) { - Endpoint_ClearCurrentBank(); - while (!(Endpoint_ReadWriteAllowed())); + Endpoint_ClearIN(); + while (!(Endpoint_IsINReady())); } /* Write the next byte to the OUT endpoint */ @@ -372,7 +370,7 @@ TASK(CDC_Task) Endpoint_SelectEndpoint(CDC_RX_EPNUM); /* Check if endpoint has a command in it sent from the host */ - if (Endpoint_ReadWriteAllowed()) + if (Endpoint_IsOUTReceived()) { /* Read in the bootloader command (first byte sent from host) */ uint8_t Command = FetchNextCommandByte(); @@ -402,8 +400,8 @@ TASK(CDC_Task) else if (Command == 'A') { /* Set the current address to that given by the host */ - CurrAddress = (FetchNextCommandByte() << 8); - CurrAddress |= FetchNextCommandByte(); + CurrAddress = (FetchNextCommandByte() << 9); + CurrAddress |= (FetchNextCommandByte() << 1); /* Send confirmation byte back to the host */ WriteNextResponseByte('\r'); @@ -426,9 +424,9 @@ TASK(CDC_Task) } else if (Command == 's') { - WriteNextResponseByte(boot_signature_byte_get(4)); - WriteNextResponseByte(boot_signature_byte_get(2)); - WriteNextResponseByte(boot_signature_byte_get(0)); + WriteNextResponseByte(SIGNATURE_0); + WriteNextResponseByte(SIGNATURE_1); + WriteNextResponseByte(SIGNATURE_2); } else if (Command == 'b') { @@ -478,24 +476,29 @@ TASK(CDC_Task) { WriteNextResponseByte(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS)); } - else if ((Command == 'C') || (Command == 'c')) - { - if (Command == 'c') - { - /* Increment the address if the second byte is being written */ - CurrAddress++; - } - + else if (Command == 'C') + { /* Write the high byte to the current flash page */ - boot_page_fill(((uint32_t)CurrAddress << 1), FetchNextCommandByte()); + boot_page_fill(CurrAddress, FetchNextCommandByte()); + + /* Send confirmation byte back to the host */ + WriteNextResponseByte('\r'); + } + else if (Command == 'c') + { + /* Write the low byte to the current flash page */ + boot_page_fill(CurrAddress | 1, FetchNextCommandByte()); + /* Increment the address */ + CurrAddress += 2; + /* Send confirmation byte back to the host */ WriteNextResponseByte('\r'); } else if (Command == 'm') { /* Commit the flash page to memory */ - boot_page_write((uint32_t)CurrAddress << 1); + boot_page_write(CurrAddress); /* Wait until write operation has completed */ boot_spm_busy_wait(); @@ -505,15 +508,15 @@ TASK(CDC_Task) } else if ((Command == 'B') || (Command == 'g')) { - /* Delegate the block write/read to a seperate function for clarity */ + /* Delegate the block write/read to a separate function for clarity */ ReadWriteMemoryBlock(Command); } else if (Command == 'R') { #if defined(RAMPZ) - uint16_t ProgramWord = pgm_read_word_far(((uint32_t)CurrAddress << 1)); + uint16_t ProgramWord = pgm_read_word_far(CurrAddress); #else - uint16_t ProgramWord = pgm_read_word(CurrAddress << 1); + uint16_t ProgramWord = pgm_read_word(CurrAddress); #endif WriteNextResponseByte(ProgramWord >> 8); @@ -522,10 +525,10 @@ TASK(CDC_Task) else if (Command == 'D') { /* Read the byte from the endpoint and write it to the EEPROM */ - eeprom_write_byte((uint8_t*)CurrAddress, FetchNextCommandByte()); + eeprom_write_byte((uint8_t*)(uint16_t)(CurrAddress >> 1), FetchNextCommandByte()); /* Increment the address after use */ - CurrAddress++; + CurrAddress += 2; /* Send confirmation byte back to the host */ WriteNextResponseByte('\r'); @@ -533,10 +536,10 @@ TASK(CDC_Task) else if (Command == 'd') { /* Read the EEPROM byte and write it to the endpoint */ - WriteNextResponseByte(eeprom_read_byte((uint8_t*)CurrAddress)); + WriteNextResponseByte(eeprom_read_byte((uint8_t*)(uint16_t)(CurrAddress >> 1))); /* Increment the address after use */ - CurrAddress++; + CurrAddress += 2; } else if (Command == 27) { @@ -552,22 +555,22 @@ TASK(CDC_Task) Endpoint_SelectEndpoint(CDC_TX_EPNUM); /* Remember if the endpoint is completely full before clearing it */ - bool IsEndpointFull = !(Endpoint_ReadWriteAllowed()); + bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed()); /* Send the endpoint data to the host */ - Endpoint_ClearCurrentBank(); + Endpoint_ClearIN(); /* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */ if (IsEndpointFull) { - while (!(Endpoint_ReadWriteAllowed())); - Endpoint_ClearCurrentBank(); + while (!(Endpoint_IsINReady())); + Endpoint_ClearIN(); } /* Select the OUT endpoint */ Endpoint_SelectEndpoint(CDC_RX_EPNUM); /* Acknowledge the command from the host */ - Endpoint_ClearCurrentBank(); + Endpoint_ClearOUT(); } }