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

Add driver for SX126x modems #949

Merged
merged 15 commits into from
Oct 1, 2024
Merged

Conversation

TristanWebber
Copy link

Adds driver for SX126x modems.

  • Created new driver (radio_sx126x.c). Uses the same functions as radio.c for anything called by LMIC but for 'private' functions it follows the API described in the SX126x Data Sheet
  • Renamed radio.c to radio_sx127x.c and added #if to select the correct file
  • Modified config.h and lmic_project_config.h to handle the new options
  • Minor additions to hal.cpp and hal.h to deal with the slightly different interface on the SX126x family
  • Added a new board pinmap for Heltec Lora32 V3 (which is identical to Heltec Wireless Stick Lite V3)

Physical tests - Adding notes here because it's been tested in a relatively narrow set of possible configurations:

  • Hardware tested: Heltec Wireless Stick Lite V3 with MCU = ESP32-S3 @ 240MHz and SX1262 modem configured with DC-DC regulator, DIO2 controlling RF Antenna, DIO3 controlling TCXO
  • RX window timing was adjusted to account for differences in this modem vs the SX127x family
  • Tested on TTN using OTAA join of LoRaWAN 1.0.3 over AU915
  • FSK has been implemented but NOT tested

@baranator
Copy link

baranator commented Nov 25, 2023

Hi!

I'm currently tinkering around with the Heltec Wireless Stick lite v3 and stumbled across your PR. Somehow i cannot get it to work - neither in platformio nor in Arduino. I set the defines in lmic_project_config.h and also alternatively tried setting a pinmap according to the heltec schematic for this device.

#define CFG_eu868 1
#define CFG_sx1262_radio 1
#define ARDUINO_heltec_wifi_lora_32_V3
#define hal_init LMICHAL_init

I tried the ttn-otaa.ino example of this library in the Arduino IDE, set the Board to Heltec Wireless Stick (v3)

The "best" results i got with this configuration: The device boots, and i get the serial-output Starting but then nothing else happens. Strangely if i then push the user_sw button on the board, i get this, but in the ttn-console i don't see the joining request or any transferred data. This also happens, when i try the LMIC-node example .

Do you have any ideas on this? Would be great to get it running.

@TristanWebber
Copy link
Author

Hi Eike,

Thanks for getting in touch. I won't be able to look at this in depth this week but should be able to give it some time next week. However a couple of comments to get you started:

  1. I've only tested on the AU915 band, so we may need to have some back and forth to get to issues with EU868 because I don't have the means to directly test that myself. But I'm up for it if you are
  2. I have avoided the lmic_project_config.h file and have instead been using platform.ini in my platform.io projects. I doubt this will make any difference but figured I'd mention just in case:
build_flags = 
	-D hal_init=LMICHAL_init
	-D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS
	-D CFG_au915=1
	-D CFG_sx1262_radio=1
	-D LMIC_DEBUG_LEVEL=2
  1. I suggest you compile the project with #define LMIC_DEBUG_LEVEL 2 or in platform.ini. This should give some logging after the Starting you are currently getting and with any luck this will provide some useful information on where I can start looking for the issue.
  2. Do you own or have access to the gateway the node would be connecting to? If so, can you see any logging on the gateway?

I'll get onto this in a week or so but if you can get some debug logs in the interim that would give me a head start!

Tristan

@baranator
Copy link

baranator commented Nov 27, 2023

Setting Debug Level 2 does not give that much information either.

