Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: new driver for at86rf2xx radios #2825

Merged
merged 3 commits into from
Apr 28, 2015

Conversation

haukepetersen
Copy link
Contributor

this PR is the continuation of @thomaseichinger's work started in #2650.

Tested (and working) with the iot-lab_M3 (at86rf321). With the iot-lab_M3 it should be possible with this PR at the current state to run the new network stack -> happy testing :-)

Update: driver should be stable with iot-lab_M3 and samr21-xpro - also tested successfully against the Xbee S1 and validated packets against Wireshark.

Receiving also works with the samr32-xpro (at86rf233), here the sending still has problems -> will fix this next week.

I heavily restructured the code again -> the goal was to separate the drivers internals from the 'netdev' adaption to a large extend. This is not completely clean -> especially when receiving data there are still some fixed references into netdev...

Some more known issues:

  • the RSSI seems to be faulty
  • enabling/disabling of AUTOACK, CSMA, PROMISCUOUS-Mode is missing
  • a lot of doxygen documentation is missing
  • some doxygen is still wrong (copy/paste)
  • the IEEE802.15.4 frame header creation/parsing is not cleanly separated from the driver, yet
  • probably more...

@haukepetersen haukepetersen added State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet Area: drivers Area: Device drivers NSTF labels Apr 16, 2015
endif
ifneq (,$(filter ng_at86rf212b,$(USEMODULE)))
USEMODULE += ng_at86rf2xx
endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pattern matching: ifneq (,$(filter ng_at86rf2%,$(USEMODULE)))

@biboc
Copy link
Member

biboc commented Apr 17, 2015

@haukepetersen, Great job!
I will try it soon.

How do you add each driver "specialities"? By some #ifdef inside the code?

EDIT: I see you added some MODULE_NG_AT86RF233

@haukepetersen
Copy link
Contributor Author

@Kijewski good point, will fix, thx

@bapclenet Actually I am not sure, yet. @thomaseichinger and my initial idea was actually to find a way, so you could run say an at86rf231 and an at86rf212b simultaneously. But when working on it yesterday I found the ifdef solution to be far easier... So any ideas are welcome - until then I would say we go with the iedef variant

@biboc
Copy link
Member

biboc commented Apr 17, 2015

I see. If we use both transceiver at the same time, we will have two net interfaces,won't we? And then send a message will require to select the interface.
I don't know much about the new network stack, do you have a diagram somewhere to get an overview?

Why do we need PSEUDOMODULES if each driver is considered as a MODULE?

@kaspar030
Copy link
Contributor

For my network driver interface, I usually have a *_setup and a *_init function. *_setup can hav any signature and is totally driver/system dependand. I use it to e.g., setup the SPI pins. It could be used to switch the driver into the right device mode for the corresponding instance.

But for initial merge, I'd say compile-time device selection is fine.

@haukepetersen
Copy link
Contributor Author

minor update, now communication between the iot-lab_M3 and the samr21-xpro using short addresses works.

@biboc
Copy link
Member

biboc commented Apr 17, 2015

Between two samr21 (AT86RF233), I can transmit packets by short addresses but not with long ones.

@haukepetersen
Copy link
Contributor Author

yapp, I have the same behavior here, will look into it today.

@OlegHahm OlegHahm added the CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable label Apr 20, 2015
buf[pos++] = (uint8_t)((dev->addr_long) >> 8);
buf[pos++] = (uint8_t)((dev->addr_long) & 0xff);
}
/* unsupported address length */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

function doesn't handle broadcast case (hdr->dst_l2addr_len==0 && (hdr->flags & NG_NETIF_HDR_FLAGS_BROADCAST)).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(should also (hdr->flags & NG_NETIF_HDR_FLAGS_MULTICAST) in the same manner)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is on the TODO list :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a

if (hdr->flags == (NG_NETIF_HDR_FLAGS_BROADCAST | NG_NETIF_HDR_FLAGS_MULTICAST))) {
    /* set FCF */
    buf[pos++] = 0xff;
    buf[pos++] = 0xff;
}

;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one question: is the broadcast address always the short address?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 802.15.4 standard only defines the short address (0xffff) as broadcast address, so yes.

