ADC not showing registers in peripheral view

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

ADC not showing registers in peripheral view

1,332 Views
petervangrieken
Contributor II

I have an application in freertos for an LPC1769 that is using an ADC to read out a temperature sensor. The problem is that when debugging, I can't see the registers of the ADC in the memory monitor. Other peripherals like GPIO etc can be inspected without problems.

The weird thing is that when I hover the mouse over the ADC, I get a popup saying the ADC is disabled (?). I'm not sure why because the ADC is actually working (dumping the ADDR0 register via ethernet to a PC and working fine). Am I doing something wrong or is this a bug in LPCXpresso?

Using LPCXpresso 8.2.2 (just upgraded from 8.2.0 because of this issue, but same issue)

Debugger: lpclink 2

OS: Win8 x64

Screenshot showing problem with memory monitor not showing registers:

ADC.jpg

same debug session showing memory monitor with GPIO (registers show up just fine):

Untitled.jpg

Labels (2)
Tags (3)
0 Kudos
4 Replies

739 Views
lpcxpresso_supp
NXP Employee
NXP Employee

So as I said before, the Peripherals View (in top left of the IDE windows) will show the ADC grayed out (disabled) based on the value of the  PCAD bit of the PCONP register when the view is updated (i.e. when program execution is halted, for example when hitting a breakpoint).

On the other hand, if the ADC peripheral has been added to the Memory View, then this will show the registers within the ADC peripheral if the accesses the debugger makes to that set of registers do not cause a memory access fault. Which could be due to the PCAD bit again, to the ADC peripheral clock, or for other reasons.

I can only assume that you are seeing some strange mismatch between these two things. However I have been unable to reproduce this here.

Regards,

LPCXpresso Support

0 Kudos

739 Views
petervangrieken
Contributor II

Hi, 

sorry this took a while (working on several projects at the same time)...

I took a look at the ADC init routines, but I'm actually doing this literally by the book (code below). The first thing I do is set the PCADC bit in the PCONP register, and I double checked this function to be called before doing anything else with the ADC. 

Init routine called from main() before any threads are started:

void my_Init_ADC(void)
{
   // 1. Power: In the PCONP register (Table 46), set the PCADC bit.
   // Remark: On reset, the ADC is disabled. To enable the ADC, first set the PCADC bit,
   // and then enable the ADC in the AD0CR register (bit PDN Table 532). To disable the
   // ADC, first clear the PDN bit, and then clear the PCADC bit.

   LPC_SC->PCONP = LPC_SC->PCONP | ( 1 << PCADC);       // Enable power to ADC peripheral

   // 2. Clock: In the PCLKSEL0 register (Table 40), select PCLK_ADC. To scale the clock for
   // the ADC, see bits CLKDIV in Table 532.

   LPC_SC->PCLKSEL0 = LPC_SC->PCLKSEL0 | (1 << PCLK_ADC);                // Enable peripheral clock to ADC peripheral.
   LPC_ADC->ADCR = (0x01 << SEL) | (4095 << CLKDIV) | (1 << BURST) | (1 << PDN) | (0x00 << START) | (0 << EDGE);

   // 3. Pins: Enable ADC0 pins through PINSEL registers. Select the pin modes for the port
   // pins with ADC0 functions through the PINMODE registers (Section 8.5).

   LPC_PINCON->PINSEL1 = LPC_PINCON->PINSEL1 | (0x01 << 14);                  // Enable ADC0.0 on P0.23
   //LPC_PINCON->PINMODE1 = LPC_PINCON->PINMODE1 | (0x02 << 14);       // no pullup/pulldown resistor
   LPC_PINCON->PINMODE1 = LPC_PINCON->PINMODE1 | (0x03 << 14);         // Pullup resistor


   // 4. Interrupts: To enable interrupts in the ADC, see Table 536. Interrupts are enabled in
   // the NVIC using the appropriate Interrupt Set Enable register. Disable the ADC
   // interrupt in the NVIC using the appropriate Interrupt Set Enable register.

   // 5. DMA: See Section 29.6.4. For GPDMA system connections, see Table 544.
}

