avr_t * m128rfa1_create(struct drumfish_cfg *config) { avr_t *avr; avr = avr_make_mcu_by_name("atmega128rfa1"); if (!avr) { fprintf(stderr, "Failed to create AVR core 'atmega128rfa1'\n"); return NULL; } /* Setup any additional init/deinit routines */ avr->special_init = m128rfa1_init; avr->special_deinit = m128rfa1_deinit; avr->special_data = config; /* Initialize our AVR */ avr_init(avr); /* Our chips always run at 16mhz */ avr->frequency = 16000000; /* Set our fuses */ avr->fuse[0] = 0xE6; // low avr->fuse[1] = 0x1C; // high avr->fuse[2] = 0xFE; // extended //avr->lockbits = 0xEF; // lock bits /* Check to see if we initialized our flash */ if (!avr->flash) { fprintf(stderr, "Failed to initialize flash correctly.\n"); return NULL; } /* Based on fuse values, we'll always want to boot from the bootloader * which will always start at 0x1f800. */ avr->pc = PC_START; avr->codeend = avr->flashend; /* Setup our UARTs */ if (uart_pty_init(avr, &uart_pty[0], '0')) { fprintf(stderr, "Unable to start UART0.\n"); return NULL; } uart_pty_connect(&uart_pty[0]); if (uart_pty_init(avr, &uart_pty[1], '1')) { fprintf(stderr, "Unable to start UART1.\n"); return NULL; } uart_pty_connect(&uart_pty[1]); return avr; }
int main(int argc, char *argv[]) { struct avr_flash flash_data; char boot_path[1024] = "ATmegaBOOT_168_atmega328.ihex"; uint32_t boot_base, boot_size; char * mmcu = "atmega328p"; uint32_t freq = 16000000; int debug = 0; int verbose = 0; /* * To allow other programs to know that the model is * online and ready for programming, we create a file * called emu_online.txt * * At the beginning we clean up the file and then write * to it later on once the emulator is running. */ char * emu_online_file = "emu_online.txt"; int emu_online_flag = 0; for (int i = 1; i < argc; i++) { if (!strcmp(argv[i] + strlen(argv[i]) - 4, ".hex")) strncpy(boot_path, argv[i], sizeof(boot_path)); else if (!strcmp(argv[i], "-d")) debug++; else if (!strcmp(argv[i], "-v")) verbose++; else if (strstr(argv[i], ".ihex") != NULL) strcpy( boot_path, argv[1] ); else { fprintf(stderr, "%s: invalid argument %s\n", argv[0], argv[i]); exit(1); } } if( access(emu_online_file, F_OK) != -1 ){ remove(emu_online_file); } avr = avr_make_mcu_by_name(mmcu); if (!avr) { fprintf(stderr, "%s: Error creating the AVR core\n", argv[0]); exit(1); } uint8_t * boot = read_ihex_file(boot_path, &boot_size, &boot_base); if (!boot) { fprintf(stderr, "%s: Unable to load %s\n", argv[0], boot_path); exit(1); } if (boot_base > 32*1024*1024) { mmcu = "atmega2560"; freq = 20000000; } printf("%s booloader 0x%05x: %d bytes\n", mmcu, boot_base, boot_size); snprintf(flash_data.avr_flash_path, sizeof(flash_data.avr_flash_path), "simduino_%s_flash.bin", mmcu); flash_data.avr_flash_fd = 0; // register our own functions avr->custom.init = avr_special_init; avr->custom.deinit = avr_special_deinit; avr->custom.data = &flash_data; avr_init(avr); avr->frequency = freq; memcpy(avr->flash + boot_base, boot, boot_size); free(boot); avr->pc = boot_base; /* end of flash, remember we are writing /code/ */ avr->codeend = avr->flashend; avr->log = 1 + verbose; // even if not setup at startup, activate gdb if crashing avr->gdb_port = 1234; if (debug) { avr->state = cpu_Stopped; avr_gdb_init(avr); } uart_pty_init(avr, &uart_pty); uart_pty_connect(&uart_pty, '0'); while (1) { int state = avr_run(avr); if ( state == cpu_Done || state == cpu_Crashed) break; if( emu_online_flag == 0){ fopen(emu_online_file, "w+"); emu_online_flag = 1; } } }