The Destination Address field, when present, specifies the address of the intended recipient of the frame. A
value of 0xffff in this field shall represent the broadcast short address, which shall be accepted as a valid
address by all devices currently listening to the channel.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IETF documents also only speak about 0xffff as broadcast address for IEEE 802.15.4.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure there is any EUI-64 defined for broadcast. Only thing in that direction I know of is, that the least significant bit of the first byte (0x01) signifies unicast/multicast.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(but since IEEE 802.15.4 does not support multicast, this is out of scope ;-))

@kaspar030
Copy link
Contributor

Is this driver supposed to work with the 212b?

@haukepetersen
Copy link
Contributor Author

updated driver, handling of long addresses should work now (tested with 231, 233 and against xbee device).

@biboc
Copy link
Member

biboc commented Apr 20, 2015

The old driver worked with 212b, so this one should work (this is the aim of the driver).
BUT, you won't be able to set the right emission frequency yet because this is a specificity of the 212b.
Later this driver will work with the 230, 231, 233 and 212b as Hauke mentioned.

@haukepetersen
Copy link
Contributor Author

@kaspar030: handling of broadcast addresses is not implemented, yet. In general the driver is also supposed to work with the at86rf212b, but I have not tested this (as I have no device available). But I think there might be some slight alterations needed for getting it to work

/* default to compress pan TODO: provide means to specify src PAN*/
buf[0] |= NG_IEEE802154_FCF_PAN_COMP;
if (hdr->dst_l2addr_len == 2) {
/* default to 2 byte addresses for src and dst */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to take NETCONF_OPT_SRC_LEN for the length of the source address.

@jonas-rem
Copy link
Contributor

When executing ifconfig on the samr21-xpro board the program crashed (isr_hard_fault).

The reason was the uninitialized netif. From where should ng_netif_init() be called? Would this be /tests/driver_at86rf2xx/main.c in this case?

When calling ng_netif_init() before ng_netif_add(dev->mac_pid), ifconfig returnes valid prints, otherwise isr_hard_fault.

Will test against linux tomorrow.

@biboc
Copy link
Member

biboc commented Apr 20, 2015

@Jremmert-phytec-iot, which example did youuse to make the ´samr21-xpro´ go to ´isr_hard_fault()´ ?
The example provided by Hauke in tests/driver_at86rf2xx should work

@jonas-rem
Copy link
Contributor

@bapclenet, I used the one hauke provided (tests/driver_at86rf2xx) goes to isr_hard_fault. If the mac layer wants to register its kernel_pid ng_netif_add(dev->mac_pid) (ng_netif.c), the function is executed but nothing will be registered.

int ng_netif_add(kernel_pid_t pid)
{
    for (int i = 0; i < NG_NETIF_NUMOF; i++) {
        if (ifs[i] == pid) {    /* avoid duplicates */
            return 0;
        }   

/* registering fails here because ifs[i] !== KERNEL_PID_UNDEF, although it should be.
 * So nothing will be assigned to ifs[i]. In my case it remains at 14578 or so ;). 
 * When I add a call to the initialization function, the correct MAC kernel_pid (5) 
 * gets assigned. */
        else if (ifs[i] == KERNEL_PID_UNDEF) { 
            ifs[i] = pid;

            for (int j = 0; if_handler[j].add != NULL; j++) {
                if_handler[j].add(pid);
            }

            return 0;
        }
    }

    return -ENOMEM;
}

I have no idea why it worked for you without the initialization. Maybe the uninitialized value of ifs[i] was 0 ( KERNEL_PID_UNDEF)? Maybe I have missed something fundamental?

@biboc
Copy link
Member

biboc commented Apr 21, 2015

@jremmert-phytec-iot, I've got the same configuration, and pid is 5 for me.
I think you're right, ng_netif_init() should be called. @haukepetersen ?
Btw, why ng_netreg_init is not called as well?

@miri64
Copy link
Member

miri64 commented Apr 21, 2015

@jremmert-phytec-iot it seems that you have another interface registered. Does it work if you set a higher NG_NETIF_NUMOF?

@bapclenet It should work without ng_netif_init(). The C standard states that all static memory should be set to 0, if no other value is provided. ng_netif_init() was added for testing purposes only (it might even be set into TEST_SUITES #ifdefs)

@miri64
Copy link
Member

miri64 commented Apr 21, 2015

At the very least: ng_netreg_init() should not be called in this driver, but by auto_init.

@jonas-rem
Copy link
Contributor

Ok, it is clear that ng_netref_init() should not be called in the driver since it would delete all other registered interfaces.

As test setup I just checked out the latest master, applied this PR and flashed this test application. So, there should not be any other interfaces. Also ng_netif_add() is called the first time from ng_nomac.

When setting a breakpoint to ng_netif_add and printing the variables on the first (and only) call:

(gdb) print ifs[0]
$3 = 14976
(gdb) print pid
$4 = 5

I investigated a bit more. The memory address of ifs[0] is written to 0 in reset_handler(). Later, kernel_init() prints some stuff on the shell before it starts the idle and main thread. This print changes the content of the memory address of ifs[0]. If I uncomment these printf calls, everything works, without ng_netif_init.

I assume that ifs[0] is initialized after all this, in main thread-context, but is it initialized with 0 then? So, initialize netif once after the startup procedure would solve this problem.

@OlegHahm
Copy link
Member

Check for make doc 2>&1 | grep '.*warning' | grep ng_at86rf2xx and similar for ng_ieee802154.h.

#ifdef __cplusplus
}
#endif

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Travis complains here
Missed something like
/**
* @brief IEEE 802.14.4 header definitions
* @{
*/
/ * * @} */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ups, must have overlooked that one... fixed.

