Giter Site home page Giter Site logo

Comments (10)

cjhdev avatar cjhdev commented on July 18, 2024 1

I didn't took a deep look, but I assume the mandatory interfaces are those marked with @warning this function must be implemented on target for correct operation.

Yeah more or less.

I'm at master, should i also check the development branch?

Master is best. Development might not work properly.

so far i haven't seen any timer being setup

LDL has a bunch of internal timers that depend on the platform providing a free-running 32bit counter.

  • LDL_System_time() returns the counter value at any time
  • LDL_System_tps() returns the rate at which the counter increments (ticks per second)
  • LDL_System_eps() returns the error in ticks (error per second)

So on Arduino for example:

  • LDL_System_time() wraps micros()
  • LDL_System_tps() returns 1000000
  • LDL_System_eps() returns 5000 to account for a ceramic resonator

from lora_device_lib.

cjhdev avatar cjhdev commented on July 18, 2024

Hello

Thanks, I started this project to learn the protocol and also because I felt the other implementations looked crazy.

This project is active but I am (probably) the only person using it. It would be great to get some more users and contributors that appreciate the style of this implementation over the alternatives. Before accepting contributions I think it would be necessary to lay down some guidelines so that no effort is wasted.

There is no roadmap, there could be one if there was serious interest. The reason I haven't done class B and C is because I have no need for these modes. The biggest challenge with implementing these modes (or indeed any new features) is verifying that they work correctly. Class B needs a lot more tooling than class A.

I would describe the quality as experimental. I don't think you should use it for anything serious at the moment. This could change if more people use it. I think it would also be good to run it through the LoRaWAN conformance test at some point.

I'm planning to release 0.1.7 in the next week or two. I'll see if I can also produce a list of what works well and what needs to be improved.

from lora_device_lib.

C47D avatar C47D commented on July 18, 2024

Hi,

I would describe the quality as experimental. I don't think you should use it for anything serious at the moment. This could change if more people use it. I think it would also be good to run it through the LoRaWAN conformance test at some point.

Thanks for the quick reply, to be honest I just been told that the plan A is to use modules commanded via AT commands, so I'm no longer in a hurry, at least not for work projects.

I'm still interested in using this library as a learning exercise and in personal projects, seems like I will be using LoRaWan for a while and, as you did when you started this project, I would use it to learn the protocol.

I'm planning to release 0.1.7 in the next week or two. I'll see if I can also produce a list of what works well and what needs to be improved.

I would like to propose the following, let me know if you agree. I can get more familiar with LoRaWan and maybe other implementations of it, then if you feel like it I can help with small and easy tasks of the to be implemented list.


So far I have been able to include LDL to my project and initialize boath Board and Radio, just noticed I must implement all the weak functions in lora_system, am I right? Maybe a porting guide would be nice for us who aren't familiar with LDL.

Regards

from lora_device_lib.

cjhdev avatar cjhdev commented on July 18, 2024

I think an AT command module is wise for proof of concept. You don't want to get bogged down in technical details before you know if the technology is right for the application.

Yes I agree a todo list is a good idea.

Yes I agree a porting guide would be helpful.

Some of the system interfaces will work just fine with the weak implementations, while others are show stoppers. Looking at the API documentation it occurs to me not all of the mandatory interfaces are marked as mandatory.

The arduino wrapper is a good reference for what is mandatory.

edit:

I should also mention that since I am in the UK I only ever use the setting for the EU_863_870 region. I have in the past emulated some of the other regions but not for some time.

from lora_device_lib.

C47D avatar C47D commented on July 18, 2024

I should also mention that since I am in the UK I only ever use the setting for the EU_863_870 region. I have in the past emulated some of the other regions but not for some time.

I'm located in Mexico, will test the US_902_928 region.

Some of the system interfaces will work just fine with the weak implementations, while others are show stoppers. Looking at the API documentation it occurs to me not all of the mandatory interfaces are marked as mandatory.

I didn't took a deep look, but I assume the mandatory interfaces are those marked with @warning this function must be implemented on target for correct operation. I'm at master, should i also check the development branch?

The arduino wrapper is a good reference for what is mandatory.

I will take a look at it, so far i haven't seen any timer being setup, while in loramac-node, they use the microcontroller RTC, is this only neccesary on Class B or C nodes?

from lora_device_lib.

C47D avatar C47D commented on July 18, 2024

LDL has a bunch of internal timers that depend on the platform providing a free-running 32bit counter.

LDL_System_time() returns the counter value at any time
LDL_System_tps() returns the rate at which the counter increments (ticks per second)
LDL_System_eps() returns the error in ticks (error per second)
So on Arduino for example:

LDL_System_time() wraps micros()
LDL_System_tps() returns 1000000
LDL_System_eps() returns 5000 to account for a ceramic resonator

Haven't been on my work station, I'm using STM32 devices, I guess the HAL_GetTick() function for LDL_System_time() should work, it should return the same value in LDL_System_tps() and I will calculate the value for LDL_System_eps()

EDIT

Just uploaded my test project LDL_Sandbox.

The main changes i did are:

