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; }
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); }
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); }
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)); }
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); }
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); } }
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); } }
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); }
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; }
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; }