Multi-Level Frequency Modulation#
MFM configuration routines Note that this feature is only supported on EFR32xG23 devices.
This feature can be used to directly control the TX interpolation filter input to allow for a more flexible frequency modulation scheme than the standard MODEM. When doing this, the MFM buffer is treated as an array of 8-bit signed data used as normalized frequency deviation to the SYNTH frequency to directly control the interpolation filter input. No support for frame handling, coding, nor shaping is supported. Only compatible with FSK modulations.
The functions in this group configure RAIL Multi-Level Frequency Modulation (MFM) hardware acceleration features.
To configure MFM functionality, the application must first set up a RAIL instance with RAIL_Init() and other setup functions. Before enabling MFM, a ping-pong buffer (called buffer0 and buffer1 below) must be configured via RAIL_SetMfmPingPongFifo() and populated with the initial buffer content. MFM is enabled by setting RAIL_TxDataSource_t::TX_MFM_DATA using RAIL_ConfigData() and is activated when transmit is started by RAIL_StartTx(). Once transmitting the data in the ping-pong buffers, RAIL will manage them so it looks like a continuous transmission to the receiver. Every time one of the ping-ping buffers has been transmitted, RAIL_EVENT_MFM_TX_BUFFER_DONE is triggered so the application can update the data in that buffer without the need to start/stop the transmission. RAIL_EVENT_MFM_TX_BUFFER_DONE can be enable with RAIL_ConfigEvents(). Use RAIL_StopTx() to finish transmitting.
uint8_t txCount = 0;
typedef struct RAIL_MFM_Config_App {
RAIL_MFM_PingPongBufferConfig_t buffer;
RAIL_StateTiming_t timings;
} RAIL_MFM_Config_App_t;
// Main RAIL_EVENT callback
static void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events)
{
// Increment TX counter
if (events & RAIL_EVENT_MFM_BUF_DONE) {
txCount++;
return;
}
}
}
static const RAIL_MFM_Config_App_t mfmConfig = {
.buffer = {
.pBuffer0 = (&channelHoppingBufferSpace[0]),
.pBuffer1 = (&channelHoppingBufferSpace[MFM_RAW_BUF_SZ_BYTES / 4]),
.bufferSizeWords = (MFM_RAW_BUF_SZ_BYTES / 4)
},
.timings = {
.idleToTx = 100,
.idleToRx = 0,
.rxToTx = 0,
.txToRx = 0,
.rxSearchTimeout = 0,
.txToRxSearchTimeout = 0
};
RAIL_Status_t mfmInit(void)
{
// initialize MFM
uint32_t idx;
uint32_t *pDst0 = mfmConfig.pBuffer0;
uint32_t *pDst1 = mfmConfig.pBuffer1;
RAIL_Status_t status;
for (idx = 0; idx < (MFM_RAW_BUF_SZ_BYTES / 16); idx++) {
pDst0[4 * idx + 0] = 0x755A3100;
pDst1[4 * idx + 0] = 0x755A3100;
pDst0[4 * idx + 1] = 0x315A757F;
pDst1[4 * idx + 1] = 0x315A757F;
pDst0[4 * idx + 2] = 0x8BA6CF00;
pDst1[4 * idx + 2] = 0x8BA6CF00;
pDst0[4 * idx + 3] = 0xCFA68B81;
pDst1[4 * idx + 3] = 0xCFA68B81;
}
RAIL_Status_t status;
railDataConfig.txSource = TX_MFM_DATA;
status = RAIL_SetMfmPingPongFifo(railHandle,
&(config->buffer));
if (status != RAIL_STATUS_NO_ERROR) {
return (status);
}
status = RAIL_ConfigData(railHandle, &railDataConfig);
if (status != RAIL_STATUS_NO_ERROR) {
return (status);
}
status = RAIL_SetStateTiming(railHandle, &(config->timings));
if (status != RAIL_STATUS_NO_ERROR) {
return (status);
}
// start transmitting
return (RAIL_StartTx(railHandle, 0, 0, &schedulerInfo));
}
RAIL_Status_t mfmDeInit(void)
{
RAIL_Status_t status;
status = RAIL_StopTx(railHandle, RAIL_STOP_MODES_ALL);
if (status != RAIL_STATUS_NO_ERROR) {
return (status);
}
railDataConfig.txSource = TX_PACKET_DATA;
return (RAIL_ConfigData(railHandle, &railDataConfig));
}
Modules#
RAIL_MFM_PingPongBufferConfig_t
Functions#
Set MFM ping-pong buffer.
Function Documentation#
RAIL_SetMfmPingPongFifo#
RAIL_Status_t RAIL_SetMfmPingPongFifo (RAIL_Handle_t railHandle, const RAIL_MFM_PingPongBufferConfig_t * config)
Set MFM ping-pong buffer.
[in] | railHandle | A handle of RAIL instance. |
[in] | config | A MFM ping-pong buffer configuration structure. |
Returns
A status code indicating success of the function call.
184
of file common/rail_mfm.h