My program has allegedly filled up memory.  This is actually a message from the linker telling me that when I try to load the program into the chip that it will not fit.  It deduces this from the “loader script”  I gave it which is for an nRF51422_xxAA chip.   

  • AA is 256K flash/16K sram
  • AB is 128K flash/16K sram
  • AC is the new 256K flash/32K sram variant.

I kind of remember that we got some of the new bigger modules, but I can’t recall now.  I looked back through the blog and saw this comment from David.

If you exceed the 16k RAM barrier then you will only be able to use TS06.3. If you need more I can always send them to you.

I compared the TS06.2 and .3 modules and they have the same markings., except for the paint blob.


I suppose that I’m just being lazy because I could try to write some code that will load into any chip, and can scan memory to see where it runs out.  That’s a bit of a fag, but might be the best way to be sure.​

Today I have been battling with Eclipse.   My challenge is to try and fit together the three suites of test programs I have developed independently.

I have a suite of programs that test out various aspects of RSX, another suite that exercises the DW, and another that fiddles about with BLE.    They each have there own way of doing things, and the challenge is to figure out how to weave them all together.

Eclipse is being a pain, and seems reluctant to find header files.  I’ve spent all day just doing configuration stuff.

On Fri, Jan 29, 2016 at 8:18 PM, David Carkeek <> wrote:

The IMEC WUR consumes 310uW. That’s too much to leave it on all the time. If it’s going to duty cycle then time synchronization will be needed anyway. What’s the win? It could stay on for longer periods but you still have some degree of time synchronization to contend with, unless I am missing something.

This is an interesting chip I found tonight.
The receiver draws less than 1.9mA at 1.2V-1.8V.  That is 2280 uW, 7x the IMEX WUR, but it’s a full radio, and still not a lot of power. The nRF52 receiver draws min 5.8mA in non-BLE mode. The minimum operating voltage is 1.7V. I don’t know if the current would be the same at 1.7V but assume it is. 1.7V * 0.0058 = 9860 uW, 32x the IMEC WUR power or about 4x the ZL70250.
The ZL70250 comes in a 3mm x 2mm package, so it’s small. It has an SPI interface so it could be controlled by the M4 in the nRF32. This radio could be added without taking up much space. Do you think it could do the network building/meshing? SInce it’s 700-900 MHz it would go through walls easier.
It would be interesting to know if the IMEC device is going to be just a WUR or if it will be a transceiver, and its frequency.


Yes, and it sniffs too.  Designed for body-area networks.  I wonder how big the antenna is.  36 pins?  Uses both SPI and IC simultaneously?

Does it use a BGA?  Is there an eval board?

The ZL70250 is not recommended for new designs. Please see our new Sub-GHz Radio Transceivers.
ZL70251 is more recent, but perhaps not the same thing?

Sniffing increases latency, but for our kind of app a second or two of latency per hop might be just fine.   Imagine that it takes 3-4 hops to get back to the WiFi router, then it might be 4 seconds before a connection is made – hardly a calamity.  If all the nodes are off except for this radio, and then they all wake up, do their meshing thing, and go to sleep, that might not be so bad either.  

A BLE beacon allegedly lasts for years (as long as it doesn’t beacon too often).

White paper:

Has a convenient list of the competitor’s products and their power consumptions. Need to look at the TZ1030 and EnOcean.

Inline image 1

Other radios


is only 3 meter transmission distance.

Inline image 1


33mA receive current.

Dear Mik,

This is Li Huang, responsible for the business development of imec’s ultra low power radios. imec is still working within the wake up radio, and collaborating with a big semiconductor company to commercialize it.
Thus, we can consider a two phase project. In the first phase, as an early access to future chips, imec can provide the demo boards for your evaluation. In the second phase, you can engage with imec’s partner to develop your final product.
Do you have any specs on the radio?
Best Rgs,
Li Huang, PhD
Business Development Manager
Perceptive Systems for the Internet of Things
Mobile: +31 6 3104 4404
Mail address:  Holst Centre / imec the Netherlands  –  P.O. Box 8550  –  5605 KN Eindhoven  –  The Netherlands
Visiting address:  Holst Centre / imec the Netherlands  –  High Tech Campus 31  –  5656 AE Eindhoven  –  The Netherlands
Read the monthly imec magazine:
Connect with us:
Mik: <obvious questions>
Hi Mik,

