|
|
  |
Загрзчик AVR230 для AT90CAN128 |
|
|
|
Apr 26 2016, 15:30
|
Частый гость
 
Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185

|
Приветствую! Давно пользуюсь этим загрузчиком на 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. Процесс загрузки идёт, но в память ничего не записывается. Значит заковырка именно в этом макросе. А именно обращение к какому-то регистру, ответственному за запись в память. Заранее благодарен!
Сообщение отредактировал IgorKossak - Apr 27 2016, 19:16
|
|
|
|
|
Apr 27 2016, 10:13
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Действительно, оказывается раньше, в редакции 1999 года например, в документации значится две команды: SPM (Z) <- R1:R0 ESPM (RAMZ:Z) <- R1:R0. ( Instruction Set 1999)
|
|
|
|
|
Apr 27 2016, 11:40
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
У меня был случай. IAR. Проблему обнаружил случайно. Программа была написана для станка. Серия блоков управления. При пропадании напряжения питания нужно сохранять параметры в EEPROM. Изначально я собирался использовать ATMEGA8535. Написал проект. Прошиваю МК. Сама программа работает. В EEPROM не пишет. Я проверил все что можно, в дизассемблер заглядывал. Вроде все нормально. Но в EEPROM упорно не хочет писать. На тот момент была в наличии ATMEGA32. Компилирую программу под этот МК, заливаю прошивку - все работает. В общем, на тот момент мне некогда было разбираться. Собрал блоки управления на ATMEGA32A. Проблема была в IAR. Я брал старые проекты с использованием EEPROM и написанные на ассемблере в AVR-Studio. На той же 8535 запись в EEPROM исправно работала.
Я это написал к тому, что походу старые МК чем-то отличаются от МК выпущенных с определенного периода. И нужно брать старые версии IAR, и сравнивать результат компиляции с более поздними версиями IAR.
В моем случае, судя по всему, проблема была в порядке ассемблерных команд записи в EEPROM. Свежий IAR давал не тот порядок команд. И из-за этого на старых МК запись в EEPROM не работает, а на новых МК этот порядок команд прокатывает.
Сообщение отредактировал demiurg1978 - Apr 27 2016, 11:45
|
|
|
|
|
Apr 27 2016, 13:38
|

Местный
  
Группа: Свой
Сообщений: 253
Регистрация: 28-12-07
Из: Украина г. Первомайск
Пользователь №: 33 716

|
Ничего там особого нет, адрес страницы он и в Африке адрес. Я немного поигрался с Атмела загрузчиком и написал уже парочку своих, так сказать, как хочу, так и верчу. Чтение блока 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
|
|
|
|
|
Feb 10 2017, 13:16
|
Группа: Новичок
Сообщений: 1
Регистрация: 10-02-17
Пользователь №: 95 385

|
Специально зарегиcтрировался чтобы сказать спасибо! Та же фигня под Atmega1284p. Пол интернетов перелопатил, в англоязычных пространствах ничего не нашел, а тут - бац! Большое спасибо!
asellus
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|