Address filtering in AT86RF231 does not work - Page 1
Forum section: electronics / general

author: ananth_murali
author_rank: Newbie
timestamp: February 16, 2016, 04:39:09 pm
content: Hi,I am using the AT86RF231 radio in extended mode to get the hardware ACKs working. When a receiver receives a message, the following interrupts are raised: RX_START, AMI (Address Match Interrupt) followed by end of reception (TRX_END interrupt). The transmitter gets back the ACK successfully as well. However, when there are 2 receivers and a msg is meant only to one of them, both of them receive the msg and send back an ACK. This means that somehow the address filtering logic is not working. I need help figuring this out please. Here are my configuration details:1. The transmission msg header is as follows:a. FCF (2 bytes) - bit 0 to 15 - 34851Bit 0,1,2 - Frame type is MAC - 011Bit 3 (security enabled) - 0Bit 4 (frame pending) - 0Bit 5 (Ack request) - 1Bit 6 (Intra pan) - 0 (src PAN is not omitted)Bit 7,8,9 (Reserved) - 000Bit 10, 11 (16-bit short src address) - 10Bit 12, 13 (Frame version) - 00Bit 14,15 (dest address) - 10b. Sequence number - 1 bytec. Dest pan - 2 bytesd. Dest address - 2 bytese. Src pan - 2 bytesf. Src address - 2 bytesg. Some extra information needed by my MAC protocol such as length, type of the msg - 4 bytes. Not sure if including this in the header causes any problems.2. AACK_UPLD_RES_FT and AACK_FLTR_RES_FT - set to 03. AACK_FVN_MODE - set to 00 so that only frame version 0 is acknowledged.In the initialization routine of the radio, the address and PAN_IDs are set as follows:UINT16 addressHigh = GetAddress() >> 8;UINT16 addressLow = GetAddress() & 0xFF;WriteRegister(RF230_SHORT_ADDR_0, addressLow);WriteRegister(RF230_SHORT_ADDR_1, addressHigh);However, only when AACK_UPLD_RES_FT and AACK_FLTR_RES_FT are set to 1 and AACK_FVN_MODE is set to 11, are ACKs generated. This indicates that my msg header has some reserved fields. I am not sure what I am doing wrong. Any help in this regard would be great.UPDATE 1:1. AACK_FVN_MODE is set to 01 (Acknowledge frames with version number 0 or 1) and AACK_UPLD_RES_FT and AACK_FLTR_RES_FT are set to 0 (not process reserved frame types).2. FCF is set to 33809 (No reserved frame types).Bit 0,1,2 - Frame type is DATA - 100Bit 3 (security enabled) - 0Bit 4 (frame pending) - 0Bit 5 (Ack request) - 1Bit 6 (Intra pan) - 0 (srcpan is ignored)Bit 7,8,9 (Reserved) - 000Bit 10, 11 (16-bit short src address) - 01Bit 12, 13 (Frame version) - 00Bit 14,15 (dest address) - 013. Radio's address is set to 0x0.WriteRegister(RF230_SHORT_ADDR_0, 0x00);WriteRegister(RF230_SHORT_ADDR_1, 0x00);4. Transmitter sends msg to 0x00 (dest address is 0x00), then an AMI and TRX_END interrupts are generated and an ACK is generated as well.5. However, if transmitter sends msg to 0x1111 for instance (dest address is still 0x00), then an AMI and TRX_END interrupts along with an ACK are generated. This should not happen if address filtering works correctly.b. This indicates that there is something wrong with the address field configuration. I am not sure what the problem is though.Thanks,Ananth.

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2016, 07:11:26 pm
content: Have you tried just a basic configuration without changing XAH_CTRL_1 register?The simplest code that actually works can be found in the PHY driver of the Lightweight Mesh -http://www.atmel.com/tools/lightweight_mesh.aspx

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2016, 07:27:11 pm
content: And also don't change AACK_FVN_MODE for a test. And in the UPDATE 1, do you have both radios with address 0?I'm kind of lost in all the changes between the tests.

