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

📄 halstack.c

📁 该演示程序实现温度的采集与显示功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
  V0.1 Initial Release   10/July/2006  RBR

*/

#include "hal.h"
#include "halstack.h"
#include "console.h"
#include "ieee_lrwpan_defs.h"
#include "phy.h"
#include "mac.h"

extern BYTE UART0rcvBuf[200];
extern BYTE datalen;

RADIO_FLAGS local_radio_flags;





//halInit contains both processor specific initialization
void halInit(void)
{
  //Set clock source
  local_radio_flags.val = 0;
  SET_MAIN_CLOCK_SOURCE(CRYSTAL);
  halInitUart();
  halSetBaud(LRWPAN_DEFAULT_BAUDRATE);
  halInitMACTimer();
}


//initialize UART to be used by
void halInitUart(void) {
  // Setup for UART0
   IO_PER_LOC_UART0_AT_PORT0_PIN2345();
   URX0IE=INT_ON;
   U0CSR |=UART_ENABLE_RECEIVE;
   UTX0IF = 1;
}

//get a character from serial port
char halGetch(void){
   char c;
   // Turning on reception
   U0CSR |= UART_ENABLE_RECEIVE;

   while (!URX0IF);
   c = U0DBUF;
   URX0IF = FALSE;

   return c;
}

void halUtilMemCopy(BYTE *dst, BYTE *src, BYTE len) {
  while (len) {
    *dst = *src;
    dst++;src++;
    len--;
  }
}

// assuming 16us period, have 1/16us = 62500 tics per seocnd
#define T2CMPVAL (62500/SLOWTICKS_PER_SECOND)

//use timer2, will set it up for one tick per symbol
//assuming 2.4GHZ and a 32 MHZ clock.
// this is a 20 bit counter, will overflow in ~16 seconds
//should be long enough for MAC timeout cases
void halInitMACTimer(void) {

  T2CNF = 0x00; //ensure timer is idle

  T2CAPHPH = 0x02;  // setting for 16 u-second periods
  T2CAPLPL = 0x00;  // (0x0200) / 32 = 16 u-seconds
  //set the interrupt compare to its maximum value

#ifdef LRWPAN_ENABLE_SLOW_TIMER
  T2PEROF0 = (BYTE) (T2CMPVAL);
  T2PEROF1 = (BYTE) (T2CMPVAL>>8);
  //enable overflow count compare interrupt
  T2PEROF2 = ((BYTE) (T2CMPVAL>>16)) | 0x20;
#endif

  //turn on timer
  //configure timer
  T2CNF = 0x03; //start timer

  INT_SETFLAG_T2(INT_CLR); //clear processor interrupt flag
  //enable T2 processor interrupt
#ifdef LRWPAN_ENABLE_SLOW_TIMER
  INT_ENABLE_T2(INT_ON);
#endif

}

UINT32 halGetMACTimer(void){
  UINT32_UNION t;
  BOOL gie_status;

  SAVE_AND_DISABLE_GLOBAL_INTERRUPT(gie_status);
  t.bytes[UINT32_LOWORD_LSB] = T2OF0;
  t.bytes[UINT32_LOWORD_MSB] = T2OF1;
  t.bytes[UINT32_HIWORD_LSB] = T2OF2 & 0x0F;
  t.bytes[UINT32_HIWORD_MSB] = 0;
  RESTORE_GLOBAL_INTERRUPT(gie_status);
  return (t.val);
}



//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);
}

//assumes that Timer2 has been initialized and is running
UINT8 halGetRandomByte(void) {
  return(T2OF0);
}

//write a character to serial port
// Uses UART initialized by halInitUart

void halPutch(char c){
  while (!UTX0IF);
  UTX0IF = 0;
  U0DBUF = c;
}


//set the radio frequency
LRWPAN_STATUS_ENUM halSetRadioIEEEFrequency(PHY_FREQ_ENUM frequency, BYTE channel)
{
   UINT16 afreq;

   //DEBUG_STRING(DBG_TX,"halSetRadioIEEEFrequency() -set channel:");
   //DEBUG_UINT8(DBG_TX,channel);   DEBUG_STRING(DBG_TX,"\n");

   if (frequency != PHY_FREQ_2405M) return(LRWPAN_STATUS_PHY_FAILED);
   if ((channel < 11) || (channel > 26)) return(LRWPAN_STATUS_PHY_FAILED);
   afreq = 357 + 5*(channel - 11) ;
   FSCTRLL = (BYTE) afreq;
   FSCTRLH = ((FSCTRLH & ~0x03) | (BYTE)((afreq >> 8) & 0x03));
   return(LRWPAN_STATUS_SUCCESS);
}