Thanks for your clarification. Imec’s radio has a continuous power consumption of 310uW (including AFE and DBB) with the sensitivity ~-70dBm. Assuming the crystal oscillator is shared with other and its power is not considered in the wake up radio, the power can be reduced to by half. Without power conversion unit, the power can be even lower.  Do they meet your spec?
If you are interested, we can further set up a call to discuss the details. However, I am currently out of office and will be back on Feb. 10. It would be good if we can still contact via email and have a call after Feb. 10. By the way, will you join WMC? We can also discuss then.
Best Rgs,

David Carkeek

Jan 27 (2 days ago)

to me
I think this is not a stand-alone radio. I think it’s IP that can be purchased to put on your die. Of course this is out of the question for us.

But we do need to ask, since he said he trying to commercialize it. Maybe they *will* try to make a separate WUR device.

Mik Lamming

9:54 AM (2 hours ago)

to David
Can you explain the implications of 310uW and -70dBm for me in terms that I might understand?   e.g A CR2032 for a week, but an antenna the size of a bus?

David Carkeek

11:54 AM (9 minutes ago)

to me
310uW @3V-> 0.000310/3= 103uA or 0.103 mA

That matches this chart closely.
Inline image 1
The battery would last 900 hours (one month) if the radio was on continuously. It’s not good enough.
I think -70dBm refers to the receiver sensitivity. It’s not really good.
The WUR sensitivity is much less than the BLE radio. This would be a problem.
If we had the WUR radio we could make use of it through some sort of hybrid operation but it would not be good enough to reliably wake up the system at the edges of its range.
But then there’s the high current consumption to worry about. It’s too high for battery-only operation but with energy harvesting it could be low enough.
David,  That’s an excellent analysis pitched exactly at my pea-brain’s level.  Thanks.
I think we can just sit on the margin and wait to see if something happens?
OK… so I have 2W ranging working, and I have kinda calibrated the antenna.  The range is a bit disappointing, with both .02 and .03 versions.  I think there is an app note on how best to calibrate the antenna.
I have pretty much random config parameters plugged into the code, and I think they might not be best for our situation.
The “Device Driver API Guide”, the parameter to the dwt_configure is a structure of containing a lot of values.  I am using, what they call “mode 3”.

