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

📄 halstack.c

📁 无线单片机cc2430简化协议的无线收发程序
💻 C
📖 第 1 页 / 共 2 页
字号:




  // If the RSSI value is not valid, enable receiver
  if(RSSIL == 0x80)
  {
    ISRXON;
    // Turning on Rx and waiting 320u-sec to make the RSSI value become valid.
    halWait(1);
  }

  doIEEE_backoff();
  //Transmitting
  ISTXONCCA;       //TODO: replace this with IEEE Backoff
  state=FSMSTATE;
  if(state > 30)  //is TX active?
  {  //ConsolePutROMString("machine state:");ConsolePutInitData(0,state);	
    // Asserting the status flag and enabling ACK reception if expected.
    phyTxStartCallBack();
    res = LRWPAN_STATUS_SUCCESS;
    RFIM |= IRQ_TXDONE;             //enable IRQ_TXDONE interrupt
    //DEBUG_CHAR( DBG_TX,DBG_CHAR_TXSTART);
  }
  else
  {
    ISFLUSHTX;               //empty buffer
    res = LRWPAN_STATUS_PHY_CHANNEL_BUSY;
    RFIM &= ~IRQ_TXDONE;     //mask interrupt
    //DEBUG_CHAR( DBG_TX,DBG_CHAR_TXBUSY);
  }

  return(res);
}

//This timer interrupt is the periodic interrupt for
//evboard functions

#ifdef LRWPAN_ENABLE_SLOW_TIMER
#pragma vector=T2_VECTOR
__interrupt static void t2_service_IRQ(void){
  UINT32_UNION t;

  INT_GLOBAL_ENABLE(INT_OFF);
  INT_SETFLAG_T2(INT_CLR); //clear processor interrupt flag
   //compute next compare value by reading current timer value, adding offset
  t.bytes[UINT32_LOWORD_LSB] = T2OF0;
  t.bytes[UINT32_LOWORD_MSB] = T2OF1;
  t.bytes[UINT32_HIWORD_LSB] = T2OF2 & 0x0F;
  t.val = t.val + T2CMPVAL;  //add offset
  T2PEROF0 = (BYTE)  t.bytes[UINT32_LOWORD_LSB];
  T2PEROF1 = (BYTE) t.bytes[UINT32_LOWORD_MSB];
  //enable overflow count compare interrupt
  T2PEROF2 = t.bytes[UINT32_HIWORD_LSB] | 0x20;
  T2CNF = 0x03; //this clears the timer2 flags
  INT_GLOBAL_ENABLE(INT_ON);
}
#endif




//interrupt for RF error
//this interrupt is same priority as FIFOP interrupt,
//but is polled first, so will occur first.

#pragma vector=RFERR_VECTOR
__interrupt static void rf_error_IRQ(void)
{
   INT_GLOBAL_ENABLE(INT_OFF);

   // If Rx overflow occurs, the Rx FiFo is reset.
   // The Rx DMA is reset and reception is started over.
   if(FSMSTATE == 17)
   {
      DEBUG_CHAR( DBG_ITRACE,DBG_CHAR_TXBUSY);
      STOP_RADIO();
      ISFLUSHRX;
      ISFLUSHRX;
      ISRXON;
   }
   else if(FSMSTATE == 56)
   {
      DEBUG_CHAR( DBG_ITRACE,DBG_CHAR_RXOFLOW);
      ISFLUSHTX;
   }

   INT_SETFLAG_RFERR(INT_CLR);

   INT_GLOBAL_ENABLE(INT_ON);
}


