2 import "goby/acomms/protobuf/driver_base.proto";
3 import "goby/acomms/protobuf/modem_message.proto";
4 import "goby/protobuf/option_extensions.proto";
5 import "dccl/option_extensions.proto";
7 package goby.acomms.micromodem.protobuf;
9 message NarrowBandLBLParams
11 // for MICROMODEM_NARROWBAND_LBL_RANGING
12 optional uint32 transmit_freq = 1; // in hertz
13 optional uint32 transmit_ping_ms = 2; // length of tx ping
14 repeated uint32 receive_freq =
15 3; // in hertz, first element (0) == beacon A, etc.
16 optional uint32 receive_ping_ms = 4; // length of rx ping
18 optional uint32 turnaround_ms = 5;
19 optional bool transmit_flag = 6
21 true]; // Flag to indicate whether the transmit signal is
22 // actually sent (1), or whether the ping is initiated
23 // with an external synchronization pulse (0).
26 optional uint32 lbl_max_range = 7 [default = 2000];
29 message REMUSLBLParams
31 // for MICROMODEM_REMUS_LBL_RANGING
32 // LSB->MSB is LBL beacons 1,2,3,... true is enabled, false is disabled
33 // enable four beacons is b1111 == d15
34 optional uint32 enable_beacons = 1 [default = 15];
35 optional uint32 turnaround_ms = 2 [default = 50];
38 optional uint32 lbl_max_range = 3 [default = 1000];
41 message GenericLBLParams
43 // for MICROMODEM_GENERIC_LBL_RANGING
44 optional uint32 transmit_freq = 1; // in hertz
45 optional uint32 n_bits =
46 2; // number of bits to use from the signal sequence, same for outgoing
47 // as well as incoming pings
48 optional uint64 transmit_seq_code =
49 3; // outgoing sequence bits, packed into a 64 bit int
50 optional uint32 receive_freq =
51 4; // in hertz, first element (0) == beacon A, etc.
52 repeated uint64 receive_seq_code = 5; // signals to receive
53 optional uint32 bandwidth =
54 6; // chiprate/bandwidth, of outgoing and receive signals
56 optional uint32 turnaround_ms = 7;
58 optional uint32 lbl_max_range = 8 [default = 2000];
63 // for MICROMODEM_FM_SWEEP
64 required double start_freq = 1;
65 required double stop_freq = 2;
66 required double duration_ms = 3;
67 optional uint32 number_repetitions = 4 [default = 1];
68 optional double repetition_period_ms = 5 [default = 1000];
71 message MSequenceParams
73 // for MICROMODEM_M_SEQUENCE
74 required uint32 seqlen_bits =
75 1; // Sequence length, bits. Should be 2k-1, where k={4...16}
76 required uint32 number_repetitions =
77 2; // number of repetitions, between 3 to 60.
78 required uint32 carrier_cycles_per_chip = 3;
79 required uint32 carrier_freq = 4; // carrier, Hz
84 // reset all NVRAM settings to factory before
85 // setting ours ($CCCFG,ALL,0)
86 optional bool reset_nvram = 1 [default = false];
88 // add NVRAM configuration sentences to send to the modem
89 // on startup (e.g. "$CACFG,SRC,1"). Omit the "$CACFG," here.
90 // To reinitialize all values to factory settings, send "ALL,0"
91 repeated string nvram_cfg = 2; // e.g. "SRC,3"
93 // set to a non-zero value to indicate that we are using the hydroid
94 // gateway buoy which has a non-standard sentence structure (#M / !M
95 // prefixes) *do not set for the normal WHOI Micro-Modem*
96 optional uint32 hydroid_gateway_id = 3 [default = 0];
98 // LBL parameters can be set globally here or on a per-transmission
100 optional NarrowBandLBLParams narrowband_lbl = 4;
101 optional REMUSLBLParams remus_lbl = 5;
103 optional int32 keep_alive_seconds = 6 [default = 10];
105 optional int32 allowed_skew_ms = 7 [default = 1000];
107 optional GenericLBLParams generic_lbl = 8;
109 optional FMSweepParams fm_sweep = 9;
110 optional MSequenceParams m_sequence = 10;
112 optional bool use_application_acks = 20 [default = false];
113 repeated uint32 additional_application_ack_modem_id = 21;
115 optional bool query_cfg_on_startup = 22 [default = true];
117 optional bool pad_partial_frames = 23 [
119 (goby.field).description =
120 "Pad partial frames with trailing zeros to reach the full frame length. This was a workaround for a bug in early versions of the MM2 firmware."
125 required int32 mm_major = 1;
126 required int32 mm_minor = 2;
127 required int32 mm_patch = 3;
130 optional Revision revision = 30;
132 optional bool use_base64_fdp = 40 [default = false];
135 extend goby.acomms.protobuf.DriverConfig
137 optional Config config = 1000;
142 INVALID_CLOCK_MODE = -1;
143 NO_SYNC_TO_PPS_AND_CCCLK_BAD = 0;
144 NO_SYNC_TO_PPS_AND_CCCLK_GOOD = 1;
145 SYNC_TO_PPS_AND_CCCLK_BAD = 2;
146 SYNC_TO_PPS_AND_CCCLK_GOOD = 3;
151 option (dccl.msg).id = 128;
152 option (dccl.msg).max_bytes = 32;
153 option (dccl.msg).unit_system = "si";
154 option (dccl.msg).codec_version = 3;
157 repeated double one_way_travel_time = 1 [
158 (dccl.field).min = 0,
159 (dccl.field).max = 30,
160 (dccl.field).precision = 3,
161 (dccl.field).max_repeat = 4,
162 (dccl.field).units = {base_dimensions: "T"}
166 OWTT_EXACT = 1; // one_way_travel_time reported is correct and known
167 OWTT_SECOND_AMBIGUOUS = 2; // one way travel time fractional second is
168 // correct, but second is unknown
170 optional OWTTAmbiguity ambiguity = 2 [default = OWTT_EXACT];
171 optional bool is_one_way_synchronous = 3
172 [default = false]; // if false, type given by ModemTransmission.type
173 optional ClockMode receiver_clk_mode = 4
174 [default = NO_SYNC_TO_PPS_AND_CCCLK_BAD];
175 optional ClockMode sender_clk_mode = 5
176 [default = NO_SYNC_TO_PPS_AND_CCCLK_BAD];
181 PACKET_TYPE_UNKNOWN = -1;
186 FLEXIBLE_DATA_PACKET = 5;
191 INVALID_RECEIVE_MODE = -1;
199 INVALID_PSK_ERROR_CODE = -1;
201 BAD_MODULATION_HEADER = 1;
202 BAD_CRC_DATA_HEADER = 2;
203 BAD_CRC_AT_LEAST_ONE_FRAME = 3;
204 ERROR_ACCESSING_COPROC = 4;
205 EQUALIZER_TIMEOUT = 5;
206 MISSED_START_OF_PSK_PACKET = 6;
209 // $CACST,0,223413.0000,0,1440,25,0175,0166,75,01,01,01,03,1,007,006,0,3,3,0,146,03,04,-100,-1,000,-1.2,45,10000,2000
210 message ReceiveStatistics
212 option (dccl.msg) = {
219 // including in "version 0", or the original CACST
220 required ReceiveMode mode = 1;
221 required uint64 time = 2 [(dccl.field) = {
223 units: {prefix: "micro" base_dimensions: "T"}
225 required ClockMode clock_mode = 3;
226 optional int32 mfd_peak = 4 [(dccl.field).omit = true];
227 required int32 mfd_power = 5
228 [(dccl.field).min = -30, (dccl.field).max = 40];
229 required int32 mfd_ratio = 6
230 [(dccl.field).min = 0, (dccl.field).max = 16383];
231 optional int32 spl = 7 [(dccl.field).omit = true];
232 optional int32 shf_agn = 8 [(dccl.field).omit = true];
233 optional int32 shf_ainpshift = 9 [(dccl.field).omit = true];
234 optional int32 shf_ainshift = 10 [(dccl.field).omit = true];
235 optional int32 shf_mfdshift = 11 [(dccl.field).omit = true];
236 optional int32 shf_p2bshift = 12 [(dccl.field).omit = true];
237 required int32 rate = 13 [(dccl.field).min = -1, (dccl.field).max = 6];
238 required int32 source = 14 [(dccl.field).min = 0, (dccl.field).max = 127];
239 required int32 dest = 15 [(dccl.field).min = 0, (dccl.field).max = 127];
240 required PSKErrorCode psk_error_code = 16;
241 required PacketType packet_type = 17;
242 required int32 number_frames = 18
243 [(dccl.field).min = 0, (dccl.field).max = 8];
244 required int32 number_bad_frames = 19
245 [(dccl.field).min = 0, (dccl.field).max = 8];
246 required int32 snr_rss = 20 [(dccl.field).min = 0, (dccl.field).max = 255];
247 required int32 snr_in = 21 [(dccl.field).min = -10, (dccl.field).max = 30];
248 required int32 snr_out = 22 [(dccl.field).min = 0, (dccl.field).max = 25];
249 required int32 snr_symbols = 23
250 [(dccl.field).min = 0, (dccl.field).max = 30];
251 required int32 mse_equalizer = 24
252 [(dccl.field).min = -30, (dccl.field).max = 5];
253 required int32 data_quality_factor = 25
254 [(dccl.field).min = 0, (dccl.field).max = 255];
255 required double doppler = 26 [
256 (dccl.field).min = -3,
257 (dccl.field).max = 3,
258 (dccl.field).precision = 1
260 required int32 stddev_noise = 27
261 [(dccl.field).min = 0, (dccl.field).max = 255];
262 required int32 carrier_freq = 28
263 [(dccl.field).min = 100, (dccl.field).max = 30000];
264 required int32 bandwidth = 29
265 [(dccl.field).min = 1000, (dccl.field).max = 5000];
267 // new for "version 6+", firmware 0.93.0.52+
268 optional int32 version = 30 [default = 0, (dccl.field).omit = true];
269 optional string date = 31 [(dccl.field).omit = true];
270 optional int32 pcm = 32 [(dccl.field).omit = true];
275 INVALID_TRANSMIT_MODE = -1;
276 TRANSMIT_SUCCESSFUL = 0;
283 message TransmitStatistics
285 optional string date = 1;
286 optional string time = 2;
287 optional ClockMode clock_mode = 3;
288 optional TransmitMode mode = 4;
289 optional int32 probe_length = 5;
290 optional int32 bandwidth = 6;
291 optional int32 carrier_freq = 7;
292 optional int32 rate = 8;
293 optional int32 source = 9;
294 optional int32 dest = 10;
295 optional bool ack_requested = 11;
296 optional int32 number_frames_expected = 12;
297 optional int32 number_frames_sent = 13;
298 optional PacketType packet_type = 14;
299 optional int32 number_bytes = 15;
301 optional int32 version = 100 [default = 0];
304 enum TransmissionType
308 MICROMODEM_TWO_WAY_PING =
309 1; // modem 1 interrogates modem 2; modem 2 replies and modem 1
310 // computes one way travel time: $CCMPC
311 MICROMODEM_REMUS_LBL_RANGING = 2; // modem 1 pings a REMUS network of long
312 // baseline (LBL) beacons: $CCPDT
313 MICROMODEM_NARROWBAND_LBL_RANGING =
314 3; // modem 1 pings up to four transponders: $CCPNT
315 MICROMODEM_MINI_DATA =
316 4; // 13 bits (represented as a 1 frame, 2 byte data transmission where
317 // data is AND'd with 0x1ff) mini data transmission
318 MICROMODEM_FLEXIBLE_DATA =
319 5; // Flexible Data Protocol in Micro-Modem 2: Up to 100 bytes
320 MICROMODEM_HARDWARE_CONTROL = 6; // $CCMEC for writing hardware lines
321 MICROMODEM_HARDWARE_CONTROL_REPLY =
322 7; // $CAMER response to writing hardware lines
323 MICROMODEM_GENERIC_LBL_RANGING =
324 8; // $CCPGT Ping Generic Transponder from host to modem
325 MICROMODEM_FM_SWEEP = 9; // $CCSWP Send an FM sweep
326 MICROMODEM_M_SEQUENCE = 10; // $CCMSQ Send a maximal-length sequence
331 option allow_alias = true;
346 enum HardwareControlMode
354 enum HardwareControlArgument
356 option allow_alias = true;
373 message HardwareControl
375 required HardwareLine line = 1;
376 required HardwareControlMode mode = 2;
377 optional HardwareControlArgument arg = 3 [default = MODE0_ARG];
380 message HardwareControlCommand
382 option (dccl.msg).id = 515;
383 option (dccl.msg).max_bytes = 32;
384 option (dccl.msg).codec_version = 3;
386 required int32 command_src = 1 [
387 (dccl.field).min = 0,
388 (dccl.field).max = 31,
389 (dccl.field).in_head = true
391 required int32 command_dest = 2 [
392 (dccl.field).min = 0,
393 (dccl.field).max = 31,
394 (dccl.field).in_head = true
396 optional uint64 time = 3
397 [(dccl.field).in_head = true, (dccl.field).codec = "_time"];
399 // destination of $CCMEC command (defaults to same as command_dest)
400 optional int32 hw_ctl_dest = 4
401 [(dccl.field).min = 0, (dccl.field).max = 31];
403 optional HardwareControl control = 5;
408 optional TransmissionType type = 1 [
409 (goby.field).description =
410 "Type of transmission if base `type` == DRIVER_SPECIFIC",
414 // LBL parameters will be merged with configuration parameters. If a
415 // parameter is set in both places, the ones set here take precedence.
416 optional NarrowBandLBLParams narrowband_lbl = 2 [(dccl.field).omit = true];
417 optional REMUSLBLParams remus_lbl = 3 [(dccl.field).omit = true];
419 optional RangingReply ranging_reply = 4
420 [(dccl.field).omit = true, (goby.field).cfg.action = NEVER];
421 repeated ReceiveStatistics receive_stat = 5
422 [(dccl.field).omit = true,
423 (goby.field).cfg.action = NEVER]; // $CACST
424 repeated TransmitStatistics transmit_stat = 6
425 [(dccl.field).omit = true,
426 (goby.field).cfg.action = NEVER]; // $CAXST
427 repeated int32 frame_with_bad_crc = 7
428 [(dccl.field).omit = true, (goby.field).cfg.action = NEVER];
430 optional HardwareControl hw_ctl = 8 [(dccl.field).omit = true];
432 optional GenericLBLParams generic_lbl = 9 [(dccl.field).omit = true];
433 optional FMSweepParams fm_sweep = 10 [(dccl.field).omit = true];
434 optional MSequenceParams m_sequence = 11 [(dccl.field).omit = true];
437 extend goby.acomms.protobuf.ModemTransmission
439 optional Transmission transmission = 1000;
442 message MMApplicationAck
444 option (dccl.msg).id = 10;
445 option (dccl.msg).max_bytes = 32;
446 option (dccl.msg).codec_version = 3;
448 repeated AckPart part = 1 [(dccl.field).max_repeat = 4];
451 required int32 ack_dest = 1
452 [(dccl.field).min = 0, (dccl.field).max = 31];
454 required uint32 acked_frames = 2
455 [(dccl.field).min = 0, (dccl.field).max = 0xFFFFFFFF];
458 required bool ack_requested = 3;
459 required uint32 frame_start = 4
460 [(dccl.field).min = 0, (dccl.field).max = 31];