/* Default communication configuration. We use here EVK1000’s default mode (mode 3). */
static dwt_config_t config = {
    2,               /* Channel number. */
    DWT_PRF_64M,     /* Pulse repetition frequency. */
    DWT_PLEN_1024,   /* Preamble length. */
    DWT_PAC32,       /* Preamble acquisition chunk size. Used in RX only. */
    9,               /* TX preamble code. Used in TX only. */
    9,               /* RX preamble code. Used in RX only. */
    1,               /* Use non-standard SFD (Boolean) */
    DWT_BR_110K,     /* Data rate. */
    DWT_PHRMODE_STD, /* PHY header mode. */
    (1025 + 64 – 32) /* SFD timeout (preamble length + 1 + SFD length – PAC size). Used in RX only. */

​I don’t think I am using “smartPower”  (

​)  and I am not setting the power at all (
).  There is a useful note in the explanation of the latter function which explains power regs.

It would be nice to understand what matters, and what would be best for an indoor environment.  

Figuring out the best settings is not on my critical path

​, because it’s kinda working.  I think it requires some research of the various DW App notes, and some knowledge of physics to figure out what matters.

I just got two-way ranging working.  It was a struggle because I had to mess around with some of the timings.

The original code, designed to run on an M3 waits for 2600 units before responding to the ranging packet.  The M0+ won’t work at all with any value less than 6000.   Equally, the “no-response” timeouts have to be extended from 3300 to 7500 to make it listen long enough.  I can probably fine-tune these a bit.   I assume this is mostly down to the processor speed, but I can’t tell for sure.

One important thing is that the transceiver code must not be interrupted while it is constructing the response packet, or its peer transceiver will time out.

Measurements are OK, but not great.   You can just about see the laser dot on the wall below the far (anchor) TS06.3, and the laser rangefinder, and ranging TS06.3 in the foreground.  I think they are roughly on par with the BeSpoon unit.


Laser rangefinder
(The length of the rangefinder is included in it’s measurement,
so we should subtract about 6cms to the antenna = 3.2m)
DW Measurements

Some of the inaccuracy could be down to the antenna delay calibration – there’s none!

The maximum range is not great.   I can just about get through the wall and into the kitchen, a distance of about 4.5 meters.  The TS seems quite sensitive to antenna orientation.

Sensitive to antenna orientation

I ran the same code on the TS06.2 units, and the range estimates were similarly inaccurate, though better when close.  The maximum range was about the same as the 03 units, and they too were sensitive to orientation.


I’m not sure if I did this quite right, but I think I calibrated the antenna delay.   I did it by using identical types i.e. TS06.2 to TS06.2  and jiggled the antenna delay parameters until I could plot a straight line and figure out the equation.  Then I used the equation to find a better calibration parameter.   I did it for both TS06.2 and TS06.3 and got results that settle to within about 10cms.   I only calibrated it over a short physical distance so I expect it probably isn’t good for longer distances.
After calibration, the test I showed at the top of the page settled at about 3.06 meters, or about 14cms short.

Here is an interesting bit of code:

poll_rx_ts = get_rx_timestamp_u64();
resp_tx_time = (poll_rx_ts + (POLL_RX_TO_RESP_TX_DLY_UUS *                                                    UUS_TO_DWT_TIME)) >> 8;
uint32_t resp = dwt_starttx(DWT_START_TX_DELAYED);

This fragment of code is executed in the receiver application, when it receives the initial request for for ranging.  The receiver sets up the DW to send back a response message after a fixed delay.  It does this by reading the timestamp recording the instant the packet was received.  Then it adds on a fixed delay, and then tells the DW to transmit at that time.
In my code the dwt_starttx function returns an error indicating that the transmit delay isn’t long enough.
In the code intended to run on the ARM M3 the constant POLL_RX_TO_RESP_TX_DLY_UUS is 330 (uS).  In my M0+ code it has to be a lot larger.  My code is not optimized and so far I have found that the value needs to be:  2200 > POLL_RX_TO_RESP_TX_DLY_UUS > 2300 
On the init side I will have to extend those values too.  No idea what to set there, but obviously bigger.

/* Delay between frames, in UWB microseconds. Was 140 */
/* Receive response timeout. See NOTE 5 below. Was 210 */
#define RESP_RX_TIMEOUT_UUS 3000


This is single-sided one-way ranging and it is very inaccurate, though better than Nanotron, and RSSI.  Obviously my random response timings are very long, which is a substantial source of error, and my antennae delays are not calibrated.
I’m noticing that DW packet exchanges that require a fast turnaround are at best twitchy, and often flat out fail.  I’m wondering if the task switch between SPI driver and the DW app. is just taking too long.  That would be a disappointing development, having sunk so much effort into RSX.

DC: Excuse my ignorance. I’m going to ask a bunch of simpleton questions so you can see what’s going on in my mind. You don’t need to answer them.

ML: They’re not stupid questions.  They are exactly the questions I should be answering to figure out the problem.

What does RSX stand for?

RSX – dunno (probably Real Time eXecutive), the RTOS that I’m using for task scheduling etc.

What’s difference between a fast-turnaround packet and a non-fast-turnaround packet? Why is there a need for a fast turnaround?

I didn’t explain that well. It’s my nomenclature.  Think of a simple P2P example, e.g. Peer-A: “Please turn on the liight”.  Peer-B: “OK, done it”.   Normally the uC listens to the DW for a packet, then it reads it in from the DW buffer, parses “pls turn on the light”, executes it, and then may/may not send an “OK, done it” reply.  I call that slow-turnaround.  For ranging packets the turnaround time has to be precise, so it can be subtracted from the total roundtrip time.  Since the inbound, and outbound packet formats are standard, the DW can be told to handle that transaction autonomously, without involving the uC till after it is done. – i.e. fast-turnaround.  At least that used to be my theory until I saw the code.

If this is a problem, is it because of a DW hardware requirement or the uC’s inability to complete tasks fast enough? Or both? What is the packet turnaround time requirement?

At the moment I don’t know what the problem is, or what the turnaround requirement is.  The turnaround time (TT) is a parameter.  The maximum TT is perhaps discussed in the manual, or maybe I have to use a scope to figure it out.  But hopefully I can just fix it.  The longer the TT, the more likely that the whole ranging sequence gets trashed by some 3rd party wireless traffic, so there is a heavy incentive to make it short.   To figure this all out I need an extended period of uninterrupted time to figure out exactly what’s going on (Like B going out of town for a week!).  The only thing I know is that the response packets are being sent, because I see the “sent” confirmation, but the peer-receiver is issuing a timeout (TO) – which indicates that the sender took too long to respond.  I think the TO is a parameter too.  One option is simply to extend the TT and TO parameters and see if that makes the problem go away.

How long does it now take for a packet turnaround to occur?

Dunno yet.  

What is the time requirement for the packet turnaround? What is happening while the packet is being turned around?

In theory it is a short fixed amount within the limits of the DW timer resolution(15ps) and width (40bits) ~ 16s.  This is not as straightforward as it sounds because the timer wraps, and when it does the DW generates an interrupt and abandons the sequence.  (Why?)  The thing I don’t get, is why the uC needs to be involved at all, but in the demo code it clearly is.  That’s a thing I have to understand, along with a few other things.  It looks like the uC extracts the arrival time from the DW, computes the required response time, and stuff both numbers in the outgoing packet.  Clearly it would make a lot more sense for that to be done automatically by the DW hardware, but it appears not to be the case.

How much time does it take now to switch tasks between the SPI driver and the DW app? Why do the tasks need to be switched? Is it because the uC can do only one thing at a time?

Task switch time?  That’s another thing I don’t know, and need to find out.   The standard architectural approach is to make all of the drivers a separate task, so the application can conceivable wait for several streams of IO to complete.  A rather bogus example would be waiting for some long-winded SPI IO to finish, unless there was some other IO activity – a key press signalling to abort the SPI activity.  I think I can redesign the architecture to get rid of the SPI task, so there isn’t a task switch, but I’d like to know that’s the issue before I head down that rabbit hole.

Would it help to have a uC dedicated to DW tasks? Is this a problem because we are relying on the Nordic to do too many things?

A processor dedicated to SPI/DW tasks would be good.  Indeed I think that’s what BeSpoon do, which theoretically makes their uC interface a lot simpler.  But I can probably achieve the same thing by disabling task switches until DW activity finishes.  Our environment has fixed-function tasks so we don’t have to cater for tasks that have unknown IO requirements by providing the general solution I have actually implemented.

Good questions David.  You have made me reflect on my debug strategy.

Presentation collaterals from David.

The Shine package is a bit naff.
David’s tear-down slides are very interesting.
Hard to make out the vibrator.  Is it that flat square package?
6 months on 1 CR2032 is very impressive.
The A4WP support is interesting – why do they need it when the CR2032 lasts 6 months.  
Says the Ambiq Apollo is an M4 processor, and is very interesting.  30uA/MHz executing from flash is great.  And only 100nA with RTC running!
DA14581 does remote charging – why when the battery lasts 6 months – I’m confused.
What does slide on IMG_4612 mean.  Totally over my head.
DA14581 TX: 3.4 mA, RX: 3.7 mA (with ideal DC-DC) ??