So a new problem cropped up, same thing, variable being ignored at random. Making it "static" solves this. The variable in only used in this one C file. So why look at code anywhere else to determine it's usefulness ?
Oh my god stop this. Randomly permuting the code to see what makes it "work" according to your expectations is a recipe for disaster.
Instead, do this (this advice is specific for you, not an approach that should be taken 100% by everyone):
First: assume the compiler is correct. It's definitely true that compilers have bugs, but the vast, vast majority of problems are user errors, not compiler bugs. So get that out of your head, and also get out that the compiler is "not doing what you tell it" -- this is basically equivalent to calling it a compiler bug. The compiler always does what you tell it, often people just don't know what they are telling it. With your mindset fixed, follow this procedure:
Comment out all casts and all uses of volatile in the entire code base. Compile with -Wall -Werror. Maybe -Wextra for good measure. Keep *fixing* bugs until your code compiles -- not working around, but actually fixing. If you absolutely have to add back in a cast, write a comment about why it is correct, and ask an expert if there is a way around it. If they say yes, even if it includes changing a bunch of code, do it. volatile should *only ever* be used for hardware registers and global variables accessed by interrupt handlers. All other users should not be allowed under any circumstances. Then if you can possibly run your code with valgrind, ubsan or any other kind of memory testing. This is usually hard on embedded systems, but if you can run in an emulator or cross compile for a PC, even for parts of the code do so, and keep *fixing* bugs until those run without complaint.
Now you have code that is reasonably likely to have well defined behavior. It might not be correct, but it is code worth debugging. Code that changes behavior when you make meaningless changes is not worth debugging. My recommendation then is to now skip directly to -O2. When you find a bug, then switch back to -Og or -O0 to debug it. The reason to do this is mostly that it will be easier to understand what is going on in an interactive debugger. It doesn't matter what debugging tool you use: gdb, printf, toggling GPIO pins, or likely a combination of all three and more. What is good is that all of the work you did above will make it much less likely that random permutations of your code during debugging will cause the issue to go away. This is good: ultimately predictable systems are easy to debug and unpredictable ones difficult. What you have gained by following these steps is both made your code more predictable (in that it avoids undefined or many types of surprising behavior) and you have improved your ability to predict the C language. Starting with -O2 helps you because you never get to a situation of having a program that works with a debug build and you are afraid to turn on optimizations because it might break. In addition, if the behavior changes when you turn off optimizations, then you have already determined that either the problem is undefined behavior or a timing error. That means you are already well on your way to diagnosing and fixing it.
But the #1 piece of advice I would distill from this is: use volatile only for hardware registers and global variables used to communicate between interrupt handlers (or async signal handlers) and the main thread or other normal threads. Any other use is guaranteed incorrect.