Hi, its been a while 
Ok, I have a battery powered project that uses 3 software UART receivers - connected to three sensors on different pins. The hardware UART is used for an RF module, and the sensors only respond when 'pinged' so I can receive them one at time. The software simply pings each sensor at a time, gathers results from each, then sends these via an RF transciever - it them goes to sleep. The only way to wake it up is a pushbutton connected to thre MCLR pin. This means it spends much of its time asleep, a button press wakes itup, it does its job an goes back to sleep - very simple.
I would like to implement a 'timeout' function in case a connection to one of the sensors is damaged. Currently, because I'm using a basic software UART, it simple continuously waits for a start bit in each of the UART routines. This means the unit remains 'powered up' and uses precious current should a fault condition occur.
I've thought about using the watchdog timer, but that would wake it up from sleep every so often, and because of current consumption, I would prefer it to remain in sleep mode until the MCLR pin is pulled low (hardware reset). Plus, as I'm using three of these UARTS, constantly checking a timer (like a TMR0 overflow) woudl have to be in many many places in the code.
So, I'm thinking of setting up timer0 (or any of the timers) to provide an interrupt after a timeout period, then, inside the interrupt routine it raises a flag to indicate a timeout condition then 'jumps' (using the goto instruction) to the end of the code where it powers down and sleeps. - I realize this is very bad practice (not returning form interrupt, or any subroutines) but my thinking is, once sent to sleep it can *only* wake up with a hardware reset.
I know the hardware reset forces the PC to 0x0000, but does the stack clear upon reset? My fears are, as I'm calling subroutines quite often (and returning from them), if inside one of these subs, the interrupt pings but goes straight to the end of the code (then sleep) than I'll have two addresses in the stack. If these aren't cleared upon a hard reset after sleep, then I'll get a stack overflow.
Any idea's on implementing a timeout for a software UART? I'm writing in assembly (original project was done 7 years ago lol). It is fairly unique in that should a timeout occur, then it just has to go to the error routine (flashing LED's) then sleep - without needing to store anything from that session.
EDIT:
Ok, I just realised that I'm dumb - for every call the stack gets an address popped in, last address that goes is is the first one out, so sending the code to another part with 'goto', then sending it to sleep won't matter - because the only thing that can wake it up is a reset. And as code will always call a subroutine first, the latest address will be the one available, any remaining return addresses will be discarded or over written. So it should work just fine.
I didn't delete the post because there may be other ways for creating a 'timeout' for software UART's, and others may benefit from any replies here.
Ok, I have a battery powered project that uses 3 software UART receivers - connected to three sensors on different pins. The hardware UART is used for an RF module, and the sensors only respond when 'pinged' so I can receive them one at time. The software simply pings each sensor at a time, gathers results from each, then sends these via an RF transciever - it them goes to sleep. The only way to wake it up is a pushbutton connected to thre MCLR pin. This means it spends much of its time asleep, a button press wakes itup, it does its job an goes back to sleep - very simple.
I would like to implement a 'timeout' function in case a connection to one of the sensors is damaged. Currently, because I'm using a basic software UART, it simple continuously waits for a start bit in each of the UART routines. This means the unit remains 'powered up' and uses precious current should a fault condition occur.
I've thought about using the watchdog timer, but that would wake it up from sleep every so often, and because of current consumption, I would prefer it to remain in sleep mode until the MCLR pin is pulled low (hardware reset). Plus, as I'm using three of these UARTS, constantly checking a timer (like a TMR0 overflow) woudl have to be in many many places in the code.
So, I'm thinking of setting up timer0 (or any of the timers) to provide an interrupt after a timeout period, then, inside the interrupt routine it raises a flag to indicate a timeout condition then 'jumps' (using the goto instruction) to the end of the code where it powers down and sleeps. - I realize this is very bad practice (not returning form interrupt, or any subroutines) but my thinking is, once sent to sleep it can *only* wake up with a hardware reset.
I know the hardware reset forces the PC to 0x0000, but does the stack clear upon reset? My fears are, as I'm calling subroutines quite often (and returning from them), if inside one of these subs, the interrupt pings but goes straight to the end of the code (then sleep) than I'll have two addresses in the stack. If these aren't cleared upon a hard reset after sleep, then I'll get a stack overflow.
Any idea's on implementing a timeout for a software UART? I'm writing in assembly (original project was done 7 years ago lol). It is fairly unique in that should a timeout occur, then it just has to go to the error routine (flashing LED's) then sleep - without needing to store anything from that session.
EDIT:
Ok, I just realised that I'm dumb - for every call the stack gets an address popped in, last address that goes is is the first one out, so sending the code to another part with 'goto', then sending it to sleep won't matter - because the only thing that can wake it up is a reset. And as code will always call a subroutine first, the latest address will be the one available, any remaining return addresses will be discarded or over written. So it should work just fine.
I didn't delete the post because there may be other ways for creating a 'timeout' for software UART's, and others may benefit from any replies here.
Last edited: