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

📄 timerdrv.c

📁 56f8300E系列dsp的BOOTloader
💻 C
📖 第 1 页 / 共 4 页
字号:
/*******************************************************************************
*
* Motorola Inc.
* (c) Copyright 2002 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
* $Element: /project/dsp568_sdk/sdk/src/dsp56838evm/nos/bsp/timerdrv.c $ 
* $Author: saa $ 
* $Revision: /main/2 $ 
* $VOB: /project/dsp568_sdk $ 
* $OS: solaris $ 
*
* Description:       source file for the 56838 posix timer driver 
*
* Notes:  
*
******************************************************************************/
#include "port.h"
#include "bsp.h"
#include "arch.h"

#include "timerdrv.h"
#include "timer.h"

static unsigned long TimerISRCount; /* system timer counter */

/* Local prototypes */
static void    timerRealTimeClockISR(union sigval Params); 
 
/* QT ISR prototypes */
extern posix_tContext   posix_ctx_A_0;
extern posix_tContext   posix_ctx_A_1;
extern posix_tContext   posix_ctx_A_2;
extern posix_tContext   posix_ctx_A_3;
extern posix_tContext   posix_ctx_B_0;
extern posix_tContext   posix_ctx_B_1;
extern posix_tContext   posix_ctx_B_2;
extern posix_tContext   posix_ctx_B_3;
extern posix_tContext   posix_ctx_C_0;
extern posix_tContext   posix_ctx_C_1;
extern posix_tContext   posix_ctx_C_2;
extern posix_tContext   posix_ctx_C_3;
extern posix_tContext   posix_ctx_D_0;
extern posix_tContext   posix_ctx_D_1;
extern posix_tContext   posix_ctx_D_2;
extern posix_tContext   posix_ctx_D_3;

