Пример #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;
}
Пример #2
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);
}
Пример #3
0
void uart_udp_init(struct avr_t * avr, uart_udp_t * p)
{
	p->avr = avr;
	p->irq = avr_alloc_irq(&avr->irq_pool, 0, IRQ_UART_UDP_COUNT, irq_names);
	avr_irq_register_notify(p->irq + IRQ_UART_UDP_BYTE_IN, uart_udp_in_hook, p);

	if ((p->s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
		fprintf(stderr, "%s: Can't create socket: %s", __FUNCTION__, strerror(errno));
		return ;
	}

	struct sockaddr_in address = { 0 };
	address.sin_family = AF_INET;
	address.sin_port = htons (4321);

	if (bind(p->s, (struct sockaddr *) &address, sizeof(address))) {
		fprintf(stderr, "%s: Can not bind socket: %s", __FUNCTION__, strerror(errno));
		return ;
	}

	printf("uart_udp_init bridge on port %d\n", 4321);

	pthread_create(&p->thread, NULL, uart_udp_thread, p);

}
Пример #4
0
void ac_input_init(avr_t *avr, ac_input_t *b)
{
	const char * name = ">ac_input";
	b->irq = avr_alloc_irq(&avr->irq_pool, 0, IRQ_AC_COUNT, &name);
	b->avr = avr;
	b->value = 0;
	avr_cycle_timer_register_usec(avr, 100000 / 50, switch_auto, b);
	printf("ac_input_init period %duS or %d cycles\n",
			100000 / 50, avr_usec_to_cycles(avr, 100000 / 50));
}
Пример #5
0
void
hc595_init(
    struct avr_t * avr,
    hc595_t *p)
{
    p->irq = avr_alloc_irq(&avr->irq_pool, 0, IRQ_HC595_COUNT, irq_names);
    avr_irq_register_notify(p->irq + IRQ_HC595_SPI_BYTE_IN, hc595_spi_in_hook, p);
    avr_irq_register_notify(p->irq + IRQ_HC595_IN_LATCH, hc595_latch_hook, p);
    avr_irq_register_notify(p->irq + IRQ_HC595_IN_RESET, hc595_reset_hook, p);

    p->latch = p->value = 0;
}
/**
 * Initializes a dummy card reader.
 * The card reader registers a DATA IRQ, which transmits data
 * according to the clock-and-data method of transfer.
 *
 * According to HID's documentation (see readme), bits are read when a
 * falling edge occurs on the CLK line. A low signal on the data line
 * signifies a 1, while a high signal is a 0. The clock maintains a
 * constant high signal except when CARD line is low; then the clock
 * changes between low and high every 500 nanoseconds. This results in
 * a data transfer rate of 1 bit per millisecond.
 *
 * @param avr_t *avr The main AVR simulator.
 * @param card_reader_t *card_reader An uninitialized struct to initialize.
 * @param struct uart_pty_t *serial The serial port to read from.
 * @param struct card_reader_clock_t *clock The clock module of this card reader.
 */
void card_reader_init(struct avr_t *avr, card_reader_t *card_reader, struct uart_pty_t *serial, struct card_reader_clock_t *clock) {
	memset(card_reader, 0, sizeof(*card_reader));
	card_reader->avr    = avr;
	card_reader->serial = serial;           // The serial port to read swipes from
	card_reader->clock  = clock;
	card_reader->state  = CARD_READER_IDLE; // Initially idle
	
	// Allocate and connect to IRQs
	card_reader->irq = avr_alloc_irq(&avr->irq_pool, 0, 2, card_reader_irq_names);

	// Listen to input from the serial port
	avr_irq_register_notify(serial->irq + IRQ_UART_PTY_BYTE_OUT, card_reader_swipe_interface, card_reader);
}
Пример #7
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);
    }
}
Пример #8
0
void ledrow_core_init(struct avr_t *avr, struct ledrow_t * b, int size)
{
	memset(b, 0, sizeof(*b));
	int i;
	b->avr = avr;

	/*
	 * Register callbacks on all our IRQs
	 */
	b->irq = avr_alloc_irq(&avr->irq_pool, 0, size, irq_names);

	for (int i = 0; i < size; i++)
	{
		avr_irq_register_notify(b->irq + i, ledrow_pin_changed_hook, b);
	}
}
Пример #9
0
void spk_core_init(struct avr_t *avr, struct spk_t * b, int rate, float speed)
{
	memset(b, 0, sizeof(*b));
	//int i;
	b->avr = avr;

	/*
	 * Register callbacks on all our IRQs
	 */
	b->irq = avr_alloc_irq(&avr->irq_pool, 0, 1, irq_names);
	avr_irq_register_notify(b->irq, spk_pin_changed_hook, b);

	b->freq_scale = (speed * avr->frequency) / rate;
	printf("b->freq_scale=%d \n", b->freq_scale);

	spk_reset(b);
}
Пример #10
0
avr_irq_t *
avr_iomem_getirq(
		avr_t * avr,
		avr_io_addr_t addr,
		const char * name,
		int index)
{
	if (index > 8)
		return NULL;
	avr_io_addr_t a = AVR_DATA_TO_IO(addr);
	if (avr->io[a].irq == NULL) {
		/*
		 * Prepare an array of names for the io IRQs. Ideally we'd love to have
		 * a proper name for these, but it's not possible at this time.
		 */
		char names[9 * 20];
		char * d = names;
		const char * namep[9];
		for (int ni = 0; ni < 9; ni++) {
			if (ni < 8)
				sprintf(d, "=avr.io%04x.%d", addr, ni);
			else
				sprintf(d, "8=avr.io%04x.all", addr);
			namep[ni] = d;
			d += strlen(d) + 1;
		}
		avr->io[a].irq = avr_alloc_irq(&avr->irq_pool, 0, 9, namep);
		// mark the pin ones as filtered, so they only are raised when changing
		for (int i = 0; i < 8; i++)
			avr->io[a].irq[i].flags |= IRQ_FLAG_FILTERED;
	}
	// if given a name, replace the default one...
	if (name) {
		int l = strlen(name);
		char n[l + 10];
		sprintf(n, "avr.io.%s", name);
		free((void*)avr->io[a].irq[index].name);
		avr->io[a].irq[index].name = strdup(n);
	}
	return avr->io[a].irq + index;
}
Пример #11
0
avr_irq_t *
avr_io_setirqs(
		avr_io_t * io,
		uint32_t ctl,
		int count,
		avr_irq_t * irqs )
{
	// allocate this module's IRQ
	io->irq_count = count;

	if (!irqs) {
		const char ** irq_names = NULL;

		if (io->irq_names) {
			irq_names = malloc(count * sizeof(char*));
			memset(irq_names, 0, count * sizeof(char*));
			char buf[64];
			for (int i = 0; i < count; i++) {
				/*
				 * this bit takes the io module 'kind' ("port")
				 * the IRQ name ("=0") and the last character of the ioctl ('p','o','r','A')
				 * to create a full name "=porta.0"
				 */
				char * dst = buf;
				// copy the 'flags' of the name out
				const char * kind = io->irq_names[i];
				while (isdigit(*kind))
					*dst++ = *kind++;
				while (!isalpha(*kind))
					*dst++ = *kind++;
				// add avr name
//				strcpy(dst, io->avr->mmcu);
				strcpy(dst, "avr");
				dst += strlen(dst);
				*dst ++ = '.';
				// add module 'kind'
				strcpy(dst, io->kind);
				dst += strlen(dst);
				// add port name, if any
				if ((ctl & 0xff) > ' ')
					*dst ++ = tolower(ctl & 0xff);
				*dst ++ = '.';
				// add the rest of the irq name
				strcpy(dst, kind);
				dst += strlen(dst);
				*dst = 0;

//				printf("%s\n", buf);
				irq_names[i] = strdup(buf);
			}
		}
		irqs = avr_alloc_irq(&io->avr->irq_pool, 0,
						count, irq_names);
		if (irq_names) {
			for (int i = 0; i < count; i++)
				free((char*)irq_names[i]);
			free((char*)irq_names);
		}
	}

	io->irq = irqs;
	io->irq_ioctl_get = ctl;
	return io->irq;
}