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

📄 rf256_drv.c

📁 小区巡检系统,MSPF437,里面主要参考的内容为TI单片机的低功耗处理,仅供参考,不能用于商业.
💻 C
字号:
/* rf256_drv.c */

#include "hal.h"
#include "pub_func.h"

/* rf256_drv.h */
#include "rf256_drv.h"


/* turn RF on
*/
void rf_on(void)
{
    //init RF related pin
    RF_PWC_PIN_INIT();
    RF_CLK_PIN_INIT();
    RF_RX_PIN_INIT();
    RF_TX_PIN_INIT();
    //turn RF field on
    RF_TX_0();

    //must power on after PIN Init
    RF_PWC_ON();

    //init TA
    TACTL = TASSEL_0+MC_2+TACLR;
}

/* turn RF off
*/
void rf_off(void)
{
    //power off
    RF_PWC_OFF();

    //close TA?

    //must uninit after power off 
    //just to reduce power
    RF_RX_PIN_UNINIT();
    RF_CLK_PIN_UNINIT();

    RF_TX_0();
}

/* find window
*/
static int rf_findwindow(void)
{
    unsigned short time_walk=0;

    //must turn RF field on
    RF_TX_0();    

    for(;;)
    {
          //reset 
        TACTL |= TACLR;

        do{
            
            //we got the window
            if(TAR > (RF_FLSTNW_START_THRES-5)) {
                return 0;
            }

            //max time before failure
            //if(time_walk> RF_FLSTNW_FAIL_THRES)
            if(time_walk> 340)
            {
                //failed
                return 1;
            }

            time_walk++;

        }while(RF_RX_BIT() == RF_FLSTNW_LEVEL);
        
    }
    
}

/* read a page miller code, the frame must have start/stop bit
*/
int _rf_readmiller(long * page)
{
    char lvl; // current lvl
    char prelvl;  //previouse lvl
    
    char bitcnt;
    char start;

    int lvl_chg;  //level change time

    char halfbit; 
    char bwidth; //bit width

    //_clr_wdt();
    //find window
    if(rf_findwindow()) {  
        return 1;
    }
    //_clr_wdt();
    
    //start bit is 0, start level is 1
    prelvl = ((~RF_FLSTNW_LEVEL) & 0x01);
    //start time 0
    lvl_chg = 0;

    bitcnt = 0;
    start = 0;
    
    //reset timer
    TACTL |= TACLR;
    
    //wait for first lvl, bypass window
    while(RF_RX_BIT() == RF_FLSTNW_LEVEL)
    {
        if(TAR > RF_FLSTNW_WIDTH) {
            return 2;
        }
    }

    //reset timer
    TACTL |= TACLR;

    do
    {
        //wait 1 bit
        do {
            
            bwidth = TAR-lvl_chg;
            // 2.5 bit width without level change, impossible
            if(bwidth > (RFRX_2BIT_WIDTH+RFRX_BIT_DISTORT)) {
                return 4;
            }
            lvl = RF_RX_BIT();
            
        }while(lvl == prelvl);

        bwidth = TAR-lvl_chg;
        //save
        lvl_chg = lvl_chg+bwidth;
        prelvl = lvl;

        if(start == 0) {
            start = 1;
            if((bwidth >= (RFRX_BIT_WIDTH-RFRX_BIT_DISTORT))
                                && (bwidth <= (RFRX_BIT_WIDTH+RFRX_BIT_DISTORT)))
            {
                halfbit = 0;
            }
            else
            {
                halfbit = 1;
            }

            continue;
        }

        // 1 bit
        if((bwidth >= (RFRX_BIT_WIDTH-RFRX_BIT_DISTORT))
            && (bwidth <= (RFRX_BIT_WIDTH + RFRX_BIT_DISTORT)))
        {
            (*page) <<= 1;
            (*page) |= halfbit;
            bitcnt ++;

            continue;
        }
        
        // 1.5bit
        if((bwidth >= (RFRX_15BIT_WIDTH-RFRX_BIT_DISTORT))
            && (bwidth <= (RFRX_15BIT_WIDTH+RFRX_BIT_DISTORT)))
        {
            //toggle first
            halfbit = 1-halfbit;
            if(halfbit == 0)
            {
                goto _add1;
            }
            else
            {
                goto _add0;
            }
        }
        // 2bit
        else
        {
            goto _add1;
        }

_add1:
        (*page) <<= 1;
        (*page) |= 1;
        bitcnt ++;
_add0:
        
        (*page) <<= 1;
        bitcnt ++;
        
    }while(bitcnt < RFPAGE_LEN);
    
    return 0;
    
}

int rf_readmiller(long * page)
{
    long cmp;
    char tempt;
    char rc;

    for(tempt=0; tempt<3; tempt++)
    {
        rc = (char)_rf_readmiller(page);
        //_clr_wdt();

        cmp = *page;
        rc += (char)_rf_readmiller(page);
        //_clr_wdt();

        //error, try again
        if(rc) continue;

        //correct
        if(cmp == *page) {
            break;
        }
        rc = 8;
    }

    return rc;
}

