jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.49k stars 377 forks source link

[RFM9x] Last Bit truncated during TX. Including possible fix. #808

Closed ramaza closed 1 year ago

ramaza commented 1 year ago

Almost similar to issue #805 I experience a problem with a Feather M0 board that uses an RFM95 radio. The former issue was with a RFM69 radio. My modulation settings are FSK with 1200Baud. I verified again with SDR equipment that the last Bit is truncated/garbled. Please have a look at the following before/after image. It shows the last few symbols of the demodulated FSK signal and the very last symbol is colored. The last symbol doesn't even have half of it's regular symbol duration.

rfm95_last_symbol_truncated

I assume that the reason for this problem is aggressive clearing of IRQ-Flags. Not clearing IRQ-Flags in the finishTransmit() method solves the problem. The culprit could be RADIOLIB_SX127X_FLAG_FIFO_OVERRUN because according to the datasheet it clears FIFO buffer when this flag is set. Theoretically at that point in time the TX process is finished and the content of the buffer can anyway be abandonded. So far I tracked down the problem to some interrupt clearing behavior but I'm still investigating.

jgromes commented 1 year ago

Interesting - maybe the clearIRQFlags method could be modified with a uint16_t flags argument controlling which flags should be cleared, and the FIFO overrun flag could be unset when calling clearIRQFlags in finishTransmit. I'm guessing that at that point, the flag should not be set anyway. Or maybe a simpler solution would be to wait for a short period in finishTransmit before clearing all flags.

ramaza commented 1 year ago

If the following line within clearIRQFlags is changed from

this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2, 0b11111111);

to

this->mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2, 0b11101111);

the Problem is gone. Which confirms that setting RADIOLIB_SX127X_FLAG_FIFO_OVERRUN flag (too early) is the culprit.

Unfortunately I'm not in a good position to suggest a clean solution because I'm still getting familiar with the do's and don'ts of working with Semtech/HopeRF radios. Nonetheless I can see in the code that clearIRQFlags is anyway called before TX and RX opmode is activated in the radio so maybe it's good enough to resign from manipulating interrupts within finishTransmit and leave everything else as it is.

jgromes commented 1 year ago

I was able to reproduce this behavior (the top signal in the image below). Indeed, clearing the mentioned bit does cause strange mangling of the last bit, as it's duration obviously isn't a multiple of the 1200 baud bit rate (833 us - highlighted in blue).

In the second signal, it can be seen that not clearing the interrupt flag does indeed fix the issue, as the final bit is a multiple of 833 us. However, I would prefer a different solution - delaying the flag clearing by at least one bit duration. This is shown in the last signal, all IRQ flags are cleared, but only after waiting 833 us after entering the startTransmit method.

I pushed this fix in the latest commit, so the issue should be fixed without changing IRQ clearing functionality.

BTW which software did you use to record the signals you posted?

Screenshot_60

ramaza commented 1 year ago

Thanks for fixing this so fast. Oh, and there is a small mistake in your comment text. You meant to say finishTransmit instead of startTransmit.

My screnshot is from a custom SDR tool I hacked together with the great LuaRadio project and an RTL-SDR receiver. I call it "great" because it helped me a lot to learn SDR processing despite the fact that GNU Radio is way more popular and powerful.

From your screenshot I could identify URH (Universal Radio Hacker) as another powerful tool I didn't know. It seems to do exactely what my goal was with my custom tool and much more.

jgromes commented 1 year ago

Thanks for fixing this so fast. Oh, and there is a small mistake in your comment text. You meant to say finishTransmit instead of startTransmit.

Oops, sorry, yes that's exactly what I meant.

You're correct, it's URH. I use it mainly because it's quite easy and fast for debugging stuff in RadioLib.