Can you not manually disable the watchdog timer before entering ISP?
I think this code might disable it:
Regarding WDMOD, Section 28.4.1 of the user manual states:
Quote:
Once the WDEN and/or WDRESET bits are set they can not be cleared by software. Both flags are cleared by an external reset or a Watchdog timer underflow.
So, this is not possible, but that's by design - the intent is that once you've set the WDT, under no circumstances can it be disabled by rogue code.
My intended solution to the problem makes use of an external EEPROM. Once my application receives a serial command to enter bootloader mode, it will do the following:
- write a special code to a given location in EEPROM
- force a reset in software
- during the boot sequence, before the WDT is initialized, it will check this EEPROM location for the code. If found, it will clear the code and enter bootloader mode (skipping WDT init altogether).
The net effect is the same... Haven't implemented it yet but I don't expect any problems.
I found this technote(ics.nxp.com/support/documents/microcontrollers/pdf/an10356.pdf) at NXP site, showing ISP entry from user code for the LPC21xx series. I've tried to adapt the following to existing code to the LPC1768 using the online compiler. I think my problem is remapping the interrupt vectors can anyone shed some light on this. Should this still be possible?
The steps involved in entering ISP mode from user code are as follows: (LPC21xx)
• Configure the RXD0 pin (UART 0 receive) as input. This is done by entering the appropriate values in the PINSEL0 and IODIR0 registers.
• Configure P0.14 as an output pin.
• Clear P0.14 (Set low)
• Disable interrupts by setting the corresponding bits in the VIC Interrupt Enable Clear register (VICIntEnClear at address 0xFFFF F014) for anyinterrupt source that was previously enabled for interrupts.
• If the PLL is connected, disconnect it (Recommended).
• Set the Peripheral Bus Divider to ¼ if needed.
• If the UART is equipped with a Fractional Baud Rate generator then the Fractional Divider register (FDR) should be set to its reset value (This is not shown in the code below).
• Restore Timer1 to its reset state. Timer 1 is used by the ISP to auto baud.
• Re-Map the interrupt vectors to the boot block.
• Invoke the bootloader by calling a function that is located at the bootloader entry point, i.e. the reset vector at 0x00.
My current LPC1768 version
#include "mbed.h" #include "LPC17xx.h" #define MEMMAP (*((volatile unsigned int *) 0x400FC040)) #define VICINTENCLR (*((volatile unsigned int *) 0xffffffff)) void (*bootloader_entry)(void); unsigned long temp; DigitalOut myled(LED_1); DigitalOut myled2(LED_2); Serial pc(P0_2, P0_3); // tx, rx void init(void) { temp = LPC_PINCON->PINSEL0; /* Connect RXD0 & TXD0 pins to GPIO */ LPC_PINCON->PINSEL0 = temp & 0xFFFFFFF3; /* Select P2.10 as an output and P0.1 as an input */ temp = LPC_GPIO2->FIODIR;//LPC_PINCON->IODIR0; temp = temp | 0x400; temp = temp & 0xFFFFFFFD; LPC_GPIO2->FIODIR = temp;// LPC_PINCON->IODIR0 = temp; /* Clear P2.10 */ LPC_GPIO2->FIOCLR = 0x400; // 1<<10;// IOCLR0 = 0x4000; /* Disable Interrupts in the VIC*/ VICINTENCLR =0x0; /* Disconnect PLL if you want to do ISP at crystal frequency. Otherwise you need to pass the PLL freq when bootloader goes in ISP mode. cclk = crystal when PLL is disconnected cclk = PLL freq when PLL is connected. Disconnecting the PLL is recommended. */ LPC_SC->PLL0CON = 0x0; LPC_SC->PLL0FEED = 0xAA; LPC_SC->PLL0FEED= 0x55; /* Set the VPB divider to 1/4 if your application changes the VPBDIV value. The bootloader is hard-coded to use the reset value of VPBDIV register VPBDIV = 0x0; */ /* Restore reset state of Timer1 */ LPC_TIM1->PR =0x0;//TIMER1_PR=0x0; LPC_TIM1->MCR =0x0;//TIMER1_MCR=0x0; LPC_TIM1->CCR =0x0;//TIMER1_CCR=0x0; /* Map bootloader vectors */ MEMMAP = 0x0; /* Point to bootloader entry point i.e. reset vector 0x0 */ bootloader_entry = (void (*)(void))(0x0); } int main() { int ten = 60; pc.baud(9600); while (1) { myled = 1; myled2 = !myled2; wait(0.2); myled = 0; wait(0.2); pc.printf("Count Down to ISP! %d", ten); ten=ten-1; if (ten==0) { ten=60; init(); bootloader_entry(); } } }