I am new to the DECAWAVE world and was looking for a little help.
When porting code for a new micro controller to run the examples given in the example library, do I need to change every aspect of the port.c and port.h file or just the functions that I need to run the individual example that i want to do. And if there is a better approach, please let me know.
I did a port to an ARM M0, and got all the examples to work in a few days, and I am not a hot programmer by any means.
You don’t actually need to implement the DW interrupt line, and so you can null out the mutex because the examples poll the status register. Of course in real code you will want to multi-thread.
Read the documents that explain how ranging works, and what the various library calls actually do. You’ll save time in the long run.
Here’s a ToDo list which I’m sure others will modify in the light of their experience:
Write some wrapper code writetospi and readfromspi for the native SPI driver code supplied by your uC vendor. (or… sigh - write your own drivers)
Demonstrate SPI works by getting the library function dwt_readdevid to work at default speed, then make it work at the highest speed you can. 8M in my case.
During debugging I managed to get the chip into a state where dwt_spicswakeup seemed not to be enough, so I ported the reset procedure that waggles and then disconnects the RSTN pin. It’s subtle so make sure you understand how to set the pins up correctly for the task.
The various flavors of tx/rx packet then worked repeatably, and ran overnight without a hitch.
The ranging demos have hard-coded constants for three important delay, sleep, and timeout parameters which I had to fiddle with to work with my super-slow processor.
General advice:
Write yourself some code to print out the status results in a form that’s easy to understand
Identify the critical parts of the code where your uC needs to respond quickly, and avoid doing slow stuff - like printing messages. LEDs are your friends.
Get the single-sided ranging to work first - fewer timeout issues.
Hope that helps.
I can second all the advice here. I wish someone had written this concise of a list when I started my project!
It is also useful to link the lcd_display() function to a simple printf() if you’re working with a console. Furthermore you can link reset_DW1000() to dwt_softreset() at least until you run into the issue mentioned above. Finally you can link deca_sleep() to delay() or something similar if it’s useful. This way you can run the example code as is and not modify any code in the decadriver or examples folder.
I would add that if you’re working with an OS, not only will the microcontroller response be slow (~5x slower than example code in my case) it will also be inconsistent. I would recommend using the HPDWARN bit in the SYS_STATUS register to protect against random long delays when turning a receive around into a transmit (in ranging examples). Otherwise you need to increase the timing parameters even further or a ranging measurements will eventually hang (~1/1000 do this for me).
#6 on a list would be adding interrupts and multi-threading. I am starting this now. Does any have some example code they wrote to illustrate use of dwt_isr() and an example of an RX and TX callback function?
Just for information I am using a TI Stellaris Launchpad LM4F1205HQR. I am curious to see if any one has tried to use this processor or any other TI processor?
Thanks for the compliment Brian. I agree with all your excellent suggestions. The comment about using an OS is particularly useful, because delays cause all sorts of mysterious errors that are hard to diagnose until you get familiar with how it all works. But that’s traditional fare for real-time systems I guess.
I too am multi-threading my code. I want an architecture that will work across a range of processor speeds, and having a robust process model is important to me, so I have gone for reliability/simplicity first, and efficiency second. Nothing more useful to report yet.
Sean, I’m not a TI RTOS expert, but if you develop your code by cobbling onto some RTOS “hello world” example you will have proven drivers, timers, queues and mutexes available when you need them, and a non-disruptive path to a more complex architecture when you need it.
I don’t know your level of experience so I may be teaching you to suck eggs, or something that sounds like rocket science. I’m old school and use a lot of printf messages, but as I said earlier that can really screw up timings in a real-time environment, and lead to some mysterious behaviors. One reason for DW using an LCD to display printf messages is that it tends to minimize delays (unless it emulates a slow serial interface). But adding an LCD takes time. Fortunately many debuggers have the ability to ambush standard IO and send it up the debug wire to your IDE, or a terminal emulator. Debug hardware interfaces contain their own internal buffers that make everything go a lot faster (c.f. SEGGER RTT Viewer for example), It might be worth your time to look for similar hooks in your TI system.
Maybe someone else knows the TI landscape well enough to know if this is a bum steer?
Thanks for all the pointers guys! It has been really helpful! I have not gotten it working yet, I am still working on getting the SPI read and write functions set properly, I have a question regarding the slave select. If I pull up slave select between each octet will that screw up everything or does the slave select have to remain down for the entire header and body transmission?
You cannot pull it up. Needs to stay low for the whole transaction, as each time the CS goes high the SPI interface in the DW1000 is reset and the next byte will be considered first byte of the header …
You said we need to start by writing some wrapper code to get the spi functions working properly. Aren’t there functions for this included in the decawave drivers? Could you elaborate on what you mean by this? Sorry, I’m very new to microcontrollers and SPI.
The decadriver software wants to communicate to the chip using SPI. The software does not know how to do this on your specific chip / platform / driver. You have to write a function that does this for the software: a wrapper.
I am trying to port the code to the PSOC 5LP processor. (which is a Cotex-M processor using the kiel gcc compiler)
It appears the porting should be straight forward.
So far I have the SPI and mutex functions and IRQ compiling ok.
The only thing I am unsure of now is the clocking. Do I need to set up a custom system clock or do I only need to change a constant in the API that determines how fast the processor is running?
Hi, alls,
I am a beginner in this area. I don’t have too much electronic background. I have purchased several DWM1000 chips and a few Arduino boards. Then I realize my naive that I don’t know how to connect them together. Do I need an adapter board? Wish someone could give me some suggestions.