?? halstack.c
字號:
/*
V0.1 Initial Release 10/July/2006 RBR
*/
#include <stdio.h>
#include "lrwpan_config.h"
#include "hal.h"
#include "halstack.h"
#include "console.h"
#include "debug.h"
#include "ieee_lrwpan_defs.h"
#include "memalloc.h"
static RADIO_FLAGS local_radio_flags;
static UINT16 radio_panid;
static SADDR radio_saddr;
static BYTE current_channel; //channels 11 to 16
typedef enum _RADIO_STATE_ENUM {
RADIO_STATE_OFF,
RADIO_STATE_ON
}RADIO_STATE_ENUM;
RADIO_STATE_ENUM radio_state;
#ifdef LRWPAN_ASYNC_INTIO
static volatile BYTE serio_rxBuff[LRWPAN_ASYNC_RX_BUFSIZE];
static volatile BYTE serio_rxHead, serio_rxTail;
#endif
//halInit contains both processor specific initialization
void halInit(void){
radio_state = RADIO_STATE_OFF;
local_radio_flags.val = 0;
halInitUart();
halInitMACTimer();
}
//we are going to initialize the console to single character
//input, and no echo to emulate the micro
void halInitUart(void) {
TX9 = 0; TXEN = 1; // transmit enable SYNC = 0; // async mode BRGH = 1; // hi speed mode halSetBaud(LRWPAN_DEFAULT_BAUDRATE); TRISC7=1; // RC7 input TRISC6=0; // RC6 output RX9 = 0; // 8-bit reception SPEN = 1; // serial port enable CREN = 0; // clear enable first CREN = 1; // now enable first
#ifdef LRWPAN_ASYNC_INTIO
RCIE = 0;
serio_rxHead = 0;
serio_rxTail = 0;
RCIE = 1;
RCIP = 1;
PEIE = 1;
#endif
}
#ifdef LRWPAN_ASYNC_INTIO
//get a character from serial port, uses interrupt driven IO
char halGetch(void){
while(serio_rxTail == serio_rxHead);
serio_rxTail++;
if (serio_rxTail == LRWPAN_ASYNC_RX_BUFSIZE) serio_rxTail = 0;
return (serio_rxBuff[serio_rxTail]);
}
BOOL halGetchRdy(void){
return(serio_rxTail != serio_rxHead);
}
#else
char halGetch(void){
while(!RCIF);
return(RCREG);
}
BOOL halGetchRdy(void){
return(RCIF);
}
#endif
//write a character to serial port
// Uses UART initialized by halInitUart
void halPutch(char c){
while(!TXIF);
TXREG = c;
}
void halRawPut(char c){
while(!TXIF);
TXREG = c;
}
//defined such that timer0 has a period of 1 symbol, or 16 us
//FOSC assumed to be some multiple of 4 MHZ
#define SYMBOL_FREQ 62500 //equals to symbols period of 16us
#define T0_PRESCALE ((FOSC/(SYMBOL_FREQ/SYMBOLS_PER_MAC_TICK()))/4)
#define MAX_WAIT_MS (TO_PRESCALE*4*65536*1000)/FOSC //maximum wait in milliseconds
#if T0_PRESCALE > 256
#error "Timer 0 PRESCALE TOO LARGE"
#endif
#if (T0_PRESCALE == 256)
#define T0_PREBITS 7
#elif (T0_PRESCALE == 128)
#define T0_PREBITS 6
#elif (T0_PRESCALE == 64)
#define T0_PREBITS 5
#elif (T0_PRESCALE == 32)
#define T0_PREBITS 4
#elif (T0_PRESCALE == 16)
#define T0_PREBITS 3
#elif (T0_PRESCALE == 8)
#define T0_PREBITS 2
#elif (T0_PRESCALE == 4)
#define T0_PREBITS 1
#elif (T0_PRESCALE == 2)
#define T0_PREBITS 0
#else
#error "Illegal Timer0 prescale!"
#endif
#define T3_PRESCALE 8
#if (T3_PRESCALE == 8)
#define T3_PREBITS (3 << 4)
#elif (T3_PRESCALE == 4)
#define T3_PREBITS (2<< 4)
#elif (T3_PRESCALE == 2)
#define T0_PREBITS (1 << 4)
#elif (T3_PRESCALE == 1)
#define T3_PREBITS 0
#else
#error "Illegal Timer0 prescale!"
#endif
#define T3PERIOD ((FOSC/4)/T3_PRESCALE)/SLOWTICKS_PER_SECOND
#if (T3PERIOD > 65535)
#error "slow_tics_per_second define is too small!"
#endif
UINT8 halMacTimerOflow; //assumed incremented by interrupt service
//Timer0 used as MAC timer, Timer3/CCP1 capture compare as theuser periodic interrupt timer
void halInitMACTimer(void) {
halMacTimerOflow =0;
//setup Timer0
T0CON = T0_PREBITS ; //convenient that all other bits beside prescale are '0'
TMR0H = 0;
TMR0L = 0;
TMR0IF = 0;
#ifdef LRWPAN_ENABLE_SLOW_TIMER
//setup Timer3, will use compare mode with CCP1
T3CON = 0xC0 | T3_PREBITS; //uses TMR3 as clock source for compare modules
TMR3H = 0;
TMR3L = 0;
TMR3IF = 0;
//configure CCP1 as period register for Timer3
CCP1IF = 0;
CCP1CON = 0; //reset
CCP1CON = 0x0A; //software interrupt on timer match
T3CCP1 = 0;
T3CCP2 = 1; //select timer3 as match source
//setup the first match with CCP1
//now configure interrupts
TMR3IE = 0;
CCPR1 = T3PERIOD;
CCP1IP = 1;
CCP1IE = 1;
TMR3ON = 1;
#endif
TMR0IE = 1;
//turn on the timers
TMR0ON = 1;
IPEN = 0; //disable priorities
GIEL = 1;
}
void halShutdown(void){
//disable timer interrupts so that they don't wake us up
TMR0IE = 0;
#ifdef LRWPAN_ENABLE_SLOW_TIMER
CCP1IE = 0;
#endif
halDisableRadio();
}
void halWarmstart(void){
//enable timer interrupts
TMR0IE = 1;
#ifdef LRWPAN_ENABLE_SLOW_TIMER
CCP1IE =1;
#endif
}
//only works as long as SYMBOLS_PER_MAC_TICK is not less than 1
UINT32 halMacTicksToUs(UINT32 ticks){
UINT32 rval;
rval = (ticks/SYMBOLS_PER_MAC_TICK())* (1000000/LRWPAN_SYMBOLS_PER_SECOND);
return(rval);
}
//read the macTimer, assumes interrupts, Timer0 are enabled!
UINT32 halGetMACTimer(void)
{
UINT8 iStatus;
UINT32 rval;
do {
rval = TMR0L; //freeze timer 0
rval += ((UINT16) TMR0H << 8);
SAVE_AND_DISABLE_GLOBAL_INTERRUPT(iStatus) ;
if (rval > 2) { //ok, trust that the Oflow byte is correctly incremented by ISR
break;
}
RESTORE_GLOBAL_INTERRUPT(iStatus) ; //renable global interrupt, allow to tick some more
}
while(1);
//at this point, global interrupts are disabled, read overflow value
rval += ((UINT32) halMacTimerOflow) << 16;
RESTORE_GLOBAL_INTERRUPT(iStatus) ;
return (rval);
}
#ifdef LRWPAN_COMPILER_NO_RECURSION
UINT32 halISRGetMACTimer(void)
{
UINT8 iStatus;
UINT32 rval;
do {
rval = TMR0L; //freeze timer 0
rval += ((UINT16) TMR0H << 8);
SAVE_AND_DISABLE_GLOBAL_INTERRUPT(iStatus) ;
if (rval > 2) { //ok, trust that the Oflow byte is correctly incremented by ISR
break;
}
RESTORE_GLOBAL_INTERRUPT(iStatus) ; //renable global interrupt, allow to tick some more
}
while(1);
//at this point, global interrupts are disabled, read overflow value
rval += ((UINT32) halMacTimerOflow) << 16;
RESTORE_GLOBAL_INTERRUPT(iStatus) ;
return (rval);
}
#endif
UINT32 halMACTimerNowDelta(UINT32 x){
UINT32 now;
now = halGetMACTimer();
now = (now - x);
now = now & (UINT32) MACTIMER_MAX_VALUE;
return(now);
}
void halUtilMemCopy(BYTE *dst, BYTE *src, BYTE len) {
while (len) {
*dst = *src;
dst++;src++;
len--;
}
}
void halGetProcessorIEEEAddress(BYTE *buf) {
buf[0] = aExtendedAddress_B0;
buf[1] = aExtendedAddress_B1;
buf[2] = aExtendedAddress_B2;
buf[3] = aExtendedAddress_B3;
buf[4] = aExtendedAddress_B4;
buf[5] = aExtendedAddress_B5;
buf[6] = aExtendedAddress_B6;
buf[7] = aExtendedAddress_B7;
}
//this is a software delay loop, not meant for precision
void halWaitMs (UINT32 msecs){ UINT32 i, cnt;
cnt = msecs; do { i = 20; do { halWaitUs(50); } while(--i); } while(--cnt);}
void halIdle(void) {
CLRWDT(); //clear the watchdog timer
}
//simple implementation that ignores the argument and that simply
//sleeps for the duration of the of the watchdog timer timeout
void halSleep(UINT32 msecs) {
ENABLE_WDT() ;
IDLEN = 0;
SLEEP();
NOP();
DISABLE_WDT();
}
//ISR stuff
#ifdef MCC18
#pragma interruptlow HighISR
void HighISR(void)
#endif
#ifdef HI_TECH_C
void interrupt HighISR(void)
#endif
{
//handle Timer0 interrupt first, mac timer overflow
if (TMR0IF && TMR0IE) {
TMR0IF=0;
halMacTimerOflow++;
}
#ifdef LRWPAN_ENABLE_SLOW_TIMER
//CCP1IF use for period interrupt generation with TIMER3
if (CCP1IF && CCP1IE) {
CCP1IF = 0;
CCPR1 = CCPR1 + T3PERIOD; //setup next interrupt
evbIntCallback(); // call evb
//call the usrInterrupt
usrSlowTimerInt();
}
#endif
#ifdef LRWPAN_ASYNC_INTIO
if (RCIF && RCIE) {
serio_rxHead++;
if (serio_rxHead == LRWPAN_ASYNC_RX_BUFSIZE ) serio_rxHead = 0;
serio_rxBuff[serio_rxHead] = RCREG;
}
#endif
evbRadioIntCallback();
usrIntCallback();
}
//vector everything to high priority interrup
#if defined(MCC18)
#pragma code HighVector=0x08
void HighVector (void)
{
_asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif
#if defined(MCC18)
#pragma code lowhVector=0x18
void LowVector (void)
{
_asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -