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

📄 pid.c

📁 UCSO在三星S3C44B0X CPU上的移植。ejoy it
💻 C
字号:
/* * File:        pid.c * * uC/OS Real-time multitasking kernel for the ARM processor. * * PID board specific functions. * Created by Marco Graziano (marcog@crl.com). * */#include	"ucos.h" #include	"pid.h" #include	"osdefs.h" #pragma		no_check_stack#pragma         no_optimise_crossjump#pragma         no_optimise_multiple_loads#pragma         no_optimise_cse/*  * * Functions defined in this module. * */void	PIDInit(void);		/* called by locore startup code */static int DispatchIRQ(void);	/* called by low-level IRQ trap handler */void	IRQEnable(int);void	IRQDisable(int);void	IRQReset(int);PFV	IRQInstall(int, PFV);static void DispatchFIQ(void);	/* called by low-level FIQ trap handler */void	FIQEnable(int);void	FIQDisable(int);PFV	FIQInstall(int, PFV);static void DispatchSWI(int);	/* called by low-level SWI trap handler */PFV	SWIInstall(int, PFV);void	PutByte(byte);byte	GetByte(void);void	SetLED(uint);/* interrupt registers pointer */static struct INTC *INTCReg = (struct INTC *)INTCREGS;/* 16C551 parallel port registers pointer */static struct PARP *PARPReg = (struct PARP *)PARPREGS;/* 16C551 UART registers pointer */static struct UART *UARTReg = (struct UART *)UARTREGS;/* high-level IRQ handlers */static	PFV	IRQVector[MAXIRQNUM];/* high-level FIQ handlers */static	PFV	FIQVector[MAXFIQNUM];/* high-level SWI handlers */static	PFV	SWIVector[MAXSWINUM];/* INTC masks */static	uint	SavedIRQMask;static	uint	SavedFIQMask;/* * Reset the serial port in the 16C551 controller. */ voidResetPort(void){        /* ---- initialize 16C551 ------------------------------------------ */	UARTReg->Reg2.IER = 0x0;        /* disable interrupts */        UARTReg->LCR = 0x80;            /* enable divisor latch access */        UARTReg->Reg1.DLL = 12;         /* configure divisor latch 9600 bauds */        UARTReg->Reg2.DLM = 0;        UARTReg->LCR = 0x03;            /* disable divisor latch access */                                        /* configure 8 bit data */         UARTReg->Reg3.FCR = 0;          /* disable FIFO */         UARTReg->MCR = 0x0B;            /* set modem control register */                                        /* assert RTS, DTR, interrupt enable */         UARTReg->Reg2.IER = 0x5;        /* enable receive interrupt */}/* * Initialize the PID board and PID support global data. */voidPIDInit(void){	int i;	/* ---- initialize interrupt controller ---------------------------- */	INTCReg->IRQMask = 0x80; 	/* disable interrupts in INTC */	INTCReg->FIQMask = 0x80;	SavedIRQMask = SavedFIQMask = 0x80;        /* ---- initialize 16C551 ------------------------------------------ */	ResetPort(); 	/* ---- soft vectors ---------------------------------------------- */	for (i = 0; i < MAXIRQNUM; i++) 		IRQVector[i] = (PFV)0;	for (i = 0; i < MAXFIQNUM; i++) 		FIQVector[i] = (PFV)0;	for (i = 0; i < MAXSWINUM; i++) 		SWIVector[i] = (PFV)0;	/* ---- install new trap handlers -------------------------------- */	NewIRQ(DispatchIRQ);	NewFIQ(DispatchFIQ); 	NewSWI((PFV)DispatchSWI);  } /* PIDInit *//* * Set and reset PID LEDs. * The general purpose register on the 16C551 parallel port is used to * set and reset LEDs. *  *       *              | bit3 | bit2 | bit1 | bit0 | *               --------------------------- *              | led3 | led2 | led1 | led0 | * */voidSetLED(uint Conf){	Conf = (Conf ^ 0xF) << 4; 	/* complement the configuration and */					/* shift left the LS nibble*/	PARPReg->GPR = Conf; } /* SetLED *//* * IRQ interrupt numbers: * *              0 - serial port *              1 - timer *              2 - parallel port *              3 - expansion slot *              4 - expansion slot *              5 - expansion slot *              6 - expansion slot *              7 - panic (button sw1) *//* * Interrupt service routine dispatcher. * * This is the IRQ handler called when an IRQ trap is taken. */static intDispatchIRQ(void){	extern	uint OSIntNesting;	/* defined in os.c */	extern	void rplev(void);	/* defined in subr.s */	extern	int  OSIntExit(void);	/* defined in os.c */	uint	Mask = 0x0080;	uint	Status;	int	IRQNum = 7;	/* increment nesting counter */	OSIntNesting++;	Status = INTCReg->IRQ.Status;	while (IRQNum >= 0) {		if (Status & Mask) {			/* clear interrupt to allow nesting */			INTCReg->IRQ.Reset = (1 << IRQNum);			/* restore processor level before interrupt occurred */			rplev(); 	/* re-enable interrupts if needed */			/* call registered interrupt handler */			if (IRQVector[IRQNum])				(*(IRQVector[IRQNum]))();			else				; /* spurious interrupt */			break;		}		Mask = Mask >> 1;		IRQNum--;	}	/* call exit routine - return TRUE if a context switch is needed */	return(OSIntExit()); } /* DispatchIRQ */ /* * Enable interrupt request. * * int IRQNum - interrupt request number */voidIRQEnable(int IRQNum){        uint Mask;         /* Get the old INTC mask */        Mask = SavedIRQMask;         /* Set new INTC mask enabling the new IRQ */        Mask = (Mask | (1 << IRQNum)) & 0x7F;        INTCReg->IRQMask = Mask;               /* this register is write only */         /* Save new value in the workspace */        SavedIRQMask = Mask;} /* IRQEnable *//* * Disable interrupt request. * * int IRQNum - interrupt request number */void              IRQDisable(int IRQNum){        uint Mask;         /* Get the old INTC mask */        Mask = SavedIRQMask;         /* Set new INTC mask disabling the IRQ */        Mask = (Mask & ~(1 << IRQNum)) & 0x7F;        INTCReg->IRQMask = Mask;         /* Save the new value */        SavedIRQMask = Mask;} /* IRQDisable */  /* * Reset interrupt bit in the INTC. * * int IRQNum - interrupt number */voidIRQReset(int IRQNum){         /* Writing 1 will reset interrupt bit */        INTCReg->IRQ.Reset = (1 << IRQNum);} /* IRQReset */  /* * Install and enable a new Interrupt Service Routine. * * int IRQNum - interrupt request number * PFV ISRFun - new interrupt handler * * Return: *     The old interrupt service routine address. */PFVIRQInstall(int IRQNum, PFV ISRFun){        PFV OldISR;         /* Sanity check */        if (IRQNum < 0 || MAXIRQNUM < IRQNum)                return((PFV)0);         /* Get old ISR function */        OldISR = IRQVector[IRQNum];         /* Replace with new ISR function */        IRQVector[IRQNum] = ISRFun;         /* Enable the interrupt */        IRQEnable(IRQNum);         return(OldISR);} /* IRQInstall *//* * FIQ interrupt numbers: * *		0 - serial port receive pseudo DMA *		1 - serial port transmit pseudo DMA *		2 - expansion slot *		3 - logic analyzer port *              4 - expansion slot pseudo DMA *              5 - expansion slot pseudo DMA *              6 - expansion slot pseudo DMA *              7 - expansion slot pseudo DMA *//* * Fast Interrupt service routine dispatcher. * * This is the FIQ trap handler called when an FIQ is detected. */static voidDispatchFIQ(void){	uint	Mask = 0x0080;	uint	Status;	int	FIQNum = 7;	Status = INTCReg->FIQStatus;	while (FIQNum >= 0) {		if (Status & Mask) {			/* restore processor level before interrupt */			/* call interrupt handler */			if (FIQVector[FIQNum])				(*(FIQVector[FIQNum]))();			else				; /* spurious interrupt */		}		Mask = Mask >> 1;		FIQNum--;	}} /* DispatchFIQ */ /* * Enable fast interrupt request. * * int FIQNum - interrupt request number */voidFIQEnable(int FIQNum){        uint Mask;         /* Get the old INTC mask */        Mask = SavedFIQMask;         /* Set new INTC mask enabling the new FIQ */        Mask = (Mask | (1 << FIQNum)) & 0x7F;        INTCReg->FIQMask = Mask;               /* this register is write only */         /* Save new value in the workspace */        SavedFIQMask = Mask;} /* FIQEnable *//* * Disable fast interrupt request. * * int FIQNum - interrupt request number */void              FIQDisable(int FIQNum){        uint Mask;         /* Get the old INTC mask */        Mask = SavedFIQMask;         /* Set new INTC mask disabling the FIQ */        Mask = (Mask & ~(1 << FIQNum)) & 0x7F;        INTCReg->FIQMask = Mask;         /* Save the new value */        SavedFIQMask = Mask;} /* FIQDisable */  /* * Install and enable a new Fast Interrupt Service Routine. * * int FIQNum - interrupt request number * PFV ISRFun - new interrupt handler * * Return: *     The old interrupt service routine address. */PFVFIQInstall(int FIQNum, PFV ISRFun){        PFV OldISR;         /* Sanity check */        if (FIQNum < 0 || MAXFIQNUM < FIQNum)                return((PFV)0);         /* Get old ISR function */        OldISR = FIQVector[FIQNum];         /* Replace with new ISR function */        FIQVector[FIQNum] = ISRFun;         /* Enable the interrupt */        FIQEnable(FIQNum);         return(OldISR);} /* FIQInstall *//* * Software interrupt dispatcher. * * int SWINum - SWI number * * This is the SWI trap handler called when an SWI is detected. */static voidDispatchSWI(int SwiNum){	if (SwiNum < 0 || MAXSWINUM < SwiNum)		/* illegal swi */		return;	if (SWIVector[SwiNum])		(*(SWIVector[SwiNum]))();	else		; /* swi not registered */	return;} /* DispatchSWI */ /* * Install a new SWI Service Routine. * * int SWINum - SWI number * PFV ISRFun - new service routine * * Return: *     The old service routine address. */PFVSWIInstall(int SWINum, PFV ISRFun){        PFV OldISR;         /* Sanity check */        if (SWINum < 0 || MAXSWINUM < SWINum)                return((PFV)0);         /* Get old ISR function */        OldISR = SWIVector[SWINum];         /* Replace with new ISR function */        SWIVector[SWINum] = ISRFun;         return(OldISR);} /* SWIInstall */ /* * Get a byte from the serial port. * * Return: *     The byte read or 0 if not available. */byteGetByte(void){        ureg   Status;        byte    Ch;        if ((Status = UARTReg->Reg3.IIR) != 1)                if ((Status & 0x06) == 0x04) {                        Ch = UARTReg->Reg1.RBR & 0xFF;                        return(Ch);                }        return(0);} /* GetByte *//* * Send a byte to the serial port. * * byte Ch - the byte to send * */voidPutByte(byte Ch){        ureg LineStatus;	int i;        do {                LineStatus = UARTReg->LSR;        } while(!(LineStatus & 0x20));  /* wait until ready */	for (i = 0; i < 5000; i++)	/* pause */		;        UARTReg->Reg1.THR = Ch;         /* send the byte */} /* PutByte */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -