[Tinyos-devel] TEP 101 - the proposal for ADC interfaces

Yuval Peduel yuvalpeduel at digitalsun.com
Mon Feb 14 13:33:26 PST 2005

I first heard about this proposal at Friday's TinyOS Technology Exchange 
and was disappointed
at what was outlined there. I then read the TEP and became even more 

My concerns fall into two areas:

1. As someone who does not know anything about the external ADCs or the 
MSP 430, I am very concerned that any Hardware Independent Layer spec be 
written in such a way that I as an ignorant user can safely write 
platform-independent code and that I as a developer on a new platform 
can write a compatible implementation.

2. As someone who has spent a good bit of time using the Atmel Atmega 
128 and its ADC unit, I'm very concerned about the fundamental approach 
this proposal is taking as it seems to be extending the TinyOS 1.1.x 
interface and implementation rather than looking forward to the HAA model.

Let's start with the HIL. This is supposed to be a hardware independent 
interface, yet understanding it seems to require detailed understanding 
of the MSP 430. Looking at this spec, I haven't the foggiest notion of 
how I would go about writing an application. Under what circumstances 
would I use reserve(), reserveContinuous(), and unreserve()? Under what 
circumstances would I use ADCMultiple as opposed to ADCSingle? What 
error conditions might I encounter and what error returns correspond?

Note also that as a developer of a compatible implementation, I would 
have to understand all of these issues thoroughly. I could not just play 
safe by using ADCSingle and ignore the "reserve" issues. This means that 
any HIL interface must be extremely well documented.

On to the Atmel Atmega 128, its ADC, your interfaces, and the current 
1.1.x implementations.

We've been using TinyOS since before the 1.1.0 release. In the first 
version we used, a getData call would check to see if the ADC was free 
and start the conversion if it was, but return FAIL if it wasn't. Very 
simple and very close to the hardware.

When we upgraded to a 1.1.x version of TinyOS, we found a new 
implementation with the same interface. This implementation tried to 
queue requests. Therefore, it introduced two problems:

1. There was no way of knowing whether a "successful" request was, in 
fact, currently being executed. This made it impossible to know whether 
the results were actually timely (an important issue in such 
applications as using the ADC to control radio transmission in the 
context of squelch).

2. When switching from a single-ended to a differential channel, the 
Atmel spec suggests waiting 125usec or throwing away a sample or two. 
With the original interface, if we wanted to read a differential 
channel, we could start a read at the task level and then at the 
dataReady signal throw that result away and start another, secure in the 
knowledge that no other code could get in to start a sample on a 
different channel. With the new implementation, another channel may have 
been requested before the dataReady, so even with the second request at 
the dataReady level, there was no guarantee that the two samples on the 
differential channel would be adjacent and hence result in a usable value.

As a result, we do not use the standard 1.1.x ADCM but have ported the 
old one (and cleaned it up). (Note the implications for relying on the 
code to understand the interface, a point related to the need for 
thorough documentation of HIL interfaces.)

Another concern with the current implementation is the handling of ADC 
Enable. The 1.1.x HPLADCC code keeps ADC Enable off by default. It turns 
it on at each getData, and then turns it off again at each dataReady. 
The result is that each ADC sample takes about twice as many cycles as 
it should, again an issue in such applications as CC1000 radio squelch 

Then there is the issue of "binding". Different hardware platforms use 
different voltage references. Some, like the mica, use external 
references; others use one of the two internal references. When one 
switches between one reference and another, a settling period is 
required (as when switching from a single ended to a differential 
input), though one might also argue that this generally makes no sense. 
More to the point, when the current code loads the hardware, it uses the 
value in the "binding" to specify the voltage reference. And when an 
application specifies the binding, it must, therefore, also specify the 
voltage reference. While this may be suitable at the HPL interface 
level, it clearly is not at the ADCControl level.

You note that the HPL interface should give access to the registers. The 
current HPLADC interface does not. For example, there is no way to reset 
the ADC in the middle of a conversion (important when going to sleep, as 
well as a safety net in case of errors); there is no interface to check 
if it is busy; etc. Similarly, there is no way to get around the ADC 
Enable problem other than by writing a replacement for HPLADCC.

In summary, none of the existing Atmel Atmega 128 ADC interfaces are 
well defined, and none of them are really suited as either an HPL or as 
an HAL interface. And even if the interfaces were adequately defined, 
their implementations would have to be changed enough so that much 
existing code would have to be rethought, if not rewritten.

Thus from what I can see, the idea that you want "To maintain 
compatibility with the existing code" makes no sense at all if you are 
serious about "aligning the ADC abstraction with the three-layer 
Hardware Abstraction Architecture (HAA)".

I think the HAA is a good idea and I'm glad to see it as your goal. ADCs 
are idiosyncratic enough that it is going to be very difficult, if not 
impossible, to actually integrate every possible, or even every 
reasonable ADC hardware and usage mode into such a model. But surely we 
can do much better if we do not tie ourselves to legacy code, and, 
instead, start with what we have learned about how ADC code should be 
written? If that requires throwing out the existing implementations, or 
at least letting them continue running only on TinyOS 1.x rather than 
2.x too, so be it.


More information about the Tinyos-devel mailing list