Свежие обсуждения
Микроконтроллеры

Self-programming for Atmega 48

Давно собирался попробовать этот режим, чтобы свободное пространство флеши использовать для хранения данных . Взял кусок из мануалки, модифицировал под конкретную Мегу-48. Результат - нулевой. Содержимое флеши не изменилось. BLB0 и BLB1 - mode 1. Размер страницы - 128 байт.
Написал Атмелам, но они пока молчат. Может, своими силами разберемся, если кто это пробовал.

Write_page:
; Page Erase
ldi spmcrval, (1PGERS) | (1SELFPRGEN)
rcall Do_spm

; re-enable the RWW section
; ldi spmcrval, (1RWWSRE) | (1SELFPRGEN)
; rcall Do_spm
; Это я проигнорировал, поскольку у Меги-48 нет бита RWWSRE

; transfer data from RAM to Flash page buffer
ldi looplo, low(PAGESIZEB) ;init loop variable
ldi loophi, high(PAGESIZEB) ;not required for PAGESIZEB=
256
Wrloop:
ld r0, Y+
ld r1, Y+
ldi spmcrval, (1SELFPRGEN)
rcall Do_spm
adiw ZH:ZL, 2
sbiw loophi:looplo, 2 ;use subi for PAGESIZEB=
256
brne Wrloop

; execute Page Write
subi ZL, low(PAGESIZEB) ;restore pointer
sbci ZH, high(PAGESIZEB) ;not required for PAGESIZEB=
256
ldi spmcrval, (1PGWRT) | (1SELFPRGEN)
rcall Do_spm
; re-enable the RWW section
; ldi spmcrval, (1RWWSRE) | (1SELFPRGEN)
; rcall Do_spm
; Это я проигнорировал, поскольку у Меги-48 нет бита RWWSRE
; return to RWW section
; verify that RWW section is safe to read

; Return:
; in temp1, SPMCSR
; sbrs temp1, RWWSB ; If RWWSB is set, the RWW
; section is not ready yet
; ret
; re-enable the RWW section
; ldi spmcrval, (1RWWSRE) | (1SELFPRGEN)
; rcall Do_spm
; rjmp Return

; Этот кусок я целиком проигнорировал, поскольку у Меги-48 нет
; ни RWWSRE, ни RWWSB . У меня просто :

ret

; =====================================
Do_spm:
; check for previous SPM complete
Wait_spm:
in temp1, SPMCSR
sbrc temp1, SELFPRGEN
rjmp Wait_spm
; input: spmcrval determines SPM action
; disable interrupts if enabled, store status
in temp2, SREG
cli
; check that no EEPROM write access is present
Wait_ee:
sbic EECR, EEPE
rjmp Wait_ee
; SPM timed sequence
out SPMCSR, spmcrval
spm
; restore SREG (to enable interrupts if originally enabled)
out SREG, temp2
ret

 

1. Честно говоря, не увидел, где Вы присваиваете начальные значения регистру Z (запись в буфер флэш-памяти).
2. Вдогонку - сильно подозреваю, что заполнение памяти надо начинать с границы страницы. Либо предварительно просто считать ее содержимое командой lpm, чтобы оно осталось в буфере флэша.

 

chav1961: 1. Честно говоря, не увидел, где Вы присваиваете начальные значения регистру Z (запись в буфер флэш-памяти).
2. Вдогонку - сильно подозреваю, что заполнение памяти надо начинать с границы страницы. Либо предварительно просто считать ее содержимое командой lpm, чтобы оно осталось в буфере флэша.

Код не мой. Это фирменный Atmel' овский. От себя я добавил в начале : ldi ZL,0 ldi ZH,0 . Я даже допускаю, что буфер заполнится черт те чем. Но содержимое памяти программ не заменяется _никаким_ содержимым буфера - ни правильным, ни неправильным. Команда ЗАПИСАТЬ БУФЕР ВО ПЛЕШЬ не дает совсем никакого эффекта. Работа со внешей флешью, по идее совсем похожая, в свое время прошла у меня без сучка, хотя там, казалось бы, там дополнительная работа - все команды и данные гоняются через SPI.
От Атмелей ответа дождусь, видимо, не скоро, хотя имеется положительный опыт общения с ними. Видимо, придется отжалеть пяток басков да и прикупить MCU побольше, типа 88 или 168 и задвинуть туда фирмовый код, без всяких модификаций, а ежели и там не пойдет, буду ругаться матом ( про себя ) .

 

Попробуйте еще выставить все лог.1 во всех битах блокировки.

 

chav1961: Попробуйте еще выставить все лог.1 во всех битах блокировки.
как я уже сообщал, BLB0,BLB1 - mode 1, разрешающая запись куда угодно. Fuse биты - тоже разрешено все, иначе я не смог бы достучаться до памяти программ даже через ISP .

 

Тему закрываем. Решено.