janjongboom / sam-lorawan-mbedos5

Mbed OS 5 LoRaWAN stack running on SAML21 and SAMR34 Xplained Pro
Apache License 2.0
6 stars 1 forks source link

Tickless #4

Open wimmatthijs opened 4 years ago

wimmatthijs commented 4 years ago

The Lora stack doesn't function when using Tickless macro. Is the resolution of lptimer enough to support acurate timing?

janjongboom commented 4 years ago

Tickless should be fine as long as lpticker is implemented correctly, at least on other platforms e.g. DISCO-L475VG-IOT01A... What do you see?

wimmatthijs commented 4 years ago

going to have a look at it with the one and only Husnain Virk later today :-)

It seems a problem that has already been tackled (somehwat) in this thread https://github.com/ARMmbed/mbed-os-example-lorawan/issues/103

basically what i see is just very bad performance, i have few issues

I'm running on 16MHz core clock, which should be enough, even for SF7 to get near the second accuracy for RX slot, but no luck. In tickless mode i am using exernal xtal, also used for my RTC, .... but i'm just not getting it right i guess.

Funny thing, even when i set lp_ticker to use main clock of 16MHz and just keep that running, and doing a deepsleeplock, it still shows the same behavior....

hope Husnain can help me out, i will post any new input here!

wimmatthijs commented 4 years ago

narrowed it down to problems with lp_ticker as you suggested, Jan, going to dig a bit deeper now. Something is off with the LP_timer configuration. Let me get inspired by the DISCO-L475VG-IOT01A implementation

wimmatthijs commented 4 years ago

i' ve done many tests with many many different settings, but the behaviour of the node just gets completely unpredictable when tickless is enabled. even when using the exact same settings as without tickless macro enabled (the application works perfecty without ticklesss) so i just set all the settings the same, use the same clock in lp_ticker as the main clock but all the timing becomes incredibly inconsistent if i do so. Unfortunately tackling this problem goes beyond my current needs or competence.

chheers

Wim

janjongboom commented 4 years ago

@elsalahy Any issues with tickless on the generic node?

elsalahy commented 4 years ago

@janjongboom We tested Lpticker when we implemented it a few months ago (first image before LPT, second image after LPT) image

image

You can see the curser delta improvement and the reduction of active current.

We didn't test LPT+ LoRaWAN extensively, because we had prototype battery problems that prevented reliable operation anyway (I admit we should test this more often but for us, this is just an integration issue since we can see accurate clock operation).

I hope @wimmatthijs is using my LPT implementation (that we sent from the first email) and that he is adjusting the parameters according to his clock configurations (below an example of 8MHZ clock)

image

elsalahy commented 4 years ago

Also, all the issues @wimmatthijs described indicate inaccurate clock, that is why downlinks are not received and it takes longer for OTAA to join.

The Mbed OS LoRaWAN Stack is designed to handle drifting issues by the adjustment of the following configuration in mbed_app.json "lora.max-sys-rx-error": "20" "lora.wakeup-time": "20"

while this is not a solution, it will prove the running clock inaccuracy caused by incorrect Tickelss/LPT activation.

wimmatthijs commented 4 years ago

yes agreed, the tickless does function in a way. In my case i wanted to use the XOSC32k since it is running anyway, without dividers, In this case i am getting delayed results for the rx window of about 900ms which is kind of ridiculous.... I have the feeling when i use LP ticker, it is not correctly linked to systick.

wimmatthijs commented 4 years ago

oh by the way, i did use the lpticker_api you sent me ;-) When using faster clocks (16MHz without divider) for lp_ticker the "error" i am seeing on the RX window is not very stable. Sometimes just 10ms other times up to 50+60ms So the offset that needs to be compensated isn't even stable.... very hard to do a workaround for

oh and also I don't really understand the images.... i woudn't consider 5mA low power :-D Or is this some sort of special stress test? :-D

elsalahy commented 4 years ago

@wimmatthijs You seem to have very specific requirements such as 16 MHz and no divider or using external oscillator as input. Please share configuration snippets (i.e. conf_clocks.h, lp_ticker_api.c (configuration parameters only)) in order to assist you.

Regarding the images, I said "active current" and this is not related to sleep currents.

You can see the curser delta improvement and the reduction of active current.

wimmatthijs commented 4 years ago

Thanks Achmed, Indeed I thought there was some confusion around the power consumption there. But I got your point, using the same load cycle you were consuming 5mA instead of the 12 before, right?

About my requirements, I am making a Lora node that will timestamp on the device side so the xosc will be running any way... The 16Mhz is merely selected to reduce further power consumption and it's enough to run my application, after I have looked through the problem with my hardware engineer we made some changes and using normal ticker it does now join on SF7. I just select xosc as an lpticker because I definitely don't want the main clock to be running at low power. This main clock should only start when the node wakes. I am not even sure if such a functionality is supported by embed?..... Sorry still figuring all out at best capacity.

