Ejemplo n.º 1
0
//-----------------------------------------------------------------------------
// See cul.h for a description of this function.
//-----------------------------------------------------------------------------
void sppReceive(SPP_STRUCT* pReceiveData){

   sppRxStatus = RX_WAIT;

   DMA_ABORT_CHANNEL(dmaNumberRx);
   // Setting the address to where the received data are to be written. // Setting max number of bytes to receive
   SET_DMA_DEST(dmaRx,pReceiveData);
   SET_DMA_LENGTH(dmaRx,255);

   // Arming the DMA channel. The receiver will initate the transfer when a packet is received.
   DMA_ARM_CHANNEL(dmaNumberRx);

   // Debug:
   SIDLE();

   RFIF &= ~IRQ_SFD;
   RFIM |= IRQ_SFD;
   // Turning on the receiver
   SRX();

   return;
}
Ejemplo n.º 2
0
// *************************************************************************************************
// Test RF reception
// *************************************************************************************************
void test_rf(void) 
{
  u16 time1, time2, packet1, packet2, div;
  s16 ref, delta;
  u8 i;
  s16 freqest;
  u8 freqest1;
  s16 freqest0;
  u8 continue_test = YES;
  
  // Config radio for RX
  rftest_init();

  // Set timeout in 1.5 seconds
  reset_timer1();
  set_timer1(32768*1.5);
  T1CCTL0 = 0x44;
  T1CTL   = 0x02;

  // Clear RF interrupts
  S1CON &= ~(BIT1 | BIT0);  // Clear MCU interrupt flag 
  RFIF &= ~BIT4;            // Clear "receive/transmit done" interrupt 
  RFIM |= BIT4;             // Enable "receive/transmit done" interrupt

  // Enable IRQ
  INT_ENABLE(INUM_RFTXRX, INT_ON);
  INT_ENABLE(INUM_RF, INT_ON);
  INT_ENABLE(INUM_T1, INT_ON);
  
  // Clear test result variable
  test_result = 0;
  
  // Continue to receive packets until timeout
  while ((rftest_count < RFTEST_PACKET_COUNT) && (!sTimer1.iflag))
  {
    // Start new RX if radio is IDLE
    if (MARCSTATE == 0x01) SRX();
  }
  SIDLE();
  
  // Analyze received packets
  if (sTimer1.iflag || rftest_count < RFTEST_PACKET_COUNT/2)
  {
    // Timeout - no or not enough packets received
    test_result = 0x8000;
    continue_test = NO;
  }
  else
  {
      // Store last and first packet
      for (i=0; i<RFTEST_PACKET_COUNT; i++)
      {
        if (rftest[i].valid) 
        {
          time1   = rftest[i].time;
          packet1 = rftest[i].packet_nb;
          break;
        }
      }
      for (i=RFTEST_PACKET_COUNT-1; i>0; i--)
      {
        if (rftest[i].valid) 
        {
          time2   = rftest[i].time;
          packet2 = rftest[i].packet_nb;
          break;
        }
      }
      
      // Calculate mean freqest
      freqest = 0;
      div = 0;
      for (i=0; i<RFTEST_PACKET_COUNT; i++)
      {
        if (rftest[i].valid) 
        {
            // Sign extend negative numbers
            if ((rftest[i].freqoffset & BIT7) == BIT7) 
            {
              freqest += (s16)(0xFF00 | rftest[i].freqoffset);
            }
            else
            {
              freqest += (s16)(rftest[i].freqoffset);
            }
            div++;
        }
      }
      
      // FREQEST range check
      freqest0 = freqest/(s16)div;
      if ((freqest0 < RFTEST_FREQEST_MIN) || (freqest0 > RFTEST_FREQEST_MAX)) 
      {
              test_result = 0x2000 | (u8)freqest0;
              continue_test = NO;
      }
      else
      { // FREQEST range ok
      
        // Calculate distance between 1 and 2
        // TX sends packet each 3276 ACLK ticks (= 1145 T1CLK ticks)
        ref = (packet2 - packet1)*3276;
        delta = time2 - time1;
  
        if ((ref - delta) < RFTEST_ACLK_DEVIATION_MAX)
        {
          // Store ACLK deviation in test result
          test_result = ((ref - delta)&0x0F) << 8; 
          
          // Store average FREQEST
          if (freqest < 0)
          {
            freqest1 = (u8)((freqest*(-1))/div);
            freqest1 = ~freqest1 + 1;
            test_result |= freqest1;
          }
          else
          {
            test_result |= (u8)(freqest/div);
          } 
        }
        else if ((delta - ref) < RFTEST_ACLK_DEVIATION_MAX)
        {
          // Store ACLK deviation in test result
          test_result = ((delta - ref)&0x0F) << 8; 
          
          // Store average FREQEST
          if (freqest < 0)
          {
            freqest1 = (u8)((freqest*(-1))/div);
            freqest1 = ~freqest1 + 1;
            test_result |= freqest1;
          }
          else
          {
            test_result |= (u8)(freqest/div);
          } 			
        }
        else
        {
          // Too high ACLK deviation
          test_result = 0x4000;
          continue_test = NO;
        }
      }
  }
  
  // 2nd test stage - use RF offset to catch another few packets
  if (continue_test == YES)
  {
    rftest_count = 0;
    
    // Clear RX variables
    for (i=0; i<RFTEST_PACKET_COUNT; i++)
    {
            rftest[i].valid      = 0;
            rftest[i].time 	     = 0;
            rftest[i].packet_nb  = 0;
            rftest[i].freqoffset = 0;
    }
    
    // Set frequency offset
    FSCTRL0 = freqest0;
    
    // Set timeout in 0.5 seconds
    reset_timer1();
    set_timer1(32768*0.5);
    
    // Try to receive just 1 packet
    while ((rftest_count < 1) && (!sTimer1.iflag))
    {
      // Start new RX if radio is IDLE
      if (MARCSTATE == 0x01) SRX();
    }
    SIDLE();
    
    // Analyze received packets frequency offset - should be close to 0
    if (rftest_count > 0)
    {
            if (!((rftest[0].freqoffset >= 0xFE) || (rftest[0].freqoffset <= 0x02)))
            {
                    test_result = 0x1000;
            }
    }
    else
    {
            test_result = 0x1000;
    }
  }

  // Disable IRQ
  INT_ENABLE(INUM_RFTXRX, INT_OFF);
  INT_ENABLE(INUM_RF, INT_OFF);
  INT_ENABLE(INUM_T1, INT_OFF);

  // Stop Timer1 
  T1CTL  = 0x00;
  T1CNTL = 0x55;
  reset_timer1();
}
Ejemplo n.º 3
0
//-----------------------------------------------------------------------------
// See cul.h for a description of this function.
//-----------------------------------------------------------------------------
BYTE sppSend(SPP_STRUCT* pPacketPointer){
   BYTE res = TRUE;

   // Checking that length is not too long
   if (pPacketPointer->payloadLength > SPP_MAX_PAYLOAD_LENGTH)
   {
      res = TOO_LONG;
      sppTxStatus = TX_IDLE;
   }

   // Flipping the sequence bit, writing  total packet length and address if the transfer is not a retransmission.
   // If it is a retransmission, the fields are correct
   if(!(pPacketPointer->flags & RETRANSMISSION))
   {
      pPacketPointer->flags ^= SEQUENCE_BIT;
      pPacketPointer->payloadLength += SPP_HEADER_AND_FOOTER_LENGTH;
      pPacketPointer->srcAddress = myAddress;
   }


   // Setting up the DMA
   DMA_ABORT_CHANNEL(dmaNumberTx);
   SET_DMA_SOURCE(dmaTx,pPacketPointer);


   // Proceed if the packet length is OK.
   if (res == TRUE)
   {
      // Clearing RF interrupt flags and enabling RF interrupts.
      RFIF &= ~IRQ_DONE;
      RFIM &= ~IRQ_SFD;
      INT_SETFLAG(INUM_RF, INT_CLR);
#ifdef CCA_ENABLE
      if(!CCA)
      {
         SRX();
         // Turning on Rx and waiting to make the RSSI value become valid.
         halWait(1);
      }
      if(CCA)
#endif
      {  // Setting up radio
         DMA_ABORT_CHANNEL(dmaNumberRx);
         SIDLE();
         RFTXRXIF = 0;
         INT_GLOBAL_ENABLE(FALSE);
         DMA_ARM_CHANNEL(dmaNumberTx);
         STX();
         INT_GLOBAL_ENABLE(TRUE);
         sppTxStatus = TX_IN_PROGRESS;

         if(pPacketPointer->flags & DO_ACK)
         {
            pAckData = pPacketPointer;
            waitForAck();
         }
         else
         {
            pAckData = NULL;
         }
         RFIM |= IRQ_DONE;
      }
#ifdef CCA_ENABLE
      // The "air" is busy
      else
      {
         res = CHANNEL_BUSY;
         RFIM &= ~IRQ_DONE;
         // De-flipping the sequence bit.
         if(!(pPacketPointer->flags & RETRANSMISSION))
         {
            pPacketPointer->flags ^= SEQUENCE_BIT;
         }
      }
#endif
   }
   return res;
} // ends sppSend
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
// See cul.h for a description of this function.
//-----------------------------------------------------------------------------
BOOL sppInit(UINT32 frequency, BYTE address){
   BYTE res = 0;
   BOOL status = TRUE;

   sppSetAddress(address);

   // Clearing the states of the spp.
   sppTxStatus = TX_IDLE;
   sppRxStatus = RX_IDLE;
   retransmissionCounter = 0;
   ackTimerNumber = 0;
   pAckData = 0;

   // Clearing the RF interrupt flags and enable mask and enabling RF interrupts
   RFIF = 0;
   RFIM = 0;
   INT_SETFLAG(INUM_RF,INT_CLR);
   INT_ENABLE(INUM_RF,INT_ON);

   // Setting the frequency and initialising the radio
   res = halRfConfig(FREQUENCY_4_CC1110);
   if(res == FALSE){
      status = FALSE;
   }

   // Always in RX unless sending.

   //debug:
   MCSM1 = 0x2F;
//   MCSM1 = 0x3F;

   SRX();


   // Using the timer 4 administrator to generate interrupt to check if a message is unacked...
   culTimer4AdmInit();

   // Initialising the DMA administrator
   culDmaInit();

   // Requesting a DMA channel for transmit data. No callback function is used. Instead the TX_DONE
   // interrupt is used to determine when a transfer is finished. Configuring the DMA channel for
   // transmit. The data address and length will be set prior to each specific transmission.
   dmaTx = culDmaAllocChannel(&dmaNumberTx, 0);
   if((dmaNumberTx == 0) || (dmaNumberTx > 4)){
      status = FALSE;
   }

   culDmaToRadio(dmaTx, SPP_MAX_PAYLOAD_LENGTH + SPP_HEADER_AND_FOOTER_LENGTH, 0, FALSE);

   // Requesting a DMA channel for receiving data. Giving the address of the callback function.
   // Configuring the DMA channel for receive. The data address will be set prior to each specific
   // reception.
   dmaRx = culDmaAllocChannel(&dmaNumberRx, &rxCallBack);
   if((dmaNumberRx == 0) || (dmaNumberRx > 4)){
      status = FALSE;
   }
   culDmaFromRadio(dmaRx, 0, TRUE);

   // Making sure that none of the channels are armed.
   DMA_ABORT_CHANNEL(dmaNumberRx);
   DMA_ABORT_CHANNEL(dmaNumberTx);
   INT_ENABLE(INUM_DMA, INT_ON);

   return status;
} // ends sppInit