1 /***************************************************************************//** 2 * @file 3 * @brief The MFM specific header file for the RAIL library. 4 ******************************************************************************* 5 * # License 6 * <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b> 7 ******************************************************************************* 8 * 9 * SPDX-License-Identifier: Zlib 10 * 11 * The licensor of this software is Silicon Laboratories Inc. 12 * 13 * This software is provided 'as-is', without any express or implied 14 * warranty. In no event will the authors be held liable for any damages 15 * arising from the use of this software. 16 * 17 * Permission is granted to anyone to use this software for any purpose, 18 * including commercial applications, and to alter it and redistribute it 19 * freely, subject to the following restrictions: 20 * 21 * 1. The origin of this software must not be misrepresented; you must not 22 * claim that you wrote the original software. If you use this software 23 * in a product, an acknowledgment in the product documentation would be 24 * appreciated but is not required. 25 * 2. Altered source versions must be plainly marked as such, and must not be 26 * misrepresented as being the original software. 27 * 3. This notice may not be removed or altered from any source distribution. 28 * 29 ******************************************************************************/ 30 31 #ifndef __RAIL_MFM_H__ 32 #define __RAIL_MFM_H__ 33 34 #include "rail_types.h" 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 /// @addtogroup MFM Multi-Level Frequency Modulation 41 /// @ingroup Protocol_Specific 42 /// @brief MFM configuration routines 43 /// Note that this feature is only supported on EFR32xG23 devices. 44 /// 45 /// This feature can be used to directly control the TX interpolation filter 46 /// input to allow for a more flexible frequency modulation scheme than the 47 /// standard MODEM. When doing this, the MFM buffer is treated as an array 48 /// of 8-bit signed data used as normalized frequency deviation to the SYNTH 49 /// frequency to directly control the interpolation filter input. 50 /// No support for frame handling, coding, nor shaping is supported. 51 /// Only compatible with FSK modulations. 52 /// 53 /// The functions in this group configure RAIL Multi-Level Frequency Modulation (MFM) 54 /// hardware acceleration features. 55 /// 56 /// To configure MFM functionality, the application must first set up 57 /// a RAIL instance with \ref RAIL_Init() and other setup functions. 58 /// Before enabling MFM, a ping-pong buffer (called buffer0 and buffer1 59 /// below) must be configured via \ref RAIL_SetMfmPingPongFifo() and 60 /// populated with the initial buffer content. 61 /// MFM is enabled by setting \ref RAIL_TxDataSource_t::TX_MFM_DATA using 62 /// \ref RAIL_ConfigData() and is activated when transmit is started by 63 /// \ref RAIL_StartTx(). Once transmitting the data in the ping-pong buffers, 64 /// RAIL will manage them so it looks like a continuous transmission to the 65 /// receiver. Every time one of the ping-ping buffers has been transmitted, 66 /// \ref RAIL_EVENT_MFM_TX_BUFFER_DONE is triggered so the application can 67 /// update the data in that buffer without the need to start/stop the 68 /// transmission. \ref RAIL_EVENT_MFM_TX_BUFFER_DONE can be enable with \ref 69 /// RAIL_ConfigEvents(). 70 /// Use \ref RAIL_StopTx() to finish transmitting. 71 /// 72 /// @code{.c} 73 /// 74 /// uint8_t txCount = 0; 75 /// 76 /// typedef struct RAIL_MFM_Config_App { 77 /// RAIL_MFM_PingPongBufferConfig_t buffer; 78 /// RAIL_StateTiming_t timings; 79 /// } RAIL_MFM_Config_App_t; 80 /// 81 /// // Main RAIL_EVENT callback 82 /// static void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events) 83 /// { 84 /// // Increment TX counter 85 /// if (events & RAIL_EVENT_MFM_BUF_DONE) { 86 /// txCount++; 87 /// return; 88 /// } 89 /// } 90 /// } 91 /// 92 /// static const RAIL_MFM_Config_App_t mfmConfig = { 93 /// .buffer = { 94 /// .pBuffer0 = (&channelHoppingBufferSpace[0]), 95 /// .pBuffer1 = (&channelHoppingBufferSpace[MFM_RAW_BUF_SZ_BYTES / 4]), 96 /// .bufferSizeWords = (MFM_RAW_BUF_SZ_BYTES / 4) 97 /// }, 98 /// .timings = { 99 /// .idleToTx = 100, 100 /// .idleToRx = 0, 101 /// .rxToTx = 0, 102 /// .txToRx = 0, 103 /// .rxSearchTimeout = 0, 104 /// .txToRxSearchTimeout = 0 105 /// }; 106 /// 107 /// RAIL_Status_t mfmInit(void) 108 /// { 109 /// // initialize MFM 110 /// uint32_t idx; 111 /// uint32_t *pDst0 = mfmConfig.pBuffer0; 112 /// uint32_t *pDst1 = mfmConfig.pBuffer1; 113 /// RAIL_Status_t status; 114 /// for (idx = 0; idx < (MFM_RAW_BUF_SZ_BYTES / 16); idx++) { 115 /// pDst0[4 * idx + 0] = 0x755A3100; 116 /// pDst1[4 * idx + 0] = 0x755A3100; 117 /// pDst0[4 * idx + 1] = 0x315A757F; 118 /// pDst1[4 * idx + 1] = 0x315A757F; 119 /// pDst0[4 * idx + 2] = 0x8BA6CF00; 120 /// pDst1[4 * idx + 2] = 0x8BA6CF00; 121 /// pDst0[4 * idx + 3] = 0xCFA68B81; 122 /// pDst1[4 * idx + 3] = 0xCFA68B81; 123 /// } 124 /// 125 /// RAIL_Status_t status; 126 /// railDataConfig.txSource = TX_MFM_DATA; 127 /// status = RAIL_SetMfmPingPongFifo(railHandle, 128 /// &(config->buffer)); 129 /// if (status != RAIL_STATUS_NO_ERROR) { 130 /// return (status); 131 /// } 132 /// 133 /// 134 /// status = RAIL_ConfigData(railHandle, &railDataConfig); 135 /// if (status != RAIL_STATUS_NO_ERROR) { 136 /// return (status); 137 /// } 138 /// 139 /// status = RAIL_SetStateTiming(railHandle, &(config->timings)); 140 /// if (status != RAIL_STATUS_NO_ERROR) { 141 /// return (status); 142 /// } 143 /// 144 /// // start transmitting 145 /// return (RAIL_StartTx(railHandle, 0, 0, &schedulerInfo)); 146 /// } 147 /// 148 /// RAIL_Status_t mfmDeInit(void) 149 /// { 150 /// RAIL_Status_t status; 151 /// status = RAIL_StopTx(railHandle, RAIL_STOP_MODES_ALL); 152 /// if (status != RAIL_STATUS_NO_ERROR) { 153 /// return (status); 154 /// } 155 /// 156 /// railDataConfig.txSource = TX_PACKET_DATA; 157 /// return (RAIL_ConfigData(railHandle, &railDataConfig)); 158 /// } 159 /// @endcode 160 /// 161 /// @{ 162 163 /** 164 * @struct RAIL_MFM_PingPongBufferConfig_t 165 * @brief A configuration structure for MFM Ping-pong buffer in RAIL. 166 */ 167 typedef struct RAIL_MFM_PingPongBufferConfig { 168 /** pointer to buffer0. Must be 32-bit aligned. */ 169 uint32_t *pBuffer0; 170 /** pointer to buffer1. Must be 32-bit aligned. */ 171 uint32_t *pBuffer1; 172 /** size of each buffer A and B in 32-bit words. */ 173 uint32_t bufferSizeWords; 174 } RAIL_MFM_PingPongBufferConfig_t; 175 176 /** 177 * Set MFM ping-pong buffer. 178 * 179 * @param[in] railHandle A handle of RAIL instance. 180 * @param[in] config A MFM ping-pong buffer configuration structure. 181 * @return A status code indicating success of the function call. 182 * 183 */ 184 RAIL_Status_t RAIL_SetMfmPingPongFifo(RAIL_Handle_t railHandle, 185 const RAIL_MFM_PingPongBufferConfig_t *config); 186 187 /** @} */ // end of MFM 188 189 #ifdef __cplusplus 190 } 191 #endif 192 193 #endif // __RAIL_MFM_H__ 194