搜索
bottom↓
回复: 19

等高手解惑: 如何在MDK定义一个新的mcu, 我用的是ARM968E-S.

[复制链接]

出0入4汤圆

发表于 2010-8-16 15:15:45 | 显示全部楼层 |阅读模式
我用的是ARM968E-S.NXP8009的,不在MDK的芯片list里面,是专用IC,google都没有datasheet,512k FLASH 地址从0开始,64k RAM,从0x400000开始。
可以连接JTAG并调试,但是我自己的程序不能下载到flash。尝试了很多方法去配置“target”,自己也更改了flash下载程序,编译了FLX,都不行。

希望有高手指条明路。 多谢!!!

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-8-16 15:20:20 | 显示全部楼层
ARM968应该可以选ARM分类中,ARM966的吧。不妨到ARM网站上查一下。指令集和内核结构没有大出入,找相似芯片就可以了。不用完全一致。最差选7TDMI,放弃新增的指令集的功能就可以用了。

往Flash中下载需要专门的驱动,如果你的开发工具不支持,那就没办法。
若你用的uLink2,那么Keil好像带了相关的下载驱动Demo,你参考下Keil目录里的代码,可以自己写一个uLink的Flash驱动,从而完成下载。

出0入4汤圆

 楼主| 发表于 2010-8-16 15:34:34 | 显示全部楼层
多谢楼上,我在这坐着等啊,呵呵。

ARM968E-S是有分类的在MDK的芯片列表中,比如LPC2917/9等等,可我不知道MDK是不是一定要定义芯片,因为在debug那个页面是要定义DLL的参数的,比如SARM.DLL -cLPC29xx。上传我的程序,包括测试程序。继续等。。。

flash programourdev_575330.zip(文件大小:105K) (原文件名:NXP80xx.zip)

出0入0汤圆

发表于 2010-8-16 15:42:26 | 显示全部楼层
对于编译来说,无需定义新的器件,使用同内核器件完成编译即可。如无同类型内核,则选择特性兼容的同代内核即可。

Debug页面的DLL主要用于软件仿真,硬件仿真器仿真时候的界面/寄存器等定义和显示。
如需仿真功能,则在满足上条基础上,选择最接近的器件型号。仿真时不要使用Keil提供的诸如寄存器内容显示等方便调试的功能即可。

能否下载Flash代码是仿真器/Keil提供的额外功能,需要参考额外手册解决。

出0入4汤圆

 楼主| 发表于 2010-8-16 15:47:09 | 显示全部楼层
我用的是J-LINK V8 4.14

出0入0汤圆

发表于 2010-8-16 16:00:51 | 显示全部楼层
用错工具了,现在ARM自己的工具有两个,RVMDK是用来开发成品单片机的,RVDS是用来开发ARM内核的FPGA或者SoC的,你这种情况显然应该使用RVDS来开发。

出0入0汤圆

发表于 2010-8-16 16:44:58 | 显示全部楼层
J-FLASH就可以烧的

出0入4汤圆

 楼主| 发表于 2010-8-16 17:16:19 | 显示全部楼层
J-FLASH说找不到flash设备,我这款是内置512k的,
To:hitler
我以前用ads是可以在自己的ARM7TDMI上跑的,当时没搞明白ADS怎么写flash,就自己用程序分割HEX文件然后通过RAM里面的程序一个一个的写进flash。

出0入4汤圆

 楼主| 发表于 2010-8-16 17:19:12 | 显示全部楼层
Debug页面的DLL主要用于软件仿真,硬件仿真器仿真时候的界面/寄存器等定义和显示。

如果某天我可以下载程序到flash,是否可以自定义寄存器,比如更改某个configuration或者INI文件?

出0入4汤圆

 楼主| 发表于 2010-8-17 14:09:32 | 显示全部楼层
大家帮忙看看我的启动代码.
                                               
; ARM xPSR
ModeClear       EQU 0xFFFFFFE0
UsrMode         EQU 0x00000010
FIQMode         EQU 0x00000011
IRQMode         EQU 0x00000012
SvcMode         EQU 0x00000013
AbtMode         EQU 0x00000017
UndMode         EQU 0x0000001B
SysMode         EQU 0x0000001F

I_Bit           EQU 0x00000080
F_Bit           EQU 0x00000040
T_Bit           EQU 0x00000020

SR_IF_BITS      EQU (I_Bit:or:F_Bit)


; backward compatible synonyms
IRQDBit         EQU I_Bit
FIQDBit         EQU F_Bit
Mode_USR        EQU UsrMode
Mode_FIQ        EQU FIQMode
Mode_IRQ        EQU IRQMode
Mode_SVC        EQU SvcMode

; IF VEGA_BB:LOR:VEGA_TB:LOR:VEGA_XS:LOR:VEGA_LITE:LOR:VEGA_ONE
;   IF VEGA_ONE
ICU_BASE        EQU 0x01102000        ; Base address, Obj Spec. V0.2 PNX8xxxx
SDC_BASE        EQU 0x00200000
GPIO_BASE       EQU 0x0111E400
GPIO_DATP       EQU     0x0100 ; pin
GPIO_DATW       EQU     0x0210 ; word

