1 /*
2  * @brief FLASH IAP programming & FLASH signature example using IAP commands
3  * to write to FLASH memory and a FLASH signature generator
4  *
5  * @note
6  * Copyright(C) NXP Semiconductors, 2013
7  * All rights reserved.
8  *
9  * @par
10  * Software that is described herein is for illustrative purposes only
11  * which provides customers with programming information regarding the
12  * LPC products.  This software is supplied "AS IS" without any warranties of
13  * any kind, and NXP Semiconductors and its licensor disclaim any and
14  * all warranties, express or implied, including all implied warranties of
15  * merchantability, fitness for a particular purpose and non-infringement of
16  * intellectual property rights.  NXP Semiconductors assumes no responsibility
17  * or liability for the use of the software, conveys no license or rights under any
18  * patent, copyright, mask work right, or any other intellectual property rights in
19  * or to any products. NXP Semiconductors reserves the right to make changes
20  * in the software without notification. NXP Semiconductors also makes no
21  * representation or warranty that such application will be suitable for the
22  * specified use without further testing or modification.
23  *
24  * @par
25  * Permission to use, copy, modify, and distribute this software and its
26  * documentation is hereby granted, under NXP Semiconductors' and its
27  * licensor's relevant copyrights in the software, without fee, provided that it
28  * is used in conjunction with NXP Semiconductors microcontrollers.  This
29  * copyright, permission, and disclaimer notice must appear in all copies of
30  * this code.
31  */
32 
33 #include "board.h"
34 #include <stdio.h>
35 
36 /*****************************************************************************
37  * Private types/enumerations/variables
38  ****************************************************************************/
39 
40 #define TICKRATE_HZ (10)	/* 10 ticks per second */
41 
42 /* Last sector address */
43 #define START_ADDR_LAST_SECTOR      0x0003F000
44 
45 /* LAST SECTOR */
46 #define IAP_LAST_SECTOR             63
47 
48 /* Number of bytes to be written to the last sector */
49 #define IAP_NUM_BYTES_TO_WRITE      1024
50 
51 /* Size of each sector */
52 #define SECTOR_SIZE                 4096
53 
54 /* Number elements in array */
55 #define ARRAY_ELEMENTS          (IAP_NUM_BYTES_TO_WRITE / sizeof(uint32_t))
56 
57 /* Data array to write to flash */
58 static uint32_t src_iap_array_data[ARRAY_ELEMENTS];
59 
60 /*****************************************************************************
61  * Public types/enumerations/variables
62  ****************************************************************************/
63 
64 /*****************************************************************************
65  * Private functions
66  ****************************************************************************/
67 
68 /*****************************************************************************
69  * Public functions
70  ****************************************************************************/
71 
72 /**
73  * @brief	Handle interrupt from SysTick timer
74  * @return	Nothing
75  */
SysTick_Handler(void)76 void SysTick_Handler(void)
77 {
78 	Board_LED_Toggle(0);
79 }
80 
81 /**
82  * @brief	Main program body
83  * @return	Always returns 0
84  */
main(void)85 int main(void)
86 {
87 	int i;
88 	uint8_t ret_code;
89 	uint32_t part_id;
90 
91 	/* Generic Initialization */
92 	SystemCoreClockUpdate();
93 	Board_Init();
94 	Board_LED_Set(0, false);
95 
96 	/* Enable SysTick Timer */
97 	SysTick_Config(SystemCoreClock / TICKRATE_HZ);
98 
99 	/* Initialize the array data to be written to FLASH */
100 	for (i = 0; i < ARRAY_ELEMENTS; i++) {
101 		src_iap_array_data[i] = 0x11223340 + i;
102 	}
103 
104 	/* Read Part Identification Number*/
105 	part_id = Chip_IAP_ReadPID();
106 	DEBUGOUT("Part ID is: %x\r\n", part_id);
107 
108 	/* Disable interrupt mode so it doesn't fire during FLASH updates */
109 	__disable_irq();
110 
111 	/* IAP Flash programming */
112 	/* Prepare to write/erase the last sector */
113 	ret_code = Chip_IAP_PreSectorForReadWrite(IAP_LAST_SECTOR, IAP_LAST_SECTOR);
114 
115 	/* Error checking */
116 	if (ret_code != IAP_CMD_SUCCESS) {
117 		DEBUGOUT("Command failed to execute, return code is: %x\r\n", ret_code);
118 	}
119 
120 	/* Erase the last sector */
121 	ret_code = Chip_IAP_EraseSector(IAP_LAST_SECTOR, IAP_LAST_SECTOR);
122 
123 	/* Error checking */
124 	if (ret_code != IAP_CMD_SUCCESS) {
125 		DEBUGOUT("Command failed to execute, return code is: %x\r\n", ret_code);
126 	}
127 
128 	/* Prepare to write/erase the last sector */
129 	ret_code = Chip_IAP_PreSectorForReadWrite(IAP_LAST_SECTOR, IAP_LAST_SECTOR);
130 
131 	/* Error checking */
132 	if (ret_code != IAP_CMD_SUCCESS) {
133 		DEBUGOUT("Command failed to execute, return code is: %x\r\n", ret_code);
134 	}
135 
136 	/* Write to the last sector */
137 	ret_code = Chip_IAP_CopyRamToFlash(START_ADDR_LAST_SECTOR, src_iap_array_data, IAP_NUM_BYTES_TO_WRITE);
138 
139 	/* Error checking */
140 	if (ret_code != IAP_CMD_SUCCESS) {
141 		DEBUGOUT("Command failed to execute, return code is: %x\r\n", ret_code);
142 	}
143 
144 	/* Re-enable interrupt mode */
145 	__enable_irq();
146 
147 	/* Start the signature generator for the last sector */
148 	Chip_FMC_ComputeSignatureBlocks(START_ADDR_LAST_SECTOR, (SECTOR_SIZE / 16));
149 
150 	/* Check for signature geenration completion */
151 	while (Chip_FMC_IsSignatureBusy()) {}
152 
153 	/* Get the generated FLASH signature value */
154 	DEBUGOUT("Generated signature for the last sector is: %x \r\n", Chip_FMC_GetSignature(0));
155 
156 	NVIC_DisableIRQ(SysTick_IRQn);
157 
158 	return 0;
159 }
160