-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
Add initial LoRa support #18998
Add initial LoRa support #18998
Conversation
Tagging: @tbursztyka @alexanderwachter @jukkar @chris-makaio @KwonTae-young |
893ca68
to
abe9fca
Compare
I have a custom board using the
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few comments after first quick review.
Can you split the PR and put SPI/RTC support on L1 in dedicated PRs so we can merge these first?
samples/drivers/lora/send/src/main.c
Outdated
ret = lora_send(lora_dev, data, MAX_DATA_LEN); | ||
if (ret < 0) { | ||
LOG_ERR("LoRa send failed"); | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think send and recive should be repeated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. Will use continuous loop.
drivers/lora/sx1276.c
Outdated
static int sx1276_lora_recv(struct device *dev, u8_t *data) | ||
{ | ||
Radio.SetMaxPayloadLength(MODEM_LORA, 255); | ||
Radio.Rx(0); | ||
|
||
/* Wait until the data arrives */ | ||
k_sem_take(&dev_data.data_sem, K_FOREVER); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think sx1276_lora_recv()
needs timeout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KwonTae-young Makes sense! I think the API should allow this timeout value to be specified by the application. If timeout passed is 0
, then it should block until the data arrives. What do you think?
Like below,
static int sx1276_lora_recv(struct device *dev, u8_t *data, u32_t timeout)
{
int ret;
Radio.SetMaxPayloadLength(MODEM_LORA, 255);
Radio.Rx(0);
if (!timeout) {
/* Wait until the data arrives */
k_sem_take(&dev_data.data_sem, K_FOREVER);
} else {
ret = k_sem_take(&dev_data.data_sem, K_MSEC(timeout));
if (ret < 0) {
LOG_ERR("Receive timeout!");
return ret;
}
}
memcpy(data, dev_data.rx_buf, dev_data.rx_len);
return dev_data.rx_len;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the API should allow this timeout value to be specified by the application. If timeout passed is 0, then it should block until the data arrives. What do you think?
I would suggest using the already defined macros K_FOREVER and K_NO_WAIT for that purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest using the already defined macros K_FOREVER and K_NO_WAIT for that purpose.
@alexanderwachter Okay. I think you're talking about passing K_NO_WAIT
from the application instead of passing 0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
timeout works fine.
However, if the timeout occurs once in samples/drivers/lora/receive
, it is returned and the program terminates.
***** Booting Zephyr OS version 2.0.99 *****
[00:00:00.221,000] <inf> sx1276: SX1276 Version:12 found
[00:00:01.228,000] <err> sx1276: Receive timeout!
[00:00:01.228,000] <err> lora_receive: LoRa receive failed
I am testing with the following modifications. (timeout = 1000ms)
diff --git a/samples/drivers/lora/receive/src/main.c b/samples/drivers/lora/receive/src/main.c
index 46824dd69e..99b6985165 100644
--- a/samples/drivers/lora/receive/src/main.c
+++ b/samples/drivers/lora/receive/src/main.c
@@ -48,11 +48,10 @@ void main(void)
len = lora_recv(lora_dev, data, 0);
if (len < 0) {
LOG_ERR("LoRa receive failed");
- return;
+ } else {
+ LOG_INF("Received data: %s", log_strdup(data));
}
- LOG_INF("Received data: %s", log_strdup(data));
-
/* Receive data at 1s interval */
k_sleep(1000);
}
***** Booting Zephyr OS version 2.0.99 *****
[00:00:00.221,000] <inf> sx1276: SX1276 Version:12 found
[00:00:01.228,000] <err> sx1276: Receive timeout!
[00:00:01.228,000] <err> lora_receive: LoRa receive failed
[00:00:03.229,000] <err> sx1276: Receive timeout!
[00:00:03.229,000] <err> lora_receive: LoRa receive failed
[00:00:05.230,000] <err> sx1276: Receive timeout!
[00:00:05.230,000] <err> lora_receive: LoRa receive failed
...
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KwonTae-young This is the expected behavior. And the termination depends on the user application. The sample application I have provided just terminates once the timeout is received.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Mani-Sadhasivam Okay. timeout works fine.
BTW, did anyone had plans to add LoRa support to the BSD socket layer after this initial support is merged? |
@jukkar Of course! I will work on it. That would be the exact functionality required for FOTA. |
abe9fca
to
c500035
Compare
c017120
to
6ad47f5
Compare
@carlescufi Updated the PR! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@carlescufi Not exactly similar to OT, as we don't reuse the existing loramac-node module CMake build system, but I guess it was not as straightforward to integrate as OT was (at least it looks complex).
Left a few comments to consider, not necesirally CMake related.
include/drivers/lora.h
Outdated
data arrives. | ||
* @return Length of the data received on success, negative on error | ||
*/ | ||
static inline int lora_recv(struct device *dev, u8_t *data, s32_t timeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This API is missing a parameter that would indicate the size of the data
buffer. How would the implementation know how many bytes can it copy into the data
buffer? If we blindly copy data w/o taking buffer size into consideration we will sooner or later (but rather sooner) overwrite some other data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rlubos Okay, I got the reason now. The buffer copy happens with the size of the recevied length reported by the lora stack. So even if we pass the size parameter, we can't just copy those bytes since it may or may not be received. But there are couple of usecases with size parameter:
- We can check if the buffer size exceeded the max recv length i.e., 255
- Return error if we don't receive the
size
bytes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Mani-Sadhasivam The main reason for providing an extra size
parameter is to detect when we can't copy the data so that we don't exceed the buffer provided. I'm not a Lora expert, so I'm not sure what would be the best action to take in case this happens, but the solutions I see:
- Return an error and drop the packet (results in data loss),
- Copy only the bytes that fit, return a number of bytes copied and drop the rest (that's how DATAGRAM sockets work),
- Copy only the bytes that fit, return a number of bytes copied and keep the rest of the packet for further reads (that's how STREAM sockets work)
I understand though, that any of these will require some rework and would postpone this PR. Alternatively, we could specify in the API what's the size of the buffer that needs to be provided (as according to @alexanderwachter I understand that Lora packet has a maximum size, if it's 255 bytes used in the sample I guess it could also be a reasonable approach).
@Mani-Sadhasivam @alexanderwachter can we make 100% sure that the new LoRa sample is being built by CI before we merge this PR. |
@carlescufi Sure, we can wait. I waited for almost 4 months ;) Btw, there are few comments from @rlubos and @alexanderwachter, do you want me to incorporate them now or I can do it after merging this initial PR? |
Please incorporate them now before merging this PR. |
@Mani-Sadhasivam I think you should incorporate the comments from @rlubos. |
# Top-level configuration file for LORA drivers. | ||
|
||
menuconfig LORA | ||
bool "LoRa support" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be a good idea to mark the LoRa support as [EXPERIMENTAL]
here so that it is easier to tweak the API if needed.
I understand, but there's no information whatsoever what is the expected buffer size in the API header file. So at a minimum, we should provide this information. Still, I think that extra |
@rlubos i totally agree with the buffer size argument. |
Add initial LoRa API for P2P mode. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add basic driver support for LoRa. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add support for Semtech SX1276 LoRa Modem. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add support for Semtech SX1276 LoRa Modem found within the RAK811 module on the board. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add sample application for sending data packets over LoRa. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add sample application for receiving data packets over LoRa. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add CODEOWNERS entry for LoRa API, drivers and samples. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add LoRaMac module support for building the LoRaWAN stack and LoRa drivers provided by Semtech. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add LoRaMac-node module support to make use of Semtech LoRaWAN stack and LoRa drivers. Signed-off-by: Manivannan Sadhasivam <[email protected]>
Add Add STM32_OSPEEDR_VERY_HIGH_SPEED flag for SPI1_SCK to function properly. This is needed for the proper communication with the LoRa modem. Without this flag, the received data is mangled when burst read is performed. Signed-off-by: Manivannan Sadhasivam <[email protected]>
6ad47f5
to
3092d57
Compare
@rlubos @alexanderwachter @carlescufi Incorporated the review comments. Please take a look |
@Mani-Sadhasivam This looks great but could your SX1276 not cover the whole SX12xx range? Obviously there may be work to make work generic. The LoRaMac-Node project also provides support for SX1272/73, SX1276/77/78/79 and SX1261/2 radios. |
@WilliamGFish Of course! But I don't have any modules other than SX1276, so can't test. If others in the community has the modules and interest, it can always be extended. What I have provided is the base platform. |
Hello,
This is my second attempt on adding LoRa (Long Range low power) technology support to Zephyr. This initial PR includes only P2P (Peer to Peer) support without using the LoRaMac stack. As per the discussion on the previous PR #17685, I've made use of Semtech's LoRaMac-node repository for better code maintenance. I've imported both LoRaMac and LoRa drivers (SX1276) as a module here but only P2P related drivers are enabled for now.
Since this is an initial PR, I've left many TODO items in the Zephyr SX1276 Shim driver for tackling in future.
What is working?
Only P2P support using SX1276 LoRa Radio driver. This has been tested using 96Boards Wistrio board. There is no frequency limitation as of now but only below bandwidths are supported:
125KHz, 250KHz, 500KHz
...and this limitation comes from Semtech's LoRa drivers.
Future plans
LoRaWAN support
Discussions
#5436 #5764 #17685
Thanks,
Mani