Oh bloody BUGGER!  I think I may have screwed myself.  The DW module on one of the TS06.3 boards has stopped responding to SPI.  

I tried the old test program "TS06_3_Check_C_nRF51822.hex:, that I archived on the google drive in July. It doesn't work for that board any more, but works OK on the 6.2 boards, and the other 6.3 board.  It says that the SPI is not responding.

I'm ashamed to say that I know I plugged in the JTAG wrongly on at least two occasions.  Once I fitted it back to front, and another time I fitted it left-justified, rather than right justified, so who knows what I might have done.
At the moment it's absence is not critical because with a bit of fiddling around, I can just revert to using the two 6.2 boards to develop the ranging code.  
I should drag out the scope and try to see if I recognize anything funny, but I think I'll have to wait till I get back from NJ.


//Mik
This email has been sent from a virus-free computer protected by Avast.
www.avast.com

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;
            NRF_RTC1->CC[0] =
                (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.

I have two interesting observations.  
  1. First, Blinky1, and Blinky2 never interleave their individual messages.  Why is this?  
  2. 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.

RTX

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.