//This interrupt used for both TX and RX
#pragma vector=RF_VECTOR
__interrupt void spp_rf_IRQ(void) //数据收发中断
{
  //used by spp_rf_IRQ


  BYTE flen;
  BYTE enabledAndActiveInterrupt;
  BYTE *ptr, *rx_frame;
  BYTE ack_bytes[5];
  BYTE crc;

  MACPKT *macpkt;
  //define alternate names for readability in this function
#define  fcflsb ack_bytes[0]
#define  fcfmsb  ack_bytes[1]
#define  dstmode ack_bytes[2]
#define  srcmode ack_bytes[3]

  //DEBUG_STRING(DBG_TX,"spp_rf_IRQ()\n");


  INT_GLOBAL_ENABLE(INT_OFF);
  enabledAndActiveInterrupt = RFIF;
  RFIF = 0x00;                        // Clear all radio interrupt flags
  INT_SETFLAG_RF(INT_CLR);    // Clear MCU interrupt flag
  enabledAndActiveInterrupt &= RFIM;


  // complete frame has arrived
  if(enabledAndActiveInterrupt & IRQ_FIFOP)//接收一帧数据
  {
   // DEBUG_CHAR( DBG_ITRACE,DBG_CHAR_RXRCV );

    ptr = NULL; //temporary pointer
    flen = RFD & 0x7f;  //read the length
    if (flen == LRWPAN_ACKFRAME_LENGTH) //应答帧
	{
      //DEBUG_CHAR( DBG_ITRACE,DBG_CHAR_ACKPKT );
      ack_bytes[0]= flen;
      ack_bytes[1] =  RFD;  //LSB Frame Control Field
      ack_bytes[2] = RFD;   //MSB Frame Control Field
      ack_bytes[3] = RFD;   //dsn
      ack_bytes[4] = RFD;   //RSSI
      crc = RFD;//check CRC
      if (crc & 0x7f)
	  {
        macRxCallback(ack_bytes, ack_bytes[4]);
      }
    }
	else
	{
      fcflsb = RFD;
      fcfmsb = RFD;
      if (!local_radio_flags.bits.listen_mode)
	  {
        srcmode = LRWPAN_GET_SRC_ADDR(fcfmsb);
        dstmode = LRWPAN_GET_DST_ADDR(fcfmsb);
        if ((srcmode == LRWPAN_ADDRMODE_NOADDR) && (dstmode == LRWPAN_ADDRMODE_NOADDR))
		{
          goto do_rxflush;//reject this packet, no addressing info
        }
      }

      rx_frame=NULL; //bhj add

	
      if (!macRxBuffFull())
	  {
        //rx_frame = MemAlloc(flen+1);
		macpkt = macRxGetBuffer();
		rx_frame = macpkt->data;		
        ptr = rx_frame;
      }
	  else
	  {
        //DEBUG_CHAR( DBG_ITRACE,DBG_CHAR_MACFULL );
      }

      if (ptr == NULL)
	  {
        goto do_rxflush;//just flush the bytes
      }
	  else
	  {

        *ptr = flen; ptr++;//save packet, including the length
        *ptr = fcflsb; ptr++; flen--;//save the fcflsb, fcfmsb bytes
        *ptr = fcfmsb; ptr++; flen--;
        while (flen) { *ptr = RFD;  flen--; ptr++; }//get the rest of the bytes, 最后两个字节:rssi + crc

		macpkt->rssi=*(ptr-2);
		macpkt->CRC=*(ptr-1);

		        	
		if(*(ptr-1)&0x80!=0x80)
        {
          //crc error
        }
		
        *(ptr-2) = *(ptr-2) + 0x80;//change the RSSI byte from 2's complement to unsigned number
        phyRxCallback();

			
      }
    }


  do_rxflush://flush any remaining bytes
      ISFLUSHRX;
      ISFLUSHRX;


    RFIF = 0x00;//don't know why, but the RF flags have to be cleared AFTER a read is done.
    INT_SETFLAG_RF(INT_CLR);    // Clear MCU interrupt flag
    //don't know why, but the interrupt mask has to be set again here for some reason.
    //the processor receives packets, but does not generate an interrupt
    RFIM |= IRQ_FIFOP;
  }//end receive interrupt (FIFOP)


  if(enabledAndActiveInterrupt & IRQ_TXDONE)//发送完一帧数据
  {
    //Finished TX, do call back
    //DEBUG_CHAR( DBG_ITRACE,DBG_CHAR_TXFIN );
	phy_pib.flags.bits.txFinished = 1;   //TX is finished.
	phyReleaseTxLock();
    macTxCallback();
    RFIM &= ~IRQ_TXDONE; // Clearing the tx done interrupt enable

  }
  INT_GLOBAL_ENABLE(INT_ON);

#undef  fcflsb
#undef  fcfmsb
#undef  dstmode
#undef  srcmode
}

//this is needed by printf()
int putchar (int c)  {
   if (c == '\n')  {
      while (!UTX0IF);
      UTX0IF = 0;
      U0DBUF = 0x0d;       /* output CR  */
   }

   while (!UTX0IF);  //wait until it is finished transmitting
   UTX0IF = 0;
   return (U0DBUF = c);
}


//software delay, waits is in milliseconds
void halWait(BYTE wait){
   UINT32 largeWait;

   if(wait == 0)
   {return;}
   largeWait = ((UINT16) (wait << 7));
   largeWait += 114*wait;


   largeWait = (largeWait >> CLKSPD);
   while(largeWait--);

   return;
}

