AnsweredAssumed Answered

HSADC

Question asked by ravi kumar on Aug 12, 2015
Latest reply on Aug 13, 2015 by Yuri Muhin

Driver for data capture from lradc 6 or hsadc 0 pins

 

I have written a small driver for capturing data from LRADC6 pin using HSADC. The code for configuring the hsadc is as follows

 

int mxs_hsadc_init()
{

int i;
unsigned int reg;
// mxs_hsadc_clk_enable();

__raw_writel(BF_CLKCTRL_FRAC1_HSADCFRAC(0x3f), HW_CLKCTRL_BASE_ADDRESS+HW_CLKCTRL_FRAC1_CLR); /* Clear */

__raw_writel(BF_CLKCTRL_FRAC1_HSADCFRAC(30), HW_CLKCTRL_BASE_ADDRESS+HW_CLKCTRL_FRAC1_SET); /* Set to 288 MHz*/
/* Clear the clock gate*/
__raw_writel(BM_CLKCTRL_FRAC1_CLKGATEHSADC, HW_CLKCTRL_BASE_ADDRESS+HW_CLKCTRL_FRAC1_CLR);

/* Set the HSADC CLK ADC divider to ge the Operation clock of 16 MHz*/
__raw_writel(BM_CLKCTRL_HSADC_RESETB | BF_CLKCTRL_HSADC_FREQDIV( 1 /*CLKCTRL_HSADC_FREQDIV_18*/), HW_CLKCTRL_BASE_ADDRESS+HW_CLKCTRL_HSADC);

/* 1st workaround for HSADC */
__raw_writel(HSADC_CTRL0_RESET,hsadc_base + HSADC_CTRL0_CLR);

for (i = 0; i < 10000; i++) {
reg = __raw_readl(hsadc_base + HSADC_CTRL0);
if (!(reg & HSADC_CTRL0_RESET))
break;
udelay(3);
}
__raw_writel(HSADC_CTRL0_RESET & (~HSADC_CTRL0_CLKGATE_OFF), hsadc_base + HSADC_CTRL0_SET);

__raw_writel(HSADC_CTRL0_CLKGATE_OFF,hsadc_base + HSADC_CTRL0_SET);
__raw_writel(HSADC_CTRL0_CLKGATE_OFF,hsadc_base + HSADC_CTRL0_CLR);
__raw_writel(HSADC_CTRL0_CLKGATE_OFF,hsadc_base + HSADC_CTRL0_SET);
/* 1st workaround for HSADC */

// __raw_writel(HSADC_CTRL0_CLKGATE_OFF,hsadc_base + HSADC_CTRL0_CLR);
__raw_writel(HSADC_CTRL0_RESET,hsadc_base + HSADC_CTRL0_CLR);

for (i = 0; i < 10000; i++) {
reg = __raw_readl(hsadc_base + HSADC_CTRL0);
if (!(reg & HSADC_CTRL0_RESET))
break;
udelay(3);
}
__raw_writel(HSADC_CTRL0_CLKGATE_OFF,hsadc_base + HSADC_CTRL0_CLR);

/*Disable the interrupts*/
__raw_writel(HSADC_INTR_CTRL_TIMEOUT_ENB ,hsadc_base + HSADC_CTRL1_CLR);
__raw_writel(HSADC_INTR_CTRL_END_SEQ_ENB,hsadc_base + HSADC_CTRL1_CLR);
__raw_writel(HSADC_INTR_CTRL_ADC_DONE_ENB,hsadc_base + HSADC_CTRL1_CLR);
__raw_writel(HSADC_INTR_CTRL_FIFO_OVFW_ENB,hsadc_base + HSADC_CTRL1_CLR);
__raw_writel(HSADC_INTR_CLR,hsadc_base + HSADC_CTRL1_SET);
__raw_writel(HSADC_INTR_STATUS_CLR,hsadc_base + HSADC_CTRL1_SET);

/* HSADC is set to SINGLE Mode*/
reg = 0x1;
__raw_writel(reg , hsadc_base +HSADC_SEQ_NUM);

/*Number of samples*/
reg = 0x1;
__raw_writel(reg , hsadc_base +HSADC_SEQ_SAM_NUM);

/*Power Register config */
reg =0x84000626;
__raw_writel(reg , REGS_POWER_BASE + HW_POWER_ANACLKCTRL);

/* Wake up from power down mode */
__raw_writel(HSADC_CTRL2_POWER_DOWN,hsadc_base + HSADC_CTRL2_CLR);

/*Set PreCharge Enable */
__raw_writel(HSADC_CTRL2_PRECHARGE,hsadc_base + HSADC_CTRL2_SET);

/*Set HSADC_RUN mode*/
__raw_writel(HSADC_CTRL0_RUN,hsadc_base + HSADC_CTRL0_SET);

return 0;
}

 

this code is from a another post in this community only. The hsadc is configured and i am able to read the status of control and debug registers.

The values that i get in case of single sample capture and total one sequence (configured in single capture mode) is as follows

The values posted here are in hex

ctrl0 reg : 40

ctrl1 : f0000003

 

The run bit for ctrl0 register is set in the code handling capture data. But after a number of capture of data the status of the ctrl registers change to

ctrl0 reg : 41

ctrl1 reg : f000001b which implies fifo overflow. Is there any way to clear the fifo data because it is not given in the hsadc documentation. I am reading the HW_HSADC_FIFO_DATA register to read the data. IS it the correct way of reading data from the Hsadc

 

I am also clearing the interrupt status by setting the corresponding bits.

Outcomes