Reworked the locking code, which seems to fix a few bugs caused by the interaction with contikimac. Contikimac performs a CCA check in a preempting rtimer, which requires underlying code to properly call the GET_LOCK() macro. This fix seems to solve most problems, but there may be others left.
This commit is contained in:
parent
3769a28516
commit
0035a70537
1 changed files with 57 additions and 45 deletions
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*
|
*
|
||||||
* @(#)$Id: cc2420.c,v 1.43 2010/03/09 15:45:29 joxe Exp $
|
* @(#)$Id: cc2420.c,v 1.44 2010/03/14 22:45:20 adamdunkels Exp $
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This code is almost device independent and should be easy to port.
|
* This code is almost device independent and should be easy to port.
|
||||||
|
@ -184,7 +184,7 @@ static void
|
||||||
on(void)
|
on(void)
|
||||||
{
|
{
|
||||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||||
PRINTF("on\n");
|
/* PRINTF("on\n");*/
|
||||||
receive_on = 1;
|
receive_on = 1;
|
||||||
|
|
||||||
ENABLE_FIFOP_INT();
|
ENABLE_FIFOP_INT();
|
||||||
|
@ -195,11 +195,11 @@ static void
|
||||||
off(void)
|
off(void)
|
||||||
{
|
{
|
||||||
leds_on(LEDS_GREEN);
|
leds_on(LEDS_GREEN);
|
||||||
PRINTF("off\n");
|
/* PRINTF("off\n");*/
|
||||||
receive_on = 0;
|
receive_on = 0;
|
||||||
|
|
||||||
/* Wait for transmission to end before turning radio off. */
|
/* Wait for transmission to end before turning radio off. */
|
||||||
// while(status() & BV(CC2420_TX_ACTIVE));
|
while(status() & BV(CC2420_TX_ACTIVE));
|
||||||
|
|
||||||
strobe(CC2420_SRFOFF);
|
strobe(CC2420_SRFOFF);
|
||||||
DISABLE_FIFOP_INT();
|
DISABLE_FIFOP_INT();
|
||||||
|
@ -207,17 +207,19 @@ off(void)
|
||||||
leds_off(LEDS_GREEN);
|
leds_off(LEDS_GREEN);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#define GET_LOCK() locked = 1
|
#define GET_LOCK() locked++
|
||||||
static void RELEASE_LOCK(void) {
|
static void RELEASE_LOCK(void) {
|
||||||
if(lock_on) {
|
if(locked == 1) {
|
||||||
on();
|
if(lock_on) {
|
||||||
lock_on = 0;
|
on();
|
||||||
|
lock_on = 0;
|
||||||
|
}
|
||||||
|
if(lock_off) {
|
||||||
|
off();
|
||||||
|
lock_off = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(lock_off) {
|
locked--;
|
||||||
off();
|
|
||||||
lock_off = 0;
|
|
||||||
}
|
|
||||||
locked = 0;
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static unsigned
|
static unsigned
|
||||||
|
@ -355,6 +357,7 @@ cc2420_transmit(unsigned short payload_len)
|
||||||
/* SFD went high but we are not transmitting. This means that
|
/* SFD went high but we are not transmitting. This means that
|
||||||
we just started receiving a packet, so we drop the
|
we just started receiving a packet, so we drop the
|
||||||
transmission. */
|
transmission. */
|
||||||
|
RELEASE_LOCK();
|
||||||
return RADIO_TX_ERR;
|
return RADIO_TX_ERR;
|
||||||
}
|
}
|
||||||
if(receive_on) {
|
if(receive_on) {
|
||||||
|
@ -453,20 +456,23 @@ cc2420_off(void)
|
||||||
/* If we are called when the driver is locked, we indicate that the
|
/* If we are called when the driver is locked, we indicate that the
|
||||||
radio should be turned off when the lock is unlocked. */
|
radio should be turned off when the lock is unlocked. */
|
||||||
if(locked) {
|
if(locked) {
|
||||||
|
/* printf("Off when locked (%d)\n", locked);*/
|
||||||
|
leds_on(LEDS_GREEN + LEDS_BLUE);
|
||||||
lock_off = 1;
|
lock_off = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GET_LOCK();
|
||||||
/* If we are currently receiving a packet (indicated by SFD == 1),
|
/* If we are currently receiving a packet (indicated by SFD == 1),
|
||||||
we don't actually switch the radio off now, but signal that the
|
we don't actually switch the radio off now, but signal that the
|
||||||
driver should switch off the radio once the packet has been
|
driver should switch off the radio once the packet has been
|
||||||
received and processed, by setting the 'lock_off' variable. */
|
received and processed, by setting the 'lock_off' variable. */
|
||||||
if(status() & BV(CC2420_TX_ACTIVE)) {
|
if(status() & BV(CC2420_TX_ACTIVE)) {
|
||||||
lock_off = 1;
|
lock_off = 1;
|
||||||
return 1;
|
} else {
|
||||||
|
off();
|
||||||
}
|
}
|
||||||
|
RELEASE_LOCK();
|
||||||
off();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -477,11 +483,14 @@ cc2420_on(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(locked) {
|
if(locked) {
|
||||||
|
leds_on(LEDS_GREEN + LEDS_RED);
|
||||||
lock_on = 1;
|
lock_on = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GET_LOCK();
|
||||||
on();
|
on();
|
||||||
|
RELEASE_LOCK();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -495,11 +504,12 @@ void
|
||||||
cc2420_set_channel(int c)
|
cc2420_set_channel(int c)
|
||||||
{
|
{
|
||||||
uint16_t f;
|
uint16_t f;
|
||||||
|
|
||||||
|
GET_LOCK();
|
||||||
/*
|
/*
|
||||||
* Subtract the base channel (11), multiply by 5, which is the
|
* Subtract the base channel (11), multiply by 5, which is the
|
||||||
* channel spacing. 357 is 2405-2048 and 0x4000 is LOCK_THR = 1.
|
* channel spacing. 357 is 2405-2048 and 0x4000 is LOCK_THR = 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
channel = c;
|
channel = c;
|
||||||
|
|
||||||
f = 5 * (c - 11) + 357 + 0x4000;
|
f = 5 * (c - 11) + 357 + 0x4000;
|
||||||
|
@ -519,6 +529,7 @@ cc2420_set_channel(int c)
|
||||||
strobe(CC2420_SRXON);
|
strobe(CC2420_SRXON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELEASE_LOCK();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -528,6 +539,9 @@ cc2420_set_pan_addr(unsigned pan,
|
||||||
{
|
{
|
||||||
uint16_t f = 0;
|
uint16_t f = 0;
|
||||||
uint8_t tmp[2];
|
uint8_t tmp[2];
|
||||||
|
|
||||||
|
GET_LOCK();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writing RAM requires crystal oscillator to be stable.
|
* Writing RAM requires crystal oscillator to be stable.
|
||||||
*/
|
*/
|
||||||
|
@ -548,6 +562,7 @@ cc2420_set_pan_addr(unsigned pan,
|
||||||
}
|
}
|
||||||
FASTSPI_WRITE_RAM_LE(tmp_addr, CC2420RAM_IEEEADDR, 8, f);
|
FASTSPI_WRITE_RAM_LE(tmp_addr, CC2420RAM_IEEEADDR, 8, f);
|
||||||
}
|
}
|
||||||
|
RELEASE_LOCK();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
|
@ -616,16 +631,16 @@ cc2420_read(void *buf, unsigned short bufsize)
|
||||||
#endif /* CC2420_CONF_CHECKSUM */
|
#endif /* CC2420_CONF_CHECKSUM */
|
||||||
|
|
||||||
pending = 0;
|
pending = 0;
|
||||||
|
|
||||||
if(!FIFOP_IS_1) {
|
if(!FIFOP_IS_1) {
|
||||||
/* If FIFOP is 0, there is no packet in the RXFIFO. */
|
/* If FIFOP is 0, there is no packet in the RXFIFO. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_LOCK();
|
GET_LOCK();
|
||||||
|
|
||||||
cc2420_packets_read++;
|
cc2420_packets_read++;
|
||||||
|
|
||||||
getrxbyte(&len);
|
getrxbyte(&len);
|
||||||
|
|
||||||
if(len > CC2420_MAX_PACKET_LEN) {
|
if(len > CC2420_MAX_PACKET_LEN) {
|
||||||
|
@ -713,7 +728,11 @@ cc2420_set_txpower(uint8_t power)
|
||||||
int
|
int
|
||||||
cc2420_get_txpower(void)
|
cc2420_get_txpower(void)
|
||||||
{
|
{
|
||||||
return (int)(getreg(CC2420_TXCTRL) & 0x001f);
|
int power;
|
||||||
|
GET_LOCK();
|
||||||
|
power = (int)(getreg(CC2420_TXCTRL) & 0x001f);
|
||||||
|
RELEASE_LOCK();
|
||||||
|
return power;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
|
@ -722,6 +741,8 @@ cc2420_rssi(void)
|
||||||
int rssi;
|
int rssi;
|
||||||
int radio_was_off = 0;
|
int radio_was_off = 0;
|
||||||
|
|
||||||
|
GET_LOCK();
|
||||||
|
|
||||||
if(!receive_on) {
|
if(!receive_on) {
|
||||||
radio_was_off = 1;
|
radio_was_off = 1;
|
||||||
cc2420_on();
|
cc2420_on();
|
||||||
|
@ -735,13 +756,21 @@ cc2420_rssi(void)
|
||||||
if(radio_was_off) {
|
if(radio_was_off) {
|
||||||
cc2420_off();
|
cc2420_off();
|
||||||
}
|
}
|
||||||
|
RELEASE_LOCK();
|
||||||
return rssi;
|
return rssi;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
cc2420_cca_valid(void)
|
cc2420_cca_valid(void)
|
||||||
{
|
{
|
||||||
return !!(status() & BV(CC2420_RSSI_VALID));
|
int valid;
|
||||||
|
if(locked) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
GET_LOCK();
|
||||||
|
valid = !!(status() & BV(CC2420_RSSI_VALID));
|
||||||
|
RELEASE_LOCK();
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
|
@ -757,7 +786,8 @@ cc2420_cca(void)
|
||||||
if(locked) {
|
if(locked) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GET_LOCK();
|
||||||
if(!receive_on) {
|
if(!receive_on) {
|
||||||
radio_was_off = 1;
|
radio_was_off = 1;
|
||||||
cc2420_on();
|
cc2420_on();
|
||||||
|
@ -765,6 +795,7 @@ cc2420_cca(void)
|
||||||
|
|
||||||
/* Make sure that the radio really got turned on. */
|
/* Make sure that the radio really got turned on. */
|
||||||
if(!receive_on) {
|
if(!receive_on) {
|
||||||
|
RELEASE_LOCK();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,6 +808,7 @@ cc2420_cca(void)
|
||||||
if(radio_was_off) {
|
if(radio_was_off) {
|
||||||
cc2420_off();
|
cc2420_off();
|
||||||
}
|
}
|
||||||
|
RELEASE_LOCK();
|
||||||
return cca;
|
return cca;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -793,31 +825,11 @@ pending_packet(void)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
cc2420_ugly_hack_send_only_one_symbol(void)
|
|
||||||
{
|
|
||||||
uint8_t len;
|
|
||||||
GET_LOCK();
|
|
||||||
|
|
||||||
/* Write packet to TX FIFO. */
|
|
||||||
strobe(CC2420_SFLUSHTX);
|
|
||||||
|
|
||||||
len = 1;
|
|
||||||
FASTSPI_WRITE_FIFO(&len, 1);
|
|
||||||
FASTSPI_WRITE_FIFO(&len, 1);
|
|
||||||
|
|
||||||
strobe(CC2420_STXON);
|
|
||||||
while(!SFD_IS_1);
|
|
||||||
|
|
||||||
/* Turn radio off immediately after sending the first symbol. */
|
|
||||||
strobe(CC2420_SRFOFF);
|
|
||||||
RELEASE_LOCK();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
cc2420_set_cca_threshold(int value)
|
cc2420_set_cca_threshold(int value)
|
||||||
{
|
{
|
||||||
uint16_t shifted = value << 8;
|
uint16_t shifted = value << 8;
|
||||||
|
GET_LOCK();
|
||||||
setreg(CC2420_RSSI, shifted);
|
setreg(CC2420_RSSI, shifted);
|
||||||
|
RELEASE_LOCK();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in a new issue