1 /*
2  * @brief IAP example using IAP FLASH programming
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2013
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products.  This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "board.h"
33 #include <stdio.h>
34 
35 /*****************************************************************************
36  * Private types/enumerations/variables
37  ****************************************************************************/
38 
39 #define TICKRATE_HZ (10)	/* 10 ticks per second */
40 
41 /* SystemTick Counter */
42 static volatile uint32_t sysTick;
43 
44 #define IAP_NUM_BYTES_TO_WRITE 256
45 /* Address of the last sector on flash */
46 #define last_sector_flash   0x0000F000
47 /* LAST SECTOR */
48 #define IAP_LAST_SECTOR 15
49 
50 /* IAP defines*/
51 /* Prepare sector for write operation command */
52 #define IAP_PREWRRITE_CMD 50
53 
54 /* Write Sector command */
55 #define IAP_WRISECTOR_CMD 51
56 
57 /* Erase Sector command */
58 #define IAP_ERSSECTOR_CMD 52
59 
60 /* Read PartID command */
61 #define IAP_REPID_CMD 54
62 
63 /* IAP command variables */
64 static unsigned int command[5], result[4];
65 
66 /* Data to write and write count */
67 #define WRITECOUNT (IAP_NUM_BYTES_TO_WRITE / 32)
68 static uint32_t array_data[WRITECOUNT];
69 
70 /*****************************************************************************
71  * Public types/enumerations/variables
72  ****************************************************************************/
73 
74 /*****************************************************************************
75  * Private functions
76  ****************************************************************************/
77 
78 /*****************************************************************************
79  * Public functions
80  ****************************************************************************/
81 
82 /**
83  * @brief	Handle interrupt from SysTick timer
84  * @return	Nothing
85  */
SysTick_Handler(void)86 void SysTick_Handler(void)
87 {
88 	Board_LED_Toggle(0);
89 	sysTick++;
90 }
91 
92 /**
93  * @brief	main routine for blinky example
94  * @return	Function should not exit.
95  */
main(void)96 int main(void)
97 {
98 	int i;
99 
100 	/* Generic Initialization */
101 	SystemCoreClockUpdate();
102 	Board_Init();
103 	Board_LED_Set(0, false);
104 
105 	/* Enable SysTick Timer */
106 	SysTick_Config(SystemCoreClock / TICKRATE_HZ);
107 
108 	/* Initialize the array data to be written to FLASH */
109 	for (i = 0; i < WRITECOUNT; i++) {
110 		array_data[i] = 0x11223340 + i;
111 	}
112 
113 	/* Read Part Identification Number*/
114 	command[0] = IAP_REPID_CMD;								/* Read ID command code */
115 	iap_entry(command, result);
116 
117 	/* Reinvoke ISP mode so that reprogamming of Flash possible */
118 	__disable_irq();
119 
120 	command[0] = IAP_REPID_CMD;
121 	iap_entry(command, result);
122 
123 	/* Prepare to write/erase the last sector */
124 	command[0] = IAP_PREWRRITE_CMD;						/* Prepare to write/erase command code */
125 	command[1] = IAP_LAST_SECTOR;							/* Start Sector Number */
126 	command[2] = IAP_LAST_SECTOR;							/* End Sector Number */
127 	iap_entry(command, result);
128 
129 	/* Erase the last sector */
130 	command[0] = IAP_ERSSECTOR_CMD;						/* Erase command code*/
131 	command[1] = IAP_LAST_SECTOR;							/* Start Sector Number */
132 	command[2] = IAP_LAST_SECTOR;							/* Start Sector Number */
133 	iap_entry(command, result);
134 
135 	/* Prepare to write/erase the last sector */
136 	command[0] = IAP_PREWRRITE_CMD;						/* Prepare to write/erase command code */
137 	command[1] = IAP_LAST_SECTOR;							/* Start Sector Number */
138 	command[2] = IAP_LAST_SECTOR;							/* Start Sector Number */
139 	iap_entry(command, result);
140 
141 	/* Write to the last sector */
142 	command[0] = IAP_WRISECTOR_CMD;								/* Write command code */
143 	command[1] = (uint32_t) last_sector_flash;		/* Destination Flash Address */
144 	command[2] = (uint32_t) &array_data;					/* Source RAM Address */
145 	command[3] = IAP_NUM_BYTES_TO_WRITE;					/* Number of Bytes to be written */
146 	command[4] = SystemCoreClock / 1000;					/* System clock frequency */
147 	iap_entry(command, result);
148 
149 	/* Re-enable interrupt mode */
150 	__enable_irq();
151 
152 	while (1) {
153 		__WFI();
154 	}
155 
156 	return 0;
157 }
158