I have an issue which i would like some opinions on.
I am having an issue with an older product where it appears that the processor is hanging.
When debugging this, i have been informed that the USART comms is not used anymore and is left disconnected.
I see this as an issue as my Rx line is not tied high using pull-ups (rookie mistake), so now it is floating.
To make matters worse, the unit has been moved to an noisy environment, close to large motors.
After reviewing the code i noticed a redundant while loop in my USART Rx ISR, as below.
if (rx_cnt==BUFFER_SIZE) // if BUFFER_SIZE is reached, reset to start of buffer.
My question is, can the ISR fire, due to noise, without the RXC bit been set in the register, therefore causing my app to sit waiting for RXC making it appear that my uC is hanging?
I am using an Atmega8 with AVR studio 4.18 (old project).
Any opinions on this would be greatly appreciated.
It makes no sense to POLL the RXC bit in the IRQ, after all it has to be set to get there! The simple solution would be to install a loopback connector (TXD connected to RXD) into the missing serial port on the board, in that way the input would no longer be floating!
100% agree with the polling not been needed, thats what i meant with redundant while.
I'm really interested now to see if noise could fire the ISR but not set the RXC.
If this is not possible then the polling can't hang the uC.
That's why there is a watchdog timer in microcontrollers -- at least then the app will reset and restart.
Now, you are a bit stuck with the old AVR model and existing app. If it were e.g. Mega88, I'd suggest something like watchdog interrupt and grab the return address in the ISR and log to EEPROM or somewhere. Than after a number of these incidents you can see if it is always/usually at the same spot -- a real "hang".
Or not...then I'd suspect some kind of noise zap. AVR8s are pretty tough in a variety of environments. But when hit with hard enough noise spikes (which far exceed Absolute Maximum Ratings by the way) very "interesting" things can happen, most of them ugly.
If you can reproduce on the bench you will be much of the way home.
Yes it is the old AVR that somewhat limits me.
I can't for the life of me reproduce this, the customer can't either.
There could be the argument that this is a setup issue and nothing to do with the processor at all but i'm trying un-turn every stone at this stage.
Is there anyway for me to trigger the ISR without setting RXC, or is the ISR fired by the status of RXC?
If you have the source code, why not disable the USART and be done? Problem solved. Unless you would prefer not to as the possibility of the USART being used in the future?
I can't say with 100% certainty that the USART is the issue.
This is my theory that it could be USART, but my unit is a small part of a bigger system, could be another part causing the issue.
At this point I am trying to see explore all possibilities on my side, a un-needed while loop is always a concern for me.
There is also the possibility that the USART may be used in the future so can't disable it.
Can you tack a 4.7k resistor from the RXD line to the AVR's Vcc?
Can you post a schematic of the circuit? USART area only.
As Lee notes the AVR's are pretty tough.
But you could certainly disable the interrupt now, and see if it then reproduces.
Jim its just a staright track from the pin to the outside world connector, the max232 is part of an outside jig.
I could disable but its only happening on a customer site which is in a different country. I can't produce it in the lab.
Does the RX ISR firing without setting RXC seem plausible?
In theory, no, but once you get into the realm of noise and spikes then all bets are off.
A USART should only start doing anything once it sees a start bit which is, according to the datasheet, only detected once 3 consecutive 0s are seen in the middle of the bit. So it's lowpass filtered by the hardware.
I wonder if the USART is getting the blame unfairly? Are there any other floating pins which might have get 'enabled'? Or what happens if the processor gets an unexpected reset?
Possibly Brian, I am only thinking it may be the USART because of the While loop.
The RXD areTXD lines are floating.
The MISO, MOSI and SCK lines are connected to a 6pin programming connector but would also be floating in the application.
There is nothing to handle a unexpected reset.
If the chip reset and started from scratch would be better, but the customer is reporting the unit hangs.
The hang is coming from a customer description, the unit has a PWM which should vary it's duty cycle depending on an ADC measurement and in turn vary something in their app, instead they say that the PWM holds constant.
Once they manually reset the unit, the PWM works as expected.
100% agree with above but does it sound plausible if the chip got a big noise spike and didn't reset would the PWM hold constant (latch)?
Sorry for all the vague questions but I am working off a very limited amount of information myself.
I can finally recreate this issue on my bench with a returned unit.
There is no issue with the USART.
Instead it seems that my PWM is holding its value and not changing when i write new values to it.
I spotted this errata in the datasheets and I believe it may be the issue.
Does this means all interrupts with regard to the PWM will be missed or just the next interrupt?
I update TCCR1A and OCR1B quite regularly in my code and in the same position.
I also used timer 0 for my timings.
Is it possible that this could cause the issue?
Timer1 is not an asynchronous timer. Timer2 usually is.
How do you know you are actually writing values to the timer?
I have a signal which goes high when i am in my PWM function so I am fairly sure it is writing the values.
You are correct that only timer 2 is async on the Atmega8.
I am using timer 0 and timer 1 (OC1A and OC1B as PWM) so this may not be applicable to my issue.
So what if an irq was missed (as in, never happened)...that generally should not cause your program to hang (or write it so that it won't!)......of course, if it forms some part of a handshake sequence or causes a deadlock, that might be a diff story (but again, should be set up with some escape).
If possible, try disabling IRQ's one-by-one to determine which (if any) hang. Or do the reverse & turn them all off & enable them one-by-one until something bad happens. Hopefully the failure occurs often, so you can observe it & also know pretty reliably that it is really fixed.
By the way, can't you turn on the internal pullup for the rxd pin?