void halWaitMs(const UINT32 msecs){
  UINT32 towait;

  towait = msecs;
  while (towait > 100) {
    halWait(100);
    towait -= 100;
  }
  halWait(towait);
}


void halShutdown(void) {
  //disable some interrupts
  #ifdef LRWPAN_ENABLE_SLOW_TIMER
  INT_ENABLE_T2(INT_OFF);
  #endif
  //disable RADIO interrupts
  //Radio RF interrupt
  INT_ENABLE_RF(INT_OFF);
  //enable RX RFERR interrupt on processor
  INT_ENABLE_RFERR(INT_OFF);
  //shutoff the analog power to the radio
  RFPWR = RFPWR | (1<<3);    //RFPWR.RREG_RADIO_PD = 1;

}

void halWarmstart(void) {
  UINT32 myticks;
   //re-enable the timer interrupt
  #ifdef LRWPAN_ENABLE_SLOW_TIMER
  INT_ENABLE_T2(INT_ON);
  #endif
  //turn on the radio again
  RFPWR = RFPWR & ~(1<<3);    //RFPWR.RREG_RADIO_PD = 0;
  //wait for power to stabilize
  myticks = halGetMACTimer();
  while (halMACTimerNowDelta(myticks) < MSECS_TO_MACTICKS(10)) {
    //check the power up bit, max time is supposed to be 2 ms
    if (!(RFPWR & ~(1<<4))) break;
  }
 }



//this is provided as an example
//will go into power mode 1, and use the sleep
//timer to wake up.
//Caution: Use of power down mode 2 caused erratic
//results after power up, I am not sure if was due
//to parts of RAM not retaining their value or what.
void halSleep(UINT32 msecs) {
  UINT32_UNION t;
  UINT32 delta;
  BOOL gie_status;

  SAVE_AND_DISABLE_GLOBAL_INTERRUPT(gie_status);
  //read the sleep timer
  delta = (32768 * msecs)/1000;
  t.bytes[UINT32_LOWORD_LSB] = ST0;
  t.bytes[UINT32_LOWORD_MSB] = ST1;
  t.bytes[UINT32_HIWORD_LSB] = ST2;
  //compute the compare value
  t.val = (t.val + delta)&0x00FFFFFF;
  //write the new sleep timer value
  ST2 = t.bytes[UINT32_HIWORD_LSB];
  ST1 = t.bytes[UINT32_LOWORD_MSB];
  ST0 = t.bytes[UINT32_LOWORD_LSB];
  //clear the sleep flag, enable the interrupt
  IRCON = IRCON & 0x7F; //clear the sleep flag IRCON.STIF = 0;
  IEN0 = IEN0 | (1<<5); //enable the interrupt  IEN0.STIE = 1;

  ENABLE_GLOBAL_INTERRUPT();  //interrupts must be enabled to wakeup!
  //configure the power mode and sleep
  //conPrintROMString("up0...\n");
   SET_POWER_MODE(POWER_MODE_2);
  //SET_POWER_MODE(POWER_MODE_1);
  //wake up!
  //disable sleep interrupt


  DISABLE_GLOBAL_INTERRUPT();
  IEN0 = IEN0 & ~(1<<5);  // IEN0.STIE = 0;

	

  //////wait for everything to power back up//
  while(!XOSC_STABLE);          \
  asm("NOP");//
  //conPrintROMString("up1...\n");
  RESTORE_GLOBAL_INTERRUPT(gie_status);
};




INT16 halGetAdcValue(){
   INT16 value;
   value = ((INT16)ADCH) << 8;
   value |= (INT16)ADCL;
   return value;
}


//functions used by EVboard.

//-----------------------------------------------------------------------------
// See hal.h for a description of this function.
//-----------------------------------------------------------------------------
INT16 halAdcSampleSingle(BYTE reference, BYTE resolution, UINT8 input) {
    BYTE volatile temp;
    INT16 value;

    //reading out any old conversion value
    temp = ADCH;
    temp = ADCL;


    ADC_ENABLE_CHANNEL(input);
    ADC_STOP();

    ADC_SINGLE_CONVERSION(reference | resolution | input);

    while (!ADC_SAMPLE_READY());

    ADC_DISABLE_CHANNEL(input);

    value = (((INT16)ADCH) << 8);
    value |= ADCL;

    resolution >>= 3;
    return value >> (8 - resolution);
}

⌨️ 快捷键说明

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