While this method works great for Serial3, I wanted to also control Serial0. So I started looking at the ROM. I found two functions in the ROM explicitly for controlling these signals:
0x0026d050 SerialPort0LineDriverConfig__16TVoyagerPlatformFUcT1I took a look at the assembly for these functions and found them to be pretty simple. The first parameter seems to be a boolean and the second a bitfield. I'm not exactly sure what the second parameter does, but it changes the behavior of the function when it finds the 0x20 bit set.
0x0026d094 SerialPort3LineDriverConfig__16TVoyagerPlatformFUcT1
From what I can tell, for the Port3 function, you can leave the second parameter as 0x0 and the first parameter is a bool that controls the signal. For the Port0 function, the first parameter the logical inverse of the signal you want, and the second parameter should be 0x20.
- SerialPort0LineDriverConfig(0,0) // results in Port0Sel High
- SerialPort0LineDriverConfig(1,0) // results in Port0Sel High
- SerialPort0LineDriverConfig(0,0x20) // results Port0Sel High
- SerialPort0LineDriverConfig(1,0x20) // results Port0Sel Low
- SerialPort3LineDriverConfig(0,0) // results in Port3Sel Low
- SerialPort3LineDriverConfig(1,0) // results in Port3Sel High
- SerialPort3LineDriverConfig(0,0x20) // results in Port3Sel Low
- SerialPort3LineDriverConfig(1,0x20) // results in Port3Sel Low
Incidentally, when called with the correct parameters, the assembly behind SerialPort3LineDriverConfig is virtually identical to Eckhart's code. The SerialPort0LineDriverConfig is very similar but uses as GPIO instead of DIO.