1 | %------------------------------------------------------------------------- |
---|
2 | % WARPLab Framework |
---|
3 | % |
---|
4 | % Copyright 2013, Mango Communications. All rights reserved. |
---|
5 | % Distributed under the WARP license (http://warpproject.org/license) |
---|
6 | % |
---|
7 | % Chris Hunter (chunter [at] mangocomm.com) |
---|
8 | % Patrick Murphy (murphpo [at] mangocomm.com) |
---|
9 | % Erik Welsh (welsh [at] mangocomm.com) |
---|
10 | %------------------------------------------------------------------------- |
---|
11 | |
---|
12 | classdef wl_node_group < wl_node |
---|
13 | |
---|
14 | properties (SetAccess = protected) |
---|
15 | nodes; % List of nodes in the node group |
---|
16 | end |
---|
17 | |
---|
18 | properties (SetAccess = public) |
---|
19 | verify_write_iq_checksum; % Enable checking for WriteIQ checksum |
---|
20 | end |
---|
21 | |
---|
22 | methods |
---|
23 | function obj = wl_node_group(varargin) |
---|
24 | obj.verify_write_iq_checksum = 1; % Enabled checking by default. |
---|
25 | |
---|
26 | if(isempty(varargin)) |
---|
27 | ID = -1; %Invalid ID just so the error message is caught |
---|
28 | else |
---|
29 | ID = varargin{1}; |
---|
30 | end |
---|
31 | |
---|
32 | if(numel(ID)~=1) |
---|
33 | error('ID argument must be a scalar between 0 and 7'); |
---|
34 | end |
---|
35 | |
---|
36 | switch(ID) |
---|
37 | case 0 |
---|
38 | obj.ID = hex2dec('01'); |
---|
39 | case 1 |
---|
40 | obj.ID = hex2dec('02'); |
---|
41 | case 2 |
---|
42 | obj.ID = hex2dec('04'); |
---|
43 | case 3 |
---|
44 | obj.ID = hex2dec('08'); |
---|
45 | case 4 |
---|
46 | obj.ID = hex2dec('10'); |
---|
47 | case 5 |
---|
48 | obj.ID = hex2dec('20'); |
---|
49 | case 6 |
---|
50 | obj.ID = hex2dec('40'); |
---|
51 | case 7 |
---|
52 | obj.ID = hex2dec('80'); |
---|
53 | otherwise |
---|
54 | error('ID argument must be a scalar between 0 and 7'); |
---|
55 | end |
---|
56 | |
---|
57 | % Get ini configuration file |
---|
58 | configFile = which('wl_config.ini'); |
---|
59 | if(isempty(configFile)) |
---|
60 | error('cannot find wl_config.ini. please run wl_setup.m'); |
---|
61 | end |
---|
62 | |
---|
63 | readKeys = {'network','','transport',''}; |
---|
64 | transportType = inifile(configFile,'read',readKeys); |
---|
65 | transportType = transportType{1}; |
---|
66 | |
---|
67 | switch(transportType) |
---|
68 | case 'java' |
---|
69 | obj.transport = wl_transport_eth_udp_java_bcast(); |
---|
70 | obj.transport.open(); |
---|
71 | case 'wl_mex_udp' |
---|
72 | obj.transport = wl_transport_eth_udp_mex_bcast(); |
---|
73 | obj.transport.open(); |
---|
74 | end |
---|
75 | |
---|
76 | obj.transport.hdr.destID = obj.ID; |
---|
77 | end |
---|
78 | |
---|
79 | |
---|
80 | function addNodes(obj,nodes) |
---|
81 | nodes.wl_transportCmd('add_node_group_id', obj.ID); |
---|
82 | obj.nodes = [obj.nodes(:);nodes(:)].'; |
---|
83 | obj.updateGroupModules(); |
---|
84 | end |
---|
85 | |
---|
86 | |
---|
87 | function removeNodes(obj,nodes) |
---|
88 | for n = 1:length(nodes) |
---|
89 | I = find(obj.nodes == nodes(n)); |
---|
90 | if(isempty(I)) |
---|
91 | error('Node %d is not a member of this node group', nodes(n).ID); |
---|
92 | else |
---|
93 | nodes(n).wl_transportCmd('clear_node_group_id', obj.ID); |
---|
94 | obj.nodes(I) = []; |
---|
95 | end |
---|
96 | end |
---|
97 | obj.updateGroupModules(); |
---|
98 | end |
---|
99 | |
---|
100 | |
---|
101 | function setHwVer(obj, hwVer) |
---|
102 | obj.hwVer = hwVer; |
---|
103 | end |
---|
104 | |
---|
105 | |
---|
106 | function verify_writeIQ_checksum(obj, checksum) |
---|
107 | % This is a callback to verify the WriteIQ checksum in the case that WriteIQ is called by a |
---|
108 | % broadcast transport. Need to verify the checksum for each node in the node group. |
---|
109 | % |
---|
110 | if ( obj.verify_write_iq_checksum == 1 ) |
---|
111 | if ( numel(checksum) > 1 ) |
---|
112 | error('Cannot verify more than one checksum at a time.') |
---|
113 | end |
---|
114 | |
---|
115 | for i = 1:numel(obj.nodes) |
---|
116 | node_checksum = obj.nodes(i).wl_basebandCmd('write_iq_checksum'); |
---|
117 | |
---|
118 | if ( node_checksum ~= checksum(1) ) |
---|
119 | warning('Checksums do not match on node %d: %d != %d', obj.ID, node_checksum, checksum) |
---|
120 | end |
---|
121 | end |
---|
122 | end |
---|
123 | end |
---|
124 | |
---|
125 | |
---|
126 | function out = sendCmd(obj, cmd) |
---|
127 | % Node groups can't receive anything. So we'll just silently |
---|
128 | % pass the command along to the sendCmd_noresp method. |
---|
129 | % |
---|
130 | sendCmd_noresp(obj, cmd); |
---|
131 | |
---|
132 | out = wl_resp(); |
---|
133 | end |
---|
134 | |
---|
135 | |
---|
136 | function sendCmd_noresp(obj, cmd) |
---|
137 | % This method is responsible for serializing the command |
---|
138 | % objects provided by each of the components of WARPLab into a |
---|
139 | % vector of values that the transport object can send. This |
---|
140 | % method is used when a board should not send an immediate |
---|
141 | % response. The transport object is non-blocking -- it will send |
---|
142 | % the command and then immediately return. |
---|
143 | % |
---|
144 | obj.transport.send('message', cmd.serialize()); |
---|
145 | end |
---|
146 | |
---|
147 | |
---|
148 | function out = receiveResp(obj) |
---|
149 | error('NoResponses', 'Node groups use a broadcast transport and cannot receive responses from WARP nodes.') |
---|
150 | end |
---|
151 | |
---|
152 | |
---|
153 | function disp(obj) |
---|
154 | fprintf('Node Group ID: %d\n',obj.ID); |
---|
155 | fprintf('Node Members:\n'); |
---|
156 | disp(obj.nodes); |
---|
157 | end |
---|
158 | end |
---|
159 | |
---|
160 | |
---|
161 | methods (Hidden = true) |
---|
162 | function updateGroupModules(obj) |
---|
163 | if(~isempty(obj.nodes)) |
---|
164 | obj.baseband = obj.nodes(1).baseband; |
---|
165 | obj.num_interfacesGroups = obj.nodes(1).num_interfacesGroups; |
---|
166 | obj.num_interfaces = obj.nodes(1).num_interfaces; |
---|
167 | obj.interfaceGroups = obj.nodes(1).interfaceGroups; |
---|
168 | obj.interfaceIDs = obj.nodes(1).interfaceIDs; |
---|
169 | obj.trigger_manager = obj.nodes(1).trigger_manager; |
---|
170 | obj.user = obj.nodes(1).user; |
---|
171 | else |
---|
172 | obj.baseband = []; |
---|
173 | obj.num_interfacesGroups = []; |
---|
174 | obj.num_interfaces = []; |
---|
175 | obj.interfaceGroups = []; |
---|
176 | obj.interfaceIDs = []; |
---|
177 | obj.trigger_manager = []; |
---|
178 | obj.user = []; |
---|
179 | end |
---|
180 | end |
---|
181 | end |
---|
182 | end % end classdef |
---|