From: Michel Pollet Date: Sun, 14 Jun 2015 10:50:00 +0000 (+0100) Subject: simduino: Simplified, made compatible with m2560 X-Git-Tag: v1.6~64 X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=f6363b60812be10c6bf9fc9793dfee636a7d223b;p=sx%2Fsimavr.git simduino: Simplified, made compatible with m2560 Allow testing on atmega256 bootloader too. Signed-off-by: Michel Pollet --- diff --git a/examples/board_simduino/Makefile b/examples/board_simduino/Makefile index 2332dcb..b1e970f 100644 --- a/examples/board_simduino/Makefile +++ b/examples/board_simduino/Makefile @@ -1,4 +1,4 @@ -# +# # Copyright 2008, 2009 Michel Pollet # # This file is part of simavr. @@ -39,7 +39,6 @@ include ${simavr}/Makefile.common board = ${OBJ}/${target}.elf -${board} : ${OBJ}/button.o ${board} : ${OBJ}/uart_pty.o ${board} : ${OBJ}/${target}.o diff --git a/examples/board_simduino/simduino.c b/examples/board_simduino/simduino.c index 14a0045..007b383 100644 --- a/examples/board_simduino/simduino.c +++ b/examples/board_simduino/simduino.c @@ -42,108 +42,9 @@ #include "uart_pty.h" #include "sim_vcd_file.h" -#include "button.h" - -button_t button; uart_pty_t uart_pty; -int do_button_press = 0; avr_t * avr = NULL; avr_vcd_t vcd_file; -uint8_t pin_state = 0; // current port B - -float pixsize = 64; -int window; - -/* - * called when the AVR change any of the pins on port B - * so lets update our buffer - */ -void pin_changed_hook(struct avr_irq_t * irq, uint32_t value, void * param) -{ -// pin_state = (pin_state & ~(1 << irq->irq)) | (value << irq->irq); -} - -void displayCB(void) /* function called whenever redisplay needed */ -{ - // OpenGL rendering goes here... - glClear(GL_COLOR_BUFFER_BIT); - - // Set up modelview matrix - glMatrixMode(GL_MODELVIEW); // Select modelview matrix - glLoadIdentity(); // Start with an identity matrix - - //float grid = pixsize; - //float size = grid * 0.8; - glBegin(GL_QUADS); - glColor3f(1,0,0); - -#if 0 - for (int di = 0; di < 8; di++) { - char on = (pin_state & (1 << di)) != 0; - if (on) { - float x = (di) * grid; - float y = 0; //(si * grid * 8) + (di * grid); - glVertex2f(x + size, y + size); - glVertex2f(x, y + size); - glVertex2f(x, y); - glVertex2f(x + size, y); - } - } -#endif - glEnd(); - glutSwapBuffers(); - //glFlush(); /* Complete any pending operations */ -} - -void keyCB(unsigned char key, int x, int y) /* called on key press */ -{ - if (key == 'q') - exit(0); - //static uint8_t buf[64]; - switch (key) { - case 'q': - case 0x1f: // escape - exit(0); - break; - case ' ': - do_button_press++; // pass the message to the AVR thread - break; - case 'r': - printf("Starting VCD trace\n"); - avr_vcd_start(&vcd_file); - break; - case 's': - printf("Stopping VCD trace\n"); - avr_vcd_stop(&vcd_file); - break; - } -} - -// gl timer. if the pin have changed states, refresh display -void timerCB(int i) -{ - //static uint8_t oldstate = 0xff; - // restart timer - glutTimerFunc(1000/64, timerCB, 0); -#if 0 - if (oldstate != pin_state) { - oldstate = pin_state; - glutPostRedisplay(); - } -#endif -} - -static void * avr_run_thread(void * oaram) -{ -// int b_press = do_button_press; - - while (1) { - int state = avr_run(avr); - if ( state == cpu_Done || state == cpu_Crashed) - break; - } - return NULL; -} struct avr_flash { char avr_flash_path[1024]; @@ -155,8 +56,11 @@ struct avr_flash { void avr_special_init( avr_t * avr, void * data) { struct avr_flash *flash_data = (struct avr_flash *)data; + + printf("%s\n", __func__); // open the file - flash_data->avr_flash_fd = open(flash_data->avr_flash_path, O_RDWR|O_CREAT, 0644); + flash_data->avr_flash_fd = open(flash_data->avr_flash_path, + O_RDWR|O_CREAT, 0644); if (flash_data->avr_flash_fd < 0) { perror(flash_data->avr_flash_path); exit(1); @@ -177,7 +81,7 @@ void avr_special_deinit( avr_t* avr, void * data) { struct avr_flash *flash_data = (struct avr_flash *)data; - puts(__func__); + printf("%s\n", __func__); lseek(flash_data->avr_flash_fd, SEEK_SET, 0); ssize_t r = write(flash_data->avr_flash_fd, avr->flash, avr->flashend + 1); if (r != avr->flashend + 1) { @@ -190,81 +94,75 @@ void avr_special_deinit( avr_t* avr, void * data) int main(int argc, char *argv[]) { - //elf_firmware_t f; - //const char * pwd = dirname(argv[0]); 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; + + 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 { + fprintf(stderr, "%s: invalid argument %s\n", argv[0], argv[i]); + exit(1); + } + } - avr = avr_make_mcu_by_name("atmega328p"); + avr = avr_make_mcu_by_name(mmcu); if (!avr) { fprintf(stderr, "%s: Error creating the AVR core\n", argv[0]); exit(1); } -// snprintf(avr_flash_path, sizeof(avr_flash_path), "%s/%s", pwd, "simduino_flash.bin"); - strcpy(flash_data.avr_flash_path, "simduino_flash.bin"); + + 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->special_init = avr_special_init; - avr->special_deinit = avr_special_deinit; - avr->special_data = &flash_data; - //avr->reset = NULL; + avr->custom.init = avr_special_init; + avr->custom.deinit = avr_special_deinit; + avr->custom.data = &flash_data; avr_init(avr); - avr->frequency = 16000000; + avr->frequency = freq; - // this trick creates a file that contains /and keep/ the flash - // in the same state as it was before. This allow the bootloader - // app to be kept, and re-run if the bootloader doesn't get a - // new one - { - char path[1024]; - uint32_t base, size; -// snprintf(path, sizeof(path), "%s/%s", pwd, "ATmegaBOOT_168_atmega328.ihex"); - strcpy(path, "ATmegaBOOT_168_atmega328.ihex"); - uint8_t * boot = read_ihex_file(path, &size, &base); - if (!boot) { - fprintf(stderr, "%s: Unable to load %s\n", argv[0], path); - exit(1); - } - printf("Booloader %04x: %d\n", base, size); - memcpy(avr->flash + base, boot, size); - free(boot); - avr->pc = base; - avr->codeend = avr->flashend; - } - //avr->trace = 1; + 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 (0) { - //avr->state = cpu_Stopped; + if (debug) { + avr->state = cpu_Stopped; avr_gdb_init(avr); } uart_pty_init(avr, &uart_pty); uart_pty_connect(&uart_pty, '0'); - /* - * OpenGL init, can be ignored - */ - glutInit(&argc, argv); /* initialize GLUT system */ - - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); - glutInitWindowSize(8 * pixsize, 1 * pixsize); /* width=400pixels height=500pixels */ - window = glutCreateWindow("Glut"); /* create window */ - - // Set up projection matrix - glMatrixMode(GL_PROJECTION); // Select projection matrix - glLoadIdentity(); // Start with an identity matrix - glOrtho(0, 8 * pixsize, 0, 1 * pixsize, 0, 10); - glScalef(1,-1,1); - glTranslatef(0, -1 * pixsize, 0); - - glutDisplayFunc(displayCB); /* set window's display callback */ - glutKeyboardFunc(keyCB); /* set window's key callback */ - glutTimerFunc(1000 / 24, timerCB, 0); - - // the AVR run on it's own thread. it even allows for debugging! - pthread_t run; - pthread_create(&run, NULL, avr_run_thread, NULL); + while (1) { + int state = avr_run(avr); + if ( state == cpu_Done || state == cpu_Crashed) + break; + } - glutMainLoop(); }