aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c')
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c317
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);
+}
+