HSADC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HSADC

665 Views
imravi
Contributor II

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.

Labels (2)
Tags (1)
0 Kudos
1 Reply

384 Views
Yuri
NXP Employee
NXP Employee

Hello,

  It is correct : to read data, please use HW_HSADC_FIFO_DATA. You may use DISCARD 
bit field of HW_HSADC_CTRL0 to avoid using non-proper data.

In order to clear the (whole) FIFO, one can apply reset via SFTRST bit of HW_HSADC_CTRL0.

But it is needed to reconfigure HSADC module after that.
To check operation complete, hsadc_irq interrupt event may be used. Please refer to Table 5-1

(i.MX28 Interrupt Sources) of the i.MX28 Reference Manual.

  Some data may be lost when CPU polling technique is applied.

Please pay attention, when working with HSADC registers bit operations may be performed :

clear / set / toggle bit. Please use it to provide bit field masking operations.

  Also, please refer to section 37.4 (Programming Example) of the i.MX28 Reference Manual.


Have a great day,
Yuri

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos