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

Last change on this file was 4927, checked in by welsh, 7 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
Line 
1/** @file wl_trigger_manager.c
2 *  @brief WARPLab Framework (Trigger Manager)
3 *
4 *  This contains the code for WARPLab Framework trigger manager.
5 *
6 *  @copyright Copyright 2013-2015, Mango Communications. All rights reserved.
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 */
13
14//
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
23//
24// NOTE:
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:
28//
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//
42
43/**********************************************************************************************************************/
44/**
45 * @brief Common Functions
46 *
47 **********************************************************************************************************************/
48
49/***************************** Include Files *********************************/
50
51// Xilinx / Standard library includes
52#include <stdio.h>
53#include <xio.h>
54#include <string.h>
55
56// WARPLab includes
57#include "wl_common.h"
58#include "wl_trigger_manager.h"
59#include "wl_baseband.h"
60#include "wl_transport.h"
61
62// WARP UDP transport (for Ethernet packet structures / definitions)
63#include <WARP_ip_udp.h>
64
65
66/*************************** Constant Definitions ****************************/
67
68
69/*********************** Global Variable Definitions *************************/
70
71
72/*************************** Variable Definitions ****************************/
73
74// Trigger Test Flag
75u32      trigger_test_flag;
76
77// Trigger Ethernet ID mask for Ethernet A and B triggers
78u32      active_ethernet_id_mask;
79
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;
83
84
85/*************************** Function Prototypes *****************************/
86
87u32  trigmngr_input_id_to_AND_mask(u32 input_id);
88u32  trigmngr_input_id_to_OR_mask(u32 input_id);
89
90void trigmngr_disable_all_triggers();
91void trigmngr_enable_all_triggers();
92
93void eth_trigger_init();
94
95u32  get_eth_trigger_type(u32 eth_dev_num);
96void set_eth_trigger_type(u32 type, u32 eth_dev_num);
97
98void update_eth_trigger_control(u32 ethernet_id, u32 eth_dev_num);
99
100
101/******************************** Functions **********************************/
102
103/*****************************************************************************/
104/**
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 *
115 * @return  int              - Status of the command:
116 *                                 NO_RESP_SENT - No response has been sent
117 *                                 RESP_SENT    - A response has been sent
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) {
124
125    //
126    // IMPORTANT ENDIAN NOTES:
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    //
134
135    // Standard variables
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
147    u32                 i, j;
148    u32                 eth_dev_num;
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;
160    u32                 type;
161
162    // Set up the response header
163    resp_hdr->cmd       = cmd_hdr->cmd;
164    resp_hdr->length    = 0;
165    resp_hdr->num_args  = 0;
166
167    // Get the Ethernet device number of the socket
168    eth_dev_num = socket_get_eth_dev_num(socket_index);
169
170    // Process commands
171    switch(cmd_id){
172
173        //---------------------------------------------------------------------
174        case CMDID_TRIG_MNGR_ADD_ETHERNET_TRIG:
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]);
181
182            active_ethernet_id_mask = active_ethernet_id_mask | ethernet_id;
183
184            update_eth_trigger_control(active_ethernet_id_mask, eth_dev_num);
185
186            resp_args_32[resp_index++] = Xil_Htonl(active_ethernet_id_mask);
187
188            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
189            resp_hdr->num_args = resp_index;
190        break;
191
192
193        //---------------------------------------------------------------------
194        case CMDID_TRIG_MNGR_DEL_ETHERNET_TRIG:
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]);
201
202            active_ethernet_id_mask = active_ethernet_id_mask & ~ethernet_id;
203
204            update_eth_trigger_control(active_ethernet_id_mask, eth_dev_num);
205
206            resp_args_32[resp_index++] = Xil_Htonl(active_ethernet_id_mask);
207
208            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
209            resp_hdr->num_args = resp_index;
210        break;
211
212
213        //---------------------------------------------------------------------
214        case CMDID_TRIG_MNGR_CLR_ETHERNET_TRIGS:
215            // Remove all Ethernet triggers
216            //
217            active_ethernet_id_mask = 0;
218
219            update_eth_trigger_control(active_ethernet_id_mask, eth_dev_num);
220
221            resp_args_32[resp_index++] = Xil_Htonl(active_ethernet_id_mask);
222
223            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
224            resp_hdr->num_args = resp_index;
225        break;
226
227
228        //---------------------------------------------------------------------
229        case CMDID_TRIG_MNGR_HW_SW_ETHERNET_TRIG:
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]);
237
238            set_eth_trigger_type(trigger_type, eth_dev_num);
239
240            resp_args_32[resp_index++] = Xil_Htonl(get_eth_trigger_type(eth_dev_num));
241
242            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
243            resp_hdr->num_args = resp_index;
244        break;
245
246
247        //---------------------------------------------------------------------
248        case CMDID_TRIG_MNGR_INPUT_SEL:
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            //
268
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;
273
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]);
278
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);
282
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]);
288
289                // xil_printf("    Output: %d\n", output_id);
290
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                }
296
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                }
302
303                // Configure the output
304                switch(output_id){
305                    case 1:
306                        trigger_proc_out0_clear_config(AND_ALL | OR_ALL);
307                        trigger_proc_out0_set_config(and_inputs | or_inputs);
308                    break;
309                    case 2:
310                        trigger_proc_out1_clear_config(AND_ALL | OR_ALL);
311                        trigger_proc_out1_set_config(and_inputs | or_inputs);
312                    break;
313                    case 3:
314                        trigger_proc_out2_clear_config(AND_ALL | OR_ALL);
315                        trigger_proc_out2_set_config(and_inputs | or_inputs);
316                    break;
317                    case 4:
318                        trigger_proc_out3_clear_config(AND_ALL | OR_ALL);
319                        trigger_proc_out3_set_config(and_inputs | or_inputs);
320                    break;
321                    case 5:
322                        trigger_proc_out4_clear_config(AND_ALL | OR_ALL);
323                        trigger_proc_out4_set_config(and_inputs | or_inputs);
324                    break;
325                    case 6:
326                        trigger_proc_out5_clear_config(AND_ALL | OR_ALL);
327                        trigger_proc_out5_set_config(and_inputs | or_inputs);
328                    break;
329                }
330            }
331            // xil_printf("\n");
332        break;
333
334
335        //---------------------------------------------------------------------
336        case CMDID_TRIG_MNGR_OUTPUT_DELAY:
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)]);
352
353            // Loop Through Outputs
354            for(i = 1; i < (num_output_ids + 1); i++){
355                output_id = Xil_Ntohl(cmd_args_32[i]);
356
357                switch(output_id){
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;
364                }
365            }
366        break;
367
368
369        //---------------------------------------------------------------------
370        case CMDID_TRIG_MNGR_OUTPUT_HOLD:
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)]);
386
387            // Loop Through Outputs
388            for(i = 1; i < (num_output_ids + 1); i++){
389                output_id = Xil_Ntohl(cmd_args_32[i]);
390
391                switch(output_id){
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;
398                }
399            }
400        break;
401
402
403        //---------------------------------------------------------------------
404        case CMDID_TRIG_MNGR_OUTPUT_READ:
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]);
418
419            // Loop Through Outputs
420            for(i = 1; i < (num_output_ids + 1); i++){
421                output_id = Xil_Ntohl(cmd_args_32[i]);
422
423                switch(output_id){
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;
430                }
431            }
432
433            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
434            resp_hdr->num_args = resp_index;
435        break;
436
437
438        //---------------------------------------------------------------------
439        case CMDID_TRIG_MNGR_OUTPUT_CLEAR:
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]);
450
451            // Loop Through Outputs
452            for(i = 1; i < (num_output_ids + 1); i++){
453                output_id = Xil_Ntohl(cmd_args_32[i]);
454
455                // NOTE:  The Hold Mode register is active-low.
456                // NOTE:  If not in Hold Mode, the output is already clear
457                switch(output_id){
458                    case 1:
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);
462                        }
463                    break;
464                    case 2:
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);
468                        }
469                    break;
470                    case 3:
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);
474                        }
475                    break;
476                    case 4:
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);
480                        }
481                    break;
482                    case 5:
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);
486                        }
487                    break;
488                    case 6:
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);
492                        }
493                    break;
494                }
495            }
496        break;
497
498
499        //---------------------------------------------------------------------
500        case CMDID_TRIG_MNGR_INPUT_ENABLE:
501            // NOT SUPPORTED
502            xil_printf("TRIG_MNGR_INPUT_ENABLE is not supported\n");
503        break;
504
505
506        //---------------------------------------------------------------------
507        case CMDID_TRIG_MNGR_INPUT_DEBOUNCE:
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)]);
520
521            // Loop Through Inputs
522            for(i = 1; i < (num_input_ids + 1); i++){
523                input_id = Xil_Ntohl(cmd_args_32[i]);
524
525                switch(input_id){
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;
530
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;
541
542
543        //---------------------------------------------------------------------
544        case CMDID_TRIG_MNGR_INPUT_DELAY:
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)]);
557
558            // Loop Through Inputs
559            for(i = 1; i < (num_input_ids + 1); i++){
560                input_id = Xil_Ntohl(cmd_args_32[i]);
561
562                switch(input_id){
563                    case 1:  trigger_proc_in_eth_A_set_delay(delay);    break;
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;
569                    case 9:  trigger_proc_in_eth_B_set_delay(delay);    break;
570
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                    //
575
576                }
577            }
578        break;
579
580
581        //---------------------------------------------------------------------
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            //
589            //   - cmd_args_32[0]                               - 'ext_pin' or 'cm_pll'
590            //   - cmd_args_32[1]                               - Number of input ids (N)
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            //
601            type             = Xil_Ntohl(cmd_args_32[0]);
602            num_input_ids    = Xil_Ntohl(cmd_args_32[1]);
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();
635        break;
636
637
638        //---------------------------------------------------------------------
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'
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)
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            //
655            type             = Xil_Ntohl(cmd_args_32[0]);
656            num_output_ids   = Xil_Ntohl(cmd_args_32[1]);
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();
689        break;
690
691
692        //---------------------------------------------------------------------
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.
696        break;
697
698
699        //---------------------------------------------------------------------
700        case CMDID_TRIG_MNGR_ENERGY_RSSI_AVG_LEN:
701            wl_packet_detect_set_RSSI_duration(Xil_Ntohl(cmd_args_32[0]));
702        break;
703
704
705        //---------------------------------------------------------------------
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:
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]);
730
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
742        //---------------------------------------------------------------------
743        default:
744            wl_printf(WL_PRINT_ERROR, print_type_trigger, "Unknown trigger manager command: 0x%x\n", cmd_id);
745        break;
746    }
747
748    return resp_sent;
749}
750
751
752
753/*****************************************************************************/
754/**
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;
767
768    if (input_id <= NUM_INPUT_TRIGGERS) {
769        mask = 1 << ((input_id - 1) + AND_OFFSET_BITS);
770    }
771
772    return mask;
773}
774
775
776
777u32 trigmngr_input_id_to_OR_mask(u32 input_id){
778    u32 mask = 0;
779
780    if (input_id <= NUM_INPUT_TRIGGERS) {
781        mask = 1 << ((input_id - 1) + OR_OFFSET_BITS);
782    }
783
784    return mask;
785}
786
787
788
789/*****************************************************************************/
790/**
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){
802
803    // wl_printf(WL_PRINT_DEBUG, print_type_trigger, "Trigger received: 0x%08x\n", trig_id);
804
805    // If we are not 'sniffing' Ethernet packets, then use the software Ethernet trigger
806    if (ethernet_id & active_ethernet_id_mask){
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        }
821    }
822}
823
824
825
826/*****************************************************************************/
827/**
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() {
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();
847}
848
849
850
851/*****************************************************************************/
852/**
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() {
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();
872}
873
874
875
876/*****************************************************************************/
877/**
878 * @brief Trigger Manager subsystem initialization
879 *
880 * Initializes the trigger manager subsystem
881 *
882 * @param   None
883 *
884 * @return  int              - Status of the command:
885 *                                 XST_SUCCESS  - Command successful
886 *                                 XST_FAILURE  - Command not successful
887 *
888 ******************************************************************************/
889int trigmngr_init(){
890    int status = XST_SUCCESS;
891
892    // Initialize the global variables
893    active_ethernet_id_mask  = 0;
894    trigger_test_flag        = 0;
895
896    // Initialize Trigger Processor
897
898    // Set all reset bits (disable all triggers)
899    trigmngr_disable_all_triggers();
900
901    // Set all trigger delays to zero
902    trigger_proc_in_eth_A_set_delay(0);
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);
908    trigger_proc_in_eth_B_set_delay(0);
909
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);
916   
917    // Set the debounce mode on all external trigger inputs
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);
922
923    // De-assert all software trigger bits
924    trigger_proc_in_eth_A_lower_trigger();
925    trigger_proc_in_software_lower_trigger();
926    trigger_proc_in_eth_B_lower_trigger();
927
928    // Clear all connections to output triggers
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);
935
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);
943
944    // Set defaults for the Energy Trigger
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
947    wl_packet_detect_set_idle_duration(10);
948
949    wl_packet_detect_set_config(WL_PACKET_DETECT_CONFIG_REG_RESET);
950    wl_packet_detect_clear_config(WL_PACKET_DETECT_CONFIG_REG_RESET);
951   
952    // Initialize the Ethernet triggers
953    eth_trigger_init();
954
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    //
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
977
978    // Enable all triggers
979    trigmngr_enable_all_triggers();
980
981    // Disable the Ethernet triggers
982    trigger_proc_in_eth_A_trig_disable();
983    trigger_proc_in_eth_B_trig_disable();
984
985    return status;
986}
987
988
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
1008void wl_pkt_proc_set_ethernet_id(u32 ethernet_id, u32 eth_dev_num);
1009
1010
1011/******************************** Functions **********************************/
1012
1013
1014/*****************************************************************************/
1015/**
1016 * Ethernet Trigger Control
1017 *
1018 * These methods will control the the Ethernet triggers.
1019 *
1020 *****************************************************************************/
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
1028u32  get_eth_trigger_type(u32 eth_dev_num) {
1029    u32 ret_val = ETH_TRIG_INVALID;
1030
1031    switch(eth_dev_num) {
1032        case WL_ETH_A:
1033            ret_val = eth_A_sw_ethernet_trigger_enable;
1034        break;
1035        case WL_ETH_B:
1036            ret_val = eth_B_sw_ethernet_trigger_enable;
1037        break;
1038    }
1039
1040    return ret_val;
1041}
1042
1043
1044void set_eth_trigger_type(u32 type, u32 eth_dev_num) {
1045    switch(eth_dev_num) {
1046        case WL_ETH_A:
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            }
1057        break;
1058        case WL_ETH_B:
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            }
1069        break;
1070    }
1071}
1072
1073
1074
1075void update_eth_trigger_control(u32 ethernet_id, u32 eth_dev_num) {
1076
1077    switch(eth_dev_num) {
1078        case WL_ETH_A:
1079            if (eth_A_sw_ethernet_trigger_enable) {
1080                // If we are using SW triggers, clear the fast trigger detector
1081                wl_pkt_proc_set_ethernet_id(0, eth_dev_num);
1082            } else {
1083                // If we are using HW triggers, update the fast trigger detector
1084                wl_pkt_proc_set_ethernet_id(ethernet_id, eth_dev_num);
1085            }
1086           
1087            // If there are no active triggers, then disable the Ethernet trigger
1088            if (ethernet_id) {
1089                trigger_proc_in_eth_A_trig_enable();
1090            } else {
1091                trigger_proc_in_eth_A_trig_disable();
1092            }
1093        break;
1094        case WL_ETH_B:
1095            if (eth_B_sw_ethernet_trigger_enable) {
1096                // If we are using SW triggers, clear the fast trigger detector
1097                wl_pkt_proc_set_ethernet_id(0, eth_dev_num);
1098            } else {
1099                // If we are using HW triggers, update the fast trigger detector
1100                wl_pkt_proc_set_ethernet_id(ethernet_id, eth_dev_num);
1101            }
1102           
1103            // If there are no active triggers, then disable the Ethernet trigger
1104            if (ethernet_id) {
1105                trigger_proc_in_eth_B_trig_enable();
1106            } else {
1107                trigger_proc_in_eth_B_trig_disable();
1108            }
1109        break;
1110        default:
1111            wl_printf(WL_PRINT_ERROR, print_type_trigger, "Trigger Manager:  Unsupported Ethernet device\n");
1112            return;
1113        break;
1114    }
1115}
1116
1117
1118
1119/*****************************************************************************/
1120/**
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) {
1134
1135    // Ethernet device
1136    void                   * pkt_template;
1137    void                   * pkt_ops;
1138    u32                      tmp_ip_addr;
1139
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;
1146
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;
1154
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];
1160
1161    // Set up Ethernet device
1162    switch(eth_dev_num) {
1163        case WL_ETH_A:
1164            pkt_template = (void *)TRIG_MNGR_REG_PKT_TEMPLATE_0;
1165            pkt_ops      = (void *)TRIG_MNGR_REG_PKT_OPS_0;
1166            tmp_ip_addr  = (u32) WL_ETH_A_IP_ADDR_BASE;
1167        break;
1168        case WL_ETH_B:
1169            pkt_template = (void *)TRIG_MNGR_REG_PKT_TEMPLATE_1;
1170            pkt_ops      = (void *)TRIG_MNGR_REG_PKT_OPS_1;
1171            tmp_ip_addr  = (u32) WL_ETH_B_IP_ADDR_BASE;
1172        break;
1173        default:
1174            wl_printf(WL_PRINT_ERROR, print_type_trigger, "Trigger Manager:  Unsupported Ethernet device\n");
1175            return;
1176        break;
1177    }
1178
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);
1182
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));
1190
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);
1199
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
1203
1204    hdr_udp->src_port         = 0;
1205    hdr_udp->dest_port        = Xil_Htons((u16)NODE_UDP_MCAST_BASE);           // WARPLab broadcast port
1206
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;
1210
1211    trig_payload[0]           = Xil_Htonl(ethernet_id);
1212
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);
1216
1217    // If necessary, this will print the template array:
1218    //
1219    // print_array_u8(template0, pkt_match_len);
1220    //
1221
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));
1228
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;
1237
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;
1242
1243    // UDP src/dest ports must match
1244    hdr_udp->src_port         = U16_OP_NC;
1245    hdr_udp->dest_port        = U16_OP_EQ;
1246
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;
1251
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;
1256
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);
1260
1261    // If necessary, this will print the ops array:
1262    //
1263    // print_array_u8(ops0, pkt_match_len);
1264    //
1265}
1266
1267
Note: See TracBrowser for help on using the repository browser.