Re: [riot-devel] How to properly use cortexm_sleep

2019-05-28 Thread Oleg Artamonov
Hi.Yes, but for emergency reboots only. Implementations: https://github.com/unwireddevices/RIOT/blob/loralan-public/cpu/stm32_common/periph/iwdg.c and https://github.com/unwireddevices/RIOT/blob/loralan-public/cpu/nrf5x_common/periph/iwdg.c For task scheduling on sleepy devices we use RTC-based timers with 1 ms resolution and 1 week max period (https://github.com/unwireddevices/RIOT/tree/loralan-public/sys/rtctimers-millis; on STM32L, we use regular HW RTC with SSR register, on nRF52 — "software" RTC implemented on top of HW RTT unit). -- Sincerely yours,Oleg Artamonov+7 (916) 631-34-90www.unwds.com   27.05.2019, 21:57, "Kees Bakker" :Hey Oleg,Are you using the watchdog? On 27-05-19 07:30, Oleg Artamonov wrote:Hi We do. On STM32L0, STM32L1, nRF52, etc. Checking for interrupt flags is absolutely useless here - 1) WFI checks for any relevant interrupt flags, 2) interrupt still can happen between check and WFI. -- Sincerely yours,Oleg Artamonov+7 (916) 631-34-90www.unwds.com   26.05.2019, 18:40, "Kees Bakker" :HeyIs there anyone using cortexm_sleep for a real application? And ifyes, would you want to share how exactly that's done?Let me say that I've never written a real application with RIOT, butI would like to. One of the important requirements is that the appmust be in sleep (deep sleep) and only wake up to do some work.And another requirement is to use the watchdog.That said, I'm familiar with the following Arduino pseudo code. while (forever) { do stuff disable interrupts if !certain condition __WFI(); enable interrupts }That "certain condition" is mostly checking that no WDT or RTC interruptoccurred before disabling the interrupts. These interrupts are handledby ISR's and they set a flag. This is a fairly common thing to do, I think.I don't see (or understand) how this can be achieved with RIOT-OS andcortexm_sleep. It is essential to check the condition AFTER disabling theinterrupts.--Kees Bakker___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel ___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel
,___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] How to properly use cortexm_sleep

2019-05-27 Thread Oleg Artamonov
Hi We do. On STM32L0, STM32L1, nRF52, etc. Checking for interrupt flags is absolutely useless here - 1) WFI checks for any relevant interrupt flags, 2) interrupt still can happen between check and WFI. -- Sincerely yours,Oleg Artamonov+7 (916) 631-34-90www.unwds.com   26.05.2019, 18:40, "Kees Bakker" :HeyIs there anyone using cortexm_sleep for a real application? And ifyes, would you want to share how exactly that's done?Let me say that I've never written a real application with RIOT, butI would like to. One of the important requirements is that the appmust be in sleep (deep sleep) and only wake up to do some work.And another requirement is to use the watchdog.That said, I'm familiar with the following Arduino pseudo code. while (forever) { do stuff disable interrupts if !certain condition __WFI(); enable interrupts }That "certain condition" is mostly checking that no WDT or RTC interruptoccurred before disabling the interrupts. These interrupts are handledby ISR's and they set a flag. This is a fairly common thing to do, I think.I don't see (or understand) how this can be achieved with RIOT-OS andcortexm_sleep. It is essential to check the condition AFTER disabling theinterrupts.--Kees Bakker___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] SAM Flash Read-While-Write

