-
Notifications
You must be signed in to change notification settings - 8000 Fork 376
Unable to reproduce tests/atmega88_example.axf results #486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The README does not say that the program you build will produce that output, just "A program running with these instructions ... will display". Evidently an older version of run_avr with a higher logging level was used. Indeed, you can get closer by adding several "-v" options to the command. So there seems to be no real issue here. |
Thanks for the references; yes, this issue (if even an issue) seems to be a duplicate. So, this is just a case of the output shown in the README being out of date with the state of the main branch. |
Can this issue be reopened? I reproduced this issue and was able to get the desired / matching output by modifying the function Here is the changed code: diff --git a/simavr/sim/sim_core.c b/simavr/sim/sim_core.c
index bf7a819..7884fa5 100644
--- a/simavr/sim/sim_core.c
+++ b/simavr/sim/sim_core.c
@@ -284,6 +284,13 @@ static inline void _avr_set_r(avr_t * avr, uint16_t r, uint8_t v)
avr_io_addr_t io = AVR_DATA_TO_IO(r);
if (avr->io[io].w.c) {
avr->io[io].w.c(avr, r, v, avr->io[io].w.param);
+ if (avr->io[io].irq) {
+ avr_raise_irq(avr->io[io].irq + AVR_IOMEM_IRQ_ALL, v);
+ for (int i = 0; i < 8; i++)
+ {
+ avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1);
+ }
+ }
} else {
avr->data[r] = v;
if (avr->io[io].irq) { TLDREnable CFLAGS += -Werror -DCONFIG_SIMAVR_TRACE
make
./simavr/run_avr --mcu atmega88 --trace tests/atmega88_example.axf &> output
|
Good find @atluft Running into this myself, yeah, it appears the VCD change dumps do not work for any IO registers with write handlers.
If the change is made, the question is: Now we would be calling 2 IRQs, the IO one, and the peripheral specific one. There is a peripheral one in this case: the UART TX IRQ. Now, IRQs would be potentially duplicated. @gatk555 talked about something similar in #540 (comment) In the latest commits, there is a _call_register_irqs, but there is a bug: The value must be passed instead of reading the register in-function, because in the write case, it is not yet written. Changes for that: static inline void _call_register_irqs(avr_t * avr, uint16_t addr, uint8_t v)
{
if (addr > 31 && addr < 31 + MAX_IOs) {
avr_io_addr_t io = AVR_DATA_TO_IO(addr);
if (avr->io[io].irq) {
avr_raise_irq(avr->io[io].irq + AVR_IOMEM_IRQ_ALL, v);
for (int i = 0; i < 8; i++)
avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1);
}
}
} _avr_set_r could be then simplified to this; static inline void _avr_set_r(avr_t * avr, uint16_t r, uint8_t v)
{
REG_TOUCH(avr, r);
if (r == R_SREG) {
avr->data[R_SREG] = v;
// unsplit the SREG
SET_SREG_FROM(avr, v);
SREG();
}
if (r > 31) {
avr_io_addr_t io = AVR_DATA_TO_IO(r);
if (avr->io[io].w.c) {
avr->io[io].w.c(avr, r, v, avr->io[io].w.param);
} else {
avr->data[r] = v;
}
_call_register_irqs(avr, r, v);
_call_sram_irqs(avr, r); // Only for io region
} else
avr->data[r] = v;
} |
@jamesrwaugh , that approach is much better! Thank you for sharing and explaining the issue of duplicated IRQs. I see that now and prefer the solution you have presented. |
Running
yields
which is inconsistent with the expected output documented in the README.
All the tests are passing...
I am on CentOS 8 and using
avr-gcc
installed througharduino-cli
.The text was updated successfully, but these errors were encountered: