[4332] | 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 | |
---|
[2044] | 12 | classdef wl_node_group < wl_node |
---|
[2919] | 13 | |
---|
[2041] | 14 | properties (SetAccess = protected) |
---|
[2919] | 15 | nodes; % List of nodes in the node group |
---|
[2041] | 16 | end |
---|
[2919] | 17 | |
---|
| 18 | properties (SetAccess = public) |
---|
| 19 | verify_write_iq_checksum; % Enable checking for WriteIQ checksum |
---|
| 20 | end |
---|
| 21 | |
---|
[2041] | 22 | methods |
---|
[2044] | 23 | function obj = wl_node_group(varargin) |
---|
[2919] | 24 | obj.verify_write_iq_checksum = 1; % Enabled checking by default. |
---|
[2041] | 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 |
---|
[4332] | 31 | |
---|
[2041] | 32 | if(numel(ID)~=1) |
---|
[2865] | 33 | error('ID argument must be a scalar between 0 and 7'); |
---|
[2041] | 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 |
---|
[2865] | 54 | error('ID argument must be a scalar between 0 and 7'); |
---|
[2041] | 55 | end |
---|
[4332] | 56 | |
---|
[2041] | 57 | % Get ini configuration file |
---|
| 58 | configFile = which('wl_config.ini'); |
---|
| 59 | if(isempty(configFile)) |
---|
[2865] | 60 | error('cannot find wl_config.ini. please run wl_setup.m'); |
---|
[4332] | 61 | end |
---|
| 62 | |
---|
[2041] | 63 | readKeys = {'network','','transport',''}; |
---|
| 64 | transportType = inifile(configFile,'read',readKeys); |
---|
| 65 | transportType = transportType{1}; |
---|
| 66 | |
---|
| 67 | switch(transportType) |
---|
| 68 | case 'java' |
---|
[4695] | 69 | obj.transport = wl_transport_eth_udp_java_bcast(); |
---|
[2041] | 70 | obj.transport.open(); |
---|
[2149] | 71 | case 'wl_mex_udp' |
---|
[4695] | 72 | obj.transport = wl_transport_eth_udp_mex_bcast(); |
---|
[2084] | 73 | obj.transport.open(); |
---|
[2041] | 74 | end |
---|
| 75 | |
---|
| 76 | obj.transport.hdr.destID = obj.ID; |
---|
| 77 | end |
---|
| 78 | |
---|
[4332] | 79 | |
---|
[2041] | 80 | function addNodes(obj,nodes) |
---|
[4358] | 81 | nodes.wl_transportCmd('add_node_group_id', obj.ID); |
---|
[2041] | 82 | obj.nodes = [obj.nodes(:);nodes(:)].'; |
---|
| 83 | obj.updateGroupModules(); |
---|
| 84 | end |
---|
| 85 | |
---|
[4332] | 86 | |
---|
[2919] | 87 | function removeNodes(obj,nodes) |
---|
[2041] | 88 | for n = 1:length(nodes) |
---|
| 89 | I = find(obj.nodes == nodes(n)); |
---|
| 90 | if(isempty(I)) |
---|
[4358] | 91 | error('Node %d is not a member of this node group', nodes(n).ID); |
---|
[2041] | 92 | else |
---|
[4358] | 93 | nodes(n).wl_transportCmd('clear_node_group_id', obj.ID); |
---|
[2041] | 94 | obj.nodes(I) = []; |
---|
| 95 | end |
---|
| 96 | end |
---|
| 97 | obj.updateGroupModules(); |
---|
| 98 | end |
---|
[2919] | 99 | |
---|
[4332] | 100 | |
---|
[2919] | 101 | function setHwVer(obj, hwVer) |
---|
| 102 | obj.hwVer = hwVer; |
---|
| 103 | end |
---|
| 104 | |
---|
[4332] | 105 | |
---|
[2919] | 106 | function verify_writeIQ_checksum(obj, checksum) |
---|
[4332] | 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 | % |
---|
[4695] | 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 |
---|
[2919] | 114 | |
---|
[4695] | 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 |
---|
[4358] | 122 | end |
---|
[2919] | 123 | end |
---|
| 124 | |
---|
[4332] | 125 | |
---|
[2041] | 126 | function out = sendCmd(obj, cmd) |
---|
[4332] | 127 | % Node groups can't receive anything. So we'll just silently |
---|
| 128 | % pass the command along to the sendCmd_noresp method. |
---|
| 129 | % |
---|
[4695] | 130 | sendCmd_noresp(obj, cmd); |
---|
[2919] | 131 | |
---|
[4695] | 132 | out = wl_resp(); |
---|
[2041] | 133 | end |
---|
| 134 | |
---|
[4332] | 135 | |
---|
[2041] | 136 | function sendCmd_noresp(obj, cmd) |
---|
[4332] | 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 |
---|
[2041] | 142 | % the command and then immediately return. |
---|
[4332] | 143 | % |
---|
[4695] | 144 | obj.transport.send('message', cmd.serialize()); |
---|
[2041] | 145 | end |
---|
| 146 | |
---|
[4332] | 147 | |
---|
[2041] | 148 | function out = receiveResp(obj) |
---|
[4358] | 149 | error('NoResponses', 'Node groups use a broadcast transport and cannot receive responses from WARP nodes.') |
---|
[2041] | 150 | end |
---|
[2919] | 151 | |
---|
[4332] | 152 | |
---|
[2041] | 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 | |
---|
[4332] | 160 | |
---|
[2041] | 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 |
---|
[4332] | 182 | end % end classdef |
---|