Temporary buffer of 24 kB

27 Oct 2014

Hi all,

I'm working with the nrf51822 mbed platform. I need some way to temporarily store about 20-25 kB of data downloaded over BLE, and send it up to the mother board over an SPI link. What's the best way to approach this? I am guessing I'd need some way of storing data on the internal flash. Is there an easy way to do this?

What I've tried so far: 1. Sending every received packet (20 bytes) directly up over SPI. This is not reliable, several packets are missed or messed up. I have to use software SPI because for some reason hardware SPI doesn't like the pins (0,1,2,3).

2. Trying to allocate 24 kB as a global variable (char array) - obviously doesn't work as the chip has only 16 kB RAM (only 8k available to app), but thought I'll try anyway.

3. Trying to allocate a 2D array of char[1200][20], doesn't work either (as compiler wants to make it contiguous and then it's the same as #2 above).

What I'd like to try next: allocating 20 separate variables of 1200 bytes each so the compiler doesn't have to make them contiguous. I'm hoping that the chip will automatically page in the proper flash page on access.

Before I go further, I'd like to ask if I'm misunderstanding something obvious, or am I on the right track? Is there a better way to do this? I prefer not using the Nordic SoftDevice native API for accessing the flash storage, because I'm afraid of conflicting with the firmware OTA update mechanism which also uses internal flash as temporary storage.

Thanks!

27 Oct 2014

Not a direct answer to your question, but can you do any compression of the data, or store it in a format that is more compact? Compression like RLE is simple to implement and can compress and decompress very fast. If your data consists of text, then you can reduce the character set to only alphanumeric and save a two bits per character (25% less storage requirement). It all depends on the specific kind of data you're dealing with.

27 Oct 2014

If you want to write to the internal flash, please consider the flash access APIs offered by the soft-device: sd_flash_write() for instance. You'll also find sample use of these APIs in the pstorage module offered by the Nordic SDK.

If you can wait a short while (days), then Nordic might update their hardware and offer more RAM in their dev boards.

28 Oct 2014

Thanks for the replies Dan and Rohit.

Dan East wrote:

[..] can you do any compression of the data, or store it in a format that is more compact?[..]

Interesting idea. The data is binary in nature though, I just tried compressing and only achieved 10% reduction.

Rohit Grover wrote:

If you want to write to the internal flash, please consider the flash access APIs offered by the soft-device[..]

Yes that's the last and probably the only fool-proof option. I'm trying less involved methods first.

What I'm attempting now is to create a smaller buffer in RAM, about 1-2 kB, and pause the file transfer while the buffer is sent over SPI. Then resume the transfer. Will report here how it goes.

29 Oct 2014

So the RAM-based approach isn't working and I'm ready to use internal flash.

I tried using pstorage API but I'm unsuccessful. The chip becomes unresponsive at the first call to pstorage_init(). It's very hard to debug because I cannot trace the execution path easily.

So my next question: Has anyone used pstorage API on the nordic target before? Any gotchas to be aware of? I had to search for all usages of NEED_PSTORAGE preprocessor define and add a definition right above it, for it to compile and link properly.

29 Oct 2014

by the way, Nordic has just released an updated nRF41822 (which is compatible with the older nRF); and this new chip has 32KB of total SRAM. Taking 8KB away for soft-device, you're still left with around 24KB of SRAM. Perhaps that's the way to go for you.

29 Oct 2014

Can you put the SPI rate higher? Generally SPI should be able to go faster than BLE can go. But if you can pause the transfer that can work too.

Regarding flash, I don't know how often this has to be done? Because flash generally is 'only' rated to 10k write cycles. So if this happens once a day it is fine, if you do it once per minute then soon you don't have working flash anymore.

30 Oct 2014

please also note that the system is running on low-frequency external crystal clock by default. If your SPI driver requires higher frequencies, you'll need to enable clocks explicity.

30 Oct 2014

Thanks Erik & Rohit.

@Erik: I've tried SPI rate 1MHz (default) and even 10MHz. I think the primary reason of bad performance is that I'm using the SWSPI library instead of the built-in hardware SPI unit. I cannot initialise the hardware SPI unit with the pins I want (first 4 pins), don't know why, maybe mbed limitation?

The data is mostly configuration parameter that will probably not be modified frequently. Probably once a week I guess.

@Rohit: I will check out the nRF41822, though we've frozen the hardware design. As is usual, it comes to the software guys to fix problems ;)

Regarding the SPI running on low-freq clock - really? I didn't know that, does that mean the SPI max rate is 32kHz? On our hardware we don't have a LF crystal, I'm using a LF clk synthesized from the HF crystal (had to change the mbed nRF init code). Does this have any bearing on the performance? Also, is this still relevant if I'm using the SWSPI library instead? I've noticed it uses wait_us() calls for timing.

Much appreciate your responses.

30 Oct 2014

It does have a bearing on power efficiency. using a high frequency clock as default will significantly impact your power consumption. In our internal measurements, we discovered that power numbers dropped from an average of 800uAmps to under 10uAmps upon switching to the use of an external low-frequency clock.

Clock selection happens in the startup code.

One more thing, the nRF51822 is able to reconfigure almost any GPIO for any functionality. So if you need to use SPI but find that the mbed designated SPI pins are taken up by something else, then you're free to initialize your SPI object using any pin combinations. You're not limited to how mbed's pinmap chose pins for SPI peripherals.

31 Oct 2014

Hi Rohit,

Yes reconfiguring the SPI pins is what I'm looking at now. I've verified that using the hardware SPI module is way more stable than SWSPI.

But I'm having a hard time finding where exactly. I found this on the github page: https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/spi_api.c

I cannot find this file when I convert "mbed" into a library project to be able to modify its source code. Any hints?

edit: I should also add that I've tried just providing different pin names to the SPI class constructor, but for some reason this causes the dual-blink-of-death.

As for the clock source, we don't care much about power consumption because this particular product is AC-powered! :)

31 Oct 2014

using pin names like p2 should work just fine when initializing your SPI object.

31 Oct 2014

Unfortunately, it doesn't work. I've made a separate thread about this here: http://developer.mbed.org/forum/platform-39-Nordic-nRF51822-community/topic/5250/