From: Казьмин А. <and...@ya...> - 2014-08-07 07:43:10
|
Hello, I have olimex arm-usb-ocd-h debugger and olimex jtag-swd adapter for programming my at91samd20 chip. My openocd config is looked like: source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] transport select swd source [find interface/ftdi/olimex-arm-jtag-swd.cfg] set CHIPNAME at91samd20e17 source [find target/at91samdXX.cfg] When i try to program my chip, openocd tells me, that programming is failed: Debug: 774 224 target.c:2088 target_read_u16(): address: 0x41004018, value: 0x0000 Debug: 775 224 target.c:2173 target_write_u16(): address: 0x41004018, value: 0x00000000 Debug: 776 224 ftdi.c:950 ftdi_swd_run_queue(): Executing 2 queued transactions Debug: 777 224 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg 4 = 41004018 Debug: 778 224 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000000 Debug: 779 224 ftdi.c:950 ftdi_swd_run_queue(): Executing 18 queued transactions Debug: 780 226 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg 4 = 00000040 Debug: 781 226 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg 0 = a2000012 Debug: 782 226 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 783 226 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 784 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 785 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 786 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 787 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 788 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 789 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 790 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 791 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 792 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 793 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 794 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 795 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 000018b9 Debug: 796 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 797 227 ftdi.c:982 ftdi_swd_run_queue(): OK AP write reg C = 00000f7d Debug: 798 227 ftdi.c:950 ftdi_swd_run_queue(): Executing 4 queued transactions Debug: 799 227 ftdi.c:982 ftdi_swd_run_queue(): WAIT AP write reg 4 = 41004018 Debug: 800 227 ftdi.c:950 ftdi_swd_run_queue(): Executing 3 queued transactions Debug: 801 228 ftdi.c:982 ftdi_swd_run_queue(): OK DP write reg 0 = 0000001e Debug: 802 228 ftdi.c:982 ftdi_swd_run_queue(): OK AP read reg 4 = 00000000 Debug: 803 228 ftdi.c:982 ftdi_swd_run_queue(): OK DP read reg C = 00000080 Error: 804 228 arm_adi_v5.c:512 mem_ap_read(): Failed to read memory at 0x00000080 Debug: 805 228 target.c:2092 target_read_u16(): address: 0x41004018 failed Error: 806 228 at91samd.c:340 samd_check_error(): Can't read NVM status Error: 807 228 core.c:93 flash_driver_write(): error writing to flash at address 0x00000000 at offset 0x00000000 Debug: 808 228 command.c:628 run_command(): Command failed with error code -4 Debug: 809 228 command.c:145 script_debug(): command - ocd_command ocd_command type ocd_echo ** Programming Failed ** Debug: 810 228 command.c:145 script_debug(): command - echo ocd_echo ** Programming Failed ** At the datasheet on samd20 family i found this instructions for a flash page writes: Procedure for Automatic Page Writes (MANW=0) The row to be written must be erased before the last write to the page buffer is performed. Note that partially written pages must be written with a manual write. 1. Write to the page buffer by addressing the NVM main address space directly. 1a. When the last location in the page buffer is written, the page is automatically written to NVM main address space. 2. INTFLAG.READY will be zero while programming is in progress and access through the AHB will be stalled. I assume, that we should wait for a small delay while nvm write command is executing, before we could try to check status of last write. There is my openocd patch with workaround for this bug. It works. >From 6a69265e1d4810838974b43d7e2aa8424a2c2057 Mon Sep 17 00:00:00 2001 From: Andrej Kazmin <fun...@fu...> Date: Thu, 7 Aug 2014 10:49:12 +0400 Subject: [PATCH] Samd20 flash write bug fixed On samd20 we should wait for a short delay before check nvm status. It's because access through AHB is stalled while flash is programming. --- src/flash/nor/at91samd.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c index 8ee7c52..34b7ee4 100644 --- a/src/flash/nor/at91samd.c +++ b/src/flash/nor/at91samd.c @@ -18,6 +18,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ +#include <unistd.h> + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -448,6 +450,7 @@ static struct flash_sector *samd_find_sector_by_address(struct flash_bank *bank, return NULL; } + /* Write an entire row (four pages) from host buffer 'buf' to row-aligned * 'address' in the Flash. */ static int samd_write_row(struct flash_bank *bank, uint32_t address, @@ -487,6 +490,7 @@ static int samd_write_row(struct flash_bank *bank, uint32_t address, return res; } + usleep (200); error = samd_check_error(bank); if (error) return ERROR_FAIL; -- 1.7.2.5 |