20:59:19.886 -> (⸮�I�R⸮p��I��Starting
20:59:51.537 -> Packet queued
20:59:51.570 -> 1978335: EV_JOINING
20:59:51.570 -> 1978341: engineUpdate, opmode=0x4
20:59:56.658 -> 2298138: engineUpdate, opmode=0x4
20:59:56.691 -> 2298155: EV_TXSTART
21:12:58.326 -> 51150091: TXMODE, freq=868100000, len=23, SF=7, BW=125, CR=4/5, IH=0

This is the output; at 20:59:20 i rebooted the wifi stick via reset button, then the Starting message appears, but nothing else happens. At 20:59:51 i pressed the user-Switch which causes the messages from Packet queued to EV_TXSTART , at 21:12:58 i pressed it again and got that TXMODE message. (the behaviour is the same, when i press and hold the userswitch for suspicious 5 seconds.)

The Gateway I'm testing with is mine and works for another TTN-application. However, when trying to use the sx1262 implementation, nothing happens and i don't see any Join-request, confirmation or even a payload-message.

I then tried to use the AU915 frequency, hoping to see some message about a failed join but got this:

21:32:30.889 -> �⸮�⸮A�r�s��⸮�⸮Starting
21:32:58.372 -> 1717369: engineUpdate, opmode=0x8
21:32:58.406 -> Packet queued
21:32:58.439 -> 1717394: EV_JOINING
21:32:58.439 -> 1717400: engineUpdate, opmode=0xc
21:32:58.472 -> 1717417: EV_TXSTART
21:32:58.505 -> 1717520: TXMODE, freq=926800000, len=23, SF=10, BW=125, CR=4/5, IH=0

again, when userswitch was pressed at 21:32:58. In contrast to the EU868 procedure the 5-second-gap when holding the userswitch is gone (as you see at the timestamps)

@TristanWebber
Copy link
Author

Thanks for that. The behaviour with the USER switch is strange - I don't recall anything within the example or the LMIC that would be using that pin.

What baud rate are you using for serial output? Can I suggest trying with 115200?

As for a running commentary on what may be happening with those debug messages, after the line:

21:12:58.326 -> 51150091: TXMODE, freq=868100000, len=23, SF=7, BW=125, CR=4/5, IH=0,

if everything was working correctly we would expect to see a debug message from the IRQ to identify if the transmission was completed, such as:

TIME: IRQ handler, dio=0
TIME: IRQ rawFlags=0001
TIME: IRQ flags=08

If we're not seeing the IRQ handler triggering it points to the transmission for the join request not being sent. Is the antenna connected to the board?

@baranator
Copy link

Thanks for that. The behaviour with the USER switch is strange - I don't recall anything within the example or the LMIC that would be using that pin.
yep. That is, what i puzzles me the most. I literally don't see any connection between that switch and the code/lib.

I would be ashamed, but did i may simply did the pin-wiring wrong? Checked it many times and see nothing wrong:

const lmic_pinmap lmic_pins = {
    .nss = 8,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 12,
    .dio = {  14 , LMIC_UNUSED_PIN, LMIC_UNUSED_PIN},
        .rxtx_rx_active = 0,
};

and my platformio.ini looks like this:

[mcci_lmic]
lib_deps =
    https://github.com/TristanWebber/arduino-lmic.git#sx126x ; mcci w sx1262

build_flags =
    -D hal_init=LMICHAL_init
    -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS
    -D LMIC_DEBUG_LEVEL=2            
    -D CFG_eu868=1

[env:heltec_wifi_lora_32_V3]
platform = espressif32
board = heltec_wifi_lora_32_V3
framework = arduino
lib_deps =  
    ${mcci_lmic.lib_deps}
build_flags=
    ${mcci_lmic.build_flags}	
    -D CFG_sx1262_radio=1

Do you may have a minimum working example that i could test, just to ensure not a stupidity of mine is the cause of the problem?

What baud rate are you using for serial output? Can I suggest trying with 115200?

had it on 9600, but changing it to 115200 made no difference.

@TristanWebber
Copy link
Author

Your pinmap looks fine, as does the platform.ini file. However I have been assigning the pinmap differently - I have been calling a function in the HAL. The minimal example I used for initial testing is almost identical to the ttn-otaa.ino example but with the following changes:

  1. Including another hal header file #include <arduino_lmic_hal_boards.h>
  2. Instead of explicitly assigning the pinmap I have been assigning a pointer to the pinmap in the hal
    const lmic_pinmap *pPinMap = Arduino_LMIC::GetPinmap_ThisBoard();
  3. In setup instead of calling os_init(); I call os_init_ex(pPinMap);
  4. I made a couple of other changes that result in better connection but they are likely region specific so I won't suggest those for eu868 at this point

I suspect this difference may result in a couple of horrible little virtual functions I wrote not being called properly. I should probably add this example to the repo if it turns out to work for you!

@baranator
Copy link

Your pinmap looks fine, as does the platform.ini file. However I have been assigning the pinmap differently - I have been calling a function in the HAL. The minimal example I used for initial testing is almost identical to the ttn-otaa.ino example but with the following changes:

  1. Including another hal header file #include <arduino_lmic_hal_boards.h>
  2. Instead of explicitly assigning the pinmap I have been assigning a pointer to the pinmap in the hal const lmic_pinmap *pPinMap = Arduino_LMIC::GetPinmap_ThisBoard();
  3. In setup instead of calling os_init(); I call os_init_ex(pPinMap);
  4. I made a couple of other changes that result in better connection but they are likely region specific so I won't suggest those for eu868 at this point

I suspect this difference may result in a couple of horrible little virtual functions I wrote not being called properly. I should probably add this example to the repo if it turns out to work for you!

Yes! That worked! The Board instantly joins and sends it's message, everything arrives correctly at the gateway and ttn-application. Thus the IRQ-Messages are shown, too. Let's call it eu868 confirmed ;)

