diff options
Diffstat (limited to 'Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c')
| -rw-r--r-- | Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c b/Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c new file mode 100644 index 000000000..a99ed7134 --- /dev/null +++ b/Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c @@ -0,0 +1,317 @@ +//***************************************************************************** +// +// 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. +// +//***************************************************************************** + +#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> +#include "Drivers/I2C_Communication/I2C.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_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 + +//***************************************************************************** +// +// 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[] = +{ + CHAN_AIR_PRESSURE_1,CHAN_AIR_PRESSURE_2, + 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, + CHAN_LEFT_DANCER_1, CHAN_LEFT_DANCER_2, CHAN_RIGHT_DANCER, + CHAN_DRYER_CURRENT_1, CHAN_DRYER_CURRENT_2, CHAN_DRYER_CURRENT_3 +}; + +#define 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 +#define DOUBLE_BUFFER 2 + +static bool isInitialized = false; +static bool adcCollectActive = false; +static int bufferFlipFlop = 0; + +//***************************************************************************** +// +// Global _storage for most recent sampaled Sensor Data +// +//***************************************************************************** +// +// A buffer to hold one set of ADC data that is acquired per sample time. +// +//***************************************************************************** +static uint32_t g_pui32ADCData[DOUBLE_BUFFER][SAMPLE_ARRAY_SIZE]; + +//***************************************************************************** +//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) +{ + // + // 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); + } + return 0; +} +//***************************************************************************** +// +// ADC Data get for a single data read +// +//***************************************************************************** +uint32_t ADC_GetReading(int DataItemId) +{ + 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); + + 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]); + + // + // 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]); + } + } +} + +//***************************************************************************** +// +// This function initializes the ADC hardware in preparation for data +// acquisition. +// +//***************************************************************************** +void ADCAcquireInit(void) +{ + uint32_t ui32Chan, ui32Base, ui32Seq; + + //Avaraging 8 + 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); + + + // + // 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 < NUM_ADC_CHANNELS; 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; + } + + // + // 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 == (NUM_ADC_CHANNELS - 1))) + { + ui32ChCtl |= ADC_CTL_IE | ADC_CTL_END; + } + + // + // Configure the sequence step + // + MAP_ADCSequenceStepConfigure(ui32Base, ui32Seq, ui32Chan % 8, ui32ChCtl); + } + + if (!isInitialized) + { + // Create a periodic Clock Instance with _period - triggers the ADC sampling + isInitialized = true; + + //InitI2C(); + } +} + +//***************************************************************************** +// +// 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) +{ + // + // Enable the ADC sequencers + // + MAP_ADCSequenceEnable(ADC0_BASE, 0); + MAP_ADCSequenceEnable(ADC1_BASE, 0); + + // + // 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]); + + // + // Enable ADC interrupts + // + MAP_ADCIntClear(ADC0_BASE, 0); + MAP_ADCIntClear(ADC1_BASE, 0); + MAP_ADCIntEnable(ADC0_BASE, 0); + MAP_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 + // +} + +//***************************************************************************** +// +// 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); +} + |
