; --------------------------------------------------------------------------------
; @Title: Example for flash declaration of NXP LPC13xx internal flash.
;
; @Description: 
; Script arguments:
;
;  DO lpc13xx [PREPAREONLY] [CPU=<cpu>]
;
;   PREPAREONLY only declares flash but does not execute flash programming
;   example
;
;   CPU=<cpu> selects CPU derivative <cpu>
;
; Example:
;
;   DO ~~/demo/arm/flash/lpc13xx CPU=LPC1347 PREPAREONLY
;
; List of LPC13xx derivatives and their configuration:
;
;   CPU-Type  FlashSize  EEPromSize  RamSize
;                [kB]       [kB]       [kB]
; --------------------------------------------------------------------------------
;   LPC1311        8.        -          2.
;   LPC1313       32.        -          8.
;   LPC1315       32.        2.         8.
;   LPC1316       48.        4.         8.
;   LPC1317       64.        4.         8.
;   LPC1342       16.        -          4.
;   LPC1343       32.        -          8.
;   LPC1345       32.        2.         8.
;   LPC1346       48.        4.         8.
;   LPC1347       64.        4.         8.
;
; Code Read Protection (CRP):
;
;   CRP is invoked by programming a specific pattern in flash location 
;   at 0x000002FC.
;
;  Name     Pattern      Description
; --------------------------------------------------------------------------------
;  NO_ISP   0x4E697370   Prevents sampling of pin PIO0_1 for entering ISP mode.
;                        PIO0_1 is available for other uses.
;  CRP1     0x12345678   Access to chip via the JTAG pins is disabled. This 
;                        mode allows partial flash update using the following 
;                        ISP commands and restrictions:
;                         Write to RAM command cannot access RAM below
;                          0x10000300.
;                         Copy RAM to flash command can not write to Sector 0.
;                         Erase command can erase Sector 0 only when all 
;                          sectors are selected for erase.
;                         Compare command is disabled.
;                         Read Memory command is disabled.
;                        This mode is useful when CRP is required and flash 
;                        field updates are needed but all sectors can not be 
;                        erased. Since compare command is disabled in case of 
;                        partial updates the secondary loader should implement 
;                        checksum mechanism to verify the integrity of the flash.
;  CRP2     0x87654321   Access to chip via the JTAG pins is disabled. The 
;                        following ISP commands are disabled:
;                         Read Memory
;                         Write to RAM
;                         Go
;                         Copy RAM to flash
;                         Compare
;                        When CRP2 is enabled the ISP erase command only 
;                        allows erasure of all user sectors.
;  CRP3     0x43218765   Access to chip via the JTAG pins is disabled. ISP 
;                        entry by pulling PIO0_1 LOW is disabled if a valid 
;                        user code is present in flash sector 0.
;                        This mode effectively disables ISP override using 
;                        PIO0_1 pin. It is up to the users application to 
;                        provide a flash update mechanism using IAP calls or 
;                        call reinvoke ISP command to enable flash update 
;                        via UART0. 
;                        Caution: If CRP3 is selected, no future factory 
;                        testing can be performed on the device.
;
; RAM used by IAP command handler:
;
;   Flash programming commands use the top 32 bytes of on-chip RAM. 
;   The maximum stack usage in the user allocated stack space is 128 
;   bytes and it grows downwards.
;
; HINTS:
;
;   Flash clock has to match System Clock Frequency (CCLK). 
;   FLASH.CLocK.AUTO can be used for automatic flash clock measurement.
;
;   Boot flash cannot be programmed or erased with builtin flash 
;   algorithm. 
;
;   Data has to be loaded to flash alignment to page boundaries.
;
;   Vector table checksum generation is done by script, so that it 
;   can be used or switched off, as needed.
;
; @Author: WRD
; @Copyright: (C) 1989-2019 Lauterbach GmbH, licensed for use with TRACE32(R) only
; @Chip: LPC13*
; --------------------------------------------------------------------------------
; $Rev: 7616 $
; $Id: lpc13xx.cmm 7616 2019-11-08 07:18:24Z bschroefel $

  LOCAL &parameters &param_prepareonly
  ENTRY %LINE &parameters
  &param_prepareonly=(STRing.SCAN(STRing.UPpeR("&parameters"),"PREPAREONLY",0)!=-1)

  LOCAL &param_cpu
  IF VERSION.BUILD()>=29755.
    &param_cpu=STRing.SCANAndExtract(STRing.UPpeR("&parameters"),"CPU=","")
  ELSE
    PRINT "Argument CPU= ignored because Trace32 software is too old"

  ; ------------------------------------------------------------------------------
  ; Start debugging

  IF SYStem.MODE()<5
  (
    SYStem.RESet

    IF "&param_cpu"!=""
      SYStem.CPU &param_cpu
    IF !CPUIS(LPC13*)
    (

      IF VERSION.BUILD()>=37389.
        SYStem.CPU LPC13*
      ELSE
        SYStem.CPU LPC1343
    )

    SYStem.Option EnReset OFF
    IF CABLE.TWOWIRE()
    (
      SYStem.CONFIG.DEBUGPORTTYPE SWD
    )

    SYStem.Up
  )

  ; ------------------------------------------------------------------------------
  ; Flash declaration

  FLASH.RESet
  FLASH.CLocK.AUTO
  GOSUB FlashDeclaration

  ; Flash script ends here if called with parameter PREPAREONLY
  IF &param_prepareonly
    ENDDO PREPAREDONE

  ; ------------------------------------------------------------------------------
  ; Flash programming example

  DIALOG.YESNO "Program flash memory?"
  LOCAL &progflash
  ENTRY &progflash
  IF &progflash 
  (
    ; Switch memory mapping to user flash mode, so that on-chip flash is 
    ; mapped to address 0x0--0x1ff. System Memory Remap register 
    ; SYSMEMREMAP:0..1 = 11b
    Data.Set 0x40048000 %Long 0x03

    ; Example for download 
    FLASH.ReProgram.ALL /Erase
    ; 1. Download file
    Data.LOAD.auto *
    ; 2. Checksum generation
    Data.SUM 0x0--0x1B /Long         ;Calculate checksum of all (other) vectors
    Data.Set 0x1C %Long -Data.SUM()  ;Write the 2's complement in reserved vector's spot
    ; 3. Flash programming
    FLASH.ReProgram.off

    ; Reset device
    SYStem.Down
    SYStem.Up
  )

  ENDDO


