|
18 | 18 | EXCEED AMOUNT OF FEES, IF ANY, YOU PAID DIRECTLY TO MICROCHIP FOR |
19 | 19 | THIS SOFTWARE. |
20 | 20 | */ |
| 21 | + |
| 22 | +/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ |
21 | 23 | #warning "!!RUNNING THIS PROGRAM AND FOLLOWING THE STEPS OUTLINED IN THE CONSOLE WILL PERMANENTLY DISABLE DIRECT PROGRAMMING OF THE BOARD. FOR ADDITIONAL INFORMATION, SEE THE README.MD INCLUDED WITH THIS PROJECT AND THE FAMILY DATA SHEET LOCATED AT https://ww1.microchip.com/downloads/aemDocuments/documents/MCU16/ProductDocuments/DataSheets/dsPIC33CK1024MP710-Family-Data-Sheet-DS70005496.pdf" |
22 | 24 |
|
23 | | -#include <stdio.h> |
24 | | -#include <string.h> |
25 | | -#include <stdbool.h> |
26 | 25 | #include "mcc_generated_files/flash/flash.h" |
27 | 26 | #include "mcc_generated_files/flash/flash_types.h" |
28 | 27 | #include "mcc_generated_files/boot/boot_config.h" |
| 28 | +#include "mcc_generated_files/uart/uart1.h" |
| 29 | +#include "mcc_generated_files/system/system.h" |
| 30 | +#include "icsp_inhibit.h" |
| 31 | +#include "terminal.h" |
| 32 | + |
| 33 | +#include <stdio.h> |
| 34 | +#include <string.h> |
| 35 | +#include <stdbool.h> |
| 36 | +#include <ctype.h> |
29 | 37 |
|
30 | | -#define WINDOW_SIZE 10 |
| 38 | +#define USER_INPUT_BUFFER_SIZE 50 |
31 | 39 | #define UNLOCK_COMMAND "LOCKDEVICE" |
| 40 | +#define STRCMP_MATCHES 0 |
| 41 | +#define ENTER '\r' |
| 42 | +#define TERMINAL_LINE_ERROR 7 |
| 43 | +#define TERMINAL_LINE_INPUT 5 |
| 44 | +#define TERMINAL_LINE_HOME 1 |
32 | 45 |
|
33 | 46 | // Function prototypes |
34 | | -static void ClearTerminalScreen(void); |
35 | | -static void ClearTerminalLine(void); |
36 | | -static void MoveCursor(int row); |
37 | | -static void HideCursor(void); |
38 | 47 | static void PrintWarning(void); |
39 | | -static void AppendCharToWindow(char receivedChar, char *window, int *windowIndex); |
40 | | -static void ProcessReceivedChar(char receivedChar, char *window, int *windowIndex); |
41 | | -static void ResetWindowOnMismatch(char *window, int *windowIndex); |
42 | | -static void CheckForUnlockCommand(char *window, int *windowIndex); |
43 | 48 | static uint32_t GetResetAddress(); |
44 | 49 | static bool WasLoadedByBootloader(); |
| 50 | +static void PrintBootloaderRequired(void); |
| 51 | +static char* ScanInput(void); |
| 52 | +static void PrintErrorMessage(char* error); |
| 53 | +static void PrintProgrammingDisabled(void); |
| 54 | +static void ClearUserInput(void); |
| 55 | +static void ClearErrorMessage(void); |
| 56 | +static void ResetPrompt(void); |
| 57 | + |
| 58 | +// Local Variables |
| 59 | +static char userInput[USER_INPUT_BUFFER_SIZE] = {0}; |
| 60 | +static bool errorPresent = false; |
45 | 61 |
|
46 | 62 | int main(void) |
47 | 63 | { |
48 | | - char window[WINDOW_SIZE + 1] = {0}; |
49 | | - int windowIndex = 0; |
| 64 | + const char* keyword = "LOCKDEVICE"; |
50 | 65 |
|
51 | 66 | SYSTEM_Initialize(); |
52 | | - ClearTerminalScreen(); |
| 67 | + |
| 68 | + if(WasLoadedByBootloader() == false) |
| 69 | + { |
| 70 | + PrintBootloaderRequired(); |
| 71 | + |
| 72 | + while(1) |
| 73 | + { |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + if(ICSP_INHIBIT_IsEnabled()) |
| 78 | + { |
| 79 | + PrintProgrammingDisabled(); |
| 80 | + |
| 81 | + while(1) |
| 82 | + { |
| 83 | + } |
| 84 | + } |
| 85 | + |
53 | 86 | PrintWarning(); |
54 | | - while (1) |
| 87 | + |
| 88 | + while(1) |
55 | 89 | { |
56 | | - if (UART1_IsRxReady()) |
| 90 | + char* userInput = ScanInput(); |
| 91 | + |
| 92 | + if(strcmp(userInput, keyword) == STRCMP_MATCHES) |
| 93 | + { |
| 94 | + //ICSP_INHIBIT_Enable(); //Disable during development for safety |
| 95 | + |
| 96 | + PrintProgrammingDisabled(); |
| 97 | + |
| 98 | + while(1) |
| 99 | + { |
| 100 | + } |
| 101 | + } |
| 102 | + else |
57 | 103 | { |
58 | | - char receivedChar = UART1_Read(); |
59 | | - ProcessReceivedChar(receivedChar, window, &windowIndex); |
60 | | - CheckForUnlockCommand(window, &windowIndex); |
| 104 | + PrintErrorMessage("Invalid keyword entered. Try again."); |
61 | 105 | } |
62 | 106 | } |
63 | 107 | } |
64 | 108 |
|
65 | | -static void ClearTerminalScreen(void) |
| 109 | +static char* ScanInput(void) |
66 | 110 | { |
67 | | - printf("\033[2J"); |
68 | | -} |
| 111 | + uint8_t userInputOffset = 0; |
| 112 | + char key; |
| 113 | + |
| 114 | + ClearUserInput(); |
| 115 | + |
| 116 | + do |
| 117 | + { |
| 118 | + key = UART1_Read(); |
| 119 | + |
| 120 | + /* If there is still an error message after the first user key press, |
| 121 | + * clear the error and reset the prompt before printing their input. */ |
| 122 | + if(errorPresent) |
| 123 | + { |
| 124 | + ClearErrorMessage(); |
| 125 | + ResetPrompt(); |
| 126 | + } |
| 127 | + |
| 128 | + if(isalnum(key) && (userInputOffset < sizeof(userInput))) |
| 129 | + { |
| 130 | + userInput[userInputOffset++] = key; |
| 131 | + printf("%c", key); |
| 132 | + } |
| 133 | + } |
| 134 | + while(key != ENTER); |
69 | 135 |
|
70 | | -static void ClearTerminalLine(void) |
71 | | -{ |
72 | | - printf("\33[2K\r"); |
| 136 | + return userInput; |
73 | 137 | } |
74 | 138 |
|
75 | | -static void MoveCursor(int row) |
| 139 | +static void PrintProgrammingDisabled(void) |
76 | 140 | { |
77 | | - printf("\033[%d;0f", row); |
| 141 | + TERMINAL_EnableCursor(false); |
| 142 | + TERMINAL_MoveCursor(TERMINAL_LINE_HOME); |
| 143 | + TERMINAL_ClearScreen(); |
| 144 | + |
| 145 | + printf("\r\n"); |
| 146 | + printf("\r\n"); |
| 147 | + printf("\r\n"); |
| 148 | + printf("*** ICSP Programming/Debugging permanently disabled. ***\r\n"); |
| 149 | + printf("\r\n"); |
| 150 | + printf("Use the bootloader to load all future applications into this board."); |
78 | 151 | } |
79 | 152 |
|
80 | | -static void HideCursor(void) |
| 153 | +static void ClearErrorMessage(void) |
81 | 154 | { |
82 | | - printf("\033[?25l"); |
| 155 | + TERMINAL_MoveCursor(TERMINAL_LINE_ERROR); |
| 156 | + TERMINAL_ClearLine(); |
| 157 | + |
| 158 | + errorPresent = false; |
83 | 159 | } |
84 | 160 |
|
85 | | -static void PrintWarning(void) |
| 161 | +static void ResetPrompt(void) |
86 | 162 | { |
87 | | - MoveCursor(1); |
88 | | - printf("Type LOCKDEVICE to enable the ICSP Inhibit feature."); |
89 | | - MoveCursor(3); |
90 | | - printf("WARNING: THIS PERMANENTLY DISABLES DIRECT PROGRAMMING OF THE BOARD."); |
| 163 | + TERMINAL_MoveCursor(TERMINAL_LINE_INPUT); |
| 164 | + TERMINAL_ClearLine(); |
| 165 | + printf(">> "); |
91 | 166 | } |
92 | 167 |
|
93 | | -static void ProcessReceivedChar(char receivedChar, char *window, int *windowIndex) |
| 168 | +static void PrintErrorMessage(char* errorMessage) |
94 | 169 | { |
95 | | - bool isCharValid = (*windowIndex < strlen(UNLOCK_COMMAND)) && (receivedChar == UNLOCK_COMMAND[*windowIndex]); |
| 170 | + ClearErrorMessage(); |
96 | 171 |
|
97 | | - if (isCharValid) |
98 | | - { |
99 | | - AppendCharToWindow(receivedChar, window, windowIndex); |
100 | | - MoveCursor(10); |
101 | | - printf("%s", window); |
102 | | - } |
103 | | - else |
104 | | - { |
105 | | - ResetWindowOnMismatch(window, windowIndex); |
106 | | - } |
| 172 | + printf("%s", errorMessage); |
| 173 | + errorPresent = true; |
| 174 | + |
| 175 | + ResetPrompt(); |
107 | 176 | } |
108 | 177 |
|
109 | | -static void AppendCharToWindow(char receivedChar, char *window, int *windowIndex) |
| 178 | +static void ClearUserInput(void) |
110 | 179 | { |
111 | | - window[(*windowIndex)++] = receivedChar; |
112 | | - window[*windowIndex] = '\0'; |
| 180 | + memset(userInput, 0, sizeof(userInput)); |
113 | 181 | } |
114 | 182 |
|
115 | | -static void ResetWindowOnMismatch(char *window, int *windowIndex) |
| 183 | +static void PrintWarning(void) |
116 | 184 | { |
117 | | - MoveCursor(10); |
118 | | - ClearTerminalLine(); |
119 | | - MoveCursor(5); |
120 | | - ClearTerminalLine(); |
121 | | - printf("Invalid character entered. Try again."); |
122 | | - *windowIndex = 0; |
123 | | - memset(window, 0, WINDOW_SIZE + 1); |
| 185 | + TERMINAL_EnableCursor(false); |
| 186 | + TERMINAL_MoveCursor(TERMINAL_LINE_HOME); |
| 187 | + TERMINAL_ClearScreen(); |
| 188 | + |
| 189 | + printf("Type LOCKDEVICE (plus ENTER) to enable the ICSP Inhibit feature.\r\n"); |
| 190 | + printf("\r\n"); |
| 191 | + printf("WARNING: THIS PERMANENTLY DISABLES DIRECT PROGRAMMING OF THE BOARD.\r\n"); |
| 192 | + printf("\r\n"); |
| 193 | + printf(">> "); |
| 194 | + |
| 195 | + TERMINAL_EnableCursor(true); |
124 | 196 | } |
125 | 197 |
|
126 | | -static void CheckForUnlockCommand(char *window, int *windowIndex) |
| 198 | +static void PrintBootloaderRequired(void) |
127 | 199 | { |
128 | | - if (strncmp(window, UNLOCK_COMMAND, *windowIndex) == 0 && *windowIndex == strlen(UNLOCK_COMMAND)) |
129 | | - { |
130 | | - MoveCursor(5); |
131 | | - ClearTerminalLine(); |
132 | | - printf("ICSP Programming/Debugging permanently disabled. \n"); |
133 | | - MoveCursor(10); |
134 | | - ClearTerminalLine(); |
135 | | - *windowIndex = 0; |
136 | | - memset(window, 0, WINDOW_SIZE + 1); |
137 | | - } |
| 200 | + TERMINAL_EnableCursor(false); |
| 201 | + TERMINAL_MoveCursor(TERMINAL_LINE_HOME); |
| 202 | + TERMINAL_ClearScreen(); |
| 203 | + |
| 204 | + printf("NO BOOTLOADER DETECTED!\r\n"); |
| 205 | + printf("\r\n"); |
| 206 | + printf("Because programming will be permanently disabled, \r\n"); |
| 207 | + printf("a bootloader is required to run this demo. \r\n"); |
| 208 | + printf("Please see the readme.md for more information.\r\n"); |
138 | 209 | } |
139 | 210 |
|
140 | 211 | /* The following code finds the address used by GOTO instruction programmed |
|
0 commit comments