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

📄 tc_drv.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/****************************************************************
**                                                              *
**  FILE         :  TC_DRV.C                                    *
**  COPYRIGHT    :  (c) 2004 .Xiamen Yaxon NetWork CO.LTD       *
**                                                              *
**                                                              *
**              2004/10/27                                      *
****************************************************************/
#define TC_DRV_GLOBAL
#include "includes.h"
#include "target.h"
#include "hardware.h"
#include "aic_drv.h"
#include "TC_Drv.h"

typedef struct {
    AT91PS_TC   reg;
    INT32U      pid;
    INT32U      pin_tioa_mask;
    INT32U      pin_tiob_mask;
    INT32U      pin_tclk_mask;
} TC_DESC;

static TC_DESC dev_tc[3] = {
    {   /* TC0 */
        AT91C_BASE_TC0,
        AT91C_ID_TC0,
        AT91C_P1_TIOA0,
        AT91C_P2_TIOB0,
        AT91C_P0_TCLK0
    },{/* TC1 */
        AT91C_BASE_TC1,
        AT91C_ID_TC1,
        AT91C_P4_TIOA1,
        AT91C_P5_TIOB1,
        AT91C_P3_TCLK1
    },{/* TC2 */
        AT91C_BASE_TC2,
        AT91C_ID_TC2,
        AT91C_P7_TIOA2,
        AT91C_P8_TIOB2,
        AT91C_P6_TCLK2
    }
};

/************************************************************************ 
*  TC_Calculate - calculate TC parameters
************************************************************************/
static void TC_Calculate_Clk( INT32U delay_us, INT32U mcki, INT32U *rc, INT32U *tcclk)
{
    INT32U   rc_save ;
    
    /* Adjust to us * MHz */
    *rc = delay_us *(mcki / 1000000) ;
    /* If period(microsec) * MCK(MHz) div 2 < 2, error */
    if ((rc_save = *rc >> 1) < 2 ) {
        //DEBUG_PRINT (DEBUG_ALWAYS, ("\r\n%s:%s", __FILE__, __LINE__));
        //return (ERROR);
        return;
    }
    if ( rc_save < ( 1<<16 ))
        *tcclk = TC_CLKS_MCK2 ;
    else
        if (( rc_save = *rc >> 3 ) < ( 1 << 16 ))
            *tcclk = TC_CLKS_MCK8 ;
        else
            if (( rc_save = *rc >> 5 ) < ( 1 << 16 ))
                *tcclk = TC_CLKS_MCK32 ;
            else
                if (( rc_save = *rc >> 7 ) < ( 1 << 16 ))
                    *tcclk = TC_CLKS_MCK128 ;
                else
                    if (( rc_save = *rc >> 10 ) < ( 1 << 16 ))
                        *tcclk = TC_CLKS_MCK1024 ;
                    else {
                       // DEBUG_PRINT (DEBUG_ALWAYS, ("\r\n%s:%s", __FILE__, __LINE__));
                        //return (ERROR);
                        return;
                    }
    *rc = rc_save;
}

/*****************************************************************
*  TC_Open - Initialize Timer Counter Channel and enable is clock
*****************************************************************/
void TC_Open (INT32U chan, INT32U mode, INT8U  tioa, INT8U  tiob, INT8U  tclk)
{
    TC_DESC *tc = &dev_tc[chan];
    INT32U pio;
   
    // enable TC clock 
    AT91F_PS_EnablePeriphClock(AT91C_BASE_PS,1 << tc->pid);
    //configure PIO pin
    pio = 0;
    if (tioa) pio |= tc->pin_tioa_mask;
    if (tiob) pio |= tc->pin_tiob_mask;
    if (tclk) pio |= tc->pin_tclk_mask;
    AT91C_BASE_PIO->PIO_PDR = pio;  // disable pio peripheral function
    // disable TC and interrupt 
    tc->reg->TC_CCR = AT91C_TC_CLKDIS;
    tc->reg->TC_IDR = 0xffffffff;
    // clear status bit 
    pio = tc->reg->TC_SR;
    // configure TC mode 
    tc->reg->TC_CMR = mode;
    // enable TC 
    tc->reg->TC_CCR = AT91C_TC_CLKEN;
}

/***************************************************************** 
*  TC_Close - Stop a Timer Counter Channel and disable is clock
*****************************************************************/

