Read RAW minimum pulse width?

Is there a minimum pulse width for reading signals? Most subghz signals I’ve encountered have pulses greater than 100 microseconds. I have been unable to get a good capture of signals less than 50 microseconds, though.

Right now I’m working on decoding the Encoder Reader Transmitter (ERT) Automatic Meter Reading (AMR) signal which has pulse widths of 30 microseconds.
It is OOK and the default AM270 and AM650 didn’t work. I suspected that was because the CC1101 data rate configuration on those profiles was too low so I created custom profiles with the setting_user file with data rates over 100kbps and still can’t capture pulses less than 50 us. Interestingly I am able to transmit 30 us pulses.

The CC1101 says it can go up to 600kbps which should be plenty fast for this signal. Is there something else in the Flipper implementation limiting my read raw capture resolution (or am I just doing something wrong)?

1 Like

Without digging the datasheet, I suppose this is only valid for packet mode.
Do you own some SDR?

Yes, I own a RTL-SDR. It is receive only so I was able to use it to verify that the Flipper Zero is capable of transmitting 30us pulses. I can also use it to receive the ERT signal from my power meter and verify that it is 30us pulses. I’ve recorded with the SDR and the Flipper at the same time. The SDR captures 30us pulses for about 5ms. The Flipper captures pulses between 54us and 100us within the same 5ms burst.
I wish I had another flipper or a transmit capable SDR to test pulses of different widths to see where the Flipper fails. I also wonder if the signal I’m capturing is too weak or too noisy and something in the AGC is messing up my capture.

I just tried using a raspberry pi as a transmitter to test the flipper. I used rpitx/sendook to send 30us pulses and record them on the RTL-SDR and the Flipper. The RTL-SDR captured the correct pulse width. The Flipper didn’t. If I increased the pulses to 300us, the Flipper could capture the pulses. I think the Flipper is not configured to capture this short of pulse. I think that the hardware should be capable, but I haven’t figured out how to get the configuration to work.

Pretty plausible. We already know of a problem with kinetic doorbells, leading to Flipper not recording them properly and attributed to that.

I have confirmed that it isn’t the noise or AGC by transmitting a different 30us pulse signal. I suspect that there is a limitation of the asynchronous serial mode that Flipper Zero uses to communicate with the CC1101. I can’t find any information on serial data rate the Flipper uses, but the CC1101 documentation says “The CC1101 modulator samples the level of the asynchronous input 8 times faster than the programmed data rate. The timing requirement for the asynchronous stream is that the error in the bit period must be less than one eighth of the programmed data rate.” That isn’t exactly clear, but I think it might mean that if I want to collect a 30us bit (33.333 kbaud) I need to configure the data rate 8 times faster at 250 kbaud (which is the max for OOK). Unfortunately, I suspect that the Flipper Zero serial communication is only 115.2 kbaud so it is missing much of the data the CC1101 is sending. This is my current speculation/theory - I could be entirely wrong on why it is happening, but the end result is that I can’t capture pulses shorter than about 60 or 70 us.

I suspect that the way to capture a 30us signal with the CC1101 is to use synchronous mode. I’ve tried configuring the CC1101 registers for synchronous mode using the setting_user file, but that hasn’t worked yet and I’m not sure if the flipper zero supports that mode.

Continuing to read Flipper documentation. “Flipper Zero’s SPI interface can read data at almost 400 KB per second” - if that is the case, I have no clue why I can’t receive asynchronous data above about 16 kbaud.

I suspect that the SPI communication with the CC1101 can go up to 400KBps, but the data that is received from the CC1101 on GDO0 must be at a slower data rate. I think that the CC1101 is sending at the data rate configured in the registers, but the isn’t receiving that fast.

I ran a bunch of tests with a custom preset where the flipper CC1101 was configured for 115kbaud data rate. Each test transmitted a sequence of 15 on off pulses and repeated it 100 times.
With pulse widths of 60us it received almost all pulses with the correct widths and gaps (but occasionally missed one pulse).
Pulse widths of 50us and 55us would catch the first pulse and then miss the rest in each burst.
Pulse widths of 40us and 45us would interpret large runs of pulses as a single pulse followed by missing a long run of pulses and interpretting as a long gap.
Pulse width of 30us would interpret an entire long run of pulses as a single pulse.

I think with the right test I can reverse engineer the GDO0 sample rate, but I’m hoping someone else knows what it is. More importantly, does anyone know how to change it?

I might have figured out where the 60us pulse width limitation comes from.

The system clock is 4MHz (based on this line from system_stm32wbxx.c):
uint32_t SystemCoreClock = 4000000UL; /CPU1: M4 on MSI clock after startup (4MHz)/

That clock is divided by a prescaler of 63 and then divided again by 4 in the furi_hal_subghz_start_async_rx function of furi_hal_subghz.c. That results in a clock speed of 15.873kHz or a period of 63us.

// Timer: base
LL_TIM_InitTypeDef TIM_InitStruct = {0};
TIM_InitStruct.Prescaler = 64 - 1;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 0x7FFFFFFE;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4; // Clock division for capture filter
LL_TIM_Init(TIM2, &TIM_InitStruct);

The opposite way round. RF is sampled at 8x data rate, but that’s due to Shannon. You should simply use the data rate of signal.

It doesn’t natively, for the reason you already outlined.

Good discovery. I wonder what will break if prescaling is reduced.

Thanks for the feedback.
I also found that there was a “short duration filter setting” added in the release notes for version 0.77.1. One of the comments added in the furi_hal_subghz_start_async_rx function of furi_hal_subghz.c says // Capture filter: 1/(64000000/64/4/32*8) = 16us. So it seems like someone may have already addressed this problem, but I don’t know how to use that setting.

Here’s the commit from that change. This code is still in the latest firmware version, but I don’t know how to use it to capture 16us pulses.

I think you should ask the one who wrote this code, @SkorP.