drivers/rn2xx3: basic initial implementation (without netdev)#7505
drivers/rn2xx3: basic initial implementation (without netdev)#7505kaspar030 merged 2 commits intoRIOT-OS:masterfrom
Conversation
|
Why didn't you use #7084 for this? |
because the module is not controlled by AT commands... |
|
Ah okay, I just saw device controlled via UART and thought they were AT commands, so nvm. But looking at the code again in more detail: why are you controlling the device purely via the shell? Wouldn't something similar to the xbee driver be better suited? |
|
(don't get me wrong: as a proof-of-concept this is awesome, but for long-term integration I prefer you to go direct to netdev and not just in future PRs). |
It was faster to implement and smaller changes. I wanted to have other people opinion on it before going further.
The module behaves differently. I guess I can take inspiration on the state machine, provide an API similar to schedule sx127x for radio level and an API for Mac layer. |
Well ideally it should implement netdev ;-) |
drivers/include/lorabee.h
Outdated
| * @param[in] cmd Command to send as string | ||
| * | ||
| * @return LORABEE_OK on success | ||
| * @return -LORABEE_ERR_INVALID_PARAM if command is invalid |
There was a problem hiding this comment.
Why not avoid the minus here (and in _parse_response) and make the enum values explicit negative?
There was a problem hiding this comment.
because I don' t have to explicitly set a value to all enum values. I don't know what's best I admit.
There was a problem hiding this comment.
But then I have to ask, why do you need negative numbers at all? Why not just compare for != OK when you want to know if there is an error (instead of looking for negative numbers)?
drivers/lorabee/lorabee.c
Outdated
| return 0; | ||
| } | ||
|
|
||
| int lorabee_write_cmd(lorabee_t *dev, uint8_t *cmd) |
There was a problem hiding this comment.
I'd prefer that cmd is a const char*. Every command you send to the RN device is ASCII. No need to pretend it can be binary too. Only where uart_write is being called you need a type cast.
drivers/include/lorabee.h
Outdated
| /* buffer and synchronization for command responses */ | ||
| mutex_t resp_lock; /**< mutex for waiting for command | ||
| * response */ | ||
| uint8_t resp_buf[LORABEE_MAX_MSG_LENGTH]; /**< command response data buffer */ |
There was a problem hiding this comment.
Why not make this a char[] array. We're only expecting ASCII, don't we?
drivers/lorabee/lorabee.c
Outdated
| return; | ||
| } | ||
| else { | ||
| dev->resp_buf[dev->resp_size++] = c; |
There was a problem hiding this comment.
Buffer overflow protection ??
drivers/lorabee/lorabee.c
Outdated
| } | ||
|
|
||
| if (lorabee_write_cmd(dev, (uint8_t*)"") < 0) { | ||
| return -1; |
There was a problem hiding this comment.
Why not pass back the error cause?
b403b15 to
c833ce4
Compare
|
@keestux, thanks for having a look. I think I addressed most of your comment. The uint8_t => char conversion was indeed a pain and is now fixed. |
e0ff205 to
2b4deae
Compare
|
@keestux, I updated the PR with a better error management (like you suggested). You remark regarding the Sodaqone board makes me wonder if it wouldn't be better to call this driver rn2xx3 (for rn2483 and rn2903) instead of lorabee. This is because the microchip module can be used directly on a board and not via a Bee-like pinout. What do you think ? |
ab73376 to
f5fa930
Compare
|
There are quite a few LoRaBee-like modules on the market, the RN2483/RN2903 is one of them. They are all controller by UART but with different commands. The one here uses a kind of custom ascii commands, the others I saw are controlled with AT commands. These ones will be good candidates for #7084 (here and here). I renamed the driver in this PR to rn2xx3 since it supports rn2483 and rn2903 modules. |
f5fa930 to
126b2d4
Compare
aec9024 to
fd5ff96
Compare
|
Also I removed the netdev/netopt related part and will open a PR based on this one later. |
drivers/rn2xx3/rn2xx3.c
Outdated
|
|
||
| #if ENABLE_DEBUG | ||
| /* we are interested by the debug message in the sleep timer callback */ | ||
| #define ISR_STACKSIZE (THREAD_STACKSIZE_DEFAULT) |
There was a problem hiding this comment.
Setting this here doesn't change the ISR stacksize
There was a problem hiding this comment.
what's the best place for this then ?
There was a problem hiding this comment.
No good place for this. But here it is useless. :)
Maybe a warning comment before the debug.h include is better?
There was a problem hiding this comment.
added a comment explaining how to set it via CFLAGS (untested). So not sure if it works or not.
There was a problem hiding this comment.
I tested this morning and modifying the ISR_STACKSIZE has no effect because the debug message is displayed from the idle thread. Modifying THREAD_STACKSIZE_IDLE using CFLAGS works. I updated the comment accordingly.
drivers/rn2xx3/rn2xx3_internal.c
Outdated
|
|
||
| #define RESP_TIMEOUT_SEC (5U) | ||
|
|
||
| const char * closing_seq = "\r\n"; |
drivers/rn2xx3/rn2xx3_internal.c
Outdated
| }; | ||
| } | ||
|
|
||
| void rn2xx3_bytes_to_hex(const uint8_t *byte_array, char *hex, uint8_t max_len) |
There was a problem hiding this comment.
I already read that somewhere ;)
There was a problem hiding this comment.
adapted using the fmt functions.
drivers/rn2xx3/rn2xx3_internal.c
Outdated
| int rn2xx3_cmd_finalize(rn2xx3_t *dev) | ||
| { | ||
| DEBUG("\n"); | ||
| _uart_write_str(dev, "\r\n"); |
|
@smlng @kaspar030 do you still have comments ? |
|
ACK |
| /** | ||
| * @brief Command responses and server replies status codes | ||
| */ | ||
| enum { |
There was a problem hiding this comment.
looks better now, but you still mix error codes, replies, and others - I would recommend to order/group them, i.e.,
enum {
RN2XX3_OK,
RN2XX3_DATA,
RN2XX3_TIMEOUT,
RN2XX3_ERR_MAC_INIT,
/* all other err codes ... */
RN2XX3_REPLY_TX_MAC_OK,
/* all other reply codes ... */
}
| * @param[out] dev RN2XX3 device to initialize | ||
| * @param[in] params parameters for device initialization | ||
| */ | ||
| void rn2xx3_setup(rn2xx3_t *dev, const rn2xx3_params_t *params); |
drivers/rn2xx3/rn2xx3.c
Outdated
|
|
||
| /* initialize buffers and locks*/ | ||
| dev->resp_size = 0; | ||
| dev->cmd_buf[0] = '\0'; |
There was a problem hiding this comment.
nit-picky: this is inconsistent with the rest of the code, where you set dev->cmd_buf[0] = 0;.
drivers/include/rn2xx3.h
Outdated
| #define RN2XX3_FREQ_BAND (915U) | ||
| #endif | ||
|
|
||
| #if defined(MODULE_RN2483) |
There was a problem hiding this comment.
I would make this an #if #elif #else for RN2XX3_FREQ_BAND, with an #error in the #else branch.
|
I just addressed your last comments @smlng |
|
@aabadie: please squash. @kaspar030 please check if all comments are addressed, so we can get this into the release. |
|
@smlng squashed and rebased |
|
just missing your approval here @kaspar030 :) |
|
ping @kaspar030. After that, it will be straight forward to extend the support of the Sodaq ExpLoRer board with LoRa (see #7733, that needs a small update btw) |
|
just wanted to raise this one again, it's ready to be merged. |
|
it's still on the list for the release, I'll look into it tomorrow but don't have the hardware, to no testing. |
|
@kaspar030 please check if your comments are sufficiently addressed, thx! |
kaspar030
left a comment
There was a problem hiding this comment.
some more things.
Please ignore my doxygen indentation comments, while the indentation is a bit off-standard, at least it is consistent.
| /** | ||
| * @brief RN2483/RN2903 device descriptor | ||
| */ | ||
| typedef struct { |
There was a problem hiding this comment.
This struct is massive... And it wastes quite some memory on bad ordering. But I'm ok with improving later.
drivers/include/rn2xx3.h
Outdated
| * | ||
| * @return RN2XX3_OK on success | ||
| * @return -ENXIO if UART initialization failed | ||
| * @return RN2XX3_TIMEOUT if UART communcation failed |
drivers/include/rn2xx3.h
Outdated
| /** | ||
| * @brief Restarts the RN2XX2 device | ||
| * | ||
| * dev->resp_buf contains the module name and version string. |
There was a problem hiding this comment.
indent off. Maybe "After calling this function, ..."?
drivers/include/rn2xx3.h
Outdated
| * @brief Resets the module’s configuration data and user EEPPROM to factory | ||
| * default values and restarts the module | ||
| * | ||
| * dev->resp_buf contains the module name and version string. |
drivers/include/rn2xx3.h
Outdated
| * @param[in] dev RN2XX3 device descriptor | ||
| * | ||
| * @return RN2XX3_OK on success | ||
| * @return RN2XX3_TIMEOUT if UART communcation failed |
There was a problem hiding this comment.
here and below again communication ('i' missing)
drivers/rn2xx3/rn2xx3_internal.c
Outdated
| ret = rn2xx3_process_response(dev); | ||
| rn2xx3_set_internal_state(dev, RN2XX3_INT_STATE_IDLE); | ||
|
|
||
| DEBUG("RET: %d, RESP: %s\n", ret, dev->resp_buf); |
drivers/rn2xx3/rn2xx3_internal.c
Outdated
| { | ||
| char payload_str[2]; | ||
| for (unsigned i = 0; i < payload_len; i++) { | ||
| fmt_bytes_hex(payload_str, &payload[i], 1); |
There was a problem hiding this comment.
wouldn't fmt_byte_hex() make more sense here?
drivers/rn2xx3/rn2xx3_internal.c
Outdated
|
|
||
| rn2xx3_set_internal_state(dev, RN2XX3_INT_STATE_IDLE); | ||
|
|
||
| DEBUG("RET: %d, RESP: %s\n", ret, dev->resp_buf); |
drivers/rn2xx3/rn2xx3_internal.c
Outdated
| rn2xx3_cmd_finalize(dev); | ||
|
|
||
| rn2xx3_set_internal_state(dev, RN2XX3_INT_STATE_MAC_TX); | ||
| uint8_t ret = rn2xx3_process_response(dev); |
There was a problem hiding this comment.
fold this and the return?
tests/driver_rn2xx3/Makefile
Outdated
| @@ -0,0 +1,10 @@ | |||
| APPLICATION = driver_rn2xx3 | |||
There was a problem hiding this comment.
the include below sets this to tests_driver_rn2xx3, so remove?
|
@kaspar030, sorry for doxygen comments indentation, I prefer this because it's aligned with input/output parameters. Otherwise, I addressed your comments, and fixed other spaces misplaced around |
|
ping @kaspar030, lets get this done. |
The coding conventions say "Line length: aim for no more than 80 characters per line, the absolute maximum should be 100 characters per line." This PR has 60 lines over 80 characters. More than 50 of that are either
If this would be "objective readability vs coding conventions", I wouldn't mind. But I think this is more "I prefer this vs. coding conventions". Also, this PR's doxygen formatting is quite different than in other files. I think we should go for consistency here... |
|
@kaspar030, I updated the doxygen based on how this is already done in other drivers (Si70xx and At86RF2xx), it should be consistent now. I kept the line length below 100 (widest is 99) |
|
@kaspar030 do you ACK ? |
kaspar030
left a comment
There was a problem hiding this comment.
ACK for the formal things (untested).
|
Let's go! |
|
Gratulations for getting a quite large PR in! ;) |
|
Many thanks @keestux, @smlng and @kaspar030 for the in-depth review and @kYc0o for your tests and advices! (edited: added Sebastian) |
This PR adds basic support for the LoRaBee device based on Microchip RN2483 or RN2903 LoRa modules.
Those modules provides a full LoRaMAC stack + basic LoRa/FSK radio capacities that can be controlled using an UART interface. This is a bit similar to the XBee except that it doesn't use AT commands. Here the commands are sent in text mode and data using their hexadecimal representation.
For the moment, this driver provides a very simple API to initialize the device and methods to send text commands on the UART and wait for network replies.
There's also a test application that provides 3 shells commands:
sys,mac,radio. One can directly use them as described in the command reference document: RN2483, RN2903.My setup for testing is: Arduino-zero + Arduino wireless shield + LoRaBee. One can also use Nucleo144 boards and maybe other Arduino compatible boards.
Future improvements required (in follow-up PRs):
Better integrate into netdevAuto init with default parameters (deveui, appeui, appkey, etc)Since my module comes from Sodaq, maybe @keestux will be able to test this PR ;)
Depends on
#7592