View previous topic :: View next topic |
Author |
Message |
soonc
Joined: 03 Dec 2013 Posts: 215
|
Multiple use for a single pin |
Posted: Sun Apr 09, 2017 9:03 pm |
|
|
PIC24FJ128GA306
PIC Compiler 5.070
I have Pin B14 Setup as Rx pin of hardware UART3.
At some time in the code I disable the UART because I do not want interrupt handling for data that arrives after the initial use as a UART. Data arrives in packets approximately every 5 minutes.
However I would like to know when data (9600 Baud) starts again, and at the moment the code is polling the pin looking for activity.
This scheme works but I'd like to make use of "Interrupt On Change" (IOC) which although it would cause an interrupt it does not require as much servicing as a UART, and it should be possible to NOT service the IOC by not reading the port deliberately which should prevent further IOC interrupts until needed.
Essentially the IOC interrupt would be a one shot event until reset.
Are there any drawbacks to switching the PIN functions from UART to IOC and then back to being a UART when needed ? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19383
|
|
Posted: Mon Apr 10, 2017 1:18 am |
|
|
If you are turning on the UART, when the input drops, then you might as well leave the UART interrupt handler enabled. The interrupt handler won't do anything _till_ the line drops.
Seems an unnecessary complexity to involve another interrupt...
Then you have another problem. If you enable the UART at this point in time, the leading edge of the first character will have been missed. The chances are the UART may then return an error. Since the character it then sees is 'malformed'... This is why systems using a 'wake' on UART, or similar approaches, normally have a 'start receiving' character, followed by a short pause. The receiving device, sees the start bit, and wakes up, and then waits for the serial line to stay high, before enabling the UART, or waits for the error bit, and then resets the UART again (either way, in the 'pause').
One approach that actually gives fewer problems is as follows (structure only, not real code):
Code: |
int1 uart_disabled=TRUE;
#INT_RDA
{
int8 rx_char;
rx_char=fgetc(YOUR_UART);
if (uart_disabled)
return;
//then your handler code for the received character
......
}
//since you have always read the character, the UART is happy.
//Then in your 'main' code, simply set 'uart_disabled', 'TRUE' when you
//don't want yo handle the characters and set it 'FALSE' when you do.
|
If you are disabling the UART:
setup_UART(FALSE, YOUR_UART);
Then the UART interrupt won't be called till it is re-enabled.
When you do want to receive, disable the UART interrupt, enable the UART. read any character(s) it has waiting, and then enable the UART interrupt. On the next falling edge, the interrupt will be called. |
|
![](templates/subSilver/images/spacer.gif) |
soonc
Joined: 03 Dec 2013 Posts: 215
|
Better description |
Posted: Mon Apr 10, 2017 7:38 am |
|
|
Sorry I was not clear enough in my description.
After using the UART the first time, the code does not need the UART data.
Detecting when another RS232 data packet (burst) occurs is all that's needed the UART data is not needed.
At the moment just the overhead of stack handling for the duration of the UART data is causing other problems.
So knowing when the data bursts start allows the code to handle some other things.... !
Once the sequence has happened, and the code actually wants to use the UART again it will enable the UART and proceed.
The goal is to reduce "stack use" which is causing problems.
Polling works, but I have had occasions when polling missed the arrival of the next data packets and that also upsets things.
Note! I only need to know start of the UART data burst, I don't need the data at that time.
I'll be getting hardware in today and will be able to code my idea.
Thanks for your suggestions. |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1329
|
|
Posted: Mon Apr 10, 2017 10:30 am |
|
|
If the issue is stack usage, then other interrupts are gonna cause the same type of issues at some point. The PCD compiler uses very minimal stack as is (unless you are doing something like printfs and floating point...which you won't be in an ISR).
You shouldn't be trying to fix the issue in this manner.
You should really just increase the stack size.
The stack usage for a normal UART interrupt vs an IOC or EXT will be really close to the same, so trying to just use another interrupt to avoid the stack usage is a bad idea long term. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19383
|
|
Posted: Mon Apr 10, 2017 1:02 pm |
|
|
Increase the stack size.
#build
The stack needs to be increased if you are using anything like complex printf statements etc..
If you enable another interrupt it'll use exactly the same amount of stack as the UART handler.
More stack will be used if you have changed the interrupt levels. |
|
![](templates/subSilver/images/spacer.gif) |
soonc
Joined: 03 Dec 2013 Posts: 215
|
Works but |
Posted: Mon Apr 17, 2017 9:27 pm |
|
|
Ttelmah wrote: | Increase the stack size.
#build
The stack needs to be increased if you are using anything like complex printf statements etc..
If you enable another interrupt it'll use exactly the same amount of stack as the UART handler.
More stack will be used if you have changed the interrupt levels. |
It's not an issue of stack size.
When the next block of data arrives the ISR gets called for every byte that arrives at the UART.
Making the ISR a "one shot" I'd hoped to avoid all the calls to the ISR which I believe are pushed/popped to/from the stack.
Anyway the idea works but it's not possible to ignore the IOC it has to be serviced and the IOC ISR disabled to avoid multiple ISR calls.
In the end I chose to Disable the UART on the first ISR call and that solved the problem as it became a one shot ISR. Later (in time) the code enables the UART when it needs it.
Thanks for all the help. |
|
![](templates/subSilver/images/spacer.gif) |
|