Пример #1
0
/**
 * @brief Initializes the transceiver
 *
 * This function is called to initialize the transceiver.
 *
 * @return MAC_SUCCESS  if the transceiver state is changed to TRX_OFF and the
 *                 current device part number and version number are correct;
 *         FAILURE otherwise
 */
static uint8_t trx_init(void)
{
    uint8_t trx_status;
    uint8_t poll_counter = 0;

    hal_set_rst_high();
    hal_set_slptr_low();
    /* Wait typical time of timer TR1. */
    delay_us(P_ON_TO_CLKM_AVAILABLE_TYP_US);
    /* Apply reset pulse */
    hal_set_rst_low();
    delay_us(RST_PULSE_WIDTH_US);
    hal_set_rst_high();
    /* Verify that TRX_OFF can be written */
    do
    {
        /* Wait not more than max. value of TR1. */
        if (poll_counter == P_ON_TO_CLKM_ATTEMPTS)
        {
            return(-1/* FAILURE*/);
        }
        /* Wait a short time interval. */
        delay_us(TRX_POLL_WAIT_TIME_US);
        poll_counter++;
        /* Check if AT86RF231 is connected; omit manufacturer id check */
    } while ((hal_register_read(RG_VERSION_NUM) != AT86RF231_VERSION_NUM) ||
             (hal_register_read(RG_PART_NUM) != AT86RF231_PART_NUM));

    /* Verify that TRX_OFF can be written */
    hal_register_write(RG_TRX_STATE, CMD_TRX_OFF);

    /* Verify that the trx has reached TRX_OFF. */
    poll_counter = 0;
    do
    {
        /* Wait a short time interval. */
        delay_us(TRX_POLL_WAIT_TIME_US);

        trx_status = (uint8_t)hal_subregister_read(SR_TRX_STATUS);

        /* Wait not more than max. value of TR2. */
        if (poll_counter == SLEEP_TO_TRX_OFF_ATTEMPTS)
        {
            return(-1/* FAILURE*/);
        }
        poll_counter++;
    } while (trx_status != TRX_OFF);

    tal_trx_status = TRX_OFF;

    return(0);
}
Пример #2
0
void drvr_init()
{
    U8 part_num, ver_num, irq;
    U16 man_id = 0;

    memset(&dcb, 0, sizeof(at86_dcb_t));

    delay_us(TIME_TO_ENTER_P_ON);
    hal_init();

    // reset all regs in at86rf
    drvr_at86_reset();

    part_num = hal_register_read(AT86_PART_NUM);
    ver_num = hal_register_read(AT86_VERSION_NUM);
    man_id |= hal_register_read(AT86_MAN_ID_1) << 8;
    man_id |= hal_register_read(AT86_MAN_ID_0);

    hal_register_write(AT86_IRQ_MASK, 0);
    irq = hal_register_read(AT86_IRQ_STATUS);

    // force transceiver off while we configure the intps
    hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF);
    delay_us(TIME_P_ON_TO_TRX_OFF);

    // wait for transceiver to transition to the off state
    while (drvr_get_trx_state() != TRX_OFF);

    hal_register_write(AT86_IRQ_MASK, (1<<IRQ_MASK_TRX_END) | (1<<IRQ_MASK_RX_START));

    // configure the CSMA parameters
    drvr_config_csma(drvr_get_rand() & 0xf, drvr_get_rand() & 0xf, aMinBE, aMacMaxFrameRetries, aMaxCsmaBackoffs);

    // set the default channel
    drvr_set_channel(11);

    // set autocrc mode
    drvr_set_auto_crc(true);

    // start the contiki driver process and register the event number
    process_start(&drvr_process, NULL);
    event_drvr_conf = process_alloc_event();

    // put trx in rx auto ack mode
    drvr_set_trx_state(RX_AACK_ON);
    while (drvr_get_trx_state() != RX_AACK_ON);
}
Пример #3
0
U8 drvr_get_ed()
{
    // ED register needs to be written with a dummy value to initiate a manual ED
    // reading. The ED level will appear after approx 8 symbol times or 128 usec.
    hal_register_write(RG_PHY_ED_LEVEL, 0);
    delay_us(140);
    return hal_register_read(RG_PHY_ED_LEVEL);
}
Пример #4
0
/** \brief  This function reads the value of a specific subregister.
 *
 *  \see Look at the at86rf231_registermap.h file for register and subregister
 *       definitions.
 *
 *  \param  address  Main register's address.
 *  \param  mask  Bit mask of the subregister.
 *  \param  position   Bit position of the subregister
 *  \retval Value of the read subregister.
 */