2019-01-25 Thread Oleg Artamonov
> so there will be no difference between using RWWEE and main flash at allFix: except interrupt handlers.If you have strict interrupt timings requirements and a lot of flash accesses, you should use RWWEE on SAML or second NVM bank on STM32L even with blocking flashpage driver. -- Sincerely yours,Oleg Artamonov+7 (916) 631-34-90www.unwds.com   25.01.2019, 11:46, "Oleg Artamonov" :The only difference between RWWEE and regular flash is that they implemented separate NVM controller for the RWWEE, so you can access it without blocking the main flash (and without blocking program execution if it is executed from flash). As for now, RIOT uses blocking flashpage driver (https://github.com/RIOT-OS/RIOT/blob/master/cpu/sam0_common/periph/flashpage.c#L118), so there will be no difference between using RWWEE and main flash at all. To utilize RWWEE advantage, driver must be interrupt-based.In all other aspects, there's no difference between RWWEE and main flash. If you need EEPROM emulation, same wear-leveling and read-modify-write algorithms should be implemented.P.S. STM32L0 and STM32L4 with dual bank NVM have the same functionality — both banks can be read or one bank read and another bank written simultaneously. See AN4767 for details — https://www.st.com/content/ccc/resource/technical/document/application_note/group0/ab/6a/0f/b7/1a/84/40/c3/DM00230416/files/DM00230416.pdf/jcr:content/translations/en.DM00230416.pdf-- Sincerely yours,Oleg Artamonov+7 (916) 631-34-90www.unwds.com   25.01.2019, 11:21, "Dylan Laduranty" <dylanladura...@gmail.com>:Hello Federico, IIRC, this flash can be use as a virtual EEPROM. Maybe It would be better to write a eeprom driver (like STM32 [1]) rather than add it to the flashpage driver ?I also think this memory is 8KB for SAML21J18 (not 8Kb), which is a lot :) As a side note: SAML21 also have 8KB of Low Power SRAM in addition to its 32 KB of SRAM I've never played with these additional memories but I'll be happy to help. Cheers,Dylan [1] https://github.com/RIOT-OS/RIOT/blob/master/cpu/stm32_common/periph/eeprom.c Le mer. 23 janv. 2019 à 14:27, Federico Pellegrin <f...@evolware.org> a écrit :Hi,Working on SAML21 based project it came to my attention also thepresence of an 8Kb additional flash that is called "Read-While-Write"(or RWWEE in the datasheet) that, as far as I understood, can beprogrammed and read in a very similar way to the normal flash. This iscurrently not supported anyhow in RIOT as far as I see. This is alsopresent in other SAM chips (a grep on the RIOT sam0 common includestells me saml21, samd21 and samr30).Well it's just 8Kb (in saml21 case) but a customer is asking about it ;)Before starting to fiddle with code I was wondering if any of youalready saw this or had intention to work on or had problems with thisor any information would be great :)On the other side I would also be interested in an opinion if theaccess to this facility should eventually be kept totally separatefrom the current (with some possible code redundancy, but with thepossibility no to include it into a project) or could be integratedinto the current flashpage driver (bringing some complication of thelogic of the current code)Thanks!Cheers,Federico___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel--Dylan Laduranty ,___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel,___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] SAM Flash Read-While-Write

2019-01-25 Thread Oleg Artamonov
The only difference between RWWEE and regular flash is that they implemented separate NVM controller for the RWWEE, so you can access it without blocking the main flash (and without blocking program execution if it is executed from flash). As for now, RIOT uses blocking flashpage driver (https://github.com/RIOT-OS/RIOT/blob/master/cpu/sam0_common/periph/flashpage.c#L118), so there will be no difference between using RWWEE and main flash at all. To utilize RWWEE advantage, driver must be interrupt-based.In all other aspects, there's no difference between RWWEE and main flash. If you need EEPROM emulation, same wear-leveling and read-modify-write algorithms should be implemented.P.S. STM32L0 and STM32L4 with dual bank NVM have the same functionality — both banks can be read or one bank read and another bank written simultaneously. See AN4767 for details — https://www.st.com/content/ccc/resource/technical/document/application_note/group0/ab/6a/0f/b7/1a/84/40/c3/DM00230416/files/DM00230416.pdf/jcr:content/translations/en.DM00230416.pdf-- Sincerely yours,Oleg Artamonov+7 (916) 631-34-90www.unwds.com   25.01.2019, 11:21, "Dylan Laduranty" :Hello Federico, IIRC, this flash can be use as a virtual EEPROM. Maybe It would be better to write a eeprom driver (like STM32 [1]) rather than add it to the flashpage driver ?I also think this memory is 8KB for SAML21J18 (not 8Kb), which is a lot :) As a side note: SAML21 also have 8KB of Low Power SRAM in addition to its 32 KB of SRAM I've never played with these additional memories but I'll be happy to help. Cheers,Dylan [1] https://github.com/RIOT-OS/RIOT/blob/master/cpu/stm32_common/periph/eeprom.c Le mer. 23 janv. 2019 à 14:27, Federico Pellegrin <f...@evolware.org> a écrit :Hi,Working on SAML21 based project it came to my attention also thepresence of an 8Kb additional flash that is called "Read-While-Write"(or RWWEE in the datasheet) that, as far as I understood, can beprogrammed and read in a very similar way to the normal flash. This iscurrently not supported anyhow in RIOT as far as I see. This is alsopresent in other SAM chips (a grep on the RIOT sam0 common includestells me saml21, samd21 and samr30).Well it's just 8Kb (in saml21 case) but a customer is asking about it ;)Before starting to fiddle with code I was wondering if any of youalready saw this or had intention to work on or had problems with thisor any information would be great :)On the other side I would also be interested in an opinion if theaccess to this facility should eventually be kept totally separatefrom the current (with some possible code redundancy, but with thepossibility no to include it into a project) or could be integratedinto the current flashpage driver (bringing some complication of thelogic of the current code)Thanks!Cheers,Federico___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel--Dylan Laduranty ,___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] size_t vs int usage

2018-06-27 Thread Oleg Artamonov
"and how come no one else is getting this error ?" Probably you are the first to build it with GCC 7.x :) It has stricter rules regarding variable types. -- Sincerely yours,Oleg Artamonov+7 (916) 631-34-90www.unwds.com   27.06.2018, 16:03, "Neil Jones" :I'm getting several failures on MIPS with size_t vs int usage in this PR (#9368) eg: Building application "tests_driver_ata8520e" for "pic32-clicker" with MCU "mips_pic32mx".

main.c: In function 'ata8520e_sigfox_cmd':
main.c:84:24: error: format '%d' expects argument of type 'int', but argument 3 has type 'size_t' [-Werror=format=]
"message length is %d", SIGFOX_MAX_TX_LENGTH, strlen(argv[2]));

IIRC size_t is unsigned so the error is correct, how did this code get upstream, and how come no one else is getting this error ?

I presume the fact that this PR add SPI support for MIPS(PIC32) these drivers are now getting built for MIPS, but how is this not a failure on other architectures ?

Should I fix these in this PR or create another one ?

Cheers,

Neil

 
 ,___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel
___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] AES crypto optimizations, speed and size

2018-01-02 Thread Oleg Artamonov
I believe results will be even better on most Cortexes, with nice performance 
gain with run-time T-tables on high-speed CPUs — as a rule, MCU core gains 
speed easier than flash, so 168-Mhz high-end Cortex-M4F may have same flash 
memory as entry-level Cortex-M0, limited at 20-30 MHz effective clock speed.

For example, STM32F4, flash wait cycles vs core clock: 
https://yadi.sk/i/SEI7mXtK3RAFxg, effective flash clock is 20 MHz. Same for 
Atmel SAM3U (https://yadi.sk/i/B4iA0ik33RAGVK, 24 MHz effective flash clock), 
same for EFM32, etc.

TI CC1310 and CC2650 have 8KB flash cache so maybe they'll perform better with 
in-flash T-tables, but that's a very specific case (not to mention that flash 
cache may be disabled and used as a regular RAM, and it often is, as there's 
only 20 KB of regular RAM available). Anyway, they have hardware AES 
accelerator too.

On low-end MCUs (20 MHz or less, 8-bit and 16-bit architectures) in-flash 
T-tables should be faster, but most such MCUs have a very limited amount of 
flash as well, so wasting 7 KB on T-tables is not an option anyway.

-- 
Sincerely yours,
Oleg Artamonov
+7 (916) 631-34-90
www.unwds.com



