[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/msp430/adc12
AdcStreamP.nc, NONE, 1.1 Msp430Adc12DMAWireC.nc, NONE,
1.1 WireAdcStreamP.nc, NONE, 1.1 AdcP.nc, 1.4,
1.5 AdcReadStreamClientC.nc, 1.4, 1.5 HplAdc12P.nc, 1.4,
1.5 Msp430Adc12ClientAutoDMAC.nc, 1.5,
1.6 Msp430Adc12ClientAutoDMA_RVGC.nc, 1.6,
1.7 Msp430Adc12ClientAutoRVGC.nc, 1.6, 1.7 Msp430Adc12ImplP.nc,
1.5, 1.6 Msp430Adc12MultiChannel.nc, 1.2, 1.3 README.txt, 1.6, 1.7
Jan-Hinrich Hauer
janhauer at users.sourceforge.net
Mon Apr 7 02:41:58 PDT 2008
Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv23244/tos/chips/msp430/adc12
Modified Files:
AdcP.nc AdcReadStreamClientC.nc HplAdc12P.nc
Msp430Adc12ClientAutoDMAC.nc Msp430Adc12ClientAutoDMA_RVGC.nc
Msp430Adc12ClientAutoRVGC.nc Msp430Adc12ImplP.nc
Msp430Adc12MultiChannel.nc README.txt
Added Files:
AdcStreamP.nc Msp430Adc12DMAWireC.nc WireAdcStreamP.nc
Log Message:
- bugfix: ReadStream did not work with a "usPeriod" parameter > 0xFFFF (the fix uses/adapts the atmel ReadStream code)
- bugfix: overflow interrupts were not handled/signalled correctly from the HAL
- fixed the wiring for DMA, which was not correct when used by more than one client
- polished the HPL and added some comments
- introduced a compile time warning when DMA/TimerA is accessed (will be removed once we decide how these components are arbitrated)
--- NEW FILE: AdcStreamP.nc ---
/* $Id: AdcStreamP.nc,v 1.1 2008/04/07 09:41:55 janhauer Exp $
* Copyright (c) 2005 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*
* Copyright (c) 2004, Technische Universitaet Berlin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of the Technische Universitaet Berlin nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* Convert MSP430 HAL A/D interface to the HIL interfaces (adapted atmega code).
* @author David Gay
* @author Jan Hauer <hauer at tkn.tu-berlin.de>
*/
#include "Timer.h"
module AdcStreamP {
provides {
interface Init @atleastonce();
interface ReadStream<uint16_t>[uint8_t client];
}
uses {
interface Msp430Adc12SingleChannel as SingleChannel[uint8_t client];
interface AdcConfigure<const msp430adc12_channel_config_t*>[uint8_t client];
interface Alarm<TMilli, uint32_t>;
}
}
implementation {
enum {
NSTREAM = uniqueCount(ADCC_READ_STREAM_SERVICE)
};
/* Resource reservation is required, and it's incorrect to call getData
again before dataReady is signaled, so there are no races in correct
programs */
norace uint8_t client = NSTREAM;
/* Stream data */
struct list_entry_t {
uint16_t count;
struct list_entry_t *next;
};
struct list_entry_t *bufferQueue[NSTREAM];
struct list_entry_t **bufferQueueEnd[NSTREAM];
uint16_t *lastBuffer, lastCount;
norace uint16_t *buffer, *pos, count;
norace uint32_t now, period;
norace bool periodModified;
command error_t Init.init() {
uint8_t i;
for (i = 0; i != NSTREAM; i++)
bufferQueueEnd[i] = &bufferQueue[i];
return SUCCESS;
}
void sampleSingle() {
call SingleChannel.getData[client]();
}
command error_t ReadStream.postBuffer[uint8_t c](uint16_t *buf, uint16_t n) {
if (n < sizeof(struct list_entry_t))
return ESIZE;
atomic
{
struct list_entry_t *newEntry = (struct list_entry_t *)buf;
if (!bufferQueueEnd[c]) // Can't post right now.
return FAIL;
newEntry->count = n;
newEntry->next = NULL;
*bufferQueueEnd[c] = newEntry;
bufferQueueEnd[c] = &newEntry->next;
}
return SUCCESS;
}
task void readStreamDone() {
uint8_t c = client;
uint32_t actualPeriod = period;
if (periodModified)
actualPeriod = period - (period % 1000);
atomic
{
bufferQueue[c] = NULL;
bufferQueueEnd[c] = &bufferQueue[c];
}
client = NSTREAM;
signal ReadStream.readDone[c](SUCCESS, actualPeriod);
}
task void readStreamFail() {
/* By now, the pending bufferDone has been signaled (see readStream). */
struct list_entry_t *entry;
uint8_t c = client;
atomic entry = bufferQueue[c];
for (; entry; entry = entry->next)
signal ReadStream.bufferDone[c](FAIL, (uint16_t *)entry, entry->count);
atomic
{
bufferQueue[c] = NULL;
bufferQueueEnd[c] = &bufferQueue[c];
}
client = NSTREAM;
signal ReadStream.readDone[c](FAIL, 0);
}
task void bufferDone() {
uint16_t *b, c;
atomic
{
b = lastBuffer;
c = lastCount;
lastBuffer = NULL;
}
signal ReadStream.bufferDone[client](SUCCESS, b, c);
}
void nextAlarm() {
call Alarm.startAt(now, period);
now += period;
}
async event void Alarm.fired() {
sampleSingle();
}
error_t nextBuffer(bool startNextAlarm) {
atomic
{
struct list_entry_t *entry = bufferQueue[client];
if (!entry)
{
// all done
bufferQueueEnd[client] = NULL; // prevent post
post readStreamDone();
return FAIL;
}
else
{
bufferQueue[client] = entry->next;
if (!bufferQueue[client])
bufferQueueEnd[client] = &bufferQueue[client];
pos = buffer = (uint16_t *)entry;
count = entry->count;
if (startNextAlarm)
nextAlarm();
return SUCCESS;
}
}
}
void nextMultiple(uint8_t c)
{
if (nextBuffer(FALSE) == SUCCESS){
msp430adc12_channel_config_t config = *call AdcConfigure.getConfiguration[c]();
config.sampcon_ssel = SAMPCON_SOURCE_SMCLK; // assumption: SMCLK runs at 1 MHz
config.sampcon_id = SAMPCON_CLOCK_DIV_1;
call SingleChannel.configureMultiple[c]( &config, pos, count, period);
call SingleChannel.getData[c]();
}
}
command error_t ReadStream.read[uint8_t c](uint32_t usPeriod)
{
if (usPeriod & 0xFFFF0000){
// "manual" sampling
period = usPeriod / 1000;
periodModified = TRUE;
client = c;
now = call Alarm.getNow();
call SingleChannel.configureSingle[c](call AdcConfigure.getConfiguration[c]());
if (nextBuffer(FALSE) == SUCCESS)
sampleSingle();
} else {
period = usPeriod;
periodModified = FALSE;
client = c;
nextMultiple(c);
}
return SUCCESS;
}
async event error_t SingleChannel.singleDataReady[uint8_t streamClient](uint16_t data)
{
if (client == NSTREAM)
return FAIL;
if (count == 0)
{
now = call Alarm.getNow();
nextBuffer(TRUE);
}
else
{
*pos++ = data;
if (!--count)
{
atomic
{
if (lastBuffer)
{
/* We failed to signal bufferDone in time. Fail. */
bufferQueueEnd[client] = NULL; // prevent post
post readStreamFail();
return FAIL;
}
else
{
lastBuffer = buffer;
lastCount = pos - buffer;
}
}
post bufferDone();
nextBuffer(TRUE);
}
else
nextAlarm();
}
return FAIL;
}
async event uint16_t* SingleChannel.multipleDataReady[uint8_t streamClient](
uint16_t *buf, uint16_t length)
{
atomic
{
if (lastBuffer)
{
/* We failed to signal bufferDone in time. Fail. */
bufferQueueEnd[client] = NULL; // prevent post
post readStreamFail();
return 0;
}
else
{
lastBuffer = buffer;
lastCount = pos - buffer;
}
}
post bufferDone();
nextMultiple(streamClient);
return 0;
}
const msp430adc12_channel_config_t defaultConfig = {
inch: SUPPLY_VOLTAGE_HALF_CHANNEL,
sref: REFERENCE_VREFplus_AVss,
ref2_5v: REFVOLT_LEVEL_1_5,
adc12ssel: SHT_SOURCE_ACLK,
adc12div: SHT_CLOCK_DIV_1,
sht: SAMPLE_HOLD_4_CYCLES,
sampcon_ssel: SAMPCON_SOURCE_SMCLK,
sampcon_id: SAMPCON_CLOCK_DIV_1
};
default async command const msp430adc12_channel_config_t* AdcConfigure.getConfiguration[uint8_t c]()
{
return &defaultConfig;
}
default async command error_t SingleChannel.configureMultiple[uint8_t c](
const msp430adc12_channel_config_t *config, uint16_t b[],
uint16_t numSamples, uint16_t jiffies)
{
return FAIL;
}
default async command error_t SingleChannel.getData[uint8_t c]()
{
return FAIL;
}
default async command error_t SingleChannel.configureSingle[uint8_t c](
const msp430adc12_channel_config_t *config){ return FAIL; }
}
--- NEW FILE: Msp430Adc12DMAWireC.nc ---
/*
* Copyright (c) 2006, Technische Universitaet Berlin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of the Technische Universitaet Berlin nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* - Revision -------------------------------------------------------------
* $Revision: 1.1 $
* $Date: 2008/04/07 09:41:55 $
* @author: Jan Hauer <hauer at tkn.tu-berlin.de>
* ========================================================================
*/
configuration Msp430Adc12DMAWireC
{
} implementation {
components Msp430DmaC, Msp430Adc12DMAP;
Msp430Adc12DMAP.DMAControl -> Msp430DmaC.Control;
Msp430Adc12DMAP.DMAChannel -> Msp430DmaC.Channel2;
#warning Accessing DMA.channel2 for ADC12
}
--- NEW FILE: WireAdcStreamP.nc ---
/* $Id: WireAdcStreamP.nc,v 1.1 2008/04/07 09:41:55 janhauer Exp $
* Copyright (c) 2005 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/**
* Support component for AdcReadStreamClientC.
*
* @author David Gay
* @author Jan Hauer
*/
#include "Msp430Adc12.h"
configuration WireAdcStreamP {
provides interface ReadStream<uint16_t>[uint8_t client];
uses {
interface AdcConfigure<const msp430adc12_channel_config_t*>[uint8_t client];
interface Msp430Adc12SingleChannel[uint8_t client];
interface Resource[uint8_t client];
}
}
implementation {
components AdcStreamP, MainC, new AlarmMilli32C() as Alarm,
new ArbitratedReadStreamC(uniqueCount(ADCC_READ_STREAM_SERVICE), uint16_t) as ArbitrateReadStream;
ReadStream = ArbitrateReadStream;
AdcConfigure = AdcStreamP;
Resource = ArbitrateReadStream;
ArbitrateReadStream.Service -> AdcStreamP;
AdcStreamP.Init <- MainC;
Msp430Adc12SingleChannel = AdcStreamP.SingleChannel;
AdcStreamP.Alarm -> Alarm;
}
Index: AdcP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/AdcP.nc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** AdcP.nc 12 Dec 2006 18:23:06 -0000 1.4
--- AdcP.nc 7 Apr 2008 09:41:55 -0000 1.5
***************
*** 39,43 ****
interface ReadNow<uint16_t> as ReadNow[uint8_t client];
interface Resource as ResourceReadNow[uint8_t client];
- interface ReadStream<uint16_t> as ReadStream[uint8_t streamClient];
}
uses {
--- 39,42 ----
***************
*** 49,57 ****
interface AdcConfigure<const msp430adc12_channel_config_t*> as Config[uint8_t client];
interface Msp430Adc12SingleChannel as SingleChannel[uint8_t client];
- // for ReadStream only:
- interface AdcConfigure<const msp430adc12_channel_config_t*> as ConfigReadStream[uint8_t streamClient];
- interface Msp430Adc12SingleChannel as SingleChannelReadStream[uint8_t streamClient];
- interface Resource as ResourceReadStream[uint8_t streamClient];
-
}
}
--- 48,51 ----
***************
*** 62,71 ****
STATE_READNOW,
STATE_READNOW_INVALID_CONFIG,
- STATE_READSTREAM,
- };
-
- struct stream_entry_t {
- uint16_t count;
- struct stream_entry_t *next;
};
--- 56,59 ----
***************
*** 74,87 ****
norace uint8_t owner;
norace uint16_t value;
- norace uint16_t *resultBuf;
-
- // atomic section in postBuffer() makes norace safe
- norace struct stream_entry_t *streamBuf[uniqueCount(ADCC_READ_STREAM_SERVICE)];
- norace uint32_t usPeriod[uniqueCount(ADCC_READ_STREAM_SERVICE)];
- msp430adc12_channel_config_t streamConfig;
-
- void task finishStreamRequest();
- void task signalBufferDone();
- void nextReadStreamRequest(uint8_t streamClient);
error_t configure(uint8_t client)
--- 62,65 ----
***************
*** 97,102 ****
command error_t Read.read[uint8_t client]()
{
- if (call ResourceRead.isOwner[client]())
- return EBUSY;
return call ResourceRead.request[client]();
}
--- 75,78 ----
***************
*** 109,114 ****
state = STATE_READ;
result = call SingleChannel.getData[client]();
! }
! if (result != SUCCESS){
call ResourceRead.release[client]();
signal Read.readDone[client](result, 0);
--- 85,89 ----
state = STATE_READ;
result = call SingleChannel.getData[client]();
! } else {
call ResourceRead.release[client]();
signal Read.readDone[client](result, 0);
***************
*** 190,324 ****
return 0;
}
-
- command error_t ReadStream.postBuffer[uint8_t streamClient]( uint16_t* buf, uint16_t count )
- {
- struct stream_entry_t *newEntry = (struct stream_entry_t *) buf;
-
- newEntry->count = count;
- newEntry->next = 0;
- atomic {
- if (!streamBuf[streamClient])
- streamBuf[streamClient] = newEntry;
- else {
- struct stream_entry_t *tmp = streamBuf[streamClient];
- while (tmp->next)
- tmp = tmp->next;
- tmp->next = newEntry;
- }
- }
- return SUCCESS;
- }
-
- command error_t ReadStream.read[uint8_t streamClient]( uint32_t _usPeriod )
- {
- if (!streamBuf[streamClient])
- return EINVAL;
- if (call ResourceReadStream.isOwner[streamClient]())
- return EBUSY;
- usPeriod[streamClient] = _usPeriod;
- return call ResourceReadStream.request[streamClient]();
- }
-
- void task finishStreamRequest()
- {
- call ResourceReadStream.release[owner]();
- if (!streamBuf[owner])
- // all posted buffers were filled
- signal ReadStream.readDone[owner]( SUCCESS, usPeriod[owner] );
- else {
- // the commented code below makes gcc throw
- // "internal error: unsupported relocation error" !?!
- /*
- do {
- signal ReadStream.bufferDone[owner]( FAIL, (uint16_t *) streamBuf[owner], 0);
- streamBuf[owner] = streamBuf[owner]->next;
- } while (streamBuf[owner]);
- */
- signal ReadStream.readDone[owner]( FAIL, 0 );
- }
- }
-
- event void ResourceReadStream.granted[uint8_t streamClient]()
- {
- error_t result;
- const msp430adc12_channel_config_t *config;
- struct stream_entry_t *entry = streamBuf[streamClient];
-
- if (!entry)
- result = EINVAL;
- else {
- config = call ConfigReadStream.getConfiguration[streamClient]();
- if (config->inch == INPUT_CHANNEL_NONE)
- result = EINVAL;
- else {
- owner = streamClient;
- streamConfig = *config;
- streamConfig.sampcon_ssel = SAMPCON_SOURCE_SMCLK; // assumption: SMCLK runs at 1 MHz
- streamConfig.sampcon_id = SAMPCON_CLOCK_DIV_1;
- streamBuf[streamClient] = entry->next;
- result = call SingleChannelReadStream.configureMultiple[streamClient](
- &streamConfig, (uint16_t *) entry, entry->count, usPeriod[streamClient]);
- if (result == SUCCESS)
- result = call SingleChannelReadStream.getData[streamClient]();
- else {
- streamBuf[streamClient] = entry;
- post finishStreamRequest();
- return;
- }
- }
- }
- if (result != SUCCESS){
- call ResourceReadStream.release[streamClient]();
- signal ReadStream.readDone[streamClient]( FAIL, 0 );
- }
- return;
- }
-
-
- async event uint16_t* SingleChannelReadStream.multipleDataReady[uint8_t streamClient](
- uint16_t *buf, uint16_t length)
- {
- error_t nextRequest;
-
- if (!resultBuf){
- value = length;
- resultBuf = buf;
- post signalBufferDone();
- if (!streamBuf[streamClient])
- post finishStreamRequest();
- else {
- // fill next buffer (this is the only async code dealing with buffers)
- struct stream_entry_t *entry = streamBuf[streamClient];
- streamBuf[streamClient] = streamBuf[streamClient]->next;
- nextRequest = call SingleChannelReadStream.configureMultiple[streamClient](
- &streamConfig, (uint16_t *) entry, entry->count, usPeriod[streamClient]);
- if (nextRequest == SUCCESS)
- nextRequest = call SingleChannelReadStream.getData[streamClient]();
- if (nextRequest != SUCCESS){
- streamBuf[owner] = entry;
- post finishStreamRequest();
- }
- }
- } else {
- // overflow: can't signal data fast enough
- struct stream_entry_t *entry = (struct stream_entry_t *) buf;
- entry->next = streamBuf[streamClient];
- streamBuf[streamClient] = entry; // what a waste
- post finishStreamRequest();
- }
- return 0;
- }
-
- void task signalBufferDone()
- {
- signal ReadStream.bufferDone[owner]( SUCCESS, resultBuf, value);
- resultBuf = 0;
- }
-
- async event error_t SingleChannelReadStream.singleDataReady[uint8_t streamClient](uint16_t data)
- {
- // won't happen
- return SUCCESS;
- }
default async command error_t ResourceRead.request[uint8_t client]() { return FAIL; }
--- 165,168 ----
***************
*** 333,348 ****
default event void ResourceReadNow.granted[uint8_t nowClient](){}
default async event void ReadNow.readDone[uint8_t client]( error_t result, uint16_t val ){}
! default async command error_t SubResourceReadNow.immediateRequest[uint8_t nowClient]()
! {
! return FAIL;
! }
!
! default async command error_t ResourceReadStream.request[uint8_t streamClient]() { return FAIL; }
! default async command error_t ResourceReadStream.release[uint8_t streamClient]() { return FAIL; }
! default async command bool ResourceReadStream.isOwner[uint8_t streamClient]() { return FALSE; }
! default event void ReadStream.bufferDone[uint8_t streamClient]( error_t result,
! uint16_t* buf, uint16_t count ){}
! default event void ReadStream.readDone[uint8_t streamClient]( error_t result, uint32_t actualPeriod ){ }
!
default async command error_t SingleChannel.getData[uint8_t client]()
{
--- 177,181 ----
default event void ResourceReadNow.granted[uint8_t nowClient](){}
default async event void ReadNow.readDone[uint8_t client]( error_t result, uint16_t val ){}
! default async command error_t SubResourceReadNow.immediateRequest[uint8_t nowClient]() { return FAIL; }
default async command error_t SingleChannel.getData[uint8_t client]()
{
***************
*** 350,354 ****
}
- // will be placed in flash
const msp430adc12_channel_config_t defaultConfig = {INPUT_CHANNEL_NONE,0,0,0,0,0,0,0};
default async command const msp430adc12_channel_config_t*
--- 183,186 ----
***************
*** 356,383 ****
{
return &defaultConfig;
! }
!
! default async command const msp430adc12_channel_config_t*
! ConfigReadStream.getConfiguration[uint8_t client]()
! {
! return &defaultConfig;
! }
!
! default async command error_t SingleChannelReadStream.configureMultiple[uint8_t client](
! const msp430adc12_channel_config_t *config, uint16_t buffer[],
! uint16_t numSamples, uint16_t jiffies)
! {
! return FAIL;
! }
!
! default async command error_t SingleChannelReadStream.getData[uint8_t client]()
! {
! return FAIL;
! }
!
default async command error_t SingleChannel.configureSingle[uint8_t client](
const msp430adc12_channel_config_t *config){ return FAIL; }
!
!
! }
!
--- 188,194 ----
{
return &defaultConfig;
! }
default async command error_t SingleChannel.configureSingle[uint8_t client](
const msp430adc12_channel_config_t *config){ return FAIL; }
!
! }
Index: AdcReadStreamClientC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/AdcReadStreamClientC.nc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** AdcReadStreamClientC.nc 12 Dec 2006 18:23:07 -0000 1.4
--- AdcReadStreamClientC.nc 7 Apr 2008 09:41:55 -0000 1.5
***************
*** 49,60 ****
uses interface AdcConfigure<const msp430adc12_channel_config_t*>;
} implementation {
! components AdcP,
#ifdef REF_VOLT_AUTO_CONFIGURE
// if the client configuration requires a stable
// reference voltage, the reference voltage generator
// is automatically enabled
! new Msp430Adc12ClientAutoRVGC() as Msp430AdcPlient;
#else
! new Msp430Adc12ClientC() as Msp430AdcPlient;
#endif
--- 49,61 ----
uses interface AdcConfigure<const msp430adc12_channel_config_t*>;
} implementation {
! components WireAdcStreamP,
#ifdef REF_VOLT_AUTO_CONFIGURE
// if the client configuration requires a stable
// reference voltage, the reference voltage generator
// is automatically enabled
! new Msp430Adc12ClientAutoRVGC() as Msp430AdcClient;
! AdcConfigure = Msp430AdcClient.AdcConfigure;
#else
! new Msp430Adc12ClientC() as Msp430AdcClient;
#endif
***************
*** 63,73 ****
};
! ReadStream = AdcP.ReadStream[RSCLIENT];
! AdcConfigure = AdcP.ConfigReadStream[RSCLIENT];
! AdcP.SingleChannelReadStream[RSCLIENT] -> Msp430AdcPlient.Msp430Adc12SingleChannel;
! AdcP.ResourceReadStream[RSCLIENT] -> Msp430AdcPlient.Resource;
! #ifdef REF_VOLT_AUTO_CONFIGURE
! AdcConfigure = Msp430AdcPlient.AdcConfigure;
! #endif
}
--- 64,71 ----
};
! ReadStream = WireAdcStreamP.ReadStream[RSCLIENT];
! AdcConfigure = WireAdcStreamP.AdcConfigure[RSCLIENT];
! WireAdcStreamP.Resource[RSCLIENT] -> Msp430AdcClient.Resource;
! WireAdcStreamP.Msp430Adc12SingleChannel[RSCLIENT] -> Msp430AdcClient.Msp430Adc12SingleChannel;
}
Index: HplAdc12P.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/HplAdc12P.nc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** HplAdc12P.nc 12 Dec 2006 18:23:07 -0000 1.4
--- HplAdc12P.nc 7 Apr 2008 09:41:55 -0000 1.5
***************
*** 54,72 ****
MSP430REG_NORACE(ADC12IE);
MSP430REG_NORACE(ADC12IV);
async command void HplAdc12.setCtl0(adc12ctl0_t control0){
! ADC12CTL0 = *(uint16_t*)&control0;
}
async command void HplAdc12.setCtl1(adc12ctl1_t control1){
! ADC12CTL1 = *(uint16_t*)&control1;
}
async command adc12ctl0_t HplAdc12.getCtl0(){
! return *(adc12ctl0_t*) &ADC12CTL0;
}
async command adc12ctl1_t HplAdc12.getCtl1(){
! return *(adc12ctl1_t*) &ADC12CTL1;
}
--- 54,76 ----
MSP430REG_NORACE(ADC12IE);
MSP430REG_NORACE(ADC12IV);
+
+ // SFRs are accessed directly or cast to a pointer, both works fine
+ // (we don't access all SFRs directly, because that would result in
+ // much higher memory footprint)
async command void HplAdc12.setCtl0(adc12ctl0_t control0){
! ADC12CTL0 = *((uint16_t*) &control0);
}
async command void HplAdc12.setCtl1(adc12ctl1_t control1){
! ADC12CTL1 = *((uint16_t*) &control1);
}
async command adc12ctl0_t HplAdc12.getCtl0(){
! return *((adc12ctl0_t*) &ADC12CTL0);
}
async command adc12ctl1_t HplAdc12.getCtl1(){
! return *((adc12ctl1_t*) &ADC12CTL1);
}
***************
*** 93,105 ****
async command void HplAdc12.resetIFGs(){
! if (!ADC12IFG)
! return;
! else {
! // workaround, because ADC12IFG is not writable
! uint8_t i;
! volatile uint16_t tmp;
! for (i=0; i<16; i++)
! tmp = call HplAdc12.getMem(i);
! }
}
--- 97,102 ----
async command void HplAdc12.resetIFGs(){
! ADC12IV = 0;
! ADC12IFG = 0;
}
***************
*** 109,113 ****
}
! async command void HplAdc12.stopConversion(){
ADC12CTL0 &= ~(ADC12SC + ENC);
ADC12CTL0 &= ~(ADC12ON);
--- 106,112 ----
}
! async command void HplAdc12.stopConversion(){
! // stop conversion mode immediately, conversion data is unreliable
! ADC12CTL1 &= ~(CONSEQ0 | CONSEQ1);
ADC12CTL0 &= ~(ADC12SC + ENC);
ADC12CTL0 &= ~(ADC12ON);
Index: Msp430Adc12ClientAutoDMAC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12ClientAutoDMAC.nc,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** Msp430Adc12ClientAutoDMAC.nc 29 May 2007 16:19:20 -0000 1.5
--- Msp430Adc12ClientAutoDMAC.nc 7 Apr 2008 09:41:55 -0000 1.6
***************
*** 49,55 ****
interface Resource;
interface Msp430Adc12SingleChannel;
}
} implementation {
! components Msp430DmaC, Msp430Adc12DMAP, Msp430Adc12P;
enum {
--- 49,56 ----
interface Resource;
interface Msp430Adc12SingleChannel;
+ interface Msp430Adc12Overflow;
}
} implementation {
! components Msp430DmaC, Msp430Adc12DMAP, Msp430Adc12P, Msp430Adc12DMAWireC;
enum {
***************
*** 58,66 ****
Resource = Msp430Adc12P.Resource[ID];
Msp430Adc12SingleChannel = Msp430Adc12DMAP.SingleChannel[ID];
Msp430Adc12DMAP.SubSingleChannel[ID] -> Msp430Adc12P.SingleChannel[ID];
Msp430Adc12DMAP.AsyncAdcControl[ID] -> Msp430Adc12P.DMAExtension[ID];
- Msp430Adc12DMAP.DMAControl -> Msp430DmaC.Control;
- Msp430Adc12DMAP.DMAChannel -> Msp430DmaC.Channel0;
}
--- 59,66 ----
Resource = Msp430Adc12P.Resource[ID];
Msp430Adc12SingleChannel = Msp430Adc12DMAP.SingleChannel[ID];
+ Msp430Adc12Overflow = Msp430Adc12P.Overflow[ID];
Msp430Adc12DMAP.SubSingleChannel[ID] -> Msp430Adc12P.SingleChannel[ID];
Msp430Adc12DMAP.AsyncAdcControl[ID] -> Msp430Adc12P.DMAExtension[ID];
}
Index: Msp430Adc12ClientAutoDMA_RVGC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12ClientAutoDMA_RVGC.nc,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** Msp430Adc12ClientAutoDMA_RVGC.nc 25 Jun 2007 13:44:49 -0000 1.6
--- Msp430Adc12ClientAutoDMA_RVGC.nc 7 Apr 2008 09:41:55 -0000 1.7
***************
*** 48,55 ****
interface Resource;
interface Msp430Adc12SingleChannel;
}
uses interface AdcConfigure<const msp430adc12_channel_config_t*>;
} implementation {
! components Msp430Adc12P, Msp430RefVoltArbiterP;
enum {
--- 48,56 ----
interface Resource;
interface Msp430Adc12SingleChannel;
+ interface Msp430Adc12Overflow;
}
uses interface AdcConfigure<const msp430adc12_channel_config_t*>;
} implementation {
! components Msp430Adc12P, Msp430RefVoltArbiterP, Msp430Adc12DMAWireC;
enum {
***************
*** 57,60 ****
--- 58,62 ----
};
Resource = Msp430RefVoltArbiterP.ClientResource[ID];
+ Msp430Adc12Overflow = Msp430Adc12P.Overflow[ID];
Msp430RefVoltArbiterP.AdcResource[ID] -> Msp430Adc12P.Resource[ID];
***************
*** 70,76 ****
Msp430Adc12DMAP.SubSingleChannel[ID] -> Msp430Adc12P.SingleChannel[ID];
Msp430Adc12DMAP.AsyncAdcControl[ID] -> Msp430Adc12P.DMAExtension[ID];
-
- Msp430Adc12DMAP.DMAControl -> Msp430DmaC.Control;
- Msp430Adc12DMAP.DMAChannel -> Msp430DmaC.Channel0;
-
}
--- 72,74 ----
Index: Msp430Adc12ClientAutoRVGC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12ClientAutoRVGC.nc,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** Msp430Adc12ClientAutoRVGC.nc 25 Jun 2007 13:44:49 -0000 1.6
--- Msp430Adc12ClientAutoRVGC.nc 7 Apr 2008 09:41:55 -0000 1.7
***************
*** 47,50 ****
--- 47,51 ----
interface Msp430Adc12SingleChannel;
interface Msp430Adc12MultiChannel;
+ interface Msp430Adc12Overflow;
}
uses interface AdcConfigure<const msp430adc12_channel_config_t*>;
***************
*** 58,61 ****
--- 59,63 ----
Msp430Adc12SingleChannel = Msp430Adc12P.SingleChannel[ID];
Msp430Adc12MultiChannel = Msp430Adc12P.MultiChannel[ID];
+ Msp430Adc12Overflow = Msp430Adc12P.Overflow[ID];
Msp430RefVoltArbiterP.AdcResource[ID] -> Msp430Adc12P.Resource[ID];
Index: Msp430Adc12ImplP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12ImplP.nc,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** Msp430Adc12ImplP.nc 25 Jun 2007 15:47:15 -0000 1.5
--- Msp430Adc12ImplP.nc 7 Apr 2008 09:41:55 -0000 1.6
***************
*** 64,67 ****
--- 64,68 ----
implementation
{
+ #warning Accessing TimerA for ADC12
enum {
SINGLE_DATA = 1,
***************
*** 87,91 ****
--- 88,97 ----
command error_t Init.init()
{
+ adc12ctl0_t ctl0;
call HplAdc12.stopConversion();
+ ctl0 = call HplAdc12.getCtl0();
+ ctl0.adc12tovie = 1;
+ ctl0.adc12ovie = 1;
+ call HplAdc12.setCtl0(ctl0);
return SUCCESS;
}
***************
*** 326,330 ****
adc12ctl1_t ctl1 = {
adc12busy: 0,
! ctl1.conseq = 3,
adc12ssel: config->adc12ssel,
adc12div: config->adc12div,
--- 332,336 ----
adc12ctl1_t ctl1 = {
adc12busy: 0,
! conseq: 3,
adc12ssel: config->adc12ssel,
adc12div: config->adc12div,
***************
*** 405,410 ****
adc12ctl1_t ctl1 = {
adc12busy: 0,
! // use seq. of channels (rep.seq. channel does not work with TimerA + MSC ?)
! conseq: (jiffies == 0) ? 3 : 1,
adc12ssel: config->adc12ssel,
adc12div: config->adc12div,
--- 411,415 ----
adc12ctl1_t ctl1 = {
adc12busy: 0,
! conseq: (numSamples > numMemctl+1) ? 3 : 1,
adc12ssel: config->adc12ssel,
adc12div: config->adc12div,
***************
*** 421,425 ****
uint16_t i, mask = 1;
adc12ctl0_t ctl0 = call HplAdc12.getCtl0();
! ctl0.msc = 1;
ctl0.sht0 = config->sht;
ctl0.sht1 = config->sht;
--- 426,430 ----
uint16_t i, mask = 1;
adc12ctl0_t ctl0 = call HplAdc12.getCtl0();
! ctl0.msc = (jiffies == 0) ? 1 : 0;
ctl0.sht0 = config->sht;
ctl0.sht1 = config->sht;
***************
*** 482,492 ****
resetAdcPin( (call HplAdc12.getMCtl(0)).inch );
if (state & MULTI_CHANNEL){
- ADC12IV = 0; // clear any pending overflow
for (i=1; i<numChannels; i++)
resetAdcPin( (call HplAdc12.getMCtl(i)).inch );
}
! call HplAdc12.stopConversion();
! call HplAdc12.resetIFGs();
! state &= ~ADC_BUSY;
}
--- 487,498 ----
resetAdcPin( (call HplAdc12.getMCtl(0)).inch );
if (state & MULTI_CHANNEL){
for (i=1; i<numChannels; i++)
resetAdcPin( (call HplAdc12.getMCtl(i)).inch );
}
! atomic {
! call HplAdc12.stopConversion();
! call HplAdc12.resetIFGs();
! state &= ~ADC_BUSY;
! }
}
***************
*** 505,515 ****
async command error_t DMAExtension.stop[uint8_t id]()
{
! atomic {
! if (call ADCArbiterInfo.userId() == id){
! stopConversion();
! return SUCCESS;
! }
! }
! return FAIL;
}
--- 511,516 ----
async command error_t DMAExtension.stop[uint8_t id]()
{
! stopConversion();
! return SUCCESS;
}
***************
*** 520,523 ****
--- 521,525 ----
async event void HplAdc12.conversionDone(uint16_t iv)
{
+ bool overflow = FALSE;
if (iv <= 4){ // check for overflow
if (iv == 2)
***************
*** 525,528 ****
--- 527,533 ----
else
signal Overflow.conversionTimeOverflow[clientID]();
+ // only if the client didn't ask for data as fast as possible (jiffies was not zero)
+ if (!(call HplAdc12.getCtl0()).msc)
+ overflow = TRUE;
}
switch (state & CONVERSION_MODE_MASK)
***************
*** 537,541 ****
repeatContinue = signal SingleChannel.singleDataReady[clientID](
call HplAdc12.getMem(0));
! if (repeatContinue == FAIL)
stopConversion();
break;
--- 542,546 ----
repeatContinue = signal SingleChannel.singleDataReady[clientID](
call HplAdc12.getMem(0));
! if (repeatContinue != SUCCESS)
stopConversion();
break;
***************
*** 544,557 ****
case MULTI_CHANNEL:
{
! uint16_t i = 0;
do {
*resultBuffer++ = call HplAdc12.getMem(i);
} while (++i < numChannels);
resultBufferIndex += numChannels;
! if (resultBufferLength == resultBufferIndex){
stopConversion();
! resultBuffer -= resultBufferLength;
resultBufferIndex = 0;
! signal MultiChannel.dataReady[clientID](resultBuffer, resultBufferLength);
} else call HplAdc12.enableConversion();
}
--- 549,564 ----
case MULTI_CHANNEL:
{
! uint16_t i = 0, k;
do {
*resultBuffer++ = call HplAdc12.getMem(i);
} while (++i < numChannels);
resultBufferIndex += numChannels;
! if (overflow || resultBufferLength == resultBufferIndex){
stopConversion();
! resultBuffer -= resultBufferIndex;
! k = resultBufferIndex - numChannels;
resultBufferIndex = 0;
! signal MultiChannel.dataReady[clientID](resultBuffer,
! overflow ? k : resultBufferLength);
} else call HplAdc12.enableConversion();
}
***************
*** 559,563 ****
case MULTIPLE_DATA:
{
! uint16_t i = 0, length;
if (resultBufferLength - resultBufferIndex > 16)
length = 16;
--- 566,570 ----
case MULTIPLE_DATA:
{
! uint16_t i = 0, length, k;
if (resultBufferLength - resultBufferIndex > 16)
length = 16;
***************
*** 568,583 ****
} while (++i < length);
resultBufferIndex += length;
!
! if (resultBufferLength - resultBufferIndex > 15)
return;
! else if (resultBufferLength - resultBufferIndex > 0){
adc12memctl_t memctl = call HplAdc12.getMCtl(0);
memctl.eos = 1;
call HplAdc12.setMCtl(resultBufferLength - resultBufferIndex, memctl);
- } else {
- stopConversion();
- resultBuffer -= resultBufferLength;
- resultBufferIndex = 0;
- signal SingleChannel.multipleDataReady[clientID](resultBuffer, resultBufferLength);
}
}
--- 575,592 ----
} while (++i < length);
resultBufferIndex += length;
! if (overflow || resultBufferLength == resultBufferIndex){
! stopConversion();
! resultBuffer -= resultBufferIndex;
! k = resultBufferIndex - length;
! resultBufferIndex = 0;
! signal SingleChannel.multipleDataReady[clientID](resultBuffer,
! overflow ? k : resultBufferLength);
! } else if (resultBufferLength - resultBufferIndex > 15)
return;
! else {
! // last sequence < 16 samples
adc12memctl_t memctl = call HplAdc12.getMCtl(0);
memctl.eos = 1;
call HplAdc12.setMCtl(resultBufferLength - resultBufferIndex, memctl);
}
}
***************
*** 592,596 ****
resultBuffer = signal SingleChannel.multipleDataReady[clientID](
resultBuffer-resultBufferLength,
! resultBufferLength);
if (!resultBuffer)
stopConversion();
--- 601,605 ----
resultBuffer = signal SingleChannel.multipleDataReady[clientID](
resultBuffer-resultBufferLength,
! overflow ? 0 : resultBufferLength);
if (!resultBuffer)
stopConversion();
Index: Msp430Adc12MultiChannel.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/Msp430Adc12MultiChannel.nc,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** Msp430Adc12MultiChannel.nc 12 Dec 2006 18:23:07 -0000 1.2
--- Msp430Adc12MultiChannel.nc 7 Apr 2008 09:41:55 -0000 1.3
***************
*** 75,85 ****
* numSamples = (numMemctl+1) * 2
*
! * @param jiffies Sampling period per sequence in terms of clock ticks of
! * "sampcon_ssel" and input divider "sampcon_id". A sequence of (numMemctl+1)
! * is always sampled as fast as possible and <code>jiffies</code> specifies
! * the time between those sequences. For example, if numSamples =
! * (numMemctl+1) * 5, then dataReady() will be signalled after (approx.)
! * 5*jiffies clock ticks after the call to getData() and each set of
! * numMemctl+1 channels was sampled at (almost) the same time.
*
* @return SUCCESS means that the ADC was configured successfully and
--- 75,80 ----
* numSamples = (numMemctl+1) * 2
*
! * @param jiffies Sampling period in terms of clock ticks of "sampcon_ssel"
! * and input divider "sampcon_id".
*
* @return SUCCESS means that the ADC was configured successfully and
Index: README.txt
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/msp430/adc12/README.txt,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** README.txt 25 Jun 2007 15:47:15 -0000 1.6
--- README.txt 7 Apr 2008 09:41:55 -0000 1.7
***************
*** 37,42 ****
single channel with a specified sampling frequency and (2) the
Msp430Adc12MultiChannel allows to sample a group of up to 16 different ADC
! channels "at once" (with minimum latency) and in addition define a sampling
! frequency for the whole group (useful for multi-channel accelerometers, etc.).
On the MSP430 two additional hardware modules may play a role when the ADC12 is
used: the internal reference voltage generator and the DMA controller.
--- 37,42 ----
single channel with a specified sampling frequency and (2) the
Msp430Adc12MultiChannel allows to sample a group of up to 16 different ADC
! channels.
!
On the MSP430 two additional hardware modules may play a role when the ADC12 is
used: the internal reference voltage generator and the DMA controller.
More information about the Tinyos-2-commits
mailing list