/****************************************************************************** * * Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * Use of the Software is limited solely to applications: * (a) running on a Xilinx device, or * (b) that interact with a Xilinx device through a bus or interconnect. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of the Xilinx shall not be used * in advertising or otherwise to promote the sale, use or other dealings in * this Software without prior written authorization from Xilinx. * ******************************************************************************/ /****************************************************************************/ /** * * @file xsysmon_extmux_example.c * * This file contains a design example using the driver functions * of the System Monitor/ADC driver. This example shows the usage of the * driver/device in interrupt mode with external mux and XADC in Simulateneous * Sequencer mode. This example hasn't been tested with the analog inputs * connected through external mux. It is provided to illustrate the usage of * external mux. * * @note * * This code assumes that no Operating System is being used. * * *
*
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -----------------------------------------------------
* 5.00a sdm  08/30/11 First release
* 5.03a bss  04/25/13 Modified SysMonIntrExample function to set
*		      Sequencer Mode as Safe mode instead of Single
*		      channel mode before configuring Sequencer registers.
*		      CR #703729
* 
* *****************************************************************************/ /***************************** Include Files ********************************/ #include "xsysmon.h" #include "xparameters.h" #include "xstatus.h" #include "xintc.h" #include "stdio.h" #include "xil_exception.h" /************************** Constant Definitions ****************************/ /* * The following constants map to the XPAR parameters created in the * xparameters.h file. They are defined here such that a user can easily * change all the needed parameters in one place. */ #define SYSMON_DEVICE_ID XPAR_SYSMON_0_DEVICE_ID #define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID #define INTR_ID XPAR_INTC_0_SYSMON_0_VEC_ID #define printf xil_printf /* Small foot-print printf function */ /**************************** Type Definitions ******************************/ /***************** Macros (Inline Functions) Definitions ********************/ /************************** Function Prototypes *****************************/ static int SysMonIntrExample(XIntc* IntcInstPtr, XSysMon* SysMonInstPtr, u16 SysMonDeviceId, u16 SysMonIntrId); static void SysMonInterruptHandler(void *CallBackRef); static int SysMonSetupInterruptSystem(XIntc* IntcInstPtr, XSysMon *SysMonPtr, u16 IntrId ); /************************** Variable Definitions ****************************/ static XSysMon SysMonInst; /* System Monitor driver instance */ static XIntc IntcInst; /* Instance of the XIntc driver */ volatile static int EosFlag = FALSE; /* EOS interrupt */ /****************************************************************************/ /** * * Main function that invokes the Interrupt example. * * @param None. * * @return * - XST_SUCCESS if the example has completed successfully. * - XST_FAILURE if the example has failed. * * @note None. * *****************************************************************************/ int main(void) { int Status; /* * Run the SysMonitor interrupt example, specify the parameters that * are generated in xparameters.h. */ Status = SysMonIntrExample(&IntcInst, &SysMonInst, SYSMON_DEVICE_ID, INTR_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; } return XST_SUCCESS; } /****************************************************************************/ /** * * This function runs a test on the XADC device using the driver APIs. * * The function does the following tasks: * - Initiate the XADC device driver instance * - Run self-test on the device * - Reset the device * - Set up sequencer registers to continuously monitor the auxiliary * channel pairs avaibale in XADC * - Setup interrupt system * - Enable interrupts * - Set up configuration registers to start the sequencer in simultaneous * sampling mode * - Wait until End of sequence interrupt occurs and read the conversion * data * * @param IntcInstPtr is a pointer to the Interrupt Controller * driver Instance. * @param SysMonInstPtr is a pointer to the XSysMon driver Instance. * @param SysMonDeviceId is the XPAR__DEVICE_ID value * from xparameters.h. * @param SysMonIntrId is * XPAR___VEC_ID value from * xparameters.h. * * @return * - XST_SUCCESS if the example has completed successfully. * - XST_FAILURE if the example has failed. * * @note This function may never return if no interrupt occurs. * ****************************************************************************/ static int SysMonIntrExample(XIntc* IntcInstPtr, XSysMon* SysMonInstPtr, u16 SysMonDeviceId, u16 SysMonIntrId) { int Status; XSysMon_Config *ConfigPtr; u32 IntrStatus; u32 IntrEnable; u32 AdcData[8]; int Index; printf("\r\nXADC External MUX Example. \r\n"); /* * Initialize the SysMon driver. */ ConfigPtr = XSysMon_LookupConfig(SysMonDeviceId); if (ConfigPtr == NULL) { return XST_FAILURE; } XSysMon_CfgInitialize(SysMonInstPtr, ConfigPtr, ConfigPtr->BaseAddress); /* * Self Test the System Monitor/ADC device. */ Status = XSysMon_SelfTest(SysMonInstPtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Disable the Channel Sequencer before configuring the Sequencer. */ XSysMon_SetSequencerMode(SysMonInstPtr, XSM_SEQ_MODE_SAFE); /* * Enable the following auxiliary channel pairs in the Sequencer * registers: * - Auxiliary Channel 0 & 8 * - Auxiliary Channel 1 & 9 * - Auxiliary Channel 2 & 10 * - Auxiliary Channel 3 & 11 */ Status = XSysMon_SetSeqChEnables(SysMonInstPtr, 0x0F0000); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the ADCCLK frequency equal to 1/32 of System clock for the System * Monitor/ADC in the Configuration Register 2. */ XSysMon_SetAdcClkDivisor(SysMonInstPtr, 32); /* * Setup the interrupt system. */ Status = SysMonSetupInterruptSystem(IntcInstPtr, SysMonInstPtr, SysMonIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable global interrupt of System Monitor. */ XSysMon_IntrGlobalEnable(SysMonInstPtr); /* * Clear any pending interrupts. */ IntrStatus = XSysMon_IntrGetStatus(SysMonInstPtr); XSysMon_IntrClear(SysMonInstPtr, IntrStatus); /* * Enable EOS interrupts. */ XSysMon_IntrEnable(SysMonInstPtr, XSM_IPIXR_EOS_MASK); IntrEnable = XSysMon_IntrGetEnabled(SysMonInstPtr); if ((IntrEnable & XSM_IPIXR_EOS_MASK) != XSM_IPIXR_EOS_MASK) { return XST_FAILURE; } /* * Enable external Mux and connect to Aux CH0 and Aux CH8. */ XSysMon_SetExtenalMux(SysMonInstPtr, 0x10); /* 0b'10000 to CH[4:0] */ /* * Enable simultaneous sequencer mode. */ XSysMon_SetSequencerMode(SysMonInstPtr, XSM_SEQ_MODE_SIMUL); while (EosFlag != TRUE); EosFlag = FALSE; /* Clear the Flag */ XSysMon_GetStatus(SysMonInstPtr); /* Clear the latched status */ /* * Read the ADC converted Data from the data registers. */ /* Read ADC data for channels 0 - 3 */ for (Index = 0; Index < 4; Index++) { AdcData[Index] = XSysMon_GetAdcData(SysMonInstPtr, XSM_CH_AUX_MIN + Index); } /* Read ADC data for channels 8 - 11 */ for (Index = 0; Index < 4; Index++) { AdcData[Index + 4] = XSysMon_GetAdcData(SysMonInstPtr, XSM_CH_AUX_MIN + Index + 8); } return XST_SUCCESS; } /*****************************************************************************/ /** * * This function is the Interrupt Service Routine for the XADC device. * It will be called by the processor when an interrupt is asserted by the * device. * * There are 10 different interrupts supported * - Over Temperature * - ALARM 0 * - ALARM 1 * - ALARM 2 * - End of Sequence * - End of Conversion * - JTAG Locked * - JATG Modified * - Over Temperature DeActive * - ALARM 0 DeActive * * This function only handles EOS interrupts. * User of this code may need to modify the code to meet the needs of the * application. * * @param CallBackRef is the callback reference passed from the Interrupt * controller driver, which in our case is a pointer to the * driver instance. * * @return None. * * @note This function is called within interrupt context. * ******************************************************************************/ static void SysMonInterruptHandler(void *CallBackRef) { u32 IntrStatusValue; XSysMon *SysMonPtr = (XSysMon *)CallBackRef; /* * Get the interrupt status from the device and check the value. */ IntrStatusValue = XSysMon_IntrGetStatus(SysMonPtr); if (IntrStatusValue & XSM_IPIXR_EOS_MASK) { /* * Set End of Conversion interrupt flag so the code * in application context can be aware of this interrupt. */ EosFlag = TRUE; XSysMon_GetStatus(SysMonPtr); /* Clear the latched status */ } /* * Clear all bits in Interrupt Status Register. */ XSysMon_IntrClear(SysMonPtr, IntrStatusValue); } /****************************************************************************/ /** * * This function sets up the interrupt system so interrupts can occur for the * System Monitor/ADC. The function is application-specific since the actual * system may or may not have an interrupt controller. The System Monitor/ADC * device could be directly connected to a processor without an interrupt * controller. The user should modify this function to fit the application. * * @param IntcInstPtr is a pointer to the Interrupt Controller driver * Instance. * @param SysMonPtr is a pointer to the driver instance for the System * Monitor device which is going to be connected to the interrupt * controller. * @param IntrId is XPAR___VEC_ID * value from xparameters.h * * @return XST_SUCCESS if successful, or XST_FAILURE. * * @note None. * * ****************************************************************************/ static int SysMonSetupInterruptSystem(XIntc* IntcInstPtr, XSysMon *SysMonPtr, u16 IntrId ) { int Status; /* * Initialize the interrupt controller driver so that it's ready to use. */ Status = XIntc_Initialize(IntcInstPtr, INTC_DEVICE_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the handler that will be called when an interrupt * for the device occurs, the handler defined above performs the * specific interrupt processing for the device. */ Status = XIntc_Connect(IntcInstPtr, IntrId, (XInterruptHandler) SysMonInterruptHandler, SysMonPtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Start the interrupt controller so interrupts are enabled for all * devices that cause interrupts. Specify real mode so that the System * Monitor/ACD device can cause interrupts through the interrupt * controller. */ Status = XIntc_Start(IntcInstPtr, XIN_REAL_MODE); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable the interrupt for the System Monitor/ADC device. */ XIntc_Enable(IntcInstPtr, IntrId); /* * Initialize the exception table. */ Xil_ExceptionInit(); /* * Register the interrupt controller handler with the exception table. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler) XIntc_InterruptHandler, IntcInstPtr); /* * Enable non-critical exceptions. */ Xil_ExceptionEnable(); return XST_SUCCESS; }