02.01.2018, 19:27, "Ludwig Knüpfer" <ludwig.knuep...@fu-berlin.de>:
> Hello,
>
> First of all thank you for sharing your insights!
>
> While I'm not entirely sure I get all the implications right away I do have 
> the following thoughts:
>
> I assume the results can not be generalized for the CPU architecture because 
> CPU clock and flash reading speed does vary independently.
>
> I do expect the result depends on the concrete product and configuration 
> you're looking at. A factor 2 memory access speed difference in between all 
> cortex m products does not seem very unlikely to me.
>
> Did you factor this in to your conclusion? Any thoughts?
>
> Cheers,
> Ludwig
>
___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] AES crypto optimizations, speed and size

2018-01-02 Thread Oleg Artamonov
* oops, sorry, here is the plain text version, no HTML *

Hello all,

Recently we did some AES encoding/decoding optimizations and experiments, and 
here I want to share results.

System: STM32L151CCU6 @ 32 MHz, arm-none-eabi-gcc 6.3.1, -O2

What we tried:
* existing option: FULL_UNROLL to unroll loops in aes.c
* new option: AES_CALCULATE_TABLES to calculate AES T-tables in runtime if 
possible instead of storing everything in the flash memory
* new implementation: AES_ASM (AES-128 only) using "All the AES You Need on 
Cortex-M3 and M4" code by Peter Schwabe and Ko Stoffelen, see 
https://github.com/Ko-/aes-armcortexm and https://eprint.iacr.org/2016/714.pdf

What we measured:
* firmware size (we have quite a big fw, but only AES options were changed 
between build)
* time to encode/decode a single AES-128 block, using xtimer_now (1 us default 
tick )

Ok, so here it comes (encoding / decoding, firmware size):
* default RIOT AES implementation (no unroll, T-tables in flash): 74 / 131 us, 
104.8 KB
* no unroll, run-time T-tables calc: 77 / 139 us, 97.1 KB

* full unroll, T-tables in flash: 64 / 108 us, 110.1 KB
* full unroll, run-time T-tables calc: 56 / 108 us, 102.1 KB

* assembler: 45 / 87 us, 104.6 KB

It seems that storing all T-tables in flash is quite useless, at least on 
Cortex-M MCUs: takes a lot of flash and performance improvement is 
insignificant or even negative. Unrolling loops with run-time T-tables provides 
25-30 % speed improvement over default settings _and_ firmware size reduction 
by 2.7 KB at the same time, so if you need fast and portable implementation — 
look no further.

Code: https://github.com/unwireddevices/RIOT/tree/loralan-public/sys/crypto 
(aes.c, aes_asm_cortexm.c)

I'm not sure about other hardware platforms, but as Cortex-M3/M4 is the most 
popular processor core now, I think default AES implementation in RIOT should 
be changed to run-time T-tables calculation to save flash.

P.S. 
https://docs.google.com/spreadsheets/d/1RwxomeVPoE-SngUHeRgPoI3ObQVgENsQQuIliMXDZNg/edit?usp=sharing
___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


[riot-devel] AES crypto optimizations, speed and size

2018-01-02 Thread Oleg Artamonov
Hello all, Recently we did some AES encoding/decoding optimizations and experiments, and here I want to share results. System: STM32L151CCU6 @ 32 MHz, arm-none-eabi-gcc 6.3.1, -O2 What we tried:* existing option: FULL_UNROLL to unroll loops in aes.c* new option: AES_CALCULATE_TABLES to calculate AES T-tables in runtime if possible instead of storing everything in the flash memory* new implementation: AES_ASM (AES-128 only) using "All the AES You Need on Cortex-M3 and M4" code by Peter Schwabe and Ko Stoffelen, see https://github.com/Ko-/aes-armcortexm and https://eprint.iacr.org/2016/714.pdf What we measured:* firmware size (we have quite a big fw, but only AES options were changed between build)* time to encode/decode a single AES-128 block, using xtimer_now (1 us default tick ) Ok, so here it comes (encoding / decoding, firmware size):* default RIOT AES implementation (no unroll, T-tables in flash): 74 / 131 us, 104.8 KB* no unroll, run-time T-tables calc: 77 / 139 us, 97.1 KB * full unroll, T-tables in flash: 64 / 108 us, 110.1 KB* full unroll, run-time T-tables calc: 56 / 108 us, 102.1 KB * assembler: 45 / 87 us, 104.6 KB It seems that storing all T-tables in flash is quite useless, at least on Cortex-M MCUs: takes a lot of flash and performance improvement is insignificant or even negative. Unrolling loops with run-time T-tables provides 25-30 % speed improvement over default settings _and_ firmware size reduction by 2.7 KB at the same time, so if you need fast and portable implementation — look no further. Code: https://github.com/unwireddevices/RIOT/tree/loralan-public/sys/crypto (aes.c, aes_asm_cortexm.c) I'm not sure about other hardware platforms, but as Cortex-M3/M4 is the most popular processor core now, I think default AES implementation in RIOT should be changed to run-time T-tables calculation to save flash. P.S. https://docs.google.com/spreadsheets/d/1RwxomeVPoE-SngUHeRgPoI3ObQVgENsQQuIliMXDZNg/edit?usp=sharing___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] GNRC with sleepy nodes

