This is a library for the Silicon Labs Si4463 wireless IC, which has been used in (or will be used in) some of my projects. The Si4463 offers various configuration options, including modulation, data packet format, and CRC algorithm, and can output up to +20dBm (100mW) of power. Additionally, the Si4463 is also used in many pre-made modules, such as the HopeRF RFM26W and the Dorji_Com DRF4463F. The entire Si446x transceiver series should also be compatible with this library.
This library allows users to configure the chip to send and receive variable-length data packets (up to 128 bytes) and trigger callback functions when events occur (such as receiving new data packets and completing data packet transmission). These callback functions run directly from the interrupt routine, making the program’s response to events much faster than with polling libraries.
Download from GitHub
Documentation
Pinout
Si4463 | ATmega328 | Arduino Uno | Arduino Mega | Description |
---|---|---|---|---|
VCC | 3.3V | 3.3V | 3.3V | Power (3.3V) |
GPIO0 | – | – | – | – |
GPIO1 | – | – | – | – |
SDO | B4 (18) | 12 | 50 | SPI MISO |
SDI | B3 (17) | 11 | 51 | SPI MOSI |
SCLK | B5 (19) | 13 | 52 | SPI SCK |
NSEL | B2 (16) | 10 | 10 | SPI SS |
NIRQ | D2 (4) | 2 | 2 | Interrupt |
SDN | D5 (11) | 5 | 5 | Shutdown/reset High = on, Low = off |
GND | GND | GND | GND | Ground |
The Si4463 is not 5V compatible, you’ll need to do some level conversion to bring the 5V IO voltage down to 3.3V.
Callbacks
This library uses an event-based callback mechanism. When an event occurs, the callback function runs from the interrupt routine. Therefore, please ensure that any global variables used in the callback function are declared as “volatile”, to avoid data inconsistencies, just like in normal ISR handling. If the microcontroller is currently in sleep mode, these events will wake it up. Additionally, you can use the Si446x_setupCallback() function to set up the callback function and the Si446x_setupWUT() function to enable or disable certain callbacks.
Event | Callback | Default setting |
---|---|---|
New packet incoming | SI446X_CB_RXBEGIN | Off |
Valid packet received | SI446X_CB_RXCOMPLETE | Always enabled |
Invalid packet received | SI446X_CB_RXINVALID | Always enabled |
Transmission of packet complete | SI446X_CB_SENT | Off |
Wakeup timer expired | SI446X_CB_WUT | Off |
Supply voltage below threshold | SI446X_CB_LOWBATT | Off |
Wakeup timer (WUT)
The SI4463 can be configured to use a wake-up timer (WUT) to periodically wake up the device. When the wake-up timer is active and the radio is in sleep mode, the SI4463 consumes only a very low 900nA current. When the WUT expires, the SI446X_CB_WUT
callback function will be executed. Additionally, the low battery detector uses the wake-up timer to initiate power voltage measurement. If the power voltage is lower than the set threshold, the Si446x_setLowBatt()
callback function will be executed, notifying the system of a low battery condition.
Calculating the correct mantissa (M) and exponent (R) values for the WUT can be a little difficult so here’s a calculator:
WUT Calculator | |
---|---|
Interval (seconds) | |
R | |
M | |
Resolution | |
Actual interval | |
- |
Compatible chips/modules
Device | Tested |
---|---|
Si4460 | Not tested |
Si4461 | Not tested |
Si4463 | Works |
Si4467 | Not tested |
Si4468 | Not tested |
HopeRF RFM26W | Works |
Dorji_Com DRF4463F | Works |
Radio configuration
Wireless configuration is quite complex. You can use the Wireless Development Suite (WDS) to create different configuration header files:
- Open WDS (it may take some time to load, or try clicking the center logo).
- Select “Simulate Broadcast”.
- Scroll down and select “Si4463”.
- Ensure the revision version is set to “C2”.
- Click the “Select Single” button.
- Select “Wireless Configuration Application”.
- Click the “Select Application” button.
- Click “Open” (top-right corner) and select the config_normal.xml file from the GitHub repository.
Avoid changing the following areas:
- Data Packet Options tab: Do not change any settings in this tab.
- Interrupt Options tab: Do not change any settings in this tab.
- GPIO and FRR tabs: If your module uses different pins for RF TX/RX switching, only change GPIO 2 and 3. Do not change NIRQ and SDO.
Generate a new header file with the updated configuration:
- Click “Generate Source” (bottom-right corner).
- Select “Save Custom Wireless Configuration Header File”.
- Save the file to a location.
The generated configuration file is not usable yet, as WDS lacks some options. A Perl script (and its Windows .exe version) is provided in the GitHub repository to fix this issue. The script reads the radio_config_Si4463.h file and outputs to radio_config.h. You can use the Windows .exe by dragging the input header file to the top of the exe, which will output to radio_config.h.
Manual Configuration Header Fix:
- Delete all “#include” lines (usually only one line around line 41).
- In the ‘RF_POWER_UP’ definition, change the second value from 0x81 to 0x01 (normal startup, no patch required).
- In the ‘RF_GLOBAL_CONFIG_1’ definition, change the fifth value (GLOBAL_CONFIG) from 0x20 to 0x30 (set FIFO to single 129-byte mode).
- In the ‘RF_PKT_RX_THRESHOLD_12’ definition, change the last value (PKT_FIELD_2_LENGTH_7_0) from 0x3F to 0x80 (set maximum data packet length to 128).
- Delete the “SI446X_PATCH_CMDS” and “RF_GLOBAL_CONFIG_1_1” lines from the “RADIO_CONFIGURATION_DATA_ARRAY” definition.
GPIO
The Si4463 has 4 GPIO pins (numbered 0 to 3), which can be configured in various ways. Most pre-made modules use 2 GPIO pins to control the RF TX/RX switching. By default, the library configures GPIO2=HIGH on receive and GPIO3=HIGH on transmit, which is suitable for RFM26W and DRF4463F. Most other modules use the same configuration, but it’s essential to check.
Library Coding Tips
- When the radio enters sleep mode,
Si446x_sleep()
will automatically wake up when its SPI select line is set to active. After SPI communication is complete,Si446x_sleep()
must be called again to re-enter sleep mode. Si446x_setupWUT()
requires 300us to complete if WUT was previously disabled.
Range Testing
Using the config_longrange_500 configuration from the GitHub repo, I successfully received valid data packets at a distance of 2.2 km (1.37 miles) and invalid data packets at 3.79 km (2.36 miles) in a relatively flat rural area. This was achieved using a 3dBi antenna, not the one usually provided with the wireless module.