Added burstmode ADC conversion mode, with CONFIG_ADC_BURSTMODE option in Kconfig. From Max

This commit is contained in:
Gregory Nutt 2014-07-24 16:23:31 -06:00
parent ab572091c5
commit fdff663e57

View File

@ -158,6 +158,8 @@ static void adc_reset(FAR struct adc_dev_s *dev)
regval |= SYSCON_PCONP_PCADC;
putreg32(regval, LPC17_SYSCON_PCONP);
/* Power up before we access hardware */
putreg32(ADC_CR_PDN, LPC17_ADC_CR);
regval = getreg32(LPC17_SYSCON_PCLKSEL0);
@ -165,39 +167,70 @@ static void adc_reset(FAR struct adc_dev_s *dev)
regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_ADC_SHIFT);
putreg32(regval, LPC17_SYSCON_PCLKSEL0);
#ifdef CONFIG_ADC_BURSTMODE
clkdiv = LPC17_CCLK / 3 / 65 / priv->sps;
//putreg32(0x04, LPC17_ADC_INTEN); /* Enable only last channel interrupt */
putreg32(0x100, LPC17_ADC_INTEN); /* Enable only global interrupt */
putreg32((priv->mask) | /* Select channels 0 to 7 on ADC0 */
// (clkdiv) << 8) | /* CLKDIV = divisor to make the samples
// * per second conversion rate */
((32) << 8) | /* CLKDIV = divisor to make the faster
* conversion rate */
(0 << 16) | /* BURST = 0, BURST capture all selected
* channels */
(1 << 17) | /* Reserved bit = 0 */
(1 << 21) | /* PDN = 1, normal operation */
(1 << 26) | (0 << 25) | (0 << 24) | /* START = at MAT0 signal */
(1 << 27), /* EDGE = 1 (CAP/MAT signal rising
* trigger A/D conversion) */
LPC17_ADC_CR);
#else /*CONFIG_ADC_BURSTMODE*/
clkdiv = LPC17_CCLK / 8 / 65 / priv->sps;
clkdiv <<= 8;
clkdiv &= 0xff00;
putreg32(ADC_CR_PDN | ADC_CR_BURST | clkdiv | priv->mask, LPC17_ADC_CR);
#endif /*CONFIG_ADC_BURSTMODE*/
if ((priv->mask & 0x01) != 0)
{
lpc17_configgpio(GPIO_AD0p0);
}
if ((priv->mask & 0x02) != 0)
{
lpc17_configgpio(GPIO_AD0p1);
}
if ((priv->mask & 0x04) != 0)
{
lpc17_configgpio(GPIO_AD0p2);
}
if ((priv->mask & 0x08) != 0)
{
lpc17_configgpio(GPIO_AD0p3);
}
if ((priv->mask & 0x10) != 0)
{
lpc17_configgpio(GPIO_AD0p4);
}
if ((priv->mask & 0x20) != 0)
{
lpc17_configgpio(GPIO_AD0p5);
}
if ((priv->mask & 0x40) != 0)
{
lpc17_configgpio(GPIO_AD0p6);
}
if ((priv->mask & 0x80) != 0)
{
lpc17_configgpio(GPIO_AD0p7);
@ -276,6 +309,7 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable)
if (enable)
{
#ifndef CONFIG_ADC_BURSTMODE
#ifdef CONFIG_ADC_CHANLIST
/* Trigger interrupt at the end of conversion on the last A/D channel
* in the channel list.
@ -288,6 +322,11 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable)
putreg32(ADC_INTEN_GLOBAL, LPC17_ADC_INTEN);
#endif
#else /*CONFIG_ADC_BURSTMODE*/
/* Enable only global interrupt */
putreg32(0x100, LPC17_ADC_INTEN);
#endif /*CONFIG_ADC_BURSTMODE*/
}
else
{
@ -320,6 +359,7 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
static int adc_interrupt(int irq, void *context)
{
#ifndef CONFIG_ADC_BURSTMODE
#ifdef CONFIG_ADC_CHANLIST
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
@ -359,23 +399,198 @@ static int adc_interrupt(int irq, void *context)
unsigned char ch;
int32_t value;
regval = getreg32(LPC17_ADC_GDR);
ch = (regval >> 24) & 0x07;
priv->buf[ch] += regval & 0xfff0;
regval = getreg32(LPC17_ADC_GDR);
ch = (regval >> 24) & 0x07;
priv->buf[ch] += regval & 0xfff0;
priv->count[ch]++;
if (priv->count[ch] >= CONFIG_ADC0_AVERAGE)
{
value = priv->buf[ch] / priv->count[ch];
value <<= 15;
value = priv->buf[ch] / priv->count[ch];
value <<= 15;
adc_receive(&g_adcdev,ch,value);
priv->buf[ch] = 0;
priv->count[ch] = 0;
priv->buf[ch] = 0;
priv->count[ch] = 0;
}
return OK;
#endif
#else /*CONFIG_ADC_BURSTMODE*/
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
volatile uint32_t regVal, regVal2, regVal3;
//lpc17_gpiowrite(LPCXPRESSO_GPIO0_21, 1); /* Set pin P0.21 */
/* Teste si une interruption a bien eu lieu */
regVal2 = getreg32(LPC17_ADC_STAT); /* Read ADSTAT will clear the interrupt flag */
if ((regVal2) & (1<<16))
{
if ((priv->mask & 0x01) != 0)
{
regVal = getreg32(LPC17_ADC_DR0);
#ifdef CONFIG_ADC_DIRECT_ACCESS
/* Store the data value plus the status bits */
ADC0Buffer0[0] = regVal;
ADC0IntDone = 1;
#else /* CONFIG_ADC_DIRECT_ACCESS */
#ifdef CONFIG_ADC_WORKER_THREAD
/* Store the data value plus the status bits */
ADC0Buffer0[0] = regVal;
ADC0IntDone = 1;
#else /* CONFIG_ADC_WORKER_THREAD */
if ((regVal) & (1 << 31))
{
adc_receive(&g_adcdev, 0, (regVal >> 4) & 0xFFF);
}
#endif /* CONFIG_ADC_WORKER_THREAD */
#endif /* CONFIG_ADC_DIRECT_ACCESS */
#ifdef CONFIG_ADC_DEBUG_DAC
/* Adjust the binary value to the lpc1768's register format (plus high
* speed profile in bit 16)
*/
// putreg32(((((regVal >> 4) & 0xFFF) << 6)| 0x10000) & 0xffff, LPC17_DAC_CR);
#endif /*CONFIG_ADC_DEBUG_DAC*/
}
if ((priv->mask & 0x02) != 0)
{
regVal = getreg32(LPC17_ADC_DR1);
#ifdef CONFIG_ADC_DIRECT_ACCESS
/* Store the data value plus the status bits */
ADC1Buffer0[0] = regVal;
ADC0IntDone = 1;
#else /*CONFIG_ADC_DIRECT_ACCESS*/
#ifdef CONFIG_ADC_WORKER_THREAD
/* Store the data value plus the status bits */
ADC1Buffer0[0] = regVal;
ADC0IntDone = 1;
#else /*CONFIG_ADC_WORKER_THREAD*/
if ((regVal) & (1 << 31))
{
adc_receive(&g_adcdev, 1, (regVal >> 4) & 0xFFF);
}
#endif /*CONFIG_ADC_WORKER_THREAD*/
#endif /*CONFIG_ADC_DIRECT_ACCESS*/
}
if ((priv->mask & 0x04) != 0)
{
regVal = getreg32(LPC17_ADC_DR2);
#ifdef CONFIG_ADC_DIRECT_ACCESS
/* Store the data value plus the status bits */
ADC2Buffer0[0] = regVal;
ADC0IntDone = 1;
#else /*CONFIG_ADC_DIRECT_ACCESS*/
#ifdef CONFIG_ADC_WORKER_THREAD
/* Store the data value plus the status bits */
ADC2Buffer0[0] = regVal;
ADC0IntDone = 1;
#else /*CONFIG_ADC_WORKER_THREAD*/
if ((regVal) & (1 << 31))
{
adc_receive(&g_adcdev, 2, (regVal >> 4) & 0xFFF);
}
#endif /*CONFIG_ADC_WORKER_THREAD*/
#endif /*CONFIG_ADC_DIRECT_ACCESS*/
}
#ifdef CONFIG_ADC_WORKER_THREAD
/* Store the data value plus the status bits */
ADC2Buffer0[0] = regVal;
ADC0IntDone = 1;
#else /* CONFIG_ADC_WORKER_THREAD */
if ((priv->mask & 0x08) != 0)
{
regVal = getreg32(LPC17_ADC_DR3);
if ((regVal) & (1 << 31))
{
adc_receive(&g_adcdev, 3, (regVal >> 4) & 0xFFF);
}
}
if ((priv->mask & 0x10) != 0)
{
regVal = getreg32(LPC17_ADC_DR4);
if ((regVal) & (1 << 31))
{
adc_receive(&g_adcdev, 4, (regVal >> 4) & 0xFFF);
}
}
if ((priv->mask & 0x20) != 0)
{
regVal = getreg32(LPC17_ADC_DR5);
if ((regVal) & (1 << 31))
{
adc_receive(&g_adcdev, 5, (regVal >> 4) & 0xFFF);
}
}
if ((priv->mask & 0x40) != 0)
{
regVal = getreg32(LPC17_ADC_DR6);
if ((regVal) & (1 << 31))
{
adc_receive(&g_adcdev, 6, (regVal >> 4) & 0xFFF);
}
}
if ((priv->mask & 0x80) != 0)
{
regVal = getreg32(LPC17_ADC_DR7);
if ((regVal) & (1 << 31))
{
adc_receive(&g_adcdev, 7, (regVal >> 4) & 0xFFF);
}
}
#endif /*CONFIG_ADC_WORKER_THREAD*/
#ifdef CONFIG_ADC_WORKER_THREAD
if (ADC0IntDone == 1)
{
work_queue(HPWORK, &priv->irqwork, (worker_t)adc_irqworker, (FAR void *)priv, 0);
}
#endif /*CONFIG_ADC_WORKER_THREAD*/
regVal3 = getreg32(LPC17_ADC_GDR); /* Read ADGDR clear the DONE and OVERRUN bits */
putreg32((priv->mask) | /* Select channels 0 to 7 on ADC0 */
((32) << 8) | /* CLKDIV = 16 */
(0 << 16) | /* BURST = 1, BURST capture all selected channels */
(1 << 17) | /* Reserved bit = 0 */
(1 << 21) | /* PDN = 1, normal operation */
(1 << 26) | (0 << 25) | (0 << 24) | /* START = at MAT0 signal */
(1 << 27), /* EDGE = 1 (CAP/MAT signal rising trigger A/D
* conversion) */
LPC17_ADC_CR);
//lpc17_gpiowrite(LPCXPRESSO_GPIO0_21, 0); /* Reset pin P0.21 */
//irqrestore(saved_state);
return OK;
#endif /*CONFIG_ADC_BURSTMODE*/
}
/****************************************************************************
@ -389,7 +604,7 @@ static int adc_interrupt(int irq, void *context)
* Initialize the adc
*
* Returned Value:
* Valid can device structure reference on succcess; a NULL on failure
* Valid can device structure reference on success; a NULL on failure
*
****************************************************************************/