/** 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[in] Command Single character AVR910 protocol command indicating what memory operation to perform */ static void ReadWriteMemoryBlock(const uint8_t Command) { uint16_t BlockSize; char MemoryType; bool HighByte = false; uint8_t LowByte = 0; BlockSize = (FetchNextCommandByte() << 8); BlockSize |= FetchNextCommandByte(); MemoryType = FetchNextCommandByte(); if ((MemoryType != 'E') && (MemoryType != 'F')) { /* Send error byte back to the host */ WriteNextResponseByte('?'); return; } /* Disable timer 1 interrupt - can't afford to process nonessential interrupts * while doing SPM tasks */ TIMSK1 = 0; /* Check if command is to read memory */ if (Command == 'g') { /* Re-enable RWW section */ boot_rww_enable(); while (BlockSize--) { if (MemoryType == 'F') { /* Read the next FLASH byte from the current FLASH page */ #if (FLASHEND > 0xFFFF) 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 { /* Read the next EEPROM byte into the endpoint */ WriteNextResponseByte(eeprom_read_byte((uint8_t*)(intptr_t)(CurrAddress >> 1))); /* Increment the address counter after use */ CurrAddress += 2; } } }
/** Reads or writes a block of EEPROM or FLASH memory to or from the appropriate CDC data endpoint, depending * on the AVR109 protocol command issued. * * \param[in] Command Single character AVR109 protocol command indicating what memory operation to perform */ static void ReadWriteMemoryBlock(const uint8_t Command) { uint16_t BlockSize; char MemoryType; uint8_t HighByte = 0; uint8_t LowByte = 0; BlockSize = (FetchNextCommandByte() << 8); BlockSize |= FetchNextCommandByte(); MemoryType = FetchNextCommandByte(); if ((MemoryType != MEMORY_TYPE_FLASH) && (MemoryType != MEMORY_TYPE_EEPROM)) { /* Send error byte back to the host */ WriteNextResponseByte('?'); return; } /* Check if command is to read a memory block */ if (Command == AVR109_COMMAND_BlockRead) { /* Re-enable RWW section */ boot_rww_enable(); while (BlockSize--) { if (MemoryType == MEMORY_TYPE_FLASH) { /* Read the next FLASH byte from the current FLASH page */ #if (FLASHEND > 0xFFFF) 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 { /* Read the next EEPROM byte into the endpoint */ WriteNextResponseByte(eeprom_read_byte((uint8_t*)(intptr_t)(CurrAddress >> 1))); /* Increment the address counter after use */ CurrAddress += 2; } } }