Exemplo n.º 1
0
void sendAck(SPP_STRUCT* receivedPacket)
{
   SIDLE();
   // Debug:
   halWait(1);
   DMA_ABORT_CHANNEL(dmaNumberTx);

   RFTXRXIF = 0;
   STX();
   RFIF &= ~IRQ_DONE;
   while(RFTXRXIF == 0);
   RFD = SPP_HEADER_AND_FOOTER_LENGTH + SPP_ACK_LENGTH;
   RFTXRXIF = 0;
   while(RFTXRXIF == 0);
   RFTXRXIF = 0;
   RFD = receivedPacket->srcAddress;
   while(RFTXRXIF == 0);
   RFTXRXIF = 0;
   RFD = myAddress;
   while(RFTXRXIF == 0);
   RFTXRXIF = 0;
   RFD = ACK;
   while(!(RFIF & IRQ_DONE));
   RFIF &= ~IRQ_DONE;

   return;
}
Exemplo n.º 2
0
// *************************************************************************************************
// RF TX/RX IRQ providing data handling
// *************************************************************************************************
void rftest_RfTxRxIsr(void)
{
  u8 pass, i;
  u16 time, timeout;
  
  // First clear pointer to fifo
  rftest_packet_ptr = 0;

  // Read first byte
  rftest_packet[rftest_packet_ptr++] = RFD;
  
  // Load timeout counter  
  timeout = 400;

  // Wait until all 10 bytes have been received
  while ( (rftest_packet_ptr < RFTEST_PACKET_LENGTH)  && (timeout-- != 0) ) 
  {
    if ((TCON & BIT1) == BIT1)
    {
      // Read next bytes
      rftest_packet[rftest_packet_ptr++] = RFD;

      // Clear IRQ flag
      TCON &= ~BIT1;
    }
  }

  // Indicate that RX is over
  if (rftest_packet_ptr == RFTEST_PACKET_LENGTH) 
  {
    // Radio off during decoding
    SIDLE();
    
    // Store current 16-bit time
    time  = T1CNTL;
    time |= T1CNTH << 8;
    time = (sTimer1.cycles*11453) + (u16)(((u32)time*32768)/187500);
    
    // Check if packet is valid
    pass = 1;
    for (i=1; i<RFTEST_PACKET_LENGTH; i++)
    {
      if (rftest_packet[i] != ref_packet[i]) pass = 0;
    }
    
    // Continue if packet ok
    if (pass)
    {
      rftest[rftest_count].valid        = 1;
      rftest[rftest_count].time 	= time;
      rftest[rftest_count].packet_nb	= rftest_packet[0];
      rftest[rftest_count].freqoffset	= FREQEST;
      rftest_count++;
    }
  }
}
Exemplo n.º 3
0
// *************************************************************************************************
// RF TX/RX general IRQ providing status handling
// *************************************************************************************************
void rftest_RfIsr(void)
{
  u8 rfif_reg = RFIF;
  
  // Clear CPU int flag
  S1CON &= ~0x03;
  
  // check status register
  if ((rfif_reg & BIT7) == BIT7)
  {
    // TX underflow error
    SIDLE();
  }
  else if ((rfif_reg & IRQ_RXOVF) == IRQ_RXOVF)
  {
    // RX overflow error
    SIDLE();
    while(MARCSTATE != 0x01);
    rftest_packet_ptr = 0;
  } 

  // Clear IRQ
  RFIF = 0x00;  
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
// *************************************************************************************************
// Exit continuous TX
// *************************************************************************************************
void stop_continuous_tx(void)
{
  SIDLE();
}
Exemplo n.º 6
0
// *************************************************************************************************
// Sets the radio hardware to the required initial state.
// *************************************************************************************************
void rftest_radio_init(void)
{
  u8 FSCAL3_Register_u8;

  SYNC1       = RFTEST_SYNC_WORD >> 8;  /*  Sync word, high byte                                */
  SYNC0       = (u8) RFTEST_SYNC_WORD;  /*  Sync word, low byte                                 */
  PKTLEN      = RFTEST_PACKET_LENGTH;   /*  Packet length                                       */
  PKTCTRL1    = 0x00;               /*  Packet automation control                           */
  PKTCTRL0    = 0x00;               /*  Packet automation control                           */
  ADDR        = 0x00;               /*  Device address                                      */
  CHANNR      = 0x00;               /*  Channel number                                      */
  FSCTRL1     = 0x12;               /*  Frequency synthesizer control                       */
  FSCTRL0     = 0x00;               /*  Frequency synthesizer control                       */
#ifdef ISM_EU
  FREQ2       = 0x24;               /*  Frequency control word, high byte                   */
  FREQ1       = 0x2D;               /*  Frequency control word, middle byte                 */
  FREQ0       = 0x55;               /*  Frequency control word, low byte                    */
  MDMCFG4     = 0x3D;               /*  Modem configuration                                 */
  MDMCFG3     = 0x55;               /*  Modem configuration                                 */
  MDMCFG2     = 0x15;               /*  Modem configuration                                 */
  MDMCFG1     = 0x12;               /*  Modem configuration                                 */
  MDMCFG0     = 0x11;               /*  Modem configuration                                 */
#else
  #ifdef ISM_US
  FREQ2       = 0x26;               /*  Frequency control word, high byte                   */
  FREQ1       = 0x19;               /*  Frequency control word, middle byte                 */
  FREQ0       = 0x11;               /*  Frequency control word, low byte                    */
  MDMCFG4     = 0x3D;               /*  Modem configuration                                 */
  MDMCFG3     = 0x55;               /*  Modem configuration                                 */
  MDMCFG2     = 0x15;               /*  Modem configuration                                 */
  MDMCFG1     = 0x12;               /*  Modem configuration                                 */
  MDMCFG0     = 0x11;               /*  Modem configuration                                 */ 
  #else
    #ifdef ISM_LF
    FREQ2       = 0x12;               /*  Frequency control word, high byte                   */
    FREQ1       = 0x0A;               /*  Frequency control word, middle byte                 */
    FREQ0       = 0xAA;               /*  Frequency control word, low byte                    */
    MDMCFG4     = 0x3D;               /*  Modem configuration                                 */
    MDMCFG3     = 0x55;               /*  Modem configuration                                 */
    MDMCFG2     = 0x15;               /*  Modem configuration                                 */
    MDMCFG1     = 0x12;               /*  Modem configuration                                 */
    MDMCFG0     = 0x11;               /*  Modem configuration                                 */ 
    #else
      #error "No ISM band specified"
    #endif
  #endif
#endif
  DEVIATN     = 0x60;               /*  Modem deviation setting                             */
  MCSM2       = 0x07;               /*  Main Radio Control State Machine configuration      */
  MCSM1       = 0x02;               /*  Main Radio Control State Machine configuration      */
  MCSM0       = 0x18;               /*  Main Radio Control State Machine configuration      */
  FOCCFG      = 0x1D;               /*  Frequency Offset Compensation configuration         */
  BSCFG       = 0x1C;               /*  Bit Synchronization configuration                   */
  AGCCTRL2    = 0xC7;               /*  AGC control                                         */
  AGCCTRL1    = 0x10;               /*  AGC control                                         */
  AGCCTRL0    = 0xB2;               /*  AGC control                                         */
  FREND1      = 0xB6;               /*  Front end RX configuration                          */
  FREND0      = 0x10;               /*  Front end TX configuration                          */
  FSCAL3      = 0xEA;               /*  Frequency synthesizer calibration                   */
  FSCAL2      = 0x2A;               /*  Frequency synthesizer calibration                   */
  FSCAL1      = 0x00;               /*  Frequency synthesizer calibration                   */
  FSCAL0      = 0x1F;               /*  Frequency synthesizer calibration                   */
  IOCFG2      = 0x00;               /*  Radio Test Signal Configuration (P1_7)              */
  IOCFG1      = 0x00;               /*  Radio Test Signal Configuration (P1_6)              */
  IOCFG0      = 0x00;               /*  Radio Test Signal Configuration (P1_5)              */
  TEST1       = 0x31;

  // Read FSCAL3 register, set bits enabling charge pump calibration and write register again
  FSCAL3_Register_u8 = FSCAL3 | 0x20;
  FSCAL3 = FSCAL3_Register_u8;

  // Set output power
  PA_TABLE0 = RFTEST_OUTPUT_POWER; 

  // Start calibration manually
  SIDLE();
  SCAL();

  // Wait until calibration completed
  while(MARCSTATE != 0x01);
  FSCAL3 &= ~0x30;  
    
  // Enter powerdown mode
  SIDLE();
}
Exemplo n.º 7
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();
}
Exemplo n.º 8
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