I did some further testing, and actually it appears to be very inconsistent here (note: this is all done in the same debug session, breakpoint is set and I just resume the debug session until the breakpoint is hit):

- Sometimes the ADC is indicated in grey as if it is disabled, but I can see the peripheral and it's registers just fine:

pastedImage_4.png

- Sometimes the ADC is indicated as grey as if it's disabled and I can not see the registers of the peripheral

Capture2.JPG

- Sometimes the peripheral shows as enabled and I can perfectly well see the registers:

pastedImage_6.png

Could this be related to the fact this is a freertos project? It's not a really urgent issue for me as the ADC appears to be working properly in the application, but nevertheles I'm interested to know what I'm doing wrong...

With kind regards

Peter

0 Kudos

739 Views
petervangrieken
Contributor II

Just did another quick test by modifying main() so no threads are created and the only thing running is a function that reads the ADC. So reading the ADC is not started from within a thread. Same inconsistent behaviour as in previous post however...

int main(void)
{
  signed int l_Temperature=0;
  unsigned char l_TempWarningLevel=0;

  setup_main_hw();

  while(1)
  {
      CheckTemperature(&l_TempWarningLevel, &l_Temperature);
  }

  //code below not included here (starting threads) as it's not called anymore...

}

static void setup_main_hw(void)
{
   my_InitSPI();
   InitGPIO();

   ReadEepromValues();
   InitRoutingTable();

   my_Init_ADC(); // -> See function source in previous post
   Timer0Init(); // Warning: uses values from eeprom. Make sure to read eeprom before using timers!
   InitZeroCrossDetection(); // Initialize zero cross detection

}

unsigned int my_GetADCValue(void)
{
    return ( (LPC_ADC->ADDR0 & RESULT) >> 4);
}

void CheckTemperature(unsigned char *Warninglevel, signed int *Temperature)
{
   // Temperature sensor used: MCP9700.
   // Sensitivity: 0.01K/v
   // Vout = 0.1 -> 1.75V
   // Vref = 3.3V / resolution 12bit
   // Temperature = (Vout-0.5)/0.01

   double VperBit = 3.3/4095;


    static unsigned char l_WarningLevel = 0;
    *Temperature = my_GetADCValue();
    *Temperature = (((double)*Temperature * VperBit)-0.5)/0.001;

    switch (l_WarningLevel)
    {
       case 0:
       if (*Temperature > TEMPWARNINGLEVEL1)
       {
       l_WarningLevel = ERR_TEMP1;
       }
       break;

       case 1:
       if (*Temperature > TEMPWARNINGLEVEL2)
       {
       l_WarningLevel = ERR_TEMP2;
       }
       if (*Temperature < (TEMPWARNINGLEVEL1 - TEMPWARNINGLEVELTHERSHOLD))
       {
       l_WarningLevel = TEMPOK;
       }
       break;

       case 2:
       if (*Temperature < (TEMPWARNINGLEVEL2 - TEMPWARNINGLEVELTHERSHOLD))
       {
       l_WarningLevel = ERR_TEMP1;
       }
       break;

       default:
       break;
    }

}
 

0 Kudos

739 Views
lpcxpresso_supp
NXP Employee
NXP Employee

I've just done a quick test here of the ADC peripheral display on an LPC1768 here and don't see any issue.

But just to explain, the Peripherals view for LPC175x_6x debug connections implements a simple mechanism of checking if the peripheral is enabled or not - by looking at the PCAD bit of the PCONP register. [Note that this system does not exist in the Peripherals view for other MCUs.]

However in order for the ADC to be truly enabled, you need to ensure that your code is following the full mechanism for configuring the ADC, as described in the ADC chapter of the user manual. Without this, I would imagine that some of the registers are giving bus fault errors when the debugger tries to access them.

So in the first place double check your ADC setup code and let us know if you still see issues after fixing any issues.

Regards,

LPCXpresso Support

0 Kudos