⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adcsequencedmap.nc

📁 Develop Zigbee network real-time Os
💻 NC
字号:

/*
 * Copyright (c) 2007 University of Copenhagen
 * 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 University of Copenhagen 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/*
 * 
 * @author Marcus Chang
 *
 */

module AdcSequenceDmaP {

  provides interface Init;
  provides interface AdcControl;
  provides interface StdControl as PortControl[uint8_t id];
  provides interface Read<int16_t>[uint8_t id];
  uses interface Dma as Dma1;
  uses interface Dma as Dma2;
  uses interface StdOut;

}

implementation
{

#include "Adc.h"
#include "dma.h"

  uint8_t reference;
  uint8_t resolution;
  uint8_t input;

  uint8_t counter = 0;

  dma_config_t * dmaConfigValue, * dmaConfigRegister;
  
  int16_t adc_value[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  uint8_t adc_port[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  bool inUse[] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE };
    
  command error_t Init.init() {
    
    dmaConfigValue = call Dma1.getConfig();
    dmaConfigRegister = call Dma2.getConfig();

    /* setup DMA for ADC values */
    dmaConfigValue->SRCADDR = (uint16_t) 0xDFBA;          // address of source 
    dmaConfigValue->DESTADDR = (uint16_t) &adc_value[0];    // address of destination       
    dmaConfigValue->VLEN      = VLEN_USE_LEN;  // Using LEN to determine how many bytes to transfer
    dmaConfigValue->IRQMASK   = TRUE;          // Issue an IRQ upon completion.
    dmaConfigValue->DESTINC   = DESTINC_1;     // The destination address is to be incremented by 1 after each transfer
    dmaConfigValue->SRCINC    = SRCINC_0;      // The source address inremented by 1 byte after each transfer
    dmaConfigValue->TRIG      = DMATRIG_ADC_CHALL;  // The DMA channel will be started manually
    dmaConfigValue->WORDSIZE  = WORDSIZE_WORD; // One byte is transferred each time.
    dmaConfigValue->TMODE     = TMODE_SINGLE_REPEATED;   // The number of bytes specified by LEN is transferred

    /* setup DMA for port reading */
    dmaConfigRegister->SRCADDR = (uint16_t) 0xDFB5;          // address of source 
    dmaConfigRegister->DESTADDR = (uint16_t) &adc_port[0];    // address of destination       
    dmaConfigRegister->VLEN      = VLEN_USE_LEN;  // Using LEN to determine how many bytes to transfer
    dmaConfigRegister->IRQMASK   = TRUE;          // Issue an IRQ upon completion.
    dmaConfigRegister->DESTINC   = DESTINC_1;     // The destination address is to be incremented by 1 after each transfer
    dmaConfigRegister->SRCINC    = SRCINC_0;      // The source address inremented by 1 byte after each transfer
    dmaConfigRegister->TRIG      = DMATRIG_ADC_CHALL;  // The DMA channel will be started manually
    dmaConfigRegister->WORDSIZE  = WORDSIZE_BYTE; // One byte is transferred each time.
    dmaConfigRegister->TMODE     = TMODE_SINGLE_REPEATED;   // The number of bytes specified by LEN is transferred

    
    return SUCCESS;
  }

  command void AdcControl.enable(uint8_t ref, uint8_t res, uint8_t in) {

    /* enable ADC interrupt */
    ADCIE = 1;
    ADC_STOP();
 
    /* save parameters */
    reference = ref;
    resolution = res;
    input = in;

    /* setup sequence */
    ADC_SEQUENCE_SETUP(reference | resolution | ADC_AIN7);

  }

  command void AdcControl.disable() {

    /* disable ADC interrupt */
    ADCIE = 0; 
  }


  /****************************************************************************
  **
  ****************************************************************************/
  command error_t PortControl.start[uint8_t id]() {
  
    /* enable channel if not already enabled */
    if (!inUse[id]) {
        inUse[id] = TRUE;
        ADC_ENABLE_CHANNEL(id);  

        /* number of ADC values to be transfered by DMA */
        counter++;
        dmaConfigValue->LEN = counter;
        dmaConfigRegister->LEN = counter;

        if (counter == 1) {
            call Dma1.armChannel();
            call Dma2.armChannel();
        }
    }
 
  
    return SUCCESS;
  }
 
  command error_t PortControl.stop[uint8_t id]() {
  
    /* disable channel if not already disabled */
    if (inUse[id]) {
        inUse[id] = FALSE;
        ADC_DISABLE_CHANNEL(id);  

        /* number of ADC values to be transfered by DMA */
        counter--;
        dmaConfigValue->LEN = counter;
        dmaConfigRegister->LEN = counter;

        if (counter == 0) {
            call Dma1.stopTransfer();
            call Dma2.stopTransfer();
        }
    }
 
    return SUCCESS;
  }


  /****************************************************************************
  **
  ****************************************************************************/
  command error_t Read.read[uint8_t id]() {

    /* start conversion sequence */        
    ADC_SAMPLE_SINGLE();
//    ADC_SAMPLE_CONTINUOUS();

    /* setup extra conversion of the reference voltage */
    ADC_SINGLE_CONVERSION(ADC_REF_AVDD | ADC_14_BIT | ADC_PVR);
    
    return SUCCESS;  
  }
   

  task void signalReadDone();
  int16_t value;

  async event void Dma1.transferDone() {
//    call StdOut.print("DMA val\n\r");              
  }

  async event void Dma2.transferDone() {
//    call StdOut.print("DMA reg\n\r");          
  }

  /* Interrupt handler */
  MCS51_INTERRUPT(SIG_ADC) {

    /* read reference value from register */        
    value = (( (uint16_t) ADCH) << 8);
    value |= ADCL;

    /* extra conversion done - process readings */
    post signalReadDone();
  }

  task void signalReadDone() {
    uint8_t i, id, res;
    error_t result;
      
    /* map out reference value according to resolution */
    value >>= 2;
        
    /* if reference value is correct, assume conversion is correct */
    if (value == 0x01FF)
        result = SUCCESS;
    else
        result = FAIL;
        
    /* setup resolution shifting */        
    res = (8 - (resolution >> 3));

    /* traverse adc readings */
    for (i = 0; i < counter; i++) {

        /* read port id from register */    
        id = ((adc_port[i] & 0x0F) - 1);
        
        /* buggy cc2430 */
        id = (id == 0x0C) ? 0x07 : id;

        /* signal value */        
        signal Read.readDone[id](result, adc_value[i] >> res);    

//        call StdOut.print("ID: ");
//        call StdOut.printHex(id);
//        call StdOut.print(": ");
//        call StdOut.printHexword(adc_value[i]);
//        call StdOut.print("\n\r");                
    }

//    call StdOut.print("\n\r");        

  }

  default event void Read.readDone[uint8_t id](error_t result, int16_t val) { }

  async event void StdOut.get(uint8_t c) {
  }
}

⌨️ 快捷键说明

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