2017-11-21 Thread Oleg Artamonov
We have two xtimer-like RTC-based timers implemented on STM32L1: * https://github.com/unwireddevices/RIOT/tree/loralan-public/sys/rtctimers — rtctimers for ~1 second to 1 week delays, it uses regular RTC calendar* https://github.com/unwireddevices/RIOT/tree/loralan-public/sys/rtctimers-millis — rtctimers-millis for ~1 ms to 1 min delays, it uses RTC_SSR subseconds register (not available on some devices) and RTC calendar seconds register* RTC_SSR driver implementation — https://github.com/unwireddevices/RIOT/blob/loralan-public/cpu/stm32l1/periph/rtc.c P.S. On STM32L1, regular XTIMER can not run from 32 kHz clock in stop or standby mode, as all TIMx timers need APB1 clocking. Switching xtimer to RTC clock will degrade its resolution. -- Sincerely yours,Oleg Artamonov+7 (916) 631-34-90www.unwds.com   21.11.2017, 19:27, "Daniel Evans" <photonthun...@gmail.com>:First, I should add that I currently have a working samd21 low power implementation but to accomplish that I use rtt.c for my always running clock and then standby sleep the module whenever it gets to the idle task.  This is a hack and is not a clean implementation and means you don’t use XTIMER and no use of the nice built in protocols, I have my own hacked LoRa mesh network. Referring specifically to the samd21, which includes the samr21 and loosely the saml21, this is the path as I see it for getting low power working natively with RIOT: 1) Add a method to make setting up the generic clocks that includes run in standby and on demand options.2) Add flags for peripherals so that you can set the clock and run in standby3) Tweak XTIMER so that it can be run by a low power 32kHz clock when sleeping All of these things have been discussed and are in the works and are on the list but not currently top priority.  Low power is critical for my application and I am a little surprised it isn’t for more users, but I imagine others just hack around it as well? Hope that helps a little, Dan  On Nov 21, 2017, at 6:07 AM, Francisco Molina <francisco.mol...@inria.cl> wrote: >Issues #7743 and #7332 both discuss the problem.>>Dan I saw those issues but they only refer to the fact that xtimer doesn't run during sleep modes, is that the only issue? Cheers Francisco___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel,___devel mailing listdevel@riot-os.orghttps://lists.riot-os.org/mailman/listinfo/devel___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] Minimal MCU clock speed for using it as a border-router.

2017-06-13 Thread Oleg Artamonov
Hi

 

We have 6LoWPAN border routers running on Contiki OS and TI CC1310 @ 48 MHz — 
RAM is the main issue, 20k is enough for up to ~100 nodes in the network. No 
heavy traffic, though — except OTA fw updates, but we perform them one by one, 
not simultaneously.

 

I believe RIOT should have similar or lower hardware requirements, so a border 
router on STM32L4 should be fine.

 

--

Oleg Artamonov

+7 (916) 631-34-90

 <http://www.unwireddevices.com/> Unwired Devices LLC 

 

