This adds docs, example config, flash driver. Driver is only supports K1921VK01T model for now. Change-Id: I135259bb055dd2df1a17de99f066e2b24eae1b0f Signed-off-by: Bogdan Kolbov <kolbov@niiet.ru> Reviewed-on: http://openocd.zylin.com/3011 Tested-by: jenkins Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>tags/v0.10.0-rc1
@@ -128,7 +128,7 @@ Flash drivers | |||
ADUC702x, AT91SAM, AVR, CFI, DSP5680xx, EFM32, EM357, FM3, Kinetis, | |||
LPC8xx/LPC1xxx/LPC2xxx/LPC541xx, LPC2900, LPCSPIFI, Marvell QSPI, | |||
Milandr, NuMicro, PIC32mx, PSoC4, SiM3x, Stellaris, STM32, STMSMI, | |||
Milandr, NIIET, NuMicro, PIC32mx, PSoC4, SiM3x, Stellaris, STM32, STMSMI, | |||
STR7x, STR9x, nRF51; NAND controllers of AT91SAM9, LPC3180, LPC32xx, | |||
i.MX31, MXC, NUC910, Orion/Kirkwood, S3C24xx, S3C6400, XMC4xxx. | |||
@@ -0,0 +1,112 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2015 by Bogdan Kolbov * | |||
* kolbov@niiet.ru * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc. * | |||
***************************************************************************/ | |||
.text | |||
.syntax unified | |||
.cpu cortex-m4 | |||
.thumb | |||
.thumb_func | |||
/* K1921VK01T has 128-bitwidth flash, so it`s able to load 4x32-bit words at the time. | |||
* And only after all words loaded we can start write | |||
*/ | |||
/* Registers addresses */ | |||
#define FLASH_FMA 0x00 /* Address reg */ | |||
#define FLASH_FMD1 0x04 /* Data1 reg */ | |||
#define FLASH_FMC 0x08 /* Command reg */ | |||
#define FLASH_FCIS 0x0C /* Operation Status reg */ | |||
#define FLASH_FCIC 0x14 /* Operation Status Clear reg */ | |||
#define FLASH_FMD2 0x50 /* Data2 reg */ | |||
#define FLASH_FMD3 0x54 /* Data3 reg */ | |||
#define FLASH_FMD4 0x58 /* Data4 reg*/ | |||
/* Params: | |||
* r0 - write cmd (in), status (out) | |||
* r1 - count | |||
* r2 - workarea start | |||
* r3 - workarea end | |||
* r4 - target address | |||
* Clobbered: | |||
* r5 - rp | |||
* r6 - wp, tmp | |||
* r7 - flash base | |||
*/ | |||
ldr r7, =#0xA001C000 /* Flash reg base*/ | |||
wait_fifo: | |||
ldr r6, [r2, #0] /* read wp */ | |||
cmp r6, #0 /* abort if wp == 0 */ | |||
beq exit | |||
ldr r5, [r2, #4] /* read rp */ | |||
cmp r5, r6 /* wait until rp != wp */ | |||
beq wait_fifo | |||
load_data: | |||
ldr r6, [r5] /* read data1 */ | |||
str r6, [r7, #FLASH_FMD1] | |||
adds r5, #4 | |||
ldr r6, [r5] /* read data2 */ | |||
str r6, [r7, #FLASH_FMD2] | |||
adds r5, #4 | |||
ldr r6, [r5] /* read data3 */ | |||
str r6, [r7, #FLASH_FMD3] | |||
adds r5, #4 | |||
ldr r6, [r5] /* read data4 */ | |||
str r6, [r7, #FLASH_FMD4] | |||
adds r5, #4 | |||
start_write: | |||
str r4, [r7, #FLASH_FMA] /* set addr */ | |||
adds r4, #16 | |||
str r0, [r7, #FLASH_FMC] /* write cmd */ | |||
busy: | |||
ldr r6, [r7, #FLASH_FCIS] /* wait until flag set */ | |||
cmp r6, #0x0 | |||
beq busy | |||
cmp r6, #2 /* check the error bit */ | |||
beq error | |||
movs r6, #1 /* clear flags */ | |||
str r6, [r7, #FLASH_FCIC] | |||
cmp r5, r3 /* wrap rp at end of buffer */ | |||
bcc no_wrap | |||
mov r5, r2 | |||
adds r5, #8 | |||
no_wrap: | |||
str r5, [r2, #4] /* store rp */ | |||
subs r1, r1, #1 /* decrement 16-byte block count */ | |||
cmp r1, #0 | |||
beq exit /* loop if not done */ | |||
b wait_fifo | |||
error: | |||
movs r0, #0 | |||
str r0, [r2, #4] /* set rp = 0 on error */ | |||
exit: | |||
mov r0, r6 /* return status in r0 */ | |||
bkpt #0 |
@@ -5380,6 +5380,66 @@ if @{ [info exists IMEMORY] && [string equal $IMEMORY true] @} @{ | |||
@end example | |||
@end deffn | |||
@deffn {Flash Driver} niietcm4 | |||
This drivers handles the integrated NOR flash on NIIET Cortex-M4 | |||
based controllers. Flash size and sector layout are auto-configured by the driver. | |||
Main flash memory is called "Bootflash" and has main region and info region. | |||
Info region is NOT memory mapped by default, | |||
but it can replace first part of main region if needed. | |||
Full erase, single and block writes are supported for both main and info regions. | |||
There is additional not memory mapped flash called "Userflash", which | |||
also have division into regions: main and info. | |||
Purpose of userflash - to store system and user settings. | |||
Driver has special commands to perform operations with this memmory. | |||
@example | |||
flash bank $_FLASHNAME niietcm4 0 0 0 0 $_TARGETNAME | |||
@end example | |||
Some niietcm4-specific commands are defined: | |||
@deffn Command {niietcm4 uflash_read_byte} bank ('main'|'info') address | |||
Read byte from main or info userflash region. | |||
@end deffn | |||
@deffn Command {niietcm4 uflash_write_byte} bank ('main'|'info') address value | |||
Write byte to main or info userflash region. | |||
@end deffn | |||
@deffn Command {niietcm4 uflash_full_erase} bank | |||
Erase all userflash including info region. | |||
@end deffn | |||
@deffn Command {niietcm4 uflash_erase} bank ('main'|'info') first_sector last_sector | |||
Erase sectors of main or info userflash region, starting at sector first up to and including last. | |||
@end deffn | |||
@deffn Command {niietcm4 uflash_protect_check} bank ('main'|'info') | |||
Check sectors protect. | |||
@end deffn | |||
@deffn Command {niietcm4 uflash_protect} bank ('main'|'info') first_sector last_sector ('on'|'off') | |||
Protect sectors of main or info userflash region, starting at sector first up to and including last. | |||
@end deffn | |||
@deffn Command {niietcm4 bflash_info_remap} bank ('on'|'off') | |||
Enable remapping bootflash info region to 0x00000000 (or 0x40000000 if external memory boot used). | |||
@end deffn | |||
@deffn Command {niietcm4 extmem_cfg} bank ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh') pin_num ('func1'|'func3') | |||
Configure external memory interface for boot. | |||
@end deffn | |||
@deffn Command {niietcm4 service_mode_erase} bank | |||
Perform emergency erase of all flash (bootflash and userflash). | |||
@end deffn | |||
@deffn Command {niietcm4 driver_info} bank | |||
Show information about flash driver. | |||
@end deffn | |||
@end deffn | |||
@deffn {Flash Driver} nrf51 | |||
All members of the nRF51 microcontroller families from Nordic Semiconductor | |||
include internal flash and use ARM Cortex-M0 core. | |||
@@ -50,7 +50,9 @@ NOR_DRIVERS = \ | |||
mrvlqspi.c \ | |||
psoc4.c \ | |||
sim3x.c \ | |||
xmc4xxx.c | |||
xmc4xxx.c \ | |||
niietcm4.c | |||
noinst_HEADERS = \ | |||
core.h \ | |||
@@ -63,6 +63,7 @@ extern struct flash_driver psoc4_flash; | |||
extern struct flash_driver sim3x_flash; | |||
extern struct flash_driver jtagspi_flash; | |||
extern struct flash_driver xmc4xxx_flash; | |||
extern struct flash_driver niietcm4_flash; | |||
/** | |||
* The list of built-in flash drivers. | |||
@@ -110,6 +111,7 @@ static struct flash_driver *flash_drivers[] = { | |||
&sim3x_flash, | |||
&jtagspi_flash, | |||
&xmc4xxx_flash, | |||
&niietcm4_flash, | |||
NULL, | |||
}; | |||
@@ -0,0 +1,55 @@ | |||
# K1921VK01T | |||
# http://niiet.ru/chips/nis?id=354 | |||
source [find target/swj-dp.tcl] | |||
source [find mem_helper.tcl] | |||
if { [info exists CHIPNAME] } { | |||
set _CHIPNAME $CHIPNAME | |||
} else { | |||
set _CHIPNAME k1921vk01t | |||
} | |||
set _ENDIAN little | |||
# Work-area is a space in RAM used for flash programming | |||
if { [info exists WORKAREASIZE] } { | |||
set _WORKAREASIZE $WORKAREASIZE | |||
} else { | |||
set _WORKAREASIZE 0x10000 | |||
} | |||
#jtag scan chain | |||
if { [info exists CPUTAPID] } { | |||
set _CPUTAPID $CPUTAPID | |||
} else { | |||
if { [using_jtag] } { | |||
set _CPUTAPID 0x410fc241 | |||
} { | |||
# SWD IDCODE | |||
set _CPUTAPID 0x2ba01477 | |||
} | |||
} | |||
swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID | |||
set _TARGETNAME $_CHIPNAME.cpu | |||
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME | |||
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 | |||
flash bank $_CHIPNAME.flash niietcm4 0 0 0 0 $_TARGETNAME | |||
adapter_khz 2000 | |||
adapter_nsrst_delay 100 | |||
if {[using_jtag]} { | |||
jtag_ntrst_delay 100 | |||
} | |||
reset_config srst_nogate | |||
if {![using_hla]} { | |||
# if srst is not fitted use SYSRESETREQ to | |||
# perform a soft reset | |||
cortex_m reset_config sysresetreq | |||
} |