Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Загрзчик AVR230 для AT90CAN128
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Д_М
Приветствую!
Давно пользуюсь этим загрузчиком на Mega128. http://www.atmel.com/Images/doc2541.pdf Работает чётко всем советую. Нужда заставила связаться с AT90CAN128. Решил сделать загрузчик для этого чипа. Этот загрузчик очень старый. На момент его выхода ещё не существовало AT90CAN128. Загрузчик был написан для IAR v2.28. Когда я его перенёс на IAR v6.4 транслятор выдал ощибку на ассемблеровскую инструкцию espm. И действительно не у AT90CAN128 не у Mega128 такой команды нет. Получается, что espm - это макрос, который знает IAR v2.28, но не знает IAR v6.4. В инклудах траслятора я этот макрос не нашёл. Ниже кусок кода, где этот макрос используется.

CODE
spmSPM:
movw r31:r30, r17:r16

rcall spmWait

in r20, SREG
cli

#ifdef __RAMPZ__
in r21, RAM_PZ
out RAM_PZ, r18
#endif

#ifdef __MEMSPM__
sts SPMREG, r22
#else
out SPMREG, r22
#endif

#ifdef __RAMPZ__
espm
#else
spm
#endif

У меня __MEMSPM__ включено, так как памяти больше, чем 64к. Ума не могу приложить что может делать этот макрос, помимо (вместо команды SPM). Единственно, чем он может отличать от spm - это выбором страницы, но это сделано выше out RAM_PZ, r18. Пробовал перехитрить судьбу. Решил взять проект Mega128 и забить адреса всех регистров AT90CAN128. Процесс загрузки идёт, но в память ничего не записывается. Значит заковырка именно в этом макросе. А именно обращение к какому-то регистру, ответственному за запись в память.

Заранее благодарен!
Д_М
Включил ассемблерный листинг получилось:
114 00000022 #ifdef __RAMPZ__
115 00000022 95F8 espm
116 00000024 #else
118 00000024 #endif

Просмотрел весь перенчь команд AVR, но инструкции 95F8 я не нашёл. Уже собрался дизассемблировать. Открыл перечь команд AVR, которые были в комплекте с дизассемблером и пожалуйста:
Extended Store Program Memory ESPM 1001 0101 1111 1000
Вот и инструкция 95F8. Если запусить дизассемблер, он выдаст espm

И как это понимать?
Д_М
В загрузчике для Мега 128 попробовал заменить ESPM на SPM. Работает. Попробовал тоже самое на AT90CAN128 - безрезультатно. Процесс идёт, в память ничего не записывается. Проверял выглузкой из флэш памяти контроллеря.
zombi
Цитата(Д_М @ Apr 26 2016, 19:36) *
Просмотрел весь перенчь команд AVR, но инструкции 95F8 я не нашёл.

Здесь смотрели Atmel AVR 8-bit Instruction Set? page 135.
aiwa
Скорее всего это из разряда:
"The behavior was not correct in earlier versions of the compiler platform. The new release uses a new internal compiler platform which is a bit more strict."

Точно не уверен, но предположу что неправильное поведение более ранних версий иара заключалось в реализации "espm" в виде блока
1. установка RAMZ
2. инструкция записи SPM
3. восстановление RAMZ

demiurg1978
Обратитесь к Ксении на этом форуме. http://electronix.ru/forum/index.php?showuser=35237
Она и советом поможет и старыми версиями IAR. Кстати, гугл на нее и указал. "espm avr"
aiwa
Действительно, оказывается раньше, в редакции 1999 года например, в документации значится две команды:
SPM (Z) <- R1:R0
ESPM (RAMZ:Z) <- R1:R0.
(Instruction Set 1999)
zombi
Цитата(Д_М @ Apr 27 2016, 00:14) *
В загрузчике для Мега 128 попробовал заменить ESPM на SPM. Работает. Попробовал тоже самое на AT90CAN128 - безрезультатно. Процесс идёт, в память ничего не записывается. Проверял выглузкой из флэш памяти контроллеря.

