Improve rf23x cca procesing

Fix delay_loop timing bug by using long long calculation.
128rfa1 and rf230 both working with contikimac RDC
This commit is contained in:
David Kopf 2011-11-14 11:49:58 -05:00
parent 062b85123e
commit 31ba84eb75
3 changed files with 30 additions and 19 deletions

View file

@ -952,7 +952,7 @@ HAL_RF230_ISR()
/* Save RSSI for this packet if not in extended mode, scaling to 1dB resolution */ /* Save RSSI for this packet if not in extended mode, scaling to 1dB resolution */
#if !RF230_CONF_AUTOACK #if !RF230_CONF_AUTOACK
#if 0 // 3-clock shift and add is faster on machines with no hardware multiply #if 0 // 3-clock shift and add is faster on machines with no hardware multiply
// While the compiler should use similar code for multiply by 3 there may be a bug with -Os in avr-gcc that calls the general subroutine // With -Os avr-gcc saves a byte by using the general routine for multiply by 3
rf230_last_rssi = hal_subregister_read(SR_RSSI); rf230_last_rssi = hal_subregister_read(SR_RSSI);
rf230_last_rssi = (rf230_last_rssi <<1) + rf230_last_rssi; rf230_last_rssi = (rf230_last_rssi <<1) + rf230_last_rssi;
#else // Faster with 1-clock multiply. Raven and Jackdaw have 2-clock multiply so same speed while saving 2 bytes of program memory #else // Faster with 1-clock multiply. Raven and Jackdaw have 2-clock multiply so same speed while saving 2 bytes of program memory

View file

