Цитата(SasaVitebsk @ Oct 14 2007, 21:45)

Почему то сама запись не происходит. Флэш после операции девственно чист.
...
PS: ATMEGA640
Доброго времени суток, коллеги!
Столкнулся с подобной проблемой, не пишется FLASH из бутлоадера. Бутлоадер немного переделанный под себя из AES-аппнота, подобных бутлоадеров понаделано прилично под меги 16/32/64, все работают. А вот под 640 - не шьет

Исходные данные: камень Atmega640-16AU, питание схемы 5В, кварц 14.7456МГц.
Фузы: E:0xF4 H:0xDA L:0xD7 L:0x3F (вообще последний должен быть 0x0C, но ставлю 0x3F для тестов, чтобы уж точно была разрешена запись spm и чтобы потом FLASH можно было прочитать для сравнения)
Вот кусочки исходников, откуда пишется во FLASH
CODE
else if (type == TYPE_PROGRAM)
{
// Program page buffer into flash page
unsigned int *q = (unsigned int *) pageBuffer;
unsigned char APPFLASH *r = address;
do
{
spmWriteWord(r, *q++);
r += 2;
}
while (--size);
spmErasePage(address);
spmProgramPage(address);
}
Вот исходник spm640.asm (сделал специальный под 640, обрезав "лишнее")
CODE
NAME spm(16)
PUBLIC spmWriteWord
PUBLIC spmErasePage
PUBLIC spmProgramPage
PUBLIC spmEEWriteByte
#define __ENABLE_BIT_DEFINITIONS__
#include INCLUDE_FILE
#if !defined( EEMWE )
#define EEMWE EEMPE
#endif
#if !defined( EEWE )
#define EEWE EEPE
#endif
//=============================================================================
// I/O registers used
RSEG CODE
//=============================================================================
// Writes one word to a temporary page buffer
spmWriteWord:
movw r1:r0, r19:r18
ldi r22, (1 << SPMEN)
rjmp spmSPM
//=============================================================================
// Erases one flash page
spmErasePage:
ldi r22, (1 << PGERS) | (1 << SPMEN)
rjmp spmSPM
//=============================================================================
// Programs the temporary buffer to flash memory
spmProgramPage:
ldi r22, (1 << PGWRT) | (1 << SPMEN)
//=============================================================================
// Executes self-programming command
spmSPM:
; movw r31:r30, r17:r16
; в целях тестирования по адресу 0 всегда пишем константу 0x1357
ldi r31, 0
ldi r30, 0
ldi r19, 0x13
ldi r18, 0x57
movw r1:r0, r19:r18
rcall spmWait
in r20, SREG
cli
sts SPMCSR, r22
spm
dw 0xFFFF
nop
out SREG, r20
ret
spmWait:
wdr
__spmWait:
lds r23, SPMCSR
andi r23, (1 << SPMEN)
brne __spmWait
ret
//=============================================================================
// Writes one byte to EEPROM memory
spmEEWriteByte:
rcall spmWait
rcall spmEEWriteByteComplete
out EEARL, r16
out EEARH, r17
out EEDR, r18
sbi EECR, EEMWE
sbi EECR, EEWE
spmEEWriteByteComplete:
sbic EECR, EEWE
rjmp spmEEWriteByteComplete
ret
END
Вот настройки линкера
CODE
-ca90
-w29
//=============================================================================
// Interrupt vectors
-Z(CODE)INTVEC=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-BOOT_SIZE+IVT_SIZE-1)
-H1895 -h(CODE)(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-BOOT_SIZE+IVT_SIZE-1)
//=============================================================================
// Code memory
-Z(CODE)NEAR_F,HUGE_F,SWITCH,INITTAB,DIFUNCT,CODE=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-1)
-Z(FARCODE)FAR_F,FARCODE=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-1)
//=============================================================================
// RAM
-Z(DATA)NEAR_I,NEAR_Z=RAM_BASE-(RAM_BASE+RAM_SIZE-1)
-Z(DATA)RSTACK+100=RAM_BASE-(RAM_BASE+RAM_SIZE-1)
-Z(DATA)CSTACK+(RAM_SIZE-300-APP_SRAM_USAGE)=RAM_BASE-(RAM_BASE+RAM_SIZE-1)
Вот вывод map-а
CODE
****************************************
* *
* MODULE MAP *
* *
****************************************
DEFINED ABSOLUTE ENTRIES
PROGRAM MODULE, NAME : ?ABS_ENTRY_MOD
Absolute parts
ENTRY ADDRESS REF BY
===== ======= ======
APP_SRAM_USAGE 0000042E
RAM_BASE 00000200
RAM_SIZE 00002000
IVT_SIZE 000000E4
FLASH_SIZE 00010000
BOOT_SIZE 00001000
*************************************************************************
..............
SEGMENTS IN THE MODULE
======================
INTVEC
Common segment, address: CODE 0000F000 - 0000F063 (0x64 bytes), align: 0
Segment part 0.
****************************************
* *
* SEGMENTS IN ADDRESS ORDER *
* *
****************************************
SEGMENT SPACE START ADDRESS END ADDRESS SIZE TYPE ALIGN
======= ===== ============= =========== ==== ==== =====
INTVEC CODE 0000F000 - 0000F063 64 com 1
NEAR_F CODE 0000F064 - 0000F097 34 rel 0
SWITCH CODE 0000F098 dse 0
HUGE_F CODE 0000F098 dse 0
INITTAB CODE 0000F098 - 0000F09D 6 rel 0
DIFUNCT CODE 0000F09E dse 0
CODE CODE 0000F09E - 0000F9C9 92C rel 1
ABSOLUTE DATA 0000001F rel 0
DATA 00000020
DATA 00000021
DATA 00000027 - 00000028 2
DATA 0000002A - 0000002B 2
DATA 0000002D - 0000002E 2
DATA 00000030 - 00000031 2
DATA 00000033 - 00000034 2
DATA 00000036 - 00000036 1
DATA 0000004C - 0000004E 3
DATA 00000055 - 00000055 1
DATA 00000060 - 00000060 1
DATA 0000006F - 0000006F 1
DATA 0000007C - 0000007C 1
DATA 00000080 - 00000082 3
DATA 00000084 - 00000085 2
DATA 000000C0 - 000000C1 2
DATA 000000C4 - 000000C6 3
DATA 00000101 - 00000102 2
DATA 00000104 - 00000105 2
DATA 00000107 - 00000108 2
DATA 0000010A - 0000010B 2
NEAR_I DATA 00000200 dse 0
NEAR_Z DATA 00000200 - 0000061F 420 rel 0
RSTACK DATA 00000620 - 0000071F 100 dse 0
CSTACK DATA 00000720 - 00001FF1 18D2 dse 0
****************************************
* *
* END OF CROSS REFERENCE *
* *
****************************************
2 506 bytes of CODE memory
7 666 bytes of DATA memory (+ 41 absolute )
Errors: none
Warnings: none
Пишу бутлоадер, обновляю через него прошивку, читаю FLASH - чистая с 0-го адреса (0xFFFF), с 0xF000 - бутлоадер.
Пишу бутлоадер и рабочую прошивку, обновляю через бутлоадер прошивку, читаю FLASH - прошивка по адресу 0 на константу 0x1357 не затирается, с 0xF000 - бутлоадер.
Прошу помощи, уже весь мозг сломал, в чем может быть причина, куда копать.