I have been thinking about a workaround, Using only the lp_ticker for the RX windows on the high speed main clock and then manually putting the node to sleep only to wake up at RTC interrupt or external interrupt.

Bet even with the main clock in lp ticker it doesn't get me the right timing....

wimmatthijs commented 4 years ago

By the way I am packing my bags at the moment to go to Vietnam but I will try to drop my configs here this afternoon

wimmatthijs commented 4 years ago

Hi Guys,

Here's my clocks file and after that the Low power ticker Although i have been using different kinds of configs to 'play' around with. I didn't change any other configs, accept in the system_saml21.c file there is also a defined parameter #define __SYSTEM_CLOCK (16000000) which seems to influence some of the internal workings

conf_clocks.h file :

#include <clock.h>

#ifndef CONF_CLOCKS_H_INCLUDED
#define CONF_CLOCKS_H_INCLUDED

/* System clock bus configuration */
#define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT     false
#define CONF_CLOCK_FLASH_WAIT_STATES            3
#define CONF_CLOCK_CPU_DIVIDER                  SYSTEM_MAIN_CLOCK_DIV_1
#define CONF_CLOCK_LOW_POWER_DIVIDER            SYSTEM_MAIN_CLOCK_DIV_1
#define CONF_CLOCK_BACKUP_DIVIDER               SYSTEM_MAIN_CLOCK_DIV_1

/* SYSTEM_CLOCK_SOURCE_OSC16M configuration - Internal 16MHz oscillator */
#define CONF_CLOCK_OSC16M_FREQ_SEL              SYSTEM_OSC16M_16M  //Wim : doesn't make any difference if 8M or 16M
//#define CONF_CLOCK_OSC16M_FREQ_SEL              SYSTEM_OSC16M_8M //FIXME: USE to be SYSTEM_OSC16M_16M
#define CONF_CLOCK_OSC16M_ON_DEMAND             true
#define CONF_CLOCK_OSC16M_RUN_IN_STANDBY        false

/* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */
#define CONF_CLOCK_XOSC_ENABLE                  false //Wim : changed to true
#define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL        SYSTEM_CLOCK_EXTERNAL_CRYSTAL
#define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY      32000000UL //WHYYY is this 12MHz??? This is not external crystal but a SECOND external clocking signal???
//What is the difference between XOSC and XOSC32K??
#define CONF_CLOCK_XOSC_STARTUP_TIME            SYSTEM_XOSC_STARTUP_32768
#define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL       false
#define CONF_CLOCK_XOSC_ON_DEMAND               false
#define CONF_CLOCK_XOSC_RUN_IN_STANDBY          false

/* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */
#define CONF_CLOCK_XOSC32K_ENABLE               true
#define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL     SYSTEM_CLOCK_EXTERNAL_CRYSTAL
#define CONF_CLOCK_XOSC32K_STARTUP_TIME         SYSTEM_XOSC32K_STARTUP_65536
#define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT    true
#define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT  true
#define CONF_CLOCK_XOSC32K_ON_DEMAND            true//Fixme: was orginally True
#define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY       true //Fixme: was orginally false

/* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */
#define CONF_CLOCK_OSC32K_ENABLE                false  //WIM : orginal file has False
#define CONF_CLOCK_OSC32K_STARTUP_TIME          SYSTEM_OSC32K_STARTUP_130
#define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT    false
#define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT   false
#define CONF_CLOCK_OSC32K_ON_DEMAND             false
#define CONF_CLOCK_OSC32K_RUN_IN_STANDBY        false

/* SYSTEM_CLOCK_SOURCE_OSCULP32K configuration - Internal Ultra Low Power 32KHz oscillator */
#define CONF_CLOCK_OSCULP32K_ENABLE_1KHZ_OUTPUT    false
#define CONF_CLOCK_OSCULP32K_ENABLE_32KHZ_OUTPUT   false

/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
#define CONF_CLOCK_DFLL_ENABLE                  false //WIM : put back to true
//#define CONF_CLOCK_DFLL_ENABLE                  false //fixme: was originally True
#define CONF_CLOCK_DFLL_LOOP_MODE               SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED
#define CONF_CLOCK_DFLL_ON_DEMAND               false //WIM : set to true to see if Lorastack will use it, it doesn't
#define CONF_CLOCK_DFLL_RUN_IN_STANDBY          false

/* DFLL open loop mode configuration */
#define CONF_CLOCK_DFLL_FINE_VALUE              (512)

