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

📄 hal.c

📁 Contiki是一个开源
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------------*//** \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. */uint8_thal_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 writes a new value to one of the radio transceiver's *          subregisters. * *  \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 *  \param  value  Value to write into the subregister. */voidhal_subregister_write(uint8_t address, uint8_t mask, uint8_t position,                            uint8_t value){    /* Read current register value and mask area outside the subregister. */    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 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. * *  \param  rx_frame    Pointer to the data structure where the frame is stored. *  \param  rx_callback Pointer to callback function for receiving one byte at a time. */voidhal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback){    uint8_t *rx_data=0;    /*  check that we have either valid frame pointer or callback pointer */    if (!rx_frame && !rx_callback)        return;    AVR_ENTER_CRITICAL_REGION();    HAL_SS_LOW();    /*Send frame read command.*/    SPDR = HAL_TRX_CMD_FR;    while ((SPSR & (1 << SPIF)) == 0) {;}    uint8_t 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)){        uint16_t crc = 0;        if (rx_frame){            rx_data = (rx_frame->data);            rx_frame->length = frame_length; /* Store frame length. */        } else {            rx_callback(frame_length);        }        /*Upload frame buffer to data pointer. Calculate CRC.*/        SPDR = frame_length;        while ((SPSR & (1 << SPIF)) == 0) {;}        do{            uint8_t tempData = SPDR;            SPDR = 0;       /*  dummy write */            if (rx_frame){                *rx_data++ = tempData;            } else {                rx_callback(tempData);            }            crc = _crc_ccitt_update(crc, tempData);            while ((SPSR & (1 << SPIF)) == 0) {;}        } while (--frame_length > 0);        /*Read LQI value for this frame.*/        if (rx_frame){            rx_frame->lqi = SPDR;        } else {            rx_callback(SPDR);        }                HAL_SS_HIGH();        /*Check calculated crc, and set crc field in hal_rx_frame_t accordingly.*/        if (rx_frame){            rx_frame->crc = (crc == HAL_CALCULATED_CRC_OK);        } else {            rx_callback(crc != HAL_CALCULATED_CRC_OK);        }    } else {        HAL_SS_HIGH();        if (rx_frame){            rx_frame->length = 0;            rx_frame->lqi    = 0;            rx_frame->crc    = false;        }    }    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief  This function will download a frame to the radio transceiver's frame *          buffer. * *  \param  write_buffer    Pointer to data that is to be written to frame buffer. *  \param  length          Length of data. The maximum length is 127 bytes. */voidhal_frame_write(uint8_t *write_buffer, uint8_t length){    length &= HAL_TRX_CMD_RADDRM; /* Truncate length to maximum frame length. */    AVR_ENTER_CRITICAL_REGION();    HAL_SS_LOW(); /* Initiate the SPI transaction. */    /*SEND FRAME WRITE COMMAND AND FRAME LENGTH.*/    SPDR = HAL_TRX_CMD_FW;    while ((SPSR & (1 << SPIF)) == 0) {;}    uint8_t dummy_read = SPDR;    SPDR = length;    while ((SPSR & (1 << SPIF)) == 0) {;}    dummy_read = SPDR;    /* Download to the Frame Buffer. */    do{        SPDR = *write_buffer++;        --length;        while ((SPSR & (1 << SPIF)) == 0) {;}        dummy_read = SPDR;    } while (length > 0);    HAL_SS_HIGH(); /* Terminate SPI transaction. */    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief Read SRAM * * This function reads from the SRAM of the radio transceiver. * * \param address Address in the TRX's SRAM where the read burst should start * \param length Length of the read burst * \param data Pointer to buffer where data is stored. */voidhal_sram_read(uint8_t address, uint8_t length, uint8_t *data){    AVR_ENTER_CRITICAL_REGION();    HAL_SS_LOW(); /* Initiate the SPI transaction. */    /*Send SRAM read command.*/    SPDR = HAL_TRX_CMD_SR;    while ((SPSR & (1 << SPIF)) == 0) {;}    uint8_t dummy_read = SPDR;    /*Send address where to start reading.*/    SPDR = address;    while ((SPSR & (1 << SPIF)) == 0) {;}    dummy_read = SPDR;    /*Upload the chosen memory area.*/    do{        SPDR = HAL_DUMMY_READ;        while ((SPSR & (1 << SPIF)) == 0) {;}        *data++ = SPDR;    } while (--length > 0);    HAL_SS_HIGH();    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief Write SRAM * * This function writes into the SRAM of the radio transceiver. * * \param address Address in the TRX's SRAM where the write burst should start * \param length  Length of the write burst * \param data    Pointer to an array of bytes that should be written */voidhal_sram_write(uint8_t address, uint8_t length, uint8_t *data){    AVR_ENTER_CRITICAL_REGION();    HAL_SS_LOW();    /*Send SRAM write command.*/    SPDR = HAL_TRX_CMD_SW;    while ((SPSR & (1 << SPIF)) == 0) {;}    uint8_t dummy_read = SPDR;    /*Send address where to start writing to.*/    SPDR = address;    while ((SPSR & (1 << SPIF)) == 0) {;}    dummy_read = SPDR;    /*Upload the chosen memory area.*/    do{        SPDR = *data++;        while ((SPSR & (1 << SPIF)) == 0) {;}        dummy_read = SPDR;    } while (--length > 0);    HAL_SS_HIGH();    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//* This #if compile switch is used to provide a "standard" function body for the *//* doxygen documentation. */#if defined(DOXYGEN)/** \brief ISR for the radio IRQ line, triggered by the input capture. *  This is the interrupt service routine for timer1.ICIE1 input capture. *  It is triggered of a rising edge on the radio transceivers IRQ line. */void RADIO_VECT(void);#else  /* !DOXYGEN */ISR(RADIO_VECT){    /*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();    /*Send Register address and read register content.*/    SPDR = RG_IRQ_STATUS | HAL_TRX_CMD_RR;    /* This is the second part of the convertion of system time to a 16 us time       base. The division is moved here so we can spend less time waiting for SPI       data.     */    isr_timestamp /= HAL_US_PER_SYMBOL; /* Divide so that we get time in 16us resolution. */    isr_timestamp &= HAL_SYMBOL_MASK;    while ((SPSR & (1 << SPIF)) == 0) {;}    uint8_t interrupt_source = SPDR; /* The interrupt variable is used as a dummy 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)){        if(rx_start_callback != NULL){            /* 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; /*  frame_length used for dummy data */            while ((SPSR & (1 << SPIF)) == 0) {;}            frame_length = SPDR;            HAL_SS_HIGH();            rx_start_callback(isr_timestamp, frame_length);        }    } else if (interrupt_source & HAL_TRX_END_MASK){        if(trx_end_callback != NULL){            trx_end_callback(isr_timestamp);        }    } else if (interrupt_source & HAL_TRX_UR_MASK){        ;    } else if (interrupt_source & HAL_PLL_UNLOCK_MASK){        ;    } else if (interrupt_source & HAL_PLL_LOCK_MASK){        hal_pll_lock_flag++;        ;    } else if (interrupt_source & HAL_BAT_LOW_MASK){        /*  Disable BAT_LOW interrupt to prevent endless interrupts. The interrupt */        /*  will continously be asserted while 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 {        ;    }}#   endif /* defined(DOXYGEN) *//*----------------------------------------------------------------------------*//* This #if compile switch is used to provide a "standard" function body for the *//* doxygen documentation. */#if defined(DOXYGEN)/** \brief Timer Overflow ISR * This is the interrupt service routine for timer1 overflow. */void TIMER1_OVF_vect(void);#else  /* !DOXYGEN */ISR(TIMER1_OVF_vect){    hal_system_time++;}#endif/** @} *//** @} *//*EOF*/

⌨️ 快捷键说明

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