Casting pointers to volatile memory to pointers to regular memory is permitted,
but using those pointers to access the memory results in undefined behavior.
This commit changes the casts to no longer drop the volatile qualifier.
References: https://en.cppreference.com/w/c/language/volatile
gcc 9 started complaining about type mismatches:
1. all int sized return types are expected to be
"unsigned int" instead of e.g., "uint32_t"
2. all arguments are expected to be passed as (volatile)
void * pointers
This commit fixes 1. by doing ifdef'ed typedefs for I2 and I4, an fixes
2. by using void pointers, then casting within the template bodies.