// ***************************************************************************** // // 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 #include #include #include #include #include #include #include #include #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_DISPENSER_TEMP_3 ADC_CTL_CH0 #define CHAN_DISPENSER_TEMP_1 ADC_CTL_CH1 #define CHAN_RGB_RED ADC_CTL_CH2 #define CHAN_TEMP_3 ADC_CTL_CH3 #define CHAN_POS_WINDER ADC_CTL_CH10 #define CHAN_RGB_GREEN ADC_CTL_CH12 #define CHAN_RGB_BLUE ADC_CTL_CH13 #define CHAN_DISPENSER_TEMP_5 ADC_CTL_CH16 #define CHAN_DISPENSER_TEMP_6 ADC_CTL_CH17 #define CHAN_TEMP_1 ADC_CTL_CH18 #define CHAN_TEMP_2 ADC_CTL_CH19 #define CHAN_DISPENSER_TEMP_4 ADC_CTL_CH20 #define CHAN_POS_POOLER ADC_CTL_CH21 #define CHAN_DISPENSER_TEMP_2 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[] = { CHAN_DISPENSER_TEMP_3, CHAN_DISPENSER_TEMP_1, CHAN_RGB_RED, CHAN_TEMP_3, CHAN_POS_POOLER, CHAN_RGB_GREEN, CHAN_RGB_BLUE, CHAN_DISPENSER_TEMP_5, CHAN_DISPENSER_TEMP_6, CHAN_TEMP_1, CHAN_TEMP_2, CHAN_DISPENSER_TEMP_4, CHAN_DISPENSER_TEMP_2, CHAN_POS_WINDER }; #define NUM_ADC_CHANNELS (sizeof(g_pui32ADCSeq) / \ sizeof(g_pui32ADCSeq[0])) #define SAMPLE_ARRAY_SIZE (NUM_ADC_CHANNELS + I2C_NUM_OF_CHANNELS) static bool isInitialized = false; // ***************************************************************************** // // 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[SAMPLE_ARRAY_SIZE]; // ***************************************************************************** //configured in the cfg file and thats why should be defined as extern // ***************************************************************************** extern Semaphore_Handle adcResultSem; static Clock_Handle adcSampleClock; static Clock_Params clkParams; static ProcessCallback processCallBack; // ***************************************************************************** // ADCClockHandle: clock event handler - initiates trigger for the adc sampaling // ***************************************************************************** // This function starts an ADC Conversion. static void ADCClockHandle(UArg arg0) { // // Kick off the next ADC acquisition. When these are done they will // cause an ADC interrupt. // MAP_ADCProcessorTrigger(ADC1_BASE, 0); MAP_ADCProcessorTrigger(ADC0_BASE, 0); } // ***************************************************************************** // // 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); // // Retrieve the data from all ADC sequencers // MAP_ADCSequenceDataGet(ADC0_BASE, 0, &g_pui32ADCData[0]); //offset in the array calculated as sempeling of 16 channels each one of 16 bits MAP_ADCSequenceDataGet(ADC1_BASE, 0, &g_pui32ADCData[8]); // // Release adc result semaphore // 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); } } } // ***************************************************************************** // // 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 Clock_Params_init(&clkParams); clkParams.period = 0; clkParams.startFlag = FALSE; adcSampleClock = Clock_create(ADCClockHandle, 11, &clkParams, NULL); 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); MAP_ADCSequenceDataGet(ADC1_BASE, 0, g_pui32ADCData); // // Enable ADC interrupts // MAP_ADCIntClear(ADC0_BASE, 0); MAP_ADCIntClear(ADC1_BASE, 0); MAP_ADCIntEnable(ADC0_BASE, 0); MAP_IntEnable(INT_ADC0SS0); uint8_t i; for (i = NUM_ADC_CHANNELS; i < SAMPLE_ARRAY_SIZE; ++i) { g_pui32ADCData[i] = MAX_DIGITAL_POTENTIOMETER_READ; } // Store process processCallBack = _callback; // Start a periodic Clock Instance with _period - triggers the ADC sampling Clock_setPeriod(adcSampleClock, _period); Clock_start(adcSampleClock); // // 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 Clock_stop(adcSampleClock); // // Disable ADC interrupts // MAP_IntDisable(INT_ADC0SS0); MAP_IntDisable(INT_ADC1SS0); // // Disable ADC sequencers // MAP_ADCSequenceDisable(ADC0_BASE, 0); MAP_ADCSequenceDisable(ADC1_BASE, 0); }