-
Notifications
You must be signed in to change notification settings - Fork 388
Open
Description
Hi,
the following code for mega1284P configures the USART1 as SPI-master and sends out the same byte again and again (stop the simulation with Ctrl+C!) at maximum speed=f_osc/2. It also sets a pin to measure the time needed for the transmission.
On real hardware with a 18,432MHz crystal this time is about 1,74µs (measured with a scope), but in the VCD-file produced by simavr the time is about 7,7µs! This is way too much.
Is an USART as a SPI-master actually properly simulated by simavr?
#include <avr/io.h>
#include <stdint.h>
uint8_t spi_send_receive(const uint8_t v)
{
PORTB|=(1<<PB0);
while(!(UCSR1A&(1<<UDRE1)));
UDR1=v;
while(!(UCSR1A&(1<<RXC1)));
PORTB&=~(1<<PB0);
return UDR1;
}
int main(void)
{
DDRB|=(1<<PB0);
//USART1 as SPI, max speed
UBRR1=0;
DDRD|=(1<<PD3)|(1<<PD4);
UCSR1C=(1<<UMSEL11)|(1<<UMSEL10);
UCSR1B=(1<<RXEN1)|(1<<TXEN1);
UBRR1=0;
while(1)
spi_send_receive(0xaa);
return 0;
}
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <err.h>
#include <signal.h>
#include "sim_avr.h"
#include "sim_elf.h"
#include "avr_uart.h"
#include "avr_ioport.h"
#include "sim_vcd_file.h"
volatile bool run=true;
static void sigint_handler(int sig)
{
(void)sig;
run=false;
}
int main(void)
{
signal(SIGINT, &sigint_handler);
avr_t *avr1;
elf_firmware_t firmware1;
if(elf_read_firmware("avr.elf", &firmware1))
{
printf("elf_read_firmware failed\n");
return 1;
}
avr1 = avr_make_mcu_by_name("atmega1284p");
if (!avr1) {
printf("avr_make_mcu_by_name failed\n");
return 1;
}
avr_init(avr1);
avr1->frequency=18432000;
avr_load_firmware(avr1, &firmware1);
avr_vcd_t vcd1;
avr_vcd_init(avr1, "test.vcd", &vcd1, 100);
avr_vcd_add_signal(&vcd1, avr_io_getirq(avr1, AVR_IOCTL_IOPORT_GETIRQ('B'), 0), 1, "PB0");
avr_vcd_start(&vcd1);
//the simulator will block if nothing is "received", so just add a virtual connection
avr_connect_irq(avr_io_getirq(avr1, AVR_IOCTL_UART_GETIRQ('1'), UART_IRQ_OUTPUT), avr_io_getirq(avr1, AVR_IOCTL_UART_GETIRQ('1'), UART_IRQ_INPUT));
int state1;
do
{
state1=avr_run(avr1);
} while(state1!=cpu_Done && state1!=cpu_Crashed && run);
avr_vcd_close(&vcd1);
avr_terminate(avr1);
return 0;
}
Metadata
Metadata
Assignees
Labels
No labels