My Arduino arrived today. After a bit of poking and prodding (and failing to read the mode switch with an interrupt, possibly due to switch bouncing)... it works!

The code below expects an SPDT switch connected to pins D10 (pulled high by the Nano), D11 (wiping contact) and D12 (pulled low). This is used as a mode selector, with the Nano's LED indicating the mode; off for 87/89 IV, on for 187/189 mode (and presumably 287/289 as well). Of course you could do it with the switch connected to Vcc, D11 and Ground, but doing it with D10 and D12 allows a three-pin toggle switch to directly mount to the board.
In 87/89 IV mode it uses Frenky's interrupts. In 187/189 mode it disables the interrupts and uses my quick-and-dirty loop which just keeps reading the Tx and IrTx inputs and copying them to the IrRx and Rx outputs. The two modes can be switched at any time, no need to reset the Arduino.
#include "DigitalIO.h"
const uint8_t interruptPinIrRx = 3;
const uint8_t interruptPinRX = 2;
const uint8_t PINIrTx = 7;
const uint8_t PINSerialTX = 1;
const uint8_t ModeSelHigh = 10;
const uint8_t ModeSel = 11;
const uint8_t ModeSelLow = 12;
const uint8_t LED = 13;
void setup() {
fastPinMode(LED, OUTPUT); //Mode indicator LED
fastPinMode(ModeSelHigh, OUTPUT); //High side of mode selector switch
fastDigitalWrite(ModeSelHigh, HIGH); //Keep high
fastPinMode(ModeSelLow, OUTPUT); //High side of mode selector switch
fastDigitalWrite(ModeSelLow, LOW); //Keep low
pinMode(ModeSel, INPUT);
fastPinMode(PINSerialTX, OUTPUT);
fastDigitalWrite(PINSerialTX, HIGH);
pinMode(interruptPinIrRx, INPUT_PULLUP);
fastPinMode(PINIrTx, OUTPUT);
pinMode(interruptPinRX, INPUT_PULLUP);
}
void IrDA_RX() { //Receive IrDA from Fluke 8xIV
fastDigitalWrite(PINSerialTX, LOW);
delayMicroseconds(105);
fastDigitalToggle(PINSerialTX);
}
void IrDA_TX() { //Transmit IrDA to Fluke 8xIV
delayMicroseconds(46);
while (digitalRead(interruptPinRX)==LOW){
fastDigitalWrite(PINIrTx, HIGH);
delayMicroseconds(20);
fastDigitalToggle(PINIrTx);
delayMicroseconds(85);
}
}
void loop() {
if (digitalRead(ModeSel) == 0)
{ //Switch is off, select 87IV/89IV (IrDA) mode
attachInterrupt(digitalPinToInterrupt(interruptPinIrRx), IrDA_RX, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPinRX), IrDA_TX, FALLING);
fastDigitalWrite(LED, LOW); //Turn off mode LED
while (digitalRead(ModeSel) == 0)
{
}
}
if (digitalRead(ModeSel) == 1)
{ //Switch is on, select 187/189/287/289 (IR passthrough) mode
detachInterrupt(digitalPinToInterrupt(interruptPinIrRx));
detachInterrupt(digitalPinToInterrupt(interruptPinRX));
fastDigitalWrite(LED, HIGH); //Turn on mode LED
while (digitalRead(ModeSel) == 1)
{
fastDigitalWrite(PINSerialTX, digitalRead(interruptPinIrRx));
fastDigitalWrite(PINIrTx, 1-digitalRead(interruptPinRX));
}
}
}
I just need to tidy it up a bit now.