Почти локализовал проблему с записью. В отладочной версии смотрю запись в терминале.
Странная вещь. Проблема локализовалась в библиотечном макросе.
/*----------------------------------------------------------------------------*/
/* execute command CMD_PROGRAM_FLASH_ISP */
/*----------------------------------------------------------------------------*/
#define __new_boot_page_fill_extended(address, data) \
({ \
__asm__ __volatile__ \
( \
"movw r0, %4\n\t" \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
"clr r1\n\t" \
: \
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
"i" (_SFR_MEM_ADDR(RAMPZ)), \
"r" ((uint8_t)__BOOT_PAGE_FILL), \
"r" ((uint32_t)address), \
"r" ((uint16_t)data) \
: "r0", "r30", "r31" \
); \
})
void cmdProgramFlashIsp(void) {
unsigned char byte1,byte2;
unsigned long address, address_page1,address_page2,offset;
n_bytes = ((*(rx_pntr+1)*256)+*(rx_pntr+2)); // number of databytes to flash
rx_pntr += 10; // set pointer to flash data
address_page1 = address_flash - ( address_flash % SPM_PAGESIZE ); // addres of 1st page to program
address_page2 = ( address_flash + n_bytes ) -
( ( address_flash + n_bytes ) % SPM_PAGESIZE ); // addres of last page to program
n_pages = (( address_page2 - address_page1) / SPM_PAGESIZE ) + 1; // number of pages to flash
offset = address_flash - address_page1 ;
tiprintf ("\n\r address_page1 = %u",address_page1);
tiprintf ("\n\r address_page2 = %u",address_page2);
tiprintf ("\n\r n_pages = %u",n_pages);
tiprintf ("\n\r offset = %u",offset);
for( j = 0; j < n_pages; j++ ) { // do for all pages in message
for(i=0; i < SPM_PAGESIZE; i += 2) // load old content of flash page
{
address = address_page1 + i;
if( (address < address_flash ) ||
(address > ( address_flash + n_bytes) ) ) { // copy to buffer old data
#if defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__) || defined(__AVR_ATmega2560__)
byte1 = pgm_read_byte_far(address);
byte2 = pgm_read_byte_far(address + 1);
#else
byte1 = pgm_read_byte(address_page1 + i );
byte2 = pgm_read_byte(address_page1 + i + 1);
#endif
}
else { // copy to buffer new data
byte1 = *rx_pntr;
byte2 = *(rx_pntr+1);
rx_pntr += 2;
}
// boot_page_fill(i,(unsigned int)(byte1 |(byte2 << 8)));
__new_boot_page_fill_extended((uint32_t)i,(uint16_t)(byte1|(byte2<<8)));
//putch ('.');
}
boot_page_erase((unsigned long)address_page1); // clear page
while(boot_spm_busy());
boot_page_write((unsigned long)address_page1); // write page to flash
while(boot_spm_busy());
boot_rww_enable(); // enable Read-While-Write section
address_page1 += SPM_PAGESIZE ;
}
address_flash += n_bytes ;
for(i = 0; i < MAX_BUF_SIZE; i++) {
rx_buffer[i] = 0xFF; // clear data buffer
}
msg_size = 2; // set message length
*(tx_pntr++) = CMD_PROGRAM_FLASH_ISP;
*(tx_pntr++) = STATUS_CMD_OK;
} // end of programFlashIsp
Программа перезагружается на начало. Стоит добавить
putch ('.'); и все работает
__new_boot_page_fill_extended((uint32_t)i,(uint16_t)(byte1|(byte2<<8)));
putch ('.');
ПО всей вероятности где-то засада со стеком.
Иначе объяснить этот бред не могу.
Если закомментировать __new_boot_page_fill_extended,
то программа работает стабильно. Без перезапусков.
И без записи страницы конечно-же.