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

📄 hal.c

📁 Contiki是一个开源
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Copyright (c) 2008, Swedish Institute of Computer Science *  All rights reserved.  * *  Additional fixes for AVR contributed by: * *	Colin O'Flynn coflynn@newae.com *	Eric Gnoske egnoske@gmail.com *	Blake Leverett bleverett@gmail.com *	Mike Vidales mavida404@gmail.com *	Kevin Brown kbrown3@uccs.edu *	Nate Bohlmann nate@elfwerks.com * *   All rights reserved. * *   Redistribution and use in source and binary forms, with or without *   modification, are permitted provided that the following conditions are met: * *   * Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer. *   * Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in *     the documentation and/or other materials provided with the *     distribution. *   * Neither the name of the copyright holders nor the names of *     contributors may be used to endorse or promote products derived *     from this software without specific prior written permission. * *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *  POSSIBILITY OF SUCH DAMAGE. * *  $Id: hal.c,v 1.2 2008/10/14 18:37:28 c_oflynn Exp $*//** *   \addtogroup wireless *  @{*//** *   \defgroup hal RF230 hardware level drivers *   @{ *//** *  \file *  This file contains low-level radio driver code. *//*============================ INCLUDE =======================================*/#include <stdlib.h>#include "hal.h"#include "at86rf230_registermap.h"/*============================ MACROS ========================================*//* * Macros defined for the radio transceiver's access modes. * * These functions are implemented as macros since they are used very often. */#define HAL_DUMMY_READ         (0x00) /**<  Dummy value for the SPI. */#define HAL_TRX_CMD_RW         (0xC0) /**<  Register Write (short mode). */#define HAL_TRX_CMD_RR         (0x80) /**<  Register Read (short mode). */#define HAL_TRX_CMD_FW         (0x60) /**<  Frame Transmit Mode (long mode). */#define HAL_TRX_CMD_FR         (0x20) /**<  Frame Receive Mode (long mode). */#define HAL_TRX_CMD_SW         (0x40) /**<  SRAM Write. */#define HAL_TRX_CMD_SR         (0x00) /**<  SRAM Read. */#define HAL_TRX_CMD_RADDRM     (0x7F) /**<  Register Address Mask. */#define HAL_CALCULATED_CRC_OK   (0) /**<  CRC calculated over the frame including the CRC field should be 0. *//*============================ TYPDEFS =======================================*//*============================ VARIABLES =====================================*//** \brief This is a file internal variable that contains the 16 MSB of the *         system time. * *         The system time (32-bit) is the current time in microseconds. For the *         AVR microcontroller implementation this is solved by using a 16-bit *         timer (Timer1) with a clock frequency of 1MHz. The hal_system_time is *         incremented when the 16-bit timer overflows, representing the 16 MSB. *         The timer value it self (TCNT1) is then the 16 LSB. * *  \see hal_get_system_time */static uint16_t hal_system_time = 0;/*Flag section.*/static uint8_t volatile hal_bat_low_flag; /**<  BAT_LOW flag. */static uint8_t volatile hal_pll_lock_flag;   /**<  PLL_LOCK flag. *//*Callbacks.*//** \brief This function is called when a rx_start interrupt is signaled. * *         If this function pointer is set to something else than NULL, it will *         be called when a RX_START event is signaled. The function takes two *         parameters: timestamp in IEEE 802.15.4 symbols (16 us resolution) and *         frame length. The event handler will be called in the interrupt domain, *         so the function must be kept short and not be blocking! Otherwise the *         system performance will be greatly degraded. * *  \see hal_set_rx_start_event_handler */static hal_rx_start_isr_event_handler_t rx_start_callback;/** \brief This function is called when a trx_end interrupt is signaled. * *         If this function pointer is set to something else than NULL, it will *         be called when a TRX_END event is signaled. The function takes one *         parameter: timestamp in IEEE 802.15.4 symbols (16 us resolution). *         The event handler will be called in the interrupt domain, *         so the function must not block! * *  \see hal_set_trx_end_event_handler */static hal_trx_end_isr_event_handler_t trx_end_callback;/*============================ PROTOTYPES ====================================*//*============================ IMPLEMENTATION ================================*//** \brief  This function initializes the Hardware Abstraction Layer. */voidhal_init(void){    /*Reset variables used in file.*/    hal_system_time = 0;    hal_reset_flags();    /*IO Specific Initialization.*/    DDR_SLP_TR |= (1 << SLP_TR); /* Enable SLP_TR as output. */    DDR_RST    |= (1 << RST);    /* Enable RST as output. */    /*SPI Specific Initialization.*/    /* Set SS, CLK and MOSI as output. */    HAL_DDR_SPI  |= (1 << HAL_DD_SS) | (1 << HAL_DD_SCK) | (1 << HAL_DD_MOSI);    HAL_PORT_SPI |= (1 << HAL_DD_SS) | (1 << HAL_DD_SCK); /* Set SS and CLK high */    /* Run SPI at max speed */    SPCR         = (1 << SPE) | (1 << MSTR); /* Enable SPI module and master operation. */    SPSR         = (1 << SPI2X); /* Enable doubled SPI speed in master mode. */    /*TIMER1 Specific Initialization.*/    TCCR1B = HAL_TCCR1B_CONFIG;       /* Set clock prescaler */    TIFR1 |= (1 << ICF1);             /* Clear Input Capture Flag. */    HAL_ENABLE_OVERFLOW_INTERRUPT(); /* Enable Timer1 overflow interrupt. */    hal_enable_trx_interrupt();    /* Enable interrupts from the radio transceiver. */}/*----------------------------------------------------------------------------*//** \brief  This function reset the interrupt flags and interrupt event handlers *          (Callbacks) to their default value. */voidhal_reset_flags(void){    AVR_ENTER_CRITICAL_REGION();    /* Reset Flags. */    hal_bat_low_flag     = 0;    hal_pll_lock_flag    = 0;    /* Reset Associated Event Handlers. */    rx_start_callback = NULL;    trx_end_callback  = NULL;    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief  This function returns the current value of the BAT_LOW flag. * *  The BAT_LOW flag is incremented each time a BAT_LOW event is signaled from the *  radio transceiver. This way it is possible for the end user to poll the flag *  for new event occurances. */uint8_thal_get_bat_low_flag(void){    return hal_bat_low_flag;}/*----------------------------------------------------------------------------*//** \brief  This function clears the BAT_LOW flag. */voidhal_clear_bat_low_flag(void){    AVR_ENTER_CRITICAL_REGION();    hal_bat_low_flag = 0;    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief  This function is used to set new TRX_END event handler, overriding *          old handler reference. */hal_trx_end_isr_event_handler_thal_get_trx_end_event_handler(void){    return trx_end_callback;}/*----------------------------------------------------------------------------*//** \brief  This function is used to set new TRX_END event handler, overriding *          old handler reference. */voidhal_set_trx_end_event_handler(hal_trx_end_isr_event_handler_t trx_end_callback_handle){    AVR_ENTER_CRITICAL_REGION();    trx_end_callback = trx_end_callback_handle;    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief  Remove event handler reference. */voidhal_clear_trx_end_event_handler(void){    AVR_ENTER_CRITICAL_REGION();    trx_end_callback = NULL;    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief  This function returns the active RX_START event handler * *  \return Current RX_START event handler registered. */hal_rx_start_isr_event_handler_thal_get_rx_start_event_handler(void){    return rx_start_callback;}/*----------------------------------------------------------------------------*//** \brief  This function is used to set new RX_START event handler, overriding *          old handler reference. */voidhal_set_rx_start_event_handler(hal_rx_start_isr_event_handler_t rx_start_callback_handle){    AVR_ENTER_CRITICAL_REGION();    rx_start_callback = rx_start_callback_handle;    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief  Remove event handler reference. */voidhal_clear_rx_start_event_handler(void){    AVR_ENTER_CRITICAL_REGION();    rx_start_callback = NULL;    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief  This function returns the current value of the PLL_LOCK flag. * *  The PLL_LOCK flag is incremented each time a PLL_LOCK event is signaled from the *  radio transceiver. This way it is possible for the end user to poll the flag *  for new event occurances. */uint8_thal_get_pll_lock_flag(void){    return hal_pll_lock_flag;}/*----------------------------------------------------------------------------*//** \brief  This function clears the PLL_LOCK flag. */voidhal_clear_pll_lock_flag(void){    AVR_ENTER_CRITICAL_REGION();    hal_pll_lock_flag = 0;    AVR_LEAVE_CRITICAL_REGION();}/*----------------------------------------------------------------------------*//** \brief  This function reads data from one of the radio transceiver's registers. * *  \param  address Register address to read from. See datasheet for register *                  map. * *  \see Look at the at86rf230_registermap.h file for register address definitions. * *  \returns The actual value of the read register. */uint8_thal_register_read(uint8_t address){    /* Add the register read command to the register address. */    address &= HAL_TRX_CMD_RADDRM;    address |= HAL_TRX_CMD_RR;    uint8_t register_value = 0;    AVR_ENTER_CRITICAL_REGION();    HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */    /*Send Register address and read register content.*/    SPDR = address;    while ((SPSR & (1 << SPIF)) == 0) {;}    register_value = SPDR;    SPDR = register_value;    while ((SPSR & (1 << SPIF)) == 0) {;}    register_value = SPDR;    HAL_SS_HIGH(); /* End the transaction by pulling the Slave Select High. */    AVR_LEAVE_CRITICAL_REGION();    return register_value;}/*----------------------------------------------------------------------------*//** \brief  This function writes a new value to one of the radio transceiver's *          registers. * *  \see Look at the at86rf230_registermap.h file for register address definitions. * *  \param  address Address of register to write. *  \param  value   Value to write. */voidhal_register_write(uint8_t address, uint8_t value){    /* Add the Register Write command to the address. */    address = HAL_TRX_CMD_RW | (HAL_TRX_CMD_RADDRM & address);    AVR_ENTER_CRITICAL_REGION();    HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */    /*Send Register address and write register content.*/    SPDR = address;    while ((SPSR & (1 << SPIF)) == 0) {;}    uint8_t dummy_read = SPDR;    SPDR = value;    while ((SPSR & (1 << SPIF)) == 0) {;}    dummy_read = SPDR;    HAL_SS_HIGH(); /* End the transaction by pulling the Slave Slect High. */    AVR_LEAVE_CRITICAL_REGION();}

⌨️ 快捷键说明

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