author: ananth_murali
author_rank: Newbie
timestamp: February 16, 2016, 08:05:24 pm
content: Thanks for your response Alex. I will remove update 2 so that it is less confusing.Quote from: ataradov on February 16, 2016, 07:11:26 pmYes, I did try a basic configurationand tx always gets an ACK irrespective of what address the src is set to or the address to which the tx transmits.. There is no AMI generated (if the radios are set to their respective addresses or 0x0)Quote from: ataradov on February 16, 2016, 07:27:11 pmYes, both radios are set to address 0.

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2016, 08:18:59 pm
content: If both of them have address 0, how they should react? They both will ACK the frame, of course.

author: ananth_murali
author_rank: Newbie
timestamp: February 16, 2016, 08:38:18 pm
content: Quote from: ataradov on February 16, 2016, 08:18:59 pmIf receiver's address is something like 0x1ABE and transmitter sends to address 0x1000, then also frame is ACKd.Btw, I modified my previous response after updating my test.

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2016, 08:53:52 pm
content: There must be something else configured. The radio should not (and it does not) behave this way.Do you have a sniffer to confirm this? Can you attach some sniffer logs and complete radio registers initialization code?

author: ananth_murali
author_rank: Newbie
timestamp: February 16, 2016, 09:04:27 pm
content: I don't have access to a sniffer at the moment, but I am trying to get one.Here is the radio register initialization code. These are done after setting the channel, CCA, transmit power and interrupts (at the very end of initialization).UINT16 addressHigh = GetAddress() >> 8;UINT16 addressLow = GetAddress() & 0xFF;WriteRegister(RF230_SHORT_ADDR_0, addressLow);WriteRegister(RF230_SHORT_ADDR_1, addressHigh);WriteRegister(RF230_PAN_ID_0, 0x0);WriteRegister(RF230_PAN_ID_1, 0x0);WriteRegister(RF230_IEEE_ADDR_0, 0x00);WriteRegister(RF230_IEEE_ADDR_1, 0x00);WriteRegister(RF230_IEEE_ADDR_2, 0x00);WriteRegister(RF230_IEEE_ADDR_3, 0x00);WriteRegister(RF230_IEEE_ADDR_4, 0x00);WriteRegister(RF230_IEEE_ADDR_5, 0x00);WriteRegister(RF230_IEEE_ADDR_6, 0x00);WriteRegister(RF230_IEEE_ADDR_7, 0x00);//RX_AACK configurationWriteRegister(RF230_TRX_CTRL_2, 0x00);WriteRegister(RF230_XAH_CTRL_1, 0x04);WriteRegister(RF230_XAH_CTRL_0, 0x0E);WriteRegister(RF230_CSMA_SEED_1, 0x42);WriteRegister(RF230_CSMA_SEED_0, 0xAA);//TX_ARET configurationWriteRegister(RF230_TRX_CTRL_1, 0x20);WriteRegister(RF230_CSMA_BE, 0x53);

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2016, 09:11:59 pm
content: Quote from: ananth_murali on February 16, 2016, 09:04:27 pmHow do you know that frame gets ACKed then?I don't see anything specifically wrong with your settings.