From: devel [mailto:devel-boun...@riot-os.org] On Behalf Of Martine Lenders
Sent: Monday, June 12, 2017 3:03 PM
To: RIOT OS kernel developers <devel@riot-os.org>
Subject: Re: [riot-devel] Minimal MCU clock speed for using it as a 
border-router.

 

Hi Neo,

 

regarding clock speed I'm not aware of any restrictions on the 
`gnrc_border_router` example (though there are some on space, which most STM32 
MCUs should fulfill). It might get slower and depending on the traffic it might 
get overwhelmed, but I think no one ever made any experiments for that 
specifically.

 

Best regards,

Martine

 

2017-06-12 12:42 GMT+02:00 Neo <n...@nenaco.de <mailto:n...@nenaco.de> >:

Dear RIOT-developers,

up to now I have worked with a beaglebone as a 6LoWPAN border router.

I want now to change to a microcontroller based system (STM32 family).

Now my question - what is the minimum clock speed of such a controller to be 
able to work as a border-router?

Thanks a lot!

Best regards,

Neo

___
devel mailing list
devel@riot-os.org <mailto:devel@riot-os.org> 
https://lists.riot-os.org/mailman/listinfo/devel

 

___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


[riot-devel] periph_clk_en on STM32L with -Os optimization may result in Hard Fault

2017-02-20 Thread Oleg Artamonov
Hi everyone

 

While working with low-power modes on STM32L1, we found a bug (?) in gcc
with -Os optimization - somehow it "optimizes" rather simple
periph_clk_en(bus_t bus, uint32_t mask) function in
cpu/stm32_common/cpu_common.c, so using it right after waking up from STOP
mode results in Hard Fault (for some reasons, in our firmware it is called
from clk_init(), and clk_init() is called right after __WFI() in LPM code,
as we need to switch MCU from 2 MHz MSI clock back to our default clock
settings).

 

Didn't dig it any deeper yet, but just for everyone to know:

 

-void periph_clk_en(bus_t bus, uint32_t mask)

+void __attribute__((optimize("O3"))) periph_clk_en(bus_t bus, uint32_t
mask)

 

fixes it.

 

--

Oleg Artamonov

+7 (916) 631-34-90

www.unwds.com

 

___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


[riot-devel] LPM, ADC, RTC etc. on STM32L1

2017-01-04 Thread Oleg Artamonov
Hi everyone,

We are using RIOT in a commercial project - LoRa modules based on Semtech
SX1276 transceiver and STM32L151CC MCU; previously, we had some experience
with Contiki and didn't like it at all. RIOT is much more attractive, but
unfortunately, there's only basic support for STM32L1: no low-power modes at
all, I2C driver hangs on any bus error including NACK, etc. Current RIOT
version doesn't even builds for STM32L1-based boards.

So we fixed it.

Here it is: https://github.com/unwireddevices/RIOT/tree/stm32l1_lpm

What has been fixed/improved:

1) Low-Power Modes (LPM). DEEPSLEEP with configurable core clock (default is
65 kHz MSI), STOP, STANDBY, switching to MSI clock, including LP-RUN mode.
GPIOs are automatically configured before entering sleep to minimize power
consumptions according to the rules:
a) if SPI interface is enabled, switch SCK and MOSI to DO, 0; NSS to DO,
1
b) if UART interface is enabled, switch TX to DO, 1
c) disable USART controllers (otherwise we received some garbage on
L152RE - but not on L151CC - while playing with GPIOs)
d) keep state of GPIOs configured for EXTI (external interrupts - you
may have some buttons etc. on them used to wake up MCU, so you don't want
them to be disabled during sleep)
e) keep state of GPIOs configured with
lpm_arch_add_gpio_exclusion(gpio_t gpio) and
lpm_arch_del_gpio_exclusion(gpio_t gpio) functions (e.g. you have some
peripheral devices attached to GPIOs and don't want them to change their
state during sleep)
 f) switch all other GPIOs to AIN, no pull-up, no pull-down

After waking up, all GPIOs will be restored to their original state.

