Changeset 1541
- Timestamp:
- Jun 8, 2012 5:27:47 PM (13 months ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
buspirate_spi.c (modified) (13 diffs)
-
flash.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/buspirate_spi.c
r1474 r1541 40 40 /* 115200bps, 8 databits, no parity, 1 stopbit */ 41 41 sp_fd = sp_openserport(dev, 115200); 42 /* FIXME: Error checking */ 42 43 return 0; 43 44 } … … 49 50 #define sp_flush_incoming(...) 0 50 51 #endif 52 53 static unsigned char *bp_commbuf = NULL; 54 static int bp_commbufsize = 0; 55 56 static int buspirate_commbuf_grow(int bufsize) 57 { 58 unsigned char *tmpbuf; 59 60 /* Never shrink. realloc() calls are expensive. */ 61 if (bufsize <= bp_commbufsize) 62 return 0; 63 64 tmpbuf = realloc(bp_commbuf, bufsize); 65 if (!tmpbuf) { 66 /* Keep the existing buffer because memory is already tight. */ 67 msg_perr("Out of memory!\n"); 68 return ERROR_OOM; 69 } 70 71 bp_commbuf = tmpbuf; 72 bp_commbufsize = bufsize; 73 return 0; 74 } 51 75 52 76 static int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt, … … 117 141 static int buspirate_spi_shutdown(void *data) 118 142 { 119 unsigned char buf[5];120 int ret = 0;143 int ret = 0, ret2 = 0; 144 /* No need to allocate a buffer here, we know that bp_commbuf is at least DEFAULT_BUFSIZE big. */ 121 145 122 146 /* Exit raw SPI mode (enter raw bitbang mode) */ 123 b uf[0] = 0x00;124 ret = buspirate_sendrecv(b uf, 1, 5);125 if (ret) 126 return ret;127 if (memcmp(b uf, "BBIO", 4)) {147 bp_commbuf[0] = 0x00; 148 ret = buspirate_sendrecv(bp_commbuf, 1, 5); 149 if (ret) 150 goto out_shutdown; 151 if (memcmp(bp_commbuf, "BBIO", 4)) { 128 152 msg_perr("Entering raw bitbang mode failed!\n"); 129 return 1; 130 } 131 msg_pdbg("Raw bitbang mode version %c\n", buf[4]); 132 if (buf[4] != '1') { 133 msg_perr("Can't handle raw bitbang mode version %c!\n", 134 buf[4]); 135 return 1; 153 ret = 1; 154 goto out_shutdown; 155 } 156 msg_pdbg("Raw bitbang mode version %c\n", bp_commbuf[4]); 157 if (bp_commbuf[4] != '1') { 158 msg_perr("Can't handle raw bitbang mode version %c!\n", bp_commbuf[4]); 159 ret = 1; 160 goto out_shutdown; 136 161 } 137 162 /* Reset Bus Pirate (return to user terminal) */ 138 buf[0] = 0x0f; 139 ret = buspirate_sendrecv(buf, 1, 0); 140 if (ret) 141 return ret; 142 163 bp_commbuf[0] = 0x0f; 164 ret = buspirate_sendrecv(bp_commbuf, 1, 0); 165 166 out_shutdown: 143 167 /* Shut down serial port communication */ 144 ret = serialport_shutdown(NULL); 145 if (ret) 146 return ret; 147 msg_pdbg("Bus Pirate shutdown completed.\n"); 148 149 return 0; 168 ret2 = serialport_shutdown(NULL); 169 /* Keep the oldest error, it is probably the best indicator. */ 170 if (ret2 && !ret) 171 ret = ret2; 172 bp_commbufsize = 0; 173 free(bp_commbuf); 174 bp_commbuf = NULL; 175 if (ret) 176 msg_pdbg("Bus Pirate shutdown failed.\n"); 177 else 178 msg_pdbg("Bus Pirate shutdown completed.\n"); 179 180 return ret; 150 181 } 151 182 152 183 int buspirate_spi_init(void) 153 184 { 154 unsigned char buf[512];155 185 char *dev = NULL; 156 186 char *speed = NULL; … … 182 212 msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed].name); 183 213 214 /* Default buffer size is 19: 16 bytes data, 3 bytes control. */ 215 #define DEFAULT_BUFSIZE (16 + 3) 216 bp_commbuf = malloc(DEFAULT_BUFSIZE); 217 if (!bp_commbuf) { 218 bp_commbufsize = 0; 219 msg_perr("Out of memory!\n"); 220 return ERROR_OOM; 221 } 222 bp_commbufsize = DEFAULT_BUFSIZE; 223 184 224 ret = buspirate_serialport_setup(dev); 185 if (ret)186 return ret;187 225 free(dev); 226 if (ret) { 227 bp_commbufsize = 0; 228 free(bp_commbuf); 229 bp_commbuf = NULL; 230 return ret; 231 } 188 232 189 233 if (register_shutdown(buspirate_spi_shutdown, NULL)) … … 193 237 for (i = 0; i < 19; i++) { 194 238 /* Enter raw bitbang mode */ 195 b uf[0] = 0x00;239 bp_commbuf[0] = 0x00; 196 240 /* Send the command, don't read the response. */ 197 ret = buspirate_sendrecv(b uf, 1, 0);241 ret = buspirate_sendrecv(bp_commbuf, 1, 0); 198 242 if (ret) 199 243 return ret; … … 216 260 } 217 261 /* Enter raw bitbang mode */ 218 b uf[0] = 0x00;219 ret = buspirate_sendrecv(b uf, 1, 5);220 if (ret) 221 return ret; 222 if (memcmp(b uf, "BBIO", 4)) {262 bp_commbuf[0] = 0x00; 263 ret = buspirate_sendrecv(bp_commbuf, 1, 5); 264 if (ret) 265 return ret; 266 if (memcmp(bp_commbuf, "BBIO", 4)) { 223 267 msg_perr("Entering raw bitbang mode failed!\n"); 224 268 msg_pdbg("Got %02x%02x%02x%02x%02x\n", 225 buf[0], buf[1], buf[2], buf[3], buf[4]); 226 return 1; 227 } 228 msg_pdbg("Raw bitbang mode version %c\n", buf[4]); 229 if (buf[4] != '1') { 269 bp_commbuf[0], bp_commbuf[1], bp_commbuf[2], 270 bp_commbuf[3], bp_commbuf[4]); 271 return 1; 272 } 273 msg_pdbg("Raw bitbang mode version %c\n", bp_commbuf[4]); 274 if (bp_commbuf[4] != '1') { 230 275 msg_perr("Can't handle raw bitbang mode version %c!\n", 231 b uf[4]);276 bp_commbuf[4]); 232 277 return 1; 233 278 } 234 279 /* Enter raw SPI mode */ 235 b uf[0] = 0x01;236 ret = buspirate_sendrecv(b uf, 1, 4);237 if (ret) 238 return ret; 239 if (memcmp(b uf, "SPI", 3)) {280 bp_commbuf[0] = 0x01; 281 ret = buspirate_sendrecv(bp_commbuf, 1, 4); 282 if (ret) 283 return ret; 284 if (memcmp(bp_commbuf, "SPI", 3)) { 240 285 msg_perr("Entering raw SPI mode failed!\n"); 241 286 msg_pdbg("Got %02x%02x%02x%02x\n", 242 buf[0], buf[1], buf[2], buf[3]); 243 return 1; 244 } 245 msg_pdbg("Raw SPI mode version %c\n", buf[3]); 246 if (buf[3] != '1') { 287 bp_commbuf[0], bp_commbuf[1], bp_commbuf[2], 288 bp_commbuf[3]); 289 return 1; 290 } 291 msg_pdbg("Raw SPI mode version %c\n", bp_commbuf[3]); 292 if (bp_commbuf[3] != '1') { 247 293 msg_perr("Can't handle raw SPI mode version %c!\n", 248 b uf[3]);294 bp_commbuf[3]); 249 295 return 1; 250 296 } 251 297 252 298 /* Initial setup (SPI peripherals config): Enable power, CS high, AUX */ 253 b uf[0] = 0x40 | 0xb;254 ret = buspirate_sendrecv(b uf, 1, 1);255 if (ret) 256 return 1; 257 if (b uf[0] != 0x01) {299 bp_commbuf[0] = 0x40 | 0xb; 300 ret = buspirate_sendrecv(bp_commbuf, 1, 1); 301 if (ret) 302 return 1; 303 if (bp_commbuf[0] != 0x01) { 258 304 msg_perr("Protocol error while setting power/CS/AUX!\n"); 259 305 return 1; … … 261 307 262 308 /* Set SPI speed */ 263 b uf[0] = 0x60 | spispeed;264 ret = buspirate_sendrecv(b uf, 1, 1);265 if (ret) 266 return 1; 267 if (b uf[0] != 0x01) {309 bp_commbuf[0] = 0x60 | spispeed; 310 ret = buspirate_sendrecv(bp_commbuf, 1, 1); 311 if (ret) 312 return 1; 313 if (bp_commbuf[0] != 0x01) { 268 314 msg_perr("Protocol error while setting SPI speed!\n"); 269 315 return 1; … … 271 317 272 318 /* Set SPI config: output type, idle, clock edge, sample */ 273 b uf[0] = 0x80 | 0xa;274 ret = buspirate_sendrecv(b uf, 1, 1);275 if (ret) 276 return 1; 277 if (b uf[0] != 0x01) {319 bp_commbuf[0] = 0x80 | 0xa; 320 ret = buspirate_sendrecv(bp_commbuf, 1, 1); 321 if (ret) 322 return 1; 323 if (bp_commbuf[0] != 0x01) { 278 324 msg_perr("Protocol error while setting SPI config!\n"); 279 325 return 1; … … 281 327 282 328 /* De-assert CS# */ 283 b uf[0] = 0x03;284 ret = buspirate_sendrecv(b uf, 1, 1);285 if (ret) 286 return 1; 287 if (b uf[0] != 0x01) {329 bp_commbuf[0] = 0x03; 330 ret = buspirate_sendrecv(bp_commbuf, 1, 1); 331 if (ret) 332 return 1; 333 if (bp_commbuf[0] != 0x01) { 288 334 msg_perr("Protocol error while raising CS#!\n"); 289 335 return 1; … … 301 347 unsigned char *readarr) 302 348 { 303 static unsigned char *buf = NULL;304 349 unsigned int i = 0; 305 350 int ret = 0; … … 309 354 310 355 /* 3 bytes extra for CS#, len, CS#. */ 311 buf = realloc(buf, writecnt + readcnt + 3); 312 if (!buf) { 313 msg_perr("Out of memory!\n"); 314 exit(1); // -1 315 } 356 if (buspirate_commbuf_grow(writecnt + readcnt + 3)) 357 return ERROR_OOM; 316 358 317 359 /* Assert CS# */ 318 b uf[i++] = 0x02;319 320 b uf[i++] = 0x10 | (writecnt + readcnt - 1);321 memcpy(b uf + i, writearr, writecnt);360 bp_commbuf[i++] = 0x02; 361 362 bp_commbuf[i++] = 0x10 | (writecnt + readcnt - 1); 363 memcpy(bp_commbuf + i, writearr, writecnt); 322 364 i += writecnt; 323 memset(b uf + i, 0, readcnt);365 memset(bp_commbuf + i, 0, readcnt); 324 366 325 367 i += readcnt; 326 368 /* De-assert CS# */ 327 b uf[i++] = 0x03;328 329 ret = buspirate_sendrecv(b uf, i, i);369 bp_commbuf[i++] = 0x03; 370 371 ret = buspirate_sendrecv(bp_commbuf, i, i); 330 372 331 373 if (ret) { … … 334 376 } 335 377 336 if (b uf[0] != 0x01) {378 if (bp_commbuf[0] != 0x01) { 337 379 msg_perr("Protocol error while lowering CS#!\n"); 338 380 return SPI_GENERIC_ERROR; 339 381 } 340 382 341 if (b uf[1] != 0x01) {383 if (bp_commbuf[1] != 0x01) { 342 384 msg_perr("Protocol error while reading/writing SPI!\n"); 343 385 return SPI_GENERIC_ERROR; 344 386 } 345 387 346 if (b uf[i - 1] != 0x01) {388 if (bp_commbuf[i - 1] != 0x01) { 347 389 msg_perr("Protocol error while raising CS#!\n"); 348 390 return SPI_GENERIC_ERROR; … … 350 392 351 393 /* Skip CS#, length, writearr. */ 352 memcpy(readarr, b uf + 2 + writecnt, readcnt);394 memcpy(readarr, bp_commbuf + 2 + writecnt, readcnt); 353 395 354 396 return ret; -
trunk/flash.h
r1540 r1541 37 37 38 38 /* Error codes */ 39 #define ERROR_OOM -100 39 40 #define TIMEOUT_ERROR -101 40 41
Note: See TracChangeset
for help on using the changeset viewer.