uint8_t
hal_subregister_read( uint8_t address, uint8_t mask, uint8_t position ) {
	/* Read current register value and mask out subregister. */
	uint8_t register_value = hal_register_read(address);
	register_value &= mask;
	register_value >>= position; /* Align subregister value. */

	return(register_value);
}
Пример #5
0
/*! \brief  This function reads the value of a specific subregister.
 *
 *  \see Look at the at86rf23x_registermap.h file for register and subregister
 *       definitions.
 *
 *  \param  address  Main register's address.
 *  \param  mask  Bit mask of the subregister.
 *  \param  position   Bit position of the subregister
 *  \retval Value of the read subregister.
 *
 */
u8 hal_subregister_read(u16 address, u8 mask, u8 position)
{
   //Read current register value and mask out subregister.
   u8 register_value = hal_register_read(address);
   register_value &= mask;
   register_value >>= position; //Align subregister value.

   return register_value;
}
Пример #6
0
/*! \brief  This function reads the value of a specific subregister.
 *
 *  \see Look at the at86rf230_registermap.h file for register and subregister 
 *       definitions.
 *
 *  \param  address  Main register's address.
 *  \param  mask  Bit mask of the subregister.
 *  \param  position   Bit position of the subregister
 *  \retval Value of the read subregister.
 *
 *  \ingroup hal_avr_api
 */
uint8_t hal_subregister_read( uint8_t address, uint8_t mask, uint8_t position ){
    
    //Read current register value and mask out subregister.
    uint8_t register_value = hal_register_read( address );
    register_value &= mask;
    register_value >>= position; //Align subregister value.
    
    return register_value;
}
Пример #7
0
U64 drvr_get_ext_addr()
{
    U8 i;
    U64 addr = 0;

    for (i=0; i<8; i++)
    {
        addr |= hal_register_read(RG_IEEE_ADDR_0 + i) << (8 * i);
    }
    return addr;
}
Пример #8
0
U16 drvr_get_short_addr()
{
    U8 i;
    U16 addr = 0;

    for (i=0; i<2; i++)
    {
        addr |= hal_register_read(RG_SHORT_ADDR_0 + i) << (8 * i);
    }
    return addr;
}
Пример #9
0
U16 drvr_get_pan_id()
{
    U8 i;
    U16 pan_id = 0;

    for (i=0; i<2; i++)
    {
        pan_id |= hal_register_read(RG_PAN_ID_0 + i) << (8 * i);
    }
    return pan_id;
}
Пример #10
0
/** \brief  This function writes a new value to one of the radio transceiver's
 *          subregisters.
 *
 *  \see Look at the at86rf231_registermap.h file for register and subregister
 *       definitions.
 *
 *  \param  address  Main register's address.
 *  \param  mask  Bit mask of the subregister.
 *  \param  position  Bit position of the subregister
 *  \param  value  Value to write into the subregister.
 */
void
hal_subregister_write( uint8_t address, uint8_t mask, uint8_t position, uint8_t value) {
	/* Read current register value and mask area outside the subregister. */
	volatile uint8_t register_value = hal_register_read(address);
	register_value &= ~mask;

	/* Start preparing the new subregister value. shift in place and mask. */
	value <<= position;
	value &= mask;

	value |= register_value; /* Set the new subregister value. */

	/* Write the modified register value. */
	hal_register_write(address, value);
}
Пример #11
0
/*! \brief  This function writes a new value to one of the radio transceiver's
 *          subregisters.
 *
 *  \see Look at the at86rf23x_registermap.h file for register and subregister
 *       definitions.
 *
 *  \param  address  Main register's address.
 *  \param  mask  Bit mask of the subregister.
 *  \param  position  Bit position of the subregister
 *  \param  value  Value to write into the subregister.
 *
 */
