Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

A/D converter: a conversion is never completed

2005-11-09 by Joerg Sommer

Hi,

I have a LPC2292 and want to use some analog input channels (Ain0, Ain1,
Ain6) to get data from analog sensors. I use this routine to initialize
the sensors:

#v+
void sensors_init(void)
{
    /* setup the A/D converter
     * use Ain0, Ain1, Ain6: 0x1 + 0x2 + 0x40
     * divide the PCLK by 13+1 to get 4.5MHz: 0xD00
     * repeat the evaluation: 0x10000
     * 11 bits accuracy: bit 17--19 cleared
     * enable: 0x200000
     * start with timer 0 match 2: 0x2000000 (configured in rtc.c)
     */
    write_reg(ADCR, 0x2210D43);

    /* set the usage of P0.27--P0.28 as Ain for brightness and temperature */
    write_reg(PINSEL1, (read_reg(PINSEL1) & 0xFC3FFFFF) | 0x1400000);

    /* no need to set the usage of P3.29 as Ain6 for voltage, because this is
       done by the fix BOOT value of 01 */

    /* P1.24 and P1.25 are GPIO input pins by default; nothing to change */

    /* set the interrupt routine */
    write_reg(VICVectCntl12, 0x32);
    write_reg(VICVectAddr12, (uint32_t)interrupt_handler);
    write_reg(VICIntEnable, 0x40000);	  /* enable A/D conv. interrupt line */
}
#v-

and this routine as interrupt handler:

#v+
static void
#if defined(__arm__) && defined(__GNUC__)
  __attribute__ ((interrupt ("IRQ") ))
#endif
    interrupt_handler(void)
{
    uint32_t reg = read_reg(ADDR);

    if ( (reg & 1<<31) != 0 ) {
        /* no value available, the A/D converter need some time */
        update_VIC();
        return;
    }

    uint16_t val = (reg >> 6) & 0x3FF;
    switch ( (reg >> 24) & 0x7 ) {
      case 0:
        if (sensors_get_brightness() != val) {
            uint8_t tmp = sensors_get_brightness();
            sensors_last_brightness = val;

            if ( ! sensors_is_standby() && (tmp / 32) != (val / 32) )
              display_set_dimming( nvram_sensors_cfg->dim_level[val/32] );
        }
        break;
      case 1:
        if (sensors_get_temperature() != val) {
            sensors_last_temp = val;

            if (val > nvram_sensors_cfg->temp_threshold)
              display_set_dimming( 0 );
        }
        break;
      case 6:
        if (sensors_get_voltage() != val) {
            sensors_last_voltage = val;
        }
        break;
    }

    update_VIC();
}
#v-

If I poll the ADDR register I see the DONE bit is never set. The Match
0.1 works, because this triggers an interrupt and I get this one. What is
wrong? Why the DONE bit is never set and the interrupt handler is never
called. Any ideas?

Bye, Joerg.
-- 
And 1.1.81 is officially BugFree(tm), so if you receive any bug-reports
on it, you know they are just evil lies.
         -- Linus Torvalds

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.