|This email has been sent from a virus-free computer protected by Avast.
I have upgraded the SPI handler to interleave chatter with multiple SPI devices. The problem is that I only have one SPI device that I know works. I tried plugging in a uSD card and talking to it, but I’m not getting anything definitive back from it. It may be answering, or maybe not. I don’t want to write all that protocol code for talking to the uSD card yet.
I really wish I had some dumb-arse SPI device I could use to check out the code.
However it all seems to work, as far as it goes. I keep swapping between the DW and the uSD (working or not) and the DW keeps working just fine, so I think I’m going to declare victory and move on.
One thing I notices, and which disappoints me, is that the processor doesn’t sleep between character interrupts on the UART, or between bytes on the SPI. I’m not sure how much there is to be saved there, because the thread-suspend/recover code is probably quite substantial, and I suspect the scheduler doesn’t send things to sleep unless there is a promising delay coming up.
rtos_suspend = 1;
expected_time = os_suspend();
expected_time &= TIMER_MASK;
if (expected_time > 2)
prev_time = NRF_RTC1->COUNTER;
expected_time += prev_time;
(expected_time > TIMER_MASK) ? expected_time – TIMER_MASK : expected_time;
Need to clarify what I have done, because the next step is to extend this model to handle the SPI bus. I’m trying to prototype multiple threads accessing a common resource – the UART in this example. I also want to make sure that I can shut down the processor as much as possible while this is going on. This is not rocket science, just a RTX familiarization exercise.
I’m using RTX which is an RTOS provided by Keil, but available for free via ARM, and Nordic. It’s reasonably lightweight, and allegedly well-tried and tested. The question is can I get it to do what I need.
My test program needs to demonstrate use of a mutex to serialize access to a shared resource (the UART, as a stand-in for the SPI bus), and show that it can be driven from a variety of types of threads: the main loop, user threads, and a timer event handler.
The test program sets up five threads, three of which try to output to the UART in parallel. Here’s what each thread does:
- Following initialization crap, main() loops forever, alternately suspending itself for 1s, and then sending two “wakeup” inter-thread signals to the two user-threads, called Blinky1, and Blinky2.
- A timer-event handling thread is woken by the RTC every 100ms, and sends a text message to the UART. The message records the number of times the handler has been called.
- Blinky1, and Blinky2 simple wait for a signal from the main loop, and then try to send 10 text messages to the UART as fast as they are able.
- A fifth thread, “Idle”, runs only when all other threads are idle.
Each thread is assigned a LED which get’s turned on whenever it is the active thread.
- First, Blinky1, and Blinky2 never interleave their individual messages. Why is this?
- It is interesting how much of the time the Idle thread is running. Even though there is a lot of UART activity the Idle LED stays on almost all the time.
Here are the LED assignments, and below is a video showing the program running.
Managed to get a simple 2-thread Blinky program running under RTX. The lack of documentation about how to structure the project was the problem. There’s another configuration file, that has to be set up for each project.
Today I discovered that I have to make a new project for each different arrangement of drivers. It ought to be handled with a few compile-time defines, but that would make things even more ugly.
Now I’m seeing if I can create a thread to handle UART activity. that means creating a whole new project.
I have been exploring RTX. After having told David that there are all these real-time operating systems, but they all seem too complicated, I decided I should revisit, and check out that this is still the case. Better to use tried and trusted code, than re-do everything.
RTX is the RTOS that Keil push, and it is kind of available for free via Nordic. There is an example, for the 51422. I tried to drag the code over to Eclipse and compile it, but there are a bunch of defined constants, and some unwritten conventions that are getting in the way of compiling everything.
It’s been three days of struggle so far, and I’m really not getting to the bottom of it, so I’m beginning to think that it is a PITA.
One issue is that RTX assumes a particular kind of inbuilt timer, and the 51822 doesn’t have that, so it has to be fudged.
We have a “way” of licensing the Keil uVision v5.11 environment, but I’m not sure if that method will work for the latest 5.17 version – and then of course would it work for the next release? Another complete PITA to try that out, and then all the code would have to be ported to uVision.
For light relief from hacking, I looked over the eval board David gave me, and decided to see what was better about it, compared to the nRF51822. I see four significant advantages.
- Power consumption is about 5x (sic) better
- Double the memory.
- It looks like it might be possible to have multiple SPI channels active, so avoiding multiplexing.
- BLE TX/RX use 60% power, or better.
2.4 GHz transceiver
- -96 dBm sensitivity in Bluetooth® low energy mode (3dBm better)
- 1 Mbps, 2 Mbps supported data rates
- TX Power -20 to +4 dBm in 4 dB steps
- Single pin antenna interface
- 5.5 mA peak current in RX and TX (0 dBm) (was 9.7 Rx/8 Tx)
- RSSI (1 dB resolution)
ARM® Cortex™-M4 32-bit processor with FPU, 64 MHz
- 52 μA/MHz running from flash memory (was 275 μA/MHz running from flash memory)
- 48 μA/MHz running from RAM (150 μA/MHz running from RAM)
- Data Watchpoint and Trace (DWT), Embedded Trace Macrocell (ETM), and Instrumentation Trace Macro cell (ITM)
- Serial Wire Debug (SWD)
- Trace port
Flexible Power Management
- Supply voltage range 1.7 V to 3.6 V – (was 1.8 V to 3.6 V)
- Fully automatic LDO and DC/DC regulator system
- Fast wake-up using 64 MHz internal oscillator
- 0.4 μA at 3 V in OFF mode (was 0.6)
- 0.7μA at 3 V in OFF mode with 32 kB RAM retention (was 1.2uA)
- 1.9 μA at 3 V in ON mode, 32.768 kHz crystal oscillator and Real Time Counter running with 32 kB RAM retention
- 512 kB flash/64 kB RAM (256 kB flash /32 kB RAM)
Nordic SoftDevice ready
Support for concurrent multi-protocol
Type 2 Near Field Communication (NFC-A) Tag with wakeup on field
12-bit, 200 ksps ADC – 8 configurable channels with programmable gain
64 level comparator
15 level low power comparator with wakeup
32 General Purpose I/O Pins
3 x 4 channel Pulse Width Modulator units with EasyDMA
Digital microphone interface (PDM)
5x 32-bit timers with counter mode
Up to 3x SPI Master/Slave with EasyDMA
2x I2C compatible 2-Wire Master/Slave
UART (CTS/RTS) with EasyDMA
Programmable Peripheral Interconnect (PPI)
Quadrature Decoder (QDEC)
AES HW encryption with EasyDMA
3x Real Timer Counter (RTC)
QFN48 package, 6 x 6 mm
WLCSP package, 3.0 x 3.2 mm
A few nice additions, and a bunch of code-architecture changes that caused me to make a lot of changes to my code.
Slowly running through all my test programs to drag them into the new world, and to make sure I understand how all this new stuff works.
The usual tedious, head-scratching to figure it all out.
I already have a configuration file for each type of board. I use compile-time defines to decide which board file to use, and a bunch of other defines to decide what set of drivers to include in the compile – e.g. UART, or semo-hosting. Nordic have decided that all of these kind of constants should be held in a config file. Because each of my programs can be compiled with a different bunch of drivers, depending on what it does, I have introduced a new directory called “config” that contains the various configurations. Config has a subdir for each different configuration of drivers, so I have one called config/UART that sets up all the constants for the UART drivers. I expect I’ll have to do the same for SPI, TWI and so forth.
I am hopeful that this change will make it a helluva lot easier to multi-thread the code.
Your Doctor Doesn’t Want to Hear About Your Fitness-Tracker Data
Some patients are bringing troves of fitness-tracker data to their checkups, but the doctor might not find it all that helpful.
Yet while sensor-embedded wearables will need to get a lot more reliable before doctors find them useful, Sehgal acknowledges that devices such as the Apple Watch or the Polar heart-rate monitor have been useful because they’ve helped some people get more active. However, he says, “Where I think the rubber really meets the road is: can you take people with chronic disease and manage it with these devices? It’s still too early to say.”