void TC_Close (INT32U chan)
{
    TC_DESC *tc = &dev_tc[chan];
    tc->reg->TC_CCR = AT91C_TC_CLKDIS;
    tc->reg->TC_IDR = 0xffffffff;
    AT91F_PS_DisablePeriphClock(AT91C_BASE_PS,1 << tc->pid);
}


/******************************************************************* 
*  TC_Read - read TC's current counter
*******************************************************************/

INT32U TC_Read (INT32U chan)
{
    TC_DESC *tc = &dev_tc[chan];
    return (tc->reg->TC_CV);
    
}

/****************************************************************** 
* write TC's RA,RB,RC
******************************************************************/

void TC_Write (INT32U chan, INT32U ra, INT32U rb, INT32U rc)
{
	TC_DESC *tc = &dev_tc[chan];

	tc->reg->TC_RA = ra;
	tc->reg->TC_RB = rb;
	tc->reg->TC_RC = rc;
}

/****************************************************************** 
*  READ THE TC SR REGISTER
******************************************************************/
INT32U TC_GetStatus(INT32U chan)
{
    TC_DESC *tc = &dev_tc[chan];
    // Return the value of the Status Register
    return ( tc->reg->TC_SR ) ;
}

/****************************************************************** 
*  CONFIG A TC AS RC COMPARE MODE ,AND RC COMPARE TIGGER ENABLE
*  FIRST CALL TC_Open;
******************************************************************/
void TC_Config (INT32U chan, INT32U us, INT32U mcki)
{
    TC_DESC *tc = &dev_tc[chan];
	INT32U rc, clk;

    /* disable TC and interrupt */
    tc->reg->TC_CCR = AT91C_TC_CLKDIS;
    tc->reg->TC_IDR = 0xffffffff;

	/* calc TC register value */
	TC_Calculate_Clk(us, mcki, &rc, &clk);
	
	tc->reg->TC_RA = 0;
	tc->reg->TC_RB = 0;
	tc->reg->TC_RC = rc;
	tc->reg->TC_CMR &= 0xFFF8; // clear TCCLKS
	tc->reg->TC_CMR |= clk&0x07|AT91C_TC_WAVE|AT91C_TC_CPCTRG; 	
    /* enable TC */
    tc->reg->TC_CCR = AT91C_TC_CLKEN;	
}


/****************************************************************** 
*  SET COMMAND TO TC
******************************************************************/
INT32U TC_Ioctl (INT32U chan, INT32U cmd, INT32U *arg)
{
    TC_DESC *tc = &dev_tc[chan];
    INT32U dummy;
    
    switch (cmd) {
    case TC_CMD_BLOCK_MODE:
        AT91C_BASE_TCB0->TCB_BMR = (INT32U) arg;
        break;
    case TC_CMD_BLOCK_SYNC:
        AT91C_BASE_TCB0->TCB_BCR = AT91C_TCB_SYNC;
        break;
    case TC_CMD_START:
        tc->reg->TC_CCR = AT91C_TC_SWTRG;
        break;
    case TC_CMD_INT_ENABLE:
        tc->reg->TC_IER = (INT32U) arg;
        break;
    case TC_CMD_INT_ACK:
        dummy = tc->reg->TC_SR;
        break;
    case TC_CMD_MODE_CAPTURE:
    case TC_CMD_MODE_WAVEFORM:
    
    default:
        return (false);
    }
    return (true);
}

/*************************************************************
*  初始化作为系统时基的定时器0
*************************************************************/

void AT91_TC0_Init(void (*isr_handler)(void))
{
    TC_Open (SYS_TC0,TC_CLKS_MCK128|AT91C_TC_CPCTRG,0,0,0);
    AIC_Install_Isolate( AT91C_ID_TC0,TC0_PRIO,AIC_LEVEL_LOW, isr_handler);    
    TC_Config (SYS_TC0,(1000/OS_TICKS_PER_SEC)*1000,MCK);
    AIC_Int_Enable(AT91C_ID_TC0);    
    TC_Ioctl(SYS_TC0, TC_CMD_START, NULL);
    TC_Ioctl(SYS_TC0, TC_CMD_INT_ENABLE, (INT32U *)AT91C_TC_CPCS);
	
}	

⌨️ 快捷键说明

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