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

📄 drv_nim_qpsk.c

📁 tunner驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************
*
* FILENAME
*	DRV_NIM.c
*
* PURPOSE 
*	EMMA2L Reference Model NIM Driver
*
* AUTHOR
*	Kenji.Matsuura
*
* DATE 
*	09/04/2002
*
* HISTORY 
*
*
*****************************************************************/

#include <stdio.h>
#include <string.h>
#include <math.h>


#include "COM.h"
#include "DRV_Internal.h"

#include "mmac/rtos.h"

#include "DRV_NIM.h"
#include "DRV_IIC.h"
#include "DRV_NIM_QPSK_Internal.h"
#include "DRV_NIM_TUNER_Internal.h"
#include "mmac/iic.h"				/* m-kenji IIC */


/****************************************************************
*	External Valiables
****************************************************************/
extern BOOL	DRV_NIM_Initialized;		/* NIM Driver Initialized Flag			*/
extern I32 	DRV_NIM_TUNER_InterFrequency;				/* Intermeiate Frequency 				*/
extern UI8	DRV_NIM_FreqSweepControl;			/* Frequency Sweep Stop Enable			*/
extern UI8	DRV_NIM_FreqSweepStatus;			/* Frequency Sweep Status Run			*/
extern UI8	DRV_NIM_FreqAmendmentControl;		/* Frequency Amendment Control			*/
extern UI8	DRV_NIM_FreqAmendmentStatus;		/* Frequency Amendment Status Run		*/


/*****************************************************************
*		Global Variables
*****************************************************************/
DRV_NIM_QPSK_STATUS		DRV_NIM_QPSK_StatusInfo;



/****************************************************************
*	Static Functions
****************************************************************/
static BOOL	DRV_NIM_QPSK_SetG4Reg(void);
static BOOL	QpskFreqValidRangeCheck(void);
static int	QpskGetFreqDeviation(void);
static BOOL	GetRegister(UI8 RegGroup,UI8 RegNumber,UI8 *GetData,UI8 GetLength);
static int	CalcApr19(void);
static int	CalcValue28(int BaudRate, int SampleRate);
static int	CalcValue42(int BaudRate, int SampleRate,double Ratio);
static BOOL	QpskClkSweepSwitch(UI8 Switch);
static BOOL	QpskCarSweepSwitch(UI8 Switch);
static BOOL QPSK_FEC_Reset(void);


/****************************************************************
*	Static Valiables
****************************************************************/
static	int	QpskSymbolRate;		/* current symbol rate  */
static	int	QpskDFNumber;		/* Number				*/
static	int	QpskDFRatio;		/* Ratio				*/
static	int	QpskDFGain;			/* Gain					*/
static	int	QpskCarSweepLim;	/* Carrier sweep limit	*/
static	int	QpskFsamp;			/* SymbolRate sampling freqency */
static	DRV_NIM_QPSK_VITERBI_RATE QpskViterbiRate;	/* Vterbi Rate */