@haukepetersen
Copy link
Contributor Author

fixed named issues and rebased and squashed. Travis should now be happy.

@biboc
Copy link
Member

biboc commented Apr 27, 2015

Great!
Here is Travis fail:
The command "sudo apt-get update" failed and exited with 100 during .
@authmillenon

@haukepetersen
Copy link
Contributor Author

Seems Travis is broken once more...

@miri64
Copy link
Member

miri64 commented Apr 27, 2015

@haukepetersen please rebase. #2873 fixed the issue.

@haukepetersen
Copy link
Contributor Author

rebased.

}
}

size_t ng_at86rf2xx_rx_len(ng_at86rf2xx_t *dev)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Page 946 of the datasheet (SAM R21) states, that the MSB should be masked for 802.15.4 compliance. Shouldn't this be done here?

On reception, the PHR is returned as the first octet during Frame Buffer read access. While the IEEE 802.15.4-2006 standard declares bit seven of the PHR octet as being reserved, the AT86RF233 preserves this bit upon transmission and reception so it can be used to carry additional information within proprietary networks. Nevertheless, this bit is not considered to be a part of the frame length, so only frames between one and 127 octets are possible. For IEEE 802.15.4 compliant operation bit [7] has to be masked by software.

EDIT: My comment refers to size_t ng_at86rf2xx_rx_len(ng_at86rf2xx_t *dev) of course. I wasn't aware of how GitHub is displaying line comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That paragraph I have not read before, so you are right that masking the bit is a good idea. As long as we have RIOT devices only (with the same driver), it should not be an issue for now, though. So again: Lets fix this after this PR is merged.

@biboc biboc removed the CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable label Apr 28, 2015
@biboc
Copy link
Member

biboc commented Apr 28, 2015

Travis complained about the label need squashing. Let Travis work and this PR should be fine for merging.

@miri64
Copy link
Member

miri64 commented Apr 28, 2015

Can't restart. Let's wait until the H&A if something happens, otherwise let's merge it than

@haukepetersen
Copy link
Contributor Author

Ok, if the label was the only thing Travis complained about, I say: Let's merge this now!

@miri64
Copy link
Member

miri64 commented Apr 28, 2015

Yeah, let's merge it.

miri64 added a commit that referenced this pull request Apr 28, 2015
drivers: new driver for at86rf2xx radios
@miri64 miri64 merged commit b829dfa into RIOT-OS:master Apr 28, 2015
@biboc
Copy link
Member

biboc commented Apr 28, 2015

Great! :-)
Good job @haukepetersen

if (max_len < sizeof(int16_t)) {
return -EOVERFLOW;
}
*((uint16_t *)val) = NG_AT86RF2XX_MAX_PKT_LENGTH;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are returning the full 802.15.4 packet length here without taking care of the 802.15.4 header that also has to be appended.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bapclenet I opened issue #3086 for that discussion

@miri64 miri64 added the Area: network Area: Networking label Sep 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers Area: network Area: Networking
Projects
None yet
Development

Successfully merging this pull request may close these issues.