SCU_BASE        EQU 0x0111D800
DAIF_BASE       EQU 0x0111CC00

SCU_SYS_PCON    EQU SCU_BASE  + 0x0C
APU_RANA8       EQU DAIF_BASE + 0x9C
; ENDIF

; ICU offsets
FIQRequest      EQU 0x00  ; R-
FIQSource       EQU 0x04  ; R-
FIQEnable       EQU 0x08  ; R-
FIQClear        EQU 0x10  ; -W
FIQEnable_Set         EQU 0x14  ; -W
FIQEnable_Clear EQU 0x18  ; -W
IRQRequest      EQU 0x20  ; R-
IRQSource       EQU 0x24  ; R-
IRQEnable       EQU 0x28  ; R-
IRQClear        EQU 0x30  ; -W
IRQEnable_Set         EQU 0x34  ; -W
IRQEnable_Clear EQU 0x38  ; -W

; backward compatible synonyms
FIQ_CLEAR       EQU FIQClear
FIQ_ENBC        EQU FIQEnable_Clear
IRQ_CLEAR       EQU IRQClear
IRQ_ENBC        EQU IRQEnable_Clear



; Vega register values, bits, masks, ..
CLK_IF_Bit      EQU 0x08
DCL_EN_Bit      EQU 0x20

; IF VEGA_ONE
;        IMPORT       |Image$$DTCM$$Base|
; ELSE
RAM_Base        EQU     0x0400000
; ENDIF


RAM_Limit       EQU     0x0040FFF8  ; 64kB  ;tc added

IRQ_StackLen    EQU     0x080

USR_StackLen    EQU     0x400



; IF DF_FIQ_MON
; (4 Priority groups stacking * 8 regs) + Max(Prio0) => 156bytes (0x9C)
FIQ_StackLen    EQU     0x0A0
; ELSE
; (4 Priority groups stacking * 6 regs) + Max(Prio0) => 124bytes (0x7C)
;FIQ_StackLen    EQU     0x080
; ENDIF

SVC_StackLen    EQU     0x000


FIQ_Stack       EQU     RAM_Limit                ; FIQ stack down from top
IRQ_Stack       EQU     FIQ_Stack-FIQ_StackLen   ; IRQ stack follows
SVC_Stack       EQU     IRQ_Stack-IRQ_StackLen   ; followed by SVC stack
USR_Stack       EQU     SVC_Stack-SVC_StackLen   ; followed by USR stack

USR_StackTop    EQU     USR_Stack-USR_StackLen   ; followed by ZI Data


; --- Macro to provide a WEAK dummy function in its own AREA
;       the function returns -1 (common rejection code)
    MACRO      ;  (functionName)
    dummyFunc   $func
        AREA    DummyArea_$func, CODE
        EXPORT  $func[WEAK]
$func
    IF {CODESIZE}=32
        mvn     r0,#0
    ELSE
        mov        r0,#0
        mvn     r0,r0
    ENDIF
        bx      r14

    MEND



;;;;;;;;;;;;;;;;;; startup.s ;;;;;;;;;;;;

  IF :LNOT:({CODESIZE}=32)
           CODE32
  ENDIF
       

                AREA    RESET, CODE, READONLY
                ARM
   
; == DEFINES ============================================================
; -------------------------------------------------------------------------
; Macro for exception handlers enterring a loop (Not IRQ/FIQ/Reset)
; -------------------------------------------------------------------------
;;;;;;;;;;;;;gm mark ;;;;;;;;;;;
Vectors         LDR     PC, Reset_Addr
                LDR     PC, Undef_Addr
                LDR     PC, SWI_Addr
                LDR     PC, PAbt_Addr
                LDR     PC, DAbt_Addr
                NOP                               ; Reserved Vector
                LDR     PC, IRQ_Addr
                LDR     PC, FIQ_Addr

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
                DCD     0                         ; Reserved Address
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_Handler

Undef_Handler   B       Undef_Handler
SWI_Handler     B       SWI_Handler
PAbt_Handler    B       PAbt_Handler
DAbt_Handler    B       DAbt_Handler

IRQ_Handler     B                IRQ_Handler

FIQ_Handler     PROC
                EXPORT  FIQ_Handler               [WEAK]
                B       .
                ENDP

Default_Handler PROC
                B       .
                ENDP
; Reset Handler
                EXPORT  Reset_Handler
Reset_Handler   

; --------------------------------------
; Disable IRQs and FIQs
        MRS        a1,CPSR                 ; read status register
        ORR        a1,a1,#SR_IF_BITS        ; set I and F bits
        MSR        CPSR_cf,a1                ; and write back

        EXPORT        FIQ_Stack
        EXPORT        IRQ_Stack