void hal_subregister_write(u16 address, u8 mask, u8 position,
      u8 value)
{
   //Read current register value and mask area outside the subregister.
   u8 register_value = hal_register_read(address);
   register_value &= ~mask;

   //Start preparing the new subregister value. shift in place and mask.
   value <<= position;
   value &= mask;

   value |= register_value; //Set the new subregister value.

   //Write the modified register value.
   hal_register_write(address, value);
}
Пример #12
0
static uint8_t
extract_random_bit_() {
	uint8_t ret;
	uint8_t trx_ctrl_0 = hal_register_read(TRX_CTRL_0);
	
	// Set radio clock output to 8MHz
	hal_register_write(TRX_CTRL_0,0x8|5);

	do {
		TEMPORAL_AGITATION(); // WARNING: This step may hide lack of entropy!

		ret = !!(PIND&(1<<6));
		ret <<= 1;
		ret |= !!(PIND&(1<<6));
	} while((ret==0)||(ret==3));

	// Toss out the other bit, we only care about one of them.
	ret &= 1;
	
	// Restore the clkm state
	hal_register_write(TRX_CTRL_0,trx_ctrl_0);
	
	return ret;
}
Пример #13
0
/*! \brief  This function will upload a frame from the radio transceiver's frame
 *          buffer.
 *
 *          If the frame currently available in the radio transceiver's frame buffer
 *          is out of the defined bounds. Then the frame length, lqi value and crc
 *          be set to zero. This is done to indicate an error.
 *
 */
uint8_t* hal_frame_read(void)
{
   uint8_t* pFrame = bmm_buffer_alloc();

   if(pFrame != NULL)
   {
      rx_frame_t *rx_frame = (rx_frame_t*)pFrame;

#ifdef SINGLE_CHIP
      AVR_ENTER_CRITICAL_REGION();

      volatile uint8_t *pSrc = (volatile uint8_t *)0x180;
      uint8_t frame_length = hal_register_read(RG_TST_RX_LENGTH);
      if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH))
      {
         // read length and save frame content -> lqi is NOT included in frame length byte
         rx_frame->length = frame_length;
         //memcpy(rx_data, (void *)pSrc, frame_length);
         memcpy(rx_frame->data, (void *)pSrc, frame_length-1);
         // save LQI /
         //rx_frame->lqi = *(pSrc + (frame_length + 1));
         rx_frame->lqi = *(pSrc + frame_length);
      }
      else
      {
         rx_frame->length = 0;
         rx_frame->lqi    = 0;
         rx_frame->crc    = false;
         bmm_buffer_free(pFrame); // free allcoated buffer
         pFrame = NULL; // set buffer pointer to NULL, that next app do not use it
      }
      AVR_LEAVE_CRITICAL_REGION();
#else
      uint8_t* rx_data = &rx_frame->data[0];

      AVR_ENTER_CRITICAL_REGION();

      HAL_SS_LOW();

      //Send frame read command.
      SPDR = HAL_TRX_CMD_FR;
      while ((SPSR & (1 << SPIF)) == 0) {;}
      u8 frame_length = SPDR;

      //Read frame length.
      SPDR = frame_length;
      while ((SPSR & (1 << SPIF)) == 0) {;}
      frame_length = SPDR;

      //Check for correct frame length.
      if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH))
      {
         rx_frame->length = frame_length; //Store frame length.

         //Upload frame buffer to data pointer. Calculate CRC.
         SPDR = frame_length;
         while ((SPSR & (1 << SPIF)) == 0)
            ;

         do
         {
            u8 tempData = SPDR;
            SPDR = 0;       // dummy write

            //*rx_data++ = tempData;
            *rx_data = tempData;
            rx_data++;
            while ((SPSR & (1 << SPIF)) == 0)
               ;
         } while (--frame_length > 0);

         //Read LQI value for this frame.
         rx_frame->lqi = SPDR;

         HAL_SS_HIGH();
      }
      else
      {
         HAL_SS_HIGH();

         if (rx_frame)
         {
            rx_frame->length = 0;
            rx_frame->lqi    = 0;
            rx_frame->crc    = false;
            bmm_buffer_free(pFrame); // free allocated buffer
            pFrame = NULL; // set buffer pointer to NULL, that next app do not use it
         }
      }

      AVR_LEAVE_CRITICAL_REGION();

