Исходный код:
CODE
#define PG_ERS 0b00000011 //SPMEN-1, PGERS-1
#define PG_WRT 0b00000101 //SPMEN-1, PGWRT-1
#asm(".EQU SPMCR = 0x57")
#asm(".EQU RWW_SRE = 0x11")
void WAIT_SPMEN(void)
{
#asm
PUSH R20
LBL1:
LDS R20,SPMCR //считываем SPMCR в R20
SBRC R20,0 //проверка сброса флага SPMEN
RJMP LBL1 //ждем пока очистится
POP R20
#endasm
}
void enableRWW(void)
{
WAIT_SPMEN();
#asm
PUSH R20
LDI R20,RWW_SRE //загрузить в R20 0x11
STS SPMCR,R20 //загрузить R20 в SPMCR
SPM
POP R20
#endasm
}
unsigned int read_program_memory (unsigned int adr ,unsigned char cmd)
{
#asm
PUSH R30
PUSH R31
PUSH R18
PUSH R26
PUSH R27
LDD R30,y+1 //ZL = LSB
LDD R31,y+2 //ZH = MSB
LD R18, y // загружаем комманду
SBRC R18, 0 //;read lockbits? (second argument = 0x09)
STS SPMCR, R18 //;STS SPMCR, R18 ;if so, place second argument in SPMEN register
LPM R26, Z+
LPM R27, Z
MOVW R30,R26
POP R27
POP R26
POP R18
POP R31
POP R30
#endasm
}
void write_page (unsigned int adr, unsigned char function)
{
WAIT_SPMEN();
#asm
PUSH R30
PUSH R31
PUSH R26
LDD R30,y+1 //ZL = LSB
LDD R31,y+2 //ZX = MSB
LDD R26,y+0 //загружаем функицю
STS SPMCR, R26
SPM
POP R26
POP R31
POP R30
#endasm
}
void fill_temp_buffer (unsigned int data, unsigned int adr)
{
WAIT_SPMEN();
#asm
PUSH R30
PUSH R31
PUSH R0
PUSH R1
PUSH R19
LDD R30,y+0 //ZL = LSB
LDD R31,y+1 //ZH = MSB
LDD R0,y+2 //
LDD R1,y+3 //
LDI R19, 0x01 //взводим SPMEN
STS SPMCR, R19 //SPMCR, R19
SPM //Store program memory
POP R19
POP R1
POP R0
POP R31
POP R30
#endasm
}
void main(void){
write_page(0, PG_ERS);
enableRWW();
fill_temp_buffer(0x1234, 0);
fill_temp_buffer(0x5678, 2);
write_page(0, PG_WRT);
while (1) {}
}
#define PG_WRT 0b00000101 //SPMEN-1, PGWRT-1
#asm(".EQU SPMCR = 0x57")
#asm(".EQU RWW_SRE = 0x11")
void WAIT_SPMEN(void)
{
#asm
PUSH R20
LBL1:
LDS R20,SPMCR //считываем SPMCR в R20
SBRC R20,0 //проверка сброса флага SPMEN
RJMP LBL1 //ждем пока очистится
POP R20
#endasm
}
void enableRWW(void)
{
WAIT_SPMEN();
#asm
PUSH R20
LDI R20,RWW_SRE //загрузить в R20 0x11
STS SPMCR,R20 //загрузить R20 в SPMCR
SPM
POP R20
#endasm
}
unsigned int read_program_memory (unsigned int adr ,unsigned char cmd)
{
#asm
PUSH R30
PUSH R31
PUSH R18
PUSH R26
PUSH R27
LDD R30,y+1 //ZL = LSB
LDD R31,y+2 //ZH = MSB
LD R18, y // загружаем комманду
SBRC R18, 0 //;read lockbits? (second argument = 0x09)
STS SPMCR, R18 //;STS SPMCR, R18 ;if so, place second argument in SPMEN register
LPM R26, Z+
LPM R27, Z
MOVW R30,R26
POP R27
POP R26
POP R18
POP R31
POP R30
#endasm
}
void write_page (unsigned int adr, unsigned char function)
{
WAIT_SPMEN();
#asm
PUSH R30
PUSH R31
PUSH R26
LDD R30,y+1 //ZL = LSB
LDD R31,y+2 //ZX = MSB
LDD R26,y+0 //загружаем функицю
STS SPMCR, R26
SPM
POP R26
POP R31
POP R30
#endasm
}
void fill_temp_buffer (unsigned int data, unsigned int adr)
{
WAIT_SPMEN();
#asm
PUSH R30
PUSH R31
PUSH R0
PUSH R1
PUSH R19
LDD R30,y+0 //ZL = LSB
LDD R31,y+1 //ZH = MSB
LDD R0,y+2 //
LDD R1,y+3 //
LDI R19, 0x01 //взводим SPMEN
STS SPMCR, R19 //SPMCR, R19
SPM //Store program memory
POP R19
POP R1
POP R0
POP R31
POP R30
#endasm
}
void main(void){
write_page(0, PG_ERS);
enableRWW();
fill_temp_buffer(0x1234, 0);
fill_temp_buffer(0x5678, 2);
write_page(0, PG_WRT);
while (1) {}
}
В результате во флеш так и остается FFFF FFFF
Фьюзы выставлены правильно, BLB тоже.
В чем может быть глюк ?
Первоисточник кода во вложении (известный всем MegaLoad).
Пушами и попами это я уже от безисходности обложил