Значит проблема не в SPM/ESPM.
demiurg1978
У меня был случай. IAR. Проблему обнаружил случайно. Программа была написана для станка. Серия блоков управления. При пропадании напряжения питания нужно сохранять параметры в EEPROM. Изначально я собирался использовать ATMEGA8535. Написал проект. Прошиваю МК. Сама программа работает. В EEPROM не пишет. Я проверил все что можно, в дизассемблер заглядывал. Вроде все нормально. Но в EEPROM упорно не хочет писать. На тот момент была в наличии ATMEGA32. Компилирую программу под этот МК, заливаю прошивку - все работает.
В общем, на тот момент мне некогда было разбираться. Собрал блоки управления на ATMEGA32A. Проблема была в IAR. Я брал старые проекты с использованием EEPROM и написанные на ассемблере в AVR-Studio. На той же 8535 запись в EEPROM исправно работала.

Я это написал к тому, что походу старые МК чем-то отличаются от МК выпущенных с определенного периода. И нужно брать старые версии IAR, и сравнивать результат компиляции с более поздними версиями IAR.

В моем случае, судя по всему, проблема была в порядке ассемблерных команд записи в EEPROM. Свежий IAR давал не тот порядок команд. И из-за этого на старых МК запись в EEPROM не работает, а на новых МК этот порядок команд прокатывает.
pavel-pervomaysk
Ничего там особого нет, адрес страницы он и в Африке адрес.
Я немного поигрался с Атмела загрузчиком и написал уже парочку своих, так сказать, как хочу, так и верчу.



Чтение блока

CODE
;----------------------; Load address, encrypt block, send to usart
read_blockx: ;
ldi tmp2,st_ok ;
rcall us_tx ; Send command to the USART1
;----------------------;
lds zl,p_ah ; Init RAMPZ:Z pointer
out RAMPZ,zl ; Flash address RAMPZ0
lds zh,p_am ; Flash address M
lds zl,p_al ; Flash address L
ldi yl,low (bc_data) ; Encrypted AES data
ldi yh,high(bc_data) ; RAM pointer
;----------------------; Read 256 bytes from Flash
ldi loop3,0 ; amount
read_b_c: ;
elpm tmp2,z+ ; load FLASH byte, address=+1
st y+,tmp2 ; store byte in ram
dec loop3 ;
brne read_b_c ;
;----------------------; Encrypt block
ldi tmp,1 ; load aes ecncrypt mode
sts aesm,tmp ; AES Encryption
rcall _aesB ; Encrypt stored Block
;----------------------; Send block to USART1
ldi yl,low (bdc_data) ; Encrypted AES data
ldi yh,high(bdc_data) ; RAM pointer
ldi loop3,0 ; 256 bytes!
read_b_ce: ;
ld tmp2,y+ ;
rcall us_tx ; Send data to the USART1
dec loop3 ;
brne read_b_ce ;
;----------------------;
rjmp init_flags ; clear flags jump to boot_main



Запись блока

CODE
;----------------------;
write_blockx: ;
clr tmp ; selecl mode Decrypt
sts aesm,tmp ; save mode
rcall _aesB ; decrypr received block 256bytes
; save result block 256 bytes in (bdc_data)
lds zl,p_ah ; Init RAMPZ:Z pointer
out RAMPZ,zl ; Flash address RAMPZ0
lds zh,p_am ; Flash address M
lds zl,p_al ; Flash address L
;----------------------;
;ldi yl,low (bc_data) ; pure received data without decrypting
;ldi yh,high(bc_data) ; RAM pointer

ldi yl,low (bdc_data) ; Decrypted AES data
ldi yh,high(bdc_data) ; RAM pointer
rcall write_page ; Write page to flash!
wr_b_end: ;
rcall us_tx ; Send command to the USART1
rjmp init_flags ; clear flags jump to boot_main


CODE
; code from datasheet AT90CAN32/64/128
; Y = RAM data pointer
; RAMPZ0:Z = flash address pointer
; Edited lpm to ELPM!
; added Status wrote page!

