source: ResearchApps/PHY/WARPLAB/WARPLab7/C_Code_Reference/wl_trigger_manager.c

Last change on this file was 4927, checked in by welsh, 8 years ago

Cleaned up trigger manager command names: Instead of set_reset / clear_reset, changed to trig_disable / trig_enable; Formalized hold mode using defines. Increased trigger output delay for all outputs to conform to trigger manager v1.07.g.

File size: 53.0 KB
RevLine 
[4284]1/** @file wl_trigger_manager.c
2 *  @brief WARPLab Framework (Trigger Manager)
3 *
4 *  This contains the code for WARPLab Framework trigger manager.
5 *
[4668]6 *  @copyright Copyright 2013-2015, Mango Communications. All rights reserved.
[4284]7 *          Distributed under the WARP license  (http://warpproject.org/license)
8 *
9 *  @author Chris Hunter (chunter [at] mangocomm.com)
10 *  @author Patrick Murphy (murphpo [at] mangocomm.com)
11 *  @author Erik Welsh (welsh [at] mangocomm.com)
12 */
[1915]13
[4668]14//
[4466]15// NOTE:
16//     In version 1.04.a of the trigger manager, we broke the dependence of the Ethernet
17//     trigger(s) on the software trigger.  In this version of the trigger manager, each
18//     Ethernet trigger also has a bit that can be used by software to cause the trigger.
19//     This was done so that the software trigger was able to be used exclusively by user
20//     software (ie the reference design does not use the software trigger).
21// 
22
[4668]23//
[4466]24// NOTE:
[4668]25//     The trigger manager terminology can be a bit confusing, since the term "Trigger ID"
26//     gets used interchangably for a number of distinct IDs.  In order to help clarify
27//     things, we will try to use the following conventions:
[4466]28//
[4668]29//       1) Trigger Input IDs are used to identify the trigger input that is desired.  In
30//          general, we will try to refer to these as input_ids.
31//
32//       2) Trigger Output IDs are used to identify the trigger output that is desired.  In
33//          general, we will try to refer to these as output_ids.
34//
35//       3) Trigger Ethernet IDs are used to qualify Ethernet triggers.  The Ethernet trigger packet
36//          contains a Trigger Ethernet ID that the Trigger Manager uses to filter Ethernet trigger
37//          packets.  This allows a user to cause an Ethernet trigger event in a sub-set of nodes,
38//          which are sensitized to a given Trigger Ethernet ID, by specifying that Trigger Ethernet
39//          ID in the Ethernet trigger packet.  In general, we will try to refer to these as
40//          ethernet_ids.
41//
[4466]42
43/**********************************************************************************************************************/
44/**
[4668]45 * @brief Common Functions
[4466]46 *
47 **********************************************************************************************************************/
48
[4284]49/***************************** Include Files *********************************/
[1915]50
[4284]51// Xilinx / Standard library includes
[4437]52#include <stdio.h>
[4284]53#include <xio.h>
[4514]54#include <string.h>
[1915]55
[4284]56// WARPLab includes
57#include "wl_common.h"
58#include "wl_trigger_manager.h"
59#include "wl_baseband.h"
60#include "wl_transport.h"
[1915]61
[4514]62// WARP UDP transport (for Ethernet packet structures / definitions)
63#include <WARP_ip_udp.h>
[1915]64
[4514]65
[4284]66/*************************** Constant Definitions ****************************/
[1915]67
68
[4284]69/*********************** Global Variable Definitions *************************/
[1942]70
[1915]71
[4284]72/*************************** Variable Definitions ****************************/
[1915]73
[4668]74// Trigger Test Flag
75u32      trigger_test_flag;
[4184]76
[4668]77// Trigger Ethernet ID mask for Ethernet A and B triggers
78u32      active_ethernet_id_mask;
79
[4466]80// Flag to indicate that Ethernet triggers are done via software vs hardware "sniffing"
81u32      eth_A_sw_ethernet_trigger_enable;
82u32      eth_B_sw_ethernet_trigger_enable;
[4284]83
[4668]84
[4284]85/*************************** Function Prototypes *****************************/
86
[4668]87u32  trigmngr_input_id_to_AND_mask(u32 input_id);
88u32  trigmngr_input_id_to_OR_mask(u32 input_id);
[4284]89
[4668]90void trigmngr_disable_all_triggers();
91void trigmngr_enable_all_triggers();
[4466]92
93void eth_trigger_init();
[4468]94
95u32  get_eth_trigger_type(u32 eth_dev_num);
[4466]96void set_eth_trigger_type(u32 type, u32 eth_dev_num);
[4468]97
[4668]98void update_eth_trigger_control(u32 ethernet_id, u32 eth_dev_num);
[4466]99
100
[4284]101/******************************** Functions **********************************/
102
103/*****************************************************************************/
104/**
[4514]105 * Process Trigger Manager Commands
106 *
107 * This function is part of the Ethernet processing system and will process the
108 * various trigger manager related commands.
109 *
110 * @param   socket_index     - Index of the socket on which to send message
111 * @param   from             - Pointer to socket address structure (struct sockaddr *) where command is from
112 * @param   command          - Pointer to WARPLab Command
113 * @param   response         - Pointer to WARPLab Response
114 *
[4668]115 * @return  int              - Status of the command:
116 *                                 NO_RESP_SENT - No response has been sent
117 *                                 RESP_SENT    - A response has been sent
[4514]118 *
119 * @note    See on-line documentation for more information about the Ethernet
120 *          packet structure for WARPLab:  www.warpproject.org
121 *
122 ******************************************************************************/
123int trigmngr_process_cmd(int socket_index, void * from, wl_cmd_resp * command, wl_cmd_resp * response) {
[4284]124
[4668]125    //
[4514]126    // IMPORTANT ENDIAN NOTES:
[4668]127    //     - command
128    //         - header - Already endian swapped by the framework (safe to access directly)
129    //         - args   - Must be endian swapped as necessary by code (framework does not know the contents of the command)
130    //     - response
131    //         - header - Will be endian swapped by the framework (safe to write directly)
132    //         - args   - Must be endian swapped as necessary by code (framework does not know the contents of the response)
133    //
[4284]134
[4668]135    // Standard variables
[4514]136    u32                 resp_sent      = NO_RESP_SENT;
137
138    wl_cmd_resp_hdr   * cmd_hdr        = command->header;
139    u32               * cmd_args_32    = command->args;
140    u32                 cmd_id         = WL_CMD_TO_CMDID(cmd_hdr->cmd);
141
142    wl_cmd_resp_hdr   * resp_hdr       = response->header;
143    u32               * resp_args_32   = response->args;
144    u32                 resp_index     = 0;
145
146    // Specific command variables
[4668]147    u32                 i, j;
[4514]148    u32                 eth_dev_num;
[4668]149    u32                 ethernet_id;
150    u32                 num_output_ids;
151    u32                 output_id;
152    u32                 num_input_ids;
153    u32                 input_id;
154    u32                 num_or_input_ids, num_and_input_ids;
155    u32                 output_start, or_start, and_start;
156    u32                 or_inputs, and_inputs;
157    u32                 trigger_type;
158    u32                 delay;
159    u32                 mode;
[4783]160    u32                 type;
[4514]161
[4668]162    // Set up the response header
163    resp_hdr->cmd       = cmd_hdr->cmd;
164    resp_hdr->length    = 0;
165    resp_hdr->num_args  = 0;
[4284]166
[4668]167    // Get the Ethernet device number of the socket
168    eth_dev_num = socket_get_eth_dev_num(socket_index);
[4184]169
[4668]170    // Process commands
171    switch(cmd_id){
[4184]172
[4668]173        //---------------------------------------------------------------------
[4783]174        case CMDID_TRIG_MNGR_ADD_ETHERNET_TRIG:
[4668]175            // Add the new Trigger Ethernet ID to the internal mask of all enabled
176            // Trigger Ethernet IDs
177            //
178            // NOTE:  Trigger Ethernet IDs must be one-hot encoded
179            //
180            ethernet_id = Xil_Ntohl(cmd_args_32[0]);
[1915]181
[4668]182            active_ethernet_id_mask = active_ethernet_id_mask | ethernet_id;
[1915]183
[4668]184            update_eth_trigger_control(active_ethernet_id_mask, eth_dev_num);
[1915]185
[4668]186            resp_args_32[resp_index++] = Xil_Htonl(active_ethernet_id_mask);
[1915]187
[4668]188            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
189            resp_hdr->num_args = resp_index;
190        break;
[4184]191
192
[4668]193        //---------------------------------------------------------------------
[4783]194        case CMDID_TRIG_MNGR_DEL_ETHERNET_TRIG:
[4668]195            // Remove the new Trigger Ethernet ID from the internal mask of all enabled
196            // Trigger Ethernet IDs
197            //
198            // NOTE:  Trigger Ethernet IDs must be one-hot encoded
199            //
200            ethernet_id = Xil_Ntohl(cmd_args_32[0]);
[4328]201
[4668]202            active_ethernet_id_mask = active_ethernet_id_mask & ~ethernet_id;
[1915]203
[4668]204            update_eth_trigger_control(active_ethernet_id_mask, eth_dev_num);
[1915]205
[4668]206            resp_args_32[resp_index++] = Xil_Htonl(active_ethernet_id_mask);
[4514]207
[4668]208            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
209            resp_hdr->num_args = resp_index;
210        break;
[4184]211
212
[4668]213        //---------------------------------------------------------------------
[4783]214        case CMDID_TRIG_MNGR_CLR_ETHERNET_TRIGS:
[4668]215            // Remove all Ethernet triggers
216            //
217            active_ethernet_id_mask = 0;
[1915]218
[4668]219            update_eth_trigger_control(active_ethernet_id_mask, eth_dev_num);
[1915]220
[4668]221            resp_args_32[resp_index++] = Xil_Htonl(active_ethernet_id_mask);
[4514]222
[4668]223            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
224            resp_hdr->num_args = resp_index;
225        break;
[4184]226
227
[4668]228        //---------------------------------------------------------------------
[4783]229        case CMDID_TRIG_MNGR_HW_SW_ETHERNET_TRIG:
[4668]230            // Select whether to use HW or SW for Ethernet triggers
231            //
232            // NOTE:  This command allows for better timing synchronization between
233            //        heterogeneous WARP v3 and WARP v2 networks since HW triggers
234            //        are not supported for WARP v2
235            //
236            trigger_type = Xil_Ntohl(cmd_args_32[0]);
[4468]237
[4668]238            set_eth_trigger_type(trigger_type, eth_dev_num);
[4468]239
[4668]240            resp_args_32[resp_index++] = Xil_Htonl(get_eth_trigger_type(eth_dev_num));
[4514]241
[4668]242            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
243            resp_hdr->num_args = resp_index;
244        break;
[4468]245
246
[4668]247        //---------------------------------------------------------------------
[4783]248        case CMDID_TRIG_MNGR_INPUT_SEL:
[4668]249            // TRIG_MNGR_INPUT_SEL Packet Format:
250            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
251            //   - NOTE:  This command contains three lists of parameters:
252            //                1) output ids
253            //                2) "OR" input ids
254            //                3) "AND" input ids
255            //            Since these lists can be arbitrarily long, they are each preceded by the number
256            //            of elements in each list.
257            //
258            //   - cmd_args_32[0]                               - Number of output ids (N)
259            //   - cmd_args_32[1 to N]                          - Output ID(s)
260            //   - cmd_args_32[(N + 1)]                         - Number of "OR" input ids (M)
261            //   - cmd_args_32[(N + 1) to (M + N + 1)]          - "OR" input ID(s)
262            //   - cmd_args_32[(M + N + 2)]                     - Number of "AND" input ids (M)
263            //   - cmd_args_32[(M + N + 2) to (P + M + N + 2)]  - "AND" input ID(s)
264            //
265            // NOTE:  This function will clear any previous state for the outputs specified in the argument list
266            //     and will not affect any outputs not specified in the argument list.
267            //
[4184]268
[4668]269            // Get start positions for the argument lists
270            output_start          = 0;
271            or_start              = Xil_Ntohl(cmd_args_32[output_start]) + 1;
272            and_start             = or_start + Xil_Ntohl(cmd_args_32[or_start]) + 1;
[4184]273
[4668]274            // Get the number of each type of argument
275            num_output_ids        = Xil_Ntohl(cmd_args_32[0]);
276            num_or_input_ids      = Xil_Ntohl(cmd_args_32[or_start]);
277            num_and_input_ids     = Xil_Ntohl(cmd_args_32[and_start]);
[2012]278
[4668]279            // xil_printf("Num Outputs = %d\n", num_output_ids);
280            // xil_printf("Num OR      = %d\n", num_or_input_ids);
281            // xil_printf("Num AND     = %d\n", num_and_input_ids);
[4284]282
[4668]283            // Loop Through Outputs
284            for(i = 1; i < (num_output_ids + 1); i++) {
285                or_inputs  = 0;
286                and_inputs = 0;
287                output_id  = Xil_Ntohl(cmd_args_32[i]);
[2012]288
[4668]289                // xil_printf("    Output: %d\n", output_id);
[2012]290
[4668]291                // Loop Through OR input ids
292                for(j = 1; j < (num_or_input_ids + 1); j++) {
293                    // xil_printf("        OR Input: %d\n", Xil_Ntohl(cmd_args_32[j + or_start]));
294                    or_inputs = or_inputs + trigmngr_input_id_to_OR_mask(Xil_Ntohl(cmd_args_32[j + or_start]));
295                }
[2012]296
[4668]297                // Loop Through AND input ids
298                for(j = 1; j < (num_and_input_ids + 1); j++){
299                    // xil_printf("      AND Input: %d\n", Xil_Ntohl(cmd_args_32[j + and_start]));
300                    and_inputs = and_inputs + trigmngr_input_id_to_AND_mask(Xil_Ntohl(cmd_args_32[j + and_start]));
301                }
[4184]302
[4668]303                // Configure the output
304                switch(output_id){
305                    case 1:
[4783]306                        trigger_proc_out0_clear_config(AND_ALL | OR_ALL);
307                        trigger_proc_out0_set_config(and_inputs | or_inputs);
[4668]308                    break;
309                    case 2:
[4783]310                        trigger_proc_out1_clear_config(AND_ALL | OR_ALL);
311                        trigger_proc_out1_set_config(and_inputs | or_inputs);
[4668]312                    break;
313                    case 3:
[4783]314                        trigger_proc_out2_clear_config(AND_ALL | OR_ALL);
315                        trigger_proc_out2_set_config(and_inputs | or_inputs);
[4668]316                    break;
317                    case 4:
[4783]318                        trigger_proc_out3_clear_config(AND_ALL | OR_ALL);
319                        trigger_proc_out3_set_config(and_inputs | or_inputs);
[4668]320                    break;
321                    case 5:
[4783]322                        trigger_proc_out4_clear_config(AND_ALL | OR_ALL);
323                        trigger_proc_out4_set_config(and_inputs | or_inputs);
[4668]324                    break;
325                    case 6:
[4783]326                        trigger_proc_out5_clear_config(AND_ALL | OR_ALL);
327                        trigger_proc_out5_set_config(and_inputs | or_inputs);
[4668]328                    break;
329                }
330            }
331            // xil_printf("\n");
332        break;
[2012]333
[4184]334
[4668]335        //---------------------------------------------------------------------
[4783]336        case CMDID_TRIG_MNGR_OUTPUT_DELAY:
[4668]337            // TRIG_MNGR_OUTPUT_DELAY Packet Format:
338            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
339            //   - NOTE:  This command contains a list of parameters:  output ids
340            //            Since this list can be arbitrarily long, it is preceded by the number
341            //            of elements in the list.
342            //
343            //   - cmd_args_32[0]                               - Number of output ids (N)
344            //   - cmd_args_32[1 to N]                          - Output ID(s)
345            //   - cmd_args_32[(N + 1)]                         - Delay value
346            //
347            // NOTE:  This function will clear any previous delay state for the output ids
348            //        specified in the argument list.
349            //
350            num_output_ids   = Xil_Ntohl(cmd_args_32[0]);
351            delay            = Xil_Ntohl(cmd_args_32[(num_output_ids + 1)]);
[2017]352
[4668]353            // Loop Through Outputs
354            for(i = 1; i < (num_output_ids + 1); i++){
355                output_id = Xil_Ntohl(cmd_args_32[i]);
[4184]356
[4668]357                switch(output_id){
[4783]358                    case 1:  trigger_proc_out0_set_delay(delay);  break;
359                    case 2:  trigger_proc_out1_set_delay(delay);  break;
360                    case 3:  trigger_proc_out2_set_delay(delay);  break;
361                    case 4:  trigger_proc_out3_set_delay(delay);  break;
362                    case 5:  trigger_proc_out4_set_delay(delay);  break;
363                    case 6:  trigger_proc_out5_set_delay(delay);  break;
[4668]364                }
365            }
366        break;
[2018]367
368
[4668]369        //---------------------------------------------------------------------
[4783]370        case CMDID_TRIG_MNGR_OUTPUT_HOLD:
[4668]371            // TRIG_MNGR_OUTPUT_HOLD Packet Format:
372            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
373            //   - NOTE:  This command contains a list of parameters:  output ids
374            //            Since this list can be arbitrarily long, it is preceded by the number
375            //            of elements in the list.
376            //
377            //   - cmd_args_32[0]                               - Number of output ids (N)
378            //   - cmd_args_32[1 to N]                          - Output ID(s)
379            //   - cmd_args_32[(N + 1)]                         - Hold mode value
380            //
381            // NOTE:  This function will clear any previous hold mode state for the output ids
382            //        specified in the argument list.
383            //
384            num_output_ids   = Xil_Ntohl(cmd_args_32[0]);
385            mode             = Xil_Ntohl(cmd_args_32[(num_output_ids + 1)]);
[2012]386
[4668]387            // Loop Through Outputs
388            for(i = 1; i < (num_output_ids + 1); i++){
389                output_id = Xil_Ntohl(cmd_args_32[i]);
[4184]390
[4668]391                switch(output_id){
[4783]392                    case 1:  trigger_proc_out0_set_hold_mode(mode);  break;
393                    case 2:  trigger_proc_out1_set_hold_mode(mode);  break;
394                    case 3:  trigger_proc_out2_set_hold_mode(mode);  break;
395                    case 4:  trigger_proc_out3_set_hold_mode(mode);  break;
396                    case 5:  trigger_proc_out4_set_hold_mode(mode);  break;
397                    case 6:  trigger_proc_out5_set_hold_mode(mode);  break;
[4668]398                }
399            }
400        break;
[4184]401
[4328]402
[4668]403        //---------------------------------------------------------------------
[4783]404        case CMDID_TRIG_MNGR_OUTPUT_READ:
[4668]405            // TRIG_MNGR_OUTPUT_READ Packet Format:
406            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
407            //   - NOTE:  This command contains a list of parameters:  output ids
408            //            Since this list can be arbitrarily long, it is preceded by the number
409            //            of elements in the list.
410            //
411            //   - cmd_args_32[0]                               - Number of output ids (N)
412            //   - cmd_args_32[1 to N]                          - Output ID(s)
413            //
414            // NOTE:  This function will return a list of output values for the specified output ids
415            //        in the same order as they are listed in the argument list.
416            //
417            num_output_ids = Xil_Ntohl(cmd_args_32[0]);
[4514]418
[4668]419            // Loop Through Outputs
420            for(i = 1; i < (num_output_ids + 1); i++){
421                output_id = Xil_Ntohl(cmd_args_32[i]);
[2018]422
[4668]423                switch(output_id){
[4783]424                    case 1:  resp_args_32[resp_index++] = Xil_Htonl((trigger_proc_get_output_values() & OUT0) > 0);  break;
425                    case 2:  resp_args_32[resp_index++] = Xil_Htonl((trigger_proc_get_output_values() & OUT1) > 0);  break;
426                    case 3:  resp_args_32[resp_index++] = Xil_Htonl((trigger_proc_get_output_values() & OUT2) > 0);  break;
427                    case 4:  resp_args_32[resp_index++] = Xil_Htonl((trigger_proc_get_output_values() & OUT3) > 0);  break;
428                    case 5:  resp_args_32[resp_index++] = Xil_Htonl((trigger_proc_get_output_values() & OUT4) > 0);  break;
429                    case 6:  resp_args_32[resp_index++] = Xil_Htonl((trigger_proc_get_output_values() & OUT5) > 0);  break;
[4668]430                }
431            }
[4184]432
[4668]433            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
434            resp_hdr->num_args = resp_index;
435        break;
[2018]436
[4184]437
[4668]438        //---------------------------------------------------------------------
[4783]439        case CMDID_TRIG_MNGR_OUTPUT_CLEAR:
[4668]440            // TRIG_MNGR_OUTPUT_CLEAR Packet Format:
441            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
442            //   - NOTE:  This command contains a list of parameters:  output ids
443            //            Since this list can be arbitrarily long, it is preceded by the number
444            //            of elements in the list.
445            //
446            //   - cmd_args_32[0]                               - Number of output ids (N)
447            //   - cmd_args_32[1 to N]                          - Output ID(s)
448            //
449            num_output_ids = Xil_Ntohl(cmd_args_32[0]);
[2018]450
[4668]451            // Loop Through Outputs
452            for(i = 1; i < (num_output_ids + 1); i++){
453                output_id = Xil_Ntohl(cmd_args_32[i]);
[4184]454
[4927]455                // NOTE:  The Hold Mode register is active-low.
456                // NOTE:  If not in Hold Mode, the output is already clear
[4668]457                switch(output_id){
458                    case 1:
[4927]459                        if(trigger_proc_out0_get_hold_mode() == OUT_HOLD_MODE_ENABLE){
460                            trigger_proc_out0_set_hold_mode(OUT_HOLD_MODE_DISABLE);
461                            trigger_proc_out0_set_hold_mode(OUT_HOLD_MODE_ENABLE);
[4668]462                        }
463                    break;
464                    case 2:
[4927]465                        if(trigger_proc_out1_get_hold_mode() == OUT_HOLD_MODE_ENABLE){
466                            trigger_proc_out1_set_hold_mode(OUT_HOLD_MODE_DISABLE);
467                            trigger_proc_out1_set_hold_mode(OUT_HOLD_MODE_ENABLE);
[4668]468                        }
469                    break;
470                    case 3:
[4927]471                        if(trigger_proc_out2_get_hold_mode() == OUT_HOLD_MODE_ENABLE){
472                            trigger_proc_out2_set_hold_mode(OUT_HOLD_MODE_DISABLE);
473                            trigger_proc_out2_set_hold_mode(OUT_HOLD_MODE_ENABLE);
[4668]474                        }
475                    break;
476                    case 4:
[4927]477                        if(trigger_proc_out3_get_hold_mode() == OUT_HOLD_MODE_ENABLE){
478                            trigger_proc_out3_set_hold_mode(OUT_HOLD_MODE_DISABLE);
479                            trigger_proc_out3_set_hold_mode(OUT_HOLD_MODE_ENABLE);
[4668]480                        }
481                    break;
482                    case 5:
[4927]483                        if(trigger_proc_out4_get_hold_mode() == OUT_HOLD_MODE_ENABLE){
484                            trigger_proc_out4_set_hold_mode(OUT_HOLD_MODE_DISABLE);
485                            trigger_proc_out4_set_hold_mode(OUT_HOLD_MODE_ENABLE);
[4668]486                        }
487                    break;
488                    case 6:
[4927]489                        if(trigger_proc_out5_get_hold_mode() == OUT_HOLD_MODE_ENABLE){
490                            trigger_proc_out5_set_hold_mode(OUT_HOLD_MODE_DISABLE);
491                            trigger_proc_out5_set_hold_mode(OUT_HOLD_MODE_ENABLE);
[4668]492                        }
493                    break;
494                }
495            }
496        break;
[4184]497
[4328]498
[4668]499        //---------------------------------------------------------------------
[4783]500        case CMDID_TRIG_MNGR_INPUT_ENABLE:
[4694]501            // NOT SUPPORTED
502            xil_printf("TRIG_MNGR_INPUT_ENABLE is not supported\n");
[4668]503        break;
[2024]504
[4438]505
[4668]506        //---------------------------------------------------------------------
[4783]507        case CMDID_TRIG_MNGR_INPUT_DEBOUNCE:
[4668]508            // TRIG_MNGR_INPUT_DEBOUNCE Packet Format:
509            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
510            //   - NOTE:  This command contains a list of parameters:  input ids
511            //            Since this list can be arbitrarily long, it is preceded by the number
512            //            of elements in the list.
513            //
514            //   - cmd_args_32[0]                               - Number of input ids (N)
515            //   - cmd_args_32[1 to N]                          - Input ID(s)
516            //   - cmd_args_32[(N + 1)]                         - Debounce mode
517            //
518            num_input_ids    = Xil_Ntohl(cmd_args_32[0]);
519            mode             = Xil_Ntohl(cmd_args_32[(num_input_ids + 1)]);
[2024]520
[4668]521            // Loop Through Inputs
522            for(i = 1; i < (num_input_ids + 1); i++){
523                input_id = Xil_Ntohl(cmd_args_32[i]);
[2024]524
[4668]525                switch(input_id){
[4783]526                    case 5:  trigger_proc_in_ext_P0_debounce_mode(mode);  break;
527                    case 6:  trigger_proc_in_ext_P1_debounce_mode(mode);  break;
528                    case 7:  trigger_proc_in_ext_P2_debounce_mode(mode);  break;
529                    case 8:  trigger_proc_in_ext_P3_debounce_mode(mode);  break;
[4328]530
[4668]531                    // NOTE:  The following cases are invalid:
532                    //   case 1:  // Invalid -- Ethernet A input has no debounce circuit
533                    //   case 2:  // Invalid -- Energy detection input has no debounce circuit
534                    //   case 3:  // Invalid -- AGC done input has no debounce circuit
535                    //   case 4:  // Invalid -- Software trigger input has no debounce circuit
536                    //   case 9:  // Invalid -- Ethernet B input has no debounce circuit
537                    //
538                }
539            }
540        break;
[4328]541
[4438]542
[4668]543        //---------------------------------------------------------------------
[4783]544        case CMDID_TRIG_MNGR_INPUT_DELAY:
[4668]545            // TRIG_MNGR_INPUT_DELAY Packet Format:
546            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
547            //   - NOTE:  This command contains a list of parameters:  input ids
548            //            Since this list can be arbitrarily long, it is preceded by the number
549            //            of elements in the list.
550            //
551            //   - cmd_args_32[0]                               - Number of input ids (N)
552            //   - cmd_args_32[1 to N]                          - Input ID(s)
553            //   - cmd_args_32[(N + 1)]                         - Input delay
554            //
555            num_input_ids    = Xil_Ntohl(cmd_args_32[0]);
556            delay            = Xil_Ntohl(cmd_args_32[(num_input_ids + 1)]);
[4438]557
[4668]558            // Loop Through Inputs
559            for(i = 1; i < (num_input_ids + 1); i++){
560                input_id = Xil_Ntohl(cmd_args_32[i]);
[4328]561
[4668]562                switch(input_id){
563                    case 1:  trigger_proc_in_eth_A_set_delay(delay);    break;
[4783]564                    case 3:  trigger_proc_in_agc_done_set_delay(delay);  break;
565                    case 5:  trigger_proc_in_ext_P0_set_delay(delay);   break;
566                    case 6:  trigger_proc_in_ext_P1_set_delay(delay);   break;
567                    case 7:  trigger_proc_in_ext_P2_set_delay(delay);   break;
568                    case 8:  trigger_proc_in_ext_P3_set_delay(delay);   break;
[4668]569                    case 9:  trigger_proc_in_eth_B_set_delay(delay);    break;
[4328]570
[4668]571                    // NOTE:  The following cases are invalid:
572                    //   case 2:  // Invalid -- Energy input has no delay circuit
573                    //   case 4:  // Invalid -- Software input has no delay circuit
574                    //
[2028]575
[4668]576                }
577            }
578        break;
[4184]579
[2028]580
[4668]581        //---------------------------------------------------------------------
[4783]582        case CMDID_TRIG_MNGR_IDELAY:
583            // TRIG_MNGR_IDELAY Packet Format:
584            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
585            //   - NOTE:  This command contains a list of parameters:  input ids
586            //            Since this list can be arbitrarily long, it is preceded by the number
587            //            of elements in the list.
588            //
[4786]589            //   - cmd_args_32[0]                               - 'ext_pin' or 'cm_pll'
590            //   - cmd_args_32[1]                               - Number of input ids (N)
[4783]591            //   - cmd_args_32[2 to N]                          - Input ID(s)
592            //   - cmd_args_32[(N + 2) to (N + N)]              - IDELAY value of corresponding input ID (UFix_5_0)
593            //
594            // NOTE:  The following Input IDs are invalid:
595            //   - 1 - Invalid -- Ethernet A input has no IDELAY circuit
596            //   - 2 - Invalid -- Energy detection input has no IDELAY circuit
597            //   - 3 - Invalid -- AGC done input has no IDELAY circuit
598            //   - 4 - Invalid -- Software trigger input has no IDELAY circuit
599            //   - 9 - Invalid -- Ethernet B input has no IDELAY circuit
600            //
[4786]601            type             = Xil_Ntohl(cmd_args_32[0]);
602            num_input_ids    = Xil_Ntohl(cmd_args_32[1]);
[4783]603
604            // Loop Through Inputs
605            if (type == IO_DELAY_TYPE_PIN) {
606                for (i = 2; i < (num_input_ids + 2); i++) {
607                    input_id = Xil_Ntohl(cmd_args_32[i]);
608                    delay    = (Xil_Ntohl(cmd_args_32[(num_input_ids + i)]) & IO_DELAY_MASK);
609
610                    switch (input_id) {
611                        case 5: trigger_proc_in_ext_P0_set_idelay_pin(delay); break;
612                        case 6: trigger_proc_in_ext_P1_set_idelay_pin(delay); break;
613                        case 7: trigger_proc_in_ext_P2_set_idelay_pin(delay); break;
614                        case 8: trigger_proc_in_ext_P3_set_idelay_pin(delay); break;
615                    }
616                }
617            } else {
618                for (i = 2; i < (num_input_ids + 2); i++) {
619                    input_id = Xil_Ntohl(cmd_args_32[i]);
620                    delay    = (Xil_Ntohl(cmd_args_32[(num_input_ids + i)]) & IO_DELAY_MASK);
621
622                    switch (input_id) {
623                        case 5: trigger_proc_in_ext_P0_set_idelay_cm_pll(delay); break;
624                        case 6: trigger_proc_in_ext_P1_set_idelay_cm_pll(delay); break;
625                        case 7: trigger_proc_in_ext_P2_set_idelay_cm_pll(delay); break;
626                        case 8: trigger_proc_in_ext_P3_set_idelay_cm_pll(delay); break;
627                    }
628                }
629            }
630
631            // Toggle IDELAY set bit
632            trigger_proc_idelay_update_clear();
633            trigger_proc_idelay_update_set();
634            trigger_proc_idelay_update_clear();
[4668]635        break;
[2028]636
637
[4668]638        //---------------------------------------------------------------------
[4783]639        case CMDID_TRIG_MNGR_ODELAY:
640            // TRIG_MNGR_ODELAY Packet Format:
641            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
642            //   - NOTE:  This command contains a list of parameters:  input ids
643            //            Since this list can be arbitrarily long, it is preceded by the number
644            //            of elements in the list.
645            //
646            //   - cmd_args_32[1]                               - 'ext_pin' or 'cm_pll'
[4786]647            //   - cmd_args_32[0]                               - Number of output ids (N)
648            //   - cmd_args_32[2 to N]                          - Output ID(s)
649            //   - cmd_args_32[(N + 2) to (N + N)]              - ODELAY value of corresponding output ID (UFix_5_0)
[4783]650            //
651            // NOTE:  The following Output IDs are invalid:
652            //   - 1 - Invalid -- Baseband output has no ODELAY circuit
653            //   - 2 - Invalid -- AGC output has no ODELAY circuit
654            //
[4786]655            type             = Xil_Ntohl(cmd_args_32[0]);
656            num_output_ids   = Xil_Ntohl(cmd_args_32[1]);
[4783]657
658            // Loop Through Inputs
659            if (type == IO_DELAY_TYPE_PIN) {
660                for (i = 2; i < (num_output_ids + 2); i++) {
661                    output_id = Xil_Ntohl(cmd_args_32[i]);
662                    delay     = (Xil_Ntohl(cmd_args_32[(num_output_ids + i)]) & IO_DELAY_MASK);
663
664                    switch (output_id) {
665                        case 3: trigger_proc_in_ext_P0_set_odelay_pin(delay); break;
666                        case 4: trigger_proc_in_ext_P1_set_odelay_pin(delay); break;
667                        case 5: trigger_proc_in_ext_P2_set_odelay_pin(delay); break;
668                        case 6: trigger_proc_in_ext_P3_set_odelay_pin(delay); break;
669                    }
670                }
671            } else {
672                for (i = 2; i < (num_output_ids + 2); i++) {
673                    output_id = Xil_Ntohl(cmd_args_32[i]);
674                    delay     = (Xil_Ntohl(cmd_args_32[(num_output_ids + i)]) & IO_DELAY_MASK);
675
676                    switch (output_id) {
677                        case 3: trigger_proc_in_ext_P0_set_odelay_cm_pll(delay); break;
678                        case 4: trigger_proc_in_ext_P1_set_odelay_cm_pll(delay); break;
679                        case 5: trigger_proc_in_ext_P2_set_odelay_cm_pll(delay); break;
680                        case 6: trigger_proc_in_ext_P3_set_odelay_cm_pll(delay); break;
681                    }
682                }
683            }
684
685            // Toggle IDELAY set bit
686            trigger_proc_odelay_update_clear();
687            trigger_proc_odelay_update_set();
688            trigger_proc_odelay_update_clear();
[4668]689        break;
[4184]690
[2029]691
[4668]692        //---------------------------------------------------------------------
[4783]693        case CMDID_TRIG_MNGR_ENERGY_BUSY_THRESHOLD:
694            wl_packet_detect_set_busy_threshold(Xil_Ntohl(cmd_args_32[0]));
695            wl_packet_detect_set_idle_threshold(0xFFFF);                      // Set to make sure the idle condition is always met.
[4668]696        break;
[2029]697
[4184]698
[4668]699        //---------------------------------------------------------------------
[4783]700        case CMDID_TRIG_MNGR_ENERGY_RSSI_AVG_LEN:
701            wl_packet_detect_set_RSSI_duration(Xil_Ntohl(cmd_args_32[0]));
[4668]702        break;
[4284]703
[4514]704
[4668]705        //---------------------------------------------------------------------
[4783]706        case CMDID_TRIG_MNGR_ENERGY_BUSY_MIN_LEN:
707            wl_packet_detect_set_busy_duration(Xil_Ntohl(cmd_args_32[0]));
708        break;
709
710
711        //---------------------------------------------------------------------
712        case CMDID_TRIG_MNGR_ENERGY_IFC_SEL:
713            wl_packet_detect_clear_config(WL_PACKET_DETECT_CONFIG_REG_MASK_ALL);
714            wl_packet_detect_set_config(IFC_TO_PACKET_DETECT_MASK(Xil_Ntohl(cmd_args_32[0])));
715        break;
716
717
718        //---------------------------------------------------------------------
719        case CMDID_TRIG_MNGR_TEST_TRIGGER:
[4668]720            // TRIG_MNGR_TEST_TRIGGER Packet Format:
721            //   - NOTE:  All u32 parameters in cmd_args_32 are byte swapped so use Xil_Ntohl()
722            //
723            //   - cmd_args_32[0]                               - Trigger Test Flag (optional)
724            //
725            // NOTE:  Based on the number of arguments, the command will either set the trigger
726            //     test flag or return and reset the trigger test flag.
727            //
728            if(cmd_hdr->num_args == 1){
729                trigger_test_flag =  Xil_Ntohl(cmd_args_32[0]);
[2018]730
[4668]731            // Requesting status of test trigger reception
732            } else {
733                resp_args_32[resp_index++] = Xil_Htonl(trigger_test_flag);
734
735                resp_hdr->length  += (resp_index * sizeof(resp_args_32));
736                resp_hdr->num_args = resp_index;
737
738                trigger_test_flag  = 0;
739            }
740        break;
741
[4184]742        //---------------------------------------------------------------------
[4668]743        default:
744            wl_printf(WL_PRINT_ERROR, print_type_trigger, "Unknown trigger manager command: 0x%x\n", cmd_id);
745        break;
746    }
[4284]747
[4668]748    return resp_sent;
[1915]749}
750
[4184]751
752
[4284]753/*****************************************************************************/
754/**
[4668]755 * Trigger Manager Mask Functions
756 *
757 * These functions convert trigger input ids to mask values to be used in the trigger
758 * manager.
759 *
760 * @param   input_id         - ID of the input to convert
761 *
762 * @return  u32              - Mask value of input ID
763 *
764 *****************************************************************************/
765u32 trigmngr_input_id_to_AND_mask(u32 input_id){
766    u32 mask = 0;
[4284]767
[4668]768    if (input_id <= NUM_INPUT_TRIGGERS) {
769        mask = 1 << ((input_id - 1) + AND_OFFSET_BITS);
770    }
[4284]771
[4668]772    return mask;
[2012]773}
774
[4184]775
776
[4668]777u32 trigmngr_input_id_to_OR_mask(u32 input_id){
778    u32 mask = 0;
[2012]779
[4668]780    if (input_id <= NUM_INPUT_TRIGGERS) {
781        mask = 1 << ((input_id - 1) + OR_OFFSET_BITS);
782    }
[4438]783
[4668]784    return mask;
[2012]785}
786
[4184]787
788
[4284]789/*****************************************************************************/
790/**
[4668]791 * Trigger Processing
792 *
793 * This method is called when a trigger is received.
794 *
795 * @param   ethernet_id      - ID contained within the trigger Ethernet packet
796 * @param   eth_dev_num      - Ethernet device on which trigger was received
797 *
798 * @return  None
799 *
800 *****************************************************************************/
801void trigmngr_trigger_in(u32 ethernet_id, u32 eth_dev_num){
[1915]802
[4668]803    // wl_printf(WL_PRINT_DEBUG, print_type_trigger, "Trigger received: 0x%08x\n", trig_id);
[4284]804
[4668]805    // If we are not 'sniffing' Ethernet packets, then use the software Ethernet trigger
806    if (ethernet_id & active_ethernet_id_mask){
[4466]807        switch (eth_dev_num) {
808            case WL_ETH_A:
809                if (eth_A_sw_ethernet_trigger_enable) {
810                    trigger_proc_in_eth_A_raise_trigger();
811                    trigger_proc_in_eth_A_lower_trigger();
812                }
813            break;
814            case WL_ETH_B:
815                if (eth_B_sw_ethernet_trigger_enable) {
816                    trigger_proc_in_eth_B_raise_trigger();
817                    trigger_proc_in_eth_B_lower_trigger();
818                }
819            break;
820        }
[4668]821    }
[4466]822}
[4438]823
[4466]824
825
826/*****************************************************************************/
827/**
[4668]828 * Trigger Manager disable all triggers
829 *
830 * This method disables all triggers by setting the reset bit on all triggers
831 *
832 * @param    None
833 *
834 * @return   None
835 *
836 *****************************************************************************/
837void trigmngr_disable_all_triggers() {
[4927]838    trigger_proc_in_eth_A_trig_disable();
839    trigger_proc_in_energy_trig_disable();
840    trigger_proc_in_agc_done_trig_disable();
841    trigger_proc_in_software_trig_disable();
842    trigger_proc_in_ext_P0_trig_disable();
843    trigger_proc_in_ext_P1_trig_disable();
844    trigger_proc_in_ext_P2_trig_disable();
845    trigger_proc_in_ext_P3_trig_disable();
846    trigger_proc_in_eth_B_trig_disable();
[1915]847}
848
[4184]849
850
[4284]851/*****************************************************************************/
852/**
[4668]853 * Trigger Manager enable all triggers
854 *
855 * This method enables all triggers by clearing the reset bit on all triggers
856 *
857 * @param    None
858 *
859 * @return   None
860 *
861 *****************************************************************************/
862void trigmngr_enable_all_triggers() {
[4927]863    trigger_proc_in_eth_A_trig_enable();
864    trigger_proc_in_energy_trig_enable();
865    trigger_proc_in_agc_done_trig_enable();
866    trigger_proc_in_software_trig_enable();
867    trigger_proc_in_ext_P0_trig_enable();
868    trigger_proc_in_ext_P1_trig_enable();
869    trigger_proc_in_ext_P2_trig_enable();
870    trigger_proc_in_ext_P3_trig_enable();
871    trigger_proc_in_eth_B_trig_enable();
[4486]872}
873
874
875
876/*****************************************************************************/
877/**
[4284]878 * @brief Trigger Manager subsystem initialization
879 *
880 * Initializes the trigger manager subsystem
881 *
[4668]882 * @param   None
[4284]883 *
[4668]884 * @return  int              - Status of the command:
885 *                                 XST_SUCCESS  - Command successful
886 *                                 XST_FAILURE  - Command not successful
887 *
[4284]888 ******************************************************************************/
[1915]889int trigmngr_init(){
[4668]890    int status = XST_SUCCESS;
[1915]891
[4668]892    // Initialize the global variables
893    active_ethernet_id_mask  = 0;
894    trigger_test_flag        = 0;
[4284]895
[4668]896    // Initialize Trigger Processor
897
[4486]898    // Set all reset bits (disable all triggers)
[4668]899    trigmngr_disable_all_triggers();
[4486]900
[4466]901    // Set all trigger delays to zero
[4668]902    trigger_proc_in_eth_A_set_delay(0);
[4783]903    trigger_proc_in_agc_done_set_delay(0);
904    trigger_proc_in_ext_P0_set_delay(0);
905    trigger_proc_in_ext_P1_set_delay(0);
906    trigger_proc_in_ext_P2_set_delay(0);
907    trigger_proc_in_ext_P3_set_delay(0);
[4668]908    trigger_proc_in_eth_B_set_delay(0);
[2009]909
[4783]910    trigger_proc_out0_set_delay(0);
911    trigger_proc_out1_set_delay(0);
912    trigger_proc_out2_set_delay(0);
913    trigger_proc_out3_set_delay(0);
914    trigger_proc_out4_set_delay(0);
915    trigger_proc_out5_set_delay(0);
[4713]916   
[4466]917    // Set the debounce mode on all external trigger inputs
[4783]918    trigger_proc_in_ext_P0_debounce_mode(1);
919    trigger_proc_in_ext_P1_debounce_mode(1);
920    trigger_proc_in_ext_P2_debounce_mode(1);
921    trigger_proc_in_ext_P3_debounce_mode(1);
[2009]922
[4466]923    // De-assert all software trigger bits
924    trigger_proc_in_eth_A_lower_trigger();
[4668]925    trigger_proc_in_software_lower_trigger();
[4466]926    trigger_proc_in_eth_B_lower_trigger();
[2009]927
[4668]928    // Clear all connections to output triggers
[4783]929    trigger_proc_out0_clear_config(AND_ALL | OR_ALL);
930    trigger_proc_out1_clear_config(AND_ALL | OR_ALL);
931    trigger_proc_out2_clear_config(AND_ALL | OR_ALL);
932    trigger_proc_out3_clear_config(AND_ALL | OR_ALL);
933    trigger_proc_out4_clear_config(AND_ALL | OR_ALL);
934    trigger_proc_out5_clear_config(AND_ALL | OR_ALL);
[2009]935
[4783]936    // Set hold mode to disabled (ie disable "sticky" bits)
937    trigger_proc_out0_set_hold_mode(1);
938    trigger_proc_out1_set_hold_mode(1);
939    trigger_proc_out2_set_hold_mode(1);
940    trigger_proc_out3_set_hold_mode(1);
941    trigger_proc_out4_set_hold_mode(1);
942    trigger_proc_out5_set_hold_mode(1);
[2009]943
[4466]944    // Set defaults for the Energy Trigger
[4668]945    //   Disable the idle-checking functionality of the trigger manager core
946    //       - Even a 1 cycle drop below the idle threshold will count as idle
[4783]947    wl_packet_detect_set_idle_duration(10);
[2009]948
[4783]949    wl_packet_detect_set_config(WL_PACKET_DETECT_CONFIG_REG_RESET);
950    wl_packet_detect_clear_config(WL_PACKET_DETECT_CONFIG_REG_RESET);
[4466]951   
[4486]952    // Initialize the Ethernet triggers
953    eth_trigger_init();
[2028]954
[4668]955    // Configure Trigger Processor
956    //   Default configuration:
957    //       Inputs:
958    //           Ethernet A       - Disabled
959    //           Energy           - Enabled
960    //           AGC Done         - Enabled
961    //           Software         - Enabled
962    //           Debug Input 0    - Enabled
963    //           Debug Input 1    - Enabled
964    //           Debug Input 2    - Enabled
965    //           Debug Input 3    - Enabled
966    //           Ethernet B       - Disabled
967    //       Outputs:
968    //           Baseband         - [ETH_A, ETH_B]
969    //           ACG              - [ETH_A, ETH_B]
970    //           Debug Output 0   - []
971    //           Debug Output 1   - []
972    //           Debug Output 2   - []
973    //           Debug Output 3   - []
974    //
[4783]975    trigger_proc_out0_set_config(OR_ETH_A | OR_ETH_B);   // Out0: warplab_buffers baseband
976    trigger_proc_out1_set_config(OR_ETH_A | OR_ETH_B);   // Out1: AGC start
[4466]977
[4668]978    // Enable all triggers
979    trigmngr_enable_all_triggers();
[4466]980
[4486]981    // Disable the Ethernet triggers
[4927]982    trigger_proc_in_eth_A_trig_disable();
983    trigger_proc_in_eth_B_trig_disable();
[4486]984
[4668]985    return status;
[1915]986}
987
988
[4466]989
990
991
992/**********************************************************************************************************************/
993/**
994 * @brief WARP v3 Specific Functions
995 *
996 **********************************************************************************************************************/
997
998/***************************** Include Files *********************************/
999
1000/*************************** Constant Definitions ****************************/
1001
1002/*********************** Global Variable Definitions *************************/
1003
1004/*************************** Variable Definitions ****************************/
1005
1006/*************************** Functions Prototypes ****************************/
1007
[4668]1008void wl_pkt_proc_set_ethernet_id(u32 ethernet_id, u32 eth_dev_num);
[4466]1009
1010
1011/******************************** Functions **********************************/
1012
1013
[4284]1014/*****************************************************************************/
1015/**
[4668]1016 * Ethernet Trigger Control
1017 *
1018 * These methods will control the the Ethernet triggers.
1019 *
1020 *****************************************************************************/
[4466]1021void eth_trigger_init() {
1022    // By default, WARP v3 uses HW triggers for both Eth A and Eth B
1023    set_eth_trigger_type(ETH_TRIG_HW, WL_ETH_A);
1024    set_eth_trigger_type(ETH_TRIG_HW, WL_ETH_B);
1025}
1026
1027
[4468]1028u32  get_eth_trigger_type(u32 eth_dev_num) {
[4668]1029    u32 ret_val = ETH_TRIG_INVALID;
[4468]1030
[4668]1031    switch(eth_dev_num) {
[4468]1032        case WL_ETH_A:
[4668]1033            ret_val = eth_A_sw_ethernet_trigger_enable;
1034        break;
[4468]1035        case WL_ETH_B:
[4668]1036            ret_val = eth_B_sw_ethernet_trigger_enable;
1037        break;
1038    }
[4468]1039
[4668]1040    return ret_val;
[4468]1041}
1042
1043
[4466]1044void set_eth_trigger_type(u32 type, u32 eth_dev_num) {
[4668]1045    switch(eth_dev_num) {
[4184]1046        case WL_ETH_A:
[4466]1047            switch(type) {
1048                case ETH_TRIG_HW:
1049                    trigger_proc_in_eth_A_use_hw_trig();
1050                    eth_A_sw_ethernet_trigger_enable = 0;
1051                break;
1052                case ETH_TRIG_SW:
1053                    trigger_proc_in_eth_A_use_sw_trig();
1054                    eth_A_sw_ethernet_trigger_enable = 1;
1055                break;
1056            }
[4668]1057        break;
[4184]1058        case WL_ETH_B:
[4466]1059            switch(type) {
1060                case ETH_TRIG_HW:
1061                    trigger_proc_in_eth_B_use_hw_trig();
1062                    eth_B_sw_ethernet_trigger_enable = 0;
1063                break;
1064                case ETH_TRIG_SW:
1065                    trigger_proc_in_eth_B_use_sw_trig();
1066                    eth_B_sw_ethernet_trigger_enable = 1;
1067                break;
1068            }
[4668]1069        break;
1070    }
[4184]1071}
1072
1073
[4466]1074
[4668]1075void update_eth_trigger_control(u32 ethernet_id, u32 eth_dev_num) {
[4466]1076
[4668]1077    switch(eth_dev_num) {
[4184]1078        case WL_ETH_A:
[4466]1079            if (eth_A_sw_ethernet_trigger_enable) {
1080                // If we are using SW triggers, clear the fast trigger detector
[4786]1081                wl_pkt_proc_set_ethernet_id(0, eth_dev_num);
[4466]1082            } else {
1083                // If we are using HW triggers, update the fast trigger detector
[4786]1084                wl_pkt_proc_set_ethernet_id(ethernet_id, eth_dev_num);
[4466]1085            }
1086           
1087            // If there are no active triggers, then disable the Ethernet trigger
[4668]1088            if (ethernet_id) {
[4927]1089                trigger_proc_in_eth_A_trig_enable();
[4466]1090            } else {
[4927]1091                trigger_proc_in_eth_A_trig_disable();
[4466]1092            }
[4668]1093        break;
[4184]1094        case WL_ETH_B:
[4466]1095            if (eth_B_sw_ethernet_trigger_enable) {
1096                // If we are using SW triggers, clear the fast trigger detector
[4786]1097                wl_pkt_proc_set_ethernet_id(0, eth_dev_num);
[4466]1098            } else {
1099                // If we are using HW triggers, update the fast trigger detector
[4786]1100                wl_pkt_proc_set_ethernet_id(ethernet_id, eth_dev_num);
[4466]1101            }
1102           
1103            // If there are no active triggers, then disable the Ethernet trigger
[4668]1104            if (ethernet_id) {
[4927]1105                trigger_proc_in_eth_B_trig_enable();
[4466]1106            } else {
[4927]1107                trigger_proc_in_eth_B_trig_disable();
[4466]1108            }
[4668]1109        break;
[4184]1110        default:
[4668]1111            wl_printf(WL_PRINT_ERROR, print_type_trigger, "Trigger Manager:  Unsupported Ethernet device\n");
[4184]1112            return;
1113        break;
[4668]1114    }
[4184]1115}
1116
1117
1118
[4284]1119/*****************************************************************************/
1120/**
[4668]1121 * Trigger Manager Ethernet Packet Processor
1122 *
1123 * This method configures the fast trigger logic in the warplab_pkt_proc core so that
1124 * Ethernet triggers can be directly snooped from the incoming Ethernet packet reducing
1125 * delay / jitter when using Ethernet triggers.
1126 *
1127 * @param   ethernet_id      - Trigger Ethernet ID to match
1128 *          eth_dev_num      - Indicates which Ethernet device to use
1129 *
1130 * @return  None
1131 *
1132 *****************************************************************************/
1133void wl_pkt_proc_set_ethernet_id(u32 ethernet_id, u32 eth_dev_num) {
[4184]1134
[4668]1135    // Ethernet device
1136    void                   * pkt_template;
[4184]1137    void                   * pkt_ops;
[4514]1138    u32                      tmp_ip_addr;
[4184]1139
[4668]1140    // Helper pointers, for interpreting various packet parts
1141    ethernet_header        * hdr_eth;
1142    ipv4_header            * hdr_ip;
1143    udp_header             * hdr_udp;
1144    wl_transport_header    * hdr_xport;
1145    u32                    * trig_payload;
[4184]1146
[4668]1147    // Packet length:
1148    //     Ethernet header
1149    //     IP header
1150    //     UDP header
1151    //     WL_TRANSPORT header
1152    //     Trigger Ethernet ID
1153    const int pkt_match_len =  WARP_IP_UDP_HEADER_LEN + sizeof(wl_transport_header) + 4;
[1915]1154
[4668]1155    // Local arrays to construct packet template and template operators
1156    //     The template cannot be constructed directly in the pkt_proc BRAM, since Sysgen shared memories
1157    //     aren't byte-addressable (they lack byte enables, so any write access writes the full word)
1158    u8 template0[pkt_match_len];
1159    u8 ops0[pkt_match_len];
[1915]1160
[4668]1161    // Set up Ethernet device
1162    switch(eth_dev_num) {
[4184]1163        case WL_ETH_A:
[4783]1164            pkt_template = (void *)TRIG_MNGR_REG_PKT_TEMPLATE_0;
1165            pkt_ops      = (void *)TRIG_MNGR_REG_PKT_OPS_0;
[4673]1166            tmp_ip_addr  = (u32) WL_ETH_A_IP_ADDR_BASE;
[4668]1167        break;
[4184]1168        case WL_ETH_B:
[4783]1169            pkt_template = (void *)TRIG_MNGR_REG_PKT_TEMPLATE_1;
1170            pkt_ops      = (void *)TRIG_MNGR_REG_PKT_OPS_1;
[4673]1171            tmp_ip_addr  = (u32) WL_ETH_B_IP_ADDR_BASE;
[4668]1172        break;
[4184]1173        default:
[4668]1174            wl_printf(WL_PRINT_ERROR, print_type_trigger, "Trigger Manager:  Unsupported Ethernet device\n");
[4184]1175            return;
1176        break;
[4668]1177    }
[4184]1178
[4668]1179    // Ensure the local arrays are zero (makes it safe between soft boots)
1180    bzero(template0, pkt_match_len);
1181    bzero(ops0, pkt_match_len);
[1915]1182
[4668]1183    // Assign helper pointers to their respective first bytes in the blank template buffer
1184    //     Address offsets here match received Ethernet frames (ETH-IP-UDP-WL)
1185    hdr_eth      = (ethernet_header *) template0;
1186    hdr_ip       = (ipv4_header *)((void*)hdr_eth + ETH_HEADER_LEN);
1187    hdr_udp      = (udp_header *)((void*)hdr_ip + IP_HEADER_LEN_BYTES);
1188    hdr_xport    = (wl_transport_header *)((void*)hdr_udp + UDP_HEADER_LEN + WARP_IP_UDP_DELIM_LEN);
1189    trig_payload = (u32 *)((void*)hdr_xport + sizeof(wl_transport_header));
[1915]1190
[4668]1191    // Configure the packet template
1192    hdr_eth->dest_mac_addr[0] = 0xFF;
1193    hdr_eth->dest_mac_addr[1] = 0xFF;
1194    hdr_eth->dest_mac_addr[2] = 0xFF;
1195    hdr_eth->dest_mac_addr[3] = 0xFF;
1196    hdr_eth->dest_mac_addr[4] = 0xFF;
1197    hdr_eth->dest_mac_addr[5] = 0xFF;
1198    hdr_eth->ethertype        = Xil_Htons(ETHERTYPE_IP_V4);
[1915]1199
[4668]1200    hdr_ip->protocol          = IP_PROTOCOL_UDP;
1201    hdr_ip->src_ip_addr       = 0;                                             // Any source IP address is fine
1202    hdr_ip->dest_ip_addr      = Xil_Htonl((u32)(tmp_ip_addr | 0xFF));          // X.X.X.255
[1915]1203
[4668]1204    hdr_udp->src_port         = 0;
1205    hdr_udp->dest_port        = Xil_Htons((u16)NODE_UDP_MCAST_BASE);           // WARPLab broadcast port
[1915]1206
[4668]1207    hdr_xport->src_id         = Xil_Htons((u16)0);
1208    hdr_xport->dest_id        = Xil_Htons((u16)BROADCAST_DEST_ID);
1209    hdr_xport->pkt_type       = PKTTYPE_TRIGGER;
[1915]1210
[4668]1211    trig_payload[0]           = Xil_Htonl(ethernet_id);
[1915]1212
[4668]1213    // Zero out full template, then write the part we need
1214    bzero(pkt_template, 64*4);
1215    memcpy(pkt_template, template0, pkt_match_len);
[1915]1216
[4668]1217    // If necessary, this will print the template array:
1218    //
1219    // print_array_u8(template0, pkt_match_len);
1220    //
[1915]1221
[4668]1222    // Configure the packet template operators
1223    hdr_eth      = (ethernet_header *)ops0;
1224    hdr_ip       = (ipv4_header *)((void*)hdr_eth + ETH_HEADER_LEN);
1225    hdr_udp      = (udp_header *)((void*)hdr_ip + IP_HEADER_LEN_BYTES);
1226    hdr_xport    = (wl_transport_header *)((void*)hdr_udp + UDP_HEADER_LEN + WARP_IP_UDP_DELIM_LEN);
1227    trig_payload = (u32 *)((void*)hdr_xport + sizeof(wl_transport_header));
[1915]1228
[4668]1229    // Dest Ethernet address must match (all 0xFF for broadcast)
1230    hdr_eth->dest_mac_addr[0] = U8_OP_EQ;
1231    hdr_eth->dest_mac_addr[1] = U8_OP_EQ;
1232    hdr_eth->dest_mac_addr[2] = U8_OP_EQ;
1233    hdr_eth->dest_mac_addr[3] = U8_OP_EQ;
1234    hdr_eth->dest_mac_addr[4] = U8_OP_EQ;
1235    hdr_eth->dest_mac_addr[5] = U8_OP_EQ;
1236    hdr_eth->ethertype        = U16_OP_EQ;
[1915]1237
[4668]1238    // IP protocol (UDP) and dest addr (.255) must match
1239    hdr_ip->protocol          = U8_OP_EQ;
1240    hdr_ip->src_ip_addr       = U32_OP_NC;
1241    hdr_ip->dest_ip_addr      = U32_OP_EQ;
[1915]1242
[4668]1243    // UDP src/dest ports must match
1244    hdr_udp->src_port         = U16_OP_NC;
1245    hdr_udp->dest_port        = U16_OP_EQ;
[1915]1246
[4668]1247    // WARPLab transport dest ID and packet type must match
1248    hdr_xport->src_id         = U16_OP_NC;
1249    hdr_xport->dest_id        = U16_OP_EQ;
1250    hdr_xport->pkt_type       = U8_OP_EQ;
[1915]1251
[4668]1252    // Trigger Ethernet IDs are one-hot encoded; a trigger packet will have one or more
1253    //    bit-OR'd IDs in its payload.
1254    // If any Ethernet ID matches any previously-enabled Ethernet ID, the core should assert
1255    trig_payload[0]           = U32_OP_AA;
[1915]1256
[4668]1257    // Zero out full template, then write the part we need
1258    bzero(pkt_ops, 64*4);
1259    memcpy(pkt_ops, ops0, pkt_match_len);
[4438]1260
[4668]1261    // If necessary, this will print the ops array:
1262    //
1263    // print_array_u8(ops0, pkt_match_len);
1264    //
[4466]1265}
1266
1267
Note: See TracBrowser for help on using the repository browser.