mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-12-23 01:29:33 +00:00
Add macros by Roger Larsson to select between hardware or software SPI transactions.
Minor speed optimizations.
This commit is contained in:
parent
b58e13f8e1
commit
0ba9846abd
@ -47,7 +47,7 @@
|
||||
* \file
|
||||
* \brief This file contains low-level radio driver code.
|
||||
*
|
||||
* $Id: hal.h,v 1.3 2010/02/26 21:15:29 dak664 Exp $
|
||||
* $Id: hal.h,v 1.4 2010/11/30 19:47:40 dak664 Exp $
|
||||
*/
|
||||
|
||||
#ifndef HAL_AVR_H
|
||||
@ -366,7 +366,9 @@ void hal_register_write( uint8_t address, uint8_t value );
|
||||
uint8_t hal_subregister_read( uint8_t address, uint8_t mask, uint8_t position );
|
||||
void hal_subregister_write( uint8_t address, uint8_t mask, uint8_t position,
|
||||
uint8_t value );
|
||||
void hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback);
|
||||
//void hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback);
|
||||
/* For speed RF230BB does not use a callback */
|
||||
void hal_frame_read(hal_rx_frame_t *rx_frame);
|
||||
void hal_frame_write( uint8_t *write_buffer, uint8_t length );
|
||||
void hal_sram_read( uint8_t address, uint8_t length, uint8_t *data );
|
||||
void hal_sram_write( uint8_t address, uint8_t length, uint8_t *data );
|
||||
|
@ -56,6 +56,7 @@
|
||||
* This file contains low-level radio driver code.
|
||||
* This version is optimized for use with the "barebones" RF230bb driver,
|
||||
* which communicates directly with the contiki core MAC layer.
|
||||
* It is optimized for speed at the expense of generality.
|
||||
*/
|
||||
|
||||
|
||||
@ -131,6 +132,42 @@ static uint16_t hal_system_time = 0;
|
||||
/*============================ PROTOTYPES ====================================*/
|
||||
/*============================ IMPLEMENTATION ================================*/
|
||||
|
||||
#ifndef RF230BB_HARDWARE_SPI
|
||||
#define RF230BB_HARDWARE_SPI 1
|
||||
#endif
|
||||
|
||||
#if RF230BB_HARDWARE_SPI
|
||||
// AVR with hardware spi tranfers
|
||||
#define HAL_SPI_TRANSFER_OPEN() { \
|
||||
AVR_ENTER_CRITICAL_REGION(); \
|
||||
HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */
|
||||
#define HAL_SPI_TRANSFER_WRITE(to_write) SPDR = to_write
|
||||
#define HAL_SPI_TRANSFER_WAIT() ({while ((SPSR & (1 << SPIF)) == 0) {;}}) /* gcc extension, alternative inline function */
|
||||
#define HAL_SPI_TRANSFER_READ() (SPDR)
|
||||
#define HAL_SPI_TRANSFER_CLOSE() \
|
||||
HAL_SS_HIGH(); /* End the transaction by pulling the Slave Select High. */ \
|
||||
AVR_LEAVE_CRITICAL_REGION(); \
|
||||
}
|
||||
#define HAL_SPI_TRANSFER(to_write) ( \
|
||||
HAL_SPI_TRANSFER_WRITE(to_write), \
|
||||
HAL_SPI_TRANSFER_WAIT(), \
|
||||
HAL_SPI_TRANSFER_READ() )
|
||||
|
||||
#else /* RF230BB_HARDWARE_SPI */
|
||||
// Software SPI transfers (Mulle, for reference)
|
||||
#define HAL_SPI_TRANSFER_OPEN() { uint8_t spiTemp; \
|
||||
AVR_ENTER_CRITICAL_REGION(); \
|
||||
HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */
|
||||
#define HAL_SPI_TRANSFER_WRITE(to_write) (spiTemp = spiWrite(to_write))
|
||||
#define HAL_SPI_TRANSFER_WAIT() (0)
|
||||
#define HAL_SPI_TRANSFER_READ() (spiTemp)
|
||||
#define HAL_SPI_TRANSFER_CLOSE() \
|
||||
HAL_SS_HIGH(); /* End the transaction by pulling the Slave Select High. */ \
|
||||
AVR_LEAVE_CRITICAL_REGION(); \
|
||||
}
|
||||
#define HAL_SPI_TRANSFER(to_write) (spiTemp = spiWrite(to_write))
|
||||
#endif /* RF230BB_HARDWARE_SPI */
|
||||
|
||||
/** \brief This function initializes the Hardware Abstraction Layer.
|
||||
*/
|
||||
void
|
||||
@ -313,22 +350,14 @@ hal_register_read(uint8_t address)
|
||||
|
||||
uint8_t register_value = 0;
|
||||
|
||||
AVR_ENTER_CRITICAL_REGION();
|
||||
|
||||
HAL_SS_LOW(); /* Start the SPI transaction by pulling the Slave Select low. */
|
||||
HAL_SPI_TRANSFER_OPEN();
|
||||
|
||||
/*Send Register address and read register content.*/
|
||||
SPDR = address;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
register_value = SPDR;
|
||||
register_value = HAL_SPI_TRANSFER(address); // dummy read
|
||||
|
||||
SPDR = register_value;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
register_value = SPDR;
|
||||
register_value = HAL_SPI_TRANSFER(register_value); // dummy write
|
||||
|
||||
HAL_SS_HIGH(); /* End the transaction by pulling the Slave Select High. */
|
||||
|
||||
AVR_LEAVE_CRITICAL_REGION();
|
||||
HAL_SPI_TRANSFER_CLOSE();
|
||||
|
||||
return register_value;
|
||||
}
|
||||
@ -348,22 +377,14 @@ hal_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. */
|
||||
HAL_SPI_TRANSFER_OPEN();
|
||||
|
||||
/*Send Register address and write register content.*/
|
||||
SPDR = address;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
uint8_t dummy_read = SPDR;
|
||||
uint8_t dummy_read = HAL_SPI_TRANSFER(address);
|
||||
|
||||
SPDR = value;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
dummy_read = SPDR;
|
||||
dummy_read = HAL_SPI_TRANSFER(value);
|
||||
|
||||
HAL_SS_HIGH(); /* End the transaction by pulling the Slave Slect High. */
|
||||
|
||||
AVR_LEAVE_CRITICAL_REGION();
|
||||
HAL_SPI_TRANSFER_CLOSE();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -425,33 +446,30 @@ hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position,
|
||||
* 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.
|
||||
* This version is optimized for use with contiki RF230BB driver
|
||||
* This version is optimized for use with contiki RF230BB driver.
|
||||
* The callback routine and CRC are left out for speed in reading the rx buffrer .
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
void
|
||||
hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback)
|
||||
//hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback)
|
||||
hal_frame_read(hal_rx_frame_t *rx_frame)
|
||||
{
|
||||
uint8_t *rx_data=0;
|
||||
// uint8_t *rx_data=0;
|
||||
uint8_t *rx_data;
|
||||
|
||||
/* check that we have either valid frame pointer or callback pointer */
|
||||
// if (!rx_frame && !rx_callback)
|
||||
// return;
|
||||
|
||||
AVR_ENTER_CRITICAL_REGION();
|
||||
|
||||
HAL_SS_LOW();
|
||||
HAL_SPI_TRANSFER_OPEN();
|
||||
|
||||
/*Send frame read command.*/
|
||||
SPDR = HAL_TRX_CMD_FR;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
uint8_t frame_length = SPDR;
|
||||
(void)HAL_SPI_TRANSFER(HAL_TRX_CMD_FR);
|
||||
|
||||
/*Read frame length.*/
|
||||
SPDR = frame_length;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
frame_length = SPDR;
|
||||
uint8_t frame_length = HAL_SPI_TRANSFER(0);
|
||||
|
||||
/*Check for correct frame length.*/
|
||||
if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)){
|
||||
@ -462,44 +480,43 @@ hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback)
|
||||
// } else {
|
||||
// rx_callback(frame_length);
|
||||
// }
|
||||
/*Upload frame buffer to data pointer. Calculate CRC.*/
|
||||
SPDR = frame_length;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
/*Upload frame buffer to data pointer */
|
||||
|
||||
HAL_SPI_TRANSFER_WRITE(0);
|
||||
HAL_SPI_TRANSFER_WAIT();
|
||||
|
||||
do{
|
||||
uint8_t tempData = SPDR;
|
||||
SPDR = 0; /* dummy write */
|
||||
*rx_data++ = HAL_SPI_TRANSFER_READ();
|
||||
HAL_SPI_TRANSFER_WRITE(0);
|
||||
HAL_SPI_TRANSFER_WAIT();
|
||||
|
||||
// if (rx_frame){
|
||||
*rx_data++ = tempData;
|
||||
// *rx_data++ = tempData;
|
||||
// } else {
|
||||
// rx_callback(tempData);
|
||||
// }
|
||||
/* RF230 does crc in hardware, for speed we hope the buffer is not being overwritten! */
|
||||
/* RF230 does crc in hardware, doing the checksum here ensures the rx buffer has not been overwritten by the next packet */
|
||||
/* Since doing the checksum makes such overwrites more probable, we skip it and hope for the best. */
|
||||
/* A full buffer should be read in 320us at 2x spi clocking, so with a low interrupt latency overwrites should not occur */
|
||||
// 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;
|
||||
rx_frame->lqi = HAL_SPI_TRANSFER_READ();
|
||||
// } else {
|
||||
// rx_callback(SPDR);
|
||||
// }
|
||||
|
||||
HAL_SS_HIGH();
|
||||
rx_frame->crc = 1;
|
||||
|
||||
/*Check calculated crc, and set crc field in hal_rx_frame_t accordingly.*/
|
||||
// if (rx_frame){
|
||||
// rx_frame->crc = (crc == HAL_CALCULATED_CRC_OK);
|
||||
rx_frame->crc = 1;
|
||||
// } else {
|
||||
// rx_callback(crc != HAL_CALCULATED_CRC_OK);
|
||||
// }
|
||||
} else {
|
||||
HAL_SS_HIGH();
|
||||
|
||||
// if (rx_frame){
|
||||
rx_frame->length = 0;
|
||||
rx_frame->lqi = 0;
|
||||
@ -507,7 +524,7 @@ hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback)
|
||||
// }
|
||||
}
|
||||
|
||||
AVR_LEAVE_CRITICAL_REGION();
|
||||
HAL_SPI_TRANSFER_CLOSE();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -522,32 +539,20 @@ hal_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. */
|
||||
HAL_SPI_TRANSFER_OPEN();
|
||||
|
||||
/*SEND FRAME WRITE COMMAND AND FRAME LENGTH.*/
|
||||
SPDR = HAL_TRX_CMD_FW;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
uint8_t dummy_read = SPDR;
|
||||
|
||||
uint8_t dummy_read = HAL_SPI_TRANSFER(HAL_TRX_CMD_FW);
|
||||
|
||||
SPDR = length;
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
dummy_read = SPDR;
|
||||
dummy_read = HAL_SPI_TRANSFER(length);
|
||||
|
||||
/* Download to the Frame Buffer. */
|
||||
do{
|
||||
SPDR = *write_buffer++;
|
||||
--length;
|
||||
dummy_read = HAL_SPI_TRANSFER(*write_buffer++);
|
||||
} while (--length > 0);
|
||||
|
||||
while ((SPSR & (1 << SPIF)) == 0) {;}
|
||||
|
||||
dummy_read = SPDR;
|
||||
} while (length > 0);
|
||||
|
||||
HAL_SS_HIGH(); /* Terminate SPI transaction. */
|
||||
|
||||
AVR_LEAVE_CRITICAL_REGION();
|
||||
HAL_SPI_TRANSFER_CLOSE();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -653,11 +658,11 @@ 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.
|
||||
TCNT1 register. Not implented in RF230BB for speed
|
||||
*/
|
||||
uint32_t isr_timestamp = hal_system_time;
|
||||
isr_timestamp <<= 16;
|
||||
isr_timestamp |= TCNT1;
|
||||
// uint32_t isr_timestamp = hal_system_time;
|
||||
// isr_timestamp <<= 16;
|
||||
// isr_timestamp |= TCNT1;
|
||||
volatile uint8_t state;
|
||||
|
||||
INTERRUPTDEBUG(1);
|
||||
@ -672,8 +677,8 @@ ISR(RADIO_VECT)
|
||||
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;
|
||||
// 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. */
|
||||
@ -723,14 +728,15 @@ ISR(RADIO_VECT)
|
||||
#if RF230_CONF_AUTOACK
|
||||
rf230_last_rssi=hal_subregister_read(SR_ED_LEVEL);
|
||||
if (rf230_last_rssi >= RF230_MIN_RX_POWER) {
|
||||
// if (hal_subregister_read(SR_ED_LEVEL) >= RF230_MIN_RX_POWER) {
|
||||
// if (hal_subregister_read(SR_ED_LEVEL) >= RF230_MIN_RX_POWER) {
|
||||
#else
|
||||
rf230_last_rssi=hal_subregister_read(SR_RSSI);
|
||||
// if (hal_subregister_read(SR_RSSI) >= RF230_MIN_RX_POWER/3) {
|
||||
// if (hal_subregister_read(SR_RSSI) >= RF230_MIN_RX_POWER/3) {
|
||||
if (rf230_last_rssi >= RF230_MIN_RX_POWER/3) {
|
||||
#endif
|
||||
#endif
|
||||
hal_frame_read(&rxframe, NULL);
|
||||
// hal_frame_read(&rxframe, NULL);
|
||||
hal_frame_read(&rxframe);
|
||||
rf230_interrupt();
|
||||
// trx_end_callback(isr_timestamp);
|
||||
#ifdef RF230_MIN_RX_POWER
|
||||
|
Loading…
Reference in New Issue
Block a user