View previous topic :: View next topic |
Author |
Message |
mgiuliani
Joined: 30 Mar 2023 Posts: 20
|
PIC24 IO state initialization built-in function issues? |
Posted: Tue Sep 24, 2024 9:26 am |
|
|
My team has devices using PIC24FJ1024GB610, and I'm using CCS C Compiler version 5.075. We have devices on occasion that will have their firmware freeze after waking up from sleep, and they look to be freezing where we are initializing all of the post-wakeup pin states using the output_a() through output_g() built-in functions. It could also be in the set_tris_a() through set_tris_g() function calls immediately after that its hanging at but not beyond that. Are there any known issues with these functions that could cause firmware to freeze? The internal WDT is the only way it recovers. These are the first function calls we make immediately after waking up:
setup_adc_ports ( sAN13 | sAN14 | sAN15 | sAN22, VSS_VDD);
setup_adc (ADC_OFF);
output_a ((A15_IS << 15) | (A14_IS << 14) | (A13_IS << 13) | (A12_IS << 12) | (A11_IS << 11) | (A10_IS << 10) | (A9_IS << 9) | (A8_IS << 8) | (A7_IS << 7) | (A6_IS << 6) | (A5_IS << 5) | (A4_IS << 4) | (A3_IS << 3) | (A2_IS << 2) | (A1_IS << 1) | A0_IS );
output_b ((B15_IS << 15) | (B14_IS << 14) | (B13_IS << 13) | (B12_IS << 12) | (B11_IS << 11) | (B10_IS << 10) | (B9_IS << 9) | (B8_IS << 8) | (B7_IS << 7) | (B6_IS << 6) | (B5_IS << 5) | (B4_IS << 4) | (B3_IS << 3) | (B2_IS << 2) | (B1_IS << 1) | B0_IS );
output_c ((C15_IS << 15) | (C14_IS << 14) | (C13_IS << 13) | (C12_IS << 12) | (C11_IS << 11) | (C10_IS << 10) | (C9_IS << 9) | (C8_IS << 8) | (C7_IS << 7) | (C6_IS << 6) | (C5_IS << 5) | (C4_IS << 4) | (C3_IS << 3) | (C2_IS << 2) | (C1_IS << 1) | C0_IS );
output_d ((D15_IS << 15) | (D14_IS << 14) | (D13_IS << 13) | (D12_IS << 12) | (D11_IS << 11) | (D10_IS << 10) | (D9_IS << 9) | (D8_IS << 8) | (D7_IS << 7) | (D6_IS << 6) | (D5_IS << 5) | (D4_IS << 4) | (D3_IS << 3) | (D2_IS << 2) | (D1_IS << 1) | D0_IS );
output_e ((E15_IS << 15) | (E14_IS << 14) | (E13_IS << 13) | (E12_IS << 12) | (E11_IS << 11) | (E10_IS << 10) | (E9_IS << 9) | (E8_IS << 8) | (E7_IS << 7) | (E6_IS << 6) | (E5_IS << 5) | (E4_IS << 4) | (E3_IS << 3) | (E2_IS << 2) | (E1_IS << 1) | E0_IS );
output_f ((F15_IS << 15) | (F14_IS << 14) | (F13_IS << 13) | (F12_IS << 12) | (F11_IS << 11) | (F10_IS << 10) | (F9_IS << 9) | (F8_IS << 8) | (F7_IS << 7) | (F6_IS << 6) | (F5_IS << 5) | (F4_IS << 4) | (F3_IS << 3) | (F2_IS << 2) | (F1_IS << 1) | F0_IS );
output_g ((G15_IS << 15) | (G14_IS << 14) | (G13_IS << 13) | (G12_IS << 12) | (G11_IS << 11) | (G10_IS << 10) | (G9_IS << 9) | (G8_IS << 8) | (G7_IS << 7) | (G6_IS << 6) | (G5_IS << 5) | (G4_IS << 4) | (G3_IS << 3) | (G2_IS << 2) | (G1_IS << 1) | G0_IS );
set_tris_a ((A15_ID << 15) | (A14_ID << 14) | (A13_ID << 13) | (A12_ID << 12) | (A11_ID << 11) | (A10_ID << 10) | (A9_ID << 9) | (A8_ID << 8) | (A7_ID << 7) | (A6_ID << 6) | (A5_ID << 5) | (A4_ID << 4) | (A3_ID << 3) | (A2_ID << 2) | (A1_ID << 1) | A0_ID );
set_tris_b ((B15_ID << 15) | (B14_ID << 14) | (B13_ID << 13) | (B12_ID << 12) | (B11_ID << 11) | (B10_ID << 10) | (B9_ID << 9) | (B8_ID << 8) | (B7_ID << 7) | (B6_ID << 6) | (B5_ID << 5) | (B4_ID << 4) | (B3_ID << 3) | (B2_ID << 2) | (B1_ID << 1) | B0_ID );
set_tris_c ((C15_ID << 15) | (C14_ID << 14) | (C13_ID << 13) | (C12_ID << 12) | (C11_ID << 11) | (C10_ID << 10) | (C9_ID << 9) | (C8_ID << 8) | (C7_ID << 7) | (C6_ID << 6) | (C5_ID << 5) | (C4_ID << 4) | (C3_ID << 3) | (C2_ID << 2) | (C1_ID << 1) | C0_ID );
set_tris_d ((D15_ID << 15) | (D14_ID << 14) | (D13_ID << 13) | (D12_ID << 12) | (D11_ID << 11) | (D10_ID << 10) | (D9_ID << 9) | (D8_ID << 8) | (D7_ID << 7) | (D6_ID << 6) | (D5_ID << 5) | (D4_ID << 4) | (D3_ID << 3) | (D2_ID << 2) | (D1_ID << 1) | D0_ID );
set_tris_e ((E15_ID << 15) | (E14_ID << 14) | (E13_ID << 13) | (E12_ID << 12) | (E11_ID << 11) | (E10_ID << 10) | (E9_ID << 9) | (E8_ID << 8) | (E7_ID << 7) | (E6_ID << 6) | (E5_ID << 5) | (E4_ID << 4) | (E3_ID << 3) | (E2_ID << 2) | (E1_ID << 1) | E0_ID );
set_tris_f ((F15_ID << 15) | (F14_ID << 14) | (F13_ID << 13) | (F12_ID << 12) | (F11_ID << 11) | (F10_ID << 10) | (F9_ID << 9) | (F8_ID << 8) | (F7_ID << 7) | (F6_ID << 6) | (F5_ID << 5) | (F4_ID << 4) | (F3_ID << 3) | (F2_ID << 2) | (F1_ID << 1) | F0_ID );
set_tris_g ((G15_ID << 15) | (G14_ID << 14) | (G13_ID << 13) | (G12_ID << 12) | (G11_ID << 11) | (G10_ID << 10) | (G9_ID << 9) | (G8_ID << 8) | (G7_ID << 7) | (G6_ID << 6) | (G5_ID << 5) | (G4_ID << 4) | (G3_ID << 3) | (G2_ID << 2) | (G1_ID << 1) | G0_ID );
We have all but ruled out hardware or application firmware design issues causing this, so we are wondering if there is a compiler issue, or maybe a silicon issue causing the hangups. The fact that this only happens on a handful of devices all with the exact same hardware, and is happening across different batches makes us think it's a silicon issue more likely but we want to check all of the boxes. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Tue Sep 24, 2024 2:06 pm |
|
|
Some thoughts. I tend not to embed bit manipulations inside other function calls with any compiler because of some painful memories from decades ago. That was the first thing that popped into my head: I'd create the port state first, then pass that on to the output_x() or set_tris_x() functions.
Second thought: have a look at the list file to ensure that there's no loops being coded in place of the above. Talking about some sort of test & jump that can get caught in a forever loop should there be some sort of issue.
Are you seeing this problem with #use fast_io(x) directives? Fast_io tells the compiler to NOT 'second guess' your TRIS settings, whereas the default could maybe be hitting a weird RMW (read modify write) problem with the ports under certain conditions?
Last thing, I'd get rid of the shifts entirely as written and go with an if based approach instead. For example,
Code: | a_pattern = 0x0000;
if (A15_IS) {
a_pattern |= 0x8000;
}
if (A14_IS) {
a_pattern |= 0x4000;
}
...
output_a(a_pattern); |
Something to try. Hopefully it makes the problem go away. I tend to try to 'lead' the compiler into making behind the scenes coding choices that are difficult to screw up because I've had to troubleshoot weird issues countless times. When I altered my style to be quite explicit, the weirdness definitely decreased....not just with the CCS compiler, but with other compilers as well.
If these alterations don't alleviate the problem then I'd be inclined to agree that it's some sort of very weird silicon issue with the processors in question. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Tue Sep 24, 2024 3:25 pm |
|
|
There really shouldn't be any ASM associated with output_X and set_tris_x that hangs up. Those don't usually poll any registers (you can check your ASM to verify though). My guess is something else is getting hung up (an interrupt for example).
If you are squirrelly enough, you can setup a timer interrupt to go off and then in the interrupt you can inspect the stack to see what line of code the interrupt is triggering off of (this sounds easier than it is...see other discussions on this forum on how to do this correctly).
I definitely doubt it is the code you have shown. Side note, please use code blocks to display code. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Wed Sep 25, 2024 1:52 am |
|
|
It could be length.
Honestly setup an int1 array union and write the bits you want into this.
Then just output the assembled value.
The compiler does have a length restriction on lines, and another on the
length of arithmetic expansions. This is such an awfully cumbersome way
of doing this operation that this might be happening.
It is awful code.
Try the maths separately into an int16 variable. Does the hang move to
this line instead of the output?. If so you have your answer. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Sep 25, 2024 5:57 am |
|
|
wow, my old eyes went FUZZY just trying to read the post !
Considering how poorly I type, I'd have 30-35 'typos' in the first line of code.
Pretty sure it'd be a good idea to NAME the bits. That way YOU will know what they control. It'll also help others now or in the future to help figure out what and why the code does what it does.
Mr. T's 'union' IS the way to go !
Code that is EASY to see, is easier to understand and a lot quicker to debug. |
|
|
mgiuliani
Joined: 30 Mar 2023 Posts: 20
|
|
Posted: Wed Sep 25, 2024 8:03 am |
|
|
Thanks for the advice everyone, I'll try cleaning up how this is written. And my bad about the code block, I forgot that's a formatting option here. To avoid soiling my good name I should mention I didn't write the code for this device, I just inherited it. This is definitely a messy way of setting the states. You'd need a therapist after seeing how most of the application code is written. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Sep 25, 2024 2:10 pm |
|
|
One of the best things YOU can do , is to add comments at the end of nearly EVERY line of code, as you go !
Might save a few hours of gazing at it 3 dayze from now wondering WHAT it's supposed to do.....BTDT 2many times ! |
|
|
|