drivers/sx1276: LoRa transceiver phy driver proposal#6002
drivers/sx1276: LoRa transceiver phy driver proposal#6002Cr0s wants to merge 19 commits intoRIOT-OS:masterfrom
Conversation
|
It's working for us. We were able to send and receive data. Cheers! |
drivers/include/sx1276.h
Outdated
| @@ -0,0 +1,450 @@ | |||
| /* | |||
| * Copyright (C) 2016 Cr0s | |||
There was a problem hiding this comment.
It's usually preferred to provide an e-mail address - either here or in the doxygen @author line.
|
also a real name. -----Original Message----- OlegHahm commented on this pull request.
It's usually preferred to provide an e-mail address - either here or in the doxygen You are receiving this because you are subscribed to this thread. |
drivers/sx1276/sx1276.c
Outdated
| sx1276_reg_write(dev, | ||
| SX1276_REG_DIOMAPPING1, | ||
| (sx1276_reg_read(dev, SX1276_REG_DIOMAPPING1) | ||
| & SX1276_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX1276_RF_LORA_DIOMAPPING1_DIO0_00); |
There was a problem hiding this comment.
Not sure why the SX1276_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX1276_RF_LORA_DIOMAPPING1_DIO0_00 are "DIO0", if you are in lora mode, shouldn't both the mask and the mode be for "DIO3"? so to make sure "DIO3" generates de CADDONE ISR. Cheers.
There was a problem hiding this comment.
Well spotted. Since CAD mode didn't tested, this obvious copy-paste mistake was not seen before.
Gonna fix it asap.
P.S.: the actual error present in the original Semtech's code:
https://github.com/Lora-net/LoRaMac-node/blob/master/src/radio/sx1276/sx1276.c#L1164
so it was inherited as it is.
drivers/include/sx1276.h
Outdated
| * Radio driver supported modems. | ||
| */ | ||
| typedef enum { | ||
| SX1276_MODEM_FSK = 0, SX1276_MODEM_LORA, |
There was a problem hiding this comment.
Please spit into multiple lines.
drivers/include/sx1276.h
Outdated
| * Radio driver internal state machine states definition. | ||
| */ | ||
| typedef enum { | ||
| SX1276_RF_IDLE = 0, SX1276_RF_RX_RUNNING, SX1276_RF_TX_RUNNING, SX1276_RF_CAD, |
Huh? |
| (void) arg; | ||
| } | ||
|
|
||
| void *dio_polling_thread(void *arg) |
There was a problem hiding this comment.
Hi!, I'm not sure why would you choose to use threads over pin interrupts? Doesn't this make packet loss more likely? Plus doesn't this implement a pooling system witch is cpu and energy intensive? Also, is it really needed since you are using stack memory and other resources. Cheers
There was a problem hiding this comment.
Hi! I'll try to clarify reasons why I did that.
The main point is to not doing complex stuff inside DIO's ISRs and do it in separate thread instead.
Doesn't this make packet loss more likely?
I think no, the RX handling is pretty straightforward and doesn't involve complex mechanisms such as packet queues which may overflow or something like that.
Plus doesn't this implement a pooling system witch is cpu and energy intensive?
The dio_polling_thread doesn't poll a DIO pins as busy-waiting one. The major part of a time this thread is blocked on awaiting messages that comes from DIO interrupt handlers.
As this thread is awaiting for messages in blocked state, it's not CPU-intensive at all.
Also, is it really needed since you are using stack memory and other resources
This thread is needed since the handler of DIO interrupt might be pretty heavy in matter of stack usage. For example, consider the DIO0 interrupt on RX. After the RX event occurs, if we just call the event handler's callback and If we put some stack-heavy MAC logic into that callback, the ISR stack will definitely be overflowed than if we will do event callback from the separate thread.
The stack space is allocated for this thread only.
Another solution I came up with is to force user to create a thread to handle messages from the driver, but it's seems to me a clear violation of implementation hiding principle and that will lead to more ways to do something wrong.
I hope I made the rationale clear for you.
Cheers.
There was a problem hiding this comment.
Hi @Cr0s!
Just read this discussion.
Netdev2 allows a similar flow without the need of another thread on the driver side. For instance, the enc28j60 driver calls netdev->event_callback with NETDEV2_ISR_EVENT and this is translated to a message to the gnrc_netdev2 thread. In the end, the isr function of the driver is called (as shown here).
In this case the dio_polling_thread could be the isr function of the driver (note the isr function is not in ISR context, the name is a bit tricky :P). Probably it would need some flags to identify which interrupt occured.
There was a problem hiding this comment.
Hello, @jia200x.
Getting rid of a separate thread could be made as a part of the netdev2 interface adaption.
drivers/sx1276/sx1276.c
Outdated
|
|
||
| static inline void send_event(sx1276_t *dev, sx1276_event_type_t event_type) | ||
| { | ||
| if (dev->sx1276_event_cb != NULL) { |
There was a problem hiding this comment.
Couldn't we use an assert here instead?
drivers/sx1276/sx1276.c
Outdated
| spi_release(dev->spi); | ||
|
|
||
| if (res < 0) { | ||
| printf("sx1276: error initializing SPI_%i device (code %i)\n", |
There was a problem hiding this comment.
Please change all printfs to DEBUG.
drivers/sx1276/sx1276.c
Outdated
|
|
||
| /* Check presence of SX1276 */ | ||
| if (!sx1276_test(dev)) { | ||
| DEBUG("init_radio: test failed"); |
drivers/sx1276/sx1276.c
Outdated
| sx1276_set_channel(dev, dev->settings.channel); | ||
|
|
||
| /* Create DIO event lines handler */ | ||
| kernel_pid_t pid = thread_create((char *) dev->_internal.dio_polling_thread_stack, sizeof(dev->_internal.dio_polling_thread_stack), THREAD_PRIORITY_MAIN, |
drivers/sx1276/sx1276.c
Outdated
| /* Set radio in continuous reception */ | ||
| sx1276_set_op_mode(dev, SX1276_RF_OPMODE_RECEIVER); | ||
|
|
||
| for (i = 0; i < 32; i++) { |
There was a problem hiding this comment.
Why 32? Please use a macro/constant here.
There was a problem hiding this comment.
32 is the number of random bits that we will get from the transceiver and then we will put them into 32 bit integer.
There was a problem hiding this comment.
@OlegHahm Any update on this? Should I add macro or leave it as is?
| | SX1276_RF_IMAGECAL_IMAGECAL_START); | ||
|
|
||
| while ((sx1276_reg_read(dev, SX1276_REG_IMAGECAL) & SX1276_RF_IMAGECAL_IMAGECAL_RUNNING) | ||
| == SX1276_RF_IMAGECAL_IMAGECAL_RUNNING) { |
There was a problem hiding this comment.
@PeterKietzmann, @haukepetersen, how do we handle this in general? Didn't we agree on a failsafe counter for these kind of loops to avoid infinitely trying?
There was a problem hiding this comment.
Yes, it's better to replace that with some timeout-based polling to avoid infinite loops in bad cases. I've seen lot of similar loops in RIOT's peripheral drivers. Example.
There was a problem hiding this comment.
@OlegHahm Any update on this? Should I leave it as is or add timeout counters?
…to sx1276-radio-driver Forget to pull as always
|
Hi you all. |
|
@emmanuelsearch anything stated as "working" in description is actually working fine, it can be merged at the moment. |
|
I have a couple of Semtech SX1272 devices that should be compatible with SX1276 : they only covers bands from 850MHz to 1GHz and can be configured with 3 bandwidths (500KHz, 250KHz and 125KHz). |
|
@Cr0s any update on your side with this one ? |
|
ping @Cr0s, are planning to continue your work on this PR ? |
|
@Cr0s which board and which radio device did you use for testing? |
|
Do you know if the sx1272 radio is with your sx1276 driver? |
|
@PeterKietzmann, I started to work on adapting this work (mainly #6645) to SX1272 and SX1276. Still work in progress but in a better shape that those ones. |
|
@PeterKietzmann I don't think this driver can be used for sx1272 without some work. |
|
Thanks for both your quick responses! @aabadie where can I find your work, is it already visible for the public? |
|
@PeterKietzmann, yes. here : https://github.com/aabadie/RIOT/tree/driver_sx127x (Something I did without hardware yesterday) I quickly tested it this morning on sx1272 but it didn't work. I'm wondering if SPI works on Nucleo boards. |
|
@aabadie |
is it mandatory ? |
|
Yes, the GPIO definition seems to prevail on the SPI definition. |
|
@dylad, @PeterKietzmann, I opened a PR with my rework : #6797 |
|
Closing since #6797 is merged. |
Hello to RIOT folks!
I'd like to propose this initial implementation of LoRa physical layer driver.
Features that are considered as "done":
What will be done to make this driver complete (by me or someone else who wish and could):
I appreciate any feedback, fix proposals and related points!
Best regards,
Cr0s