LPCXpresso802 board stuck in flash error

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

LPCXpresso802 board stuck in flash error

1,068 Views
drsmith_yorku
Contributor III

I'm working on the Wakeup Timer for the LPC802 but have crashed my board.  The built-in debugger will no longer connect, giving the following error:

ProgramPage (0x0, 0x100003D8, 0x80) status 0x1 - driver reported driver error - ONCHIP driver rc 10 - Source and destination data not equal

Closing flash driver LPC80x_16.cfx
Target error from Commit Flash write: Ef(49): Flash driver operation gave error.
GDB stub (crt_emu_cm_redlink) terminating - GDB protocol problem: Pipe has been closed by GDB.

I was modifying the CTimer example from the NXP code examples for the LPC802 (LPC802-EX-CODE-MCUXPRESSO) in order to just get the WKT working.  The goal is to use the WKT to drive a LED via the WKT interrupt.  I removed all of the CTimer code in the example, only leaving the WKT code.  I'm also converting the register calls to the values set in LPC802.h, the header file that comes with the SDK for the board (e.g. SYSCON->… instead of LPC_SYSCON->…)

I'm looking for suggestions for 

1. How to reset the board so it stops hanging.  (I'm assuming that I should use an external debugger via the SWD port)

2. What to change about the WKT initialization or the ISR so that it prevents this issue again in the future.

thanks!

James

void WKT_Config() {
 // Step 1: In the SYSAHBCLCKCTRL register, set bit 9 to enable the clock to the reg. interface
 // also enable GPIO for the LED.
 SYSCON->SYSAHBCLKCTRL0 |= (SYSCON_SYSAHBCLKCTRL0_WKT_MASK|SYSCON_SYSAHBCLKCTRL0_GPIO0_MASK); //(WKT|GPIO0);// Enable some clocks
 // Power-up the LPOSC
 // PD: Power config register.  Active Low: Bit 6 set to 0 (zero) makes the Low Power Osc. turn ON.
 SYSCON->PDRUNCFG &= ~(SYSCON_PDRUNCFG_LPOSC_PD_MASK);      // Power-up the LPOSC
 // Enable the LPOSC clock to the WKT
 // Enable clock for the Wakeup Timer.
 // Bit 1 of LPOSCCLKEN set to 1 to enable. (Section 6.6.8 of the User Manual)
 SYSCON->LPOSCCLKEN |= (1<<SYSCON_LPOSCCLKEN_WKT_SHIFT);  // Enable the LPOSC clock to the WKT
 // Step 2. Clear the WKT reset using the PRESETCTRL register
 // (Peripheral Reset Control 0 Register)
 // WKT: bit 9.  0 is "assert" the reset. 1 is "clear" the reset.
 SYSCON->PRESETCTRL0 &= (SYSCON_PRESETCTRL0_WKT_RST_N_MASK);   // "0": Assert the reset
 SYSCON->PRESETCTRL0 |= ~(SYSCON_PRESETCTRL0_WKT_RST_N_MASK);  // "1": Clear the reset
 // Step 3. Connect WKT interrupt to #15 in NVIC
 NVIC_EnableIRQ(WKT_IRQn);                 // Enable the WKT interrupt in the NVIC
 // Step 4. Enable the Clock source
 //          a) Enable the low power oscillator in PDRUNCFG register if you're using that clock source
 //   b) Enable the FRO and FRO output in PDRUNCFG register if used as the clock source
 //          c) (otherwise ext. clock source via PIO0_11 and switch matrix PINENABLE0 and CTRL registers)
 //LPC_WKT->CTRL = DIVIDED_IRC<<WKT_CLKSEL;// Select fro_clk/16 as WKT clock source
 WKT->CTRL |= (1<<WKT_CTRL_CLKSEL_MASK); // Set bit 0 to 1 for Low power clock. //LOW_POWER_OSC<<WKT_CLKSEL;// Select LPOSC as WKT clock source (approx. 1 MHz)
 WKT->COUNT = WKT_RELOAD;              // Start the WKT, counts down WKT_RELOAD clocks then interrupts

  // Set data direction on
  // GPIO to Output.
  GPIO->DIRSET[0] = (1UL<<8);
  // Turn on the LED.
  GPIO->CLR[0] = (1UL<<8);
}

// Function name: WKT_IRQHandler (interrupt service routine)
// Description:   WKT interrupt service routine.
//                Toggles a pin, restarts the WKT.
// Parameters:    None
// Returns:       Void
void WKT_IRQHandler(void) {
  WKT->CTRL |= 1<<WKT_CTRL_ALARMFLAG_SHIFT;         // Clear the interrupt flag
  WKT->COUNT = WKT_RELOAD;               // Restart the WKT
  // Toggle the LED
  GPIO->NOT[0] = (1UL<<8);

  return;
}

//
// main routine
//
int main(void) {

  // WKT: Wake Timer
  // Configure and start the WKT, also configures an output pin, which toggles every WKT interrupt
  WKT_Config();
  while(1) { // Have a tequila
   asm("NOP");
  } // end of while 1
} // end of main
Labels (1)
3 Replies

824 Views
drsmith_yorku
Contributor III

I figured out how to re-enable the CMSIS-DAP debugger on the LPCXpresso board.  I bridged the EXT_DBG connector and then connected a Segger JLink.  I downloaded the following via the JLink.

#include "LPC802.h"
// prototypes
void WKT_Config();
// main routine
//
int main(void) {
  // WKT: Wake Timer configuration
  WKT_Config();
  while(1) { // Have a tequila
   asm("NOP");
  } // end of while 1
} // end of main

// Function name: WKT_Config
// Description:   Initialize a GPIO output pin and the WKT, then start it.
// Parameters:    None
// Returns:       Void
// Source: Ch. 18 of the User Manual (UM11045)
void WKT_Config() {
 // Enable GPIO for the LED.
 SYSCON->SYSAHBCLKCTRL0 |= (SYSCON_SYSAHBCLKCTRL0_GPIO0_MASK); //(WKT|GPIO0);// Enable some clocks
   // Set data direction on
   // GPIO to Output.
   GPIO->DIRSET[0] = (1UL<<LED_USER1);
   // Turn on the LED.
   GPIO->CLR[0] = (1UL<<LED_USER1);
   // Turn off the LED.
   GPIO->SET[0] = (1UL<<LED_USER1);
 // Step 1:
 // turn off the WKT enabling clock.
 SYSCON->SYSAHBCLKCTRL0 &= ~(SYSCON_SYSAHBCLKCTRL0_WKT_MASK);
 // Step 2: disable the vector lookup for WKT.
 NVIC_DisableIRQ(WKT_IRQn);   // turn off the WKT interrupt.
}
So, I've turned off the WKT, after unbridging EXT_DBG and disconnecting the JLink, the CMSIS-DAP connection works again.
Now, to figure out why the WKT code locked things up in the first place...
James
0 Kudos

824 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello James,

I  refer to your requirement " modifying the CTimer example from the NXP code examples for the LPC802 (LPC802-EX-CODE-MCUXPRESSO) in order to just get the WKT working.",   delete the needless codes, change LED from port0_17 to port0_8 as your attached code , it can work well on my side , and also there is no problem about debug .

I attached project, you can have a look.


Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

824 Views
drsmith_yorku
Contributor III

Hi Alice,

Thanks for the prompt and helpful reply.  I realized that I misinterpreted what was going on in the original version of the code in the lines associated with the Reset Control.

wrong_code.PNG

Normally, with an "&=" I would expect to see a tilde to invert the bitmask.  If forgot to do that and it resulted in a number of other registers getting reset, instead of just WKT.

I finished the modification of the original code to only use the defintions/macros in lpc802.h.  Here it is, and it works, with an ISR period of about 100 ms.

// based on LPC802_Project_NXPCode_Ctimer_Ex.c
//
// ------------------------------------------------------------------------------------
#define WKT_FREQ 1000000   // Use if the WKT is clocked by the LPOSC
//#define WKT_FREQ 937500  // Use if the WKT is clocked by the 15 MHz FRO, via the div-by-16 WKT divider
#define WKT_RELOAD 100000      // Reload value for the WKT down counter
#define WKT_INT_FREQ (WKT_FREQ/WKT_RELOAD)  // INterrupt frequency of the WKT.
#define LED_USER1 (8)  // PIO0_8_RXD
#include "LPC802.h"
// prototypes
void WKT_Config();
// main routine
//
int main(void) {
  // WKT: Wake Timer configuration
  WKT_Config();
  while(1) { // Have a tequila
   asm("NOP");
  } // end of while 1
} // end of main

// Function name: WKT_Config
// Description:   Initialize a GPIO output pin and the WKT, then start it.
// Parameters:    None
// Returns:       Void
// Source: Ch. 18 of the User Manual (UM11045)
void WKT_Config() {
 // --------------------------------------------------------
 // Step 1.  Make an LED turn on.  Checks that board is up and running.
 // Enable GPIO for the LED.
 SYSCON->SYSAHBCLKCTRL0 |= (SYSCON_SYSAHBCLKCTRL0_GPIO0_MASK);
 // GPIO to Output.
 GPIO->DIRSET[0] = (1UL<<LED_USER1);
 // Turn on the LED.
 GPIO->CLR[0] = (1UL<<LED_USER1);
 // --------------------------------------------------------
 // Step 2: turn on the Wake-up Timer (WKT) enabling clock.
 SYSCON->SYSAHBCLKCTRL0 |= (SYSCON_SYSAHBCLKCTRL0_WKT_MASK);
 // --------------------------------------------------------
 // Step 3: disable the vector lookup for WKT.
 NVIC_DisableIRQ(WKT_IRQn);  // turn off the WKT interrupt.
 // --------------------------------------------------------
 // Step 4: Turn on the Low Power Oscillator's power supply.
 //    bit 6 to 0 in order to turn it ON. (Active low)
 // old version:  LPC_SYSCON->PDRUNCFG &= ~(LPOSC_PD);      // Power-up the LPOSC
 SYSCON->PDRUNCFG &= ~(SYSCON_PDRUNCFG_LPOSC_PD_MASK);
 // --------------------------------------------------------
 // Step 5: Enable the LPOSC clock to the WKT.  (Bit 1 to 1)
 // old version:  LPC_SYSCON->LPOSCCLKEN |= 1<<WKT_CLK_EN;  // Enable the LPOSC clock to the WKT
 SYSCON->LPOSCCLKEN |= (SYSCON_LPOSCCLKEN_WKT_MASK);
 // --------------------------------------------------------
 // Step 6: Reset the WKT.
 //       Set bit 9 to 0: assert (i.e. "make") the WKT reset
 //    Set bit 9 to 1: clear the WKT reset (i.e. "remove" reset)
 // the original version was broken here.  Missing ~ on first line.  Too much ~ on 2nd line.
 // without this fix, other modules were getting reset and resulting in hard fault.
 SYSCON->PRESETCTRL0 &= ~(SYSCON_PRESETCTRL0_WKT_RST_N_MASK);   // Reset the WKT
 SYSCON->PRESETCTRL0 |= (SYSCON_PRESETCTRL0_WKT_RST_N_MASK);  // clear the reset.
 // --------------------------------------------------------
 // Step 7: Load the timer
 // --------------------------------------------------------
 // Select the LPOSC as the WKT clock source (0b0001)
 // Bit 0 (CLKSEL) to 1 for Low Power Clock
 // BIt 1 (ALARMFLAG) read flag.  If 1, an interrupt has happend. if 0, then no timeout.
 // Bit 2 (CLEARCTR).  Set to 1 to clear the counter.
 // Bit 3 (SEL_EXTCLK).  Set to 0 for internal clock source.
 //
 //LPC_WKT->CTRL = LOW_POWER_OSC<<WKT_CLKSEL;// Select LPOSC as WKT clock source (approx. 1 MHz)
 WKT->CTRL = 0x00000001;
 // need to un-hardcode the line above (line 90.)
 // load the timer count-down value. (The "Timeout value")
 WKT->COUNT = WKT_RELOAD;              // Start the WKT, counts down WKT_RELOAD clocks then interrupts
 // Enable the IRQ
 NVIC_EnableIRQ(WKT_IRQn);                 // Enable the WKT interrupt in the NVIC
}

// Function name: WKT_IRQHandler (interrupt service routine)
// Description:   WKT interrupt service routine.
//                Toggles a pin, restarts the WKT.
// Parameters:    None
// Returns:       Void
void WKT_IRQHandler(void) {
  WKT->CTRL |= (1<<WKT_CTRL_ALARMFLAG_SHIFT); // Clear the interrupt flag
  WKT->COUNT = WKT_RELOAD;                 // Restart the WKT
  // Toggle the LED
  GPIO->NOT[0] = (1UL<<LED_USER1);

  return;
}
0 Kudos