Quite an old topic, but I think this can be a solution for those who seek it, so I'm writing it (I also needed it now ):
I think your interrupt handler is broken. On SPI, the data is transferred half-duplex; which means "as you receive data, you send data". So in order to receive and send data back, you actually transfer 4 bytes, but two of them is garbage (or, simply not cared).
So, when the master sends you a command, it already receives whatever is in your USIDR register (which is most probably 0) - as in SPI, they "exchange" bytes (but master probably knows this data is garbage -- SPI library in Arduino knows it). Now, you must prepare your data at that instant and put it to USIDR, so that the master can receive it, when it sends garbage data (or any data which you won't care) and clock pulses. Note that, this "data preparation" can take some time, so master might need a delay there (between sending the command and receiving the answer). Basically,
ISR (USI_OVF_vect)
{
byte b = USIBR;
hadSpiInterrupt = true;
if(command == 0)
command = b;
switch(command)
{
// add to incoming byte, return result
case 'a':
USIDR = frq; // spit out Frquency Reading
break;
default: // this block will only work, when the master sent 'garbage' to retrieve answer
USIDR = 0; // this is not important for one byte protocol - since this data is what is being sent at 'next clock pulse' -- which is the next command for one-byte-protocol
command = 0; // we reset the command, so we can process the next one
break;
} // end of switch
} // end of interrupt service routine ISR (USI_OVF_vect)
Note that, whence the Master sent you command, you made some switch-case comparisons etc. before you put something back to USIDR (note that, not to the USIBR; because that register is just a 'buffer' (copy) register, you need to put data to USIDR, I think); so master must know 'how long to wait there'. Since clock is pulsed by the master; it's not a problem if it waits 'too long' as long as not too little. Say, it must wait 1 microseconds. After this, the master will start clock-pulsing again which will yield him whatever you put to the USIDR register - which is the response of the command. Note that we also reset command register to 0. This is true if all your commands return only one bytes. If they return more than one, you need a logic to determine this here (maybe check previous command and count the bytes sent to decide when it's over, etc. etc. etc.)
I'm sorry, I cannot test this right now but I think this is what was missing in your code. Can you try it? I'll also try it myself but I dunno when