msp430adc12implp.nc

来自「tinyos-2.x.rar」· NC 代码 · 共 658 行 · 第 1/2 页

NC
658
字号
  }

  async command error_t SingleChannel.configureMultipleRepeat[uint8_t id](
      const msp430adc12_channel_config_t *config,
      uint16_t *buf, uint8_t length, uint16_t jiffies)
  {
    error_t result = ERESERVE;
#ifdef ADC12_CHECK_ARGS
#ifndef ADC12_TIMERA_ENABLED
    if (jiffies>0) 
      return EINVAL;
#endif
    if (!config || !buf || !length || length > 16 || jiffies == 1 || jiffies == 2)
      return EINVAL;
#endif
    atomic {
      if (state & ADC_BUSY)
        return EBUSY;
      if (call ADCArbiterInfo.userId() == id){
        adc12ctl1_t ctl1 = {
          adc12busy: 0,
          conseq: 3,
          adc12ssel: config->adc12ssel,
          adc12div: config->adc12div,
          issh: 0,
          shp: 1,
          shs: (jiffies == 0) ? 0 : 1,
          cstartadd: 0
        };
        adc12memctl_t memctl = {
          inch: config->inch,
          sref: config->sref,
          eos: 0
        };        
        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;

        state = MULTIPLE_DATA_REPEAT;
	resultBufferStart = NULL;
        resultBufferLength = length;
        resultBufferStart = buf;
        resultBufferIndex = 0;            
        
        call HplAdc12.setCtl0(ctl0);
        call HplAdc12.setCtl1(ctl1);
        for (i=0; i<(length-1) && i < 15; i++)
          call HplAdc12.setMCtl(i, memctl);
        memctl.eos = 1;  
        call HplAdc12.setMCtl(i, memctl);
        call HplAdc12.setIEFlags(mask << i);        
        
        if (jiffies){
          state |= USE_TIMERA;
          prepareTimerA(jiffies, config->sampcon_ssel, config->sampcon_id);
        }
        result = SUCCESS;
      }
    }
    return result;
  }

  async command error_t SingleChannel.getData[uint8_t id]()
  {
    atomic {
      if (call ADCArbiterInfo.userId() == id){
        if ((state & MULTIPLE_DATA_REPEAT) && !resultBufferStart)
          return EINVAL;
        if (state & ADC_BUSY)
          return EBUSY;
        state |= ADC_BUSY;
        clientID = id;
        configureAdcPin((call HplAdc12.getMCtl(0)).inch);
        call HplAdc12.startConversion();
        if (state & USE_TIMERA)
          startTimerA(); 
        return SUCCESS;
      }
    }
    return FAIL;
  }

  async command error_t MultiChannel.configure[uint8_t id](
      const msp430adc12_channel_config_t *config,
      adc12memctl_t *memctl, uint8_t numMemctl, uint16_t *buf, 
      uint16_t numSamples, uint16_t jiffies)
  {
    error_t result = ERESERVE;
#ifdef ADC12_CHECK_ARGS
#ifndef ADC12_TIMERA_ENABLED
    if (jiffies>0) 
      return EINVAL;
#endif
    if (!config || !memctl || !numMemctl || numMemctl > 15 || !numSamples || 
        !buf || jiffies == 1 || jiffies == 2 || numSamples % (numMemctl+1) != 0)
      return EINVAL;
#endif
    atomic {
      if (state & ADC_BUSY)
        return EBUSY;
      if (call ADCArbiterInfo.userId() == id){
        adc12ctl1_t ctl1 = {
          adc12busy: 0,
          conseq: (numSamples > numMemctl+1) ? 3 : 1, 
          adc12ssel: config->adc12ssel,
          adc12div: config->adc12div,
          issh: 0,
          shp: 1,
          shs: (jiffies == 0) ? 0 : 1,
          cstartadd: 0
        };
        adc12memctl_t firstMemctl = {
          inch: config->inch,
          sref: config->sref,
          eos: 0
        };     
        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;

        state = MULTI_CHANNEL;
	resultBufferStart = NULL;
        resultBufferLength = numSamples;
        resultBufferStart = buf;
        resultBufferIndex = 0;
        numChannels = numMemctl+1;
        call HplAdc12.setCtl0(ctl0);
        call HplAdc12.setCtl1(ctl1);
        call HplAdc12.setMCtl(0, firstMemctl);
        for (i=0; i<(numMemctl-1) && i < 14; i++){
          memctl[i].eos = 0;
          call HplAdc12.setMCtl(i+1, memctl[i]);
        }
        memctl[i].eos = 1;
        call HplAdc12.setMCtl(i+1, memctl[i]);
        call HplAdc12.setIEFlags(mask << (i+1));        
        
        if (jiffies){
          state |= USE_TIMERA;
          prepareTimerA(jiffies, config->sampcon_ssel, config->sampcon_id);
        }
        result = SUCCESS;
      }      
    }
    return result;
  }

  async command error_t MultiChannel.getData[uint8_t id]()
  {
    uint8_t i;
    atomic {
      if (call ADCArbiterInfo.userId() == id){
        if (!resultBufferStart)
          return EINVAL;
        if (state & ADC_BUSY)
          return EBUSY;
        state |= ADC_BUSY;
        clientID = id;
        for (i=0; i<numChannels; i++)
          configureAdcPin((call HplAdc12.getMCtl(i)).inch);
        call HplAdc12.startConversion();
        if (state & USE_TIMERA)
          startTimerA(); 
        return SUCCESS;
      }
    }
    return FAIL;
  }
  
  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){
      for (i=1; i<numChannels; i++)
        resetAdcPin( (call HplAdc12.getMCtl(i)).inch );
    }
    atomic {
      call HplAdc12.stopConversion();
      call HplAdc12.resetIFGs(); 
      state &= ~ADC_BUSY;
    }
  }

  async command error_t DMAExtension.start[uint8_t id]()
  { 
    atomic {
      if (call ADCArbiterInfo.userId() == id){
        call HplAdc12.setIEFlags(0);
        call HplAdc12.resetIFGs();
        return SUCCESS;
      }
    }
    return FAIL;
  }
  
  async command error_t DMAExtension.stop[uint8_t id]()
  {
    stopConversion();
    return SUCCESS;
  }
  
  async event void TimerA.overflow(){}
  async event void CompareA0.fired(){}
  async event void CompareA1.fired(){}

  async event void HplAdc12.conversionDone(uint16_t iv)
  {
    bool overflow = FALSE;
    uint16_t *resultBuffer;

    if (iv <= 4){ // check for overflow
      if (iv == 2)
        signal Overflow.memOverflow[clientID]();
      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) 
    { 
      case SINGLE_DATA:
        stopConversion();
        signal SingleChannel.singleDataReady[clientID](call HplAdc12.getMem(0));
        break;
      case SINGLE_DATA_REPEAT:
        {
          error_t repeatContinue;
          repeatContinue = signal SingleChannel.singleDataReady[clientID](
                call HplAdc12.getMem(0));
          if (repeatContinue != SUCCESS)
            stopConversion();
          break;
        }
#ifndef ADC12_ONLY_WITH_DMA
      case MULTI_CHANNEL:
        {
          uint16_t i = 0, k;
          resultBuffer = resultBufferStart + resultBufferIndex;
          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);
          }
        }
        break;
      case MULTIPLE_DATA:
        {
          uint16_t i = 0, length, k;
          resultBuffer = resultBufferStart + resultBufferIndex;
          if (resultBufferLength - resultBufferIndex > 16) 
            length = 16;
          else
            length = resultBufferLength - resultBufferIndex;
          do {
            *resultBuffer++ = call HplAdc12.getMem(i);
          } 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);
          }
        }
        break;
      case MULTIPLE_DATA_REPEAT:
        {
          uint8_t i = 0;
          resultBuffer = resultBufferStart;
          do {
            *resultBuffer++ = call HplAdc12.getMem(i);
          } while (++i < resultBufferLength);
          
          resultBufferStart = signal SingleChannel.multipleDataReady[clientID](
              resultBuffer-resultBufferLength,
              overflow ? 0 : resultBufferLength);
          if (!resultBufferStart)  
            stopConversion();
          break;
        }
#endif
      } // switch
  }

  default async event error_t SingleChannel.singleDataReady[uint8_t id](uint16_t data)
  {
    return FAIL;
  }
   
  default async event uint16_t* SingleChannel.multipleDataReady[uint8_t id](
      uint16_t *buf, uint16_t numSamples)
  {
    return 0;
  }
   
  default async event void MultiChannel.dataReady[uint8_t id](uint16_t *buffer, uint16_t numSamples) {};
  
  default async event void Overflow.memOverflow[uint8_t id](){}
  default async event void Overflow.conversionTimeOverflow[uint8_t id](){}

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?