The sets the DDRD to all inputs, and prints 'SET' to the usart. It then starts printing out on the USART the value of PIND.
In simavr application:
for (;;) {
vr_ioport_external_t p;
int state = avr_run(avr);
if (state == cpu_Done || state == cpu_Crashed)
break;
if (kbhit()) {
//when key is pressed, change the pull up/down values
getch();
p.mask = 0xff;
p.value = 111;
avr_ioctl(avr, AVR_IOCTL_IOPORT_SET_EXTERNAL('D'), &p);
}
}
The idea is after seeing 'SET' go out the usart, the simavr user presses a key. This changes the pullup values. The value read from PIND in the AVR loop should change. It does not.
It seems the act of writing either DDR or PORT will update PIN properly taking into account the new external defaults. But changing the external defaults does not update PIN by itself. I think avr_ioport_read needs to look the updated value of .external.pull_value. This logic ( if output, else if external pull, else if internal pull), is present in avr_ioport_update_irqs, but it seems like it needs to be in the direct read as well.
Perhaps I am using simavr incorrectly? In my application loop I do this: (pseudocode)
while(1){
avr_run(avr)
use avr_ioctl to read the all the port's status with AVR_IOCTL_IOPORT_GETSTATE
emulate whatever computational logic and peripherals I have on the board
use avr_ioctl to set the new inputs (PINx) with AVR_IOCTL_IOPORT_SET_EXTERNAL
}
Most examples set up IRQs for each pin. I am doing IRQs for the usart. I am trying to emulate a physical board I have which uses a whole port (PORTB) as an 8-bit bus. I don't see a way to get a callback that tells me all 8 pins of the port at once as a byte, or a way to set all 8 pin inputs at once as a byte, except thru the ioctl calls above. If I set up an ioctl for each pin, when the AVR writes a byte on a port, I get 8 callbacks, each giving me 1 bit of the port. This seems to be the way simavr is intended to be used, and also seems completely crazy to me.
Actually if you look at the code, you'll find there IS a IRQ that sends the whole port as a whole. IOPORT_IRQ_PIN_ALL is exactly what you want. Most examples don't need it, but it's there...
This does not work as expected:
on the AVR:
The sets the DDRD to all inputs, and prints 'SET' to the usart. It then starts printing out on the USART the value of PIND.
In simavr application:
The idea is after seeing 'SET' go out the usart, the simavr user presses a key. This changes the pullup values. The value read from PIND in the AVR loop should change. It does not.
Changing the AVR code to this does work:
It seems the act of writing either DDR or PORT will update PIN properly taking into account the new external defaults. But changing the external defaults does not update PIN by itself. I think avr_ioport_read needs to look the updated value of .external.pull_value. This logic ( if output, else if external pull, else if internal pull), is present in avr_ioport_update_irqs, but it seems like it needs to be in the direct read as well.
Perhaps I am using simavr incorrectly? In my application loop I do this: (pseudocode)
Most examples set up IRQs for each pin. I am doing IRQs for the usart. I am trying to emulate a physical board I have which uses a whole port (PORTB) as an 8-bit bus. I don't see a way to get a callback that tells me all 8 pins of the port at once as a byte, or a way to set all 8 pin inputs at once as a byte, except thru the ioctl calls above. If I set up an ioctl for each pin, when the AVR writes a byte on a port, I get 8 callbacks, each giving me 1 bit of the port. This seems to be the way simavr is intended to be used, and also seems completely crazy to me.