-
Notifications
You must be signed in to change notification settings - Fork 375
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
Reading from a pulled-up port after writing to it fails #204
Comments
I've just noticed that instead of commenting out the write to |
Furthermore, just leaving in another
doesn't fix the issue; the |
I have a maybe even simpler way of demonstrating this bug. Take the following AVR program:
and the following SimAVR program:
Then, we can play around with changing |
I have also just now discovered that the bug only manifest itself if the "sense" port has its pull-up resistor enabled. By commenting out the line
I am seeing correct behaviour from SimAVR. |
@gergoerdi : Yes, I also stumbled upon it some time ago. This is actually not a bug, but rather a misconception in how an internal pullup simulation implemented currently (see avr_ioport_update_irqs() in avr_ioport.c). Any pin configured as pulled-up input and connected to any signal source is affected. |
Well, my /prefered/ way was for a 'peripheral' to enforce it's own pullup/down to be fair. The pullup simulation was introduced to handle the case where there the pin isn't attached to anything, so it gets a default state. I knew it wasn't perfect. But, I've been thinking we might need to expand the IRQ a bit to handle 'floating' state, when you can raise_irq(... 'X'). I realized I needed that for the VCD anyway... |
@buserror : I vote for your idea of extending IRQ with 'floating' state and can try to sketch it somehow, if you would outline it more deeply. |
Hmm github munched my previous comment it seems?!?! FTH Anyway, @hovercraft-github I don't have a way to contact you, but I've added you as contributor. Please never push to master, we can continue doing pull requests and I will continue to merge to master. As you've seen, I've started to do it for my own features as well. |
I'll retype what I had typed before tho. Github did munch my message!: Idea is to add an AVR_IRG_FLAG_FLOAT... The receiving handler will be responsible to do a avr_irq_getflags(irq) & ... to know if it's floating or not... Thats should be compatible with every other piece of code...? |
There is already an unnamed array with flags in sim_irq.h: |
Yes, I believe this shouldn't break any existing code. |
Unless you have started this, i'm going to do it @hovercraft-github -- I need it for my VCD files, and it's a good test. |
Ok, I have not made significant progress yet |
I've pushed what I had in mind for the avr_irq, and the support for it in the VCD bits. Still need to creep up in the ioports module. |
@buserror Michel, please help me understand the idea behind this. I see there is a new procedure avr_raise_irq_float now. To handle pull-ups with it I think we should add a set of new IRQs into ioport for every pin, something like [IOPORT_IRQ_PIN0_SRC_IMP] = ">srcimp0" .. ">srcimp7", giving the application a way to specify an output impedance of connected circuit. Is it correct? |
Do you mean you want to change the pullups states 'externally'? I think it's already handled by the ioport, since you can specify the pullups from the firmware -- perhaps it has an ioctl already? Otherwise we could do with an IRQ to set the pullup values, but it'd need to be get/set 8 bits so it can be 'chained'... otherwise we could also set an IRQ state that gets set when an IRQ is marked as floating? not sure I like that that much, as it becomes a bit too 'generic' and makes tracking down code more complicated, that's why I prefer to keep the pullup values into the module itself... If you explain your use case we can come up with something. |
The use case is simple and very common: an application connects an output of some ("external" relative to the simavr) component to the MCU pin, which is configured as internally pulled-up input by the firmware.
in the avr_ioport_update_irqs. The same when there is nothing connected to the pin at all (the default). Otherwise, when the bus driver output goes to the active (low output impedance) state, simavr should NOT call avr_raise_irq(p->io.irq + i, 1) in the avr_ioport_update_irqs in response to any DDR or PORT writes or other events. |
In principle it would be enough to have just two signal source impedance values: low_source_impedance=0 and high_source_impedance=-1(meaning infinity) |
To make things clear, the following simple arduino sketch will not work in the current version of simavr:
If we connect buttons to the input pins, the firmware will not sense its press and LEDs will always remain lit. In PR #246 I created board_keypress example and atmega88_pullups_test which demonstrates this behaviour. @buserror Michel, please give your opinion about this and my posts above. |
Have you tried AVR_MCU_EXTERNAL_PORT_PULL macros? simavr/simavr/sim/avr/avr_mcu_section.h Line 196 in 5715c08
It's supposed to handle that sort of case really. |
As far as I can understand, the AVR_MCU_EXTERNAL_PORT_PULL macro controls the state of external pull-ups only. This is not the same feature as an internal pull-up, so seems it's not applicable in our case. When we are connecting an external voltage source to the input pin, our objective in this situation is to avoid call like avr_raise_irq(p->io.irq + i, ...) inside the avr_ioport_update_irqs_pin procedure (avr_ioport.c line 61 for internall pull-ups).
, I would say we can't achieve that even we somehow abuse p->external. |
I have the following code, reduced as far as I could:
What it tries to do, is to pulse low
PD0
andPC0
before reading in some input onPC5
. Originally, this came up in the context of a 4x4 keypad where there are four row selectors and four column readers, but the problem can be shown even on this smaller example.In SimAVR, I set
PC5
in response toPD0
going low:If I run this, I see that the debug output on
PB0
never goes high.However, if I comment out the line
PORTC &= ~_BV(PC0);
i.e. I don't write toPORTC
before readingPINC
, then it works as expected and I seePB0
changing between 0 and 1.The text was updated successfully, but these errors were encountered: