📄 halstack.c
字号:
//get pointer to selected channel
pBuf = &pSharedMem[0] + ((current_channel-11)*PKTBUF_SIZE) + SHARED_MEM_HDR ;
if (rx_flag) {
hdr = (UINT32 *)&pSharedMem[0];
//copy the global msg ID
last_global_msg_id = *(hdr+1);
//if get here we have the shared object
//first, check RX
//copy over the entire hdr first to the selected channel
CopyMemory(pktbuf,(PVOID)pBuf, sizeof(UINT32)+2);
sender_pid = pktbuf[0];
sender_pid += ((UINT32)pktbuf[1] << 8);
sender_pid += ((UINT32)pktbuf[2] << 16);
sender_pid += ((UINT32)pktbuf[3] << 24);
sender_msgid = pktbuf[4];
pktlen = pktbuf[5];
if (sender_pid && sender_pid != mypid){
if ((sender_pid != last_rx_pid) ||
sender_msgid != last_rx_msgid) {
//new msg, copy it out
last_rx_pid = sender_pid;
last_rx_msgid = sender_msgid;
fcflsb = *(pBuf+7);
fcfmsb = *(pBuf+8);
dsn = *(pBuf+9);
//check if received byte is ACK first!
if (LRWPAN_IS_ACK(fcflsb)) {
//this is an ACK!
//do call back here, do not allocate space
phyRxCallback();
macRxCallback(pBuf+6, *(pBuf+10));
DEBUG_STRING(2,"Received ACK\n");
goto DoSharedMemTxRx_exit;
}
//Need to check for address rejection HERE
if (!local_radio_flags.bits.listen_mode && !util_accept_packet(pBuf+6)) {
DEBUG_STRING(2,"Packet rejected by address filtering\n");
goto DoSharedMemTxRx_exit;
}
//see if MAC has room
if (macRxBuffFull()) {
DEBUG_STRING(2,"MAC Rx buffer is full, rejecting packet!\n");
goto DoSharedMemTxRx_exit;
}
//now copy the payload
newpkt = MemAlloc(pktlen);
CopyMemory(newpkt,(PVOID)(pBuf+sizeof(UINT32)+2),pktlen);
DEBUG_STRING(DBG_INFO,"In shared memory, received msg size: ");
DEBUG_UINT8(DBG_INFO,pktlen);
DEBUG_STRING(DBG_INFO,"\n");
phyRxCallback();
macRxCallback(newpkt, *(newpkt+pktlen-2)); //rssi byte
//before returning, see if this packet had an ACK request
if (LRWPAN_GET_ACK_REQUEST(fcflsb)&& !local_radio_flags.bits.listen_mode) {
//we just received a packet with request for ACK
//and we are not in listen mode, so do autoack
//the AUTOACK will wipe out this packet for other Node processes
//that have not yet read it, but this is ok because is the
//ACK request bit is set, then there is only one recipeient
hdr = (UINT32 *)&pSharedMem[0];
//write the TX in progress flag
*hdr = 1;
//copy the global msg ID
last_global_msg_id = *(hdr+1);
write_shmem_hdr(&pktbuf[0], mypid, tx_msgid, LRWPAN_ACKFRAME_LENGTH+1);
tx_msgid++;
//format the packet same as way as it sits in RXFIFO
//as this is how we pass it to MAC routines
pktbuf[6] = LRWPAN_ACKFRAME_LENGTH; //length, NOT including packet
//format the fcslsb
pktbuf[7] = LRWPAN_FRAME_TYPE_ACK; //fcslsb
pktbuf[8] = 0; //fcsMSB
pktbuf[9] = dsn;
pktbuf[10] = util_get_rssi();
pktbuf[11] = util_get_CRC();
CopyMemory((PVOID)pBuf, &pktbuf[0], 12);
*(hdr+2) = halGetMACTimer(); //write transmit start time to header
//clear the TX in progress
*hdr = 0;
//increment the global msg id
*(hdr+1) = *(hdr+1) + 1;
last_global_msg_id = *(hdr+1); //save it
Sleep(0); //send the ack, give time to read
DEBUG_STRING(2,"Sent auto-ack\n");
goto DoSharedMemTxRx_exit;
}
}
}
} else {
DEBUG_STRING(DBG_INFO,"Writing to shared memory..\n");
hdr = (UINT32 *)&pSharedMem[0];
phyTxStartCallBack();
//write the TX in progress flag
*hdr = 1;
//copy the global msg ID
last_global_msg_id = *(hdr+1);
write_shmem_hdr(&pktbuf[0], mypid, tx_msgid, plen);
memcpy(&pktbuf[6],pload,plen);
//now copy to shared memory
CopyMemory((PVOID)pBuf, &pktbuf[0], plen+ sizeof(UINT32)+2);
*(hdr+2) = halGetMACTimer(); //write transmit start time to header
//clear the TX in progress
*hdr = 0;
//increment the global msg id
*(hdr+1) = *(hdr+1) + 1;
last_global_msg_id = *(hdr+1); //save it
//now do TX
tx_msgid++;
}
DoSharedMemTxRx_exit:
//release Mutex
rc = ReleaseMutex(hMutex);
if (!rc) printf("Release Mutex failed!");
}
//halInit contains both processor specific initialization
void halInit(void){
radio_state = RADIO_STATE_OFF;
local_radio_flags.val = 0;
halInitUart();
halInitMACTimer();
InitSharedMemory();
}
//we are going to initialize the console to single character
//input, and no echo to emulate the micro
void halInitUart(void) {
DWORD cRead, cWritten, fdwMode, fdwOldMode;
hStdin = GetStdHandle(STD_INPUT_HANDLE);
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE ||
hStdout == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, "GetStdHandle", "Console Error", MB_OK);
return;
}
if (! GetConsoleMode(hStdin, &fdwOldMode))
{
MessageBox(NULL, "GetConsoleMode", "Console Error", MB_OK);
return;
}
fdwMode = fdwOldMode &
~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
if (! SetConsoleMode(hStdin, fdwMode))
{
MessageBox(NULL, "SetConsoleMode", "Console Error", MB_OK);
return;
}
}
//get a character from serial port
char halGetch(void){
return ((char) getchar());
}
//write a character to serial port
// Uses UART initialized by halInitUart
void halPutch(char c){
putchar(c); //char does not appear on console until '\r' is sent
}
void halInitMACTimer(void) {
BOOL x;
x = QueryPerformanceFrequency(&lpFrequency);
if (x == FALSE){
printf("High Performance Counter not supported\n");
}
else{
printf("High Performance Counter is supported\n");
tics_per_second = lpFrequency.LowPart;
}
}
//assuming 2.4GHz, so 1 symbol = 16 us
UINT32 sym_to_ticks(UINT32 x){
double fticks;
UINT32 rval;
fticks = (1.0/(LRWPAN_SYMBOLS_PER_SECOND) * ((float)tics_per_second))*x;
//printf("Symbols: %u, Tics per second: %u, fticks:%f\n",
// x,tics_per_second,fticks);
rval = (UINT32) fticks;
return(rval);
}
//this is inaccurate since there is less than one symbol per MAC tic
//under WIN32
UINT32 sym_per_mac_tick(void){
double symbols_per_tick;
UINT32 rval;
symbols_per_tick = 1.0 /((1.0/(LRWPAN_SYMBOLS_PER_SECOND) * ((float)tics_per_second)));
rval = (UINT32) symbols_per_tick;
if (!rval)rval++; //don't return 0
return(rval);
}
UINT32 msecs_to_ticks(UINT32 x){
double fsecs,fticks;
UINT32 rval;
fsecs = ((float)x)/1000;
fticks = fsecs * tics_per_second;
rval = (UINT32) fticks;
return(rval);
}
UINT32 halMacTicksToUs(UINT32 x){
double usecs;
UINT32 rval;
usecs = (((float)x)/((float)tics_per_second)) * 1000000;
rval = (UINT32) usecs;
return(rval);
}
UINT32 halGetMACTimer(void){
LARGE_INTEGER timecnt;
UINT32 x;
QueryPerformanceCounter(&timecnt);
x = timecnt.LowPart;
return x;
}
#if 0
UINT32 halMACTimerNowDelta(UINT32 x) {
return(((halGetMACTimer()-(x))& MACTIMER_MAX_VALUE));
}
UINT32 halMACTimerNowDelta_dbg(UINT32 x) {
UINT32 p,q,y;
p = halGetMACTimer();
q = p - x;
y = q & MACTIMER_MAX_VALUE;
return(y);
}
#endif
void halUtilMemCopy(BYTE *dst, BYTE *src, BYTE len) {
while (len) {
*dst = *src;
dst++;src++;
len--;
}
}
UINT8 halGetRandomByte(void) {
LARGE_INTEGER timecnt;
UINT32 x;
QueryPerformanceCounter(&timecnt);
x = timecnt.LowPart;
return((UINT8)x);
}
LRWPAN_STATUS_ENUM halInitRadio(PHY_FREQ_ENUM frequency, BYTE channel, RADIO_FLAGS radio_flags)
{
if ((channel < 11) || (channel > 26)) {
printf("Error in halInitRadio, invalid channel: %d\n",channel);
return(LRWPAN_STATUS_PHY_FAILED);
}
current_channel = channel;
local_radio_flags = radio_flags;
radio_state = RADIO_STATE_ON;
block_radio_rx = FALSE;
return(LRWPAN_STATUS_SUCCESS);
}
void halDisableRadio(void){
block_radio_rx = TRUE;
radio_state = RADIO_STATE_OFF;
}
void halShutdown(void) {
halDisableRadio();
}
//nothing to do
void halWarmstart(void) {}
LRWPAN_STATUS_ENUM halSetChannel(BYTE channel){
current_channel = channel;
return(LRWPAN_STATUS_SUCCESS);
}
LRWPAN_STATUS_ENUM halSendPacket(BYTE flen, BYTE *frm)
{
BYTE tmpbuf[LRWPAN_MAX_FRAME_SIZE+1]; //maximum payload size
BYTE *ptr;
if ((flen+2) > LRWPAN_MAX_FRAME_SIZE) {
printf("Error in halSendPacket, frame size: %d exceeds max size: %d\n",
flen, LRWPAN_MAX_FRAME_SIZE);
return LRWPAN_STATUS_PHY_TX_START_FAILED;
}
//format the packet in the same way as it sits in RXFIFO.
//First byte is length that does not include lenght byte
ptr = &tmpbuf[0];
*ptr = flen+2; //length does not include length byte
ptr++;
//copy frame
memcpy(ptr,frm,flen);
ptr = ptr+flen;
//set frame check sequence
*ptr = util_get_rssi(); //dummy RSSI
ptr++;
*ptr = util_get_CRC(); //CRC byte
ptr = &tmpbuf[1];
DEBUG_STRING(DBG_INFO,"TXing packet\n");
DEBUG_PRINTPACKET(DBG_INFO, ptr, flen+2);
//now transmit the packet
ptr = &tmpbuf[0];
DoSharedMemTxRx(FALSE, ptr, flen+2+1);
macTxCallback(); //do MAC TX callback
phyTxEndCallBack();
Sleep(0); //sleep for a bit to allow other process to read it
return(LRWPAN_STATUS_SUCCESS);
}
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;
}
void halIdle(void) {
}
void halSetRadioPANID(UINT16 panid){
radio_panid = panid;
}
void halSetRadioShortAddr(SADDR saddr){
radio_saddr = saddr;
}
void halSleep(UINT32 msecs) {
//sleep for this number of milliseconds
Sleep(msecs);
}
void halWaitMs(UINT32 msecs){
UINT32 this_timer;
this_timer = halGetMACTimer();
while (halMACTimerNowDelta(this_timer) < MSECS_TO_MACTICKS(msecs));
}
void halSuspend(UINT32 msecs) {
//sleep for this number of milliseconds
Sleep(msecs);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -