#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];
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);
{
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) {
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();
}