NB: there's CPU_NUMBER_OF_PORTS define, it should be set according to your
MCU. For example, L152RE has 8 ports (GPIOA...GPIOH) while L151CC only 6
ports (GPIOA...GPIOE, GPIOH). Although for some reason they didn't mention
it in datasheet nor RM0038, accessing GPIOF on L151CC will result in Bus
Fault (but if you want to get rid of CPU_NUMBER_OF_PORTS, you can always
catch HardFaults manually).

NB: to get the best power consumption possible, you have to set digital
inputs of external devices to 0 or 1 if they don't have pullups (e.g. I2C
have external pullups as a rule, but SPI doesn't). Otherwise, if you just
switch corresponding GPIO to AIN, input connected to it will be in some
state defined by random noises, probably switching between 0 and 1 and
consuming few dozens microamperes (e.g. if you just switch SPI off and
corresponding pins to AIN with SX1276 connected to it, it will consume about
100-200 uA instead of expected 1 uA).

NB: it is possible to switch between core frequencies by calling
lpm_set(LPM_IDLE) (switch to MSI) and lpm_set(LPM_RUN) (back to default
clock, usually HSE or HSI). Timer frequencies and STDIO UART baudrate will
be recalculated and preserved if possible (e.g. don't expect 460 kbps UART
with 32 kHz MSI clock), but other clocks have to be fixed manually.

2) ADC. Support for special channels - on-chip temperature (not very useful)
and reference voltage (extremely useful).

NB: reference voltage is NOT reported, instead Vdd is calculated. As a rule,
you don't need to know Vref, but you have to know Vdd to convert ADC
readings to volts.

3) I2C. Two major problems solved:

a) inability to handle NACK. Default I2C driver _always_ waits for ACK,
so any problem on a bus will result in an endless loop. NACK is needed to
check if device is present on a bus, and some devices use NACK as part of
their regular protocol (SHT21, for example)
b) inability to use 2 devices on a same I2C bus. Each device tries to
initialize the bus, and initializing already initialized I2C bus results in
BERR. Simplest solution is to leave initialization as it is, but turn off
I2C before it.

4) RTC timer can be used to wake up CPU from SLEEP/STOP/STANDBY.

5) Small fixes. Proper GPIO operations (with intermediary variable and
without intermediary glitches), CMSIS updated, BRR register enabled for
HD/XL devices only, etc.

NB: everything is provided AS IS. Code was mostly tested on our own boards
with our own RIOT build. It builds for BOARD=nucleo-l1, but only some
functions were actually tested on it.

--
Oleg Artamonov
+7 (916) 631-34-90
www.unwds.com


___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel


Re: [riot-devel] STM32l1xx Internal ADC Channels

2016-12-21 Thread Oleg Artamonov
Hi Francisco,

 

We did it a while ago, it's quite easy.

 

https://github.com/unwireddevices/RIOT/blob/master/cpu/stm32l1/periph/adc.c

https://github.com/unwireddevices/RIOT/blob/master/cpu/stm32l1/include/perip
h_cpu.h

 

1)  In board.h configure internal ADC channels with GPIO_UNDEF pin

 

#define ADC_CONFIG {\

{ GPIO_PIN(PORT_A, 1), 1 },\

{ GPIO_PIN(PORT_A, 2), 2 },\

{ GPIO_PIN(PORT_A, 3), 3 },\

{ GPIO_PIN(PORT_A, 4), 4 },\

{ GPIO_PIN(PORT_A, 5), 5 },\

{ GPIO_PIN(PORT_A, 6), 6 }, \

{ GPIO_PIN(PORT_A, 7), 7 }, \

{ GPIO_UNDEF, ADC_VREF_CHANNEL}, \

{ GPIO_UNDEF, ADC_TEMPERATURE_CHANNEL}, \

}

 

2)  In adc.c do not initialize GPIO if it equals GPIO_UNDEF (lines
87-90)

3)  In adc.c before accessing internal lines, wake up sensor and Vref
(lines 171-174), after getting data disable it (lines 206-207)

 

That's it.

 

--

Oleg Artamonov

+7 (916) 631-34-90

www.unwds.com

 

 

___
devel mailing list
devel@riot-os.org
https://lists.riot-os.org/mailman/listinfo/devel