Arduino lmic library config for ESP32

I’m using the lmic library from mcci, which I think is the standard people seem to use. I’m using it with a custom dev board - not one they list. I can see that most of the LoRa integrated boards use non-standard SPI pins (i.e. not the default hardware pins on the ESP32). So I need to change these for my board. I can just hack the library, but wondered if there’s actually a config option, like the lmic_pinmap, which doesn’t specify SCK, MOSI and MISO? Anyone know?

The introductory section for MCCI LMIC mentions the new gold standard for Arduino:

with lots and lots of support for ESP32 devices.

But to answer your question, the libraries pickup the default definitions for SPI. You can have NSS/CS on any pin but you do need to tell it which one and which pins are connected for DIO0 and DIO1.

Hmm ok, I read the big thread about ESP32 here and it lists non-standard SPI pins for the TTGO boards etc. Guess I’ll see if it does use hspi or vspi by default.

Um, I just put an extra layer of gift wrapping on the gift wrapped solution that LMIC-node brings to the party.

The person who answers the most questions on this forum about ESP32, @bluejedi, created LMIC-node so you don’t have to read the big threads etc etc.

I did take a quick look at that lmic-node lib and it’s for platform.io. I’m currently using the standard Arduino IDE for this project (I mainly use Visual Studio, STMCube and Espressive IDE amongst others, but not Platform.io). It looks like lmic-node is just a wrapper around the library I’m already using though.

No, LMIC-node is not just a wrapper around MCCI LMIC.
It’s a well tested cross-platform application that works out of the box for all supported boards and platforms and solves exactly the kind of issues you are currently running in to.

As far as I’m aware there currently is no such config option. MCCI LMIC uses the default SPI port (which uses the Arduino SPI pin definitions from the BSP).
Arduino pin definitions are configured in a board-specific BSP which for your custom board does not exist. When selecting another, existing board instead (part of) those definitions will be incorrect.

Hacking the MCCI library unneeded is bad practice and maintenance prone.
Use apropriate Arduino ESP32 mechanisms to set the SPI port instead.
LMIC-node gives good examples for that (check the board support files).
It’s probably easiest to update one of the existing board support files and change any pins as needed for your custom board.

If you’re accustomed to more professional IDE’s than Arduino IDE you will probably love PlatformIO (the PlatformIO IDE is a plugin for VSCode).

As Visual Studio user you will probably be familiar with Visual Studio Code (VSCode) already.

Installing PlatformIO, downloading and getting LMIC-node up and running is quick, easy and well documented.

Once you have this running it will be easier to start your own journey / use LMIC with your own code.

Thanks, yes I took a look at the src and can see where it defines the SPI pins, to match the various boards. If I update one of the board files, it’s still going to be overwritten if the lib is updated, isn’t it? I’m happy to maintain my own fork in any case.

I’ll probably just expand the HalPinmap_t structure with extra entries for mosi,miso and sck pins, to add flexibility, and maybe some additional error codes to identify where it fails during initialization. (I mostly work on hardware design and am adding LoRa to the existing Sigfox, GSM/nbIoT and Wifi comms, so really just need to ensure the board is sending data ok from my perspective).

I have taken a look at platform.io before - I don’t actually use VS Code, only the full version of Visual Studio along with a bunch of other IDEs, and prefer not to add another for one project that I’ll probably never use again, if I can avoid it :grin: I’ll see how it goes though!

PlatformIO is mostly an IDE plugin that can be used on:

VSCode, Atom, Cloud9, Codeanywhere (Cloud), Eclipse Che (Cloud), CLion,CodeBlocks, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, Vim and, erm, Visual Studio

but they do have their own IDE in the works.

Nope - you can put your pin definitions in to the main file if you want.

To LMIC? Do let us know how you get on with that. :upside_down_face: It’s not the clearest code base in the world. And if you have issues with the stack / connectivity / version / MAC commands, it will make it more interesting to debug.

As for maintaining your own fork, apart from the many files & lack of comments, there is the no small matter than LMIC is changing its event model which will move the goal posts.

The whole idea is that these Arduino centric libraries pick up the default pins so none of this should be necessary - I know LMIC well enough that I sometimes use it raw and when I put it on an ATmega4808 it just worked as expected. For a supported board, LMIC-node just works.

Yep that’s the part I’ve extended now to add the SPI pin definitions - doesn’t seem any worse than any other libs I’ve worked on :rofl:. I think to add support for a custom board type I would have had to add to the HAL files, in the library though, right?

I’ve added a new enum list so I can query the reason for an error/failure via a new lib function, just to make it easier to debug for myself. Doesn’t exactly help performance when enabled, so I’ll be keeping it on a fork. Not too worried about maintenance for this, as I’m only using the code to test the hardware - not for ongoing dev on my part :grin:.

For “for one project that I’ll probably never use again”?

You won’t add any flexibility here because SPI implementations are hardware platform dependent. Arduino framework’s SPI.begin() by default is parameterless and uses the SPI pins defined in the BSP. It depends on the Arduino core for a specific platform whether SPI.begin() provides any parameters or not. So specifying SPI pins in the pinmap structure will actually be useless for general use.

As said there is no need to change LMIC if you want to use other SPI pins for LoRa on your ESP32.

The ESP has an internal MUX for peripherals though, so can route either of its SPI channels to any set of pins (though it does incur a performance hit if not on the defaults, but still way faster than the LoRa chips can handle). There’s also the possibility people might want to use VSPI at full speed to run a display via DMA while using the secondary HSPI channel at lower speed for the LoRa comms. I dunno, it wasn’t a huge piece of work in any case - pretty much done now, except for adding some extra error logs. If I wasn’t too lazy to update everything in the HAL, I’d modify the init to pass a reference to the SPI device in so it can be set up outside of the HAL - that’s what I’ve done on graphic drivers before. As said I’m just keeping it on a fork, so it won’t cause any issues for anyone but me :grin:.