📄 rf256_drv.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 + -