/** * @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); }
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); }
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); }
/** \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); }
/*! \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; }
/*! \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; }
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; }
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; }
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; }
/** \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); }
/*! \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); }
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; }
/*! \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; }
//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. } }