реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> AT91SAM7S32 и JTAG, SAM-BA в камне отвечает, а вот JTAG молчит
RabidRabbit
сообщение Dec 11 2009, 10:02
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Собрал отладочный модуль на базе AT91SAM7S32. По JTAG - не видится (Olimex ARM-JTAG + H-JTAG 0.92, H-JTAG таргет не детектит, для проверки с платой на AT91SAM7S256 связывается нормально). SAM-BA на SAM7S32 отвечает нормально только в терминалке. SAM-BA (виндовая прога) из AT91ISP v1.13 говорит, что не удалось получить доступ к программированию флэш-памяти. Может, кто-нибудь подскажет направление, куда копать? Некоторые данные - кварц 18,432 МГц, на VCORE конденсаторы только 0.1 мкФ, бит MC_FSR.SECURITY = 0, установлены 2 локбита на 0 и 1-й регионы флэша (MC_FSR.LOCKS0 = 1, MC_FSR.LOCKS1 = 1). ERASE пока применять не пробовал, но с горя сегодня попробую :-/
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 11 2009, 10:05
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(RabidRabbit @ Dec 11 2009, 13:02) *
ERASE пока применять не пробовал, но с горя сегодня попробую :-/

Дык с этого начинать надо при подобного рода проблемах.
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Dec 11 2009, 17:36
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



ERASE не помог, только SAM-BA слетела wink.gif Восстановил SAM-BA и скачал передыдущую версию AT91ISP v1.10, в ней прога SAM-BA v2.6 нормально подключилась к камню. JTAG по-прежнему не работает sad.gif
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Dec 12 2009, 20:17
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Видимо, придётся писать свой загрузчик и отлаживаться с помощью вывода через DBGU sad.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 12 2009, 22:44
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



А на JTAGSEL правильный уровень? В еррате есть бага, связанная с пином TDI, но на работоспособности сказываться она по идее не должна. Хотя кто его знает, на самом деле.
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Dec 13 2009, 06:27
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



JTAGSEL оставлен висящим в воздухе, на нём 0 при включенном питании. TDI подтянут к "земле" через 15К, пробовал его и к +3.3В подтягивать - монопенисуально sad.gif Попробую JTAGSEL железно на GND подсадить... Зато уже половину загрузчика накропал smile.gif Кстати, попутно вопрос - при выдаче контроллеру памяти команды REMAP переключение происходит моментально (ну, с учётом конвейера) или через какое-то определённое время?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 13 2009, 17:18
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(RabidRabbit @ Dec 13 2009, 09:27) *
Кстати, попутно вопрос - при выдаче контроллеру памяти команды REMAP переключение происходит моментально (ну, с учётом конвейера) или через какое-то определённое время?

Моментально.
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Dec 16 2009, 23:10
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Что-то я уже обалдеваю от загрузчика :-/ После выдачи команды на запись страницы флэш происходит зависание до передёргивания питания. Символ, который передаётся после "LAST ALIVE POINT" приходит, а после - молчание. Где-то я туплю, но вот никак не пойму - где. Сначала думал, что нужно из ОЗУ выполняться, чтобы флэш писать, а нифига, не помогло. Посмотрите, пожалуйста, буду рад любым соображениям.

CODE
;
; main.s
;

; external OSC 16 MHz
; master clock at 28.0 MHz

INCLUDE common.inc

BOOTLOADER_AREA_SIZE EQU 0x400
APP_MAX_SIZE EQU (0x8000 - BOOTLOADER_AREA_SIZE)
APPLICATION_BEGIN_ADDR EQU 0x100400
APP_SIZE_OFFSET EQU 0x0
APP_CHECKSUM_OFFSET EQU 0x4
APP_EXCEPTIONS_START EQU 0x8
FLASH_START_ADDR EQU 0x100000
RAM_START_ADDR EQU 0x200000
DBGU_TXRDY_WAIT EQU 0x60000
DBGU_RXRDY_WAIT EQU 0x500000

AREA RESET, CODE, READONLY
ARM
; exception vectors
exception_block_start
ldr pc, Reset_Addr
ldr pc, Undef_Addr
ldr pc, SWI_Addr
ldr pc, PAbt_Addr
ldr pc, DAbt_Addr
nop
ldr pc, [pc, #-0xF20] ; go to by IRQ vector
ldr pc, FIQ_Addr
exception_vectors
; address map for exeption vectors
Reset_Addr
DCD Reset_Handler
Undef_Addr
DCD Undef_Handler
SWI_Addr
DCD SWI_Handler
PAbt_Addr
DCD PAbt_Handler
DAbt_Addr
DCD DAbt_Handler
FIQ_Addr
DCD FIQ_Handler
exception_block_end

; loopbacks for unused exception vectors
Undef_Handler
SWI_Handler
PAbt_Handler
DAbt_Handler
FIQ_Handler
unusedExceptionLoopback
b unusedExceptionLoopback


AREA TEXT, CODE, READONLY
ARM
; reset handler
EXPORT Reset_Handler
ENTRY
Reset_Handler
; reset controller
ldr r0, =RSTC_BASE
ldr r1, =0xA5000401 ; KEY = 0xA5, BODIEN = 0, ERSTL = 4, URSTIEN = 0, URSTEN = 1
str r1, [r0, #RSTC_MR]
; flash controller: 0 wait states, MCK = 28 MHz
ldr r0, =EFC_BASE
ldr r1, =0x002A0000 ; FMCN = 0x2B, FWS = 0, NEBP = 0, PROGE = 0, LOCKE = 0, FRDY = 0
str r1, [r0, #EFC0_FMR]
; watchdog
ldr r0, =WDT_BASE
ldr r1, =0x00008000 ; disable watchdog
str r1, [r0, #WDT_MR]
; copy self to RAM
ldr r0, =0x100000
ldr r1, =0x200000
ldr r3, =256
selfCopyLoop
ldr r4, [r0], #4
str r4, [r1], #4
subs r3, r3, #1
bne selfCopyLoop
; execute remap
ldr r0, =EFC_BASE
ldr r1, =1
str r1, [r0, #MC_RCR]
ldr PC, =(0x200000 + continueEntry - 0x100000)
continueEntry
; enable main oscillator and PLL
ldr r0, =PMC_BASE
; after that we have master clock at 32768 Hz
ldr r1, =0x00000701 ; OSCOUNT = 7, OSCBYPASS = 0, MOSCEN = 1
str r1, [r0, #PMC_MOR]
; wait for stabilization
init_waitMainOsc
ldr r1, [r0, #PMC_SR]
tst r1, #PMC_B_MOSCS
beq init_waitMainOsc
; pll (16000000 / 1) * 7 = 112000000
ldr r1, =0x00063F01 ; USBDIV = 0, MUL = 0x06, OUT = 0, PLLCOUNT = 0x4F, DIV = 0x01
str r1, [r0, #PMC_PLLR]
; wait for lock
init_waitPll
ldr r1, [r0, #PMC_SR]
tst r1, #PMC_B_LOCK
beq init_waitPll
; setup prescaler
ldr r1, =0x00000008 ; MDIV = 0, PRES = 2, CSS = 0
str r1, [r0, #PMC_MCKR]
; wait for master clock
init_waitPrescaler
ldr r1, [r0, #PMC_SR]
tst r1, #PMC_B_MCKRDY
beq init_waitPrescaler
; setup master clock source
ldr r1, =0x0000000B ; MDIV = 0, PRES = 2, CSS = 3
str r1, [r0, #PMC_MCKR]
; wait for master clock
init_waitMasterClock
ldr r1, [r0, #PMC_SR]
tst r1, #PMC_B_MCKRDY
beq init_waitMasterClock
; after that we have master clock at 28 MHz
; setup stack for IRQ mode
msr CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
ldr sp, =0x202000
; setup stack for user mode
msr CPSR_c, #Mode_USR:OR:F_Bit
ldr sp, =0x201F00
; now cpu in user mode, FIQ disabled
; enable clock for PIOA controller
ldr r1, =( 1 << 2 )
str r1, [r0, #PMC_PCER]
; setup IO pins roles and states
ldr r0, =PIO_BASE
; set all lines as IO, except PA9 & PA10
ldr r1, =0xFFFFF9FF
str r1, [r0, #PIO_PER]
; set lines as inputs
str r1, [r0, #PIO_ODR]
; get buttons 3 and 4
ldr r2, [r0, #PIO_PDSR]
; set PA9 & PA10 under DBGU control
mvn r1, r1
str r1, [r0, #PIO_PDR]
str r1, [r0, #PIO_ASR]
; set up DBGU
ldr r0, =DBGU_BASE
ldr r1, =0x800 ; PAR = no parity
str r1, [r0, #DBGU_MR]
ldr r1, =91 ; 19200 baud
str r1, [r0, #DBGU_BRGR]
ldr r1, =0x50 ;TXEN | RXEN
str r1, [r0, #DBGU_CR]
; check PA19 and PA20, if it zero - go to init loader
tst r2, #0x180000
beq init_loader
; verify application checksum
; address of first byte of application
ldr r2, =APPLICATION_BEGIN_ADDR
; load application size
ldr r3, [r2], #4
ldr r4, =127 ; min size - 1
; if app size < threshold, go to init loader
cmp r3, r4
bls init_loader
ldr r4, =APP_MAX_SIZE
; if app size > limit, go to init loader
cmp r3, r4
bhi init_loader
; load application checksum
ldr r4, [r2], #4
; calculate checksum
ldr r5, =0
checksum_loop
ldr r6, [r2], #4
eor r6, r5, lsl #1
orr r6, r5, lsr #31
mov r5, r6
subs r3, #4
bhi checksum_loop
; compare checksums
cmp r4, r5
bne init_loader
starting_app
; starting application
; copy exception table to RAM
ldr r0, =(APPLICATION_BEGIN_ADDR + APP_EXCEPTIONS_START)
ldr r1, =(0x200000 + exception_vectors - 0x100000)
ldmia r0, {r2-r7}
stmia r1, {r2-r7}
; jump to reset vector
ldr PC, =0

init_loader
; waiting for command
loaderWaitCmd
ldr r2, =DBGU_BASE
bl dbguReadOneByte
tst r5, r5
beq loaderWaitCmd
mov LR, PC
sub LR, LR, #24
subs r1, r1, #1 ; if r1 == 1
beq loaderSendHello ; send hello string
subs r1, r1, #1 ; if r1 == 2
beq loaderReadFirmware ; receive firmware and store it to flash
b loaderWaitCmd

; send hello string to remote
loaderSendHello
ldr r0, =strHello
b dbguSendBytes

; receive firmware from remote and store it to flash
loaderReadFirmware
str LR, [SP, #-4]!
; start addr for write
ldr r12, =APPLICATION_BEGIN_ADDR
; first send ACK
bl sendAck
; receive size (4 bytes) of firmware, size = count of 128-bytes pages
ldr r0, =fwSize
ldr r3, =4
bl dbguReadBytes
tst r3, r3
bne loaderReadFirmware_crash
; load received value
ldr r10, [r0]
; check size
tst r10, r10
beq loaderReadFirmware_crash
ldr r3, =(APP_MAX_SIZE / 128)
cmp r10, r3
bhi loaderReadFirmware_crash
; send ACK
bl sendAck
; init destination address
ldr r9, =(BOOTLOADER_AREA_SIZE / 128)
; receive 128 bytes from remote
loaderReadFirmware_loop
ldr r3, =128
bl dbguReadBytes
tst r3, r3
bne loaderReadFirmware_crash
; write data to flash page buffer
ldr r0, =flashSectorBuf
ldr r1, =128
pageBufCopy
ldr r3, [r0], #4
str r3, [r12], #4
subs r1, r1, #4
bhi pageBufCopy
; send ACK 1
bl sendAck
; EFC base addr
ldr r0, =EFC_BASE
; wait for FRDY
ldr r3, =6144
writePageWait
ldr r4, [r0, #EFC0_FSR]
tst r4, #1
bne writePageWriteCmd
subs r3, r3, #1
bne writePageWait
b loaderReadFirmware_crash
writePageWriteCmd
; send ACK 2 [[[[[[[[[[ LAST ALIVE POINT ]]]]]]]]]]
bl sendAck
; write sector to flash
ldr r0, =EFC_BASE
ldr r1, =0x5A000001
orr r1, r9, lsl #8
str r1, [r0, #EFC0_FCR]
; send ACK 3 [[[[[[[[[[ THIS ACK NOT RECEIVED ]]]]]]]]]]
bl sendAck
; wait for FRDY
ldr r0, =EFC_BASE
ldr r3, =6144
writePageWait2
ldr r4, [r0, #EFC0_FSR]
tst r4, #1
bne writePageCheckErrors
subs r3, r3, #1
bne writePageWait2
b loaderReadFirmware_crash
writePageCheckErrors
; send ACK 4
bl sendAck
; check for errors
tst r4, #0xA ; PROGE | LOCKE
bne loaderReadFirmware_crash
; send ACK 5
bl sendAck
; inc page
add r9, r9, #1
; dec pages count
subs r10, r10, #1
bhi loaderReadFirmware_loop
; send success message
ldr r0, =strAllOk
bl dbguSendBytes
; wait another cmd
ldr PC, [SP], #4
loaderReadFirmware_crash
; send NACK
ldr r0, =strErr
bl dbguSendBytes
ldr r0, =0x100000
sendNackWaitLoop
subs r0, r0, #1
bne sendNackWaitLoop
; something wrong, reset chip
ldr r0, =RSTC_BASE
ldr r1, =0xA500000D ; EXTRST | PERRST | PROCRST
str r1, [r0, #RSTC_CR]
loaderReadFirmare_crash_loop
b loaderReadFirmare_crash_loop


sendAck
stmfd SP!, {r0,r1,LR}
ldr r0, =strAck
bl dbguSendBytes
ldmfd SP!, {r0,r1,PC}

; write one byte to DBGU transmitter holding register
; IN
; r1 - byte to send
; OUT
; r3 != 0 if no error
dbguSendOneByte
; load counter
ldr r3, =DBGU_TXRDY_WAIT
; first wait for TXRDY
dbguSendOneByte_wait
ldr r4, [r2, #DBGU_SR]
tst r4, #2 ; TXRDY
bne dbguSendOneByte_send
subs r3, r3, #1
bne dbguSendOneByte_wait
bx LR
dbguSendOneByte_send
str r1, [r2, #DBGU_THR]
mov PC, LR

; read one byte from DBGU receiver holding register
; OUT
; r1 - received byte
; r5 != 0 if no error
dbguReadOneByte
; load counter
ldr r5, =DBGU_RXRDY_WAIT
; wait for RXRDY
dbguReadOneByte_wait
ldr r4, [r2, #DBGU_SR]
tst r4, #1 ; RXRDY
bne dbguReadOneByte_read
subs r5, r5, #1
bne dbguReadOneByte_wait
bx LR
dbguReadOneByte_read
ldr r1, [r2, #DBGU_RHR]
mov PC, LR

; send some bytes by DBGU
; IN
; r0 - start address of ASCIIZ string
; OUT
; r1 == 0 if no error
dbguSendBytes
stmfd SP!, {r0,r2-r4,LR}
ldr r2, =DBGU_BASE
dbguSendBytes_loop
ldrb r1, [r0], #1
tst r1, r1
beq dbguSendBytes_exit
bl dbguSendOneByte
tst r3, r3
bne dbguSendBytes_loop
dbguSendBytes_exit
ldmfd SP!, {r0,r2-r4,PC}

; read some bytes by DBGU
; IN
; r0 - start address of target buffer
; r3 - count of bytes to read
; OUT
; r3 == 0 if no error
dbguReadBytes
stmfd SP!, {r0-r2,r4,r5,LR}
ldr r2, =DBGU_BASE
dbguReadBytes_loop
bl dbguReadOneByte
tst r5, r5
beq dbguReadBytes_exit
strb r1, [r0], #1
subs r3, r3, #1
bne dbguReadBytes_loop
dbguReadBytes_exit
ldmfd SP!, {r0-r2,r4,r5,PC}



strHello
DCB "sBoot v0.1", 13, 10, 0
strAck
DCB ">", 0
strErr
DCB "E", 0
strAllOk
DCB "Ok", 13, 10, 0



AREA STACK, NOINIT, READWRITE
SPACE 0x400
fwSize
SPACE 4
flashSectorBuf
SPACE 128

END
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 16 2009, 23:36
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(RabidRabbit @ Dec 17 2009, 02:10) *
Сначала думал, что нужно из ОЗУ выполняться, чтобы флэш писать, а нифига, не помогло. Посмотрите, пожалуйста, буду рад любым соображениям.

Правильно думали - никаких обращений к флеш во время записи быть не должно.
Только есть у меня такое предположение, что программа скомпилирована по нулевому адресу и после этой команды:
Код
    ldr        PC, =(0x200000 + continueEntry - 0x100000)

спокойно продолжает выполняться из флеш.
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Dec 17 2009, 07:17
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Не, с адресами всё в порядке, в PC грузится адрес ОЗУ. Спасибо за подтверждение того, что нельзя читать из флэш в процессе записи - продолжил копать в этом направлении и выкопал smile.gif Во-первых, при вызове sendAck символы для отсылки читались из флэш, это я устранил загрузкой относительных адресов (стали приходить три ">" и один "E") из чего я сделал вывод, что задержки в ~1.5 миллисекунды мало, поэтому изменил счётчик попыток чтения бита FRDY с 6144 на 0x100000 - и оно заработало smile.gif Теперь буду разбираться с запуском того, что загружается smile.gif
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Dec 19 2009, 17:33
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Всё, допилил, заработало smile.gif Загрузчик влез в 1 килобайт, наверное, при использовании наречия тумбо-юмбо, можно было и в 768 байт упихать smile.gif А если ещё и по размеру оптимизировать... wink.gif Короче говоря, я очень рад, что (наверное) больше самбу грузить не придётся wink.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 19 2009, 17:35
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



На случай, если придется.
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Dec 19 2009, 19:48
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Ага, видел этот пост. Одна из причин для меня отказаться от использования SAM-BA - глючный шнурок USB<->UART, который иногда подвешивает драйвер, и если терминалку или мой собственный загрузчик можно снести таскменеджером, то атмеловская SAM-BA v2.6 если зависнет, то лечится только ребутом sad.gif А так, предложенная Вами процедура - действительно удобный способ подготовить камень к обновлению прошивки, типа юзер в меню выбрал "активировать загрузчик" - и вуаля smile.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 16:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.0148 секунд с 7
ELECTRONIX ©2004-2016