; -------------------------------------------------------------------------------- ; @Title: Serial flash script for Traveo-ii CYT4BF8-CM0+ on CYTVII-B-H-8M ; ; @Description: ; The S25FL256(Spansion) is connected to the SMIF controller ; ; SRAM: 0x28001000 ; SMIF(controller) Base: 0x40420000 or 0x40430000 ; ; P24_1 - SPI_CLK/SPIB_CLK ; P24_3 - SPI_CS0 ; P24_4 - SPIB_CS1 ; P25_0 - SPI_IO0 ; P25_1 - SPI_IO1 ; P25_2 - SPI_IO2 ; P25_3 - SPI_IO3 ; P25_4 - SPIB_IO0 ; P25_5 - SPIB_IO1 ; P25_6 - SPIB_IO2 ; P25_7 - SPIB_IO3 ; ; Script arguments: ; ; DO cytvii-spi [PREPAREONLY] [CPU=] [DUALPORT=0|1] ; ; PREPAREONLY only declares flash but does not execute flash programming ; ; CPU= selects CPU derivative ; ; DUALPORT=0|1 default value is 0 (disabled). ; ; Example: ; ; DO ~~/demo/arm/flash/cytvii-spi.cmm PREPAREONLY DUALPORT=1 ; ; ; @Chip: CYT4BF8-CM0+ ; @Board: CYTVII-B-H-8M ; @Author: JIM ; @Keywords: ARM, Cortex-M0+ ; @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only ; -------------------------------------------------------------------------------- ; $Id: cytvii-spi.cmm 12207 2023-06-13 23:55:13Z jjeong $ &SMIF_BASE=0x40420000 ;smif0=0x40420000, smif1=0x40430000 ;&SMIF_MODE="OCTAL_DDR" ;if the SPI AHB XIP is for the octal ddr mode, then the flash contents should be written with the wordSWAP. PRIVATE ¶meters ENTRY %LINE ¶meters PRIVATE ¶m_prepareonly ¶m_cpu ¶m_dualport ¶m_prepareonly=(STRing.SCAN(STRing.UPpeR("¶meters"),"PREPAREONLY",0)!=-1) ¶m_cpu=STRing.SCANAndExtract(STRing.UPpeR("¶meters"),"CPU=","") ¶m_dualport=STRing.SCANAndExtract(STRing.UPpeR("¶meters"),"DUALPORT=","0") ; -------------------------------------------------------------------------------- ; initialize and start the debugger RESet SYStem.RESet SYStem.CPU CYT4BF8-CM0+ SYStem.CONFIG.DEBUGPORTTYPE JTAG IF hardware.COMBIPROBE()||hardware.UTRACE() ( SYStem.CONFIG.CONNECTOR MIPI20T ) SYStem.Option.DUALPORT ON SYStem.MemAccess DAP SYStem.JtagClock 10MHz Trace.DISable Break.RESet SYStem.Up ; ------------------------------------------------------------------------------ ; clk enable GOSUB FLL_100MHz_SETUP PER.Set.simple ASD:0x40261258 %Long 0x80000110 ; SMIF clock increase around 30Mhz (Enable SYSCLK_HF6 and set FLL/2) ; ------------------------------------------------------------------------------ ; pin mux setting (alternative function setting) GOSUB PIN_MUX ; ------------------------------------------------------------------------------ ; spi controller setting GOSUB SMIF_INIT GOSUB READ_ID_TEST ; ------------------------------------------------------------------------------ ; Flash declaration GOSUB FlashDeclaration "¶m_dualport" ; Flash script ends here if called with parameter PREPAREONLY IF ¶m_prepareonly ENDDO PREPAREDONE ; ------------------------------------------------------------------------------- ; Flash programming example DIALOG.YESNO "Program flash memory?" LOCAL &progflash ENTRY &progflash IF &progflash ( FLASH.ReProgram.ALL IF "&SMIF_MODE"=="OCTAL_DDR" Data.LOAD.auto * /WordSWAP ELSE Data.LOAD.auto * FLASH.ReProgram.off ; Reset device SYStem.Down SYStem.Up ) ENDDO PIN_MUX: ( PER.Set.simple ASD:0x40300180 %Long 0x17171700 ;HSIOM PRT[24] PER.Set.simple ASD:0x40300184 %Long 0x00000017 ;HSIOM PRT[24] PER.Set.simple ASD:0x40300190 %Long 0x17171717 ;HSIOM PRT[25] PER.Set.simple ASD:0x40300194 %Long 0x17171717 ;HSIOM PRT[25] ;GPIO pull up, because of the /HOLD pin PER.Set.simple ASD:0x40310C14 %Long 0x00180000 PER.Set.simple ASD:0x40310C44 %Long 000AAEE0 ;PRT[24] PER.Set.simple ASD:0x40310C94 %Long 0x00CC0000 PER.Set.simple ASD:0x40310CC4 %Long 0xAAEEAAEE RETURN ) SMIF_INIT: ( PER.Set.simple A:&SMIF_BASE+0x000 %Long 0x0300 ;base->unCTL.u32Register PER.Set.simple A:&SMIF_BASE+0x080 %Long 0x0000 ;base->unTX_DATA_FIFO_CTL PER.Set.simple A:&SMIF_BASE+0x0C0 %Long 0x0000 ;base->unRX_DATA_MMIO_FIFO_CTL PER.Set.simple A:&SMIF_BASE+0x7C8 %Long 0x0000 ;base->unINTR_MASK PER.Set.simple A:&SMIF_BASE+0x800 %Long 0x0000 ;base->DEVICE0[idx].unCTL PER.Set.simple A:&SMIF_BASE+0x880 %Long 0x0000 ;base->DEVICE1[idx].unCTL PER.Set.simple A:&SMIF_BASE+0x000 %Long 0x3010 PER.Set.simple A:&SMIF_BASE+0x800 %Long 0x0001 ;base->DEVICE0[idx].unCTL PER.Set.simple A:&SMIF_BASE+0x880 %Long 0x0201 ;base->DEVICE1[idx].unCTL PER.Set.simple A:&SMIF_BASE+0x808 %Long 0x60000000 ; ahb address PER.Set.simple A:&SMIF_BASE+0x80C %Long 0xF8000000 ; ahb size mask, 0x7FFFFFF 8*16MB PER.Set.simple A:&SMIF_BASE+0x820 %Long 0x3 ;4Bytes addr mode PER.Set.simple A:&SMIF_BASE+0x840 %Long 0x40000013 ;read command & 1bit cmd PER.Set.simple A:&SMIF_BASE+0x844 %Long 0x0<<16. ; 1bit addr PER.Set.simple A:&SMIF_BASE+0x848 %Long 0x0 PER.Set.simple A:&SMIF_BASE+0x84C %Long 0x00000000 ;0 dummy cycles PER.Set.simple A:&SMIF_BASE+0x850 %Long 0x0<<16. ; 1bit data PER.Set.simple A:&SMIF_BASE+0x100 %Long Data.Long(A:&SMIF_BASE+0x100)&~0x80000000 ;disable cache for ahb address PER.Set.simple A:&SMIF_BASE+0x800 %Long 0x80000001 ;enable PER.Set.simple A:&SMIF_BASE+0x000 %Long 0x80003011 ;enable AHB ; GOSUB S25FL256_QUADIO_READ_1_4_4 RETURN ) READ_ID_TEST: ( PER.Set.simple A:&SMIF_BASE+0x000 %Long Data.Long(A:&SMIF_BASE)&~0x1 //MMIO enable, AHB disable PER.Set.simple A:&SMIF_BASE+0x50 %Long 0x0010009f ;readid command PER.Set.simple A:&SMIF_BASE+0x50 %Long 0x02180003 ;read 4bytes, 0x2:RX_COUNT[26:24], 1:cs0[23:20], 0x8:last[19], 03:4Bytes read[15:0] GOSUB READ_SMIF_FIFO ENTRY &temp PRINT "1st 0x" (&temp)&0xFF " (Manufacturer)" PRINT "2nd 0x" (&temp>>8.)&0xFF " (Device ID)" PRINT "3rd 0x" (&temp>>16.)&0xFF PRINT "4th 0x" (&temp>>24.)&0xFF GOSUB SMIF_INIT RETURN ) READ_SMIF_FIFO: ( &bkup_pc=Register(pc) Register.Set R6 &SMIF_BASE Data.Assemble ST:0x28040000 movs r0,#0xD8 Data.Assemble , ldr r0,[r6,r0] Data.Assemble , b 0x28040000 Register.Set PC 0x28040000 Step 3. &rdata=Register(r0) //print "read: 0x" &rdata Register.Set PC &bkup_pc RETURN &rdata ) FlashDeclaration: ( PRIVATE &FlashSize &FlashDriver &FlashBaseAddr PARAMETERS &DualPort FLASH.RESet &FlashDriver="snor_cysmif.bin" &FlashSize=0x2000000 ;32Mbytes (256MBits) &FlashBaseAddr=0x60000000 ;SPI AHB base address FLASH.Create 2. &FlashBaseAddr++(&FlashSize-0x1) 0x10000 TARGET2 Byte ;for Cypress S25FL256 IF "&DualPort"=="0" FLASH.TARGET2 0x28001000 0x28003000 0x2000 ~~/demo/arm/flash/byte/&FlashDriver ELSE FLASH.TARGET2 0x28001000 E:0x28003000 0x2000 ~~/demo/arm/flash/byte/&FlashDriver /DualPort ; Read FLASH Manufacturer and Device ID SILENT.FLASH.SPI.CMD 2. 0x9F /READ 0x4 vm:0x0 IF (Data.Long(vm:0)&0xFFFF)!=0x0201 //S25FL256 id code ( PRINT "We expect the id code 0x0201 but we got the id 0x" %Hex Data.Long(vm:0x0)&0xFFFF FLASH.Delete 2. ENDDO ) FLASH.List RETURN ) ; -------------------------------------------------------------------------------- ; subroutines CM0_CLOCK_SETUP: ( GOSUB FLL_100MHz_SETUP ; CLK_ROOT_SELECT[0] ; ENABLE = 1 ; DIRECT_MUX = 0 (Select IMO) ; ROOT_DIV = 0 (Transparent mode feed through select) ; ROOT_MUX = 0 (Select PATH0) Data.Set E:0x40261240 %Long (0x1<<31.) ; CPUSS_MEM_CLOCK_CTL.INT_DIV = 0 (-> divide CLK_HF0 by 1 -> CLK_MEM) Data.Set E:0x40201010 %Long 0x0 ; CPUSS_SLOW_CLOCK_CTL.INT_DIV = 0 (-> divide CLK_MEM by 1 -> CLK_SLOW) Data.Set E:0x40201010 %Long 0x0 RETURN ) FLL_100MHz_SETUP: ( PRIVATE &MULT &OUTOUT_DIV &REF_DIV &UPDATE_TOL &LOCK_TOL &LF_PGAIN &LF_IGAIN PRIVATE &CCO_RANGE &SETTLING_COUNT &f ; f_cco = f_ref * mult / ref_div ; f_cco = 8MHz * 250 / 10 = 200MHz &MULT=250. &REF_DIV=10. &f = (8.*&MULT)/&REF_DIV ; CCO ranges: ; 0: 48-64MHz ; 1: 64-85MHz ; 2: 85-113MHz ; 3: 113-150MHz ; 4: 150-200MHz IF &f<=64. &CCO_RANGE=0. ELSE IF &f<=85. &CCO_RANGE=1. ELSE IF &f<=113. &CCO_RANGE=2. ELSE IF &f<=150. &CCO_RANGE=3. ELSE &CCO_RANGE=4. ; f_out = fcco / div = 200MHz/2 = 100MHz &OUTOUT_DIV=1. ; 0: f_out = f_cco, 1: f_out = f_cco/2 &LOCK_TOL=10. &UPDATE_TOL=&LOCK_TOL/2. &LF_PGAIN=5. &LF_IGAIN=2. &SETTLING_COUNT=8. ; 8/8MHz = ~ 1us ; disable FLL Data.Set AD:0x40261538 %Long (0xXXXXXXXX&~(0x3<<28.))|(0x2<<28.) ; BYPASS_SEL = FLL_REF Data.Set AD:0x40261530 %Long 0xXXXXXXXX&~(0x1<<31.) ; FLL_ENABLE = 0 Data.Set AD:0x40261538 %Long 0xXXXXXXXX&~(0x3<<28.) ; BYPASS_SEL = AUTO WAIT 1ms ; CLK_FLL_CONFIG Data.Set AD:0x40261530 %Long (&OUTOUT_DIV<<24.)|(&MULT<<0.) ; CLK_FLL_CONFIG2 Data.Set AD:0x40261534 %Long (&UPDATE_TOL<<24.)|(&LOCK_TOL<<16.)|(&REF_DIV<<0.) ; CLK_FLL_CONFIG3 Data.Set AD:0x40261538 %Long (&SETTLING_COUNT<<8.)|(&LF_PGAIN<<4.)|(&LF_IGAIN<<0.) ; CLK_FLL_CONFIG4 Data.Set AD:0x4026153C %Long (0xXXXXXXXX&~(0x7<<8.))|(&CCO_RANGE<<8.) ; enable CCO Data.Set AD:0x4026153C %Long 0xXXXXXXXX|(0x1<<31.) ; wait for CCO ready WAIT (Data.Long(AD:0x40261540)&(0x1<<2.))==(0x1<<2.) ; enable FLL Data.Set AD:0x40261530 %Long 0xXXXXXXXX|(0x1<<31.) ; wait for FLL locked WAIT (Data.Long(AD:0x40261540)&(0x1<<0.))==(0x1<<0.) ; clear FLL unlocked flag Data.Set AD:0x40261540 %Long (0x1<<1.) ; tbd: is FLL clock stable? RETURN ) S25FL256_QUADIO_READ_1_4_4: ( PER.Set.simple ASD:0x40420800 %Long 0x00000001 ;dis PER.Set.simple ASD:0x40420820 %Long 0x3 ;4Byte address mode PER.Set.simple ASD:0x40420840 %Long 0x400000EC ;read quad io(1-4-4) command PER.Set.simple ASD:0x40420844 %Long 0x2<<16. ;4bit addr PER.Set.simple ASD:0x40420848 %Long 0x0 PER.Set.simple ASD:0x4042084C %Long 0x40000005 ;6 dummy cycles PER.Set.simple ASD:0x40420850 %Long 0x2<<16. ;4bit data PER.Set.simple ASD:0x40420800 %Long 0x80000001 ;en RETURN ) ENDDO