// get system time (ticks)
uint32_t LDL_System_time(void)
{
    return HAL_GetTick(); // Provide a tick value in millisecond.
}

// ticks per second
uint32_t LDL_System_tps(void)
{
    return HAL_GetTickFreq();  // Return tick frequency.
}

// TODO: error per second
uint32_t LDL_System_eps(void)
{
    return 0UL;
}

/* Session keys must be handled here */
void LDL_System_getIdentity(void *app, struct lora_system_identity *value)
{
	(void) app;

	const uint8_t device_eui [] = {
		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
	};

	const uint8_t application_eui [] = {
		0x08 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
	};

	const uint8_t application_key [] = {
		0x08 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
	};

	memcpy(value->devEUI, device_eui, sizeof device_eui);
	memcpy(value->appEUI, application_eui, sizeof application_eui);
	memcpy(value->appKey, application_key, sizeof application_key);
}

void main() {

...
}

My current output is:

app_handler: LORA_MAC_STARTUP
app_handler: LORA_MAC_TX_BEGIN
app_handler: LORA_MAC_CHIP_ERROR

The only place where the LORA_MAC_CHIP_ERROR is used in the lora_mac.c file is:

if(LDL_Event_checkTimer(&self->events, LORA_EVENT_WAITA, &error) || LDL_Event_checkTimer(&self->events, LORA_EVENT_WAITB, &error)){
#ifndef LORA_DISABLE_CHIP_ERROR_EVENT
self->handler(self->app, LORA_MAC_CHIP_ERROR, NULL);
#endif
LDL_Event_clearInput(&self->events);
LDL_Event_clearTimer(&self->events, LORA_EVENT_WAITA);
LDL_Event_clearTimer(&self->events, LORA_EVENT_WAITB);
self->state = LORA_STATE_RECOVERY_RESET;
self->op = LORA_OP_RESET;
LDL_Radio_reset(self->radio, true);
/* hold reset for at least 100us */
LDL_Event_setTimer(&self->events, LORA_EVENT_WAITA, ((LDL_System_tps() + LDL_System_eps())/10000UL) + 1U);
}
}

So I will try to check what leads to that error.

from lora_device_lib.

cjhdev avatar cjhdev commented on July 18, 2024

Looking good.

I see the problem, you need to connect the radio "DIO" control lines. That part is missing from the example you are based on, it's not very clear.

You need to detect the DIO line(s) rising edge and then call LDL_MAC_interrupt(&mac, n, LDL_System_time()) where n is the index of the line (e.g. DIO0 is n == 0). You only need DIO0, DIO1, DIO2, and DIO3.

This is how the arduino wrapper does it. That function is called by an ISR for a particular control line. There is implementation specific logic but the important part is that I call LDL_MAC_interrupt().

If you use an interrupt, make sure to define LORA_SYSTEM_ENTER_CRITICAL and _LEAVE_CRITICAL. This should work:

#define LORA_SYSTEM_ENTER_CRITICAL(APP) volatile uint32_t primask = __get_PRIMASK();__disable_irq();
#define LORA_SYSTEM_LEAVE_CRITICAL(APP) __set_PRIMASK(primask);

I recommend to put this in a header file, then define LORA_TARGET_INCLUDE to be the name of that file (e.g. -DLORA_TARGET_INCLUDE='"your_header.h"'). All the other LDL build options can go there.

You will need to also define:

  • LORA_ENABLE_SX1276
  • LORA_ENABLE_US_902_928
  • LORA_DISABLE_FULL_CODEC

I assume you've already done this somewhere I can't see. I mean, you can do it all from the makefile if you prefer.

Once you get that sorted you will probably find that the example sends too frequently since the US doesn't have a duty cycle limit. To slow it down you can either add a delay in your app, or set LDL_MAC_setAggregatedDutyCycle() to impose a global duty cycle limit. A setting of 7 will give you a ~1% duty cycle limit.

edit: made mistake on global duty cycle

from lora_device_lib.

C47D avatar C47D commented on July 18, 2024

Hi,

Thanks for taking a look at the project, just noticed i uploaded the keys of it, so i had to make the repo private :/, let me know if you want me to give you access to it.

I see the problem, you need to connect the radio "DIO" control lines. That part is missing from the example you are based on, it's not very clear.

You need to detect the DIO line(s) rising edge and then call LDL_MAC_interrupt(&mac, n, LDL_System_time()) where n is the index of the line (e.g. DIO0 is n == 0). You only need DIO0, DIO1, DIO2, and DIO3.

This is how the arduino wrapper does it. That function is called by an ISR for a particular control line. There is implementation specific logic but the important part is that I call LDL_MAC_interrupt().

Here's how i implemented it:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	switch (GPIO_Pin) {
	case DIO0_Pin:
		LDL_MAC_interrupt(&mac, 0, LDL_System_time());
		break;
	case DIO1_Pin:
		LDL_MAC_interrupt(&mac, 1, LDL_System_time());
		break;
	case DIO2_Pin:
		LDL_MAC_interrupt(&mac, 2, LDL_System_time());
		break;
	case DIO3_Pin:
		LDL_MAC_interrupt(&mac, 3, LDL_System_time());;
		break;
	default:
		break;
	}
}

