adc initerrupts

This commit is contained in:
Lok Tep 2015-12-21 17:23:07 +01:00
parent 1481537f8c
commit 74c4f4636a

View File

@ -79,7 +79,6 @@
#ifndef CONFIG_ADC0_MASK
#define CONFIG_ADC0_MASK 0x01
#endif
#ifndef CONFIG_ADC0_FREQ
#define CONFIG_ADC0_FREQ 0
#endif
@ -87,6 +86,10 @@
#define LPC43_ADC_MAX_FREQUENCY 4500000
#define LPC43_ADC_MIN_FREQUENCY (BOARD_ABP3_FREQUENCY/256)
#if defined(CONFIG_ADC0_USE_TIMER) && CONFIG_ADC0_FREQ == 0
# error "set CONFIG_ADC0_FREQ!=0 if CONFIG_ADC0_USE_TIMER"
#endif
#ifndef CONFIG_ADC0_USE_TIMER
# if (CONFIG_ADC0_FREQ != 0 && (CONFIG_ADC0_FREQ > LPC43_ADC_MAX_FREQUENCY || CONFIG_ADC0_FREQ < LPC43_ADC_MIN_FREQUENCY))
# error "ADC0 sample rate can't be grater than LPC43_ADC_MAX_FREQUENCY or less than LPC43_ADC_MIN_FREQUENCY"
@ -101,10 +104,11 @@
struct up_dev_s
{
uint8_t mask;
uint8_t mask_int;
uint32_t freq;
int irq;
bool timer;
bool m_ch; /* multi channel */
bool m_ch;
};
/****************************************************************************
@ -137,9 +141,10 @@ static struct up_dev_s g_adcpriv =
{
.freq = CONFIG_ADC0_FREQ,
.mask = CONFIG_ADC0_MASK,
.mask_int = CONFIG_ADC0_MASK,
.irq = LPC43M4_IRQ_ADC0,
.timer = CONFIG_ADC0_USE_TIMER,
.m_ch = (CONFIG_ADC0_MASK & (CONFIG_ADC0_MASK-1))?true:false
.m_ch = ( CONFIG_ADC0_MASK & (CONFIG_ADC0_MASK-1) )?true:false
};
static struct adc_dev_s g_adcdev =
@ -167,6 +172,14 @@ static void adc_reset(FAR struct adc_dev_s *dev)
irqstate_t flags;
uint32_t regval;
if ( priv->m_ch ) /* calc MSB */
{
priv->mask_int |= (priv->mask_int >> 1);
priv->mask_int |= (priv->mask_int >> 2);
priv->mask_int |= (priv->mask_int >> 4);
priv->mask_int &= ~(priv->mask_int >> 1);
}
flags = irqsave();
/* Clock peripheral */
@ -212,7 +225,7 @@ static void adc_reset(FAR struct adc_dev_s *dev)
putreg32(TMR_EMR_EMC0_SET, LPC43_TIMER2_BASE+LPC43_TMR_EMR_OFFSET); /* external match */
putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_CTCR_OFFSET); /* counter/timer mode */
putreg32(LPC43_CCLK/priv->freq-1, LPC43_TIMER2_BASE+LPC43_TMR_PR_OFFSET); /* set clock */
putreg32(LPC43_CCLK/priv->freq/2-1, LPC43_TIMER2_BASE+LPC43_TMR_PR_OFFSET); /* set clock, divide by 2 - bug in chip */
putreg32(1, LPC43_TMR2_MR0); /* set match on 1*/
@ -228,61 +241,61 @@ static void adc_reset(FAR struct adc_dev_s *dev)
/* do pin configuration if defined */
#ifdef PINCONF_ADC0_CH0
#ifdef PINCONF_ADC0_C0
if ((priv->mask & 0x01) != 0)
{
lpc43_pin_config(PINCONF_ADC0_CH0);
lpc43_pin_config(PINCONF_ADC0_C0);
}
#endif /* PINCONF_ADC0_CH0 */
#endif /* PINCONF_ADC0_C0 */
#ifdef PINCONF_ADC0_CH1
#ifdef PINCONF_ADC0_C1
if ((priv->mask & 0x02) != 0)
{
lpc43_pin_config(PINCONF_ADC0_CH1);
lpc43_pin_config(PINCONF_ADC0_C1);
}
#endif /* PINCONF_ADC0_CH1 */
#endif /* PINCONF_ADC0_C1 */
#ifdef PINCONF_ADC0_CH2
#ifdef PINCONF_ADC0_C2
if ((priv->mask & 0x04) != 0)
{
lpc43_pin_config(PINCONF_ADC0_CH2);
lpc43_pin_config(PINCONF_ADC0_C2);
}
#endif /* PINCONF_ADC0_CH2 */
#endif /* PINCONF_ADC0_C2 */
#ifdef PINCONF_ADC0_CH3
#ifdef PINCONF_ADC0_C3
if ((priv->mask & 0x08) != 0)
{
lpc43_pin_config(PINCONF_ADC0_CH3);
lpc43_pin_config(PINCONF_ADC0_C3);
}
#endif /* PINCONF_ADC0_CH3 */
#endif /* PINCONF_ADC0_C3 */
#ifdef PINCONF_ADC0_CH4
#ifdef PINCONF_ADC0_C4
if ((priv->mask & 0x10) != 0)
{
lpc43_pin_config(PINCONF_ADC0_CH4);
lpc43_pin_config(PINCONF_ADC0_C4);
}
#endif /* PINCONF_ADC0_CH4 */
#endif /* PINCONF_ADC0_C4 */
#ifdef PINCONF_ADC0_CH5
#ifdef PINCONF_ADC0_C5
if ((priv->mask & 0x20) != 0)
{
lpc43_pin_config(PINCONF_ADC0_CH5);
lpc43_pin_config(PINCONF_ADC0_C5);
}
#endif /* PINCONF_ADC0_CH5 */
#endif /* PINCONF_ADC0_C5 */
#ifdef PINCONF_ADC0_CH6
#ifdef PINCONF_ADC0_C6
if ((priv->mask & 0x40) != 0)
{
lpc43_pin_config(PINCONF_ADC0_CH6);
lpc43_pin_config(PINCONF_ADC0_C6);
}
#endif /* PINCONF_ADC0_CH6 */
#endif /* PINCONF_ADC0_C6 */
#ifdef PINCONF_ADC0_CH7
#ifdef PINCONF_ADC0_C7
if ((priv->mask & 0x80) != 0)
{
lpc43_configgpio(PINCONF_ADC0_CH7);
lpc43_configgpio(PINCONF_ADC0_C7);
}
#endif /* PINCONF_ADC0_CH7 */
#endif /* PINCONF_ADC0_C7 */
irqrestore(flags);
}
@ -353,39 +366,32 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable)
{
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
if (enable)
{
uint32_t regval = getreg32(LPC43_ADC0_CR);
if (priv->freq == 0)
putreg32(priv->mask_int, LPC43_ADC0_INTEN);
if (priv->timer)
{
if ( priv->m_ch )
{
putreg32(ADC_INTEN_GLOBAL, LPC43_ADC0_INTEN);
regval |= ADC_CR_BURST;
}
else
{
putreg32(priv->mask, LPC43_ADC0_INTEN);
regval |= ADC_CR_START_NOW;
}
putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_PC_OFFSET); /* reset prescale counter */
putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_TC_OFFSET); /* reset timer counter */
putreg32(TMR_TCR_EN, LPC43_TIMER2_BASE+LPC43_TMR_TCR_OFFSET); /* enable the timer */
}
else
{
if ( priv->timer )
uint32_t regval = getreg32(LPC43_ADC0_CR);
if(priv->freq == 0 && !priv->m_ch)
{
putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_PC_OFFSET); /* reset prescale counter */
putreg32(0, LPC43_TIMER2_BASE+LPC43_TMR_TC_OFFSET); /* reset timer counter */
putreg32(TMR_TCR_EN, LPC43_TIMER2_BASE+LPC43_TMR_TCR_OFFSET); /* enable the timer */
putreg32(ADC_INTEN_GLOBAL, LPC43_ADC0_INTEN);
regval |= ADC_CR_START_NOW;
}
else
{
putreg32(ADC_INTEN_GLOBAL, LPC43_ADC0_INTEN);
regval |= ADC_CR_BURST;
}
}
putreg32(regval, LPC43_ADC0_CR);
putreg32(regval, LPC43_ADC0_CR);
}
}
else
{
@ -424,31 +430,28 @@ static int adc_interrupt(int irq, void *context)
if( priv->timer)
{
putreg32(TMR_EMR_EMC0_SET, LPC43_TIMER2_BASE+LPC43_TMR_EMR_OFFSET); /* clear EM0 bit by resetting default value */
}
if (priv->freq == 0 && priv->m_ch )
{
regval = getreg32(LPC43_ADC0_CR); /* clear burst while single conversation */
regval &= ~ADC_CR_BURST;
putreg32(regval, LPC43_ADC0_CR);
}
if (priv->freq == 0 && !priv->m_ch )
{
regval = getreg32(LPC43_ADC0_GDR);
adc_receive(&g_adcdev, (regval&ADC_GDR_CHAN_MASK)>>ADC_GDR_CHAN_SHIFT, (regval&ADC_GDR_VVREF_MASK)>>ADC_GDR_VVREF_SHIFT);
putreg32(TMR_EMR_EMC0_SET, LPC43_TIMER2_BASE+LPC43_TMR_EMR_OFFSET); /* put match to low */
}
else
{
int i;
for (i = 0; i < 8; i++)
if (priv->freq == 0 && priv->m_ch ) /* clear burst mode */
{
if (priv->mask & 1<<i)
{
regval = getreg32(LPC43_ADC0_DR(i));
adc_receive(&g_adcdev, i, (regval&ADC_DR_VVREF_MASK)>>ADC_DR_VVREF_SHIFT);
}
regval = getreg32(LPC43_ADC0_CR);
regval &= ~ADC_CR_BURST;
putreg32(regval, LPC43_ADC0_CR);
}
}
/* read data, clear interrupt by this */
int i;
for (i = 0; i < 8; i++)
{
if (priv->mask & 1<<i)
{
regval = getreg32(LPC43_ADC0_DR(i));
adc_receive(&g_adcdev, i, (regval&ADC_DR_VVREF_MASK)>>ADC_DR_VVREF_SHIFT);
}
}