/*	QPSK L64724 GRP4 Reg	*/
static UI8 Regs724[] = {
	0x81,	/* 00: 1, ,PLL_N[5:0]										*/
	0x14,	/* 01:  , ,PLL_S[5:0]										*/
	0x06,	/* 02: IMQ,DSS,QB,PLL_T[4:0]								*/
	0x18,	/* 03: VitCodeRate[2:0],TEI,SYNC2,SYNC1,PLL_M[1:0]			*/
	0x80,	/* 04: VMDC1[7:0]											*/
	0xA0,	/* 05: VMDC2L[7:0]											*/
	0x25,	/* 06: VMDC2M[15:8]											*/
	0x26,	/* 07: VMDC2H[23:16]										*/
	0x2E,	/* 08: VitMax BER Count @Rate 1/2							*/
	0x19,	/* 09: VitMax BER Count @Rate 2/3							*/
	0x0F,	/* 10: VitMax BER Count @Rate 3/4							*/
	0x0A,	/* 11: VitMax BER Count @Rate 5/6							*/
	0x07,	/* 12: VitMax BER Count @Rate 6/7							*/
	0x07,	/* 13: VitMax BER Count @Rate 7/8							*/
	0x47,	/* 14: Sync Word[7:0]										*/
	0x00,	/* 15: BER,AutoRate,,,IMQ_EN,DI_Bypass,L[1:0]				*/
	0x23,	/* 16:  ,,SSS[1:0],SSA[1:0]SST[1:0]							*/
	0x20,	/* 17:  ,,OF,OutputSelector[4:0]							*/
	0x00,	/* 18:  PLL_RESET											*/
	0x84,	/* 19:  DF_Sel[2:0],DF_Gain[1:0],DF_Ratio[2:0]				*/
	0x01,	/* 20: ,,,PD,,,,MF_20_35									*/
	0x20,	/* 21: PCLK_INV,PLL_BP,LCLK_OFF,CLK_DIV[4:0]				*/
	0xAA,	/* 22: CLK_DIV2[7:0]										*/
	0xC2,	/* 23: DC_Offset_On_Off[1:0],,CLK_DIV2[12:8]				*/
	0x54,	/* 24: PWR_REF[7:0]											*/
	0x00,	/* 25: ,,,,,INT_DC,PWR_BW[1:0]								*/
	0xBB,	/* 26: SCALE[7:0]											*/
	0x64,	/* 27: SNR_THSS[7:0]										*/
	0xAA,	/* 28: CAR_LAMBDA_SEL[3:0],CAR_MU_SEL[3:0]					*/
	0x10,	/* 29: CAR_LC_THSL[7:0]     SAMSNG is 0x10					*/
	0x00,	/* 30:  ,,,,,,,,											*/
	0xA0,	/* 31:  RS Bit/Byte,Errout_Inv,SPI_ON_ON,00000				*/
	0x8E,	/* 32: CAR_SWR[7:0]											*/
	0x2B,	/* 33: CAR_SWR[15:8]										*/
	0x9A,	/* 34: CAR_USWL[7:0]										*/
	0x19,	/* 35: CAR_USWL[15:8]										*/
	0x66,	/* 36: CAR_LSWL[7:0]										*/
	0xE6,	/* 37: CAR_LSWL[15:8]										*/
	0xB8,	/* 38: CAR_LF_INIT[7:0]										*/
	0x1E,	/* 39: CAR_LF_INIT[15:8]									*/
	0x05,	/* 40: CAR_LF_INIT[23:16]									*/
	0x65,	/* 41: CAR_SWP_SWAP,CAR_ERROR_SWAP,CAR_AUTO_SWP,,,CAR_PD_SEL,CAR_OPEN,CAR_SW	*/
	0xAA,	/* 42: CLK_LAMBDA_SEL[3:0],CLK_MU_SEL[3:0]					*/
	0x00,	/* 43: CLK_SWR[7:0]											*/
	0x44,	/* 44: CLK_SWR[15:8]										*/
	0x00,	/* 45: CLK_USWL[7:0]										*/
	0x00,	/* 46: CLK_USWL[15:8]										*/
	0x00,	/* 47: CLK_LSWL[7:0]										*/
	0x00,	/* 48: CLK_LSWL[15:8]										*/
	0x84,	/* 49: CLK_BIAS[7:0]										*/
	0x01,	/* 50: CLK_BIAS[15:8]										*/
	0x00,	/* 51: CLK_BIAS[23:16]										*/
	0x00,	/* 52: CLK_BIAS[30:24]										*/
	0x39,	/* 53: CLK_SWP_SWAP,CLK_ERROR_SWAP,CLK_AUTO_SWP,,AGC_CLK_SEL,,CLK_OPEN,CLK_SW	*/
	0x00,	/* 54: SNR_EST,PWRP_TRI,ADC_PD,FP_LOCK_LEN,PWRP,,,CLK_ALPHA_SEL					*/
			/*     0x08 ... SL5659 , 0x00 ....MI5769 AGC polarity setting 					*/
	0x0F,	/* 55: ADC_BPS,OB_2C,XCTR[3:0],DEMOD_RST,FEC_RST			*/
	0x00,	/* 56: ,,,,,,,												*/
	0x00,	/* 57: ,,,,,,,												*/
	0x14,	/* 58: ,,,,,,,												*/
	0x10,	/* 59: TXSD[6:0],											*/
	0x00,	/* 60: STXD[7:0]											*/
	0x00,	/* 61: TXED[7:0]											*/
	0x09,	/* 62: Serial_B,Serial_C[1:0],SPI_M[3:0],Serial_A			*/
	0x43,	/* 63: FMODE,SPI_CLK_AND,SPI_Mode_A_B,,SPI_N[3:0] (BCLKOUT AND'ed DVALIDOUT)	*/
	0x32,	/* 64: SPI_Gain[7:0]										*/
	0x00,	/* 65: ,,,,,,SIP_Gain[9:8]									*/
	0x66,	/* 66: SPI_Bias[7:0]										*/
	0x66,	/* 67: SPI_Bias[15:8]										*/
	0x06,	/* 68: ,SPI_Bias[22:16]										*/
	0x4B	/* 69: CLK_LC_THS[7:0]										*/
};

