Hello Alice_Yang
I have bought a LPC845-BRK which uses the LPC845 48pin part, the same as my application.
I have tried your code and slightly modified it to give debugging output. Here it is:-
//--------------------
// FAIM_and_Clocks.c
//--------------------
#include <stdio.h>
#include "LPC8xx.h"
#include "syscon.h"
#include "swm.h"
#include "faim.h"
#include "utilities.h"
#include "iap.h"
#include "FlashFaimPrg.h"
void setup_debug_uart(void);
#define CLKOUT_DIVIDE 10
#define CLKOUT_PIN P0_16
const char promptstring_clock[] = "Choose a clock to display, or 's' to skip:\n\r0 for fro_clk\n\r1 for main_clk\n\r2 for sys_pll0_clk\n\r3 for external_clk\n\r4 for wdt_osc_clk\n\r5 for system_ahb_clk\n\r6 for fro_div_clk\n\r";
const char promptstring_faimw[] = "Enter a FAIM word to program ('0' - '7'), or 's' to skip\n\r";
const char promptstring_faimr[] = "Enter a FAIM word to read ('0' - '7'), or 's' to skip\n\r";
const char promptstring_lpstrt[]= "Set the low-power start bit? Type 'y' to set, 'n' to clear. Reset the board to make a new value take effect\n\r";
const char promptstring_flashprog[] = "Programming Flash Test Press any key, or 's' to skip\n\r";
uint32_t faim_write_data[NUM_FAIM_WORDS] =
{
0x28000000, // Word 0 Bit[1]: '0' = normal start, '1' = LP start
0x00001918, // Word 1
0x00000000, // Word 2
0x00000000, // Word 3
0xAAA00000, // Word 4
0xAAAAAAAA, // Word 5
0xAAAAAAAA, // Word 6
0xAAAAAAAA // Word 7
};
#define myADDR 0x00007C00
#define myNUM_BYTES 64
const uint8_t myflashdata[64] @0x00007C00 ={50,5,0,0};
uint8_t mydata[64];
int main(void) {
unsigned char temp;
uint32_t read_data, n;
uint8_t ret_code;
uint8_t Count;
// Configure the debug uart (see Serial.c)
setup_debug_uart();
// Enable clocks to relevant peripherals
LPC_SYSCON->SYSAHBCLKCTRL[0] |= (SWM);
// Enable the clkout clock divider, divide by the previously defined value
LPC_SYSCON->CLKOUTDIV = CLKOUT_DIVIDE;
// Configure the SWM for clock out
ConfigSWM(CLKOUT, CLKOUT_PIN);
// Configure either SYSOSC or CLK_IN as source for external_clk
// Update the global clock variables (this has already been called by setup_debug_uart)
SystemCoreClockUpdate();
while(1) {
// Display internal clock frequencies and connect them to clkout clock divider
while (2) {
temp = GetConsoleCharacter((const char *)&promptstring_clock);
// Accept '0' '1' '2' '3', '4', or '5' only
if (temp < 0x30 || temp > 0x36) {
printf("\n\n\r");
break;
}
switch (temp) {
case '0': printf("fro_clk freq. = %d Hz.\n\n\r", fro_clk);
LPC_SYSCON->CLKOUTSEL = CLKOUTSEL_FRO_CLK;
break;
case '1': printf("main_clk freq. = %d Hz.\n\n\r", main_clk);
LPC_SYSCON->CLKOUTSEL = CLKOUTSEL_MAIN_CLK;
break;
case '2': printf("sys_pll0_clk freq. = %d Hz.\n\n\r", sys_pll0_clk);
LPC_SYSCON->CLKOUTSEL = CLKOUTSEL_SYSPLL0_CLK;
break;
case '3': printf("external_clk freq. is a mystery. See clock out pin.\n\n\r");
LPC_SYSCON->CLKOUTSEL = CLKOUTSEL_EXTERNAL_CLK;
break;
case '4': printf("wdt_osc_clk freq. = %d Hz.\n\n\r", wdt_osc_clk);
LPC_SYSCON->CLKOUTSEL = CLKOUTSEL_WDT_OSC_CLK;
break;
case '5': printf("system_ahb_clk freq. = %d Hz. Not available on clock out pin.\n\n\r", system_ahb_clk);
LPC_SYSCON->CLKOUTSEL = CLKOUTSEL_OFF;
break;
case '6': printf("fro_div_clk freq. = %d Hz. Not available on clock out pin.\n\n\r", fro_div_clk);
LPC_SYSCON->CLKOUTSEL = CLKOUTSEL_OFF;
break;
} // end of switch
} // end of while 2
// Read FAIM
while (3) {
temp = GetConsoleCharacter((const char *)&promptstring_faimr);
// Accept '0' - '7' only
if (temp < 0x30 || temp > 0x37) {
printf("\n\n\r");
break;
}
n = temp - 0x30; // n = the FAIM word number
FAIMRead(n, (uint32_t)&read_data); // Call the read API to make the current data visible, and load it into read_data
printf("The content of FAIM word %d is 0x%x\n\n\r", n, read_data);
} // end of while 3
//////////////////////////////////////////////////////////////////////////
//Flash Programming Test
while (5) {
temp = GetConsoleCharacter((const char *)&promptstring_flashprog);
// Accept '0' - '7' only
if (temp =='s') {
printf("\n\n\r");
break;
}
printf("myflashdata[0],[1] %02X %02X\n\n\r", myflashdata[0], myflashdata[1]);
//Erase and write flash
if ((ret_code = ErasePage(myADDR))) {
printf ("ErasePage failed. Return code was 0x%X\n\r", ret_code);
while(1);
}
printf("Page Erased \n\rmyflashdata[0],[1] %02X %02X\n\n\r", myflashdata[0], myflashdata[1]);
for(Count=0;Count<64;Count++)
{
mydata[Count]=Count;
}
// IAP Copy RAM to Flash command
if ((ret_code = Program(myADDR, myNUM_BYTES, (uint8_t *)mydata))) {
printf ("Copy RAM to Flash failed. Return code was 0x%X\n\r", ret_code);
while(1);
}
printf("Page Programmed \n\rmyflashdata[0],[1] %02X %02X\n\n\r", myflashdata[0], myflashdata[1]);
if((myflashdata[0] != 0) || (myflashdata[1] != 1))
{
printf("Flash Data Programmed Wrongly!\n\n\r");
}
}
// read FAIM again
FAIMRead(2, (uint32_t)&read_data); // Call the read API to make the current data visible, and load it into read_data
printf("The content of FAIM word %d is 0x%x\n\n\r", 2, read_data);
///////////////////////////////////////////////////////////////////////////////
// Write FAIM (Use with great caution! Know the repercussions before proceeding!)
while (4) {
temp = GetConsoleCharacter((const char *)&promptstring_faimw);
// Accept '0' - '7' only
if (temp < 0x30 || temp > 0x37) {
printf("\n\n\r");
break;
}
n = temp - 0x30; // n = the FAIM word number
if (n == 0) { // If programming FAIM word 0
temp = GetConsoleCharacter((const char *)&promptstring_lpstrt);
if (temp == 'y') {
faim_write_data[0] |= FAIM_LP_BOOT; // Set the LP start bit
}
else {
faim_write_data[0] &= ~(FAIM_LP_BOOT);// Clear the LP start bit
}
}
FAIMWrite(n, (uint32_t)&faim_write_data[n]); // Call the write API to program the new data word from the faim_write_data array
FAIMRead(n, (uint32_t)&read_data); // Call the read API to make the new data visible, and load it into read_data variable
printf("The new value of FAIM word %d is 0x%x\n\n\r", n, read_data);
} // end of while 4
} // end of while(1)
} // end of main
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
The code runs fine, however I have discovered the problem of programming the flash after reading the FAIM.
If I read FAIM pages 0 to 4 the flash programming works, however if I read page 5 or 6 or 7 the flash contents written are wrong, even though the return code is 0 from the programming function!
If I read FAIM page 5 then 2 then perform a flash write the write contents are ok.
An example of the serial output is below, not I have serial local echo on to show which key I pressed.
=============================================================
Choose a clock to display, or 's' to skip:
0 for fro_clk
1 for main_clk
2 for sys_pll0_clk
3 for external_clk
4 for wdt_osc_clk
5 for system_ahb_clk
6 for fro_div_clk
s
Enter a FAIM word to read ('0' - '7'), or 's' to skip
5The content of FAIM word 5 is 0xaaaaaaaa
Enter a FAIM word to read ('0' - '7'), or 's' to skip
s
Programming Flash Test Press any key, or 's' to skip
myflashdata[0],[1] 00 01
Page Erased
myflashdata[0],[1] FF FF
Page Programmed
myflashdata[0],[1] 81 09
Flash Data Programmed Wrongly!
Programming Flash Test Press any key, or 's' to skip
myflashdata[0],[1] 81 01
Page Erased
myflashdata[0],[1] FF FF
Page Programmed
myflashdata[0],[1] 81 09
Flash Data Programmed Wrongly!
Programming Flash Test Press any key, or 's' to skip
s
The content of FAIM word 2 is 0x0
Enter a FAIM word to program ('0' - '7'), or 's' to skip
s
Choose a clock to display, or 's' to skip:
0 for fro_clk
1 for main_clk
2 for sys_pll0_clk
3 for external_clk
4 for wdt_osc_clk
5 for system_ahb_clk
6 for fro_div_clk
s
Enter a FAIM word to read ('0' - '7'), or 's' to skip
1The content of FAIM word 1 is 0x1918
Enter a FAIM word to read ('0' - '7'), or 's' to skip
5The content of FAIM word 5 is 0xaaaaaaaa
Enter a FAIM word to read ('0' - '7'), or 's' to skip
2The content of FAIM word 2 is 0x0
Enter a FFAIM word to read ('0' - '7'), or 's' to skip
s
Programming Flash Test Press any key, or 's' to skip
myflashdata[0],[1] 81 09
Page Erased
myflashdata[0],[1] FF FF
Page Programmed
myflashdata[0],[1] 00 01
Programming Flash Test Press any key, or 's' to skip
s
The content of FAIM word 2 is 0x0
Enter a FAIM word to program ('0' - '7'), or 's' to skip
s
Choose a clock to display, or 's' to skip:
0 for fro_clk
1 for main_clk
2 for sys_pll0_clk
3 for external_clk
4 for wdt_osc_clk
5 for system_ahb_clk
6 for fro_div_clk
============================================================================
So the problem looks like the ROM flash function is failing after a FAIM read on pages 5 upwards!
I have tested on the LPCXpresso MAX LPC845 board which uses the 64 pin part and do not get the error!
As a matter of interest for the LPC845-BRK board I have to alter chip_setup.h USE_VCOMPORT 0 to get the debug output from USB, whereas for the LPCXpresso MAX LPC845 board I set to 1, looks like the pcb functionality is inverted!:-
//
// The following parameters need to be defined for projects that use the debug UART (used in serial.c)
//
#define DBGUART 0 // Choose the index for the debug UART (0 for UART0, 1 for UART1, etc.)
#define DBGBAUDRATE 9600 // Choose the baud rate for the debug UART
#define USE_VCOM_PORT 0 // '1' to use VCOM serial port, '0' to use user-defined port pins for debug UART
#if (USE_VCOM_PORT == 1)
#define DBGTXPIN TARGET_TX // For VCOM serial port (see board.h)
#define DBGRXPIN TARGET_RX // For VCOM serial port (see board.h)
#else
#define DBGTXPIN P0_25 // Use with USB-to-RS232 break-out cable (choose your own favorite TxD pin)
#define DBGRXPIN P0_24 // Use with USB-to-RS232 break-out cable (choose your own favorite RxD pin)
#endif
So in summary the problem looks related to only the 48 pin variant and only when reading from FAIM pages 5 upwards.
Please can you test on your board to confirm and advise if there is a work around as I want to alter/test FAIM page 5 in my application as well as flash writing?
Regards
Phil Green
Senior Design Engineer
C-Tec
UK