I'll try to have a look at why this workaround is needed and if can rid of it.

@TristanWebber
Copy link
Author

Great news! I'm glad it's working for you.

@AndreKR
Copy link

AndreKR commented May 15, 2024

@baranator I also have a Heltec Wireless Stick that I would like to use with LoRaWAN. Do you have a project that I can copy as a starting point?

@baranator
Copy link

baranator commented May 16, 2024

@baranator I also have a Heltec Wireless Stick that I would like to use with LoRaWAN. Do you have a project that I can copy as a starting point?

This is basically the ttn-otaa-Example of the unmodified mcci-catena library with the modifications suggested by @TristanWebber in this Thread and his modified fork added to the platformio.ini :

https://github.com/baranator/sx1262minimal

@TristanWebber
Copy link
Author

TristanWebber commented May 19, 2024 via email

@oseiler2
Copy link

oseiler2 commented May 25, 2024

Thanks for this, I have successfully got it working on a T-Beam S3 (AU915).
One thing I noticed it that the library configures the DIO[1-3], but not the busy pin returned by queryBusyPin(). Might be helpful to add that, and/or document it.

See TristanWebber#1

@TristanWebber
Copy link
Author

TristanWebber commented May 25, 2024 via email

@oseiler2
Copy link

oseiler2 and others added 2 commits June 26, 2024 18:09
Busy pin initialisation and T-Beam S3 Core/Supreme pinmap
@terrillmoore
Copy link
Member

Look like this is still in progress. Let me know when you're ready for a review / merge cycle.

@TristanWebber
Copy link
Author

@terrillmoore it's ready when you are. Yesterday's push was a bug fix and otherwise I haven't actively changed the driver for quite a while.

@terrillmoore
Copy link
Member

terrillmoore commented Jun 26, 2024 via email

@cyberman54
Copy link

cyberman54 commented Jun 30, 2024

I can confirm, this new radio driver works on a SX1262 with TTN (with LoRaWAN 1.0.3) and EU868. Tested on a T-Beam Supreme S3 board today. It did immediately join and transmit. Tested using my paxcounter project, see this branch.

@cyberman54
Copy link

ping - is a merge still planned?

Copy link
Member

@terrillmoore terrillmoore left a comment

Choose a reason for hiding this comment

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

We should consider adding info in the README:

  • contributor for the SX126x support
  • info on configuring for SX126x (ideally)

However, this can be done as a separate step.

Thanks for the contribution. I will merge this to head, and you can do any updates as separate PRs.

@@ -31,7 +31,7 @@
#define LMIC_DR_LEGACY 0

#include "lmic.h"

#if (CFG_sx1272_radio || CFG_sx1276_radio)
Copy link
Member

Choose a reason for hiding this comment

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

please use defined( on both parts, for consistency with files above.

Or, to minimize typing, we could introduce derived variables ..._sx127x_radio and ..._sx126x_radio, that are always defined, and either zero or non-zero. But I think that can be done later. (The ... should be something other than CFG because CFG is used for user configuration #defines. There are examples elsewhere.) However, I think it's better to just go for consistency and do a cleanup pass separately. You've waited long enough.

src/lmic/radio_sx127x.c Show resolved Hide resolved
@terrillmoore terrillmoore merged commit e9e7bae into mcci-catena:master Oct 1, 2024
@TristanWebber
Copy link
Author

TristanWebber commented Oct 2, 2024 via email

terrillmoore added a commit that referenced this pull request Oct 2, 2024
…erman54-patch-1

This closes pr #894 to fix a bug in power computation, but was already address in #949.
@@ -184,6 +191,13 @@ static void hal_spi_init () {
SPI.begin();
}

#if (defined(CFG_sx1261_radio) || defined(CFG_sx1262_radio))
bit_t is_busy() {
Copy link
Member

Choose a reason for hiding this comment

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

is_busy() should not be a global -- or should be hal_is_radio_busy() if it needs to be global for the driver.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants