The API provides functions to dynamically add, update, and remove component carriers, and to manage the CCID sequence. These are described below.
Updates to the RACH channels and component carrier configuration are
typically performed using immediate triggers or single-shot triggers. Single-shot should
be used to give precise control of the RACH-UPDATE timing. When using a single shot
trigger for RACH UPDATE, it must be triggered by the TUSER
bus on band 0. However, this is not recommended if more than one
band is configured.
Synchronization of the radio frame timing is typically performed using
continuous triggers based on a bit of the TUSER
bus. A
FrameInit
trigger is provided for each band,
allowing the framing on each band to be aligned independently. This allows the frame to
be aligned precisely to a particular sample.
The DFE PRACH core uses two triggers to align the update with the frame boundary. Once the core has been activated, the register interface is used to load a new configuration into the register map. The new configuration must be loaded across all bands. Any channels that are not changing must be reloaded with the same configuration as they are already running.
Once the configuration is fully loaded, the RACH_UPDATE trigger must be
fired. The trigger can either be immediate or triggered off of a TUSER
bit of band 0 with a single-shot trigger. Triggering
the RACH update will enable the new configuration internally, but it will not be adopted
until the FRAME_INIT trigger.
To adopt the new configuration, the FRAME_INIT trigger should be fired (using TUSER bit). The FRAME_INIT trigger marks the last bit of the radio frame and is necessary to align the internal scheduling. It must be aligned on the clock cycle preceding the first cycle of the CCID sequence of its band, as shown in the following figure.
Following a RACH update, the FRAME_INIT triggers for every band must be fired (aligned with that band's frame boundary) to maintain continuity of the configuration for that band. This will not disrupt any already configured captures that have not changed during the Configuration Update.
The following figure shows how the two triggers are used to perform an update to the CC configuration and RACH channel configuration. Note that a RACH_UPDATE is required every time the core has to accept a new configuration. Also, note that each RACH_UPDATE must be followed by a FRAME_INIT on each active band.
The RACH_UPDATE and the FRAME_INIT triggers should conform to the following figure regarding their relative timing:
You can see that in order to perform an update in the next frame, the RACH_UPDATE must arrive no earlier than the FRAME_INIT for the current frame and no later than the last subframe in the current frame. This is to ensure the RACH update is associated with the correct FRAME_INIT and that there is sufficient time to program the PRACH core prior to the FRAME_INIT. The timing of the RACH_UPDATE can be set using a single-shot trigger.
The API provides functions which can allow simultaneous updates to multiple component carriers and RACH channels using a single trigger, and functions that are intended to operate on one carrier at a time. This section will cover the simultaneous functions. The single carrier functions are covered in Making Single Channel Updates.
After the core has been activated, software should assemble the
configuration objects that are needed by the API. Two structures are required a
component carrier configuration and a RACH channel configuration. An XDfePrach_CCCfg
structure is declared to hold the details
of the core's component carrier configuration. An XDfePrach_RCCfg
structure is also declared to hold the details of the
core's RACH channel configuration. These structures can be populated either with the
configuration currently in effect or with an empty configuration setup. In both cases,
the current state of the core is unaffected and all data processing continues
uninterrupted.
The API provides functions which operate on the configuration structures to add, remove, or update component carriers, to enable and disable antennas, and to add, remove or update RACH channels. When all changes to the configuration structures are complete, they are scheduled to be put into effect by a final API call.
The initial component carrier configuration structure is declared and populated with code similar to the following.
/* Declare CC configuration structure */
XDfePrach_CCCfg CCConfig;
/* Retrieve the current CC configuration parameters */
XDfePrach_GetCurrentCCCfg(InstancePtr, &CCConfig);
To start from a blank CC configuration instead of the current
configuration, use the function XDfePrach_GetEmptyCCCfg
instead of XDfePrach_GetCurrentCCCfg
. The arguments and
syntax are identical for the two calls. An empty configuration is initialized to 0, and
therefore has no active component carriers.
The XDfePrach_CCCfg
structure is
capable of storing the component carrier configuration for up to three bands. All active
bands must be programmed and sent to the core at the same time whenever there is any
update to the CC configuration on any band.
To add a component carrier to the configuration, use the XDfePrach_AddCCtoCCCfg
function or the XDfePrach_AddCCtoCCCfgMB
function. The arguments to both
of these functions define the CCID value, the sub-carrier spacing for the CC, and a
bitmap representing the position of this component carrier's samples within the CCID
sequence. Additionally the XDfePrach_AddCCtoCCCfgMB
function has a BandId
argument which specifies the
band that the CC is being added to. The XDfePrach_AddCCtoCCCfg
function operates on band 0 only.
These functions allow the complete CC Sequence structure to be assembled across all three bands prior to sending them over the AXI4 register interface.
To remove a component carrier from the configuration, use XDfePrach_RemoveCCfromCCCfg
or XDfePrach_RemoveCCfromCCCfgMB
XDfePrach_CarrierCfg CarrierCfg;
u32 BitSequence;
u32 CCID;
u32 result;
CarrierCfg.SCS = 0; // Spacing = 2^x * 15 kHz, so x=1 -> 15 kHz SCS
BitSequence = 0x5555; // CC will occupy every other timeslot, starting with the first
CCID = 0; // CCID number chosen for the new carrier
/* Add the component carrier to the configuration for band 0 */
result = XDfePrach_AddCCtoCCCfg(InstancePtr, &CCConfig, CCID, BitSequence, &CarrierCfg);
/* Add the same component carrier to the configuration for band 1 */
result = XDfePrach_AddCCtoCCCfgMB(InstancePtr, &CCConfig, CCID, BitSequence, &CarrierCfg, 1);
/* Remove CCID 9 from the configuration for Band 0 */
XDfePrach_RemoveCCfromCCCfgMB(InstancePtr, &CCConfig, 9, 0);
When defining multiple CCs, ensure that the bit sequence values do not overlap. For example, to create one 122.88 MSPS CC and three 30.72 MSPS CCs, a valid set of bit sequences could be:
u32 BitSeq0_122p88 = 0x5555;
u32 BitSeq1_30p72 = 0x0202;
u32 BitSeq2_30p72 = 0x0808;
u32 BitSeq3_30p72 = 0x2020;
assert (BitSeq0_122p88 & BitSeq1_30p72 & BitSeq2_30p72 & BitSeq3_30p72 == 0);
s_axis_din0_tid
, s_axis_din1_tid
, and s_axis_din2_tid
. If
it does not match, the core records a CC sequence error for the failing band. This
condition can be detected using the following
code:XDfePrach_StatusMask status = { 0 };
XDfePrach_GetEventStatus(InstancePtr, &status);
if (status.CCSequenceError[0] != 0 || status.CCSequenceError[1] != 0 || status.CCSequenceError[2] != 0)
printf("A CC sequence error occured!\n");
The CC parameters for an existing component carrier can be updated within
the configuration using XDfePrach_UpdateCCinCCCfg
or
XDfePrach_UpdateCCinCCCfgMB
. It is also possible
to retrieve the parameters for an existing component carrier using XDfePrach_GetCarrierCfg
or XDfePrach_GetCarrierCfgMB
. The following code shows how the these
functions can be used.
/* Retrieve the carrier configuration for CCID 3, band 0 or single band configuration*/
XDfePrach_GetCarrierCfg(InstancePtr, &CCConfig, 3, &BitSequence, &CarrierCfg);
/* Update the SCS for CCID 3 */
CarrierCfg.SCS = 2; // 60 kHz SCS
XDfePrach_UpdateCCinCCCfg(InstancePtr, &CCConfig, 3, &CarrierCfg);
/*Replicate the same Configuration in Band 2*/
XDfePrach_UpdateCCinCCCfgMB(InstancePtr, &CCConfig, 3, &CarrierCfg,2);
The RACH channel configuration contains the settings for all 16 PRACH
channels that the core provides. The 16 PRACH resources are shared across all of the
active bands. The XDfePrach_RCCfg
structure defines
the NCO configuration for a RACH channel, the Decimation settings for the RACH channel's
DDC, the Component Carrier and band from which the PRACH capture will be taken and the
location of the PRACH capture within the Radio Frame.
When using Dynamic modes, some of the values in XDfePrach_RCCfg
become redundant because their registers become read only
and they are set by the s_axis_sched
interface. The
redundant fields are ignored and there is no requirement to adjust any function
calls.
The initial RACH channel configuration structure is declared and populated with code similar to the following.
/* Declare RACH configuration structure */
XDfePrach_RCCfg RCConfig;
/* Retrieve the current RACH configuration parameters */
XDfePrach_GetCurrentRCCfg(InstancePtr, &RCConfig);
To add a RACH channel to the configuration, use the XDfePrach_AddRCtoRCCfg
function for single band and the
XDfePrach_AddRCtoRCCfgMB
function for multiple
bands. These function takes as arguments: the DDC configuration, the NCO configuration,
the scheduling information which defines where the capture is located within the radio
frame(s), the RCID number of the channel being loaded, the physical channel that the
RCID will run on, and the component carrier configuration associated with this XDfePrach_RCCfg
. The function also requires an argument
which defines which CC the PRACH capture will be taken from. In the XDfePrach_AddRCtoRCCfg
function, this is a CCID, which is
implicitly taken from Band 0. The CCID must correspond to a CCID which has been enabled
in XDfePrach_CCCfg
. In XDfePrach_AddRCtoRCCfgMB
a BandId
argument is included which defines the Band that the CCID belongs to.
The NCO configuration, the DDC configuration, and Scheduling will be discussed in more detail in the NCO Configuration section.
To remove a RACH channel from the configuration, use XDfePrach_RemoveRCfromRCCfg
. There is no multiband
equivalent of this function.
//assumes XDfePrach_CCCfg structure CCCfg has already been populated.
XDfePrach_DDCCfg DdcCfg = { 0 };
XDfePrach_NCOCfg NcoCfg = { 0 };
XDfePrach_Schedule SchedCfg = { 0 };
u32 CCID;
u32 RCId;
u32 result;
CCID = 0; // CCID on which to perform RACH extraction
RCId = 1; // RACH channel identifier (0-15)
/* Set up NcoCfg */
NcoCfg.Frequency = 32;
NcoCfg.NcoGain = 1;
/* Set up DdcCfg - default RachGain is 0dB for all stages */
DdcCfg.DecimationRate = 2; // Rate #2 = 4x decimation
DdcCfg.SCS = 1; // SCS #1 = 30 kHz spacing
/* Set up SchedCfg */
SchedCfg.PatternPeriod = 20; // Enable every twentieth frame
SchedCfg.FrameID = 3; // Start on fourth frame of the period
SchedCfg.SubframeID = 0; // Start on first subframe
SchedCfg.SlotId = 0; // Start on first slot
SchedCfg.Duration = 32; // Number of slots to capture
SchedCfg.Repeats = 1; // Perform a single capture
/* Add the RACH channel to the configuration */
result = XDfePrach_AddRCtoRCCfg(InstancePtr, &RCConfig,
CCID, RCId, RCId, &DdcCfg, &NcoCfg, &SchedCfg, &CCCfg);
/* Remove RCID 4 from the configuration */
XDfePrach_RemoveRCfromRCCfg(InstancePtr, &RCConfig, 4);
The parameters for an existing RACH channel can be updated within the
configuration using XDfePrach_UpdateRCinRCCfg
and
XDfePrach_UpdateRCinRCCfgMB
, which have similar
syntax to XDfePrach_AddRCtoRCCfg
and XDfePrach_AddRCtoRCCfgMB
.
When all the require changes have been made and the CC configuration
structure and RACH channel configuration structure are both ready to be applied, call
the XDfePrach_SetNextCfg
function to write the new
configuration structures to the core.
/* Apply the changes */
result = XDfePrach_SetNextCfg(InstancePtr, &CCConfig, &RCConfig);
if (result == XST_SUCCESS)
printf("CC & RACH configurations scheduled for update\n");
else
printf("Set CC & RACH configuration failed with error code %d!\n", result);
This function will upload all of the register settings associated with
XDfePrach_CCCfg
and XDfePrach_RCCfg
to the core's registers, it will also load the RachUpdate
trigger settings (defined in Triggering Configuration Changes) and the FrameInit
trigger settings for each band. The new component carrier and
RACH channel configurations will replace the existing configurations when the RachUpdate
trigger condition occurs.
After this, the new capture configurations will remain dormant until the
FrameInit
trigger condition occurs for the band
they are targeting. Once the FrameInit
trigger
condition occurs the core can synchronize the CC sequence and initialize the
scheduler.