;@Id: boot.tpl#6 @ ;============================================================================= ; FILENAME: boot.asm ; VERSION: 3.20 ; DATE: 10 October 2002 ; ; DESCRIPTION: ; M8C Boot Code from Reset. ; ; Copyright (C) Cypress MicroSystems 2001, 2002. All rights reserved. ; ; NOTES: ; PSoC Designer's Device Editor uses a template file, BOOT.TPL, located in ; the project's root directory to create BOOT.ASM. Any changes made to ; BOOT.ASM will be overwritten every time the project is generated; therfore ; changes should be made to BOOT.TPL not BOOT.ASM. Care must be taken when ; modifying BOOT.TPL so that replacement strings (such as @PROJECT_NAME) ; are not accidentally modified. ; ; The start of _main is at a fixed location so care must be taken when adding ; user code for any interrupts within boot.asm. If too much code is added,the ; end of BOOT.ASM will extend into _main and cause a linker error. The safest ; way to add code for an interrupt is to LCALL or LJMP to a normal routine ; located in a seperate file that contains the desired additional interrupt ; code. ;============================================================================= include ".\lib\psoc_defrost_GlobalParams.inc" include "m8c.inc" include "m8ssc.inc" ;----------------------------------------------------------------------------- ; Optimization flags ;----------------------------------------------------------------------------- C_LANGUAGE_SUPPORT: equ 1 ;Set to 0 to optimize for ASM only ;----------------------------------------------------------------------------- ; The following equate is required for proper operation. Reseting its value ; is discouraged. ;----------------------------------------------------------------------------- WAIT_FOR_32K: equ 1 ; Wait for Crystal to start before allowing main() ; Is effective only if the crystal oscillator is ; selected. If the designer choses to not WAIT, ; then the ECO and PLL_Lock process must be taken ; care of with user code. ;----------------------------------------------------------------------------- ; Export Declarations ;----------------------------------------------------------------------------- export __Start export __Exit export __bss_start export __lit_start export __idata_start export __data_start export __func_lit_start export __text_start ;----------------------------------------------------------------------------- ; Interrupt Vector Table ;----------------------------------------------------------------------------- ; ; Interrupt vector table entries are 4 bytes long and contain the code ; that services the interrupt (or causes it to be serviced). ; ;----------------------------------------------------------------------------- AREA TOP(ROM, ABS) org 0 ;Reset Interrupt Vector jmp __Start ;First instruction executed following a Reset org 04h ;Supply Monitor Interrupt Vector halt ;Stop execution if power falls too low reti org 08h ;PSoC Block DBA00 Interrupt Vector // call void_handler reti org 0Ch ;PSoC Block DBA01 Interrupt Vector // call void_handler reti org 10h ;PSoC Block DBA02 Interrupt Vector // call void_handler reti org 14h ;PSoC Block DBA03 Interrupt Vector ljmp Timer32_1INT reti org 18h ;PSoC Block DCA04 Interrupt Vector // call void_handler reti org 1Ch ;PSoC Block DCA05 Interrupt Vector // call void_handler reti org 20h ;PSoC Block DCA06 Interrupt Vector // call void_handler reti org 24h ;PSoC Block DCA07 Interrupt Vector // call void_handler reti org 28h ;Analog Column 0 Interrupt Vector // call void_handler reti org 2Ch ;Analog Column 1 Interrupt Vector // call void_handler reti org 30h ;Analog Column 2 Interrupt Vector // call void_handler reti org 34h ;Analog Column 3 Interrupt Vector // call void_handler reti org 38h ;GPIO Interrupt Vector // call void_handler reti org 3Ch ;Sleep Timer Interrupt Vector // call void_handler reti ;----------------------------------------------------------------------------- ; Start of Execution ; CPU is operating at 3 MHz, change to 12 MHz ; IO Bank is Bank0 ;----------------------------------------------------------------------------- org 40h __Start: mov [bSSC_KEY1] ,0 ;Lockout Flash and Supervisiory operations mov [bSSC_KEYSP],0 ;(especially after a Software Reset Supervisory op) mov A,__bss_end ;Set top of stack to end of used RAM IF (COMM_RX_PRESENT) cmp A,40h jnc .SetStack ; Stack must start at or above 40h mov A,40h ENDIF ;(COMM_RX_PRESENT) .SetStack: swap SP,A ;------------------------------------------------------------------------- ; Set clock and BandGap trim if the operating voltage is 3.3V. On power ; up, 5V is loaded, so this is only needed for 3.3V operation. ;------------------------------------------------------------------------- IF (SUPPLY_VOLTAGE) ; 1 means 5.0V ELSE ; 0 means 3.3V mov [bSSC_TABLE_TableId], 1 ; Point to the Trim table SSC_Action TABLE_READ ; Perform a table read supervisor call M8C_SetBank1 mov A, [OSCILLATOR_TRIM_3V] mov reg[IMO_TR], A ; Load the 3V trim oscillator setting mov A, [VOLTAGE_TRIM_3V] mov reg[BDG_TR], A ; Load the bandgap trim setting for 3V M8C_SetBank0 ENDIF ;(SUPPLY_VOLTAGE) ;------------------------------------------------------------------------- ; If the user has requested the Crystal oscillator then turn it on and ; wait for it to stabilize and the system to switch over to it. The wait ; will be one sleep timer period, approximately 1 second. ;------------------------------------------------------------------------- IF (SELECT_32K & WAIT_FOR_32K) ; This will be used for XTAL and PLL startup, and is cancelled later on. mov reg[INT_MSK0], INT_MSK0_Sleep ; Only turn on Sleep interrupt mov reg[INT_MSK1], 0 ; Some could be on if s/w reset took place M8C_SetBank1 mov reg[PRT1DM0],00h ; P1[0] & P1[1] Drive Mode to High Z because mov reg[PRT1DM1],03h ; LoadConfigInit not run yet. IF (PLL_MODE) mov reg[ECO_TR],0Fh ; adjust ECO bias if in PLL lock mode ENDIF ;(PLL_MODE) M8C_SetBank0 M8C_ClearWDTAndSleep ; Reset the sleep timer M8C_SetBank1 mov reg[OSC_CR0], (OSC_CR0_Sleep_1Hz | SELECT_32K_JUST | OSC_CR0_CPU_12MHz) M8C_SetBank0 mov reg[INT_VC],0 ; Clear all pending interrupts .WaitFor1s: mov A, reg[INT_VC] ; read Interrupt Vector jz .WaitFor1s ; TimeOut occurs on Sleep Timer 1s M8C_SetBank1 mov reg[ILO_TR], 40h ; turn off the ILO, 32K is now from the ECO M8C_SetBank0 ELSE ;!(SELECT_32K & WAIT_FOR_32K) mov reg[INT_MSK0], 0 ; Turn off all interrupts mov reg[INT_MSK1], 0 ; some could be on if s/w reset took place M8C_SetBank1 mov reg[OSC_CR0], (OSC_CR0_Sleep_1Hz | OSC_CR0_CPU_12MHz) M8C_SetBank0 M8C_ClearWDTAndSleep ; Reset the sleep timer ENDIF ;(SELECT_32K & WAIT_FOR_32K) ;------------------------------------------------------------------------- ; Crystal is now fully operational. ;------------------------------------------------------------------------- IF (PLL_MODE) IF (SELECT_32K) M8C_SetBank1 mov reg[OSC_CR0], (PLL_MODE_JUST | OSC_CR0_Sleep_64Hz | SELECT_32K_JUST | OSC_CR0_CPU_12MHz) M8C_SetBank0 M8C_ClearWDTAndSleep ; Reset the sleep timer mov reg[INT_VC],0 ; Clear all pending interrupts .WaitFor16ms: mov A, reg[INT_VC] ; read Interrupt Vector jz .WaitFor16ms ; TimeOut occurs on Sleep Timer 16ms ELSE ;!(SELECT_32K) ERROR_PSoC Using the PLL without the Crystal is invalid. ENDIF ;(SELECT_32K) ENDIF ;(PLL_MODE) ;------------------------------------------------------------------------- ; default CT block RTopMux to OUT and RBotMux to AGND ;------------------------------------------------------------------------- mov reg[ACA00CR0],05h mov reg[ACA01CR0],05h mov reg[ACA02CR0],05h mov reg[ACA03CR0],05h ;------------------------------------------------------------------------- ; All the user selections and UserModule selections are now loaded. ; !!! Except CPU frequency !!!! (CPU is runing at 12 MHz) ;------------------------------------------------------------------------- Config: lcall LoadConfigInit ; Configure PSoC blocks per Dev Editor IF (C_LANGUAGE_SUPPORT) call InitCRunTime ; Initialize for C language ENDIF ;(C_LANGUAGE_SUPPORT) mov reg[INT_VC],0 ; Clear any pending interrupts which may ; have been set during the boot process. ;------------------------------------------------------------------------- ; We always enable LVD / Voltage Monitoring by default ;------------------------------------------------------------------------- M8C_EnableIntMask INT_MSK0, INT_MSK0_VoltageMonitor ; LVD only IF (SWITCH_MODE_PUMP ^ 1) ; !!! This value is 1 if the SMP is disabled !!! ;------------------------------------------------------------------------- ; Pump is enabled, and customer requests it to work. Vcc is currently at ; or is slewing towards customer's requested Vcc. ;------------------------------------------------------------------------- IF (CPU_CLOCK_JUST ^ OSC_CR0_CPU_24MHz) ; Clock is not 24MHz ;------------------------------------------------------------------------- ; < 24 MHz operation is requested. Any reasonable Vcc is OK. ;------------------------------------------------------------------------- ELSE ;!(CPU_CLOCK_JUST ^ OSC_CR0_CPU_24MHz) ;------------------------------------------------------------------------- ; 24 MHz operation is requested. Requires 5V operation. ; Only 07h setting is valid (04h | 03h) ;------------------------------------------------------------------------- IF (SUPPLY_VOLTAGE) ;------------------------------------------------------------------------- ; 4.19 thru 5.0 V is selected ;------------------------------------------------------------------------- IF (TRIP_VOLTAGE ^ 07h) ERROR_PSoC TRIP_VOLTAGE must be 4.64V(5.00V) for 24 MHz operation ENDIF ;(TRIP_VOLTAGE ^ 07h) ELSE ;!(SUPPLY_VOLTAGE) ERROR_PSoC Only valid SMP setting is 5.0 V ENDIF ;(SUPPLY_VOLTAGE) ENDIF ;(CPU_CLOCK_JUST ^ OSC_CR0_CPU_24MHz) ;------------------------------------------------------------------------- ; But must wait for the SMP to slew from 3.1 to 5 Volts, if SMP selected. ;------------------------------------------------------------------------- M8C_EnableIntMask INT_MSK0, INT_MSK0_Sleep IF (SUPPLY_VOLTAGE) M8C_SetBank1 mov reg[OSC_CR0], OSC_CR0_Sleep_512Hz M8C_SetBank0 M8C_ClearWDTAndSleep ; Reset the sleep timer mov reg[INT_VC],0 ; Clear all pending interrupts .WaitFor2ms: mov A, reg[INT_VC] ; read Interrupt Vector jz .WaitFor2ms ; TimeOut occurs on Sleep Timer 2ms ENDIF ;(SUPPLY_VOLTAGE) ;------------------------------------------------------------------------- ; Vcc is Stable and Correct, at 5V range. Setup LVD for Brownout ;------------------------------------------------------------------------- M8C_EnableIntMask INT_MSK0, INT_MSK0_VoltageMonitor ; LVD only ELSE ;!(SWITCH_MODE_PUMP ^ 1) ; SMP is disabled ;------------------------------------------------------------------------- ; Normal operation with no pump. ;------------------------------------------------------------------------- M8C_EnableIntMask INT_MSK0, INT_MSK0_VoltageMonitor ; LVD only IF (CPU_CLOCK_JUST ^ OSC_CR0_CPU_24MHz) ;------------------------------------------------------------------------- ; < 24 MHz operation is requested. Any reasonable Vcc is OK. ;------------------------------------------------------------------------- ELSE ;!(CPU_CLOCK_JUST ^ OSC_CR0_CPU_24MHz) ;------------------------------------------------------------------------- ; 24 MHz operation is requested. Requires 5V operation. ;------------------------------------------------------------------------- IF (SUPPLY_VOLTAGE) ; Set the CPU speed to 93.75kHz in order to slow down INT_VC read M8C_SetBank1 mov reg[OSC_CR0], (SELECT_32K_JUST | PLL_MODE_JUST | SLEEP_TIMER_JUST | OSC_CR0_CPU_93d7kHz) .LVDLoop: M8C_SetBank1 mov reg[VLT_CR], 00h ; LVD at 2.95 V (Power Good if >2.95V) M8C_SetBank0 mov reg[INT_VC],0 ; Clear LVD interrupt M8C_SetBank1 mov reg[VLT_CR], 07h ; Force LVD at 4.64 V (Power Not good if <4.64V) M8C_SetBank0 ; Must wait 10 usec before reading INT_VC mov A, reg[INT_VC] jz .GoodVcc jmp .LVDLoop ; Wait for good Vcc .GoodVcc: ;------------------------------------------------------------------------- ; Leave LVD at 4.64 V (Required, no exceptions) ;------------------------------------------------------------------------- ELSE ;!(SUPPLY_VOLTAGE) ERROR_PSoC 24 MHz at other than 5V is invalid. ENDIF ;(SUPPLY_VOLTAGE) ENDIF ;(CPU_CLOCK_JUST ^ OSC_CR0_CPU_24MHz) ENDIF ;(SWITCH_MODE_PUMP ^ 1) ;------------------------------------------------------------------------- ; Disable the Sleep interrupt that was used for timing above. ;------------------------------------------------------------------------- M8C_DisableIntMask INT_MSK0, INT_MSK0_Sleep ;------------------------------------------------------------------------- ; Everything has started OK. Now select requested CPU & sleep frequency. ;------------------------------------------------------------------------- M8C_SetBank1 mov reg[OSC_CR0], (SELECT_32K_JUST | PLL_MODE_JUST | SLEEP_TIMER_JUST | CPU_CLOCK_JUST) M8C_SetBank0 ;------------------------------------------------------------------------- ; Global Interrupt are NOT enabled, this should be done in main(). ; LVD is set but will not occur unless Global Interrupts are enabled. ; Global Interrupts should be as soon as possible in main(). ;------------------------------------------------------------------------- lcall _main ; Call main __Exit: jmp __Exit ; Wait here till power is turned off ;----------------------------------------------------------------------------- ; C Runtime Environment Initialization ; The following code is conditionally assembled. ;----------------------------------------------------------------------------- IF (C_LANGUAGE_SUPPORT) InitCRunTime: ;----------------------------- ; clear bss segment ;----------------------------- mov A,0 mov [__r0],<__bss_start BssLoop: cmp [__r0],<__bss_end jz BssDone mvi [__r0],A jmp BssLoop BssDone: ;---------------------------- ; copy idata to data segment ;---------------------------- mov A,>__idata_start mov X,<__idata_start mov [__r0],<__data_start IDataLoop: cmp [__r0],<__data_end jz IDataDone push A romx mvi [__r0],A pop A inc X adc A,0 jmp IDataLoop IDataDone: ret ENDIF ;(C_LANGUAGE_SUPPORT) ;------------------------------------------------------ ; RAM segments for C CONST, static & global items ;------------------------------------------------------ AREA lit __lit_start: AREA idata __idata_start: AREA func_lit __func_lit_start: AREA psoc_config(rom) __psoc_config_start: ;--------------------------------------------- ; CODE segment for general use ;--------------------------------------------- AREA text(rom) __text_start: ;--------------------------------------------- ; Begin RAM area usage ;--------------------------------------------- AREA data(ram) __data_start: AREA virtual_registers(ram) __virtual_registers_end: ;--------------------------------------------- ; RAM segment for general use ;--------------------------------------------- AREA bss(ram) __bss_start: ;end of file