; --------------------------------------------------------------------------------
; Flash declaration depending on selected CPU 

FlashDeclaration:
  LOCAL &FlashSize
  LOCAL &RAMSize
  LOCAL &cpu

  &cpu=SYStem.CPU()
  IF (("&cpu"=="LPC1317")||("&cpu"=="LPC1347"))
  (
    &FlashSize=0x10000
    &RAMSize=0x2000
    ; EEPROM size 4 kB
  )
  ELSE IF (("&cpu"=="LPC1316")||("&cpu"=="LPC1346"))
  (
    &FlashSize=0xC000
    &RAMSize=0x2000
    ; EEPROM size 4 kB
  )
  ELSE IF (("&cpu"=="LPC1315")||("&cpu"=="LPC1345"))
  (
    &FlashSize=0x8000
    &RAMSize=0x2000
    ; EEPROM size 2 kB
  )
  ELSE IF (("&cpu"=="LPC1313")||("&cpu"=="LPC1343"))
  (
    &FlashSize=0x8000
    &RAMSize=0x2000
  )
  ELSE IF (("&cpu"=="LPC1342"))
  (
    &FlashSize=0x4000
    &RAMSize=0x1000
  )
  ELSE IF (("&cpu"=="LPC1311"))
  (
    &FlashSize=0x2000
    &RAMSize=0x0800
  )
  ELSE
  (
    PRINT %ERROR "FLASH size of CPU type is unknown"
    ENDDO
  )

  IF &FlashSize>=0x2000
  (
    FLASH.Create 1. 0x000000--0x001FFF 0x1000 TARGET Long
  )
  IF &FlashSize>=0x4000
  (
    FLASH.Create 1. 0x002000--0x003FFF 0x1000 TARGET Long
  )
  IF &FlashSize>=0x8000
  (
    FLASH.Create 1. 0x004000--0x007FFF 0x1000 TARGET Long
  )
  IF &FlashSize>=0xc000
  (
    FLASH.Create 1. 0x008000--0x00BFFF 0x1000 TARGET Long
  )
  IF &FlashSize>=010000
  (
    FLASH.Create 1. 0x00C000--0x00FFFF 0x1000 TARGET Long
  )

  IF &RAMSize>=0x2000
  (
    FLASH.TARGET 0x10001200 0x10000000 0x1000 ~~/demo/arm/flash/long/lpc1300.bin
  )
  ELSE IF &RAMSize>=0x1000
  (
    FLASH.TARGET 0x10000A00 0x10000000 0x800 ~~/demo/arm/flash/long/lpc1300.bin
  )
  ELSE IF &RAMSize>=0x0800
  (
    FLASH.TARGET 0x10000500 0x10000000 0x300 ~~/demo/arm/flash/long/lpc1300.bin
  )
  ELSE
  (
    PRINT %ERROR "RAM size is not supported by the script"
    ENDDO
  )

  RETURN