static UI8 InitRegs724[] = {
	0x81,0x14,0x06,0x18,0x80,0xA0,0x25,0x26,0x2E,0x19,0x0F,0x0A,
	0x07,0x07,0x47,0x00,0x23,0x20,0x00,0x84,0x01,0x20,0xAA,0xC2,
	0x54,0x00,0xBB,0x64,0xAA,0x10,0x00,0xA0,0x8E,0x2B,0x9A,0x19,
	0x66,0xE6,0xB8,0x1E,0x05,0x65,0xAA,0x00,0x44,0x00,0x00,0x00,
	0x00,0x84,0x01,0x00,0x00,0x39,0x00,0x0F,0x00,0x00,0x14,0x10,
	0x00,0x00,0x09,0x43,0x32,0x00,0x66,0x66,0x06,0x4B};

static DF_TABLE DFTable[] = {
	{4,  8, 8},		/*  0   ~  3.75 Msps	*/
	{3,  4, 4},		/*  3.75~  7.5  Msps	*/
	{2,  2, 2},		/*  7.5 ~ 15    Msps	*/
	{1,  1, 1},		/* 15   ~ 30    Msps	*/
	{0,  1, 1},		/* 30   ~ 44.5  Msps	*/
	{0,  1, 1}		/* 45Msps				*/
};


static PLL_TABLE PLLConst[] = {
	{ 61,  1, 10,  3},
	{  6,  1,  1,  3},
	{ 17,  1,  3,  3},
	{ 16,  1,  3,  3},
	{  5,  1,  1,  3},			/*	75	*/
	{ 14,  1,  3,  2},
	{ 13,  1,  3,  2},
	{  4,  1,  1,  1},
	{ 11,  1,  3,  1},
	{ 10,  1,  3,  0},			/*	50	*/
	{  3,  1,  1,  0},
	{  8,  3,  1,  3},
	{  7,  3,  1,  2},
	{  2,  1,  1,  1},
	{  5,  3,  1,  0},			/*	25	*/
	{  4,  3,  1,  0},
	{  1,  1,  1,  2},
	{  2,  3,  1,  2}
};

static int PLLConstantFs[17] = {
	91, 90, 85, 80, 75,
	70, 65, 60, 55, 50,
	45, 40, 35, 30, 25,
	20, 15
};


static double RsBound[7]={0,3750,7500,15000,30000,44500,45000};


static VITERBI_RATE_TBL StVCR[] ={
		{ 1,2 },	/* VCR 0 = 1/2			*/
		{ 2,3 },	/* VCR 1 = 2/3			*/
		{ 3,4 },	/* VCR 2 = 3/4			*/
		{ 5,6 },	/* VCR 3 = 5/6			*/
		{ 6,7 },	/* VCR 4 = 6/7			*/
		{ 7,8 },	/* VCR 5 = 7/8			*/
		{ 3,4 },	/* VCR 6(Unused) = 3/4	*/
		{ 3,4 }		/* VCR 7(Unused) = 3/4	*/
};

#define XO_REF			(double)15.0	// Crystal frequency (MHz) 


