Proprietary Knowledge Base

    Publish
     
      • Using Peripheral Reflex System to measure transition times in RAIL

        sza2 | 12/363/2017 | 06:03 PM

        There are cases when the exact TX to RX and/or RX to TX timing information is necessary to know. Obviously, it is possible to add GPIO toggle routines to the firmware code or using RAIL_GetTime() to determine transition times – however these are more or less inaccurate and additionally these have an overhead due to the extra codes.

         

        EFR32 capable to emit TX and RX active signals. By routing these signals to PRS it is possible to examine (for example by an oscilloscope) the TX and RX active periods and thus the gaps between them, the transition times. Since in case of PRS there is a hardware channel between the producer and the consumer the measurement is very accurate. More about Peripheral Reflex System is available in “AN0025: Peripheral Reflex System (PRS)”.

         

        To exploit the advantages of PRS it is necessary to include only a few lines of code to the project.

         

        The following snippet was inserted into the Simple TRX example application executed on a Flex Gecko radio board (BRD4254A) using a BRD4001 WSTK but theoretically it should run on any EFR32 device.

         

        To test how it works open the Simple TRX example, generate the radio config, add the following snippet to the code somewhere in main.c (for example after radioInit();) and compile then debug it.

        GPIO_PinModeSet(gpioPortC, 10, gpioModePushPull, 0);
        halEnablePrs(
                   9,
                   15,
                   (PRS_RAC_RX & _PRS_CH_CTRL_SOURCESEL_MASK) >> _PRS_CH_CTRL_SOURCESEL_SHIFT,
                   (PRS_RAC_RX & _PRS_CH_CTRL_SIGSEL_MASK) >> _PRS_CH_CTRL_SIGSEL_SHIFT);
        
        GPIO_PinModeSet(gpioPortC, 11, gpioModePushPull, 0);
        halEnablePrs(
                   10,
                   5,
                   (PRS_RAC_TX & _PRS_CH_CTRL_SOURCESEL_MASK) >> _PRS_CH_CTRL_SOURCESEL_SHIFT,
                   (PRS_RAC_TX & _PRS_CH_CTRL_SIGSEL_MASK) >> _PRS_CH_CTRL_SIGSEL_SHIFT);
        

        This code will route RX active signal to PC10/P12 and TX active signal to PC11/P13 pins. Connect two oscilloscope probes to these pins to examine the waveforms.

        The following screenshots show the RX→TX and TX→RX transition times:

         

         

         

         

      • Driving FEMs (and PAs and LNAs) in RAIL

        andrasbiro | 12/348/2017 | 09:19 AM

        Driving FEMs usually require some logic signals, which can be driven from software, but generally that's not fast enough (e.g. for CSMA/CA): It needs some hardware based signals.

        Since EFR32 is an integrated radio MCU, this is not handled in the radio module, but a more general purpose module: Peripheral Reflex System, or PRS for short.

        EFR32s has 12 PRS channels, each of these channels can be driven by numerous signals from various sources, and even some logic operations can be done between them. These channels can be connected to PRS consumers, so it can trigger a timer start for example.

        You can also wire PRS channels to some GPIOs, and this is the feature we'll use. For more information of PRS, see the reference manual.

        Hardware configurator does provide an "External LNA" module, but it's not supported in RAIL (as of Flex SDK 2.0). Also, it only supports one TX/RX and one sleep pin, which is probably not enough for more complicated FEMs.

        This article is stack independent, although some stacks might provide an integrated way, like the External LNA module.

        The prs signals

        Generally a FEM requires the following:

        • rx/tx switch
        • sleep
        • rx/tx bypass

        The bypass signals are usually either compile time or application time settings, so they can be driven like any other GPIO from software, or exactly the same as sleep and rx/tx, therefore it's not part of this article.

        The following PRS signals are useful for driving a FEM:

        • RAC_ACTIVE active high when radio is on (either RX or TX)
        • RAC_LNAEN active high when LNA is needed
        • RAC_PAEN active high when PA is needed

        Note that all signals can be inverted

        RAC_ACTIVE can be used to drive the sleep pin, but using (RAC_LNAEN or RAC_PAEN) is more energy efficient.

        GPIOs usable for PRS

        See the Alternate Functionality Pinout chapter or device pinout table in the datasheet. PRS channel pins has PRS_CHx functionality on it.

        The hardware configurator can be also used as a dynamic pinout diagram in Simplicity Studio (in all Flex SDK examples)

        Keep in mind that you need independent PRS channels for each signal, you can't configure a PRS channel to two locations.
        Also, logical operations limited to channels next to each other:

        • OR operation is only supported between a channel and a previous one  (i.e. channel1 = channel0 OR channel1).
        • AND operation is only supported between a channel and the next one  (i.e. channel0 = channel0 AND channel1).

        This limits the usable pins, e.g. it's recommended to drive a sleep pin as (RAC_LNAEN or RAC_PAEN), which means whatever channel you plan to use for sleep, the previous one MUST be set up to either RAC_LNAEN or RAC_PAEN. However, you can set up the same signal to multiple channels, and you don't have to drive a gpio with a channel.

        Configuring GPIOs in RAILTest

        Generally, RAILTest is recommended to test the radio's setup and performance, so energy efficiency is not a goal here. Therefor, it would be enough to just drive pins low and high, although it's a bit simpler to use the tx/rx switch from PRS.

        RAILTest only supports a few GPIOs:
        PC10, PC11, PF2, PF3, PF4, PF5, PC9, PD9, PD10, PD11, PD12

        A number of PRS signals are supported, unfortunately drive low/high and RAC_ACTIVE is not amongst them.

        The following commands can be used

        • to drive pin high (when radio is on; 32/0 81/0 is the PRS source/signal of RAC_ACTIVE):
          • On EFR32xG1: setupDebugSignal CUSTOM_PRS 32 0
          • On everything else: setupDebugSignal CUSTOM_PRS 81 0
        • to drive pin low (CUSTOM_LIB is used internally for RAIL debugging, but on the public versions of the SDK it just drives the pin low):
          • setDebugSignal CUSTOM_LIB 0
        • to drive rx/tx pin, high on rx:
          • setDebugSignal LNAEN
        • to drive rx/tx pin, high on tx:
          • setDebugSignal PAEN
        • to turn off a pin
          • setDebugSignal OFF

        E.g. to drive the LNA on the MGM12P module (sleep pin on PD10, tx/rx on PD11)

        setDebugSignal PD10 LNAEN
        setDebugSignal PD11 CUSTOM_PRS 81 0

        Configuring GPIOs in application source

        To use PRS channels, you first need to enable GPIO and PRS clock:

        CMU_ClockEnable(cmuClock_PRS, true);
        CMU_ClockEnable(cmuClock_GPIO, true);

        Set the GPIO we use to pushpull mode:

        GPIO_PinModeSet(port, pin, gpioModePushPullAlternate, 0);

        Enable PRS signal:

        PRS->CH[x].CTRL = PRS_signal | PRS_CH_CTRL_ASYNC;

        It's recommended to use async mode, since this is needed to have a working signal even in sleep states.

        Set location of the PRS signal pin:

        PRS_ROUTELOCy |= PRS_ROUTELOCy_CHxLOC_LOCz

        (the 12 PRS channels are divided into 3 ROUTELOC registers, so channel 0-3 is in ROUTELOC0, etc)

        Enable the pin:

        BUS_RegBitWrite(&PRS->ROUTEPEN, _PRS_ROUTEPEN_CHxPEN_SHIFT, 1);

        E.g. to drive the LNA on the MGM12P module (sleep pin on PD10, tx/rx on PD11):

        CMU_ClockEnable(cmuClock_GPIO, true);
        CMU_ClockEnable(cmuClock_PRS, true);
        GPIO_PinModeSet(gpioPortD, 10, gpioModePushPullAlternate, 0);
        GPIO_PinModeSet(gpioPortD, 11, gpioModePushPullAlternate, 0);
        PRS->CH[6].CTRL = PRS_RAC_ACTIVE | PRS_CH_CTRL_ASYNC;
        PRS->CH[5].CTRL = PRS_RAC_LNAEN | PRS_CH_CTRL_ASYNC;
        PRS->ROUTELOC1 |= PRS_ROUTELOC1_CH5LOC_LOC0 | PRS_ROUTELOC1_CH6LOC_LOC13;
        BUS_RegBitWrite(&PRS->ROUTEPEN, _PRS_ROUTEPEN_CH6PEN_SHIFT, 1);
        BUS_RegBitWrite(&PRS->ROUTEPEN, _PRS_ROUTEPEN_CH5PEN_SHIFT, 1);

        Invert a signal

        Inverting a signal is very simple. To create an inverted sleep signal for example (high in sleep):

        PRS->CH[x].CTRL = PRS_RAC_ACTIVE | PRS_CH_CTRL_ASYNC | PRS_CH_CTRL_INV;

        Logical operation between signals

        As above mentioned:

        • PRS channels can be OR'ed with the previous channel (i.e. channel1 = channel0 OR channel1).
        • PRS channels can be AND'ed with the next channel (i.e. channel0 = channel0 AND channel1).

        If you meet this limitation, the setup is pretty simple, just use PRS_CH_CTRL_ORPREV and PRS_CH_CTRL_ANDNEXT.

        For example the energy efficient (RAC_LNAEN | RAC_PAEN) way to drive the LNA on MGM12P:
         

        PRS->CH[5].CTRL = PRS_RAC_LNAEN | PRS_CH_CTRL_ASYNC;
        PRS->CH[6].CTRL = PRS_RAC_PAEN | PRS_CH_CTRL_ASYNC | PRS_CH_CTRL_ORPREV;

         

      • SEGGER SystemView for non-OS projects

        sza2 | 12/345/2017 | 04:59 PM

        SEGGER SystemView is a real-time recording and visualization tool. It is freely available from SEGGER’s website.

        This article describes how to setup SEGGER SystemView for a non-OS project and shows how to modify a simple Flex / RAIL example to call SEGGER SystemView routines.

        Since Simplicity Studio contains the SystemView, it is only necessary to download the "SystemView Target Sources" package from https://www.segger.com/downloads/free-utilities/#SystemView

         

        The steps below described how to add SystemView capability to an example project and how to run it:

        • Extract SystemView source files from the downloaded archive (.zip) file to an arbitrary directory
        • Open the RAIL: Simple TRX example project and click on "Generate" to let Studio to generate the necessary files
        • From the previously extracted SystemView source files / directories copy "Config" and "SEGGER" directories and "Sample\NoOS\Config\Cortex-M\ SEGGER_SYSVIEW_Config_NoOS.c" file to the project’s root directory
        • Add the copied directories to the include path of the project:

         

        • Open and edit "main.c" and add the following lines to the code:

        #include "SEGGER_SYSVIEW.h"

        SEGGER_SYSVIEW_Conf();

        SEGGER_SYSVIEW_Start();

        #include "rail_config.h"
        #include "hal_common.h"
        #include "SEGGER_SYSVIEW.h" // include SystemView header file
        
        
        // Memory manager configuration
        #define MAX_BUFFER_SIZE  256
          // Initialize Radio
          radioInit();
        
          SEGGER_SYSVIEW_Conf(); // initialize SystemView
          SEGGER_SYSVIEW_Start(); // start SystemView
        
          // Configure RAIL callbacks
          RAIL_ConfigEvents(railHandle,
                            RAIL_EVENTS_ALL,
        • Open and edit "emdrv\gpiointerrupt.c" and add the following lines to the code:

        #include "SEGGER_SYSVIEW.h"

        SEGGER_SYSVIEW_RecordEnterISR();

        SEGGER_SYSVIEW_RecordExitISR();

        Note, "gpiointerrupt.c" is a shared SDK file, when you start to edit a popup will appear:

        It is recommended to choose "Make a Copy" to keep the original file intact.

        
        void GPIO_EVEN_IRQHandler(void)
        {
          SEGGER_SYSVIEW_RecordEnterISR(); //emit Enter ISR signal
        
          uint32_t iflags;
        
          /* Get all even interrupts. */
          iflags = GPIO_IntGetEnabled() & 0x00005555;
        
          /* Clean only even interrupts. */
          GPIO_IntClear(iflags);
        
          GPIOINT_IRQDispatcher(iflags);
        
          SEGGER_SYSVIEW_RecordExitISR(); //emit Exit ISR signal
        }
        
        • Compile and run the project as usual. SystemView does not require to project to debug, it will work if the code is just running.
        • Click on the SystemView icon in Studio to start SEGGER SystemView application:

        • When SystemView started, click on the green ‘Play’ icon.

        • A configuration window pops up. Leave all setting as their default and click "OK".

        • The SystemView application starts running. Pressing PB0 pushbutton on the WSTK board will result in events recorded:

         

      • How many preamble bytes does Si446x need for antenna diversity?

        zopapp | 12/342/2017 | 09:23 AM

        Note that at the time of writing this article this information is captured incorrectly in the data sheets. The following minimum preambe length requiements are needed for packet loss free reception and no sensitivity loss compared to non antenna diversity applications (less the the insertion loss of the T/R switch and the longer traces obviously).

        When AFC is not enabled antenna diversity requires 80 bits of preamble.

        When AFC is enabled antenna diversity requires 88 bits of preamble.

        Si446x revC2A and A2A devices support antenna diversity with DSA. This operation requitres 64 bits of preamble. Note however that co-channel rejection with DSA in antenna diversity mode is poor so this configuration is not recommended.

        Leave all the antenna diversity parameter calculations to WDS. Make sure you transmit the minimum length of preamble and Rx will just work. 

      • 4GFSK Sync word

        sza2 | 12/342/2017 | 02:42 AM

        Although, the Radio Configurator supports 4FSK modulation, the sync word is 2FSK by default and in the GUI interface it is not possible change this parameter currently.

        However, 4FSK sync word option is available by editing the generated project files.

        The following steps shows how to set the sync word to 4FSK:

        • Open an example or create a new Flex 2.0 project
        • Set the required parameters in the Application Builder
        • Click on “Generate” button and allow the Simplicity Studio to generate the necessary files
        • If the generation was successful, open the project’s rail_config.h file in the project’s root directory.
        • In const uint32_t generated[] = {} configuration array find address 605C and set bit 12 to “1”
        • Save the modified file and continue with compilation as usual

        Exampe:

        const uint32_t generated[] = {
          0x01040FF0UL, (uint32_t) generated_phyInfo,
             /* 0FF4 */ 0x00000000UL,
             /* 0FF8 */ 0x0003C000UL,
             /* 0FFC */ 0x0003C00FUL,
          0x00020004UL, 0x00000000UL,
             /* 0008 */ 0x00000000UL,
          0x00020018UL, 0x0000000FUL,
             /* 001C */ 0x00000000UL,
          0x00070028UL, 0x00000000UL,
               .
               .
               .
             /* 6058 */ 0x000004CDUL,
             /* 605C */ 0x22140A04UL, /* Change this value from 0x22140A04UL to 0x22141A04UL */
             /* 6060 */ 0x504B4133UL,
          0x00037014UL, 0x000270F8UL,
             /* 7074 */ 0x00000433UL,
             /* 7078 */ 0x00552300UL,
               .
               .
               .
          0xFFFFFFFFUL,
        };
        
        Keep in mind, if tweaking rail_config.c (or other auto-generated files) manually, then changes will be overwritten on the next re-generation of files.
      • RF range factors

        zovida | 12/341/2017 | 11:16 AM

        The achievable RF range is affected by many factors as listed below. 

        - Transmit power and TX antenna gain

        - Receive sensitivity and RX antenna gain

        - Frequency: It is related to the gain and effective area of the antenna. It can simply translate into that the lower frequency the link operates at the better RF range can be achieved. 

        - Antenna radiation pattern: The best RF range can be achieved if the TX and RX antennas are facing to each other in their maximum radiation lobes. There could be some directions where the antennas' radiation patterns do have minimum notches and thus the RF range could be poor in these directions. 

        - Interference, noise: Any in-band noise does have severe negative effects on the range since it can mask out the wanted signal at the RX side (see the co-channel rejection parameter). But, stronger out-of-band noise can also degrade the RF range based on the receiver's ACS and blocking performances.  

        - Frequency offset between TX and RX: It can become more critical in narrow-band systems where the exact carrier frequencies must correctly be set. 

        - Final product placement and enclosure: The antenna performance can be affected by any material in the close proximity of the antenna and by the antenna placement. In order to avoid any de-tuning effect (and thus RF range degradation) make sure about the recommended antenna (or i.e. module) placement and clearance. 

        - Environment: Ideal case is an outdoor environment where there are no reflections (e.g. no walls, big obstacles, trees, houses) and there is a direct line-of-sight (LOS) between the TX and RX and there isn't any obstacle in the Fresnel ellipsoid too (see online calculators for the Fresnel zone/ellipsoid). Less ideal case is an urban area, or when there is no LOS between the TX and RX. The worst situation is an office indoor environment where there is typically no LOS and there are walls, obstacles and thus reflections. Propagation constant can describe the environment which is typically 2.5...3.5 in an outdoor environment with LOS between the TX and RX nodes, while can even be 4...6 in an indoor environment.  

        - Transmitter and receiver heights: This is also related whether there is any obstacle, e.g. ground, in the Fresnel ellipsoid. If so, the RF range is negatively affected. Thus, the higher the nodes are placed at the bigger RF range can be achieved.  

         

        See a related KBA link on this topic below which describes an example estimator/calculator for the RF range.

        https://www.silabs.com/community/wireless/proprietary/knowledge-base.entry.html/2017/05/02/rf_range_calculator-SYIA