Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
BaseEmuISP.cpp@1:4ff199bddbc1, 2016-03-08 (annotated)
- Committer:
- va009039
- Date:
- Tue Mar 08 12:03:48 2016 +0900
- Revision:
- 1:4ff199bddbc1
- Child:
- 2:e3c085ac77f1
first commit.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 |
1:4ff199bddbc1 | 1 | // BaseEmuISP.cpp 2016/3/7 |
va009039 |
1:4ff199bddbc1 | 2 | #include <stdio.h> |
va009039 |
1:4ff199bddbc1 | 3 | #include <stdlib.h> |
va009039 |
1:4ff199bddbc1 | 4 | #include <string.h> |
va009039 |
1:4ff199bddbc1 | 5 | #include <stdarg.h> |
va009039 |
1:4ff199bddbc1 | 6 | #include "BaseEmuISP.h" |
va009039 |
1:4ff199bddbc1 | 7 | |
va009039 |
1:4ff199bddbc1 | 8 | void BaseEmuISP::Reset() { |
va009039 |
1:4ff199bddbc1 | 9 | mode = M_RESET; |
va009039 |
1:4ff199bddbc1 | 10 | } |
va009039 |
1:4ff199bddbc1 | 11 | |
va009039 |
1:4ff199bddbc1 | 12 | void BaseEmuISP::Poll() { |
va009039 |
1:4ff199bddbc1 | 13 | int prev_mode = mode; |
va009039 |
1:4ff199bddbc1 | 14 | int result; |
va009039 |
1:4ff199bddbc1 | 15 | int c; |
va009039 |
1:4ff199bddbc1 | 16 | char buf[32]; |
va009039 |
1:4ff199bddbc1 | 17 | switch(mode) { |
va009039 |
1:4ff199bddbc1 | 18 | case M_RESET: |
va009039 |
1:4ff199bddbc1 | 19 | echoFlag = true; |
va009039 |
1:4ff199bddbc1 | 20 | lockFlag = true; |
va009039 |
1:4ff199bddbc1 | 21 | mode = M_SYNC; |
va009039 |
1:4ff199bddbc1 | 22 | break; |
va009039 |
1:4ff199bddbc1 | 23 | case M_SYNC: |
va009039 |
1:4ff199bddbc1 | 24 | if (sync()) { |
va009039 |
1:4ff199bddbc1 | 25 | mode = M_CMD; |
va009039 |
1:4ff199bddbc1 | 26 | } |
va009039 |
1:4ff199bddbc1 | 27 | break; |
va009039 |
1:4ff199bddbc1 | 28 | case M_CMD: |
va009039 |
1:4ff199bddbc1 | 29 | if (line_proc()) { |
va009039 |
1:4ff199bddbc1 | 30 | result = cmd(line.c_str()); |
va009039 |
1:4ff199bddbc1 | 31 | snprintf(buf, sizeof(buf), "%d", result); |
va009039 |
1:4ff199bddbc1 | 32 | putln(buf); |
va009039 |
1:4ff199bddbc1 | 33 | line.clear(); |
va009039 |
1:4ff199bddbc1 | 34 | } |
va009039 |
1:4ff199bddbc1 | 35 | break; |
va009039 |
1:4ff199bddbc1 | 36 | case M_CMD_W_DATA: |
va009039 |
1:4ff199bddbc1 | 37 | if (count > 0) { |
va009039 |
1:4ff199bddbc1 | 38 | c = Getch(); |
va009039 |
1:4ff199bddbc1 | 39 | if (c != (-1)) { |
va009039 |
1:4ff199bddbc1 | 40 | if (echoFlag) { |
va009039 |
1:4ff199bddbc1 | 41 | Putch(c); |
va009039 |
1:4ff199bddbc1 | 42 | } |
va009039 |
1:4ff199bddbc1 | 43 | WriteData(addr++, c); |
va009039 |
1:4ff199bddbc1 | 44 | count--; |
va009039 |
1:4ff199bddbc1 | 45 | } |
va009039 |
1:4ff199bddbc1 | 46 | } else { |
va009039 |
1:4ff199bddbc1 | 47 | mode = M_CMD; |
va009039 |
1:4ff199bddbc1 | 48 | } |
va009039 |
1:4ff199bddbc1 | 49 | break; |
va009039 |
1:4ff199bddbc1 | 50 | case M_CMD_R_DATA: |
va009039 |
1:4ff199bddbc1 | 51 | if (count > 0) { |
va009039 |
1:4ff199bddbc1 | 52 | c = ReadData(addr++); |
va009039 |
1:4ff199bddbc1 | 53 | Putch(c); |
va009039 |
1:4ff199bddbc1 | 54 | count--; |
va009039 |
1:4ff199bddbc1 | 55 | } else { |
va009039 |
1:4ff199bddbc1 | 56 | mode = M_CMD; |
va009039 |
1:4ff199bddbc1 | 57 | } |
va009039 |
1:4ff199bddbc1 | 58 | break; |
va009039 |
1:4ff199bddbc1 | 59 | case M_CMD_J: |
va009039 |
1:4ff199bddbc1 | 60 | snprintf(buf, sizeof(buf), "%d", Part()); |
va009039 |
1:4ff199bddbc1 | 61 | putln(buf); |
va009039 |
1:4ff199bddbc1 | 62 | mode = M_CMD; |
va009039 |
1:4ff199bddbc1 | 63 | break; |
va009039 |
1:4ff199bddbc1 | 64 | } |
va009039 |
1:4ff199bddbc1 | 65 | if (prev_mode != mode) { |
va009039 |
1:4ff199bddbc1 | 66 | seq = 0; |
va009039 |
1:4ff199bddbc1 | 67 | line.clear(); |
va009039 |
1:4ff199bddbc1 | 68 | } |
va009039 |
1:4ff199bddbc1 | 69 | } |
va009039 |
1:4ff199bddbc1 | 70 | |
va009039 |
1:4ff199bddbc1 | 71 | bool BaseEmuISP::sync() { |
va009039 |
1:4ff199bddbc1 | 72 | switch(seq) { |
va009039 |
1:4ff199bddbc1 | 73 | case 0: |
va009039 |
1:4ff199bddbc1 | 74 | if (Getch() == '?') { |
va009039 |
1:4ff199bddbc1 | 75 | putln("Synchronized"); |
va009039 |
1:4ff199bddbc1 | 76 | line.clear(); |
va009039 |
1:4ff199bddbc1 | 77 | echoFlag = true; |
va009039 |
1:4ff199bddbc1 | 78 | seq++; |
va009039 |
1:4ff199bddbc1 | 79 | } |
va009039 |
1:4ff199bddbc1 | 80 | break; |
va009039 |
1:4ff199bddbc1 | 81 | case 1: |
va009039 |
1:4ff199bddbc1 | 82 | if (line_proc()) { |
va009039 |
1:4ff199bddbc1 | 83 | if (line == "Synchronized") { |
va009039 |
1:4ff199bddbc1 | 84 | putln("OK"); |
va009039 |
1:4ff199bddbc1 | 85 | line.clear(); |
va009039 |
1:4ff199bddbc1 | 86 | seq++; |
va009039 |
1:4ff199bddbc1 | 87 | } else { |
va009039 |
1:4ff199bddbc1 | 88 | seq = 0; |
va009039 |
1:4ff199bddbc1 | 89 | } |
va009039 |
1:4ff199bddbc1 | 90 | } |
va009039 |
1:4ff199bddbc1 | 91 | break; |
va009039 |
1:4ff199bddbc1 | 92 | case 2: |
va009039 |
1:4ff199bddbc1 | 93 | if (line_proc()) { |
va009039 |
1:4ff199bddbc1 | 94 | freq = atoi(line.c_str()); |
va009039 |
1:4ff199bddbc1 | 95 | putln("OK"); |
va009039 |
1:4ff199bddbc1 | 96 | return true; |
va009039 |
1:4ff199bddbc1 | 97 | } |
va009039 |
1:4ff199bddbc1 | 98 | break; |
va009039 |
1:4ff199bddbc1 | 99 | } |
va009039 |
1:4ff199bddbc1 | 100 | return false; |
va009039 |
1:4ff199bddbc1 | 101 | } |
va009039 |
1:4ff199bddbc1 | 102 | |
va009039 |
1:4ff199bddbc1 | 103 | static int split(std::vector<char*> ¶m, char *buf, const char* delimiters = " ") { |
va009039 |
1:4ff199bddbc1 | 104 | param.clear(); |
va009039 |
1:4ff199bddbc1 | 105 | char* p = strtok(buf, delimiters); |
va009039 |
1:4ff199bddbc1 | 106 | while(p != NULL) { |
va009039 |
1:4ff199bddbc1 | 107 | param.push_back(p); |
va009039 |
1:4ff199bddbc1 | 108 | p = strtok(NULL, delimiters); |
va009039 |
1:4ff199bddbc1 | 109 | } |
va009039 |
1:4ff199bddbc1 | 110 | return param.size(); |
va009039 |
1:4ff199bddbc1 | 111 | } |
va009039 |
1:4ff199bddbc1 | 112 | |
va009039 |
1:4ff199bddbc1 | 113 | int BaseEmuISP::cmd(const char *str) { |
va009039 |
1:4ff199bddbc1 | 114 | char buf[strlen(str) + 1]; |
va009039 |
1:4ff199bddbc1 | 115 | strcpy(buf, str); |
va009039 |
1:4ff199bddbc1 | 116 | std::vector<char*> p; |
va009039 |
1:4ff199bddbc1 | 117 | int arg = split(p, buf); |
va009039 |
1:4ff199bddbc1 | 118 | if (arg == 0) { |
va009039 |
1:4ff199bddbc1 | 119 | return INVALID_COMMAND; |
va009039 |
1:4ff199bddbc1 | 120 | } |
va009039 |
1:4ff199bddbc1 | 121 | std::vector<int> param; |
va009039 |
1:4ff199bddbc1 | 122 | param.push_back(p[0][0]); |
va009039 |
1:4ff199bddbc1 | 123 | for(int i = 1; i < p.size(); i++) { |
va009039 |
1:4ff199bddbc1 | 124 | param.push_back(atoi(p[i])); |
va009039 |
1:4ff199bddbc1 | 125 | } |
va009039 |
1:4ff199bddbc1 | 126 | switch(param[0]) { |
va009039 |
1:4ff199bddbc1 | 127 | case 'U': return cmd_u(arg, param[1]); |
va009039 |
1:4ff199bddbc1 | 128 | case 'A': return cmd_a(arg, param[1]); |
va009039 |
1:4ff199bddbc1 | 129 | case 'W': return cmd_w(arg, param[1], param[2]); |
va009039 |
1:4ff199bddbc1 | 130 | case 'R': return cmd_r(arg, param[1], param[2]); |
va009039 |
1:4ff199bddbc1 | 131 | case 'P': return cmd_p(arg, param[1], param[2]); |
va009039 |
1:4ff199bddbc1 | 132 | case 'C': return cmd_c(arg, param[1], param[2], param[3]); |
va009039 |
1:4ff199bddbc1 | 133 | case 'E': return cmd_e(arg, param[1], param[2]); |
va009039 |
1:4ff199bddbc1 | 134 | case 'J': return cmd_j(arg); |
va009039 |
1:4ff199bddbc1 | 135 | default: return INVALID_COMMAND; |
va009039 |
1:4ff199bddbc1 | 136 | } |
va009039 |
1:4ff199bddbc1 | 137 | } |
va009039 |
1:4ff199bddbc1 | 138 | |
va009039 |
1:4ff199bddbc1 | 139 | int BaseEmuISP::cmd_a(int arg, int p1) { |
va009039 |
1:4ff199bddbc1 | 140 | if (p1 == 0 || p1 == 1) { |
va009039 |
1:4ff199bddbc1 | 141 | echoFlag = (p1 == 1) ? true : false; |
va009039 |
1:4ff199bddbc1 | 142 | return CMD_SUCCESS; |
va009039 |
1:4ff199bddbc1 | 143 | } |
va009039 |
1:4ff199bddbc1 | 144 | return PARAM_ERROR; |
va009039 |
1:4ff199bddbc1 | 145 | } |
va009039 |
1:4ff199bddbc1 | 146 | |
va009039 |
1:4ff199bddbc1 | 147 | int BaseEmuISP::cmd_u(int arg, int p1) { |
va009039 |
1:4ff199bddbc1 | 148 | if (p1 == 23130) { |
va009039 |
1:4ff199bddbc1 | 149 | lockFlag = false; |
va009039 |
1:4ff199bddbc1 | 150 | return CMD_SUCCESS; |
va009039 |
1:4ff199bddbc1 | 151 | } |
va009039 |
1:4ff199bddbc1 | 152 | return PARAM_ERROR; |
va009039 |
1:4ff199bddbc1 | 153 | } |
va009039 |
1:4ff199bddbc1 | 154 | |
va009039 |
1:4ff199bddbc1 | 155 | int BaseEmuISP::cmd_w(int arg, int p1, int p2) { |
va009039 |
1:4ff199bddbc1 | 156 | if (p1 % 4 != 0) { |
va009039 |
1:4ff199bddbc1 | 157 | return ADDR_ERROR; |
va009039 |
1:4ff199bddbc1 | 158 | } |
va009039 |
1:4ff199bddbc1 | 159 | if (p2 % 4 != 0) { |
va009039 |
1:4ff199bddbc1 | 160 | return COUNT_ERROR; |
va009039 |
1:4ff199bddbc1 | 161 | } |
va009039 |
1:4ff199bddbc1 | 162 | addr = p1; |
va009039 |
1:4ff199bddbc1 | 163 | count = p2; |
va009039 |
1:4ff199bddbc1 | 164 | mode = M_CMD_W_DATA; |
va009039 |
1:4ff199bddbc1 | 165 | return CMD_SUCCESS; |
va009039 |
1:4ff199bddbc1 | 166 | } |
va009039 |
1:4ff199bddbc1 | 167 | |
va009039 |
1:4ff199bddbc1 | 168 | int BaseEmuISP::cmd_r(int arg, int p1, int p2) { |
va009039 |
1:4ff199bddbc1 | 169 | if (p1 % 4 != 0) { |
va009039 |
1:4ff199bddbc1 | 170 | return ADDR_ERROR; |
va009039 |
1:4ff199bddbc1 | 171 | } |
va009039 |
1:4ff199bddbc1 | 172 | if (p2 % 4 != 0) { |
va009039 |
1:4ff199bddbc1 | 173 | return COUNT_ERROR; |
va009039 |
1:4ff199bddbc1 | 174 | } |
va009039 |
1:4ff199bddbc1 | 175 | addr = p1; |
va009039 |
1:4ff199bddbc1 | 176 | count = p2; |
va009039 |
1:4ff199bddbc1 | 177 | mode = M_CMD_R_DATA; |
va009039 |
1:4ff199bddbc1 | 178 | return CMD_SUCCESS; |
va009039 |
1:4ff199bddbc1 | 179 | } |
va009039 |
1:4ff199bddbc1 | 180 | |
va009039 |
1:4ff199bddbc1 | 181 | int BaseEmuISP::cmd_p(int arg, int p1, int p2) { |
va009039 |
1:4ff199bddbc1 | 182 | return CMD_SUCCESS; |
va009039 |
1:4ff199bddbc1 | 183 | } |
va009039 |
1:4ff199bddbc1 | 184 | |
va009039 |
1:4ff199bddbc1 | 185 | int BaseEmuISP::cmd_c(int arg, int p1, int p2, int p3) { |
va009039 |
1:4ff199bddbc1 | 186 | if (p1 % 4 != 0) { |
va009039 |
1:4ff199bddbc1 | 187 | return DST_ADDR_ERROR; |
va009039 |
1:4ff199bddbc1 | 188 | } |
va009039 |
1:4ff199bddbc1 | 189 | if (p2 % 4 != 0) { |
va009039 |
1:4ff199bddbc1 | 190 | return SRC_ADDR_ERROR; |
va009039 |
1:4ff199bddbc1 | 191 | } |
va009039 |
1:4ff199bddbc1 | 192 | if (p3 != 64 && p3 != 128 && p3 != 256 && p3 != 512 && p3 != 1024) { |
va009039 |
1:4ff199bddbc1 | 193 | return COUNT_ERROR; |
va009039 |
1:4ff199bddbc1 | 194 | } |
va009039 |
1:4ff199bddbc1 | 195 | CopyData(p1, p2, p3); |
va009039 |
1:4ff199bddbc1 | 196 | return CMD_SUCCESS; |
va009039 |
1:4ff199bddbc1 | 197 | } |
va009039 |
1:4ff199bddbc1 | 198 | |
va009039 |
1:4ff199bddbc1 | 199 | int BaseEmuISP::cmd_e(int arg, int p1, int p2) { |
va009039 |
1:4ff199bddbc1 | 200 | if (SectorExist(p1) == false || SectorExist(p2) == false) { |
va009039 |
1:4ff199bddbc1 | 201 | return INVALID_SECTOR; |
va009039 |
1:4ff199bddbc1 | 202 | } |
va009039 |
1:4ff199bddbc1 | 203 | return CMD_SUCCESS; |
va009039 |
1:4ff199bddbc1 | 204 | } |
va009039 |
1:4ff199bddbc1 | 205 | |
va009039 |
1:4ff199bddbc1 | 206 | int BaseEmuISP::cmd_j(int arg) { |
va009039 |
1:4ff199bddbc1 | 207 | mode = M_CMD_J; |
va009039 |
1:4ff199bddbc1 | 208 | return CMD_SUCCESS; |
va009039 |
1:4ff199bddbc1 | 209 | } |
va009039 |
1:4ff199bddbc1 | 210 | |
va009039 |
1:4ff199bddbc1 | 211 | void BaseEmuISP::putln(const char *s) { |
va009039 |
1:4ff199bddbc1 | 212 | debugPrintf("send: %s<CR><LF>\n", s); |
va009039 |
1:4ff199bddbc1 | 213 | while(*s) { |
va009039 |
1:4ff199bddbc1 | 214 | Putch(*s++); |
va009039 |
1:4ff199bddbc1 | 215 | } |
va009039 |
1:4ff199bddbc1 | 216 | Putch('\r'); |
va009039 |
1:4ff199bddbc1 | 217 | Putch('\n'); |
va009039 |
1:4ff199bddbc1 | 218 | } |
va009039 |
1:4ff199bddbc1 | 219 | |
va009039 |
1:4ff199bddbc1 | 220 | bool BaseEmuISP::line_proc() { |
va009039 |
1:4ff199bddbc1 | 221 | int c = Getch(); |
va009039 |
1:4ff199bddbc1 | 222 | if (c != (-1)) { |
va009039 |
1:4ff199bddbc1 | 223 | if (echoFlag) { |
va009039 |
1:4ff199bddbc1 | 224 | Putch(c); |
va009039 |
1:4ff199bddbc1 | 225 | } |
va009039 |
1:4ff199bddbc1 | 226 | if (c == '\n') { |
va009039 |
1:4ff199bddbc1 | 227 | debugPrintf("<LF>\n"); |
va009039 |
1:4ff199bddbc1 | 228 | return true; |
va009039 |
1:4ff199bddbc1 | 229 | } else if (c == '\r') { |
va009039 |
1:4ff199bddbc1 | 230 | debugPrintf("<CR>"); |
va009039 |
1:4ff199bddbc1 | 231 | } else { |
va009039 |
1:4ff199bddbc1 | 232 | if (line.size() == 0) { |
va009039 |
1:4ff199bddbc1 | 233 | debugPrintf("recv: "); |
va009039 |
1:4ff199bddbc1 | 234 | } |
va009039 |
1:4ff199bddbc1 | 235 | debugPrintf("%c", c); |
va009039 |
1:4ff199bddbc1 | 236 | line += c; |
va009039 |
1:4ff199bddbc1 | 237 | } |
va009039 |
1:4ff199bddbc1 | 238 | } |
va009039 |
1:4ff199bddbc1 | 239 | return false; |
va009039 |
1:4ff199bddbc1 | 240 | } |
va009039 |
1:4ff199bddbc1 | 241 | |
va009039 |
1:4ff199bddbc1 | 242 | void BaseEmuISP::debugPrintf(const char *format, ...) { |
va009039 |
1:4ff199bddbc1 | 243 | char buf[256]; |
va009039 |
1:4ff199bddbc1 | 244 | va_list args; |
va009039 |
1:4ff199bddbc1 | 245 | va_start(args, format); |
va009039 |
1:4ff199bddbc1 | 246 | vsprintf(buf, format, args); |
va009039 |
1:4ff199bddbc1 | 247 | for(const char *s = buf; *s; s++) { |
va009039 |
1:4ff199bddbc1 | 248 | DebugPutch(*s); |
va009039 |
1:4ff199bddbc1 | 249 | } |
va009039 |
1:4ff199bddbc1 | 250 | va_end(args); |
va009039 |
1:4ff199bddbc1 | 251 | } |
va009039 |
1:4ff199bddbc1 | 252 |