aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.CodeGeneration/ProtoProperty.cs
blob: 73debac37352b8752e2ac5cc359c57ed44243565 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tango.CodeGeneration
{
    public class ProtoProperty : Property
    {
        public bool Repeated { get; set; }

        public String Description { get; set; }

        public ProtoProperty()
        {

        }

        public ProtoProperty(String name, String type) : this()
        {
            Name = name;
            Type = type;
        }

        public ProtoProperty(String name, String type, String description) : this(name, type)
        {
            Description = description;
        }
    }
}
//*****************************************************************************
//
// This is the data acquisition module.  It performs acquisition of data from
// selected channels, starting and stopping data logging, storing acquired
// data, and running the strip chart display.
//
//*****************************************************************************
/*
Notes:
    12 shared analog input channels
    12-bit precision ADC
    Hardware averaging of up to 64 samples
    As referred before the ADC has a  reference of 3V.

    Voltage reference selected using the VREF field in the ADCCTL register (page 1217)

    J0062
            PIN 21  - AN_IDS_PRESSENS_7
            PIN 9   - GND

    J0252
            PIN 21  - AN_IDS_PRESSENS_1
            PIN 9   - GND

    J0042
            PIN 21  - AN_IDS_PRESSENS_3
            PIN 9   - GND

    J0251
            PIN 21  - AN_IDS_PRESSENS_4
            PIN 9   - GND

                J0262
            PIN 21  - AN_IDS_PRESSENS_6
            PIN 9   - GND
                        J0162
            PIN 21  - AN_IDS_PRESSENS_5
            PIN 9   - GND

-----------------
void ADCAcquireInit(void) // (MillisecInit) ok

void ADCAcquireStart(ProcessCallback _callback, uint32_t _period)// (called by MillisecStart)

//reading Trigger
uint32_t ADC_TriggerCollection(void) // MillisecLoop
//Data Get
void ADC0SS0Handler(void)

each ADC there are 4 sequencers with combined sequence steps of 17 (8+4+4+1).
Hence out of 24 channels any 17 can be mapped.
If all channels are required then both ADC's are required (unless dynamic changes are being sought after).
//----------------------------------------------------


uint32_t ADC_GetReading(int DataItemId)// ADC Data get for a single data read

Void ADCProcessTask(UArg arg0, UArg arg1)

void ADCAcquireStop(void) //MillisecStop

//---------------------------------


        for (adc_i = 0; adc_i < MAX_ADC_DEVICES ; adc_i++)
            ADC_Data[adc_i] = ADC_GetReading(adc_i);
*/

#include "ADC.h"
#include "include.h"
#include <stdbool.h>

#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>

#include <driverlib/adc.h>
#include <driverlib/rom_map.h>
#include <driverlib/interrupt.h>


#include <inc/hw_memmap.h>
#include <inc/hw_ints.h>

//*****************************************************************************
//
// The following defines which ADC channel control should be used for each
// kind of data item.  Basically it maps how the ADC channels are connected
// on the board.  This is a hardware pinmap configuration.
// Physical ADC connected channels in the TIVA
//*****************************************************************************

#define CHAN_AIR_PRESSURE_1         ADC_CTL_CH0
#define CHAN_AIR_PRESSURE_2         ADC_CTL_CH1
#define CHAN_DISPENSE_PRESSURE_1    ADC_CTL_CH2
#define CHAN_DISPENSE_PRESSURE_2    ADC_CTL_CH3
#define CHAN_DISPENSE_PRESSURE_3    ADC_CTL_CH4
#define CHAN_DISPENSE_PRESSURE_4    ADC_CTL_CH5
#define CHAN_DISPENSE_PRESSURE_5    ADC_CTL_CH6
#define CHAN_DISPENSE_PRESSURE_6    ADC_CTL_CH7
#define CHAN_DISPENSE_PRESSURE_7    ADC_CTL_CH8
#define CHAN_DISPENSE_PRESSURE_8    ADC_CTL_CH9
#define CHAN_VOCSENS                ADC_CTL_CH10
#define CHAN_SPARE1                 ADC_CTL_CH11
#define CHAN_SPARE2                 ADC_CTL_CH12
#define CHAN_LEFT_DANCER_1          ADC_CTL_CH13
#define CHAN_LEFT_DANCER_2          ADC_CTL_CH14
#define CHAN_RIGHT_DANCER           ADC_CTL_CH15
#define CHAN_DRYER_CURRENT_1        ADC_CTL_CH16
#define CHAN_DRYER_CURRENT_2        ADC_CTL_CH17
#define CHAN_DRYER_CURRENT_3        ADC_CTL_CH18
#define CHAN_3V3_FPGA               ADC_CTL_CH19
/*
Connected with pull down to reg GND ADC_CTL_CH20
Connected with pull down to reg GND ADC_CTL_CH21
config as digital input from FPGA 3 ADC_CTL_CH22
config as Digital input from FPGA 3 ADC_CTL_CH23
*/

//*****************************************************************************
//
// The following maps the order that items are acquired and stored by the
// ADC sequencers.  Note that 16 samples are specified, using 2 of the
// 8 sample sequencers.  The current is sampled multiple times deliberately
// because that value tends to bounce around.  It is sampled multiple
// times and will be averaged.
//
//*****************************************************************************


uint32_t g_pui32ADCSeq[MAX_ADC_DEVICES] =
{
 CHAN_AIR_PRESSURE_1,      //0
 CHAN_AIR_PRESSURE_2,      //1
 CHAN_DISPENSE_PRESSURE_1, //2      J0252 ,PIN 21  - AN_IDS_PRESSENS_1, PIN 9   - GND
 CHAN_DISPENSE_PRESSURE_2, //3      J0142 ,PIN 21  - AN_IDS_PRESSENS_2, PIN 9   - GND
 CHAN_DISPENSE_PRESSURE_3, //4      J0042 ,PIN 21  - AN_IDS_PRESSENS_3, PIN 9   - GND
 CHAN_DISPENSE_PRESSURE_4, //5      J0152 ,PIN 21  - AN_IDS_PRESSENS_4, PIN 9   - GND
 CHAN_DISPENSE_PRESSURE_5, //6      J0162 ,PIN 21  - AN_IDS_PRESSENS_5, PIN 9   - GND
 CHAN_DISPENSE_PRESSURE_6, //7      J0262 ,PIN 21  - AN_IDS_PRESSENS_6, PIN 9   - GND
 CHAN_DISPENSE_PRESSURE_7, //8      J0062 ,PIN 21  - AN_IDS_PRESSENS_7, PIN 9   - GND
 CHAN_DISPENSE_PRESSURE_8, //9      J0052 ,PIN 21  - AN_IDS_PRESSENS_8, PIN 9   - GND
 CHAN_VOCSENS,             //10     J0072 ,PIN 21  - AN_VOCSENS, PIN  9   - GND
 CHAN_SPARE1,              //11
 CHAN_SPARE2,              //12
 CHAN_LEFT_DANCER_1,       //13      J0002 ,PIN 21  - AN5V_LDANCER1, PIN  9   - GND
 CHAN_LEFT_DANCER_2,       //14      J0002 ,PIN 22  - AN5V_LDANCER1, PIN 10   - GND
 CHAN_RIGHT_DANCER,        //15      J0102 ,PIN 21  - AN5V_RDANCER, PIN 9   - GND
 CHAN_DRYER_CURRENT_1,     //16      J1292 ,PIN 7  - AN_DRYER_CURSEN_1p, PIN 19   - AN_DRYER_CURSEN_1n
 CHAN_DRYER_CURRENT_2,     //17      J1292 ,PIN 8  - AN_DRYER_CURSEN_1p, PIN 20   - AN_DRYER_CURSEN_1n
 CHAN_DRYER_CURRENT_3,     //18      J1292 ,PIN 9  - AN_DRYER_CURSEN_1p, PIN 21   - AN_DRYER_CURSEN_1n
 CHAN_3V3_FPGA,            //19
};

//#define NUM_ADC_CHANNELS        (sizeof(g_pui32ADCSeq) /                      \
                                 sizeof(g_pui32ADCSeq[0]))
int DispenserIdToPressureSensorId[MAX_DISPENSERS] = {CHAN_DISPENSE_PRESSURE_1, CHAN_DISPENSE_PRESSURE_2 , CHAN_DISPENSE_PRESSURE_3 , CHAN_DISPENSE_PRESSURE_4 , CHAN_DISPENSE_PRESSURE_5 , CHAN_DISPENSE_PRESSURE_6 , CHAN_DISPENSE_PRESSURE_7 , CHAN_DISPENSE_PRESSURE_8 };

//const uint8_t Num_ADC_Channels = ( sizeof(g_pui32ADCSeq) / sizeof(g_pui32ADCSeq[0]) );

//#define SAMPLE_ARRAY_SIZE (NUM_ADC_CHANNELS + I2C_NUM_OF_CHANNELS)
//#define SAMPLE_ARRAY_SIZE NUM_ADC_CHANNELS


static bool isInitialized = false;
static bool adcCollectActive = false;
static int bufferFlipFlop = 0;

//*****************************************************************************
//
// Global _storage for most recent sampled Sensor Data
//
//*****************************************************************************
//
// A buffer to hold one set of ADC data that is acquired per sample time.
//
//*****************************************************************************
static uint32_t g_pui32ADCData[DOUBLE_BUFFER][MAX_ADC_DEVICES];

//*****************************************************************************
//configured in the cfg file and thats why should be defined as extern
//*****************************************************************************
extern Semaphore_Handle adcResultSem;

static ProcessCallback processCallBack;

//*****************************************************************************
// ADCClockHandle: clock event handler - initiates trigger for the adc sampaling
//*****************************************************************************
// This function starts an ADC Conversion.
//static void ADCClockHandle(UArg arg0)
uint32_t ADC_TriggerCollection(void) // (called by MillisecLoop)
{
    //
    // Kick off the next ADC acquisition.  When these are done they will
    // cause an ADC interrupt.
    //
    if (adcCollectActive == true)
    {
        MAP_ADCProcessorTrigger(ADC1_BASE, 0);
        MAP_ADCProcessorTrigger(ADC0_BASE, 0);
        MAP_ADCProcessorTrigger(ADC0_BASE, 1);
    }
    return 0;
}
//*****************************************************************************
//
// ADC Data get for a single data read
//
//*****************************************************************************
uint32_t ADC_GetReading(int DataItemId) //  // ADC Data get for a single data read
{
    int bufnotinuse;
    assert (DataItemId<MAX_ADC_DEVICES);

    if (bufferFlipFlop == 0)  bufnotinuse = 1;
    else  bufnotinuse = 0;
    return (g_pui32ADCData[bufnotinuse][DataItemId]);


}

//*****************************************************************************
//
// This is the handler for the ADC interrupt.  Even though more than one
// sequencer is used, they are configured so that this one runs last.
// Therefor when this ADC sequencer interrupt occurs, we know all of the ADC
// data has been acquired.
//
//*****************************************************************************
void ADC0SS0Handler(void)
{
    //
    // Clear the interrupts for all ADC sequencers that are used.
    //
    MAP_ADCIntClear(ADC0_BASE, 0);
    MAP_ADCIntClear(ADC1_BASE, 0);
    MAP_ADCIntClear(ADC0_BASE, 1);

    if (bufferFlipFlop == 0)  bufferFlipFlop = 1;
    else  bufferFlipFlop = 0;
    //
    // Retrieve the data from all ADC sequencers
    //
    MAP_ADCSequenceDataGet(ADC0_BASE, 0, &g_pui32ADCData[bufferFlipFlop][0]);
    //offset in the array calculated as sampling of 16 channels each one of 16 bits
    MAP_ADCSequenceDataGet(ADC1_BASE, 0, &g_pui32ADCData[bufferFlipFlop][8]);
    MAP_ADCSequenceDataGet(ADC0_BASE, 1, &g_pui32ADCData[bufferFlipFlop][16]);
    //
    // Release adc result semaphore
    //
    //the ADC Process task is mot currently active. the results will be copied to a second buffer and supplied upon request
	//Semaphore_post(adcResultSem);
}

//*****************************************************************************
//
//*****************************************************************************
Void ADCProcessTask(UArg arg0, UArg arg1)
{
	while(1)
	{
		//
		// Wait until new ADC data is available
		//
		Semaphore_pend(adcResultSem, BIOS_WAIT_FOREVER);

		//
		// Process the ADC data
		//
		if (processCallBack != NULL)
		{
			processCallBack(g_pui32ADCData[bufferFlipFlop]);
		}
	}
}


void ADCAcquireInit(void) // (called by MillisecInit)
{
    uint32_t ui32Chan, ui32Base, ui32Seq;
#ifndef EVALUATION_BOARD

    //Avaraging 8 //TODO
    //MAP_ADCHardwareOversampleConfigure(ADC0_BASE, 8);
    //MAP_ADCHardwareOversampleConfigure(ADC1_BASE, 8);
    //
    // Initialize both ADC peripherals using sequencer 0 and processor trigger.
    //
    MAP_ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
    MAP_ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
    MAP_ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 1); //sequencer 1

    ADCSequenceDisable(ADC0_BASE, 1);

    //
    // Enter loop to configure all of the ADC sequencer steps needed to
    // acquire the data for the data logger.  Multiple ADC and sequencers
    // will be used in order to acquire all the channels.
    //
    for(ui32Chan = 0; ui32Chan < MAX_ADC_DEVICES; ui32Chan++)
    {
        //
        // If this is the first ADC then set the base for ADC0
        //
        if(ui32Chan < 8)
        {
            ui32Base = ADC0_BASE;
            ui32Seq = 0;
        }
        else if(ui32Chan < 16)
        {
            //
            // Second ADC, set the base for ADC1
            //
            ui32Base = ADC1_BASE;
            ui32Seq = 0;
        }
        else
        {
            ui32Base = ADC0_BASE;
            ui32Seq = 1;
        }



        //
        // Get the channel control for each channel.  Test to see if it is the
        // last channel for the sequencer, and if so then also set the
        // interrupt and "end" flags.
        //
        uint32_t ui32ChCtl = g_pui32ADCSeq[ui32Chan];
        //TODO define all the numbers under #define and not here
        if((ui32Chan == 7) || (ui32Chan == 15)  || (ui32Chan == (MAX_ADC_DEVICES - 1)))
        {
            ui32ChCtl |= ADC_CTL_IE | ADC_CTL_END;
        }

        //
        // Configure the sequence step
        //
        MAP_ADCSequenceStepConfigure(ui32Base, ui32Seq, ui32Chan % 8, ui32ChCtl);
    }

    ADCSequenceEnable(ADC0_BASE, 1);

    ADCReferenceSet(ADC0_BASE, ADC_REF_EXT_3V);
    ADCReferenceSet(ADC1_BASE, ADC_REF_EXT_3V);

    if (!isInitialized)
    {
        // Create a periodic Clock Instance with _period - triggers the ADC sampling
        isInitialized = true;

        //InitI2C();
    }
#endif
}

//*****************************************************************************
//
// This function is called to start an acquisition running.  It determines
// which channels are to be logged, enables the ADC/I2C sequencers.
// This will start the acquisition running.
//
//*****************************************************************************
void ADCAcquireStart(ProcessCallback _callback, uint32_t _period) // (called by MillisecStart)
{
#ifndef EVALUATION_BOARD
    //
    // Enable the ADC sequencers
    //
    MAP_ADCSequenceEnable(ADC0_BASE, 0);
    MAP_ADCSequenceEnable(ADC1_BASE, 0);
    MAP_ADCSequenceEnable(ADC0_BASE, 1);

    //
    // Flush the ADC sequencers to be sure there is no lingering/ trush data.
    //
    MAP_ADCSequenceDataGet(ADC0_BASE, 0, g_pui32ADCData[0]);
    MAP_ADCSequenceDataGet(ADC1_BASE, 0, g_pui32ADCData[0]);
    MAP_ADCSequenceDataGet(ADC1_BASE, 1, g_pui32ADCData[0]);

    //
    // Enable ADC interrupts
    //
    MAP_ADCIntClear(ADC0_BASE, 0);
    MAP_ADCIntClear(ADC1_BASE, 0);
    MAP_ADCIntEnable(ADC0_BASE, 0);
    MAP_ADCIntEnable(ADC0_BASE, 1);
    ROM_IntEnable(INT_ADC0SS0);

    // Store process
    processCallBack = _callback;
    // Start a periodic Clock Instance with _period - triggers the ADC sampling
    adcCollectActive = true;
    //
    // Logging data should now start running
    //
#endif
}