If you use an interrupt, make sure to define LORA_SYSTEM_ENTER_CRITICAL and _LEAVE_CRITICAL. This should work:

#define LORA_SYSTEM_ENTER_CRITICAL(APP) volatile uint32_t primask = __get_PRIMASK();__disable_irq();
#define LORA_SYSTEM_LEAVE_CRITICAL(APP) __set_PRIMASK(primask);

I recommend to put this in a header file, then define LORA_TARGET_INCLUDE to be the name of that file (e.g. -DLORA_TARGET_INCLUDE='"your_header.h"'). All the other LDL build options can go there.

My custom header file is named LDL_options.h and goes as follows:

#ifndef LDL_OPTIONS_H_
#define LDL_OPTIONS_H_

#include "cmsis_gcc.h"

// http://stm32f4-discovery.net/2015/06/how-to-properly-enabledisable-interrupts-in-arm-cortex-m/

static volatile uint32_t primask = 0;

#define LORA_SYSTEM_ENTER_CRITICAL(APP) do { primask = __get_PRIMASK(); __disable_irq(); } while (0);
#define LORA_SYSTEM_LEAVE_CRITICAL(APP) __set_PRIMASK(primask);

#endif /* LDL_OPTIONS_H_ */

You will need to also define:

LORA_ENABLE_SX1276
LORA_ENABLE_US_902_928
LORA_DISABLE_FULL_CODEC
I assume you've already done this somewhere I can't see. I mean, you can do it all from the makefile if you prefer.

Yep, I define those symbols on the IDE, but now i think it's better to have them on the LDL_options.h file so others doesn't need to load the project into the IDE just to see the configuration. So the LDL_options.h file ends up like this:

#ifndef LDL_OPTIONS_H_
#define LDL_OPTIONS_H_

#include "cmsis_gcc.h"

// http://stm32f4-discovery.net/2015/06/how-to-properly-enabledisable-interrupts-in-arm-cortex-m/

#define LORA_ENABLE_SX1276
#define LORA_ENABLE_US_902_928
#define LORA_DISABLE_FULL_CODEC

// #define LORA_TARGET_INCLUDE	 /* See lora_platform */

static volatile uint32_t primask = 0;

#define LORA_SYSTEM_ENTER_CRITICAL(APP) do { primask = __get_PRIMASK(); __disable_irq(); } while (0);
#define LORA_SYSTEM_LEAVE_CRITICAL(APP) __set_PRIMASK(primask);

#endif /* LDL_OPTIONS_H_ */

Once you get that sorted you will probably find that the example sends too frequently since the US doesn't have a duty cycle limit. To slow it down you can either add a delay in your app, or set LDL_MAC_setAggregatedDutyCycle() to impose a global duty cycle limit. A setting of 7 will give you a ~1% duty cycle limit.

edit: made mistake on global duty cycle

Will edit the comment once i get some results later today.

Thanks for the help and patience.

EDIT
After fixing the SPI configuration and adding

#define LORA_DISABLE_CHIP_ERROR_EVENT

I got the app_handler callback called with the following lora_mac_response_types

Initializing the board
Initializing the radio
Setting the radio PA
Initializing MAC
Processing...
app_handler: LORA_MAC_RESET
app_handler: LORA_MAC_STARTUP
sending join in 40 ticks
app_handler: LORA_MAC_TX_BEGIN
app_handler: LORA_MAC_TX_COMPLETE
app_handler: LORA_MAC_RX2_SLOT
sending join in 31 ticks
app_handler: LORA_MAC_TX_BEGIN
app_handler: LORA_MAC_TX_COMPLETE
app_handler: LORA_MAC_RX2_SLOT
sending join in 6 ticks
app_handler: LORA_MAC_TX_BEGIN
app_handler: LORA_MAC_TX_COMPLETE
app_handler: LORA_MAC_RX2_SLOT
sending join in 8 ticks
app_handler: LORA_MAC_TX_BEGIN
app_handler: LORA_MAC_TX_COMPLETE
app_handler: LORA_MAC_RX2_SLOT
sending join in 0 ticks
app_handler: LORA_MAC_TX_BEGIN
app_handler: LORA_MAC_TX_COMPLETE
app_handler: LORA_MAC_RX2_SLOT
sending join in 47 ticks

Seems like the gateway is far away, I'm using one from TTN, ~10km away, will try to get one for my work place.

from lora_device_lib.

cjhdev avatar cjhdev commented on July 18, 2024

10km is probably too far for initial debug. Too close (i.e. sitting right next to the gateway) can also be an issue.

It's often useful to print time (i.e. LDL_System_time()) with each event for double checking timing.

from lora_device_lib.

C47D avatar C47D commented on July 18, 2024

Hi,

Thanks for the tips. I had to modify the logging macros (replacing PRIu32 for %d) because of my underlying functions. Everything else seems to be working as expected. Will report back when I get a gateway.

from lora_device_lib.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.