|
|
  |
AT91SAM7S32 и JTAG, SAM-BA в камне отвечает, а вот JTAG молчит |
|
|
|
Dec 11 2009, 10:02
|

Местный
  
Группа: Свой
Сообщений: 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 пока применять не пробовал, но с горя сегодня попробую :-/
|
|
|
|
|
Dec 16 2009, 23:10
|

Местный
  
Группа: Свой
Сообщений: 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
|
|
|
|
|
Dec 16 2009, 23:36
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(RabidRabbit @ Dec 17 2009, 02:10)  Сначала думал, что нужно из ОЗУ выполняться, чтобы флэш писать, а нифига, не помогло. Посмотрите, пожалуйста, буду рад любым соображениям. Правильно думали - никаких обращений к флеш во время записи быть не должно. Только есть у меня такое предположение, что программа скомпилирована по нулевому адресу и после этой команды: Код ldr PC, =(0x200000 + continueEntry - 0x100000) спокойно продолжает выполняться из флеш.
|
|
|
|
|
Dec 17 2009, 07:17
|

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

|
Не, с адресами всё в порядке, в PC грузится адрес ОЗУ. Спасибо за подтверждение того, что нельзя читать из флэш в процессе записи - продолжил копать в этом направлении и выкопал  Во-первых, при вызове sendAck символы для отсылки читались из флэш, это я устранил загрузкой относительных адресов (стали приходить три ">" и один "E") из чего я сделал вывод, что задержки в ~1.5 миллисекунды мало, поэтому изменил счётчик попыток чтения бита FRDY с 6144 на 0x100000 - и оно заработало  Теперь буду разбираться с запуском того, что загружается
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|