//*****************************************************************************
//
// This function is called to stop an acquisition running.  It disables the
// ADC sequencers.
//
//*****************************************************************************
void ADCAcquireStop(void)
{
	//Stop trigger adc sampling
	adcCollectActive = false;
    //
    // Disable ADC interrupts
    //
    MAP_IntDisable(INT_ADC0SS0);
    MAP_IntDisable(INT_ADC1SS0);

    //
    // Disable ADC sequencers
    //
    MAP_ADCSequenceDisable(ADC0_BASE, 0);
    MAP_ADCSequenceDisable(ADC1_BASE, 0);
    MAP_ADCSequenceDisable(ADC0_BASE, 1);
}

double  Calculate_Pitot_Pressure() // WHS - AN_AIRPRESS_1
{
    //MPXV7002 (NXP)
    uint32_t VsampleInBits;

    double Pressure = 0.0, temp, PKpa,PBar,VADC = 0.0 ,VSensor,PMicroBar;

    VsampleInBits = ADC_GetReading(CHAN_AIR_PRESSURE_1);

    //---- VBits -> VADC ----

    //ADC 12 bit -> 4096 -> 2.5V

    temp = VsampleInBits*2.5;
    VADC =  temp / 4096;

    //---- VADC -> VSensor ---

    //VADC = 1.96 - 10k( VSensor - 1.96) / 46.4k (from the electrical scheme)
    // VSensor = 0 V  -> VADC = 2.3824 V
    // VSensor = 10 V -> VADC = 0.2272 V

    VSensor = (1.96- VADC) * 4.64 + 1.96;

    PKpa = 5 * VSensor;
        // ---- P[Kpa] -> BAR ----

    PBar = PKpa / 100.0;

    PMicroBar = PBar/1000;
    Pressure = PMicroBar;

    return Pressure;
}

uint8_t  Calculate_Gas_Power_Consumption() // WHS
{
    // TGS 2602 (FIGARO)


/*       Concentrtion  Sensor
            [ppm]      [v]
              0      0.353
             18      0.438
             33      2.919
            100      4.196
            316      4.571
*/

    double VOC_Vsensor[]  =
    {
        0.353, //0  PPM
        0.357, //1  PPM
        0.362, //2  PPM
        0.367, //3  PPM
        0.371, //4  PPM
        0.376, //5  PPM
        0.381, //6  PPM
        0.386, //7  PPM
        0.390, //8  PPM
        0.395, //9  PPM
        0.400, //10 PPM
        0.404, //11 PPM
        0.409, //12 PPM
        0.414, //13 PPM
        0.419, //14 PPM
        0.423, //15 PPM
        0.428, //16 PPM
        0.433, //17 PPM
        0.438, //18 PPM
        0.603, //19 PPM
        0.768, //20 PPM
        0.934, //21 PPM
        1.099, //22 PPM
        1.265, //23 PPM
        1.430, //24 PPM
        1.595, //25 PPM
        1.761, //26 PPM
        1.926, //27 PPM
        2.092, //28 PPM
        2.257, //29 PPM
        2.422, //30 PPM
        2.588, //31 PPM
        2.753, //32 PPM
        2.919  //33 PPM
    };

    uint32_t VsampleInBits;

    double temp, VADC = 0.0 ,VSensor;

    uint8_t PPM = sizeof(VOC_Vsensor) / sizeof(VOC_Vsensor[0]), i;

    VsampleInBits = ADC_GetReading(CHAN_VOCSENS);

    //---- VBits -> VADC ----

    //ADC 12 bit -> 4096 -> 2.5V

    temp = VsampleInBits*2.5;
    VADC =  temp / 4096;

    //---- VADC -> VSensor ---

    //VADC = 1.96 - 10k( VSensor - 1.96) / 46.4k (from the electrical scheme)
    // VSensor = 0 V  -> VADC = 2.3824 V
    // VSensor = 10 V -> VADC = 0.2272 V

    VSensor = (1.96- VADC) * 4.64 + 1.96;

    for(i=0;i<PPM;i++)
    {
        if(VSensor <= VOC_Vsensor[i])
        {
            PPM = i;
        }
    }
    return PPM;
}