int cmd_fpga(FILE * f, int argc, char ** argv) { uint8_t * rbf = (uint8_t *)0x08060000; uint32_t flash_offs = (uint8_t *)rbf - STM32_FLASH_MEM; bool erase = false; bool load = false; bool cfg = false; if (argc > 1) { int i = 1; do { if ((strcmp(argv[i], "erase") == 0) || (strcmp(argv[i], "e") == 0)) { erase = true; } else if ((strcmp(argv[i], "load") == 0) || (strcmp(argv[i], "l") == 0)) { load = true; } else if ((strcmp(argv[i], "config") == 0) || (strcmp(argv[i], "cfg") == 0) || (strcmp(argv[i], "c") == 0)) { cfg = true; } else { fprintf(f, "Invalid argument: %s\n", argv[i]); return -1; } } while (++i < argc); } else { fprintf(f, "FPG sector: 0x%08x\n", (uint32_t)rbf); show_hex8(f, (uint32_t)rbf, rbf, 1024); return 0; } debugger_except("FPGA update, reboot required!"); if (erase) { fprintf(f, "Erasing sector: 0x%08x...\n", (uint32_t)rbf); if (stm32_flash_erase(flash_offs, 0x20000) < 0) { fprintf(f, "stm32f_flash_erase() failed!\n"); return -1; } }; if (load) { fprintf(f, "Loading FPGA .rbf file at 0x%08x...\n", (uint32_t)rbf); if (flash_xmodem_recv(f, flash_offs) < 0) { fprintf(f, "fpga_xmodem_recv() failed!\n"); return -1; } }; if (cfg) { fprintf(f, "Configuring FPGA...\n"); if (jtag3ctrl_init(rbf, 38177) < 0) { fprintf(f, "jtag3ctrl_init() failed!\n"); return -1; } }; return 0; }
/* Receive a file and write it into the flash using the YMODEM preotocol */ int dmon_ymodem_flash(struct dmon_comm * comm, uint32_t addr, unsigned int size) { /* FIXME: generalize the application load by removing the low level flash calls dependency */ #ifdef STM32_FLASH_MEM /* The YMODEM state machine is allocated at the top of the stack, make sure there is no app running before calling the dmon_ymodem_flash()! */ struct ymodem_rcv * ry = ((struct ymodem_rcv *)&_stack) - 1; uint32_t base = (uint32_t)STM32_FLASH_MEM; uint32_t offs = addr - base; int ret; DCC_LOG2(LOG_INFO, "sp=%p ry=%p", cm3_sp_get(), ry); DCC_LOG2(LOG_INFO, "offs=0x%08x size=%d", offs, size); dmon_ymodem_rcv_init(ry, true, false); ry->fsize = size; DCC_LOG(LOG_INFO, "Starting..."); while ((ret = dmon_ymodem_rcv_pkt(comm, ry)) >= 0) { if ((ret == 0) && (ry->xmodem) ) break; int len = ret; if (ry->pktno == 1) { char * cp; int fsize; cp = (char *)ry->pkt.data; DCC_LOGSTR(LOG_INFO, "fname='%s'", cp); while (*cp != '\0') cp++; /* skip null */ cp++; fsize = dec2int(cp); if (fsize == 0) { ret = 0; break; } DCC_LOG1(LOG_INFO, "fsize='%d'", fsize); ry->fsize = fsize; DCC_LOG(LOG_INFO, "YMODEM first packet..."); } else { if (ry->pktno == 2) { stm32_flash_erase(offs, ry->fsize); } stm32_flash_write(offs, ry->pkt.data, len); offs += len; } } return ret; #else return -1; #endif }