SSW_RAM_Limit   EQU    RAM_Limit
        EXPORT     SSW_RAM_Limit
SSW_USR_Stack_Limit EQU USR_Stack
        EXPORT      SSW_USR_Stack_Limit
;VTT_MMI
u32_BootPowerStatus  EQU     RAM_Limit
        EXPORT     u32_BootPowerStatus
u32_BootSignature    EQU     RAM_Limit+4
        EXPORT     u32_BootSignature

; == Start of code ==========================================================

;----------------------------------------------------------------------------
; The FIQ Interrupt handler should be linked directly on the vectore table
; address 0x1c (last exception entry) to save cycles.
; Installing an exception handler see User Guide 11.4

; ROM start, Vector Table at begin (start ad address 0)

; The RESET entry point
;        EXPORT __main

        ENTRY
;__main
; IF VEGA_BB:LOR:VEGA_TB:LOR:XS_ON_TB_DEMO:LOR:LITE_ON_TB_DEMO:LOR:VEGA_LITE:LOR:XS_ON_LITEFLASH:LOR:LITE_ON_LITEFLASH
;    IF VEGA_ONE ; if needed, add to condition above!
        MOV  r0, #0x00200000 ; SDC_BASE in r0, FCTR address for VegaOne
;    ELSE
;workaround suggested by JWE for TB (???? to be removed for BB ?????)
;the content of address 0x0111de00 should be 0x15 (LDR doesn't work before this)
;        MOV  r1, #0x0110       ; construct the target addr of PFlashCtrl
;        ADD  r1, r1, #1        ; due to not be able to use a LDR cmd here
;        MOV  r0, #0xDE00
;        ADD  r0, r0, r1, LSL #0x10 ; SDC_BASE in r0, FCTR address for !VegaOne
;    ENDIF
        MOV  r1, #0x15               ; write 0x15 value to FCTR  
        STR  r1, [r0]          ; now we can use also ldr commands !!!!

        NOP                    ; give the PFlash contr. a chance
        NOP
;add further 7 NOPS
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP       

        ADD  r0, r0, #0x10     ; handle to FWST
        LDR  r1,[r0]
        SUB  r1, r1, #0xC000
        CMP  r1, #4        
        BNE  GoAhead           ; we are from power-up

        MOV  r1, #0xC000
        ADD  r1, r1, #3        ; get 3 waitstates for PFlash
        STR  r1,[r0]
;
GoAhead
; ENDIF


; --- Reset DC-DC Converter , but not for OM6116

;  Enable CLK_IF
        LDR  r0, =SCU_SYS_PCON
        LDR  r1, [r0]
        ORR  r2, r1, #CLK_IF_Bit
        STR  r2, [r0]
        
;  Switch DCDC OFF, wait for transmission, and switch ON again
        LDR  r3, =APU_RANA8
        LDR  r4, [r3]
        AND  r5, r4, #:NOT:DCL_EN_Bit
        STR  r5, [r3]
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        STR  r4, [r3]

;  Wait until transmission completed and disable CLK_IF
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        STR  r1, [r0]

              

; --- Initialise stack pointer registers
; Enter FIQ mode and set up the FIQ stack pointer
        MOV     R0, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; No interrupts
        MSR     CPSR_cf, R0
        LDR     R13, =FIQ_Stack

; Enter IRQ mode and set up the IRQ stack pointer
        MOV     R0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
        MSR     CPSR_cf, R0
        LDR     R13, =IRQ_Stack

; Set up the SVC stack pointer last and return to SVC mode
        MOV     R0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
        MSR     CPSR_cf, R0
        LDR     R13, =SVC_Stack

; --- Initialise memory system
        ; ...

; --- Initialise critical IO devices
        ; ...

; --- Initialise interrupt system variables here
        LDR     r0, =ICU_BASE
        MVN     r2, #0
        STR     r2, [r0,#FIQ_ENBC]
        STR     r2, [r0,#FIQ_CLEAR]
        STR     r2, [r0,#IRQ_ENBC]
        STR     r2, [r0,#IRQ_CLEAR]
        

; --- Initialise memory required by C code
;        IMPORT  |Load$$RO$$Base|      ; End of ROM code (=start of ROM data)
                IMPORT  |Image$$RO$$Limit|

        IMPORT  |Image$$RW$$Base|     ; Base of RAM to initialise
                IMPORT  |Image$$RW$$Limit|

        IMPORT  |Image$$ZI$$Base| ; Base and length of ZI area
                IMPORT  |Image$$ZI$$Limit|



;        IMPORT  |Image$$ZI$$Length| ; (but RAM_Base - RAM_Limit is zeroed)

        ; --- set the ARM9 CP15 reg to use DTCM
        MRC     p15, 0, r0, c1, c0, 0 ;
        ORR     r0, r0, #0x0C                        ; W and D bit in CP15 c1 set (DTCM and ahb buffer enabled)        
        MCR     p15, 0, r0, c1, c0, 0

        ; --- set ITCM order bit
        MRC     p15, 1, r0, c15, c1, 0 ; read cp15-c15
        ORR     r0, r0, #0x40000       ; set bit 18
        MCR     p15, 1, r0, c15, c1, 0 ; write back


;        IMPORT       |Image$$DTCM$$Base|
        LDR     r0, =|Image$$RW$$Base|

        LDR     r1, =RAM_Limit
        MOV     r2, #0
ZERORAM
        CMP     r0, r1
        STRCC   r2, [r0], #4
        BCC     ZERORAM

;        LDR     r0, =|Load$$RW$$Base|    ; Get pointer to ROM data
                LDR                r0,=|Image$$RO$$Limit|;
        LDR     r1, =|Image$$RW$$Base|   ; and RAM copy
        LDR     r3, =|Image$$ZI$$Base| ; Zero init base => end of RW init

        CMP     r0, r1                  ; Check that they are different
        BEQ     RWDONE

RWINIT
        CMP     r1, r3                  ; Copy init values for RW data
        LDRCC   r2, [r0], #4
        STRCC   r2, [r1], #4
        BCC     RWINIT
RWDONE
        LDR     r1, =|SSW_FirstUnusedRAM|   ; Base   of zero init segment
        LDR     r2, =0x55555555 ; pattern
        LDR     r3, =RAM_Limit
MARKSTACK
        CMP     r1, r3                  ; mark stack
        STRCC   r2, [r1], #4
        BCC     MARKSTACK
        MOV     r2, r3         ; clear pattern to prevent beeing stacked

; --- Now change to user mode and set up user mode stack.

        MOV     R0, #Mode_USR  ; IRQ and FIQ enabled
        MSR     CPSR_cf, R0
        LDR     sp, =USR_Stack

; --- Dummy access to stack check variables (checked by final link)
        LDR     R0, =|ROMLimit|
        LDR     R0, =|RAMLimit|
        LDR     R0, =|TotalUsedRAM|

; --- Now we enter the C code
                IMPORT  __main
                LDR     R0, =__main
                BX      R0

;        IMPORT main_entry
;        BL     main_entry



; -------------------------------------------------------------------------
; SWI Exception Handler
; -------------------------------------------------------------------------
        CODE32
        EXPORT p_SWIHandler
p_SWIHandler
;----------------------------------------------------
; SWI 0                disable IRQs => set   I_Bit
; SWI 1                enable  IRQs => clear I_Bit
; SWI 2         disable FIQs => set   F_Bit
; SWI 3         disable FIQs => clear F_Bit
; SWI 4..7      reserved
;----------------------------------------------------
; SWI 8         Go to sleep (Only VegaOne)
; SWI 9..16     reserved
;----------------------------------------------------
; SWI 16..23    Patch mechanism (Only VegaOne)
;----------------------------------------------------
; SWI 24..255   Undefined
;
; assumptions for implementation of  p_SWIHandler:
; on entry: I_Bit set, mode=SVC
; SVC stack is not used => sp used as local variable
; only invoked from USR or IRQ application code => only thumb SWI to process
;----------------------------------------------------
        GBLL        SWI_TONLY
SWI_TONLY        SETL        {FALSE}   ;; set to FALSE for VEGApro

        ;--- load the SWI number into sp
IF :LNOT:SWI_TONLY
        MRS        sp, spsr
        TST        sp, #T_Bit
        LDRNEH        sp, [lr,#-2]
        BICNE        sp, sp,#0xFF00
        LDREQ        sp, [lr,#-4]
        BICEQ        sp, sp, #0xFF000000
ELSE
        LDRH        sp, [lr,#-2]
        BIC        sp, sp,#0xFF00
ENDIF

IRQSwitch
        CMP        sp, #1
        BHI        FIQSwitch
        MRS        sp, spsr
        ORRNE        sp, sp,#I_Bit                ; SWI 0: disable IRQs
        ANDEQ        sp, sp,#:NOT:I_Bit        ; SWI 1: enable  IRQs
        B       ENDSwitch

FIQSwitch
        CMP        sp, #3
;    IF VEGA_ONE ; if needed, add to condition above!
        BHI        IdleSwitch
;   ELSE
;        BHI        UnrecognisedSWILoop
;    ENDIF
        MRS        sp, spsr
        ORRNE        sp, sp,#F_Bit                ; SWI 2: disable FIQs
        ANDEQ        sp, sp,#:NOT:F_Bit        ; SWI 3: enable  FIQs

ENDSwitch

        MSR        spsr_cf, sp
        MOVS        pc,lr                ; return from SWI

;    IF VEGA_ONE ; if needed, add to condition above!

IdleSwitch ; Idle mode!!!!
        CMP        sp, #8
        BHI        PatchSwitch
       
        MCR     p15, 0, r0, c7, c0, 4
        
        MOVS        pc,lr                ; return from SWI

PatchRamStart EQU 0x300000

PatchSwitch

        AREA ArmAccess, CODE, READONLY
        CODE32

;---------------------------------------------------------------------
; u32 p_bbc_getCPSR(void)
;---------------------------------------------------------------------
        EXPORT p_bbc_getCPSR
p_bbc_getCPSR
        MRS r0,cpsr
        bx  r14

;---------------------------------------------------------------------
; Dummy data area simulating stack to the linker to allow for memory
; underrun test.
; This area is never used by any program.
;---------------------------------------------------------------------
        EXPORT SSW_FirstUnusedRAM        
        AREA DummyStack, DATA, NOINIT
SSW_FirstUnusedRAM
        SPACE      USR_StackLen+IRQ_StackLen+FIQ_StackLen
TotalUsedRAM

;---------------------------------------------------------------------
; DebugOnTBRAM data area placed to exactly after the end of the physical
; RAM of the VegaTB. It allows for RAM underrun check by the linker for
; debug builds for XS or Lite where the whole 22kB TB RAM can be used
;---------------------------------------------------------------------
        AREA DebugOnTBRAM, DATA, NOINIT
RAMLimit
        SPACE      1   ;dummy size of 1, otherwise area overlap is ignored

        AREA    StartOfRAM, DATA, NOINIT
        EXPORT  StartOfRAM
RAMStart
;     END

        AREA JustAfterROM, DATA, NOINIT
ROMLimit
;        SPACE      1   ;dummy size of 1, otherwise area overlap is ignored
        SPACE      0x80000   ; Due to the 4kB Gap between PROM and FW ROM in the 8001/10/11,
                             ; the symbol to trap memory overlap has to be huge

     END

出0入4汤圆

 楼主| 发表于 2010-8-17 14:10:30 | 显示全部楼层
这里是测试代码
/******************************************************************************/
/*  This file is part of the uVision/ARM development tools                    */
/*  Copyright KEIL ELEKTRONIK GmbH 2002-2006                                  */
/******************************************************************************/
/*                                                                            */
/*  TEST.C:  Test for Flash Programming Functions                             */
/*                                                                            */
/******************************************************************************/

#include "..\..\FlashOS.H"          // FlashOS Structures


#define M8(adr) (*((volatile unsigned char  *) (adr)))

volatile int  ret;                  // Return Code
unsigned char buf[1024];            // Programming Buffer


int main (void) {
  unsigned long n;

  ret = Init(0, 12000000, 1);       // Initialize Flash Programming Functions
                                    //   Device Base Address = 0
                                    //   Clock Frequency = 12MHz

//ret |= EraseChip();               // Test Full Chip Erase

  ret |= EraseSector(0x00000000);   // Test Sector Erase ( 8kB Sector  0)
  ret |= EraseSector(0x00002000);   // Test Sector Erase ( 8kB Sector  1)
  ret |= EraseSector(0x00004000);   // Test Sector Erase ( 8kB Sector  2)
  ret |= EraseSector(0x00006000);   // Test Sector Erase ( 8kB Sector  3)
  ret |= EraseSector(0x00008000);   // Test Sector Erase ( 8kB Sector  4)
  ret |= EraseSector(0x0000A000);   // Test Sector Erase ( 8kB Sector  5)
  ret |= EraseSector(0x0000C000);   // Test Sector Erase ( 8kB Sector  6)
  ret |= EraseSector(0x0000E000);   // Test Sector Erase ( 8kB Sector  7)
  ret |= EraseSector(0x00010000);   // Test Sector Erase (64kB Sector  8)
  ret |= EraseSector(0x00020000);   // Test Sector Erase (64kB Sector  9)
  ret |= EraseSector(0x00030000);   // Test Sector Erase ( 8kB Sector 10)
  ret |= EraseSector(0x00032000);   // Test Sector Erase ( 8kB Sector 11)
  ret |= EraseSector(0x00034000);   // Test Sector Erase ( 8kB Sector 12)
  ret |= EraseSector(0x00036000);   // Test Sector Erase ( 8kB Sector 13)
  ret |= EraseSector(0x00038000);   // Test Sector Erase ( 8kB Sector 14)
  ret |= EraseSector(0x0003A000);   // Test Sector Erase ( 8kB Sector 15)
  ret |= EraseSector(0x0003C000);   // Test Sector Erase ( 8kB Sector 16)

  // Verify Erase
  for (n = 0; n < 0x0003E000; n++) {
    if (M8(n) != 0xFF) {
      ret = 1;                      // Error
      break;
    }
  }

  // Programming Test Pattern
  for (n = 0; n < 1024; n++) {
    buf[n] = (unsigned char)n;
  }

  // Test Page Programming
  ret |= ProgramPage(0x00000400, 1024, buf);

  // Verify Programming
  for (n = 0; n < 1024; n++) {
    if (M8(0x00000400 + n) != buf[n]) {
      ret = 1;                      // Error
      break;
    }
  }

  if (ret == 0) {
    // OK
  } else {
    // Error
  }

  while (1);                        // Wait forever
}

出0入4汤圆

 楼主| 发表于 2010-8-17 14:10:52 | 显示全部楼层
/***********************************************************************/
/*  This file is part of the ARM Toolchain package                     */
/*  Copyright KEIL ELEKTRONIK GmbH 2003 - 2007                         */
/***********************************************************************/
/*                                                                     */
/*  FlashDev.C:  Flash Programming Functions adapted                   */
/*               for NXP LPC29xx                                       */
/*                                                                     */
/***********************************************************************/

#include "..\FlashOS.H"                 // FlashOS Structures

//#include <LPC29xx.H>

#define M8(adr)      (*((volatile unsigned char  *) (adr)))
#define M16(adr)     (*((volatile unsigned short *) (adr)))
#define M32(adr)     (*((volatile unsigned long  *) (adr)))

#define FLASH_BASE   0x0000000         // Flash Base Address

#define STACK_SIZE   64                 // Stack Size


/* System Control Registers*/
#define CLK_DIV         (*((volatile unsigned long *) 0x0111D800 ))        /*  Clock Divider Control*/
#define GEN_CON         (*((volatile unsigned long *) 0x0111D804 ))        /*  General Control*/
#define PLL_DIV         (*((volatile unsigned long *) 0x0111D808 ))        /*  PLL Divider Control*/
#define SYS_PCON         (*((volatile unsigned long *) 0x0111D80C ))        /*  System Power control*/
#define RST_DEL         (*((volatile unsigned long *) 0x0111D810 ))        /*  Reset Delay and Reset Source*/
#define PLL_LOCK_CON         (*((volatile unsigned long *) 0x0111D814 ))        /*  PLL lock counter control register*/
#define PB_PSTAT         (*((volatile unsigned long *) 0x0111D818 ))        /*  Peripheral Block Power Status Register*/
#define PB_PCON_ON         (*((volatile unsigned long *) 0x0111D81C ))        /*  Peripheral Block Power Enable Register*/
#define PB_PCON_OFF         (*((volatile unsigned long *) 0x0111D820 ))        /*  Peripheral Block Power Disable Register*/
#define GP_CLK         (*((volatile unsigned long *) 0x0111D824 ))        /*  General Purpose Clock Output Selection*/
#define SYS_DIV_PLLOFF         (*((volatile unsigned long *) 0x0111D828 ))        /*  System PLL Divider Control (when PLL OFF)*/
#define TYPE_INFO         (*((volatile unsigned long *) 0x0111D834 ))        /*  Type Info Register*/

/* Flash program */
#define FCTR         (*((volatile unsigned long *) 0x00200000 ))        //  P-FLASH Control register
#define FSTAT         (*((volatile unsigned long *) 0x00200004 ))        //  P-FLASH Status register
#define FPTR         (*((volatile unsigned long *) 0x00200008 ))        //  P-FLASH Programming Timer Register
#define FBWST         (*((volatile unsigned long *) 0x00200010 ))        //  P-FLASH cache control and waitstate register
#define FCRA         (*((volatile unsigned long *) 0x0020001C ))        //  P-FLASH clock prescaler register
#define FMSSTART         (*((volatile unsigned long *) 0x00200020 ))        //  P-FLASH MISR register, Start Address
#define FMSSTOP         (*((volatile unsigned long *) 0x00200024 ))        //  P-FLASH MISR register, Stop Address
#define FMSW0         (*((volatile unsigned long *) 0x0020002C ))        //  P-FLASH MISR register, 128 bit signature LSW [31:0]
#define FMSW1         (*((volatile unsigned long *) 0x00200030 ))        //  P-FLASH MISR register, 128 bit signature [63:32]
#define FMSW2         (*((volatile unsigned long *) 0x00200034 ))        //  P-FLASH MISR register, 128 bit signature [95:64]
#define FMSW3         (*((volatile unsigned long *) 0x00200038 ))        //  P-FLASH MISR register, 128 bit signature MSW [127:96]



void wait(void){
int wait_t        ;         /* only to delay */
  for (wait_t=0;wait_t<100;wait_t++) {
                __asm { nop;};
        }
        return;
}

/*
*  Initialize Flash Programming Functions
*    Parameter:      adr:  Device Base Address
*                    clk:  Clock Frequency (Hz)
*                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
*    Return Value:   0 - OK,  1 - Failed
*/

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {

  int i;

  // Setup clock to use crystal 10 MHz and generate SYS clock of 80MHz
  /*
  SYS_CLK_CONF = CLK_SEL_XTAL;
  PLL_CONTROL  = P23EN + PLL_PD;
  PLL_CONTROL  = PLL_XTAL_SEL + (15 << MSEL_SHIFT) + P23EN + PLL_PD;
  PLL_CONTROL  = PLL_XTAL_SEL + (15 << MSEL_SHIFT) + P23EN;
  while (!(PLL_STATUS & PLL_LOCK   ));  // Wait for PLL Lock
  while (!(RDET       & PLL_PRESENT));  // Wait for Clock Present
  SYS_CLK_CONF = CLK_SEL_PLL + AUTOBLK + DIV2;
  FCTR         = FS_CS + FS_DCR + FS_WPB;
  FBWST        = CACHE2EN + SPECALWAYS + WST4;
  FCRA         = ((80000000/3)/66000)-1;
*/
///////////////////////////////////////////////////
        SYS_PCON = 6; // Switch off PLL
        wait()        ;
        wait()        ;
        wait()        ;
        PLL_DIV = 0x2100; // For 13M and 27M crystal
        wait()        ;
        wait()        ;
        wait()        ;
        SYS_PCON = 0x17; // Switch on PLL
        wait()        ;
        wait()        ;
        wait()        ;

        FCRA = 0x45 ;        // 0x0111DE1C P-FLASH clock prescaler register  5*Fhclk - 1 =69=0x45
        wait()        ;
///////////////////////////////////////////////////



  // Unprotect all sectors
  for (i = 0; i < 0x10000; i += 0x2000) {
    M32(i+FLASH_BASE)  = 0;
    //FCTR               = FS_CS + FS_WRE + FS_WEB + FS_DCR + FS_WPB + FS_LOADREQ;
        FCTR = 0x8087;          // unprotect sector
    M32(i+FLASH_BASE)  = 0;
  }

#ifdef SIZE_512kB
  for (i = 0x10000; i < 0x80000; i += 0x10000) {
    M32(i+FLASH_BASE)  = 0;
    //FCTR               = FS_CS + FS_WRE + FS_WEB + FS_DCR + FS_WPB + FS_LOADREQ;
        FCTR = 0x8087;   // unprotect sector
    M32(i+FLASH_BASE)  = 0;
  }
#elif  SIZE_768kB
  for (i = 0x10000; i < 0xC0000; i += 0x10000) {
    M32(i+FLASH_BASE)  = 0;
    //FCTR               = FS_CS + FS_WRE + FS_WEB + FS_DCR + FS_WPB + FS_LOADREQ;
        FCTR = 0x8087;        // unprotect sector
    M32(i+FLASH_BASE)  = 0;
  }
#endif

  return (0);   // Success
}


/*
*  De-Initialize Flash Programming Functions
*    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
*    Return Value:   0 - OK,  1 - Failed
*/

int UnInit (unsigned long fnc) {
  return (0);
}


/*
*  Erase Sector in Flash Memory
*    Parameter:      adr:  Sector Address
*    Return Value:   0 - OK,  1 - Failed
*/

int EraseSector (unsigned long adr) {
        volatile unsigned long temp;
//  FMC_INT_CLR_STATUS = 0x01;            // Clear End of Erase flag
        FCRA = 0x45 ;        // 0x0111DE1C P-FLASH clock prescaler register  5*Fhclk - 1 =69=0x45
        wait()        ;

  // Start erase procedure
  M32(adr)  = 0;
  //FCTR      = FS_CS +          FS_WEB + FS_DCR + FS_WPB + FS_LOADREQ;
   FCTR = 0x8085; // erase
        temp = FCTR;
  M32(adr)  = 0;
   FCTR = 0x5; // erase
        temp = FCTR;
  // Set Erase Timer value
  FPTR      = ((105 * 80000) / 512) | (1 << 15);
  
//  M32(adr)  = 0;
  // Triger sector erase
//  FCTR      = FS_CS +                 + FS_DCR + FS_WPB + FS_PROGREQ;
FCTR = 0x1081; // erase
        temp = FCTR;
  M32(adr)  = 0;

//  while (!(FMC_INT_STATUS & 0x01));     // Wait for erase to finish
        __asm { nop;nop;nop;nop;nop;nop;nop;nop};
        while (( FSTAT & 0x1f ) != 0x5) ; // wait
        while (( FSTAT & 0x5 ) != 0x5) ; // wait
        temp = M32(adr);
  return (0);   // Success
}


/*
*  Program Page in Flash Memory
*    Parameter:      adr:  Page Start Address
*                    sz:   Page Size
*                    buf:  Page Data
*    Return Value:   0 - OK,  1 - Failed
*/

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {

  unsigned char rest, sz_add;

//  FMC_INT_CLR_STATUS = 0x02;          // Clear End of Burn flag
        FCRA = 0x45 ;        // 0x0111DE1C P-FLASH clock prescaler register  5*Fhclk - 1 =69=0x45
        wait()        ;

  // Preset data latches
   FCTR = 0X407; // LATCHES =0XFFFFFFFF
   FCTR = 0X007; // enable data load
  //FCTR      = FS_CS + FS_WRE + FS_WEB + FS_DCR + FS_PDL;
  //FCTR      = FS_CS + FS_WRE + FS_WEB + FS_DCR;

  if (sz >= 512) {
    rest   = 0;
    sz_add = 0;
    sz     = 512;
  }  else {
    rest   = sz & 0x03;
    sz_add = (16 - (sz & 0x0F)) >> 2;
    sz    -= rest;
  }

  // Load whole words to data latches
  while (sz) {
    M32(adr) = *((unsigned long *)buf);
    adr += 4;
    buf += 4;
    sz  -= 4;
  }

  // Load remaining word to data latches (if rest != 0)
  if (rest != 0) {
    M32(adr) = *((unsigned long *)buf) | (0xFFFFFFFF << (rest << 3));
    adr     += 4;
  }

  // Load additional words if number of loaded words is not a round number of 4 words
  while (sz_add--) {
    M32(adr) = 0xFFFFFFFF;
    adr     += 4;
  }

  // Set Program Timer value
  FPTR      = ((105 * 800) / 512) | (1 << 15);

  // Triger programming
  //FCTR      = FS_CS + FS_WRE +          FS_DCR + FS_WPB + FS_PROGREQ;
   FCTR = 0X1083; // start to program.
//  while (!(FMC_INT_STATUS & 0x02));     // Wait for burn to finish
        __asm { nop;nop;nop;nop;nop;nop;nop;nop};
        while (( FSTAT & 0x1f ) != 0x5) ; // wait
        while (( FSTAT & 0x5 ) != 0x5) ; // wait

  return (0);   // Success
}

出0入4汤圆

 楼主| 发表于 2010-8-17 14:12:36 | 显示全部楼层
很奇怪的是为什么我的FCTR可以读出数据,程序写却没有反应,可是可以用MDK直接写memory.0x200000.

出0入4汤圆

 楼主| 发表于 2010-8-24 18:57:38 | 显示全部楼层
自己来解释,把那个400多页的english datasheet看完了,原来这个IC有两个时钟总线,ITCM和DTCM,分别是代码和数据的,我想ARM公司是混合了哈佛和洛伊曼结构吧,有时候一个问题可以卡的人那么就。希望遇到同样问题的同志看看有没有个RAM是在ITCM下面的,有就下到哪里去运行吧。

出0入0汤圆

发表于 2010-8-24 22:40:26 | 显示全部楼层
再简单看看ARM928的TRM吧,在ARM网站有。
可以粗糙的不那么正确的理解为,ARM928有三个总线主控:AHB Master; ITCM; DTCM。

一般的内存是在AHB Master上的,可以直接用。
ITCM和DTCM除非你用的芯片在硬线逻辑上配置了,否则是不能直接用的,需要程序配置,然后才可以正常访问。

ARM9E系列内核都是标准的哈佛结构,但是在AHB Master那里,就有可能把地址空间合并了。
但是需要注意,DTCM和ITCM是与AHB Master并列的地址空间,可以是无关的,具体要看芯片配置。

出0入4汤圆

 楼主| 发表于 2010-8-25 09:03:12 | 显示全部楼层
楼上正解,看来从ARM7到9的移植不是那么简单的,即使同样是ARM9,也有很大的区别,特别是启动代码和中断配置,ARM公司一日千里,已经打破了传统MCU的发展速度,加之每个公司自定义的外围,每个开发者必须要走启动和系统移植这一关,不能直接做应用级别开发。这个确实有些过时了,好在流行的arm都有现成的启动代码和库,不过国内的很多初学者都在这一部分花费太多精力。

出0入4汤圆

 楼主| 发表于 2010-8-25 09:10:35 | 显示全部楼层
回复【1楼】dr2001
-----------------------------------------------------------------------

另外感谢dr2001一直耐心的回复,其实我这片IC是接近Soc的,它集成了RF控制的突发模式控制器和音频DSP,我现在山寨了flash下载和启动部分。有完整的speci和电路,如果你有兴趣,我或者可以赠送样板给你。

出0入0汤圆

发表于 2010-8-25 09:13:41 | 显示全部楼层
对于通用ARM内核,一般的代码是可以直接拿来用的,不需要过多的修改。ARM的架构的延续性基本上就是这么体现的。
对于TCM这样的时序敏感端口,一般都是特殊应用需求导致的,这个需要特别的处理和优化是正常的现象。

出0入0汤圆

发表于 2010-8-25 09:25:02 | 显示全部楼层
你这个主要是flash烧写问题吧,需要写相应的烧写bin文件,然后添加到Keil里才能烧写的。I/D-TCM一般配置下CP15就可以用了,或者默认值,按照默认方式进行使用。I/D-TCM是好东西啊

出0入4汤圆

 楼主| 发表于 2010-8-25 13:09:34 | 显示全部楼层
试过用MDK的flx文件,总是莫名退出,没时间搞清楚那些,就自己写了个下载程序用JLINK先下到ITCM的RAM区,然后下程序到DTCM区,最后编程flash。绕了个弯,不过最少我知道程序在做什么。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-13 11:06

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表