author: ananth_murali
author_rank: Newbie
timestamp: February 16, 2016, 09:26:42 pm
content: Quote from: ataradov on February 16, 2016, 09:11:59 pmOn the transmitter side, as soon as the transmission is done (TRX_END interrupt), the transmitter reads the TRX_STATE register and gets the value of last 3 bits (TRAC_STATUS). If the value is 0, then the frame was ACKed.The transmitter defines the header as follows:typedef struct IEEE802_15_4_Header {UINT16 fcf;UINT8 dsn; //Sequence numberUINT16 destpan;UINT16 dest;//UINT16 srcpan;UINT16 src;}IEEE802_15_4_Header_t;Before transmission, the length of the payload (MPDU) along with CRC length (2 bytes) and timestamp length (4 bytes) are written to the frame buffer. This is followed by writing the MPDU to the buffer.Do you see anything wrong in this?

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2016, 09:32:48 pm
content: Quote from: ananth_murali on February 16, 2016, 09:26:42 pmIs it still 0, when receiving device is physically off?Quote from: ananth_murali on February 16, 2016, 09:26:42 pmI suspect that there is something wrong with frame buffer access or the way you send the frame.1. Show how do you write data into the buffer. Better yet, make a byte-by-byte dump of all the bytes you write there.2. Make sure you are using advanced mode for transmitting. No ACK is expected in the basic mode.

author: ananth_murali
author_rank: Newbie
timestamp: February 16, 2016, 10:40:03 pm
content: Quote from: ataradov on February 16, 2016, 09:32:48 pmYes, it is 0 when receiver is off (FCF is 50705). If FCF is say 33826 (src and dest address fields are reserved), the value is 5 (NO_ACK).Quote from: ataradov on February 16, 2016, 09:32:48 pmHere is a byte-by-byte dump of the bytes written to the buffer. Please let me know if this is not clear enough. I have added comments to make it clear.Length (sum of payload (18 bytes), CRC (2 bytes), timestamp (4 bytes) for a total of 24 bytes - 0x18):18FCF:11c6Seq number:7300Destpan:0000Dest:0010Src:ba7bPayload (I send an increasing sequence number at the beginning 2 bytes followed by constant values of 1,2,3,4,5):0100010203040500Timestamp:eb1e0000Quote from: ataradov on February 16, 2016, 09:32:48 pmYes, I am using advanced mode for transmitting.

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2016, 10:54:53 pm
content: I think your FCF is incorrect. Try 0x8861. This is a standard FCF for ACK REQ + PAN ID Comp. Yours does not request an ACK.Also, sequence number is one byte. And there is no timestamp, but that specifically is not important right now.

author: ananth_murali
author_rank: Newbie
timestamp: February 16, 2016, 11:27:52 pm
content: If I understand FCF correctly, 0x8861 translates to below (table 1). If so, bit 5 is set to 0. How does this configuration request an ACK? I believe the bits should be reversed (table 2). Then it makes sense and I have used this configuration, but I interpreted it incorrectly.Table 1:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 151 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1Table 2:15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 01 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1I will change the sequence number to one byte and let you know what happens.

author: ataradov
author_rank: Super Contributor
timestamp: February 16, 2016, 11:29:13 pm
content: Bit 0 is an LSB. Your table 2 is correrct.

author: ananth_murali
author_rank: Newbie
timestamp: February 16, 2016, 11:58:34 pm
content: Changing that 2 byte seq number to 1 byte, along with 0x8861 did the trick I believe. Address filtering is working (if sender sends to correct receiver, sender gets an ACK. If sender sends to an incorrect address, no ACK is received). In the struct for the 802.15.4 header, seq number is defined as 1 byte. However, GCC is packing the 1 byte into 2 bytes (because the size of the header should be 9, but I get 10). This causes the subsequent bytes to be shifted and thus causing the address filter to not work.I believe everything should work from here onwards. If there is anything else that comes up, I will either continue this thread or start a new post.Alex, thank you very much. You have helped me fix a bug that we have been trying to fix for about a week.

author: ataradov
author_rank: Super Contributor
timestamp: February 17, 2016, 12:02:40 am
content: You can actually pack your structures that are used in protocols.#define PACK __attribute__ ((packed))typedef struct PACK NwkFrameHeader_t{uint16_t macFcf;uint8_t macSeq;uint16_t macDstPanId;uint16_t macDstAddr;uint16_t macSrcAddr;// ........} NwkFrameHeader_t;This will force GCC to put all members in the packed way. This will generate less efficient code, but in my experience it is way more efficient than hand assembled structures using >>'s and &'s.