@ -47,7 +47,7 @@
//#define delay_us( us ) ( _delay_us( ( us ) ) ) //#define delay_us( us ) ( _delay_us( ( us ) ) )
//_delay_loop_2(uint16_t count) is 4 CPU cycles per iteration, up to 32 milliseconds at 8MHz //_delay_loop_2(uint16_t count) is 4 CPU cycles per iteration, up to 32 milliseconds at 8MHz
#include <util/delay_basic.h> #include <util/delay_basic.h>
#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) #define delay_us( us ) ( _delay_loop_2(1+((unsigned long long)us*F_CPU)/4000000UL) )
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#elif defined(__MSP430__) #elif defined(__MSP430__)
@ -104,6 +104,10 @@ static bool is_promiscuous;
* RF230_INSERTACK will generate one based on the hardware result. * RF230_INSERTACK will generate one based on the hardware result.
* This is triggered when the read routine is called with a buffer * This is triggered when the read routine is called with a buffer
* length of three (the ack length). * length of three (the ack length).
* In extended nmode it can be enabled by default to support either
* method. In nonextended mode it would pass an extra ACK to RDCs
* that use the TX_OK result to signal a successful ACK.
* Adds 100 bytes of program flash and two bytes of RAM.
*/ */
#if RF320_CONF_INSERTACK && RF230_CONF_AUTORETRIES #if RF320_CONF_INSERTACK && RF230_CONF_AUTORETRIES
#define RF230_INSERTACK 1 #define RF230_INSERTACK 1
@ -527,15 +531,17 @@ on(void)
hal_set_slptr_low(); hal_set_slptr_low();
while (rf230_interruptwait) {} while (rf230_interruptwait) {}
#else #else
/* SPI based radios. The wake time depends on board capacitance, use 2x the nominal value for safety */ /* SPI based radios. The wake time depends on board capacitance.
uint8_t sreg = SREG; * Make sure the delay is long enough, as using SPI too soon will reset the MCU!
cli(); * Use 2x the nominal value for safety. 1.5x is not long enough for Raven!
*/
// uint8_t sreg = SREG;cli();
hal_set_slptr_low(); hal_set_slptr_low();
delay_us(TIME_SLEEP_TO_TRX_OFF * 2); delay_us(2*TIME_SLEEP_TO_TRX_OFF);
SREG=sreg; // delay_us(TIME_SLEEP_TO_TRX_OFF+TIME_SLEEP_TO_TRX_OFF/2);
// SREG=sreg;
#endif #endif
} }
rf230_waitidle();
#if RF230_CONF_AUTOACK #if RF230_CONF_AUTOACK
// radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON); // radio_set_trx_state(is_promiscuous?RX_ON:RX_AACK_ON);
@ -543,6 +549,7 @@ on(void)
#else #else
radio_set_trx_state(RX_ON); radio_set_trx_state(RX_ON);
#endif #endif
rf230_waitidle();
} }
static void static void
off(void) off(void)
@ -874,8 +881,8 @@ rf230_transmit(unsigned short payload_len)
#else #else
hal_set_slptr_low(); hal_set_slptr_low();
DEBUGFLOW('j'); DEBUGFLOW('j');
delay_us(TIME_SLEEP_TO_TRX_OFF); delay_us(2*TIME_SLEEP_TO_TRX_OFF); //extra delay depends on board capacitance
delay_us(TIME_SLEEP_TO_TRX_OFF); //extra delay depends on board capacitance // delay_us(TIME_SLEEP_TO_TRX_OFF+TIME_SLEEP_TO_TRX_OFF/2);
#endif #endif
} else { } else {
@ -1613,7 +1620,6 @@ rf230_cca(void)
{ {
uint8_t cca=0; uint8_t cca=0;
uint8_t radio_was_off = 0; uint8_t radio_was_off = 0;
uint8_t volatile saved_sreg = SREG;
/* If the radio is locked by an underlying thread (because we are /* If the radio is locked by an underlying thread (because we are
being invoked through an interrupt), we preted that the coast is being invoked through an interrupt), we preted that the coast is
@ -1639,8 +1645,7 @@ rf230_cca(void)
radio_was_off = 1; radio_was_off = 1;
rf230_on(); rf230_on();
} }
/* Don't allow interrupts! */
// cli();
ENERGEST_ON(ENERGEST_TYPE_LED_YELLOW); ENERGEST_ON(ENERGEST_TYPE_LED_YELLOW);
/* CCA Mode Mode 1=Energy above threshold 2=Carrier sense only 3=Both 0=Either (RF231 only) */ /* CCA Mode Mode 1=Energy above threshold 2=Carrier sense only 3=Both 0=Either (RF231 only) */
/* Use the current mode. Note triggering a manual CCA is not recommended in extended mode */ /* Use the current mode. Note triggering a manual CCA is not recommended in extended mode */
@ -1684,13 +1689,19 @@ rf230_cca(void)
#else /* RF230, RF231 */ #else /* RF230, RF231 */
/* Don't allow interrupts! */
/* Start the CCA, wait till done, return result */ /* Start the CCA, wait till done, return result */
/* Note reading the TRX_STATUS register clears both CCA_STATUS and CCA_DONE bits */ /* Note reading the TRX_STATUS register clears both CCA_STATUS and CCA_DONE bits */
{ uint8_t volatile saved_sreg = SREG;
cli();
rf230_waitidle();
hal_subregister_write(SR_CCA_REQUEST,1); hal_subregister_write(SR_CCA_REQUEST,1);
delay_us(TIME_CCA); delay_us(TIME_CCA);
while ((cca & 0x80) == 0 ) { while ((cca & 0x80) == 0 ) {
cca=hal_register_read(RG_TRX_STATUS); cca=hal_register_read(RG_TRX_STATUS);
} }
SREG=saved_sreg;
}
#endif #endif
ENERGEST_OFF(ENERGEST_TYPE_LED_YELLOW); ENERGEST_OFF(ENERGEST_TYPE_LED_YELLOW);
if(radio_was_off) { if(radio_was_off) {
@ -1699,12 +1710,10 @@ rf230_cca(void)
// if (cca & 0x40) {/*DEBUGFLOW('3')*/;} else {rf230_pending=1;DEBUGFLOW('4');} // if (cca & 0x40) {/*DEBUGFLOW('3')*/;} else {rf230_pending=1;DEBUGFLOW('4');}
if (cca & 0x40) { if (cca & 0x40) {
// DEBUGFLOW('5'); // DEBUGFLOW('5');
SREG=saved_sreg;
return 1; return 1;
} else { } else {
// DEBUGFLOW('6'); // DEBUGFLOW('6');
busyexit: busyexit:
SREG=saved_sreg;
return 0; return 0;
} }
} }

View file

@ -66,13 +66,15 @@
#define RF230_REVA ( 1 ) #define RF230_REVA ( 1 )
#define RF230_REVB ( 2 ) #define RF230_REVB ( 2 )
#define SUPPORTED_MANUFACTURER_ID ( 31 ) #define SUPPORTED_MANUFACTURER_ID ( 31 )
/* RF230 does not support RX_START interrupts in extended mode, but it seems harmless to always enable it. */
/* In non-extended mode this allows RX_START to sample the RF rssi at the end of the preamble */
//#define RF230_SUPPORTED_INTERRUPT_MASK ( 0x0C ) //disable RX_START
#if defined(__AVR_ATmega128RFA1__) #if defined(__AVR_ATmega128RFA1__)
#define RF230_SUPPORTED_INTERRUPT_MASK ( 0xFF ) #define RF230_SUPPORTED_INTERRUPT_MASK ( 0xFF )
#else #else
#define RF230_SUPPORTED_INTERRUPT_MASK ( 0x0F ) /* RF230 does not support RX_START interrupts in extended mode, but it seems harmless to always enable it. */
/* In non-extended mode this allows RX_START to sample the RF rssi at the end of the preamble */
//#define RF230_SUPPORTED_INTERRUPT_MASK ( 0x08 ) //enable trx end only
//#define RF230_SUPPORTED_INTERRUPT_MASK ( 0x0F ) //disable bat low, trx underrun
#define RF230_SUPPORTED_INTERRUPT_MASK ( 0x0C ) //disable bat low, trx underrun, pll lock/unlock
#endif #endif
#define RF230_MIN_CHANNEL ( 11 ) #define RF230_MIN_CHANNEL ( 11 )