LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
m0_ImageLoader.c
Go to the documentation of this file.
1 /*
2  * @brief M0 Image loader module
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
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 <string.h>
33 #include "board.h"
34 #include "lpc43xx_dualcore_config.h"
35 
64 /*****************************************************************************
65  * Private types/enumerations/variables
66  ****************************************************************************/
67 
68 /* Magic numbers to identify M0/M4 images */
69 #define SIGNATURE_M4_MAGIC 0xF00D4BAD
70 #define SIGNATURE_M0_MAGIC 0xBEEFF00D
71 
72 #ifndef ERROR_LED
73 /* LED to be blinked when there is an error in loading/starting M0 image */
74 #define ERROR_LED 1
75 #endif
76 
77 #define EX_BLINKY (1 << 0)
78 #define EX_USBHOST (1 << 1)
79 #define EX_USBDEV (1 << 2)
80 #define EX_LWIP (1 << 3)
81 #define EX_EMWIN (1 << 4)
82 
83 #ifdef OS_UCOS_III
84 #define OS_SIGNATURE 3
85 #elif defined(OS_FREE_RTOS)
86 #define OS_SIGNATURE 2
87 #else
88 #define OS_SIGNATURE 1
89 #endif
90 
91 #ifndef EXAMPLE_BLINKY
92 #define EXAMPLE_BLINKY 0
93 #else
94 #undef EXAMPLE_BLINKY
95 #define EXAMPLE_BLINKY EX_BLINKY
96 #endif
97 
98 #ifndef EXAMPLE_USB_HOST
99 #define EXAMPLE_USB_HOST 0
100 #else
101 #undef EXAMPLE_USB_HOST
102 #define EXAMPLE_USB_HOST EX_USBHOST
103 #endif
104 
105 #ifndef EXAMPLE_USB_DEVICE
106 #define EXAMPLE_USB_DEVICE 0
107 #else
108 #undef EXAMPLE_USB_DEVICE
109 #define EXAMPLE_USB_DEVICE EX_USBDEV
110 #endif
111 
112 #ifndef EXAMPLE_LWIP
113 #define EXAMPLE_LWIP 0
114 #else
115 #undef EXAMPLE_LWIP
116 #define EXAMPLE_LWIP EX_LWIP
117 #endif
118 
119 #ifndef EXAMPLE_EMWIN
120 #define EXAMPLE_EMWIN 0
121 #else
122 #undef EXAMPLE_EMWIN
123 #define EXAMPLE_EMWIN EX_EMWIN
124 #endif
125 
126 #define EXAMPLES_INCLUDED (EXAMPLE_BLINKY + EXAMPLE_LWIP + EXAMPLE_USB_HOST + \
127  EXAMPLE_USB_DEVICE + EXAMPLE_EMWIN)
128 
129 /* Image signature structure */
130 /* NOTE: Although the M0 structure created using this type is used in
131  * the startup assembly file, the assembly file just needs the symbol and
132  * not the type, hence keeping it as private structure.
133  */
134 struct image_sig {
135  uint32_t signature; /* Signature M0/M4 image */
136  uint32_t capability; /* Examples included */
137  uint32_t os; /* OS used */
138  char build_date[32]; /* Build Date string */
139  char build_time[32]; /* Build Time string */
140 };
141 
142 #ifdef CORE_M4
143 /* M4 Image Structure */
144 static const struct image_sig __M4Signature = {
145  SIGNATURE_M4_MAGIC, /* M4 Image magic signature */
147  OS_SIGNATURE,
148  __DATE__,
149  __TIME__,
150 };
151 #endif
152 
153 /*****************************************************************************
154  * Public types/enumerations/variables
155  ****************************************************************************/
156 #ifdef CORE_M0
157 /* Structure object that identifies the image as M0 image */
158 /* NOTE: This symbol is used in startup file (only) */
159 const struct image_sig __M0Signature = {
160  SIGNATURE_M0_MAGIC, /* M0 Image magic signature */
162  OS_SIGNATURE,
163  __DATE__,
164  __TIME__,
165 };
166 #endif
167 
168 /*****************************************************************************
169  * Private functions
170  ****************************************************************************/
171 
172 #ifdef CORE_M4
173 /* Function to blink the LED to show the error code
174  * caused by M0 image boot failure
175  */
176 static void booting_m0_failure(uint32_t msec)
177 {
178  int32_t cnt = 60000 / (msec * 2);
179  DEBUGSTR("ERROR: Boot failure!!\r\n");
180  while (cnt--) {
182  MSleep(msec);
184  MSleep(msec);
185  }
186 }
187 
188 /* Prints the information of the M0/M4 image to screen */
189 static void print_image_info(const char *pre, const struct image_sig *img)
190 {
191  DEBUGSTR("***************************************\r\n");
192  DEBUGOUT("%s: Header found at %p\r\n", pre, img);
193  DEBUGOUT("%s: Included Examples: %s%s%s%s%s\r\n", pre,
194  img->capability & EX_BLINKY ? "BLINKY" : "",
195  img->capability & EX_USBHOST ? ", USB_Host" : "",
196  img->capability & EX_USBDEV ? ", USB_Device" : "",
197  img->capability & EX_LWIP ? ", lwIP" : "",
198  img->capability & EX_EMWIN ? ", emWin" : "");
199  DEBUGOUT("%s: OS Used: %s\r\n", pre,
200  img->os == 1 ? "NONE (STANDALONE)" :
201  (img->os == 2 ? "FreeRTOS" : "UCOS-III"));
202  DEBUGOUT("%s: Built on %s %s\r\n", pre,
203  img->build_date,
204  img->build_time);
205  DEBUGSTR("***************************************\r\n");
206 }
207 
208 /* Validates the M0/M4 image at address image_addr */
209 static int CheckImages(uint32_t image_addr, const struct image_sig *m4)
210 {
211  const uint32_t *addr = (uint32_t *) image_addr + 8;
212  const struct image_sig *m0;
213 
214  uint32_t val, usbprob;
215 
216  /* Check for validity of M0 Image */
217  if (*addr != 0xAA55DEAD) {
218  DEBUGOUT("ERROR: Unable to find signature1 of M0 Image at %p\r\n",
219  ((uint32_t *) image_addr + 4));
220  booting_m0_failure(20);
221  return -1;
222  }
223 
224  /* Do sanity check */
225  addr++;
226  if ((image_addr & 0xFFF00000UL) != (*addr & 0xFFF00000UL)) {
227  DEBUGOUT("ERROR: M0 Image at 0x%08X, Infostruct at "
228  "0x%08X not is same region\r\n", image_addr, *addr);
229  booting_m0_failure(20);
230  return -1;
231  }
232 
233  /* Valid structure is found */
234  m0 = (const struct image_sig *) *addr;
235  if (m0->signature != SIGNATURE_M0_MAGIC) {
236  DEBUGSTR("M0_IMAGE: ERROR: M0 image signature 2 not found!\r\n");
237  booting_m0_failure(20);
238  return -1;
239  }
240 
241  /* This should never happen, kept only for completeness */
242  if (m4->signature != SIGNATURE_M4_MAGIC) {
243  DEBUGSTR("M0_IMAGE: ERROR: M4 image signature 2 not found!\r\n");
244  booting_m0_failure(10000);
245  return -1;
246  }
247  print_image_info("M0_IMAGE", m0);
248  print_image_info("M4_IMAGE", m4);
249  val = m0->capability & m4->capability;
250  usbprob = (m0->capability & (EX_USBHOST | EX_USBDEV)) &&
251  (m4->capability & (EX_USBHOST | EX_USBDEV));
252 
253  /* TODO: Check on possibility of running device on one core
254  * and host stack on another
255  **/
256  if (usbprob) {
257  DEBUGSTR("ERROR: Running USB Host/Device stack on both"
258  " cores is not supported yet!\r\n");
259  booting_m0_failure(2000);
260  return -1;
261  }
262 
263  if (val & EX_LWIP) {
264  DEBUGSTR("ERROR: Running lwIP on both core is not supported!\r\n");
265  booting_m0_failure(2000);
266  return -1;
267  }
268 
269  if (val & EX_EMWIN) {
270  DEBUGSTR("ERROR: Running emWIN on both core is not supported!\r\n");
271  booting_m0_failure(2000);
272  return -1;
273  }
274  return 0;
275 }
276 
277 #endif
278 
279 /*****************************************************************************
280  * Public functions
281  ****************************************************************************/
282 
283 #ifdef CORE_M4
284 /* M0 Boot loader */
285 int M0Image_Boot(uint32_t m0_image_addr)
286 {
287  /* Make sure the alignment is OK */
288  if (m0_image_addr & 0xFFF) {
289  return -1;
290  }
291 
292  /* Check the validity of images */
293  if (CheckImages(m0_image_addr, &__M4Signature) != 0) {
294  return -1;
295  }
296 
297  /* Make sure the M0 core is being held in reset via the RGU */
298  Chip_RGU_TriggerReset(RGU_M0APP_RST);
299 
300  Chip_Clock_Enable(CLK_M4_M0APP);
301 
302  /* Keep in mind the M0 image must be aligned on a 4K boundary */
303  Chip_CREG_SetM0AppMemMap(m0_image_addr);
304 
305  Chip_RGU_ClearReset(RGU_M0APP_RST);
306 
307  return 0;
308 }
309 
310 #endif
311