📄 setups12x.c
字号:
/*****************************************************
setupS12X.c - Startup and initialization code HCS12X
----------------------------------------------------
Utility functions to setup the HCS12X cores:
- Contains the main entry point of the application
that initializes the PLL and calls the main function
through the standard C startup code.
- Includes a function to setup the XGATE core.
Note: all register declarations are local to this file
to make it more portable
*****************************************************/
#pragma LINK_INFO DERIVATIVE "mc9s12xdp512"
#include "hidef.h" /* this file declares symbols user by the CodeWarrior environment */
#include <string.h>
#include "XGVectors.h" /* XG vector table */
#include "start12.h" /* to call the C-startup code */
#include "setupS12X.h"
#define HCS12_REGS 0x0000 /* HCS12 register space */
#define XGATE_REGS 0x0380 /* XGATE register space */
#define INT_REGS 0x0120 /* S12X INT register space */
/*************************************************************************************/
/* pre-start code: this is the entrypoint the reset vector points to */
#define COPCTL *((char*)(HCS12_REGS+0x3c)) // COP Watchdog control register.
#define REFDV *((char*)(HCS12_REGS+0x35)) // reference divider register.
#define SYNR *((char*)(HCS12_REGS+0x34)) // synthesizer loop divider register.
#define CRGFLG *((char*)(HCS12_REGS+0x37)) // CRG flag register.
#define LOCKm 0x08 // lock bit mask
#define CLKSEL *((char*)(HCS12_REGS+0x39)) // CRG clock select register.
#define PLLSELm 0x80 // use PLL for system clocks.
#define OscClk 8000000 // oscillator clock frequency.
#define fEclock 40000000 // final E-clock frequency (PLL).
#define RefClock 8000000 // reference clock used by the PLL.
#define REFDVVal ((OscClk/RefClock)-1) // value for the REFDV register.
#define SYNRVal ((fEclock/RefClock)-1) // value for the SYNR register.
#define FDIV8 0x40 // Enable /8 prescaler.
#if OscClk>12800000
#define FCLKDIVVal ((OscClk/200000/8)+FDIV8) // value for the FCLKDIV register.
#else
#define FCLKDIVVal (OscClk/200000) // value for the FCLKDIV register.
#endif
/*-----------------------------------------------------------------------------------*/
#pragma NO_FRAME
#pragma NO_ENTRY
#pragma NO_EXIT
#pragma CODE_SEG __NEAR_SEG NON_BANKED /* make sure this code is located in non banked */
interrupt void S12X_EntryPoint(void) {
COPCTL = 0; // disable the watchdog & clock monitor timers.
REFDV = REFDVVal; // set the REFDV register.
SYNR = SYNRVal; // set the SYNR register to give us a 40.0 MHz E-clock.
asm nop; // nops required for bug in initial silicon.
asm nop;
asm nop;
asm nop;
while((CRGFLG&LOCKm) == 0); // wait here till the PLL is locked.
CLKSEL |= PLLSELm; // switch the bus clock to the PLL.
asm jmp _Startup
}
#pragma CODE_SEG DEFAULT /* back to the standard segment */
/*************************************************************************************/
#ifdef HCS12X_V4_0 /* copy the XGATE code from ROM to RAM */
/* SetupXGATE: copies the XGATE code from FLASH to RAM and initialize the XGATE vector
base register to point to the XGATE vector table */
extern __near void _FAR_COPY_LOGICAL_GLOBAL_RC(void); /* library routine */
/* used with XGATE_CODE section (see prm file) */
extern char __SEG_START_XGATE_CODE[];
#define XGATE_ROM_CODE_START ((void*)__SEG_START_XGATE_CODE)
extern char __SEG_SIZE_XGATE_CODE[];
#define XGATE_CODE_SIZE ((int)__SEG_SIZE_XGATE_CODE)
extern char __SEG_RELOCATE_TO_XGATE_CODE[];
#define XGATE_RAM_CODE_START ((void*)__SEG_RELOCATE_TO_XGATE_CODE)
/*-----------------------------------------------------------------------------------*/
static void CopyXGateCode(void) {
/* optimized this (void)memcpy(XGATE_RAM_CODE_START, XGATE_ROM_CODE_START, XGATE_CODE_SIZE); */
__asm {
LDX #__SEG_START_XGATE_CODE
LDAB #PAGE(__SEG_START_XGATE_CODE)
LDY #GLOBAL(__SEG_RELOCATE_TO_XGATE_CODE)
LDAA #GLOBAL_PAGE(__SEG_RELOCATE_TO_XGATE_CODE)
JSR _FAR_COPY_LOGICAL_GLOBAL_RC;
DC.W LOGICAL(__SEG_SIZE_XGATE_CODE)
}
}
#endif
/*************************************************************************************
SetupXGATE
The XGATE is initialized according to the recommended sequence as follows:
1. Clear the XGE bit to suppress any incoming service requests.
2. Make sure that no thread is running on the XGATE:
Poll the XGCHID register until it reads $00. Also poll XGDBG and XGSWEIF to make sure
that the XGATE has not been stopped.
3. Set the XGVBR register to the lowest address of the XGATE vector space.
4. Clear all Channel ID flags.
5. Copy XGATE vectors and code into the RAM.
6. Initialize the S12X_INT module.
7. Enable the XGATE by setting the XGE bit.
-------------------------------------------------------------------------------------*/
#define XGMCTL *((char*)(XGATE_REGS+0x00)) // XGATE Module Control Register
#define XGIEm 0x01
#define XGSWEIFm 0x02
#define XGSSm 0x08
#define XGDBGm 0x10
#define XGDBGMm 0x20
#define XGFRZm 0x40
#define XGEm 0x80
#define XGCHID *((char*)(XGATE_REGS+0x02)) // XGATE channel ID register
#define XGVBR *((long*)(XGATE_REGS+0x04)) // XGATE vector base register
#define XGIFa (uint*)(XGATE_REGS+0x08) // address of XGATE interrupt flag regissters
#define XGSWT *((uint*)(XGATE_REGS+0x18)) // XGATE software trigger register
/*-----------------------------------------------------------------------------------*/
void S12X_SetupXGATE(void)
{
uchar x; /* loop counter */
uint *XGIFP; /* used to point to the interrupt flag registers */
XGMCTL = XGDBGMm | XGSWEIFm; /* make sure interrupts to XGate are disabled, not in debug mode & any errors are cleared */
while (XGCHID != 0); /* wait until the current thread is finished */
XGVBR= (long)(void*__far)XGATE_VectorTable; /* set the XGVBR register to its start address */
XGIFP = XGIFa; /* setup pointer to XGate interrupt flag registers */
for (x = 0; x < 8; x++) { /* clear all pending interrupts */
*XGIFP++ = 0xffff;
}
XGSWT = 0xff00; /* clear any pending software triggers */
#ifdef HCS12X_V4_0 //define?
CopyXGateCode(); /* copy the XGATE program code & vector table to the RAM */
#else
/* the XGATE code is already copied by the startup code */
#endif
XGMCTL = XGEm | XGDBGMm | XGSWEIFm | XGIEm; /* enable the XGate module */
} /* end SetupXGATE */
/*************************************************************************************/
#define INT_CFADDR *((char*)(INT_REGS+0x07)) // Interrupt Configurattion Adress Register
#define INT_CFDATA ((char*)(INT_REGS+0x08)) // Interrupt Configurattion Data Registers
#define RQST 0x80 // RQST bit mask
void S12X_SetInterruptPriority(uchar Channel, uchar Priority)
{
INT_CFADDR = (Channel << 1) & 0xf0;
INT_CFDATA[Channel & 0x07] = Priority;
} /* end SetInterruptPriority */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -