コード例 #1
0
ファイル: avr_flash.c プロジェクト: GregoryLand/simavr
static int avr_flash_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_param)
{
	if (ctl != AVR_IOCTL_FLASH_SPM)
		return -1;

	avr_flash_t * p = (avr_flash_t *)port;
	avr_t * avr = p->io.avr;

	avr_flashaddr_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
	if (avr->rampz)
		z |= avr->data[avr->rampz] << 16;
	uint16_t r01 = avr->data[0] | (avr->data[1] << 8);

//	printf("AVR_IOCTL_FLASH_SPM %02x Z:%04x R01:%04x\n", avr->data[p->r_spm], z,r01);
	avr_cycle_timer_cancel(avr, avr_progen_clear, p);
	avr_regbit_clear(avr, p->selfprgen);
	if (avr_regbit_get(avr, p->pgers)) {
		z &= ~1;
		AVR_LOG(avr, LOG_TRACE, "FLASH: Erasing page %04x (%d)\n", (z / p->spm_pagesize), p->spm_pagesize);
		for (int i = 0; i < p->spm_pagesize; i++)
			avr->flash[z++] = 0xff;
	} else if (avr_regbit_get(avr, p->pgwrt)) {
		z &= ~1;
		AVR_LOG(avr, LOG_TRACE, "FLASH: Writing page %04x (%d)\n", (z / p->spm_pagesize), p->spm_pagesize);
	} else if (avr_regbit_get(avr, p->blbset)) {
		AVR_LOG(avr, LOG_TRACE, "FLASH: Setting lock bits (ignored)\n");
	} else {
		z &= ~1;
		avr->flash[z++] = r01;
		avr->flash[z] = r01 >> 8;
	}
	return 0;
}
コード例 #2
0
ファイル: avr_uart.c プロジェクト: justinbrewer/simavr
static uint8_t avr_uart_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
{
	avr_uart_t * p = (avr_uart_t *)param;

	// clear the rxc bit in case the code is using polling
	avr_regbit_clear(avr, p->rxc.raised);

	if (!avr_regbit_get(avr, p->rxen)) {
		avr->data[addr] = 0;
		// made to trigger potential watchpoints
		avr_core_watch_read(avr, addr);
		return 0;
	}
	uint8_t v = uart_fifo_read(&p->input);

//	TRACE(printf("UART read %02x %s\n", v, uart_fifo_isempty(&p->input) ? "EMPTY!" : "");)
	avr->data[addr] = v;
	// made to trigger potential watchpoints
	v = avr_core_watch_read(avr, addr);

	// trigger timer if more characters are pending
	if (!uart_fifo_isempty(&p->input))
		avr_cycle_timer_register_usec(avr, p->usec_per_byte, avr_uart_rxc_raise, p);

	return v;
}
コード例 #3
0
ファイル: avr_flash.c プロジェクト: GregoryLand/simavr
static avr_cycle_count_t avr_progen_clear(struct avr_t * avr, avr_cycle_count_t when, void * param)
{
	avr_flash_t * p = (avr_flash_t *)param;
	avr_regbit_clear(p->io.avr, p->selfprgen);
	AVR_LOG(avr, LOG_WARNING, "FLASH: avr_progen_clear - SPM not received, clearing PRGEN bit\n");
	return 0;
}
コード例 #4
0
ファイル: avr_watchdog.c プロジェクト: Axbit/simavr
static avr_cycle_count_t avr_wdce_clear(
		struct avr_t * avr, avr_cycle_count_t when, void * param)
{
	avr_watchdog_t * p = (avr_watchdog_t *)param;
	avr_regbit_clear(p->io.avr, p->wdce);
	return 0;
}
コード例 #5
0
ファイル: avr_uart.c プロジェクト: justinbrewer/simavr
static void avr_uart_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
{
	avr_uart_t * p = (avr_uart_t *)param;

	if (addr == p->r_udr) {
		avr_core_watch_write(avr, addr, v);

		if ( p->udrc.vector)
			avr_regbit_clear(avr, p->udrc.raised);
		avr_cycle_timer_register_usec(avr,
				p->usec_per_byte, avr_uart_txc_raise, p); // should be uart speed dependent

		if (p->flags & AVR_UART_FLAG_STDIO) {
			const int maxsize = 256;
			if (!p->stdio_out)
				p->stdio_out = malloc(maxsize);
			p->stdio_out[p->stdio_len++] = v < ' ' ? '.' : v;
			p->stdio_out[p->stdio_len] = 0;
			if (v == '\n' || p->stdio_len == maxsize) {
				p->stdio_len = 0;
				AVR_LOG(avr, LOG_TRACE, FONT_GREEN "%s\n" FONT_DEFAULT, p->stdio_out);
			}
		}
		TRACE(printf("UDR%c(%02x) = %02x\n", p->name, addr, v);)
		// tell other modules we are "outputting" a byte
		if (avr_regbit_get(avr, p->txen))
コード例 #6
0
ファイル: avr_spi.c プロジェクト: rqou/simavr-prlite
static uint8_t avr_spi_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
{
    avr_spi_t * p = (avr_spi_t *)param;
    uint8_t v = p->input_data_register;
    p->input_data_register = 0;
    avr_regbit_clear(avr, p->spi.raised);
//	printf("avr_spi_read = %02x\n", v);
    return v;
}
コード例 #7
0
ファイル: avr_adc.c プロジェクト: kevinf28/simavr
static void avr_adc_reset(avr_io_t * port)
{
	avr_adc_t * p = (avr_adc_t *)port;

	// stop ADC
	avr_cycle_timer_cancel(p->io.avr, avr_adc_int_raise, p);
	avr_regbit_clear(p->io.avr, p->adsc);

	for (int i = 0; i < ADC_IRQ_COUNT; i++)
		avr_irq_register_notify(p->io.irq + i, avr_adc_irq_notify, p);
}
コード例 #8
0
ファイル: avr_twi.c プロジェクト: Axbit/simavr
static void
avr_twi_write(
		struct avr_t * avr,
		avr_io_addr_t addr,
		uint8_t v,
		void * param)
{
	avr_twi_t * p = (avr_twi_t *)param;

	uint8_t twen = avr_regbit_get(avr, p->twen);
	uint8_t twsta = avr_regbit_get(avr, p->twsta);
	uint8_t twsto = avr_regbit_get(avr, p->twsto);
	uint8_t twint = avr_regbit_get(avr, p->twi.raised);

	avr_core_watch_write(avr, addr, v);
#if AVR_TWI_DEBUG
	AVR_TRACE(avr, "%s %02x START:%d STOP:%d ACK:%d INT:%d TWSR:%02x (state %02x)\n",
			__func__, v,
			avr_regbit_get(avr, p->twsta),
			avr_regbit_get(avr, p->twsto),
			avr_regbit_get(avr, p->twea),
			avr_regbit_get(avr, p->twi.raised),
			avr_regbit_get_raw(p->io.avr, p->twsr), p->state);
#endif
	if (twen != avr_regbit_get(avr, p->twen)) {
		twen = !twen;
		if (!twen) { // if we were running, now now are not
			avr_regbit_clear(avr, p->twea);
			avr_regbit_clear(avr, p->twsta);
			avr_regbit_clear(avr, p->twsto);
			avr_clear_interrupt(avr, &p->twi);
			avr_core_watch_write(avr, p->r_twdr, 0xff);
			_avr_twi_status_set(p, TWI_NO_STATE, 0);
			p->state = 0;
			p->peer_addr = 0;
		}
		AVR_TRACE(avr, "TWEN: %d\n", twen);
		if (avr->data[p->r_twar]) {
			AVR_TRACE(avr, "TWEN Slave: %02x&%02x\n", avr->data[p->r_twar] >> 1, avr->data[p->r_twamr] >> 1);
			p->state |= TWI_COND_SLAVE;
		}
コード例 #9
0
ファイル: avr_adc.c プロジェクト: kevinf28/simavr
static void
avr_adc_write_adcsra(
		struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
{
	avr_adc_configure_trigger(avr, addr, v, param);
	
	avr_adc_t * p = (avr_adc_t *)param;
	uint8_t adsc = avr_regbit_get(avr, p->adsc);
	uint8_t aden = avr_regbit_get(avr, p->aden);

	avr->data[p->adsc.reg] = v;

	// can't write zero to adsc
	if (adsc && !avr_regbit_get(avr, p->adsc)) {
		avr_regbit_set(avr, p->adsc);
		v = avr->data[p->adsc.reg];
	}
	if (!aden && avr_regbit_get(avr, p->aden)) {
		// first conversion
		p->first = 1;
		AVR_LOG(avr, LOG_TRACE, "ADC: Start AREF %d AVCC %d\n", avr->aref, avr->avcc);
	}
	if (aden && !avr_regbit_get(avr, p->aden)) {
		// stop ADC
		avr_cycle_timer_cancel(avr, avr_adc_int_raise, p);
		avr_regbit_clear(avr, p->adsc);
		v = avr->data[p->adsc.reg];	// Peter Ross [email protected]
	}
	if (!adsc && avr_regbit_get(avr, p->adsc)) {
		// start one!
		uint8_t muxi = avr_regbit_get_array(avr, p->mux, ARRAY_SIZE(p->mux));
		union {
			avr_adc_mux_t mux;
			uint32_t v;
		} e = { .mux = p->muxmode[muxi] };
		avr_raise_irq(p->io.irq + ADC_IRQ_OUT_TRIGGER, e.v);

		// clock prescaler are just a bit shift.. and 0 means 1
		uint32_t div = avr_regbit_get_array(avr, p->adps, ARRAY_SIZE(p->adps));
		if (!div) div++;

		div = avr->frequency >> div;
		if (p->first)
			AVR_LOG(avr, LOG_TRACE, "ADC: starting at %uKHz\n", div / 13 / 100);
		div /= p->first ? 25 : 13;	// first cycle is longer

		avr_cycle_timer_register(avr,
				avr_hz_to_cycles(avr, div),
				avr_adc_int_raise, p);
	}
	avr_core_watch_write(avr, addr, v);
}
コード例 #10
0
ファイル: sim_interrupts.c プロジェクト: 33d/gbsim-win
void
avr_clear_interrupt(
		avr_t * avr,
		avr_int_vector_t * vector)
{
	if (!vector)
		return;
	if (vector->trace)
		printf("%s cleared %d\n", __FUNCTION__, vector->vector);
	vector->pending = 0;
	avr_raise_irq(&vector->irq, 0);
	if (vector->raised.reg && !vector->raise_sticky)
		avr_regbit_clear(avr, vector->raised);
}
コード例 #11
0
ファイル: avr_watchdog.c プロジェクト: FabriceSalvaire/simavr
static void
avr_watchdog_irq_notify (struct avr_irq_t *irq, uint32_t value, void *param)
{
  avr_watchdog_t *p = (avr_watchdog_t *) param;
  avr_t *avr = p->io.avr;

  /* interrupt handling calls this twice...
   * first when raised (during queuing), value = 1
   * again when cleared (after servicing), value = 0
   */

  if (!value && avr_regbit_get (avr, p->watchdog.raised))
    avr_regbit_clear (avr, p->watchdog.enable);
}
コード例 #12
0
ファイル: avr_adc.c プロジェクト: buserror/simreprap
static avr_cycle_count_t avr_adc_int_raise(struct avr_t * avr, avr_cycle_count_t when, void * param)
{
	avr_adc_t * p = (avr_adc_t *)param;
	if (avr_regbit_get(avr, p->aden)) {
		// if the interrupts are not used, still raised the UDRE and TXC flag
		avr_raise_interrupt(avr, &p->adc);
		avr_regbit_clear(avr, p->adsc);
		p->first = 0;
		p->read_status = 0;
		if( p->adts_mode == avr_adts_free_running )
			avr_raise_irq(p->io.irq + ADC_IRQ_IN_TRIGGER, 1);
	}
	return 0;
}
コード例 #13
0
ファイル: sim_interrupts.c プロジェクト: Axbit/simavr
void
avr_clear_interrupt(
		avr_t * avr,
		avr_int_vector_t * vector)
{
	if (!vector)
		return;
	if (vector->trace)
		printf("%s cleared %d\n", __FUNCTION__, vector->vector);
	vector->pending = 0;

	avr_raise_irq(vector->irq + AVR_INT_IRQ_PENDING, 0);
	avr_raise_irq(avr->interrupts.irq + AVR_INT_IRQ_PENDING,
			avr_has_pending_interrupts(avr));

	if (vector->raised.reg && !vector->raise_sticky)
		avr_regbit_clear(avr, vector->raised);
}
コード例 #14
0
ファイル: avr_twi.c プロジェクト: jdpillon/simulide
static void
avr_twi_write(
		struct avr_t * avr,
		avr_io_addr_t addr,
		uint8_t v,
		void * param)
{
	avr_twi_t * p = (avr_twi_t *)param;

	uint8_t twen = avr_regbit_get(avr, p->twen);
	uint8_t twsta = avr_regbit_get(avr, p->twsta);
	uint8_t twsto = avr_regbit_get(avr, p->twsto);
	uint8_t twint = avr_regbit_get(avr, p->twi.raised);

	avr_core_watch_write(avr, addr, v);
#if AVR_TWI_DEBUG
	printf("avr_twi_write %02x START:%d STOP:%d ACK:%d INT:%d TWSR:%02x (state %02x)\n", v,
			avr_regbit_get(avr, p->twsta),
			avr_regbit_get(avr, p->twsto),
			avr_regbit_get(avr, p->twea),
			avr_regbit_get(avr, p->twi.raised),
			avr_regbit_get_raw(p->io.avr, p->twsr), p->state);
#endif
	if (twen != avr_regbit_get(avr, p->twen)) {
		twen = !twen;
		if (!twen) { // if we were running, now now are not
			avr_regbit_clear(avr, p->twea);
			avr_regbit_clear(avr, p->twsta);
			avr_regbit_clear(avr, p->twsto);
			avr_clear_interrupt(avr, &p->twi);
			avr_core_watch_write(avr, p->r_twdr, 0xff);
			_avr_twi_status_set(p, TWI_NO_STATE, 0);
			p->state = 0;
			p->peer_addr = 0;
		}
		printf("TWEN: %d\n", twen);
	}
	if (!twen)
		return;

	uint8_t cleared = avr_regbit_get(avr, p->twi.raised);

	/*int cleared = */avr_clear_interrupt_if(avr, &p->twi, twint);
//	printf("cleared %d\n", cleared);

	if (!twsto && avr_regbit_get(avr, p->twsto)) {
		// generate a stop condition
#if AVR_TWI_DEBUG
		printf("<<<<< I2C stop\n");
#endif
		if (p->state) { // doing stuff
			if (p->state & TWI_COND_START) {
				avr_raise_irq(p->io.irq + TWI_IRQ_MOSI,
						avr_twi_irq_msg(TWI_COND_STOP, p->peer_addr, 1));
			}
		}
		p->state = 0;
	}
	if (!twsta && avr_regbit_get(avr, p->twsta)) {
#if AVR_TWI_DEBUG
		printf(">>>>> I2C %sstart\n", p->state & TWI_COND_START ? "RE" : "");
#endif
		// generate a start condition
		if (p->state & TWI_COND_START)
			_avr_twi_delay_state(p, 3, TWI_REP_START);
		else
			_avr_twi_delay_state(p, 3, TWI_START);
		p->peer_addr = 0;
		p->state = TWI_COND_START;
	}

	if (cleared &&
			!avr_regbit_get(avr, p->twsta) &&
			!avr_regbit_get(avr, p->twsto)) {
		// writing or reading a byte
		if (p->state & TWI_COND_ADDR) {
			int do_read = p->peer_addr & 1;
#if AVR_TWI_DEBUG
			if (do_read)
				printf("I2C READ byte from %02x\n", p->peer_addr);
			else
				printf("I2C WRITE byte %02x to %02x\n", avr->data[p->r_twdr], p->peer_addr);
#endif
			// a normal data byte
			uint8_t msgv = do_read ? TWI_COND_READ : TWI_COND_WRITE;

			if (avr_regbit_get(avr, p->twea))
				msgv |= TWI_COND_ACK;

			p->state &= ~TWI_COND_ACK;	// clear ACK bit

			// if the latch is ready... as set by writing/reading the TWDR
			if ((p->state & msgv)) {

				// we send an IRQ and we /expect/ a slave to reply
				// immediately via an IRQ to set the COND_ACK bit
				// otherwise it's assumed it's been nacked...
				avr_raise_irq(p->io.irq + TWI_IRQ_MOSI,
						avr_twi_irq_msg(msgv, p->peer_addr, avr->data[p->r_twdr]));

				if (do_read) { // read ?
					_avr_twi_delay_state(p, 9,
							msgv & TWI_COND_ACK ?
									TWI_MRX_DATA_ACK : TWI_MRX_DATA_NACK);
				} else {
					_avr_twi_delay_state(p, 9,
							p->state & TWI_COND_ACK ?
									TWI_MTX_DATA_ACK : TWI_MTX_DATA_NACK);
				}
			}
#if AVR_TWI_DEBUG
			else
				printf("I2C latch is not ready, do nothing\n");
#endif
		} else {
#if AVR_TWI_DEBUG
			printf("I2C Master address %02x\n", avr->data[p->r_twdr]);
#endif
			// send the address
			p->state |= TWI_COND_ADDR;
			p->peer_addr = avr->data[p->r_twdr];
			p->state &= ~TWI_COND_ACK;	// clear ACK bit

			// we send an IRQ and we /expect/ a slave to reply
			// immediately via an IRQ tp set the COND_ACK bit
			// otherwise it's assumed it's been nacked...
			avr_raise_irq(p->io.irq + TWI_IRQ_MOSI,
					avr_twi_irq_msg(TWI_COND_START, p->peer_addr, 0));

			if (p->peer_addr & 1) { // read ?
				p->state |= TWI_COND_READ;	// always allow read to start with
				_avr_twi_delay_state(p, 9,
						p->state & TWI_COND_ACK ?
								TWI_MRX_ADR_ACK : TWI_MRX_ADR_NACK);
			} else {
				_avr_twi_delay_state(p, 9,
						p->state & TWI_COND_ACK ?
								TWI_MTX_ADR_ACK : TWI_MTX_ADR_NACK);
			}
		}
		p->state &= ~TWI_COND_WRITE;
	}
}