From 957a31040a83efd1fc9c7a563b7898459ef6d572 Mon Sep 17 00:00:00 2001 From: janhauer Date: Mon, 25 Jun 2007 15:47:14 +0000 Subject: [PATCH] Added macros that can be used to reduce codesize (Msp430Adc12.h). Updated README. --- tos/chips/msp430/adc12/Msp430Adc12.h | 14 ++++++++----- tos/chips/msp430/adc12/Msp430Adc12ImplP.nc | 24 ++++++++++++++-------- tos/chips/msp430/adc12/Msp430Adc12P.nc | 9 +++++++- tos/chips/msp430/adc12/README.txt | 24 +++++++++++++++++----- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/tos/chips/msp430/adc12/Msp430Adc12.h b/tos/chips/msp430/adc12/Msp430Adc12.h index d8ce94ea..6e6854e8 100644 --- a/tos/chips/msp430/adc12/Msp430Adc12.h +++ b/tos/chips/msp430/adc12/Msp430Adc12.h @@ -37,12 +37,16 @@ #define MSP430ADC12_H #include "Msp430RefVoltGenerator.h" -#define P6PIN_AUTO_CONFIGURE +#define ADC12_TIMERA_ENABLED +#define ADC12_P6PIN_AUTO_CONFIGURE +#define ADC12_CHECK_ARGS +//#define ADC12_ONLY_WITH_DMA + +// for HIL clients #define REF_VOLT_AUTO_CONFIGURE -#define CHECK_ARGS - + typedef struct { - // see README.txt for a more detailed explanation + // see README.txt unsigned int inch: 4; // input channel unsigned int sref: 3; // reference voltage unsigned int ref2_5v: 1; // reference voltage level @@ -56,7 +60,7 @@ typedef struct { typedef struct { - // see README.txt for a more detailed explanation + // see README.txt volatile unsigned inch: 4, // input channel sref: 3, // reference voltage diff --git a/tos/chips/msp430/adc12/Msp430Adc12ImplP.nc b/tos/chips/msp430/adc12/Msp430Adc12ImplP.nc index 0c7e8f0f..36c80b8f 100644 --- a/tos/chips/msp430/adc12/Msp430Adc12ImplP.nc +++ b/tos/chips/msp430/adc12/Msp430Adc12ImplP.nc @@ -92,6 +92,7 @@ implementation void prepareTimerA(uint16_t interval, uint16_t csSAMPCON, uint16_t cdSAMPCON) { +#ifdef ADC12_TIMERA_ENABLED msp430_compare_control_t ccResetSHI = { ccifg : 0, cov : 0, out : 0, cci : 0, ccie : 0, outmod : 0, cap : 0, clld : 0, scs : 0, ccis : 0, cm : 0 }; @@ -104,10 +105,12 @@ implementation call ControlA0.setControl(ccResetSHI); call CompareA0.setEvent(interval-1); call CompareA1.setEvent((interval-1)/2); +#endif } void startTimerA() { +#ifdef ADC12_TIMERA_ENABLED msp430_compare_control_t ccSetSHI = { ccifg : 0, cov : 0, out : 1, cci : 0, ccie : 0, outmod : 0, cap : 0, clld : 0, scs : 0, ccis : 0, cm : 0 }; @@ -123,11 +126,12 @@ implementation //call ControlA1.setControl(ccResetSHI); call ControlA1.setControl(ccRSOutmod); call TimerA.setMode(MSP430TIMER_UP_MODE); // go! +#endif } void configureAdcPin( uint8_t inch ) { -#ifdef P6PIN_AUTO_CONFIGURE +#ifdef ADC12_P6PIN_AUTO_CONFIGURE switch (inch) { case 0: call Port60.selectModuleFunc(); call Port60.makeInput(); break; @@ -144,7 +148,7 @@ implementation void resetAdcPin( uint8_t inch ) { -#ifdef P6PIN_AUTO_CONFIGURE +#ifdef ADC12_P6PIN_AUTO_CONFIGURE switch (inch) { case 0: call Port60.selectIOFunc(); break; @@ -163,7 +167,7 @@ implementation const msp430adc12_channel_config_t *config) { error_t result = ERESERVE; -#ifdef CHECK_ARGS +#ifdef ADC12_CHECK_ARGS if (!config) return EINVAL; #endif @@ -207,7 +211,7 @@ implementation uint16_t jiffies) { error_t result = ERESERVE; -#ifdef CHECK_ARGS +#ifdef ADC12_CHECK_ARGS if (!config || jiffies == 1 || jiffies == 2) return EINVAL; #endif @@ -255,7 +259,7 @@ implementation uint16_t *buf, uint16_t length, uint16_t jiffies) { error_t result = ERESERVE; -#ifdef CHECK_ARGS +#ifdef ADC12_CHECK_ARGS if (!config || !buf || !length || jiffies == 1 || jiffies == 2) return EINVAL; #endif @@ -311,7 +315,7 @@ implementation uint16_t *buf, uint8_t length, uint16_t jiffies) { error_t result = ERESERVE; -#ifdef CHECK_ARGS +#ifdef ADC12_CHECK_ARGS if (!config || !buf || !length || length > 16 || jiffies == 1 || jiffies == 2) return EINVAL; #endif @@ -389,7 +393,7 @@ implementation uint16_t numSamples, uint16_t jiffies) { error_t result = ERESERVE; -#ifdef CHECK_ARGS +#ifdef ADC12_CHECK_ARGS if (!config || !memctl || !numMemctl || numMemctl > 15 || !numSamples || !buf || jiffies == 1 || jiffies == 2 || numSamples % (numMemctl+1) != 0) return EINVAL; @@ -471,8 +475,10 @@ implementation void stopConversion() { uint8_t i; +#ifdef ADC12_TIMERA_ENABLED if (state & USE_TIMERA) call TimerA.setMode(MSP430TIMER_STOP_MODE); +#endif resetAdcPin( (call HplAdc12.getMCtl(0)).inch ); if (state & MULTI_CHANNEL){ ADC12IV = 0; // clear any pending overflow @@ -519,7 +525,6 @@ implementation else signal Overflow.conversionTimeOverflow[clientID](); } -#ifndef MSP430ADC12_ONLY_DMA switch (state & CONVERSION_MODE_MASK) { case SINGLE_DATA: @@ -535,6 +540,7 @@ implementation stopConversion(); break; } +#ifndef ADC12_ONLY_WITH_DMA case MULTI_CHANNEL: { uint16_t i = 0; @@ -590,8 +596,8 @@ implementation stopConversion(); break; } - } // switch #endif + } // switch } default async event error_t SingleChannel.singleDataReady[uint8_t id](uint16_t data) diff --git a/tos/chips/msp430/adc12/Msp430Adc12P.nc b/tos/chips/msp430/adc12/Msp430Adc12P.nc index bb1afb6d..e662eea5 100644 --- a/tos/chips/msp430/adc12/Msp430Adc12P.nc +++ b/tos/chips/msp430/adc12/Msp430Adc12P.nc @@ -44,7 +44,7 @@ configuration Msp430Adc12P interface AsyncStdControl as DMAExtension[uint8_t id]; } } implementation { - components Msp430Adc12ImplP, HplAdc12P, Msp430TimerC, MainC, HplMsp430GeneralIOC, + components Msp430Adc12ImplP, HplAdc12P, MainC, new SimpleRoundRobinArbiterC(MSP430ADC12_RESOURCE) as Arbiter; Resource = Arbiter; @@ -56,6 +56,9 @@ configuration Msp430Adc12P Msp430Adc12ImplP.Init <- MainC; Msp430Adc12ImplP.ADCArbiterInfo -> Arbiter; Msp430Adc12ImplP.HplAdc12 -> HplAdc12P; + +#ifdef ADC12_P6PIN_AUTO_CONFIGURE + components HplMsp430GeneralIOC; Msp430Adc12ImplP.Port60 -> HplMsp430GeneralIOC.Port60; Msp430Adc12ImplP.Port61 -> HplMsp430GeneralIOC.Port61; Msp430Adc12ImplP.Port62 -> HplMsp430GeneralIOC.Port62; @@ -64,11 +67,15 @@ configuration Msp430Adc12P Msp430Adc12ImplP.Port65 -> HplMsp430GeneralIOC.Port65; Msp430Adc12ImplP.Port66 -> HplMsp430GeneralIOC.Port66; Msp430Adc12ImplP.Port67 -> HplMsp430GeneralIOC.Port67; +#endif +#ifdef ADC12_TIMERA_ENABLED + components Msp430TimerC; Msp430Adc12ImplP.TimerA -> Msp430TimerC.TimerA; Msp430Adc12ImplP.ControlA0 -> Msp430TimerC.ControlA0; Msp430Adc12ImplP.ControlA1 -> Msp430TimerC.ControlA1; Msp430Adc12ImplP.CompareA0 -> Msp430TimerC.CompareA0; Msp430Adc12ImplP.CompareA1 -> Msp430TimerC.CompareA1; +#endif } diff --git a/tos/chips/msp430/adc12/README.txt b/tos/chips/msp430/adc12/README.txt index 98710315..6a6ca684 100644 --- a/tos/chips/msp430/adc12/README.txt +++ b/tos/chips/msp430/adc12/README.txt @@ -32,9 +32,13 @@ rather about portability it should wire to any of these components. ==================================================================== An application that is written for an MSP430-based platform like 'eyesIFX' or -'telosb' can access the ADC12 in a more efficient way to, for example, do -high-frequency sampling through the Msp430Adc12SingleChannel interface. On the -MSP430 two additional hardware modules may become relevant when the ADC12 is +'telosb' can access the ADC12 in a more efficient way via two interfaces: (1) +the Msp430Adc12SingleChannel allows to perform one or more ADC conversions on a +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. The voltage generator outputs stabilized voltage of 1.5 V or 2.5 V, which may @@ -52,7 +56,7 @@ the client calls Resource.release(), but only after some pre-defined interval clients are present. Second, one must not forget to wire the AdcConfigure interface to the Msp430Adc12ClientAutoRVGC or Msp430Adc12ClientAutoDMA_RVGC component in addition to configuring the ADC through the -Msp430Adc12SingleChannel interface (no nesC warning will be signalled). +Msp430Adc12SingleChannel interface (a nesC warning will be signalled). The DMA controller can be used to copy conversion data from the ADC registers to the application buffer. DMA is only present on MSP430x15x and MSP430x16x @@ -67,6 +71,7 @@ by the following components that an MSP430-based application may wire to: * Msp430Adc12ClientAutoDMAC: DMA, but no automatic reference voltage * Msp430Adc12ClientAutoDMA_RVGC: DMA and automatic reference voltage +Currently Msp430Adc12MultiChannel is only provided by the first two components. I/O PINs -------------------------------------------------------------------- @@ -78,7 +83,7 @@ pin is switched to input direction. By default, for every client this is done conversion starts the respective pin is switched to peripheral module function and input direction and immediately after the conversion has finished it is switched to I/O function mode. To disable this feature please comment out the -"P6PIN_AUTO_CONFIGURE" macro in Msp430Adc12.h. +"ADC12_P6PIN_AUTO_CONFIGURE" macro in Msp430Adc12.h. Configuration for single channel conversions @@ -161,6 +166,15 @@ SAMPCON_CLOCK_DIV_1 and a "jiffies" parameter of (1000000 / 4000) = 250. // buffer contains conversion results } + +3. Implementation +==================================================================== + +The ADC12 stack is located at tinyos-2.x/tos/chips/msp430/adc12. Sensor +wrappers for the msp430 internal sensors are in +tinyos-2.x/tos/chips/msp430/sensors, an HAL test app can be found in +tinyos-2.x/apps/tests/msp430/Adc12. + ----- $Date$ -- 2.39.2