Example #1
0
struct mpu6050_t* mpu6050_alloc(struct avr_t * avr, uint8_t addr, struct sc18is600_t* sc18)
{
	struct mpu6050_t* mpu;

    // allocate and reset the object
	mpu = malloc(sizeof(mpu6050_t));
	memset(mpu, 0, sizeof(mpu6050_t));

	mpu->avr = avr;
	mpu->self_addr = addr;

    // create the irqs
	mpu->irq = avr_alloc_irq(&avr->irq_pool, MPU_IRQ_IN, MPU_IRQ_COUNT, mpu_irq_names);
	avr_irq_register_notify(mpu->irq + MPU_IRQ_IN, mpu6050_i2c_in_hook, mpu);

	if (sc18) {
		// connect to the TWI/i2c master of the SC18IS600
		avr_irq_t * sc18_irq = sc18is600_i2c_irq_get(sc18);
		avr_connect_irq(sc18_irq + SC18_I2C_IRQ_OUT, mpu->irq + MPU_IRQ_IN);
		avr_connect_irq(mpu->irq + MPU_IRQ_OUT, sc18_irq + SC18_I2C_IRQ_IN);
	}
	else {
		// "connect" the IRQs of the MPU to the TWI/i2c master of the AVR
		uint32_t i2c_irq_base = AVR_IOCTL_TWI_GETIRQ(0);
		avr_connect_irq(mpu->irq + MPU_IRQ_OUT, avr_io_getirq(avr, i2c_irq_base, TWI_IRQ_INPUT));
		avr_connect_irq(avr_io_getirq(avr, i2c_irq_base, TWI_IRQ_OUTPUT), mpu->irq + MPU_IRQ_IN);
	}

	return mpu;
}
Example #2
0
static void
_avr_io_command_write (struct avr_t *avr, avr_io_addr_t addr, uint8_t v, void *param)
{
  AVR_LOG (avr, LOG_TRACE, "%s %02x\n", __FUNCTION__, v);
  switch (v)
    {
    case SIMAVR_CMD_VCD_START_TRACE:
      if (avr->vcd)
        avr_vcd_start (avr->vcd);
      break;
      
    case SIMAVR_CMD_VCD_STOP_TRACE:
      if (avr->vcd)
        avr_vcd_stop (avr->vcd);
      break;
      
    case SIMAVR_CMD_UART_LOOPBACK:
      {
        avr_irq_t *src = avr_io_getirq (avr, AVR_IOCTL_UART_GETIRQ ('0'), UART_IRQ_OUTPUT);
        avr_irq_t *dst = avr_io_getirq (avr, AVR_IOCTL_UART_GETIRQ ('0'), UART_IRQ_INPUT);
        if (src && dst)
          {
            AVR_LOG (avr, LOG_TRACE, "%s activating uart local echo IRQ src %p dst %p\n",
                     __FUNCTION__, src, dst);
            avr_connect_irq (src, dst);
          }
      }
      break;
    }
}
Example #3
0
void
thermistor_init (struct avr_t *avr,
                 thermistor_p p,
                 int adc_mux_number,
                 short *table, int table_entries, int oversampling, float start_temp)
{
  p->avr = avr;
  p->irq = avr_alloc_irq (&avr->irq_pool, 0, IRQ_TERM_COUNT, irq_names);
  avr_irq_register_notify (p->irq + IRQ_TERM_ADC_TRIGGER_IN, thermistor_in_hook, p);
  avr_irq_register_notify (p->irq + IRQ_TERM_TEMP_VALUE_IN, thermistor_value_in_hook, p);

  p->oversampling = oversampling;
  p->table = table;
  p->table_entries = table_entries;
  p->adc_mux_number = adc_mux_number;
  p->current = start_temp;

  avr_irq_t *src = avr_io_getirq (p->avr, AVR_IOCTL_ADC_GETIRQ, ADC_IRQ_OUT_TRIGGER);
  avr_irq_t *dst = avr_io_getirq (p->avr, AVR_IOCTL_ADC_GETIRQ, adc_mux_number);
  if (src && dst)
    {
      avr_connect_irq (src, p->irq + IRQ_TERM_ADC_TRIGGER_IN);
      avr_connect_irq (p->irq + IRQ_TERM_ADC_VALUE_OUT, dst);
    }

  printf ("%s on ADC %d start %.2f\n", __func__, adc_mux_number, p->current);
}
/**
 * Lowers the card presence signal.
 * This causes the clock to start, which initiates
 * the clock-and-data transfer.
 *
 * @param struct avr_t *avr The AVR this card reader is interfacing with.
 * @param avr_cycle_count_t when The number of cycles since this function call was registered.
 * @param void *param The card_reader struct to raise the card presence signal on.
 * @return avr_cycle_count_t The value of the card presence pin.
 */
avr_cycle_count_t card_reader_lower_presence_signal(struct avr_t *avr, avr_cycle_count_t when, void *param) {
	card_reader_t *self = (card_reader_t *) param;

	avr_raise_irq(avr_io_getirq(self->avr, AVR_IOCTL_IOPORT_GETIRQ('D'), 2), 0);
	avr_raise_irq(avr_io_getirq(self->avr, AVR_IOCTL_IOPORT_GETIRQ('D'), 3), 0);
	avr_cycle_timer_register(avr, self->clock->signal_time, card_reader_clock_tick, self->clock);

	return 0;
}
Example #5
0
void LedButtonsLogic::wireHook(avr_t *avr)
{
    this->avr = avr;

    /* Every port has 8 pins. */
    const int count = strlen(ports) * 8;

    /* Construct the port names. */
    int nameLength = sizeof("PORTA0");
    const char *names[count];
    char _names[count * nameLength];
    char *s = _names;
    for (int i = 0; i < count; i++) {
        int port = i / 8;
        int pin = i % 8;

        snprintf(s, nameLength, "PORT%c%d", ports[port], pin);
        names[i] = s;
        s += nameLength;
    }

    irq = avr_alloc_irq(&avr->irq_pool, 0, count, names);

    for (int i = 0; i < count; i++) {
        int port = i / 8;
        int pin = i % 8;

        avr_connect_irq(irq + i, avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ(ports[port]), pin));

        /* We need this helper struct to keep track of 1) which port the IRQ came from,
         * and 2) which class instance to notify. */
        CallbackData *d = new CallbackData;
        d->instance = this;
        d->port = 'A' + port;
        callbackData.append(d);

        avr_irq_register_notify(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ(ports[port]), pin),
                                LedButtonsLogic::pinChanged, d);
    }

    avr_vcd_init(avr, "ledbuttons.vcd", &vcdFile, 100000);
    for (int i = 0; i < 8; i++) {
        char name[6];
        snprintf(name, 6, "PORT%c", ports[i]);
        avr_vcd_add_signal(&vcdFile,
                avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ(ports[i]), IOPORT_IRQ_PIN_ALL),
                           8 /* bits */, name);
    }
}
/**
 * Raises the card presence signal.
 * The clock signal is expected to already have stopped,
 * and the data buffer for the DATA pin will be reset.
 *
 * @param struct avr_t *avr The AVR this card reader is interfacing with.
 * @param avr_cycle_count_t when The number of cycles since this function call was registered.
 * @param void *param The card_reader struct to raise the card presence signal on.
 * @return avr_cycle_count_t The value of the card presence pin.
 */
avr_cycle_count_t card_reader_raise_presence_signal(struct avr_t *avr, avr_cycle_count_t when, void *param) {
	card_reader_t *self = (card_reader_t *) param;

	avr_raise_irq(avr_io_getirq(self->avr, AVR_IOCTL_IOPORT_GETIRQ('D'), 2), 1);
	self->swipe_buffer_pos = 0;

	return 0;
}
Example #7
0
void
vhci_usb_connect(
		struct vhci_usb_t * p,
		char uart)
{
	avr_irq_t * t = avr_io_getirq(p->avr, AVR_IOCTL_USB_GETIRQ(),
	        USB_IRQ_ATTACH);
	avr_irq_register_notify(t, vhci_usb_attach_hook, p);
}
Example #8
0
void LcdLogic::unwireHook()
{
    for (int i = 0; i < 4; i++) {
        avr_irq_t * iavr = avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 4 + i);
        avr_irq_t * ilcd = hd44780.irq + IRQ_HD44780_D4 + i;

        avr_unconnect_irq(iavr, ilcd);
        avr_unconnect_irq(ilcd, iavr);
    }

    avr_unconnect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 2),
                    hd44780.irq + IRQ_HD44780_RS);
    avr_unconnect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 3),
                    hd44780.irq + IRQ_HD44780_E);

    avr_free_irq(hd44780.irq, IRQ_HD44780_COUNT);

    avr_vcd_close(&vcdFile);
}
Example #9
0
void uart_udp_connect(uart_udp_t * p, char uart)
{
	// disable the stdio dump, as we are sending binary there
	uint32_t f = 0;
	avr_ioctl(p->avr, AVR_IOCTL_UART_GET_FLAGS(uart), &f);
	f &= ~AVR_UART_FLAG_STDIO;
	avr_ioctl(p->avr, AVR_IOCTL_UART_SET_FLAGS(uart), &f);

	avr_irq_t * src = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUTPUT);
	avr_irq_t * dst = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_INPUT);
	avr_irq_t * xon = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUT_XON);
	avr_irq_t * xoff = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUT_XOFF);
	if (src && dst) {
		avr_connect_irq(src, p->irq + IRQ_UART_UDP_BYTE_IN);
		avr_connect_irq(p->irq + IRQ_UART_UDP_BYTE_OUT, dst);
	}
	if (xon)
		avr_irq_register_notify(xon, uart_udp_xon_hook, p);
	if (xoff)
		avr_irq_register_notify(xoff, uart_udp_xoff_hook, p);
}
Example #10
0
void LcdLogic::wireHook(avr_t *avr)
{
    this->avr = avr;

    hd44780_init(avr, &hd44780, WIDTH, HEIGHT, this, LcdLogic::displayChanged);

    /* Connect data lines to Port C, 4-7 (bidirectional). */
    for (int i = 0; i < 4; i++) {
        avr_irq_t * iavr = avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 4 + i);
        avr_irq_t * ilcd = hd44780.irq + IRQ_HD44780_D4 + i;
        // AVR -> LCD
        avr_connect_irq(iavr, ilcd);
        // LCD -> AVR
        avr_connect_irq(ilcd, iavr);
    }

    avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 2),
                    hd44780.irq + IRQ_HD44780_RS);
    avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 3),
                    hd44780.irq + IRQ_HD44780_E);
    /* RW is set to GND. */

    avr_vcd_init(avr, "lcd.vcd", &vcdFile, 100000);
    avr_vcd_add_signal(&vcdFile,
            avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), IOPORT_IRQ_PIN_ALL),
            4 /* bits */, "D4-D7");
    avr_vcd_add_signal(&vcdFile,
            avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 2),
            1 /* bits */, "RS");
    avr_vcd_add_signal(&vcdFile,
            avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 3),
            1 /* bits */, "E");
}
Example #11
0
struct avr_irq_t *
get_ardu_irq(struct avr_t * avr, int ardupin, ardupin_t pins[])
{
  if (pins[ardupin].ardupin != ardupin) {
    printf("%s pin %d isn't correct in table\n", __func__, ardupin);
    return NULL;
  }
  struct avr_irq_t * irq = avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ(pins[ardupin].port), pins[ardupin].pin);
  if (!irq) {
    printf("%s pin %d PORT%C%d not found\n", __func__, ardupin, pins[ardupin].port, pins[ardupin].pin);
    return NULL;
  }
  return irq;
}
Example #12
0
static void avr_extint_reset(avr_io_t * port)
{
	avr_extint_t * p = (avr_extint_t *)port;

	for (int i = 0; i < EXTINT_COUNT; i++) {
		avr_irq_register_notify(p->io.irq + i, avr_extint_irq_notify, p);

		if (p->eint[i].port_ioctl) {
			avr_irq_t * irq = avr_io_getirq(p->io.avr,
					p->eint[i].port_ioctl, p->eint[i].port_pin);

			avr_connect_irq(irq, p->io.irq + i);
		}
	}
}
Example #13
0
void LedButtonsLogic::unwireHook()
{
    const int count = strlen(ports) * 8;

    for (int i = 0; i < count; i++) {
        int port = i / 8;
        int pin = i % 8;

        avr_irq_unregister_notify(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ(ports[port]), pin),
                                  LedButtonsLogic::pinChanged, callbackData[i]);
        delete callbackData[i];
    }
    callbackData.clear();
    avr_free_irq(irq, count);

    avr_vcd_close(&vcdFile);

    irq = NULL;
}
Example #14
0
void tests_assert_uart_receive_avr(avr_t *avr,
			       unsigned long run_usec,
			       const char *expected,
			       char uart) {
	struct output_buffer buf;
	init_output_buffer(&buf);

	avr_irq_register_notify(avr_io_getirq(avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUTPUT),
				buf_output_cb, &buf);
	enum tests_finish_reason reason = tests_run_test(avr, run_usec);
	if (reason == LJR_CYCLE_TIMER) {
		if (strcmp(buf.str, expected) == 0) {
			_fail(NULL, 0, "Simulation did not finish within %lu simulated usec. "
			     "UART output is correct and complete.", run_usec);
		}
		_fail(NULL, 0, "Simulation did not finish within %lu simulated usec. "
		     "UART output so far: \"%s\"", run_usec, buf.str);
	}
	if (strcmp(buf.str, expected) != 0)
		_fail(NULL, 0, "UART outputs differ: expected \"%s\", got \"%s\"", expected, buf.str);
}
Example #15
0
int main(int argc, char *argv[])
{
	elf_firmware_t f;
	//const char * fname =  "atmega48_ledramp.axf";
	const char * fname =  argv[1];
	char path[256];

//	sprintf(path, "%s/%s", dirname(argv[0]), fname);
//	printf("Firmware pathname is %s\n", path);
	elf_read_firmware(fname, &f);

	printf("firmware %s f=%d mmcu=%s\n", fname, (int)f.frequency, f.mmcu);

	avr = avr_make_mcu_by_name(f.mmcu);
	if (!avr) {
		fprintf(stderr, "%s: AVR '%s' now known\n", argv[0], f.mmcu);
		exit(1);
	}
	avr_init(avr);
	avr_load_firmware(avr, &f);

	// initialize our 'peripheral'
	button_init(avr, &button, "button");
	// "connect" the output irw of the button to the port pin of the AVR
	avr_connect_irq(
		button.irq + IRQ_BUTTON_OUT,
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 0));

	// connect all the pins on port B to our callback
	for (int i = 0; i < 8; i++)
		avr_irq_register_notify(
			avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), i),
			pin_changed_hook, 
			NULL);

	// even if not setup at startup, activate gdb if crashing
	avr->gdb_port = 1234;
	if (0) {
		//avr->state = cpu_Stopped;
		avr_gdb_init(avr);
	}

	/*
	 *	VCD file initialization
	 *	
	 *	This will allow you to create a "wave" file and display it in gtkwave
	 *	Pressing "r" and "s" during the demo will start and stop recording
	 *	the pin changes
	 */
	avr_vcd_init(avr, "gtkwave_output.vcd", &vcd_file, 100000 /* usec */);
	avr_vcd_add_signal(&vcd_file, 
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), IOPORT_IRQ_PIN_ALL), 8 /* bits */ ,
		"portb" );
	avr_vcd_add_signal(&vcd_file, avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), IOPORT_IRQ_PIN0), 1, "portc");
	avr_vcd_add_signal(&vcd_file, 
		button.irq + IRQ_BUTTON_OUT, 1 /* bits */ ,
		"button" );

	// 'raise' it, it's a "pullup"
	avr_raise_irq(button.irq + IRQ_BUTTON_OUT, 1);

	printf( "Demo launching: 'LED' bar is PORTB, updated every 1/64s by the AVR\n"
			"   firmware using a timer. If you press 'space' this presses a virtual\n"
			"   'button' that is hooked to the virtual PORTC pin 0 and will\n"
			"   trigger a 'pin change interrupt' in the AVR core, and will 'invert'\n"
			"   the display.\n"
			"   Press 'q' to quit\n\n"
			"   Press 'r' to start recording a 'wave' file\n"
			"   Press 's' to stop recording\n"
			);

	/*
	 * 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);

	glutMainLoop();
}
Example #16
0
int main(int argc, char *argv[])
{
	elf_firmware_t f = {{0}};
	long f_cpu = 0;
	int trace = 0;
	int gdb = 0;
	int log = 1;
	char name[16] = "";
	uint32_t loadBase = AVR_SEGMENT_OFFSET_FLASH;
	int trace_vectors[8] = {0};
	int trace_vectors_count = 0;

	if (argc == 1)
		display_usage(basename(argv[0]));

	for (int pi = 1; pi < argc; pi++) {
		if (!strcmp(argv[pi], "-h") || !strcmp(argv[pi], "-help")) {
			display_usage(basename(argv[0]));
		} else if (!strcmp(argv[pi], "-m") || !strcmp(argv[pi], "-mcu")) {
			if (pi < argc-1)
				strcpy(name, argv[++pi]);
			else
				display_usage(basename(argv[0]));
		} else if (!strcmp(argv[pi], "-f") || !strcmp(argv[pi], "-freq")) {
			if (pi < argc-1)
				f_cpu = atoi(argv[++pi]);
			else
				display_usage(basename(argv[0]));
		} else if (!strcmp(argv[pi], "-t") || !strcmp(argv[pi], "-trace")) {
			trace++;
		} else if (!strcmp(argv[pi], "-ti")) {
			if (pi < argc-1)
				trace_vectors[trace_vectors_count++] = atoi(argv[++pi]);
		} else if (!strcmp(argv[pi], "-g") || !strcmp(argv[pi], "-gdb")) {
			gdb++;
		} else if (!strcmp(argv[pi], "-v")) {
			log++;
		} else if (!strcmp(argv[pi], "-ee")) {
			loadBase = AVR_SEGMENT_OFFSET_EEPROM;
		} else if (!strcmp(argv[pi], "-ff")) {
			loadBase = AVR_SEGMENT_OFFSET_FLASH;			
		} else if (argv[pi][0] != '-') {
			char * filename = argv[pi];
			char * suffix = strrchr(filename, '.');
			if (suffix && !strcasecmp(suffix, ".hex")) {
				if (!name[0] || !f_cpu) {
					fprintf(stderr, "%s: -mcu and -freq are mandatory to load .hex files\n", argv[0]);
					exit(1);
				}
				ihex_chunk_p chunk = NULL;
				int cnt = read_ihex_chunks(filename, &chunk);
				if (cnt <= 0) {
					fprintf(stderr, "%s: Unable to load IHEX file %s\n", 
						argv[0], argv[pi]);
					exit(1);
				}
				printf("Loaded %d section of ihex\n", cnt);
				for (int ci = 0; ci < cnt; ci++) {
					if (chunk[ci].baseaddr < (1*1024*1024)) {
						f.flash = chunk[ci].data;
						f.flashsize = chunk[ci].size;
						f.flashbase = chunk[ci].baseaddr;
						printf("Load HEX flash %08x, %d\n", f.flashbase, f.flashsize);
					} else if (chunk[ci].baseaddr >= AVR_SEGMENT_OFFSET_EEPROM ||
							chunk[ci].baseaddr + loadBase >= AVR_SEGMENT_OFFSET_EEPROM) {
						// eeprom!
						f.eeprom = chunk[ci].data;
						f.eesize = chunk[ci].size;
						printf("Load HEX eeprom %08x, %d\n", chunk[ci].baseaddr, f.eesize);
					}
				}
			} else {
				if (elf_read_firmware(filename, &f) == -1) {
					fprintf(stderr, "%s: Unable to load firmware from file %s\n",
							argv[0], filename);
					exit(1);
				}
			}
		}
	}

	if (strlen(name))
		strcpy(f.mmcu, name);
	if (f_cpu)
		f.frequency = f_cpu;

	avr = avr_make_mcu_by_name(f.mmcu);
	if (!avr) {
		fprintf(stderr, "%s: AVR '%s' not known\n", argv[0], f.mmcu);
		exit(1);
	}
	avr_init(avr);
	avr_load_firmware(avr, &f);
	if (f.flashbase) {
		printf("Attempted to load a bootloader at %04x\n", f.flashbase);
		avr->pc = f.flashbase;
	}
	avr->log = (log > LOG_TRACE ? LOG_TRACE : log);
	avr->trace = trace;
	for (int ti = 0; ti < trace_vectors_count; ti++) {
		for (int vi = 0; vi < avr->interrupts.vector_count; vi++)
			if (avr->interrupts.vector[vi]->vector == trace_vectors[ti])
				avr->interrupts.vector[vi]->trace = 1;
	}

	// even if not setup at startup, activate gdb if crashing
	avr->gdb_port = 1234;
	if (gdb) {
		avr->state = cpu_Stopped;
		avr_gdb_init(avr);
	}

	// ronaldv: Register hooks
	avr_irq_register_notify(
            avr_io_getirq(avr, AVR_IOCTL_ADC_GETIRQ, ADC_IRQ_OUT_TRIGGER),
            adc_update_hook,
            NULL);
	// ronaldv: end
	
	signal(SIGINT, sig_int);
	signal(SIGTERM, sig_int);
	int k=0; 
	for (;;) {
		int state = avr_run(avr);
		if ( state == cpu_Done || state == cpu_Crashed){
			printf("k=%d, state=%d\n", k, state);
			break;
			}
		k++;
	}
	
	avr_terminate(avr);
}
Example #17
0
int main(int argc, char *argv[])
{
	elf_firmware_t f;
	const char * fname =  "wordClock-erl";
	char path[256];

//	sprintf(path, "%s/%s", dirname(argv[0]), fname);
//	printf("Firmware pathname is %s\n", path);
	elf_read_firmware(fname, &f);

	strcpy( f.mmcu, "atmega168" ); // hack
	f.frequency = 16000000;
	printf("firmware %s f=%d mmcu=%s\n", fname, (int)f.frequency, f.mmcu);
	
	avr = avr_make_mcu_by_name(f.mmcu);
	if (!avr) {
		fprintf(stderr, "%s: AVR '%s' now known\n", argv[0], f.mmcu);
		exit(1);
	}
	avr_init(avr);
	avr_load_firmware(avr, &f);

	// initialize our 'peripheral'
	// button_init(avr, &button, "button");
	// "connect" the output irw of the button to the port pin of the AVR
	/*
	avr_connect_irq(
		button.irq + IRQ_BUTTON_OUT,
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 0));
	*/
	// connect all the pins on port B to our callback
#if 0
	for (int i = 0; i < 8; i++)
		avr_irq_register_notify(
			avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), i),
			pin_changed_hook, 
			NULL);
#endif
	// even if not setup at startup, activate gdb if crashing
	avr->gdb_port = 1234;
	if (0) {
		//avr->state = cpu_Stopped;
		avr_gdb_init(avr);
	}

	/*
	 *	VCD file initialization
	 *	
	 *	This will allow you to create a "wave" file and display it in gtkwave
	 *	Pressing "r" and "s" during the demo will start and stop recording
	 *	the pin changes
	 *     
	 *      Initially set to 100 000 usec = 100 ms. I think it is how often
	 *      to flush its' log.
	 */
	avr_vcd_init(avr, "gtkwave_output.vcd", &vcd_file, 100 /* usec */);

	/* want MOSI, SCLK, XLAT, BLANK */
	avr_vcd_add_signal( &vcd_file, 
			    avr_io_getirq(avr, AVR_IOCTL_SPI_GETIRQ(0), 
					  SPI_IRQ_OUTPUT), 
			    8, "MOSI" );

	avr_vcd_add_signal(&vcd_file, 
			   avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 1 ),
			   1, "XLAT" );
	avr_vcd_add_signal(&vcd_file, 
			   avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 2 ),
			   1, "BLANK" );
	avr_vcd_add_signal(&vcd_file, 
			   avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 5 ),
			   1, "SCLK" );
#if 0
	avr_vcd_add_signal(&vcd_file, 
		button.irq + IRQ_BUTTON_OUT, 1 /* bits */ ,
		"button" );

	// 'raise' it, it's a "pullup"
	avr_raise_irq(button.irq + IRQ_BUTTON_OUT, 1);
#endif
	avr_vcd_start( &vcd_file );
							       
	printf( "Demo launching. " );
#if 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);
#endif
	// the AVR run on it's own thread. it even allows for debugging!
	pthread_t run;
	pthread_create(&run, NULL, avr_run_thread, NULL);

	sleep( 60 ); // wait 5 seconds, then exit.

	avr_vcd_stop(&vcd_file);

	/*	glutMainLoop(); */
}
Example #18
0
// ronaldv: begin
static void adc_update_hook(struct avr_irq_t *irq, uint32_t value, void *param){
	//printf("Updating ADC with: %d\n", adc0_value);
	avr_irq_t * adc0_irq = avr_io_getirq(avr, AVR_IOCTL_ADC_GETIRQ, ADC_IRQ_ADC0);
	avr_raise_irq(adc0_irq, adc0_value);
	//adc0_value += V_BANDGAP/10;
}
Example #19
0
int main(int argc, char *argv[])
{
	int state;
	elf_firmware_t f;
	const char *fname = "../BasicMotorControl.elf";
	const char *mmcu = "atmega328p";

	if (elf_read_firmware(fname, &f) != 0)
	{
		exit(1);
	}

	f.frequency = 16000000;

	printf("firmware %s f=%d mmcu=%s\n", fname, (int)f.frequency, mmcu);

	avr = avr_make_mcu_by_name(mmcu);
	if (!avr)
	{
		fprintf(stderr, "%s: AVR '%s' not known\n", argv[0], mmcu);
		exit(1);
	}

	avr_init(avr);
	avr_load_firmware(avr, &f);

#if 0
	/* even if not setup at startup, activate gdb if crashing */
	avr->gdb_port = 1234;
	avr->state = cpu_Stopped;
	avr_gdb_init(avr);
#endif

	/* VCD file initialization */
	avr_vcd_init(avr, "wave.vcd", &vcd_file, 10000 /* usec */);
	avr_vcd_add_signal(&vcd_file, avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 0), 1, "B0" ); 
	avr_vcd_add_signal(&vcd_file, avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 1), 1, "B1" ); 
	avr_vcd_add_signal(&vcd_file, avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 2), 1, "B2" ); 
	avr_vcd_add_signal(&vcd_file, avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 3), 1, "B3" ); 
	avr_vcd_start(&vcd_file);

	/* IRQ callback hooks */
	avr_irq_register_notify( avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 0), pin_changed_hook, NULL); 
	avr_irq_register_notify( avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 1), pin_changed_hook, NULL); 
	avr_irq_register_notify( avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 2), pin_changed_hook, NULL); 
	avr_irq_register_notify( avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 3), pin_changed_hook, NULL); 

	/* show some info */
	show_ports(avr);

	/* install signal handlers */
	signal(SIGINT, sig_int);
	signal(SIGTERM, sig_int);

	/* main loop */
	printf("*** Entering main loop ***\n");
	while (1) 
	{
		state = avr_run(avr);
		if (state == cpu_Done || state == cpu_Crashed)
		{
			printf("CPU State %d\n", state);
			break;
		}
	}

	avr_vcd_stop(&vcd_file);
	avr_terminate(avr);

	return 0;
}
Example #20
0
File: main.c Project: 33d/gbsim
int main(int argc, char* argv[]) {
	int r = 0;

	char* elf_file = NULL;
	int gdb_port = 0;

	for (char** arg = &argv[1]; *arg != NULL; ++arg) {
		if (strcmp("-d", *arg) == 0)
			gdb_port = atoi(*(++arg));
		else
			elf_file = *arg;
	}
	if (elf_file == NULL) {
		fprintf(stderr, "Give me a .elf file to load\n");
		return 1;
	}

	elf_firmware_t f;
	elf_read_firmware(elf_file, &f);
	avr_t* avr = avr_make_mcu_by_name("atmega328p");
	if (!avr) {
		fprintf(stderr, "Unsupported cpu atmega328p\n");
		return 1;
	}

	avr_init(avr);
	if (gdb_port != 0) {
		avr->gdb_port = gdb_port;
		avr_gdb_init(avr);
	}
	avr->frequency = 16000000;
	avr_load_firmware(avr, &f);

	pcd8544_init(avr, &lcd);
	avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 2),
			lcd.irq + IRQ_PCD8544_DC);
	avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 1),
			lcd.irq + IRQ_PCD8544_CS);
	avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 0),
			lcd.irq + IRQ_PCD8544_RST);
	avr_connect_irq(avr_io_getirq(avr, AVR_IOCTL_SPI_GETIRQ(0), SPI_IRQ_OUTPUT),
			lcd.irq + IRQ_PCD8544_SPI_IN);

	gb_keypad_init(avr, &keypad);
	for (int i = 0; i < keydefs_length; i++) {
		const keydef_t *k = keydefs + i;
		avr_connect_irq(keypad.irq + k->keypad_key,
				avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ(k->port), k->pin));

		// Start with the pin high
		avr_ioport_t* port = (avr_ioport_t*) avr->io[k->avr_port].w.param;
		key_io[i].pin_mask = (1<<k->pin);
		key_io[i].pull_value = &port->external.pull_value;
		port->external.pull_mask |= key_io[i].pin_mask;
		port->external.pull_value |= key_io[i].pin_mask;
		gb_keypad_press(&keypad, k->keypad_key, 1);
	}

	if (display_init()) {
		lcd_ram_mutex = SDL_CreateMutex();
		SDL_Thread* avr_thread = SDL_CreateThread(avr_run_thread, "avr-thread", avr);
		main_loop();
		SDL_LockMutex(lcd_ram_mutex);
		quit_flag = 1;
		SDL_UnlockMutex(lcd_ram_mutex);
		int avr_thread_return;
		SDL_WaitThread(avr_thread, &avr_thread_return);
		SDL_DestroyMutex(lcd_ram_mutex);
	} else {
		r = 1;
		fprintf(stderr, "%s\n", display_error_message());
	}

	display_destroy();

	return r;
}
Example #21
0
int
main (int argc, char *argv[])
{
  elf_firmware_t firmware;
  const char *firmware_path = "../../../firmwares/blink-led.elf";
  int rc = elf_read_firmware (firmware_path, &firmware);
  if (rc == -1)
    exit (1);
  printf ("firmware %s f=%d mmcu=%s\n", firmware_path, (int) firmware.frequency, firmware.mmcu);

  firmware.frequency = 16e6;
  avr = avr_make_mcu_by_name ("atmega2560"); // firmware.mmcu
  if (!avr)
    {
      fprintf (stderr, "%s: AVR '%s' not known\n", argv[0], firmware.mmcu);
      exit (1);
    }
  avr_init (avr);
  avr_load_firmware (avr, &firmware);

  avr->log = LOG_TRACE;
  avr->trace = 1;

  // connect all the pins on port B to our callback
  for (int i = 0; i < 8; i++)
    avr_irq_register_notify (avr_io_getirq (avr, AVR_IOCTL_IOPORT_GETIRQ ('B'), i),
                             pin_changed_hook, NULL);

  /*
   * VCD file initialization
   * 
   * This will allow you to create a "wave" file and display it in gtkwave Pressing "r" and "s"
   * during the demo will start and stop recording the pin changes
   */
  avr_vcd_init (avr, "gtkwave_output.vcd", &vcd_file, 100000); // us
  avr_vcd_add_signal (&vcd_file,
                      avr_io_getirq (avr, AVR_IOCTL_IOPORT_GETIRQ ('B'), IOPORT_IRQ_PIN_ALL),
                      8, // bits
                      "porth");

  printf ("   Press 'q' to quit\n\n"
          "   Press 'r' to start recording a 'wave' file\n"
	  "   Press 's' to stop recording\n");

  // 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)
    {
      switch (getchar())
	{
	case 'q':
	  exit(0);
	  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;
	}
      fflush(stdin);
      fflush(stdout);
      // sleep (10); // s
    }
}
Example #22
0
int main(int argc, char *argv[])
{
	elf_firmware_t		f;
	const char			*fname="../src/binw2.elf";
	const char			*mmcu="attiny13";

	elf_read_firmware(fname, &f);

	snprintf(f.mmcu, sizeof(f.mmcu) - 1, "%s", mmcu);
	f.frequency = 4800000;
	printf("firmware %s f=%d mmcu=%s\n", fname, (int)f.frequency, f.mmcu);

	avr = avr_make_mcu_by_name(f.mmcu);
	if (!avr) {
		fprintf(stderr, "%s: AVR '%s' not known\n", argv[0], f.mmcu);
		exit(1);
	}
	avr_init(avr);
	avr_load_firmware(avr, &f);

	// initialize our 'peripheral'
	button_init(avr, &button, "button");

	// "connect" the output irq of the button to the port pin of the AVR
	avr_connect_irq(
		button.irq + IRQ_BUTTON_OUT,
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), IOPORT_IRQ_PIN4));

	avr_irq_register_notify(
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), IOPORT_IRQ_DIRECTION_ALL),
		ddr_hook,
		NULL);

	avr_irq_register_notify(
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), IOPORT_IRQ_PIN_ALL),
		pin_changed_hook, 
		"portb");

	// even if not setup at startup, activate gdb if crashing
	avr->gdb_port = 1234;
	//if (0) {
	//	//avr->state = cpu_Stopped;
	//	avr_gdb_init(avr);
	//}

	/*
	 *	VCD file initialization
	 *	
	 *	This will allow you to create a "wave" file and display it in gtkwave
	 *	Pressing "r" and "s" during the demo will start and stop recording
	 *	the pin changes
	 */
	avr_vcd_init(avr, "gtkwave_output.vcd", &vcd_file, 100000 /* usec */);
	avr_vcd_add_signal(&vcd_file, 
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), IOPORT_IRQ_PIN_ALL), 8 /* bits */ ,
		"portb" );
	avr_vcd_add_signal(&vcd_file, 
		button.irq + IRQ_BUTTON_OUT, 1 /* bits */ ,
		"button" );

	// 'raise' it, it's a "pullup"
	avr_raise_irq(button.irq + IRQ_BUTTON_OUT, 0);

	printf( "Launching binw2 simulation\n"
			"   Press 'space' to press virtual button attached to pin %d\n"
			"   Press 'q' to quit\n"
			"   Press 'r' to start recording a 'wave' file\n"
			"   Press 's' to stop recording\n",
			IOPORT_IRQ_PIN4);

	/*
	 * OpenGL init, can be ignored
	 */
	glutInit(&argc, argv);		/* initialize GLUT system */

	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
	glutInitWindowSize(5 * SZ_PIXSIZE, 7 * SZ_PIXSIZE);
	window = glutCreateWindow("Glut");	/* create window */

	// Set up projection matrix
	glMatrixMode(GL_PROJECTION); // Select projection matrix
	glLoadIdentity(); // Start with an identity matrix
	glOrtho(0, 5 * SZ_PIXSIZE, 0, 7 * SZ_PIXSIZE, 0, 10);
	//glScalef(1, -1, 1);
	//glTranslatef(0, -7 * SZ_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);

	glutMainLoop();
}
Example #23
0
int main(int argc, char *argv[])
{
	elf_firmware_t f;
	const char * fname =  "atmega168_timer_64led.axf";
	//char path[256];

//	sprintf(path, "%s/%s", dirname(argv[0]), fname);
	//printf("Firmware pathname is %s\n", path);
	elf_read_firmware(fname, &f);

	printf("firmware %s f=%d mmcu=%s\n", fname, (int)f.frequency, f.mmcu);

	avr = avr_make_mcu_by_name(f.mmcu);
	if (!avr) {
		fprintf(stderr, "%s: AVR '%s' now known\n", argv[0], f.mmcu);
		exit(1);
	}
	avr_init(avr);
	avr_load_firmware(avr, &f);

	//
	// initialize our 'peripherals'
	//
	hc595_init(avr, &shifter);
	
	button_init(avr, &button[B_START], "button.start");
	avr_connect_irq(
		button[B_START].irq + IRQ_BUTTON_OUT,
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 0));
	button_init(avr, &button[B_STOP], "button.stop");
	avr_connect_irq(
		button[B_STOP].irq + IRQ_BUTTON_OUT,
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 1));
	button_init(avr, &button[B_RESET], "button.reset");
	avr_connect_irq(
		button[B_RESET].irq + IRQ_BUTTON_OUT,
		avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), 0));

	// connects the fake 74HC595 array to the pins
	avr_irq_t * i_mosi = avr_io_getirq(avr, AVR_IOCTL_SPI_GETIRQ(0), SPI_IRQ_OUTPUT),
			* i_reset = avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('D'), 4),
			* i_latch = avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('D'), 7);
	avr_connect_irq(i_mosi, shifter.irq + IRQ_HC595_SPI_BYTE_IN);
	avr_connect_irq(i_reset, shifter.irq + IRQ_HC595_IN_RESET);
	avr_connect_irq(i_latch, shifter.irq + IRQ_HC595_IN_LATCH);

	avr_irq_t * i_pwm = avr_io_getirq(avr, AVR_IOCTL_TIMER_GETIRQ('0'), TIMER_IRQ_OUT_PWM0);
	avr_irq_register_notify(
		i_pwm,
		pwm_changed_hook, 
		NULL);	
	avr_irq_register_notify(
		shifter.irq + IRQ_HC595_OUT,
		hc595_changed_hook, 
		NULL);

	// even if not setup at startup, activate gdb if crashing
	avr->gdb_port = 1234;
	if (0) {
		//avr->state = cpu_Stopped;
		avr_gdb_init(avr);
	}

	/*
	 *	VCD file initialization
	 *	
	 *	This will allow you to create a "wave" file and display it in gtkwave
	 *	Pressing "r" and "s" during the demo will start and stop recording
	 *	the pin changes
	 */
	avr_vcd_init(avr, "gtkwave_output.vcd", &vcd_file, 10000 /* usec */);

	avr_vcd_add_signal(&vcd_file, 
		avr_get_interrupt_irq(avr, 7), 1 /* bit */ ,
		"TIMER2_COMPA" );
	avr_vcd_add_signal(&vcd_file, 
		avr_get_interrupt_irq(avr, 17), 1 /* bit */ ,
		"SPI_INT" );
	avr_vcd_add_signal(&vcd_file, 
		i_mosi, 8 /* bits */ ,
		"MOSI" );

	avr_vcd_add_signal(&vcd_file, 
		i_reset, 1 /* bit */ ,
		"595_RESET" );
	avr_vcd_add_signal(&vcd_file, 
		i_latch, 1 /* bit */ ,
		"595_LATCH" );
	avr_vcd_add_signal(&vcd_file, 
		button[B_START].irq + IRQ_BUTTON_OUT, 1 /* bits */ ,
		"start" );
	avr_vcd_add_signal(&vcd_file, 
		button[B_STOP].irq + IRQ_BUTTON_OUT, 1 /* bits */ ,
		"stop" );
	avr_vcd_add_signal(&vcd_file, 
		button[B_RESET].irq + IRQ_BUTTON_OUT, 1 /* bits */ ,
		"reset" );

	avr_vcd_add_signal(&vcd_file, 
		shifter.irq + IRQ_HC595_OUT, 32 /* bits */ ,
		"HC595" );
	avr_vcd_add_signal(&vcd_file, 
		i_pwm, 8 /* bits */ ,
		"PWM" );

	// 'raise' it, it's a "pullup"
	avr_raise_irq(button[B_START].irq + IRQ_BUTTON_OUT, 1);
	avr_raise_irq(button[B_STOP].irq + IRQ_BUTTON_OUT, 1);
	avr_raise_irq(button[B_RESET].irq + IRQ_BUTTON_OUT, 1);

	printf( "Demo : This is a real world firmware, a 'stopwatch'\n"
			"   timer that can count up to 99 days. It features a PWM control of the\n"
			"   brightness, blinks the dots, displays the number of days spent and so on.\n\n"
			"   Press '0' to press the 'start' button\n"
			"   Press '1' to press the 'stop' button\n"
			"   Press '2' to press the 'reset' button\n"
			"   Press 'q' to quit\n\n"
			"   Press 'r' to start recording a 'wave' file - with a LOT of data\n"
			"   Press 's' to stop recording\n"
			"  + Make sure to watch the brightness dim once you stop the timer\n\n"
			);

	/*
	 * OpenGL init, can be ignored
	 */
	glutInit(&argc, argv);		/* initialize GLUT system */


	int w = 22, h = 8;
	
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
	glutInitWindowSize(w * pixsize, h * pixsize);		/* width=400pixels height=500pixels */
	window = glutCreateWindow("Press 0, 1, 2 or q");	/* create window */

	// Set up projection matrix
	glMatrixMode(GL_PROJECTION); // Select projection matrix
	glLoadIdentity(); // Start with an identity matrix
	glOrtho(0, w * pixsize, 0, h * pixsize, 0, 10);
	glScalef(1,-1,1);
	glTranslatef(0, -1 * h * 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);

	glutMainLoop();
}