; ---------------------------------------------------------------------------
; prepare_S32K148.cmm
; ---------------------------------------------------------------------------
  PMACRO.EXPLICIT

  ; show path and name of this script (present practice file)
  ECHO ""
  ECHO %COLOR.BLUE "### " OS.PPF() " ###"

; --------------------------------------------------------------------------------
; ETM Trace is only supported by S32K148

; --------------------------------------------------------------------------------
; initialize OFFCHIP trace (ETM, ITM)
  GOSUB Init_PinMux_Clocks

  TPIU.PortSize 4
  TPIU.PortMode Continuous

  DO prepare_clockPLL80.cmm 8.

  ETM.ON

  ENDDO

; --------------------------------------------------------------------------------

Init_PinMux_Clocks:
(
  ; set PinMux and enable Clocks
  ; enable PORTx clocks
  Data.Set AD:0x40065124 %Long Data.Long(AD:0x40065124)|0x40000000  ;PCC_PORTA.CGC=1 clock enable
  Data.Set AD:0x40065128 %Long Data.Long(AD:0x40065128)|0x40000000  ;PCC_PORTB.CGC=1 clock enable
  Data.Set AD:0x4006512C %Long Data.Long(AD:0x4006512C)|0x40000000  ;PCC_PORTC.CGC=1 clock enable
  Data.Set AD:0x40065130 %Long Data.Long(AD:0x40065130)|0x40000000  ;PCC_PORTD.CGC=1 clock enable
  Data.Set AD:0x40065134 %Long Data.Long(AD:0x40065134)|0x40000000  ;PCC_PORTE.CGC=1 clock enable

  ; pad configuration
  ; due to the routing on the EVB the timing is not trivial to handle
  ; for uTrace/Combiprobe reducing the drive strength of the CLK line showed good results
  ; for AutoFocus the drive strength must be high due to the termination
  PRIVATE &dsClk &dsData
  &dsClk=(0x0<<6.)  ; drive strength=LOW
  &dsData=(0x1<<6.) ; drive strength=HIGH
  ; TraceClk
  ; Data.Set AD:0x4004B008 %Long 0x00000600|&dsClk  ; PTC2
  Data.Set AD:0x4004C040 %Long 0x00000600|&dsClk    ; PTD16
  ; TraceD0
  Data.Set AD:0x4004C000 %Long 0x00000500|&dsData   ; PTD0
  ; Data.Set AD:0x4004C01C %Long 0x00000600|&dsData ; PTD7
  ; TraceD1
  ; Data.Set AD:0x4004C030 %Long 0x00000400|&dsData ; PTD12
  Data.Set AD:0x4004D010 %Long 0x00000200|&dsData   ; PTE4
  ; TraceD2
  Data.Set AD:0x4004C02C %Long 0x00000400|&dsData   ; PTD11
  ; Data.Set AD:0x4004C040 %Long 0x00000300|&dsData ; PTD16
  ; TraceD3
  ; Data.Set AD:0x4004C028 %Long 0x00000400|&dsData ; PTD10
  Data.Set AD:0x4004C03C %Long 0x00000300|&dsData   ; PTD15

  ; select TRACECLK_SEL=CORE
  Data.Set AD:0x40048004 %Long Data.Long(AD:0x40048004)&~0x1000 ; SIM_CHIPCTL.TRACECLK_SEL = CoreClock
  ; divide trace clock = input clock
  Data.Set AD:0x40048068 %Long Data.Long(AD:0x40048068)&~0x10000000 ; SIM_CLKDIV4.TRACEDIVEN = disable
  Data.Set AD:0x40048068 %Long 0x00000000;                          ; SIM_CLKDIV4.TRACEDIV   = 1
  Data.Set AD:0x40048068 %Long 0x10000000;                          ; SIM_CLKDIV4.TRACEDIVEN = enable

  ; optional initialize clocks
  ; GOSUB ClockInitHSI60
  ; note does not reliable on S32K148EVB
  ; GOSUB ClockInitPll112
  GOSUB ClockInitPll80
  RETURN
)


