⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setups12x.c

📁 关于XD256的应用实例,用于汽车电子开发之用
💻 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 + -