mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 16:50:55 +08:00
Added burstmode ADC conversion mode, with CONFIG_ADC_BURSTMODE option in Kconfig. From Max
This commit is contained in:
@@ -158,6 +158,8 @@ static void adc_reset(FAR struct adc_dev_s *dev)
|
|||||||
regval |= SYSCON_PCONP_PCADC;
|
regval |= SYSCON_PCONP_PCADC;
|
||||||
putreg32(regval, LPC17_SYSCON_PCONP);
|
putreg32(regval, LPC17_SYSCON_PCONP);
|
||||||
|
|
||||||
|
/* Power up before we access hardware */
|
||||||
|
|
||||||
putreg32(ADC_CR_PDN, LPC17_ADC_CR);
|
putreg32(ADC_CR_PDN, LPC17_ADC_CR);
|
||||||
|
|
||||||
regval = getreg32(LPC17_SYSCON_PCLKSEL0);
|
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);
|
regval |= (SYSCON_PCLKSEL_CCLK8 << SYSCON_PCLKSEL0_ADC_SHIFT);
|
||||||
putreg32(regval, LPC17_SYSCON_PCLKSEL0);
|
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 = LPC17_CCLK / 8 / 65 / priv->sps;
|
||||||
clkdiv <<= 8;
|
clkdiv <<= 8;
|
||||||
clkdiv &= 0xff00;
|
clkdiv &= 0xff00;
|
||||||
putreg32(ADC_CR_PDN | ADC_CR_BURST | clkdiv | priv->mask, LPC17_ADC_CR);
|
putreg32(ADC_CR_PDN | ADC_CR_BURST | clkdiv | priv->mask, LPC17_ADC_CR);
|
||||||
|
|
||||||
|
#endif /*CONFIG_ADC_BURSTMODE*/
|
||||||
|
|
||||||
if ((priv->mask & 0x01) != 0)
|
if ((priv->mask & 0x01) != 0)
|
||||||
{
|
{
|
||||||
lpc17_configgpio(GPIO_AD0p0);
|
lpc17_configgpio(GPIO_AD0p0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((priv->mask & 0x02) != 0)
|
if ((priv->mask & 0x02) != 0)
|
||||||
{
|
{
|
||||||
lpc17_configgpio(GPIO_AD0p1);
|
lpc17_configgpio(GPIO_AD0p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((priv->mask & 0x04) != 0)
|
if ((priv->mask & 0x04) != 0)
|
||||||
{
|
{
|
||||||
lpc17_configgpio(GPIO_AD0p2);
|
lpc17_configgpio(GPIO_AD0p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((priv->mask & 0x08) != 0)
|
if ((priv->mask & 0x08) != 0)
|
||||||
{
|
{
|
||||||
lpc17_configgpio(GPIO_AD0p3);
|
lpc17_configgpio(GPIO_AD0p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((priv->mask & 0x10) != 0)
|
if ((priv->mask & 0x10) != 0)
|
||||||
{
|
{
|
||||||
lpc17_configgpio(GPIO_AD0p4);
|
lpc17_configgpio(GPIO_AD0p4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((priv->mask & 0x20) != 0)
|
if ((priv->mask & 0x20) != 0)
|
||||||
{
|
{
|
||||||
lpc17_configgpio(GPIO_AD0p5);
|
lpc17_configgpio(GPIO_AD0p5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((priv->mask & 0x40) != 0)
|
if ((priv->mask & 0x40) != 0)
|
||||||
{
|
{
|
||||||
lpc17_configgpio(GPIO_AD0p6);
|
lpc17_configgpio(GPIO_AD0p6);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((priv->mask & 0x80) != 0)
|
if ((priv->mask & 0x80) != 0)
|
||||||
{
|
{
|
||||||
lpc17_configgpio(GPIO_AD0p7);
|
lpc17_configgpio(GPIO_AD0p7);
|
||||||
@@ -276,6 +309,7 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable)
|
|||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_ADC_BURSTMODE
|
||||||
#ifdef CONFIG_ADC_CHANLIST
|
#ifdef CONFIG_ADC_CHANLIST
|
||||||
/* Trigger interrupt at the end of conversion on the last A/D channel
|
/* Trigger interrupt at the end of conversion on the last A/D channel
|
||||||
* in the channel list.
|
* 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);
|
putreg32(ADC_INTEN_GLOBAL, LPC17_ADC_INTEN);
|
||||||
#endif
|
#endif
|
||||||
|
#else /*CONFIG_ADC_BURSTMODE*/
|
||||||
|
/* Enable only global interrupt */
|
||||||
|
|
||||||
|
putreg32(0x100, LPC17_ADC_INTEN);
|
||||||
|
#endif /*CONFIG_ADC_BURSTMODE*/
|
||||||
}
|
}
|
||||||
else
|
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)
|
static int adc_interrupt(int irq, void *context)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_ADC_BURSTMODE
|
||||||
#ifdef CONFIG_ADC_CHANLIST
|
#ifdef CONFIG_ADC_CHANLIST
|
||||||
|
|
||||||
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
|
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;
|
unsigned char ch;
|
||||||
int32_t value;
|
int32_t value;
|
||||||
|
|
||||||
regval = getreg32(LPC17_ADC_GDR);
|
regval = getreg32(LPC17_ADC_GDR);
|
||||||
ch = (regval >> 24) & 0x07;
|
ch = (regval >> 24) & 0x07;
|
||||||
priv->buf[ch] += regval & 0xfff0;
|
priv->buf[ch] += regval & 0xfff0;
|
||||||
|
|
||||||
priv->count[ch]++;
|
priv->count[ch]++;
|
||||||
if (priv->count[ch] >= CONFIG_ADC0_AVERAGE)
|
if (priv->count[ch] >= CONFIG_ADC0_AVERAGE)
|
||||||
{
|
{
|
||||||
value = priv->buf[ch] / priv->count[ch];
|
value = priv->buf[ch] / priv->count[ch];
|
||||||
value <<= 15;
|
value <<= 15;
|
||||||
adc_receive(&g_adcdev,ch,value);
|
adc_receive(&g_adcdev,ch,value);
|
||||||
priv->buf[ch] = 0;
|
priv->buf[ch] = 0;
|
||||||
priv->count[ch] = 0;
|
priv->count[ch] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
#endif
|
#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
|
* Initialize the adc
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Valid can device structure reference on succcess; a NULL on failure
|
* Valid can device structure reference on success; a NULL on failure
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user