//this assumes 2.4GHz frequency
LRWPAN_STATUS_ENUM halSetChannel(BYTE channel){
 return(halSetRadioIEEEFrequency(PHY_FREQ_2405M, channel));
}


void halGetProcessorIEEEAddress(BYTE *buf) {
#if (CC2430_FLASH_SIZE == 128)
  unsigned char bank;
  bank = MEMCTR;
  //switch to bank 3
  MEMCTR |= 0x30;
#endif
  //note that the flash programmer stores these in BIG ENDIAN order for some reason!!!
  buf[7] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+0);
  buf[6] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+1);
  buf[5] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+2);
  buf[4] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+3);
  buf[3] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+4);
  buf[2] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+5);
  buf[1] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+6);
  buf[0] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+7);
 #if (CC2430_FLASH_SIZE == 128)
  //resore old bank settings
  MEMCTR = bank;
#endif
}


void halGetProcessorIEEEAddress_ASC(BYTE *buf) {
#if (CC2430_FLASH_SIZE == 128)
  unsigned char bank;
  bank = MEMCTR;
  //switch to bank 3
  MEMCTR |= 0x30;
#endif
  //note that the flash programmer stores these in BIG ENDIAN order for some reason!!!
  buf[0] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+0);
  buf[1] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+1);
  buf[2] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+2);
  buf[3] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+3);
  buf[4] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+4);
  buf[5] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+5);
  buf[6] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+6);
  buf[7] = *(unsigned char __code *)(IEEE_ADDRESS_ARRAY+7);
 #if (CC2430_FLASH_SIZE == 128)
  //resore old bank settings
  MEMCTR = bank;
#endif
}






void halSetRadioIEEEAddress(void) {
  BYTE buf[8];
  halGetProcessorIEEEAddress(buf);
  IEEE_ADDR0 = buf[0];
  IEEE_ADDR1 = buf[1];
  IEEE_ADDR2 = buf[2];
  IEEE_ADDR3 = buf[3];
  IEEE_ADDR4 = buf[4];
  IEEE_ADDR5 = buf[5];
  IEEE_ADDR6 = buf[6];
  IEEE_ADDR7 = buf[7];
}

void halSetRadioPANID(UINT16 panid){
  PANIDL = (BYTE) (panid);
  PANIDH = (BYTE) (panid>>8);
 }

void halSetRadioShortAddr(SADDR saddr){
  SHORTADDRL = (BYTE) (saddr);
  SHORTADDRH = (BYTE) (saddr>>8);
}

void halSetTxPower(BYTE val)
{
    //val:0~7 ;0-min      7-max
     BYTE VALTAB[]={0xE3,0xE7,0xEB,0xEF,0xF3,0xF7,0xFB,0xFF};
    if(val>7)return;
	TXCTRLL=VALTAB[val];
}


LRWPAN_STATUS_ENUM halInitRadio(PHY_FREQ_ENUM frequency, BYTE channel, RADIO_FLAGS radio_flags)
{
  LRWPAN_STATUS_ENUM status;
  //DEBUG_STRING(DBG_TX,"halInitRadio()\n");

  // Setting the frequency
  status = halSetRadioIEEEFrequency(frequency, channel);
  if (status != LRWPAN_STATUS_SUCCESS) return(status);

  //turning on power to analog part of radio and waiting for voltage regulator.
  RFPWR = 0x04;
  while((RFPWR & 0x10)){}
  //radio_flags.listen_mode=1; //debug
  if (radio_flags.bits.listen_mode) {
    //corresponds to promiscuous modes
    //radio accepts all packets, the HUSSY!
    MDMCTRL0H &= ~ADR_DECODE;    //no address decode
    MDMCTRL0L &= ~AUTO_ACK;       //no auto ack
  } else {
    // Turning on Address Decoding
    MDMCTRL0H |= ADR_DECODE;
    //enable auto_ack
    MDMCTRL0L |= AUTO_ACK;
  }
  local_radio_flags = radio_flags;  //save this for later
  // Setting for AUTO CRC
  MDMCTRL0L |= AUTO_CRC;

  //pan
  if (radio_flags.bits.pan_coordinator) {
    MDMCTRL0H |= PAN_COORDINATOR;  //accepts frames with only source addressing modes
  } else {
    MDMCTRL0H &= ~PAN_COORDINATOR;  //rejects frames with only source addressing modes
  }

  // Turning on AUTO_TX2RX
  FSMTC1 = ((FSMTC1 & (~AUTO_TX2RX_OFF & ~RX2RX_TIME_OFF))  | ACCEPT_ACKPKT);

  // Turning off abortRxOnSrxon.
  FSMTC1 &= ~0x20;

  //now configure the RX, TX systems.
  // Setting the number of bytes to assert the FIFOP flag
  IOCFG0 = 127;  //set to max value as the FIFOP flag goes high when complete packet received

  // Flushing both Tx and Rx FiFo. The flush-Rx is issued twice to reset the SFD.
  // Calibrating the radio and turning on Rx to evaluate the CCA.
  SRXON;
  SFLUSHTX;
  SFLUSHRX;
  SFLUSHRX;
  STXCALN;
  ISSTART;

  SACKPEND;  //routers/

  halSetRadioIEEEAddress();

   //Radio can interrupt when
   //RX configuration
   //clear flags/mask in radio
   RFIF = 0;
   RFIM = 0;   //all interrupts are masked.
   //enable RX interrupt on processor
   INT_SETFLAG_RF(INT_CLR);
   INT_ENABLE_RF(INT_ON);

   //enable RX RFERR interrupt on processor
   INT_SETFLAG_RFERR(INT_CLR);
   INT_ENABLE_RFERR(INT_ON);

   //do not use DMA at this point
   //enable the RX receive interrupt here.
   RFIM |= IRQ_FIFOP;

   return(LRWPAN_STATUS_SUCCESS);
}

#define PIN_CCA   CCA    //CCA is defined in hal.h

//regardless of what happens here, we will try TXONCCA after this returns.
void  doIEEE_backoff(void) {
     BYTE be, nb, tmp, rannum;
    UINT32  delay, start_tick;

   be = aMinBE;
   nb = 0;
  do {
      if (be) {
        //do random delay
        tmp = be;
        //compute new delay
        delay = 1;
        while (tmp) {
          delay = delay << 1;  //delay = 2**be;
           tmp--;
         }
        rannum =  halGetRandomByte() & (delay-1); //rannum will be between 0 and delay-1
        delay = 0;
        while (rannum) {
            delay  += SYMBOLS_TO_MACTICKS(aUnitBackoffPeriod);
            rannum--;
         }//delay = aUnitBackoff * rannum
        //now do backoff
       start_tick = halGetMACTimer();
        while (halMACTimerNowDelta(start_tick) < delay);
      }
      //check CCA
      if (PIN_CCA)  break;
      nb++;
      be++;
      if (be > aMaxBE) be =aMaxBE;
   }while (nb <= macMaxCSMABackoffs);
  return;
}

//transmit packet
//hdrlen - header lenth
//hdr - pointer to header data
//plen - payload length
//pload - pointer to payload

LRWPAN_STATUS_ENUM halSendPacket(BYTE flen, BYTE *frm)
{
  BYTE len,state;
  LRWPAN_STATUS_ENUM res;




  //if you print out the packet, this can cause timeouts on waits
  //dbgPrintPacket(frm,flen+2);

  //total length, does not include length byte itself
  //last two bytes are the FCS bytes that are added automatically
  len = flen + PACKET_FOOTER_SIZE;

  // Clearing RF interrupt flags and enabling RF interrupts.
  if(FSMSTATE == 6 && RXFIFOCNT > 0)
  {
    ISFLUSHRX;
    ISFLUSHRX;
  }

  RFIF &= ~IRQ_TXDONE;      //Clear the RF TXDONE flag
  INT_SETFLAG_RF(INT_CLR);  //Clear processor interrupt flag

  //write packet length
  RFD = len;


  //DEBUG_STRING(DBG_TX,"halSendPacket()-len:");
  //DEBUG_UINT8(DBG_TX,flen);   DEBUG_STRING(DBG_TX," data:");
  while (flen)
  {
     RFD = *frm;
     //DEBUG_UINT8(DBG_TX,*frm);  DEBUG_STRING(DBG_TX,",");
     frm++;
     flen--;
  }
  //DEBUG_STRING(DBG_TX,"\n");




  // 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);

⌨️ 快捷键说明

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