Jump to content
  • 0

Problem with XADC channels in Nexys 4


SpainFPGAGuy

Question

Hello,

I am facing a problem I don't understand. Probably I am miss-configuring something, but I don't find what.

I am using XADC of the Nexys4 board through the PMOD connector. The design is a Microblaze with the XADC connected and a external memory to store the samples.

The XADC is configured on single channel, and feed with a waveform generator sending a sine wave of 1 KHz.

When I use the first pair of inputs, of the PMOD connector, Vaux3 in the board I get a perfect sinwave in the output. 

When I use any other XADC channel I get this a distortioned input. I use the same program and XADC configuration just changing the channel used. I get the same input on adc aux channel 2,10 and 11. Only channel 3 works.

The program I am using is this. It configures the XADC in single channel and send the data through serial port. I recover it in a python program and paint them.

Any idea?
 

#include <stdio.h>
#include "xparameters.h"
#include "platform.h"
#include "xsysmon.h"
#include "xil_printf.h"
#include "xstatus.h"
#include "xuartlite.h"


#define UARTLITE_DEVICE_ID    XPAR_UARTLITE_0_DEVICE_ID
#define SYSMON_DEVICE_ID     XPAR_SYSMON_0_DEVICE_ID
#define UART_BUFFER_SIZE 16

#define NUMBER_OF_SAMPLES 4500

int main()
{
    static XSysMon SysMonInst;      /* System Monitor driver instance */
    unsigned int ReceivedCount = 0;
    unsigned char RecvBuffer[UART_BUFFER_SIZE];
    XUartLite UartLite;

    unsigned int channel = 3;

    int Status;
    XSysMon_Config *ConfigPtr;
    XSysMon *SysMonInstPtr = &SysMonInst;
    int *sample;

    //External memory address to store samples
    sample=(int *)0x60000000;

    init_platform();

    Status = XUartLite_Initialize(&UartLite, UARTLITE_DEVICE_ID);

    while(1){
      

        ReceivedCount = 0;
        while(ReceivedCount==0){
            ReceivedCount = XUartLite_Recv(&UartLite, (unsigned char *) RecvBuffer, 1);
        }
      
        ConfigPtr = XSysMon_LookupConfig(SYSMON_DEVICE_ID);
        if (ConfigPtr == NULL) {
            return XST_FAILURE;
        }

        XSysMon_CfgInitialize(SysMonInstPtr, ConfigPtr, ConfigPtr->BaseAddress);

        XSysMon_SetAvg(SysMonInstPtr, XSM_AVG_0_SAMPLES);


        XSysMon_SetAdcClkDivisor(SysMonInstPtr, 39);

        XSysMon_SetSequencerMode(SysMonInstPtr, XSM_SEQ_MODE_SINGCHAN);

        XSysMon_SetCalibEnables(SysMonInstPtr,
                    XSM_CFR1_CAL_PS_GAIN_OFFSET_MASK |
                    XSM_CFR1_CAL_ADC_GAIN_OFFSET_MASK);

        Status=  XSysMon_SetSingleChParams(SysMonInstPtr, XSM_CH_AUX_MIN+channel,
                                FALSE, FALSE, TRUE);

        if(Status != XST_SUCCESS) {
            return XST_FAILURE;
        }

        /*
         * Disable all the alarms in the Configuration Register 1.
         */
        XSysMon_SetAlarmEnables(SysMonInstPtr, 0x0);


        /*
         * Wait till the End of conversion
         */
        //print("Capturing\n\r");
        for(int i=0;i<NUMBER_OF_SAMPLES;i++){
            XSysMon_GetStatus(SysMonInstPtr); /* Clear the old status */
            while ((XSysMon_GetStatus(SysMonInstPtr) & XSM_SR_EOC_MASK) !=
                XSM_SR_EOC_MASK);

            //Four last bits are noise
            *(sample+i) = XSysMon_GetAdcData(SysMonInstPtr, XSM_CH_AUX_MIN+channel);

        }
        //print("Finish capture\n\r");

        //xil_printf("samples=np.array([");
        for(int i=0;i<NUMBER_OF_SAMPLES-1;i++){
            xil_printf("%d,",*(sample+i));
        }
        xil_printf("%d\r\n",*(sample+NUMBER_OF_SAMPLES-1));

        xil_printf("end\n");

    }

    cleanup_platform();
    return 0;
}

 

 

 

 

 

correct.jpg

notcorrect.jpg

