1 /*
2  * Copyright (c) 2020 Seagate Technology LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file Describe the IAP commands interface on NXP LPC11U6x MCUs.
9  *
10  * The IAP (In-Application Programming) commands are located in the boot ROM
11  * code. Mostly they provide access to the on-chip flash and EEPROM devices.
12  *
13  * @note For details about IAP see the UM10732 LPC11U6x/E6x user manual,
14  *       chapter 27: LPC11U6x/E6x Flash/EEPROM ISP/IAP programming.
15  */
16 
17 #ifndef LPC11U6X_IAP_H_
18 #define LPC11U6X_IAP_H_
19 
20 /* Pointer to IAP function. */
21 #define IAP_ENTRY_ADDR			0X1FFF1FF1
22 
23 /* IAP commands. */
24 #define IAP_CMD_FLASH_PREP_SEC		50
25 #define IAP_CMD_FLASH_WRITE_SEC		51
26 #define IAP_CMD_FLASH_ERASE_SEC		52
27 #define IAP_CMD_FLASH_BLANK_CHECK_SEC	53
28 #define IAP_CMD_READ_PART_ID		54
29 #define IAP_CMD_READ_BOOT_CODE_VER	55
30 #define IAP_CMD_MEM_COMPARE		56
31 #define IAP_CMD_REINVOKE_ISP		57
32 #define IAP_CMD_READ_UID		58
33 #define IAP_CMD_FLASH_ERASE_PAGE	59
34 #define IAP_CMD_EEPROM_WRITE		61
35 #define IAP_CMD_EEPROM_READ		62
36 
37 /* IAP status codes. */
38 #define IAP_STATUS_CMD_SUCCESS		0
39 #define IAP_STATUS_INVALID_CMD		1
40 #define IAP_STATUS_SRC_ADDR_ERROR	2
41 #define IAP_STATUS_DST_ADDR_ERROR	3
42 #define IAP_STATUS_SRC_ADDR_NOT_MAPPED	4
43 #define IAP_STATUS_DST_ADDR_NOT_MAPPED	5
44 #define IAP_STATUS_COUNT_ERROR		6
45 #define IAP_STATUS_INVALID_SECTOR	7
46 #define IAP_STATUS_SECTOR_NOT_BLANK	8
47 #define IAP_STATUS_SECTOR_NOT_PREPARED	9
48 #define IAP_STATUS_COMPARE_ERROR	10
49 #define IAP_STATUS_BUSY			11
50 
51 /**
52  * @brief Entry function for IAP commands.
53  */
iap_cmd(unsigned int cmd[5])54 static inline int iap_cmd(unsigned int cmd[5])
55 {
56 	int key;
57 	int status[5];
58 
59 	/*
60 	 * Interrupts must be disabled when calling IAP. Indeed when executing
61 	 * "some" commands, the flash (where the interrupt vectors are located)
62 	 * is no longer accessible.
63 	 */
64 	key = irq_lock();
65 
66 	/*
67 	 * TODO: for the flash commands, the top 32 bytes of memory must be
68 	 * saved before calling the IAP function, and restored after. According
69 	 * to the UM10732 user manual, the IAP code may use them.
70 	 */
71 	((void (*)(unsigned int[], unsigned int[]))
72 		IAP_ENTRY_ADDR)(cmd, status);
73 
74 	irq_unlock(key);
75 
76 	return status[0];
77 }
78 
79 #endif /* LPC11U6X_IAP_H_ */
80