Packeting
Packet interval
Codec2 1200bps has been selected, it needs to be fed 6 bytes every 40ms.
dPMR uses packets that are (Header (80ms) + 4* super frame(320ms) + end (20ms)) = 1.38s long! Using such long packets has the advantage that the overhead is relatively small for the payload. This also implies that the FIFO is refilled as the transmission is ongoing.
SCIP-210, Revision 3.6 §2.1.3 : Transport framing : All frames are split up in 20 byte frames, of which 13 bytes are data.
Packet size
The raw data rate of Codec2 is 1200baud. If consider that raw data will only make up 25% of the total packet interval, then we'lll need to send at least at 4800baud. The remainder of the packet interval goes up on:
- inter-packet dead time
- intra packet overhead for data link layer : preamble, sync word, CRC, ...
- intra packet overhead for transport layer (security)
If we want to adhere more or less to dPMR, we'll want to use 6.25kHz channels. 4800baud FSK needs more than 6.25kHz bandwidth, so we'll need more bits/symbol : 4(G)FSK.
This only leaves the SI4463 and AX5043 as options.
For the 1200bps, FSK and OOK are still options:
- SX1278 : FSK : 2.4kbps BR, 4.8kHz freq.dev., 7.8kHz Rx BW.
- SX1278 : OOK : 3.0kbps, 5.2kHz Rx BW.
Is there a suitable library for the SI4463?
- RadioHead library can send 4FSK data (with a suitable config file), but can't receive it.
- The #NPR New Packet Radio project is 2FSK as well as 4FSK, but it might be difficult to strip the radio code from the application. The interfacing to the SI4463 is very different from other sources. The application code seems very much interweaved with the interface to the radio.
- Zak Kemble's library was the first one I got working with 4GFSK. But it's interrupt based and many functions don't yield a return code.
- The official SiLabs WDS3 tool can create an example project. Unfortunately the header files are nearly unusable. A header file with commands is generated, which is about 3800(!) line long. Then there's also the header file listing the properties. That one is 5800(!) lines long. I spend more time finding the right "define" statement than it would have taken me to write the statement myself based on the HTML-documentation.
- The Arduino-LoRa library interface can be used as a template. It inherits from the Stream class, which will make it easier to interface it to other libraries such as PacketIO.
So I decided to merge Zak's code and the official WDS3 code into my favorite radio library : RadioLib.
Now with the library working (based on Zak Kemble's code), I noticed that sending the 10byte packes from Zak Kemble's example takes 57ms. That's measured from the end of the 0x31 START_TX command to the falling edge of IRQ that signals a PACKET_SENT. For 1200bps, we need to send 6 bytes every 40ms. If we can't get the TX-time down, we'll have to group codec2 frames in a single wireless packet. Sending 6 bytes takes 51ms (as verified with the logic analyser: time between end of START_TX and falling PACKET_SENT IRQ). This matches with the theoretical limit: 4 bytes in 6ms = 32 bit/6ms = 5.3kbps. The radio is configured for 2.4ksymbols/s (=4.8kbps for 4GFSK).
The following settings are used in Zak Kemble's library:
- Preamble : 8 bytes (sine wave) : 2.4kbps encoded, not 4.8kbps as the rest of the packet.
- Sync word : 2 bytes
- Field 1 : 1 byte (length of the packet)
- CRC-Field 1 : 2 bytes
- Field 2 : data bytes (e.g. 6 bytes)
- CRC-Field 2 : 2 bytes
So we have 15 bytes overhead for our packet. With respect to time, we even have 23 bytes overhead, because the preamble is sent out at half the bit rate. So the total packet time = (23 + N) * 8 / 4800 [s], where N is the number of data bytes.
It takes 48.3ms to send a packet with 6 data bytes. Codec2_1200 generates 6 bytes every 40ms. So Codec2 generates the packets faster than they are transmitted.
The following condition must be met:
23 = OH = overhead = the number of bytes that are sent, but are not Codec2 data. This includes preamble, sync, encryption, ...
Which can be simplified and generalized to:
The upper communication layers will generate overhead as well. Authenticated encryption adds 20 bytes to the packet. Let's provision another 20 bytes for the higher OSI-layers.
So a number of data bytes should be at least N ≥ (23+40)/3 = 21. N must be a multiple of six, because of CODEC2_1200. So N becomes 24.
- N = 4 CODEC2_1200 frames per SI4463-packet = 4 * 6 bytes = 24 bytes
- OH = 23 + 20 + 20 = 63
- 23 bytes SI4463 data link layer (preamble, sync, CRC, etc.)
- 20 bytes of security data per packet (data secrecy + integrity)
- 20 bytes provisioned overhead
- Check 1: max. packet size : 15 + 24 + 20 + 20 = 79 bytes, which is smaller than the maximum capacity of 129 bytes of the SI4463. This however, involves stitching the two internal FIFO's of the SI4463 together. By default maximum packet size is only 64 bytes.
- Set property GLOBAL_CONFIG (group 0, index 3), field FIFO_MODE.
- Use FIFO_INFO command to make the change take effect.
- Each SI4463 packet contains 4 codec2_1200 frames, so 4 * 40 ms of audio = 160ms audio. The SI4463 sends one packet per 160ms.
- Check 2: total transmission time per packet = (23+40+24)*8/4800 = 145ms, which is smaller than 160ms.
- Speech total latency will be about 200ms, which is (not) acceptable. The acceptable delay for a normal conversation is 150ms. (FYI: the acceptable delay for your own echo must be below 50ms).
The downside of adding more data bytes in a packet is that the latency will increase. We have to find an optimum.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
Hi Simon, there's no error in Zak's library that makes the message so long. The message length is simply the result of the configured parameters. The preamble could be shortened, but that might make it more difficult for the receiver to get the message. The receiver uses the preamble to synchronize itself to the transmitter.
dPMR as well as SCIP chain lots of messages together in a single stream. The receiver only needs to synchronize at the start of the stream. As a result, the overhead of the preamble becomes relatively small with regard to the payload size.
I might have to work like that as well. It's much more complicated than sending a series of small packages because the FIFO needs to be refilled as the packet is being transmitted.
Are you sure? yes | no
Thanks for the explanation - makes sense but I can see the challenges for audio.
Are you sure? yes | no
Interesting. Why do you think Zak's library takes this long and should it be possible to speed it up?
Are you sure? yes | no