ClockInitPll80:
(
  ; ---------------------------------------------------------------------------
  ; Enable SIRC (SlowIRC)
  ;
  ; SCG_SIRCCSR .SIRCEN=1, SlowIRC=enable
  Data.Set AD:0x40064200 %Long Data.Long(AD:0x40064200)|0x1

  SCREEN.WAIT (Data.Long(AD:0x40064200)&(1<<24.))!=0 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot start SIRC!"
    STOP
    ENDDO
  )

  ; ---------------------------------------------------------------------------
  ; Switch to SIRC
  ;
  ; RCCR.SCS = SIRC
  Data.Set AD:0x40064014 %Long (Data.Long(AD:0x40064014)&~(0xf<<24.))|(0x2<<24.) ; SCG_RCCR.SCS = SIRC_CLK Slow IRC

  ; VCCR.SCS = SIRC
  Data.Set AD:0x40064018 %Long (Data.Long(AD:0x40064018)&~(0xf<<24.))|(0x2<<24.) ; SCG_VCCR.SCS = SIRC_CLK Slow IRC

  ; HCCR.SCS = SIRC
  Data.Set AD:0x4006401C %Long (Data.Long(AD:0x4006401C)&~(0xf<<24.))|(0x2<<24.) ; SCG_HCCR:SCS = reserved !!!!

  ; CLKOUTCNFG.CLOCKOUTSEL = SIRC
  Data.Set AD:0x40064020 %Long (Data.Long(AD:0x40064020)&~(0xf<<24.))|(0x2<<24.) ; SCG_CLKOUTCNFG = SIRC_CLK Slow IRC

  WAIT (Data.Long(AD:0x40064010)&(0xf<<24.))==(0x2<<24.) 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot switch to SIRC!"
    STOP
    ENDDO
  )

  ; ---------------------------------------------------------------------------
  ; System OSC init (crystal)
  ; S32K148EVB crystal clock = 8 MHz
  ;
  ; SCG_SOSCCSR.SOSCEN = 0 System OSC disable
  Data.Set AD:0x40064100 %Long Data.Long(AD:0x40064100)&~0x1

  ; SOSCCFG.Range = 8-32MHz, ERREFS=Internal
  Data.Set AD:0x40064108 %Long 0x34 ;

  ; SCG_SOSCCSR.SOSCEN = 0 System OSC enable
  Data.Set AD:0x40064100 %Long Data.Long(AD:0x40064100)|0x1

  SCREEN.WAIT (Data.Long(AD:0x40064100)&(1<<24.))!=0 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot start SOSC!"
    STOP
    ENDDO
  )

  ; ---------------------------------------------------------------------------
  ; System PLL and core divider init

  ; SCG_SPLLCSR.SPLLEN = 0  System PLL disable
  Data.Set AD:0x40064600 %Long Data.Long(AD:0x40064600)&~0x1

  ; SCG_SPLLCFG.MULT = 40-16 = 24 (PLL frequency = 320 MHz)
  Data.Set AD:0x40064608 %Long ((40.-16.)<<16.)

  ; SCG_SPLLDIV.SPLLDIV2 = 4, .SPLLDIV1 = disable
  Data.Set AD:0x40064604 %Long 0x00000300

  ; SCG_SPLLCSR.SPLLEN = 1  System PLL enable
  Data.Set AD:0x40064600 %Long Data.Long(AD:0x40064600)|0x1

  ; wait until PLL is ready
  SCREEN.WAIT (Data.Long(AD:0x40064600)&(1<<24.))!=0 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot start PLL!"
    STOP
    ENDDO
  )

  ; ---------------------------------------------------------------------------
  ; Switch to System PLL
  ;
  ; SCG_RCCR .SCS=SPLL_CLK, DIVCORE=2, DIVBUS=2, DIVSLOW=3
  ;Data.Set AD:0x40064014 %Long (Data.Long(AD:0x40064014)&~(0xf<<24.))|(0x6<<24.)
  Data.Set AD:0x40064014 %Long 0x06010012

  ; SCG_HCCR .SCS=SPLL_CLK, DIVCORE=2, DIVBUS=2, DIVSLOW=3
  ;Data.Set AD:0x4006401C %Long (Data.Long(AD:0x4006401C)&~(0xf<<24.))|(0x6<<24.)
  Data.Set AD:0x4006401C %Long 0x06010012

  ; SCG_CLKOUTCNFG .CLOCKOUTSEL=PLL
  ;Data.Set AD:0x40064020 %Long (Data.Long(AD:0x40064020)&~(0xf<<24.))|(0x6<<24.)
  Data.Set AD:0x40064020 %Long 0x06000000

  WAIT (Data.Long(AD:0x40064010)&(0xf<<24.))==(0x6<<24.) 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot switch to PLL!"
    STOP
    ENDDO
  )

  RETURN
)