#endif // SINGLE_CHIP
   }
   return pFrame;
}
Пример #14
0
//This #if compile switch is used to provide a "standard" function body for the 
//doxygen documentation.
void hal_input_capture_isr(void)
{
    uint8_t interrupt_source;
    /*The following code reads the current system time. This is done by first 
      reading the hal_system_time and then adding the 16 LSB directly from the
      TCNT1 register.
     */
   // uint32_t isr_timestamp = hal_system_time;
   // isr_timestamp <<= 16;
   // isr_timestamp |= TCNT1; 
    
    /*Read Interrupt source.*/
    HAL_SS_LOW( );
	
  interrupt_source= hal_RF_SPI_Send_Data(RG_IRQ_STATUS | HAL_TRX_CMD_RR);	

  interrupt_source= hal_RF_SPI_Send_Data(interrupt_source);//The interrupt source is read.
 //   SPDR = interrupt_source;
 //   while ((SPSR & (1 << SPIF)) == 0) {;}	
   // interrupt_source = SPDR; //The interrupt source is read.

    HAL_SS_HIGH( );

    /*Handle the incomming interrupt. Prioritized.*/
    if ((interrupt_source & HAL_RX_START_MASK)) {
        
        hal_rx_start_flag++; //Increment RX_START flag.
        
        if( rx_start_callback != NULL ){
             uint8_t frame_length;
            //Read Frame length and call rx_start callback.
            HAL_SS_LOW( );
    
            /*SPDR = HAL_TRX_CMD_FR;
            while ((SPSR & (1 << SPIF)) == 0) {;}
            uint8_t frame_length = SPDR;
        
            SPDR = frame_length; //Any data will do, so frame_length is used.
            while ((SPSR & (1 << SPIF)) == 0) {;}
            frame_length = SPDR;*/

	     frame_length=hal_RF_SPI_Send_Data(HAL_TRX_CMD_FR);	
	     frame_length=hal_RF_SPI_Send_Data(frame_length);	 
            
            HAL_SS_HIGH( );
            
            rx_start_callback( 0, frame_length );
        }
    }
    else if (interrupt_source & HAL_TRX_END_MASK) {
        
        hal_trx_end_flag++; //Increment TRX_END flag.
        
       if( trx_end_callback != NULL ){
            trx_end_callback( 0 );
           // trx_end_handler();
        }
    } 
    else if (interrupt_source & HAL_TRX_UR_MASK) {
        hal_trx_ur_flag++; //Increment TRX_UR flag.    
    } else if (interrupt_source & HAL_PLL_UNLOCK_MASK) {
        hal_pll_unlock_flag++; //Increment PLL_UNLOCK flag.   
    } else if (interrupt_source & HAL_PLL_LOCK_MASK) {
        hal_pll_lock_flag++; //Increment PLL_LOCK flag.
    } else if (interrupt_source & HAL_BAT_LOW_MASK) {

        //Disable BAT_LOW interrupt to prevent interrupt storm. The interrupt 
        //will continously be signaled when the supply voltage is less than the 
        //user defined voltage threshold.
        uint8_t trx_isr_mask = hal_register_read( RG_IRQ_MASK );
        trx_isr_mask &= ~HAL_BAT_LOW_MASK;
        hal_register_write( RG_IRQ_MASK, trx_isr_mask );
        hal_bat_low_flag++; //Increment BAT_LOW flag.
    } else {
        hal_unknown_isr_flag++;  //Increment UNKNOWN_ISR flag.
    } 
}