/*** Quadrature timer Normal ISR template ***/
#if 0
#define INSTQTISR( isr, base, device )                                  \
void isr(void)                                                          \
{																		\
    extern const union sigval sig;										\
    if(  --(device.SoftCounter) == 0 )									\
    {																	\
        device.SoftCounter = device.reloadSoftCounter;					\
        if(device.pUserFunc != 0 )										\
        device.pUserFunc( sig );										\
    }																	\
	if( (device.reloadSoftCounter == 0) && (device.SoftCounter < 2))	\
         	 periphBitSet(QTB_ONCE,(volatile unsigned short*)(base));	\
}
#else
#define POUND #
#define INSTQTISR( isr, base, device )                              \
void isr(void)                                                      \
{																	\
    asm(	adda		#0x0000002 , SP							);	\
    asm(	move.l		A10 , X:(SP)+							);	\
    asm(	move.l		R2  , X:(SP)							);	\
    asm(	move.w		device + SoftCounter_offset , A			);	\
    asm(	dec.w		A 										);	\
    asm(	bne			nextsoftstep							);	\
    asm(	tst.w 		device + pUserFunc_offset				);	\
    asm(	beq			nextsoftstep							);	\
    asm(	move.l		device + pUserFunc_offset , R2			);	\
    asm(	adda		#2 , SP									);	\
    asm(	move.w		#0 , X:(SP)								);	\
    asm(	jsr			(R2)									);	\
    asm(	suba		#2 , SP									);	\
    asm(	move.w		device + reloadSoftCounter_offset , A1	);	\
    asm(	nextsoftstep:										);	\
    asm(	move.w		A1 , device + SoftCounter_offset		);	\
    asm(	tst.w		device + reloadSoftCounter_offset		);	\
    asm(	bne 		endstep									);	\
    asm(	move.w		device + SoftCounter_offset , A1		);	\
    asm(	cmp.w 		#1 , A									);	\
    asm(	bne 		endstep									);	\
    asm(	move.l		POUND base , R2					 		);	\
    asm(	move.w		X:(R2-0x1000) , A1						);	\
    asm(	bfset		0x0040 , A								);	\
    asm(	move.w		A1 , X:( R2 - 0x1000 )					);	\
    asm(	endstep:											);	\
    asm(	move.l		X:(SP)- , R2							);	\
    asm(	move.l		X:(SP)- , A								);	\
	}
#endif

/* Quadrature timer isr service routines */
INSTQTISR( POSIXtimerISRA0, archoff_TimerA0_ControlReg, posix_ctx_A_0 )
INSTQTISR( POSIXtimerISRA1, archoff_TimerA1_ControlReg, posix_ctx_A_1 )
INSTQTISR( POSIXtimerISRA2, archoff_TimerA2_ControlReg, posix_ctx_A_2 )
INSTQTISR( POSIXtimerISRA3, archoff_TimerA3_ControlReg, posix_ctx_A_3 )

#if !defined(DSP56838EVM)
INSTQTISR( POSIXtimerISRB0, archoff_TimerB0_ControlReg, posix_ctx_B_0 )
INSTQTISR( POSIXtimerISRB1, archoff_TimerB1_ControlReg, posix_ctx_B_1 )
INSTQTISR( POSIXtimerISRB2, archoff_TimerB2_ControlReg, posix_ctx_B_2 )
INSTQTISR( POSIXtimerISRB3, archoff_TimerB3_ControlReg, posix_ctx_B_3 )
#endif /* !defined(DSP56838EVM) */

INSTQTISR( POSIXtimerISRC0, archoff_TimerC0_ControlReg, posix_ctx_C_0 )
INSTQTISR( POSIXtimerISRC1, archoff_TimerC1_ControlReg, posix_ctx_C_1 )
INSTQTISR( POSIXtimerISRC2, archoff_TimerC2_ControlReg, posix_ctx_C_2 )
INSTQTISR( POSIXtimerISRC3, archoff_TimerC3_ControlReg, posix_ctx_C_3 )

INSTQTISR( POSIXtimerISRD0, archoff_TimerD0_ControlReg, posix_ctx_D_0 )
INSTQTISR( POSIXtimerISRD1, archoff_TimerD1_ControlReg, posix_ctx_D_1 )
INSTQTISR( POSIXtimerISRD2, archoff_TimerD2_ControlReg, posix_ctx_D_2 )
INSTQTISR( POSIXtimerISRD3, archoff_TimerD3_ControlReg, posix_ctx_D_3 )

#define POSIX_TIMER_READ_PRESCALER_VALUE( bspDevice, Dummy ) \
          ( 1<< (timerStdFastStart.bits.InputSource & 0xFFF8 )   )


#define POSIX_TIMER_GET_CONTEXT(TimerID) \
((posix_tContext*)timer_qt_readCompareReg1( (arch_sTimerChannel*) TimerID ) )


extern const        qt_sQuadState  timerStdFastStart;


/*****************************************************************************
*
* Module: U64addU32
*
* Description: addition unsigned 64 and unsigned 32 bits numbers
*
* Returns: none
*
* Arguments: pFirst     - pointer to unsigned U64 value
*            second     - 32 bits unsigned number
*            pRezult    - not null pointer to U64 value
*
* Range Issues: 
*
* Special Issues:  
*           Register discription:
*                       R2 - pointer to U64 value
*                       A  - 32 bits number
*                       R3 - not null pointer to U64 value
*
*                       Module doesn't save register: B
*
* if overflow occurs then carry bit will be set
*
* Test Method: 
*
*****************************************************************************/
static void U64addU32(const U64 * pFirst, const unsigned long second, U64 * pResult)
{
    asm(adda    #1, SP      );

    asm(move.w  A0, X:(SP)+ );
    asm(move.w  A1, X:(SP)+ );
    asm(move.w  B0, X:(SP)+ );
    asm(move.w  B1, X:(SP)  );
    

    asm(move.l  X:(R2), B   );      /* Prepare data for addition least 32-bits 	*/
    asm(add     A, B        );      /* Add least 32-bits  						*/
    asm(move.l  B10, X:(R3) );      /* Save least 32-bits 						*/                               
    asm(move.l  X:(R2+2), B );      /* copy high 32-bits to result 				*/
    asm(move.l  #0, Y       );
    asm(adc     Y, B        );
    asm(move.l  B10, X:(R3+2));     /* Save least 32-bits 						*/
    
    asm(move.w  X:(SP)-, B1 );
    asm(move.w  X:(SP)-, B0 );
    asm(move.w  X:(SP)-, A1 );
    asm(move.w  X:(SP)-, A0 );
        
    asm(rts                 );
}

/*****************************************************************************
*
* Module: U64mulU32
*
* Description: multiplication unsigned 64 and unsigned 32 bits multiplier
*
* Returns: none
*
* Arguments: pFirst     - pointer to U64 value
*            second     - 32 bits multiplier
*            pRezult    - not null pointer to U64 value
*
* Range Issues: 
*
* Special Issues:  
*           Register discription:
*                       R2 - pointer to U64 value
*                       A  - 32 bits number
*                       R3 - not null pointer to U64 value
*
*                       Module doesn't save registers: B, Y
*
* Return: return higest bits of results (64..96 bits) in register A
*
* Test Method: 
*
*****************************************************************************/
static unsigned long U64mulU32(const U64 * pFirst, const unsigned long second, U64* pRezult)
{       
    asm(adda    #1, SP      );

    asm(move.w  B0, X:(SP)+ );
    asm(move.w  B1, X:(SP)+ );
    asm(move.w  Y0, X:(SP)+ );
    asm(move.w  Y1, X:(SP)  );

    asm(move.l  #0, Y       ); /* prepare register to use as carry number			*/
                
    asm(do      #4, ENDDO   ); /* multiply step by step evry 16-bits of U64 		*/
    asm(move.w  X:(R2), B0  ); /* take current 16-bits of U64 (start from least) 	*/            
    asm(impyuu  A0, B0, B   ); /* multiply least part of multiplier 				*/
    asm(add     Y, B        ); /* add carry number 									*/
    asm(move.w  B0, Y0      ); /* save 16 bits of resuls 							*/
    asm(move.w  X:(R2)+, B0 ); /* take next 16-bits of U64 							*/
    asm(move.w  Y0, X:(R3)+ ); /* save our current result to memory ( it's use to realise such possibility U64mul32(&a, b, &a)) */
    asm(impyuu  A1, B0, Y   ); /* multiply high part of multiplier 					*/
    asm(move.w  B1, B0      ); /* sum up carry number 								*/
    asm(clr.w   B1          );
    asm(add     B, Y        );
    
    asm(ENDDO:              );  

    asm(move.w  Y0, A0      ); /* if overflow occures, the higest bits will be in register A (return value) */
    asm(move.w  Y1, A1      );

    asm(adda    #-4, R2     );
    asm(adda    #-4, R3     );
    
    asm(move.w  X:(SP)-, Y1 );
    asm(move.w  X:(SP)-, Y0 );  
    asm(move.w  X:(SP)-, B1 );  
    asm(move.w  X:(SP)-, B0 );  
    
    asm(rts                 ); 
};

/*****************************************************************************
*
* Module: incU64
*
* Description: increase U64
*
* Returns: carry bit set if pU64 == 0xFFFF FFFF FFFF FFFF
*
* Arguments: pU64 - not null pointer to 64 bits dividend
*
*
* Range Issues: 
*
* Special Issues:  For executive loop only. Module doesn't save register: A
*                                           
* Test Method: 
*
*****************************************************************************/
static void incU64(U64 * pU64)
{                       
    asm(adda    #1, SP      			);

    asm(move.w  A0, X:(SP)+ 			);
    asm(move.w  A1, X:(SP)  			);
                                                            
    asm(move.l  X:(R2), A           	);  /* movel low bits to A */
    asm(inc.l   A                   	);  /* increase A */
    asm(move.l  A10, X:(R2)         	);  /* save result */
    asm(move.l  X:(R2+2), A         	);  /* movel high bits to A */
    asm(brclr   #1, SR, CarryBitClear   );  /* test carry bit ; carry bit set if overflow occurs*/
    asm(inc.l   A                   	);  /* inc hifh bits if overflow occurs */
            
    asm(CarryBitClear:              	);
    asm(move.l  A10, X:(R2+2)       	);  /* save high bits */
    
    asm(move.w  X:(SP)-, A1         	);
    asm(move.w  X:(SP)-, A0         	);

    asm(rts                         	);
}

/*****************************************************************************
*
* Module: U32divU16s
*
* Description: division unsigned 32 bits value by unsigned 16 bits value divider
*
* Returns: quotient
*
* Arguments: Dividend - not null pointer to 32 bits dividend
*            Divisor    - 16 bits unsigned divider
*
* Range Issues: 
*
* Special Issues:  For executive loop only. Module doesn't save registers: A, B, Y, X0
*
* Test Method: 
*
*****************************************************************************/
static unsigned short U32divU16s(const unsigned long Dividend, const unsigned short Divisor, unsigned long * Result)
{

    asm(	move.w  Y0, Y1      		);  /* save real divider 						*/
    asm(	brclr   #$8000, Y0, Core	);	/* if (sign bit is not set) then go core 	*/
    asm(	lsr.w   Y1          		);  /* new divider:=divider>>1 					*/

    /*			division																*/
    asm(Core:               			);  /* main part of division 					*/

    asm(	clr     B           		);  /* preparing for division 					*/
    asm(	move.w  A1, B0      		);  /* move high number position in register B 	*/
    asm(	bfclr   #$0001, SR  		);  /* clear carry flag ( for first shifting )) */

    asm(	rep     #17         		);  /* 16-bit for division + 1-bit for sign 	*/
    asm(	div     Y1, B       		);  /* Positive quotient in B0 					*/

    asm(	move.w  B0, A1      		);  /* Save quotient in A1 						*/

    asm(	add     Y1, B       		);  /* Restore remainder in B1 					*/
    asm(	asr     B           		);  /* Required for correct integer remainder 	*/

    asm(	move.w  A0, B0      		);  /* move low number position in register B 	*/
    asm(	bfclr   #$0001, SR  		);  /* clear carry flag ( for first shifting )) */

    asm(	rep     #17         		);  /* 16-bit for division + 1-bit for sign 	*/
    asm(	div     Y1, B       		);  /* Positive quotient in B0 					*/

    asm(	move.w  B0, A0      		);  /* Save quotient in A0 						*/

    asm(	add     Y1, B       		);  /* Restore remainder in B1 					*/
    asm(	asr     B           		);  /* Required for correct integer remainder 	*/

    /*					correct the result if divisor is odd number						*/
    asm(	bfclr   #$FF, A2        	);
    asm(	bfclr   #$FF, B2        	);

    asm(	brclr   #$8000, Y0, Endofdiv); 	/* if sign bit not set go Endofdiv 			*/
    asm(	brclr   #$0001, A0, EvenA   );  /* if quotient(A/[Y>>1]) is even go OddA 	*/

    asm(	add     Y1, B       		);  /* odd quotient. remainder( A / Y ) = remainder( A / [Y>>1] ) + Y >> 1 */

    asm(EvenA:              			);

    asm(	asr     A           		); 	/* quotient(A\[Y>>1])>>=1 					*/
    asm(	brclr   #$0001, Y0, Endofdiv); 	/* if divider is even go Endofdiv 			*/
    asm(	move.w  B1, B0      		); 	/* for addition operation 					*/
    asm(	clr.w   B1          		);
    asm(	clr.w   X0          		);
    asm(	clr.w   Y1          		);

⌨️ 快捷键说明

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