#ifdef _RF_WRITE
static void _rf_wait(int next_tar)
{
    //start time, exactly on 0.5 bit 
    next_tar = (TAR & (~(RFTX_05BIT_WIDTH-1))) + (next_tar);
    
    while(TAR < next_tar)
    {
        //wait for next thres
        __no_operation();
    }
}
#endif

#ifdef _RF_WRITE
/* write manchester code
*/
static int _rf_writemanchester(char bdata, char bitcnt)
{
    signed char k;
    unsigned char parity = 0;


    int next_tar;

    if(bitcnt == RFCMD_LEN) {
        next_tar = 0;
        //reset timer
        TACTL |= TACLR;

    } else {
        next_tar = RFTX_05BIT_WIDTH-1;
    }

    for(k=0; k<bitcnt; k++)
    {
        _rf_wait(next_tar);

        //on bit
        if(bdata & 0x80) {
            RF_TX_0();
        } 
        else {
            RF_TX_1();
        }
        // have to set again
        next_tar = RFTX_05BIT_WIDTH-1;

        _rf_wait(next_tar);
        
        //on half bit
        if(bdata & 0x80) {
            RF_TX_1();
            parity ^= 0x80;
        } 
        else {
            RF_TX_0();
        }

        bdata <<= 1;
    }
    
    return parity;
    
}
#endif

#ifdef _RF_WRITE
/* write manchester code
*/
int rf_writemanchester(char * page, int cmd)
{
    signed char k;
    
    unsigned char parity;
    
    //_clr_wdt();
    //find window
    if(rf_findwindow()) {  
        return 1;
    }
    //_clr_wdt();
    
    parity = _rf_writemanchester((char)cmd, RFCMD_LEN);

    //no data
    if(!page) goto _wdone;

    //data
    for(k=3; k>=0; k--) {
        parity ^= _rf_writemanchester(page[k], 8);
    }
    //parity
    _rf_writemanchester(parity, 1);
    
_wdone:
    
    //wait the last half bit
    _rf_wait(RFTX_05BIT_WIDTH-1);
    //must turn RF field on
    RF_TX_0();

    return 0;
    
}
#endif

#define RF_WRITE_DELAY  4096
#define RF_READ_DELAY    64

/* RF delay
*/
void rf_delay(int rnd)
{
    int rc;
    for(rc=0; rc<rnd; rc++) 
    {
        //_clr_wdt();
    }
}

#ifdef _RF_WRITE
/* read page
*/
int rf_readpage(long * page, int no)
{
    int rc;

    rf_writemanchester((char *) 0, RFCMD_RPAGE | (no << 4));

    rf_delay(RF_READ_DELAY);
    
    rc = rf_readmiller(page);

    return rc;
}
#endif

#ifdef _RF_WRITE
/* write page
*/
int rf_writepage(char * page, int no)
{
    int rc;
    long page_read;
    int tempt;

    for(tempt=0; tempt<3; tempt++)
    {
        rf_writemanchester(page, RFCMD_WPAGE | (no << 4));
        
        rf_delay(RF_WRITE_DELAY);
        
        rc = rf_readmiller(&page_read);
        
        if(rc) continue;
        
        if(*((long *)page) == page_read) {
            return 0;
        }
    }
    
    return 1;
}
#endif

#ifdef _RF_WRITE
/* write page
*/
int rf_writeoption(char * opt)
{
    char opt_read[4];
    
    opt[3] = 0x55;
        
    rf_writemanchester(opt, RFCMD_WCONF);
    
    rf_delay(RF_WRITE_DELAY);
    
    rf_readmiller((long *)&opt_read);

    if((opt_read[1] == opt[1]) && (opt_read[2] == opt[2])
                && (opt_read[0] == opt[0]))
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
#endif

#ifdef _RF_WRITE
/* write page
*/
int rf_writelock(char lock)
{
    char opt[4];

    opt[3] = lock;
    opt[2] = 0x55;
    opt[1] = 0x55;
    opt[0] = 0x55;

    rf_writemanchester(opt, RFCMD_WLOCK);
    
    rf_delay(RF_WRITE_DELAY);
    
    rf_readmiller((long *)&opt);

    if(opt[3] == lock)
    {
        return 0;
    }
    else
    {
        return 1;
    }
    
}
#endif

#ifdef _RF_WRITE
/* write password
*/
int rf_writepassword(char * password)
{
    int rc;

    rc = rf_writemanchester(password, RFCMD_WPAWD);
    
    rf_delay(RF_WRITE_DELAY);
    
    return rc;
}
#endif

#ifdef _RF_WRITE
/* check password
*/
int rf_checkpassword(char * password)
{
    int rc;

    rc = rf_writemanchester(password, RFCMD_CHK_PW);
    
    rf_delay(RF_READ_DELAY);
    
    return rc;
}
#endif

#ifdef _RF_WRITE
/* disable
*/
int rf_disable(void)
{
    int rc;

    rc = rf_writemanchester((char*)0, RFCMD_DISABL);
    
    return rc;
}
#endif

⌨️ 快捷键说明

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