/*****************************************************************
*
* Function Name
*	DRV_NIM_QPSK_SetSymbolRate
*
* Prototype
*	DRV_NIM_RESULT DRV_NIM_QPSK_SetSymbolRate(
*		I32 Device,
*		I32 SymbolRate,
*		DRV_NIM_QPSK_VITERBI_RATE ViterbiRate)
*
*
* Inputs
*	Device		:	NIM Device Number
*	SymbolRate	:	Symbol Rate Value
*	ViterbiRate	:	Viterbi Rate Value
*
* Outputs
*	None
*
* Return Codes
*	DRV_NIM_OK
*	DRV_NIM_NOT_INITIALIZED
*	DRV_NIM_INVALID_PARAMETER
*	DRV_NIM_FAIL
*
* Description
*	This function a setting of symbol rate.
*
*****************************************************************/
DRV_NIM_RESULT  DRV_NIM_QPSK_SetSymbolRate(
					I32 Device,I32 SymbolRate,DRV_NIM_QPSK_VITERBI_RATE ViterbiRate)
{

	int i;

	if( !DRV_NIM_Initialized ) {								/* Not Initialized ? */
		return( DRV_NIM_NOT_INITIALIZED );						/* Not Initialized */
	}

	SymbolRate /= 1000;											/* 偲傝偁偊偢丄妱偭偲偔 by Soga */

#if DRV_NIM_CHECK_PARAMETER
	if(!((0<=Device)&&(Device<DRV_NIM_NUMBER_OF_DEVICES))){		/* Invalid Device Number ?	*/
		return( DRV_NIM_INVALID_PARAMETER );					/* Invalid Parameter 		*/
	}

	if((SymbolRate < DRV_NIM_MINIMUM_SYMBOLRATE)||
	   (SymbolRate > DRV_NIM_MAXIMUM_SYMBOLRATE)){
		return( DRV_NIM_INVALID_PARAMETER );
	}

	switch(ViterbiRate){
		case DRV_NIM_QPSK_VITERBI_AUTO:
		case DRV_NIM_QPSK_VITERBI_1_2:
		case DRV_NIM_QPSK_VITERBI_2_3:
		case DRV_NIM_QPSK_VITERBI_3_4:
		case DRV_NIM_QPSK_VITERBI_5_6:
		case DRV_NIM_QPSK_VITERBI_6_7:
		case DRV_NIM_QPSK_VITERBI_7_8:
			break;
		default:
			return( DRV_NIM_INVALID_PARAMETER );
	}
#endif

	if( MMAC_RTOS_AcquireSemaphore( DRV_NIM_Semaphore
							, MMAC_RTOS_SUSPEND ) != MMAC_RTOS_OK ) {	/* Take Semaphore for Callback Table NG ? */
		return( DRV_NIM_FAIL );									/* Fail */
	}

	QpskSymbolRate = SymbolRate;
	QpskViterbiRate= ViterbiRate;

	/* select of carrier sweep limit */
	if( QpskSymbolRate >= 15000 ){
     	QpskCarSweepLim =  CARRIER_SWEEP_LIMIT_HIGH;
	}else{
		if( (7500 <= QpskSymbolRate) &&  ( 15000 > QpskSymbolRate)){
     		QpskCarSweepLim =  CARRIER_SWEEP_LIMIT_MID;
		}else{
			if( (3750 <= QpskSymbolRate) &&  ( 7500 > QpskSymbolRate)){
	     		QpskCarSweepLim =  CARRIER_SWEEP_LIMIT_MID_1;
			}else{
	     		QpskCarSweepLim =  CARRIER_SWEEP_LIMIT_LOW;
			}
		}
	}

	/* Calcurate DF param and Decide SampleRate frequency for ADC */
	QpskDFNumber	= 3 ;		/* DF Number	*/
	QpskDFRatio 	= 4 ;		/* DF Ratio		*/
	QpskDFGain		= 4 ;		/* DF Gain		*/

	for ( i=0; i<6 ; i++){
	    if ( ( QpskSymbolRate > RsBound[i]) && ( QpskSymbolRate <= RsBound[i+1])){
			QpskDFNumber	= DFTable[i].DFNumber;		/* DF Number	*/
			QpskDFRatio		= DFTable[i].DFRatio;		/* DF Ratio		*/
			QpskDFGain		= DFTable[i].DFGain;		/* DF Gain		*/
			break;
		}
	}

	/* Setting of symbol rate freqency sampling */
	QpskFsamp = (int)(((4 * QpskDFRatio * QpskSymbolRate / (1010)) /5 ) * 5.0);

	if (QpskFsamp < 10 ){	/*	Min. 10MHz	*/
		QpskFsamp = 10;
	}
	if (QpskFsamp > 90 ){	/*	Max. 90MHz	*/
		QpskFsamp = 90;
	}

	if ( QpskSymbolRate == 45000 ) { 	/* This is Max SymbolRate	*/
	 	QpskDFNumber	= 0;
		QpskDFRatio		= 1;
		QpskDFGain		= 1;
    }

	if(FALSE==DRV_NIM_QPSK_SetG4Reg()){		/*	Register set			*/
		MMAC_RTOS_ReleaseSemaphore( DRV_NIM_Semaphore );
		return( DRV_NIM_FAIL );							/* Fail */
	}

	DRV_NIM_FreqSweepStatus=QPSK_SW_ON;							/* Sweep Status ON (Run)	*/

	if( MMAC_RTOS_ReleaseSemaphore( DRV_NIM_Semaphore ) != MMAC_RTOS_OK ) {
		return( DRV_NIM_FAIL );									/* Fail */
	}


	return( DRV_NIM_OK );

}


