AnsweredAssumed Answered

LPC824 ADC demo HardFault problem

Question asked by Davaa Dorj on Dec 13, 2018
Latest reply on Dec 17, 2018 by Davaa Dorj

I'm trying to program LPC824 microcontroller board (LPC824 300mil board パーツセット - スイッチサイエンス ) with LPCOpen. I'm using it with LPCLink 2 debugger board.

 

My goal is to get some information from pressure sensor with ADC.

 

My code stops with a HardFault when executing a NVIC_EnableIRQ (on line: 92) function.

 

If I don't use "NVIC interrupt controller" then my code works and I can get value from sensor with ADC.

 

I am a beginner. Please help me. What I am doing wrong?

 

Here is my adc.c code:

 

#include "board.h"

static volatile int ticks;
static bool sequenceComplete = false;
static bool thresholdCrossed = false;

#define TICKRATE_HZ (100)     /* 100 ticks per second */

#define BOARD_ADC_CH 2


/**
* @brief     Handle interrupt from ADC sequencer A
* @return     Nothing
*/

void ADC_SEQA_IRQHandler(void) {
     uint32_t pending;

     /* Get pending interrupts */
     pending = Chip_ADC_GetFlags(LPC_ADC);

     /* Sequence A completion interrupt */
     if (pending & ADC_FLAGS_SEQA_INT_MASK) {
          sequenceComplete = true;
     }

     /* Threshold crossing interrupt on ADC input channel */
     if (pending & ADC_FLAGS_THCMP_MASK(BOARD_ADC_CH)) {
          thresholdCrossed = true;
     }

     /* Clear any pending interrupts */
     Chip_ADC_ClearFlags(LPC_ADC, pending);
}


/**
* @brief     Handle interrupt from SysTick timer
* @return     Nothing
*/

void SysTick_Handler(void) {
     static uint32_t count;

     /* Every 1/2 second */
     if (count++ == TICKRATE_HZ / 2) {
          count = 0;
          Chip_ADC_StartSequencer(LPC_ADC, ADC_SEQA_IDX);
     }
}


/**
* @brief     main routine for ADC example
* @return     Function should not exit
*/

int main(void) {
     uint32_t rawSample;
     int j;

     SystemCoreClockUpdate();
     Board_Init();

     /* Setup ADC for 12-bit mode and normal power */
     Chip_ADC_Init(LPC_ADC, 0);
     Chip_ADC_Init(LPC_ADC, ADC_CR_MODE10BIT);

     /* Need to do a calibration after initialization and trim */
     Chip_ADC_StartCalibration(LPC_ADC);
     while (!(Chip_ADC_IsCalibrationDone(LPC_ADC))) {
     }

     /* Setup for maximum ADC clock rate using sycnchronous clocking */
     Chip_ADC_SetClockRate(LPC_ADC, ADC_MAX_SAMPLE_RATE);

     Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX,
               (ADC_SEQ_CTRL_CHANSEL(BOARD_ADC_CH) | ADC_SEQ_CTRL_MODE_EOS));
     Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
     Chip_SWM_EnableFixedPin(SWM_FIXED_ADC2);
     Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);

     /* Setup threshold 0 low and high values to about 25% and 75% of max */
     Chip_ADC_SetThrLowValue(LPC_ADC, 0, ((1 * 0xFFF) / 4));
     Chip_ADC_SetThrHighValue(LPC_ADC, 0, ((3 * 0xFFF) / 4));

     Chip_ADC_ClearFlags(LPC_ADC, Chip_ADC_GetFlags(LPC_ADC));
     Chip_ADC_EnableInt(LPC_ADC,
               (ADC_INTEN_SEQA_ENABLE | ADC_INTEN_OVRRUN_ENABLE));
     Chip_ADC_SelectTH0Channels(LPC_ADC, ADC_THRSEL_CHAN_SEL_THR1(BOARD_ADC_CH));
     Chip_ADC_SetThresholdInt(LPC_ADC, BOARD_ADC_CH, ADC_INTEN_THCMP_CROSSING);

     /* Enable ADC NVIC interrupt */
     NVIC_EnableIRQ(ADC_SEQA_IRQn);

     Chip_ADC_EnableSequencer(LPC_ADC, ADC_SEQA_IDX);

     SysTick_Config(SystemCoreClock / TICKRATE_HZ);

     /* Endless loop */
     while (1) {
          /* Sleep until something happens */
          __WFI();

          if (thresholdCrossed) {
               thresholdCrossed = false;
               printf("********ADC threshold event********\r\n");
          }

          /* Is a conversion sequence complete? */
          if (sequenceComplete) {
               sequenceComplete = false;

               /* Get raw sample data for channels 0-11 */
               for (j = 0; j < 12; j++) {
                    rawSample = Chip_ADC_GetDataReg(LPC_ADC, j);
                    /* Show some ADC data */
                    if (rawSample & (ADC_DR_OVERRUN | ADC_SEQ_GDAT_DATAVALID)) {
                         printf("Chan: %d Val: %d\r\n", j, ADC_DR_RESULT(rawSample));
                         printf("Threshold range: 0x%x ",
                                   ADC_DR_THCMPRANGE(rawSample));
                         printf("Threshold cross: 0x%x\r\n",
                                   ADC_DR_THCMPCROSS(rawSample));
                         printf("Overrun: %s ",
                                   (rawSample & ADC_DR_OVERRUN) ? "true" : "false");
                         printf("Data Valid: %s\r\n\r\n",
                                   (rawSample & ADC_SEQ_GDAT_DATAVALID) ?
                                             "true" : "false");
                    }
               }
          }
     }
}

Outcomes