From cc1cfcf1663ce3ae5d35fe9f41b4d1fd4a68db56 Mon Sep 17 00:00:00 2001 From: Martin Lenders Date: Tue, 21 Jan 2014 14:39:13 +0100 Subject: [PATCH] Uncircumvent radio chip's status for IEEE 802.15.4 hardware Currently the cc2420 and at86rf231 hardware addresses (IEEE 802.15.4 short and long) and frequency channel are read only from a global variable in the driver. This global variable is only set when the user sets the address/channel though both parameters might be preset by the hardware. This change lets the driver read this parameters directly from the hardware. --- drivers/at86rf231/at86rf231.c | 18 +++++++++++ drivers/cc2420/cc2420.c | 61 ++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/drivers/at86rf231/at86rf231.c b/drivers/at86rf231/at86rf231.c index 8e73cef889..dfd3ede56a 100644 --- a/drivers/at86rf231/at86rf231.c +++ b/drivers/at86rf231/at86rf231.c @@ -29,6 +29,24 @@ void at86rf231_init(int tpid) // TODO : Enable addr decode, auto ack, auto crc // and configure security, power, channel, pan + radio_pan = 0; + radio_pan = 0x00FF & (uint16_t)at86rf231_reg_read(AT86RF231_REG__PAN_ID_0); + radio_pan |= (uint16_t)at86rf231_reg_read(AT86RF231_REG__PAN_ID_1) << 8; + + radio_channel = at86rf231_reg_read(AT86RF231_REG__PHY_CC_CCA) & AT86RF231_PHY_CC_CCA_MASK__CHANNEL; + + radio_address = 0x00FF & (uint16_t)at86rf231_reg_read(AT86RF231_REG__SHORT_ADDR_0); + radio_address |= at86rf231_reg_read(AT86RF231_REG__SHORT_ADDR_1) << 8; + + radio_address_long = 0x00000000000000FF & (uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_0); + radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 8; + radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 16; + radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 24; + radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 32; + radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 40; + radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 48; + radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 56; + at86rf231_switch_to_rx(); } diff --git a/drivers/cc2420/cc2420.c b/drivers/cc2420/cc2420.c index 9b0a67bbd7..d52db549d3 100644 --- a/drivers/cc2420/cc2420.c +++ b/drivers/cc2420/cc2420.c @@ -15,11 +15,6 @@ #define ENABLE_DEBUG (0) #include "debug.h" -static uint16_t radio_channel; -static uint16_t radio_address; -static uint64_t radio_address_long; -static uint16_t radio_pan; - /* Radio driver API */ int transceiver_pid; @@ -35,7 +30,8 @@ void cc2420_init(int tpid) cc2420_strobe(CC2420_STROBE_XOSCON); //enable crystal - while((cc2420_strobe(NOBYTE) & 0x40) == 0); //wait for crystal to be stable + while ((cc2420_strobe(NOBYTE) & 0x40) == 0); //wait for crystal to be stable + hwtimer_wait(CC2420_WAIT_TIME); reg = cc2420_read_reg(CC2420_REG_MDMCTRL0); @@ -64,13 +60,14 @@ void cc2420_init(int tpid) cc2420_set_channel(CC2420_DEFAULT_CHANNR); cc2420_set_pan(0x1111); - DEBUG("CC2420 initialized and set to channel %i and pan %i\n", radio_channel, radio_pan); + DEBUG("CC2420 initialized and set to channel %i and pan 0x1111\n", CC2420_DEFAULT_CHANNR); cc2420_init_interrupts(); cc2420_switch_to_rx(); } -void cc2420_switch_to_rx(void) { +void cc2420_switch_to_rx(void) +{ cc2420_strobe(CC2420_STROBE_RFOFF); cc2420_strobe(CC2420_STROBE_FLUSHRX); cc2420_strobe(CC2420_STROBE_FLUSHRX); @@ -93,46 +90,53 @@ void cc2420_set_monitor(uint8_t mode) { uint16_t reg; reg = cc2420_read_reg(CC2420_REG_MDMCTRL0); - if(mode) { + + if (mode) { reg &= ~CC2420_ADR_DECODE; - } else { + } + else { reg |= CC2420_ADR_DECODE; } + cc2420_write_reg(CC2420_REG_MDMCTRL0, reg); } int16_t cc2420_set_channel(uint16_t chan) { - if(chan < 11 || chan > 26) { - DEBUG("Invalid channel %i set. Valid channels are 11 through 26\n",chan); + uint16_t freq; + + if (chan < 11 || chan > 26) { + DEBUG("Invalid channel %i set. Valid channels are 11 through 26\n", chan); return -1; } - radio_channel = chan; - chan = 357 + (5 * (radio_channel-11)); //calculation from p.50 - cc2420_write_reg(CC2420_REG_FSCTRL, chan); - return radio_channel; + + /* + * calculation from http://www.ti.com/lit/ds/symlink/cc2420.pdf p.50 + */ + freq = 357 + (5 * (chan - 11)); + cc2420_write_reg(CC2420_REG_FSCTRL, freq); + return (int32_t)chan; } uint16_t cc2420_get_channel(void) { - return radio_channel; + /* undo calculation from cc2420_set_channel() */ + return ((cc2420_read_reg(CC2420_REG_FSCTRL) - 357) / 5) + 11; } uint16_t cc2420_set_address(uint16_t addr) { uint8_t buf[2]; - radio_address = addr; buf[0] = (uint8_t)(addr & 0xFF); buf[1] = (uint8_t)(addr >> 8); cc2420_write_ram(CC2420_RAM_SHORTADR, buf, 2); cc2420_set_address_long(0x00FF & addr); - return radio_address; + return addr; } uint64_t cc2420_set_address_long(uint64_t addr) { uint8_t buf[8]; - radio_address_long = addr; buf[0] = (uint8_t)(addr & 0xFF); buf[1] = (uint8_t)(addr >> 8); buf[2] = (uint8_t)(addr >> 16); @@ -142,32 +146,37 @@ uint64_t cc2420_set_address_long(uint64_t addr) buf[6] = (uint8_t)(addr >> 48); buf[7] = (uint8_t)(addr >> 56); cc2420_write_ram(CC2420_RAM_IEEEADR, buf, 8); - return radio_address_long; + return addr; } uint16_t cc2420_get_address(void) { - return radio_address; + uint16_t addr; + cc2420_read_ram(CC2420_RAM_SHORTADR, (uint8_t *)&addr, sizeof(addr)); + return addr; } uint64_t cc2420_get_address_long(void) { - return radio_address_long; + uint64_t addr; + cc2420_read_ram(CC2420_RAM_IEEEADR, (uint8_t *)&addr, sizeof(addr)); + return addr; } uint16_t cc2420_set_pan(uint16_t pan) { uint8_t buf[2]; - radio_pan = pan; buf[0] = (uint8_t)(pan & 0xFF); buf[1] = (uint8_t)(pan >> 8); cc2420_write_ram(CC2420_RAM_PANID, buf, 2); - return radio_pan; + return pan; } uint16_t cc2420_get_pan(void) { - return radio_pan; + uint16_t pan; + cc2420_read_ram(CC2420_RAM_SHORTADR, (uint8_t *)&pan, sizeof(pan)); + return pan; } void cc2420_swap_fcf_bytes(uint8_t *buf)