/*****************************************************************
*
* Function Name
*	DRV_NIM_QPSK_GetStatus
*
* Prototype
*	DRV_NIM_RESULT  DRV_NIM_QPSK_GetStatus(I32 Device,DRV_NIM_QPSK_STATUS *QpskStatus)
*
* Inputs
*	Device		:	NIM Device Number
*
* Outputs
*	QpskStatus	:	Qpsk status value pointer
*						SignalLevel / QualityLevel / LockStatus
*
* Return Codes
*	DRV_NIM_OK
*	DRV_NIM_NOT_INITIALIZED
*	DRV_NIM_INVALID_PARAMETER
*	DRV_NIM_FAIL
*
* Description
*	This function a get qpsk status.
*
*****************************************************************/
DRV_NIM_RESULT  DRV_NIM_QPSK_GetStatus(I32 Device,DRV_NIM_QPSK_STATUS *QpskStatus)
#if 1
{
	if( !DRV_NIM_Initialized ) {								/* Not Initialized ? */
		return( DRV_NIM_NOT_INITIALIZED );						/* Not Initialized */
	}

#if DRV_NIM_CHECK_PARAMETER
	if(!((0<=Device)&&(Device<DRV_NIM_NUMBER_OF_DEVICES))){	/* Invalid Device Number ?	*/
		return( DRV_NIM_INVALID_PARAMETER );					/* Invalid Parameter 		*/
	}

	if(QpskStatus==NULL){
		return( DRV_NIM_INVALID_PARAMETER );
	}
#endif

	QpskStatus->SignalLevel	= DRV_NIM_QPSK_StatusInfo.SignalLevel;
	QpskStatus->QualityLevel= DRV_NIM_QPSK_StatusInfo.QualityLevel;
	QpskStatus->LockStatus	= DRV_NIM_QPSK_StatusInfo.LockStatus;
	return( DRV_NIM_OK );
}
#else
{	/* debag */

	UI8						GetValue;
	UI16					AGCLevel;
	UI16					SNRLevel;

	/* acquire a register than L64724 */
	if(FALSE==GetRegister(3,10,&GetValue,1))		/* Group3 APR10 (AGC Value)	*/
		return( DRV_NIM_FAIL );

	AGCLevel =(I16)(128-(GetValue/2));
	QpskStatus->SignalLevel=(I8)AGCLevel;

	if(FALSE==GetRegister(3,22,&GetValue,1))		/* Group3 APR22 (SNR[7:0] Value)	*/
		return( DRV_NIM_FAIL );

	SNRLevel  = GetValue;

	if(FALSE==GetRegister(3,23,&GetValue,1))		/* Group3 APR23 (SNR[11:8] Value)	*/
		return( DRV_NIM_FAIL );

	SNRLevel |= (GetValue << 8);
	SNRLevel /= 32;
	QpskStatus->QualityLevel=(I8)SNRLevel;
	/* status check */
	if(FALSE==GetRegister(3,11,&GetValue,1))		/* Group3 APR11 (Carrier and FEC Status)	*/
		return( DRV_NIM_FAIL );

	switch(GetValue & 0x17){
		case 0x17:		/* Status : VITERBI Lock */
			QpskStatus->LockStatus=DRV_NIM_VITERBI_LOCK;
			break;
		case 0x10:	/* Status : QPSK Lock */
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
			QpskStatus->LockStatus=DRV_NIM_QPSK_LOCK;
			break;
		default:
			QpskStatus->LockStatus=DRV_NIM_UNLOCK;
			break;
	}
	return( DRV_NIM_OK );
}
#endif