/* DFLL closed loop mode configuration */
#define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR   GCLK_GENERATOR_1
#define CONF_CLOCK_DFLL_MULTIPLY_FACTOR         (48000000 / 32768)
#define CONF_CLOCK_DFLL_QUICK_LOCK              false
#define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK   false
#define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP     false
#define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE      false
#define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE    (0x1f / 4)
#define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE      (0xff / 4)

/* SYSTEM_CLOCK_SOURCE_DPLL configuration - Digital Phase-Locked Loop */
#define CONF_CLOCK_DPLL_ENABLE                  false
#define CONF_CLOCK_DPLL_ON_DEMAND               false
#define CONF_CLOCK_DPLL_RUN_IN_STANDBY          false
#define CONF_CLOCK_DPLL_LOCK_BYPASS             false
#define CONF_CLOCK_DPLL_WAKE_UP_FAST            false
#define CONF_CLOCK_DPLL_LOW_POWER_ENABLE        false

#define CONF_CLOCK_DPLL_LOCK_TIME               SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_DEFAULT
#define CONF_CLOCK_DPLL_REFERENCE_CLOCK         SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_XOSC32K
#define CONF_CLOCK_DPLL_FILTER                  SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT
#define CONF_CLOCK_DPLL_PRESCALER               SYSTEM_CLOCK_SOURCE_DPLL_DIV_1

#define CONF_CLOCK_DPLL_REFERENCE_FREQUENCY     32768
#define CONF_CLOCK_DPLL_REFERENCE_DIVIDER       1
#define CONF_CLOCK_DPLL_OUTPUT_FREQUENCY        48000000

/* DPLL GCLK reference configuration */
#define CONF_CLOCK_DPLL_REFERENCE_GCLK_GENERATOR GCLK_GENERATOR_1
/* DPLL GCLK lock timer configuration */
#define CONF_CLOCK_DPLL_LOCK_GCLK_GENERATOR     GCLK_GENERATOR_1

/* Set this to true to configure the GCLK when running clocks_init. If set to
 * false, none of the GCLK generators will be configured in clocks_init(). */
#define CONF_CLOCK_CONFIGURE_GCLK               true

/* Configure GCLK generator 0 (Main Clock) */
#define CONF_CLOCK_GCLK_0_ENABLE                true
#define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY        true
#define CONF_CLOCK_GCLK_0_CLOCK_SOURCE          SYSTEM_CLOCK_SOURCE_OSC16M
//#define CONF_CLOCK_GCLK_0_CLOCK_SOURCE          SYSTEM_CLOCK_SOURCE_OSC16M //FIXME: USED to be SYSTEM_CLOCK_SOURCE_DFLL
#define CONF_CLOCK_GCLK_0_PRESCALER             1
#define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE         false

/* Configure GCLK generator 1 */
#define CONF_CLOCK_GCLK_1_ENABLE                true
#define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY        true     
#define CONF_CLOCK_GCLK_1_CLOCK_SOURCE          SYSTEM_CLOCK_SOURCE_XOSC32K
#define CONF_CLOCK_GCLK_1_PRESCALER             1
#define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE         false

Low power ticker file :

// Wim: we are using TC4 because TC4 is in the PD0 power domain, the other timers are in PD1
#define LP_TICKER_COUNTER TC4
#define LP_TICKER_COUNTER_IRQN TC4_IRQn
#define LP_TICKER_COUNTER_HANDLER TC4_Handler
#define LP_TICKER_CALLBACK_CHANNEL TC_CALLBACK_CC_CHANNEL0
#define LP_TICKER_STATUS_CHANNEL_MATCH TC_STATUS_CHANNEL_0_MATCH
#define LP_TICKER_COMPARE_CAPTURE_CHANNEL TC_COMPARE_CAPTURE_CHANNEL_0
#define LP_TICKER_COUNTER_PRESCALER TC_CLOCK_PRESCALER_DIV1
#define LP_TICKER_COUNTER_GCLK GCLK_GENERATOR_1
#define LP_TICKER_COUNTER_FREQUENCY 32768
#define LP_TICKER_COUNTER_BIT_COUNT 16
#define LP_TICKER_COUNTER_CC0_VALUE 0xFFFF    //Wim: orignally : 0xFFFF This is just an initializing value?? will be set automatically by driver?
elsalahy commented 4 years ago

@wimmatthijs I updated your comment and I will check out the configurations later today.

wimmatthijs commented 4 years ago

@elsalahy Thanks Ahmed, so about my earlier comment, is there anything i am trying to achieve so far that is not supported by mbed? thanks

elsalahy commented 4 years ago

@wimmatthijs I apologise for not providing my feedback earlier (vacation/work reasons). I will test some configs and get back to you (I will also reply to your earlier comments).

can you please provide your targets.josn in case you edited it (for tickless)?

wimmatthijs commented 4 years ago

Except for setting the Tickless macro I didn't make any changes 😉