ClockInitHSI60:
(
  ; SIRCCSR.EN = 1 - enable SIRC
  Data.Set AD:0x40064200 %Long Data.Long(AD:0x40064200)|0x1
  SCREEN.WAIT (Data.Long(AD:0x40064200)&(1<<24.))!=0 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot start SIRC!"
    STOP
    ENDDO
  )
  ; switch to SIRC
  ; RCCR.SCS = SIRC
  Data.Set AD:0x40064014 %Long (Data.Long(AD:0x40064014)&~(0xf<<24.))|(0x2<<24.)
  ; VCCR.SCS = SIRC
  Data.Set AD:0x40064018 %Long (Data.Long(AD:0x40064018)&~(0xf<<24.))|(0x2<<24.)
  ; HCCR.SCS = SIRC
  Data.Set AD:0x4006401C %Long (Data.Long(AD:0x4006401C)&~(0xf<<24.))|(0x2<<24.)
  ; CLKOUTCNFG.CLOCKOUTSEL = SIRC
  Data.Set AD:0x40064020 %Long (Data.Long(AD:0x40064020)&~(0xf<<24.))|(0x2<<24.)

  WAIT (Data.Long(AD:0x40064010)&(0xf<<24.))==(0x2<<24.) 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot switch to SIRC!"
    STOP
    ENDDO
  )

  ; FIRCCSR.EN = 0 - disable FIRC
  Data.Set AD:0x40064300 %Long Data.Long(AD:0x40064300)&~0x1
  ; FIRCCFG = 60MHz
  Data.Set AD:0x40064308 %Long 0x3
  ; FIRCCSR.EN = 1 - enable FIRC
  Data.Set AD:0x40064300 %Long Data.Long(AD:0x40064300)|0x1

  SCREEN.WAIT (Data.Long(AD:0x40064300)&(1<<24.))!=0 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot start FIRC!"
    STOP
    ENDDO
  )

  ; switch to FIRC
  ; RCCR.SCS = FIRC
  Data.Set AD:0x40064014 %Long (Data.Long(AD:0x40064014)&~(0xf<<24.))|(0x3<<24.)
  ; HCCR.SCS = FIRC
  Data.Set AD:0x4006401C %Long (Data.Long(AD:0x4006401C)&~(0xf<<24.))|(0x3<<24.)
  ; CLKOUTCNFG.CLOCKOUTSEL = FIRC
  Data.Set AD:0x40064020 %Long (Data.Long(AD:0x40064020)&~(0xf<<24.))|(0x3<<24.)

  WAIT (Data.Long(AD:0x40064010)&(0xf<<24.))==(0x3<<24.) 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot switch to FIRC!"
    STOP
    ENDDO
  )

  RETURN
)

ClockInitPll112:
(
  ; SIRCCSR.EN = 1 - enable SIRC
  Data.Set AD:0x40064200 %Long Data.Long(AD:0x40064200)|0x1
  SCREEN.WAIT (Data.Long(AD:0x40064200)&(1<<24.))!=0 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot start SIRC!"
    STOP
    ENDDO
  )
  ; switch to SIRC
  ; RCCR.SCS = SIRC
  Data.Set AD:0x40064014 %Long (Data.Long(AD:0x40064014)&~(0xf<<24.))|(0x2<<24.)
  ; VCCR.SCS = SIRC
  Data.Set AD:0x40064018 %Long (Data.Long(AD:0x40064018)&~(0xf<<24.))|(0x2<<24.)
  ; HCCR.SCS = SIRC
  Data.Set AD:0x4006401C %Long (Data.Long(AD:0x4006401C)&~(0xf<<24.))|(0x2<<24.)
  ; CLKOUTCNFG.CLOCKOUTSEL = SIRC
  Data.Set AD:0x40064020 %Long (Data.Long(AD:0x40064020)&~(0xf<<24.))|(0x2<<24.)

  WAIT (Data.Long(AD:0x40064010)&(0xf<<24.))==(0x2<<24.) 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot switch to SIRC!"
    STOP
    ENDDO
  )

  ; SOSCCSR.EN = 0 - disalbe SOSC
  Data.Set AD:0x40064100 %Long Data.Long(AD:0x40064100)&~0x1
  ; SOSCCFG.Range = 8-32MHz, ERREFS=Internal
  Data.Set AD:0x40064108 %Long 0x34
  ; SOSCCSR.EN = 1 - enable SOSC
  Data.Set AD:0x40064100 %Long Data.Long(AD:0x40064100)|0x1
  SCREEN.WAIT (Data.Long(AD:0x40064100)&(1<<24.))!=0 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot start SOSC!"
    STOP
    ENDDO
  )

  ; SPLLCSR.EN = 0 - disalbe PLL
  Data.Set AD:0x40064600 %Long Data.Long(AD:0x40064600)&~0x1
  ; SPLLCFG.MULT = 224MHz/8MHz -16. = 28. - 16.
  Data.Set AD:0x40064608 %Long ((28.-16.)<<16.)
  ; SPLLCSR.EN = 1 - enable PLL
  Data.Set AD:0x40064600 %Long Data.Long(AD:0x40064600)|0x1

  SCREEN.WAIT (Data.Long(AD:0x40064600)&(1<<24.))!=0 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot start PLL!"
    STOP
    ENDDO
  )

  ; switch to PLL
  ; RCCR.SCS = PLL
  Data.Set AD:0x40064014 %Long (Data.Long(AD:0x40064014)&~(0xf<<24.))|(0x6<<24.)
  ; HCCR.SCS = PLL
  Data.Set AD:0x4006401C %Long (Data.Long(AD:0x4006401C)&~(0xf<<24.))|(0x6<<24.)
  ; CLKOUTCNFG.CLOCKOUTSEL = PLL
  Data.Set AD:0x40064020 %Long (Data.Long(AD:0x40064020)&~(0xf<<24.))|(0x6<<24.)

  WAIT (Data.Long(AD:0x40064010)&(0xf<<24.))==(0x6<<24.) 1.s
  IF TIMEOUT()
  (
    PRINT %ERROR "Cannot switch to PLL!"
    STOP
    ENDDO
  )

  RETURN
)