xadc.png

microblaze.jpg

Link to comment
Share on other sites

5 answers to this question

Recommended Posts

As far as I can tell from your code, you are continuously reinitialize and reconfigure the XSysMon (the XADC driver). During this process, which is redundant, you are loosing a lot of samples.

Try this instead:

#include <stdio.h>
#include "xparameters.h"
#include "platform.h"
#include "xsysmon.h"
#include "xil_printf.h"
#include "xstatus.h"
#include "xuartlite.h"


#define UARTLITE_DEVICE_ID    XPAR_UARTLITE_0_DEVICE_ID
#define SYSMON_DEVICE_ID     XPAR_SYSMON_0_DEVICE_ID
#define UART_BUFFER_SIZE 16

#define NUMBER_OF_SAMPLES 4500

int main()
{
    static XSysMon SysMonInst;      /* System Monitor driver instance */
    unsigned int ReceivedCount = 0;
    unsigned char RecvBuffer[UART_BUFFER_SIZE];
    XUartLite UartLite;

    unsigned int channel = 3;

    int Status;
    XSysMon_Config *ConfigPtr;
    XSysMon *SysMonInstPtr = &SysMonInst;
    int *sample;

    //External memory address to store samples
    sample=(int *)0x60000000;

    init_platform();

    Status = XUartLite_Initialize(&UartLite, UARTLITE_DEVICE_ID);

    ReceivedCount = 0;
    while(ReceivedCount==0){
        ReceivedCount = XUartLite_Recv(&UartLite, (unsigned char *) RecvBuffer, 1);
    }

    ConfigPtr = XSysMon_LookupConfig(SYSMON_DEVICE_ID);
    if (ConfigPtr == NULL) {
        return XST_FAILURE;
    }

    XSysMon_CfgInitialize(SysMonInstPtr, ConfigPtr, ConfigPtr->BaseAddress);

    XSysMon_SetAvg(SysMonInstPtr, XSM_AVG_0_SAMPLES);


    XSysMon_SetAdcClkDivisor(SysMonInstPtr, 39);

    XSysMon_SetSequencerMode(SysMonInstPtr, XSM_SEQ_MODE_SINGCHAN);

    XSysMon_SetCalibEnables(SysMonInstPtr,
                XSM_CFR1_CAL_PS_GAIN_OFFSET_MASK |
                XSM_CFR1_CAL_ADC_GAIN_OFFSET_MASK);

    Status=  XSysMon_SetSingleChParams(SysMonInstPtr, XSM_CH_AUX_MIN+channel,
                            FALSE, FALSE, TRUE);

    if(Status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    /*
     * Disable all the alarms in the Configuration Register 1.
     */
    XSysMon_SetAlarmEnables(SysMonInstPtr, 0x0);

    while(1){


        /*
         * Wait till the End of conversion
         */
        //print("Capturing\n\r");
        for(int i=0;i<NUMBER_OF_SAMPLES;i++){
            XSysMon_GetStatus(SysMonInstPtr); /* Clear the old status */
            while ((XSysMon_GetStatus(SysMonInstPtr) & XSM_SR_EOC_MASK) !=
                XSM_SR_EOC_MASK);

            //Four last bits are noise
            *(sample+i) = XSysMon_GetAdcData(SysMonInstPtr, XSM_CH_AUX_MIN+channel);

        }
        //print("Finish capture\n\r");

        //xil_printf("samples=np.array([");
        for(int i=0;i<NUMBER_OF_SAMPLES-1;i++){
            xil_printf("%d,",*(sample+i));
        }
        xil_printf("%d\r\n",*(sample+NUMBER_OF_SAMPLES-1));

        xil_printf("end\n");

    }

    cleanup_platform();
    return 0;
}

 

Link to comment
Share on other sites

Thank you very much for your answer. It is true I am reconfiguring it, I moved the code outside the loop.

However the reads are done in this loop, so Ishould not miss samples.

for(int i=0;i<NUMBER_OF_SAMPLES;i++){

	XSysMon_GetStatus(SysMonInstPtr);

	while ((XSysMon_GetStatus(SysMonInstPtr) & XSM_SR_EOC_MASK) != XSM_SR_EOC_MASK);

	*(sample+i) = XSysMon_GetAdcData(SysMonInstPtr, XSM_CH_AUX_MIN+channel);

}

The main problem is that it works for aux_channel 3, like you can see in the capture, but fails in all the other channels.

Regards

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...