/*****************************************************************
*
* Function Name
*	DRV_NIM_QPSK_GetSymbolRate
*
* Prototype
*	DRV_NIM_RESULT  DRV_NIM_QPSK_GetSymbolRate(
*				I32 Device,I32 *SymbolRate,DRV_NIM_QPSK_VITERBI_RATE *ViterbiRate);
*
* Inputs
*	Device		:	NIM Device Number
*
* Outputs
*	SymbolRate	:	Symbol  Rate Value pointer
*	ViterbiRate :	Viterbi Rate Value pointer
*
* Return Codes
*	DRV_NIM_OK
*	DRV_NIM_NOT_INITIALIZED
*	DRV_NIM_INVALID_PARAMETER
*	DRV_NIM_FAIL
*
* Description
*	This function a get SymbolRate or ViterbiRate.
*
*****************************************************************/
DRV_NIM_RESULT  DRV_NIM_QPSK_GetSymbolRate(
					I32 Device,I32 *SymbolRate,DRV_NIM_QPSK_VITERBI_RATE *ViterbiRate)
{
	if( !DRV_NIM_Initialized ) {								/* Not Initialized ? */
		return( DRV_NIM_NOT_INITIALIZED );						/* Not Initialized */
	}
#if DRV_NIM_CHECK_PARAMETER
	if(!((0<=Device)&&(Device<DRV_NIM_NUMBER_OF_DEVICES))){		/* Invalid Device Number ?	*/
		return( DRV_NIM_INVALID_PARAMETER );					/* Invalid Parameter 		*/
	}

	if(SymbolRate==NULL){
		return( DRV_NIM_INVALID_PARAMETER );
	}
	if(ViterbiRate==NULL){
		return( DRV_NIM_INVALID_PARAMETER );
	}
#endif
	*SymbolRate  = QpskSymbolRate;
	*ViterbiRate = QpskViterbiRate;
	return( DRV_NIM_OK );
}


/*****************************************************************
*
* Function Name
*	DRV_NIM_QPSK_GetSpectrum
*
* Prototype
*	DRV_NIM_RESULT  DRV_NIM_QPSK_GetSpectrum(I32 Device,I8 *Spectrum );
*
* Inputs
*	Device		:	NIM Device Number
*
* Outputs
*	Spectrum	:	Spectrum data pointer
*
* Return Codes
*	DRV_NIM_OK
*	DRV_NIM_NOT_INITIALIZED
*	DRV_NIM_INVALID_PARAMETER
*	DRV_NIM_FAIL
*
* Description
*	This function a get Spectrum.
*
*****************************************************************/
DRV_NIM_RESULT  DRV_NIM_QPSK_GetSpectrum(I32 Device,I8 *Spectrum )
{
	UI8		GetValue;

	if( !DRV_NIM_Initialized ) {								/* Not Initialized ? */
		return( DRV_NIM_NOT_INITIALIZED );						/* Not Initialized */
	}
#if DRV_NIM_CHECK_PARAMETER
	if(!((0<=Device)&&(Device<DRV_NIM_NUMBER_OF_DEVICES))){		/* Invalid Device Number ?	*/
		return( DRV_NIM_INVALID_PARAMETER );					/* Invalid Parameter 		*/
	}
	if(Spectrum==NULL){
		return( DRV_NIM_INVALID_PARAMETER );
	}
#endif

	if( MMAC_RTOS_AcquireSemaphore( DRV_NIM_Semaphore
							, MMAC_RTOS_SUSPEND ) != MMAC_RTOS_OK ) {	/* Take Semaphore for Callback Table NG ? */
		return( DRV_NIM_FAIL );									/* Fail */
	}

⌨️ 快捷键说明

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