Write_page: ; Write flash page 256 bytes
ldi tmp,(1<<PGERS)|(1<<SPMEN)
call Do_spm ; Page Erase
ldi tmp, (1<<RWWSRE)|(1<<SPMEN)
call Do_spm ; re-enable the RWW section
; transfer data from RAM to Flash page buffer
ldi xl,low (p_size) ; init loop variable
ldi xh,high(p_size) ; not required for PAGESIZEB<=256


Wrloop: ;
ld r0,Y+ ;
ld r1,Y+ ;
ldi tmp,(1<<SPMEN) ;
call Do_spm ;
adiw ZH:ZL,2 ;
sbiw xh:xl,2 ; use subi for PAGESIZEB<=256
brne Wrloop ;

;--------------------------; execute Page Write
subi ZL,low (p_size) ; restore pointer
sbci ZH,high(p_size) ; not required for PAGESIZEB<=256
ldi tmp, (1<<PGWRT) | (1<<SPMEN)
call Do_spm
; re-enable the RWW section
ldi tmp, (1<<RWWSRE) | (1<<SPMEN)
call Do_spm
; read back and check, optional
ldi xl,low (p_size) ; init loop variable
ldi xh,high(p_size) ; not required for PAGESIZEB<=256
subi YL,low (p_size) ; restore pointer
sbci YH,high(p_size) ;
;--------------------------;


Rdloop: ;
elpm r0,Z+ ; Load wrote data from flash
ld r1,Y+ ; Load right data from Ram
cpse r0,r1 ; compare and skip if equal
rjmp Loader_Error ; If not equal - STATUS ERROR!


rdl_p:
sbiw xh:xl,2 ; use subi for PAGESIZEB<=256
brne Rdloop ;
; return to RWW section
; verify that RWW section is safe to read

Return:
in tmp1,SPMCSR
sbrs tmp1,RWWSB ; If RWWSB is set, the RWW section is not ready yet
ldi tmp2,st_ok ;
ret
; re-enable the RWW section
ldi tmp,(1<<RWWSRE)|(1<<SPMEN)
call Do_spm ;
rjmp Return ;


Do_spm:

Wait_spm: ; check for previous SPM complete
in tmp1,SPMCSR
sbrc tmp1,SPMEN
rjmp Wait_spm
; input: spmcsrval determines SPM action

in tmp2,SREG ; disable interrupts if enabled, store status
cli

Wait_ee: ; check that no EEPROM write access is present
sbic EECR,EEWE ;
rjmp Wait_ee ;
out SPMCSR,tmp ; SPM timed sequence
spm
out SREG,tmp2 ; restore SREG (to enable interrupts if originally enabled)
ret ; return


loader_error: ;
ldi tmp2,st_err ; load status error
ret ; leave write_page

Д_М
Приветствую, Коллеги!
Прошу прощения, что открыл тему, но сам пропал! Доделал проект и теперь могу вернуться к этой задаче.
Искал другие загрузчики. Пробовал AVR231. Тоже самая технология, но улучшенная. В результате - на ATmega128 работает криво, на AT90CAN128 точно также ничего не пишет во FLASH. Если у кого-то есть проверенные на AT90CAN128 загрузчики, не откажите в любезности. Или программы, которые пишут во FLASH, в качестве примере.
Заранее благодарен!
pavel-pervomaysk
Я дал код с рабочего проекта.
Д_М
Получилось!
Всем большое спасибо за участие! Особенно Вам, pavel-pervomaysk!Как и ожидалось, проблема была нелепой. У ATmega128 SPMCSR находится в адресах ячеек памяти, а у AT90CAN128 его опусити в адресное пространство ввода - вывода. В настройках проекта надо было лишь убрать определение __MEMSPM__ и всё заработало. Была замечена дурь AVRDUDE command-line. Неправильно записал lock биты. Можно было вытягивать программу из контроллера. Легко исправляется AVRDUDE GUI. Будьте внимательны!

Если кому-то нужна помощь, обращайтесь derischev[пёс]ya.ru
asellus
Специально зарегиcтрировался чтобы сказать спасибо! Та же фигня под Atmega1284p. Пол интернетов перелопатил, в англоязычных пространствах ничего не нашел, а тут - бац!
Большое спасибо!

asellus
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.