• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SpiNNakerManchester / JavaSpiNNaker / 6270187726

21 Sep 2023 01:49PM UTC coverage: 36.862% (-0.2%) from 37.028%
6270187726

push

github

web-flow
Merge pull request #1072 from SpiNNakerManchester/test_blacklist_write

Test blacklist write

12 of 12 new or added lines in 1 file covered. (100.0%)

8660 of 23493 relevant lines covered (36.86%)

1.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

3.7
/SpiNNaker-comms/src/main/java/uk/ac/manchester/spinnaker/transceiver/BMPTransceiverInterface.java
1
/*
2
 * Copyright (c) 2018 The University of Manchester
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package uk.ac.manchester.spinnaker.transceiver;
17

18
import static java.lang.Thread.interrupted;
19
import static java.nio.ByteBuffer.allocate;
20
import static java.nio.ByteOrder.LITTLE_ENDIAN;
21
import static uk.ac.manchester.spinnaker.machine.MemoryLocation.NULL;
22
import static uk.ac.manchester.spinnaker.messages.Constants.WORD_SIZE;
23
import static uk.ac.manchester.spinnaker.messages.Utils.wordAsBuffer;
24
import static uk.ac.manchester.spinnaker.messages.model.PowerCommand.POWER_OFF;
25
import static uk.ac.manchester.spinnaker.messages.model.PowerCommand.POWER_ON;
26
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BLACKLIST_BLANK;
27
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BMP_BOOT_BLACKLIST_OFFSET;
28
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BMP_BOOT_CRC_OFFSET;
29
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BMP_BOOT_SECTOR_ADDR;
30
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BMP_BOOT_SECTOR_SIZE;
31
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.SF_BL_ADDR;
32
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.SF_BL_LEN;
33
import static uk.ac.manchester.spinnaker.transceiver.Utils.crc;
34
import static uk.ac.manchester.spinnaker.transceiver.Utils.fill;
35

36
import java.io.File;
37
import java.io.IOException;
38
import java.io.InputStream;
39
import java.nio.ByteBuffer;
40
import java.util.Collection;
41
import java.util.Set;
42

43
import javax.validation.Valid;
44
import javax.validation.constraints.NotNull;
45
import javax.validation.constraints.Positive;
46

47
import com.google.errorprone.annotations.CheckReturnValue;
48

49
import uk.ac.manchester.spinnaker.machine.MemoryLocation;
50
import uk.ac.manchester.spinnaker.machine.board.BMPBoard;
51
import uk.ac.manchester.spinnaker.machine.board.BMPCoords;
52
import uk.ac.manchester.spinnaker.messages.bmp.WriteFlashBuffer;
53
import uk.ac.manchester.spinnaker.messages.model.ADCInfo;
54
import uk.ac.manchester.spinnaker.messages.model.Blacklist;
55
import uk.ac.manchester.spinnaker.messages.model.FPGA;
56
import uk.ac.manchester.spinnaker.messages.model.FPGALinkRegisters;
57
import uk.ac.manchester.spinnaker.messages.model.FPGAMainRegisters;
58
import uk.ac.manchester.spinnaker.messages.model.FPGARecevingLinkCounters;
59
import uk.ac.manchester.spinnaker.messages.model.FPGASendingLinkCounters;
60
import uk.ac.manchester.spinnaker.messages.model.FirmwareDescriptor;
61
import uk.ac.manchester.spinnaker.messages.model.FirmwareDescriptors;
62
import uk.ac.manchester.spinnaker.messages.model.LEDAction;
63
import uk.ac.manchester.spinnaker.messages.model.PowerCommand;
64
import uk.ac.manchester.spinnaker.messages.model.VersionInfo;
65
import uk.ac.manchester.spinnaker.utils.MappableIterable;
66

67
/**
68
 * The interface supported by the {@link Transceiver} for talking to a BMP.
69
 * Emulates a lot of default handling and variant-type handling by Python.
70
 * <p>
71
 * Note that operations on a particular BMP (i.e., with the same
72
 * {@link BMPCoords}) are <strong>always</strong> thread-unsafe.
73
 *
74
 * @author Donal Fellows
75
 */
76
public interface BMPTransceiverInterface extends AutoCloseable {
77
        /**
78
         * Set the default BMP coordinates, at least for cabinet and frame.
79
         *
80
         * @param bmp
81
         *            The new default coordinates.
82
         */
83
        void bind(@Valid BMPCoords bmp);
84

85
        /**
86
         * @return The currently bound BMP coordinates. Defaults to 0,0 if not set
87
         *         by {@link #bind(BMPCoords)}.
88
         */
89
        BMPCoords getBoundBMP();
90

91
        /**
92
         * List which boards are actually available to be manipulated by a
93
         * particular BMP.
94
         *
95
         * @param bmp
96
         *            Which BMP are we asking?
97
         * @return Ordered list of board identifiers.
98
         * @throws IOException
99
         *             If anything goes wrong with networking.
100
         * @throws ProcessException
101
         *             If SpiNNaker rejects a message.
102
         * @throws InterruptedException
103
         *             If the communications were interrupted.
104
         */
105
        @ParallelSafeWithCare
106
        @CheckReturnValue
107
        MappableIterable<BMPBoard> availableBoards(@Valid BMPCoords bmp)
108
                        throws IOException, ProcessException, InterruptedException;
109

110
        /**
111
         * List which boards are actually available to be manipulated by the current
112
         * bound BMP.
113
         *
114
         * @return Ordered list of board identifiers.
115
         * @throws IOException
116
         *             If anything goes wrong with networking.
117
         * @throws ProcessException
118
         *             If SpiNNaker rejects a message.
119
         * @throws InterruptedException
120
         *             If the communications were interrupted.
121
         */
122
        @ParallelSafeWithCare
123
        @CheckReturnValue
124
        default MappableIterable<BMPBoard> availableBoards()
125
                        throws IOException, ProcessException, InterruptedException {
126
                return availableBoards(getBoundBMP());
×
127
        }
128

129
        /**
130
         * Power on the whole machine.
131
         * <p>
132
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
133
         * multi-threaded context.
134
         *
135
         * @throws IOException
136
         *             If anything goes wrong with networking.
137
         * @throws ProcessException
138
         *             If SpiNNaker rejects a message.
139
         * @throws InterruptedException
140
         *             If the thread is interrupted while waiting.
141
         */
142
        @ParallelUnsafe
143
        void powerOnMachine()
144
                        throws InterruptedException, IOException, ProcessException;
145

146
        /**
147
         * Power on some boards in the machine.
148
         * <p>
149
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
150
         * multi-threaded context.
151
         *
152
         * @param boards
153
         *            The boards to power on (managed by default BMP)
154
         * @throws IOException
155
         *             If anything goes wrong with networking.
156
         * @throws ProcessException
157
         *             If SpiNNaker rejects a message.
158
         * @throws InterruptedException
159
         *             If the thread is interrupted while waiting.
160
         */
161
        @ParallelSafeWithCare
162
        default void powerOn(Collection<@Valid BMPBoard> boards)
163
                        throws InterruptedException, IOException, ProcessException {
164
                power(POWER_ON, getBoundBMP(), boards);
×
165
        }
×
166

167
        /**
168
         * Power on a board in the machine.
169
         * <p>
170
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
171
         * multi-threaded context.
172
         *
173
         * @param board
174
         *            The board to power on (managed by default BMP)
175
         * @throws IOException
176
         *             If anything goes wrong with networking.
177
         * @throws ProcessException
178
         *             If SpiNNaker rejects a message.
179
         * @throws InterruptedException
180
         *             If the thread is interrupted while waiting.
181
         */
182
        @ParallelSafeWithCare
183
        default void powerOn(@Valid BMPBoard board)
184
                        throws InterruptedException, IOException, ProcessException {
185
                power(POWER_ON, getBoundBMP(), Set.of(board));
×
186
        }
×
187

188
        /**
189
         * Power off the whole machine.
190
         * <p>
191
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
192
         * multi-threaded context.
193
         *
194
         * @throws IOException
195
         *             If anything goes wrong with networking.
196
         * @throws ProcessException
197
         *             If SpiNNaker rejects a message.
198
         * @throws InterruptedException
199
         *             If the thread is interrupted while waiting.
200
         */
201
        @ParallelUnsafe
202
        void powerOffMachine()
203
                        throws InterruptedException, IOException, ProcessException;
204

205
        /**
206
         * Power off some boards in the machine.
207
         * <p>
208
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
209
         * multi-threaded context.
210
         *
211
         * @param boards
212
         *            The boards to power off (managed by default BMP)
213
         * @throws IOException
214
         *             If anything goes wrong with networking.
215
         * @throws ProcessException
216
         *             If SpiNNaker rejects a message.
217
         * @throws InterruptedException
218
         *             If the thread is interrupted while waiting.
219
         */
220
        @ParallelSafeWithCare
221
        default void powerOff(Collection<@Valid BMPBoard> boards)
222
                        throws InterruptedException, IOException, ProcessException {
223
                power(POWER_OFF, getBoundBMP(), boards);
×
224
        }
×
225

226
        /**
227
         * Power off a board in the machine.
228
         * <p>
229
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
230
         * multi-threaded context.
231
         *
232
         * @param board
233
         *            The board to power off (in the bound BMP)
234
         * @throws IOException
235
         *             If anything goes wrong with networking.
236
         * @throws ProcessException
237
         *             If SpiNNaker rejects a message.
238
         * @throws InterruptedException
239
         *             If the thread is interrupted while waiting.
240
         * @throws InterruptedException
241
         *             If the communications were interrupted.
242
         */
243
        @ParallelSafeWithCare
244
        default void powerOff(@Valid BMPBoard board)
245
                        throws InterruptedException, IOException, ProcessException {
246
                power(POWER_OFF, getBoundBMP(), Set.of(board));
×
247
        }
×
248

249
        /**
250
         * Send a power request to the machine.
251
         * <p>
252
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
253
         * multi-threaded context.
254
         *
255
         * @param powerCommand
256
         *            The power command to send
257
         * @param bmp
258
         *            the coordinates of the BMP; components are zero for a board
259
         *            not in a frame of a cabinet
260
         * @param boards
261
         *            The boards to send the command to
262
         * @throws IOException
263
         *             If anything goes wrong with networking.
264
         * @throws ProcessException
265
         *             If SpiNNaker rejects a message.
266
         * @throws InterruptedException
267
         *             If the thread is interrupted while waiting.
268
         * @throws InterruptedException
269
         *             If the communications were interrupted.
270
         */
271
        @ParallelUnsafe
272
        void power(@NotNull PowerCommand powerCommand, @Valid BMPCoords bmp,
273
                        Collection<@Valid BMPBoard> boards)
274
                        throws InterruptedException, IOException, ProcessException;
275

276
        /**
277
         * Set the LED state of a board in the machine.
278
         *
279
         * @param leds
280
         *            Collection of LED numbers to set the state of (0-7)
281
         * @param action
282
         *            State to set the LED to, either on, off or toggle
283
         * @param bmp
284
         *            the coordinates of the BMP this is targeting
285
         * @param boards
286
         *            Specifies the board to control the LEDs of. The command will
287
         *            actually be sent to the first board in the collection.
288
         * @throws IOException
289
         *             If anything goes wrong with networking.
290
         * @throws ProcessException
291
         *             If SpiNNaker rejects a message.
292
         * @throws InterruptedException
293
         *             If the communications were interrupted.
294
         */
295
        @ParallelSafe
296
        void setLED(Collection<Integer> leds, LEDAction action,
297
                        @Valid BMPCoords bmp, Collection<@Valid BMPBoard> boards)
298
                        throws IOException, ProcessException, InterruptedException;
299

300
        /**
301
         * Set the LED state of a board in the machine.
302
         *
303
         * @param leds
304
         *            Collection of LED numbers to set the state of (0-7)
305
         * @param action
306
         *            State to set the LED to, either on, off or toggle
307
         * @param board
308
         *            Specifies the board to control the LEDs of.
309
         * @throws IOException
310
         *             If anything goes wrong with networking.
311
         * @throws ProcessException
312
         *             If SpiNNaker rejects a message.
313
         * @throws InterruptedException
314
         *             If the communications were interrupted.
315
         */
316
        @ParallelSafe
317
        default void setLED(Collection<Integer> leds, LEDAction action,
318
                        @Valid BMPBoard board)
319
                        throws IOException, ProcessException, InterruptedException {
320
                setLED(leds, action, getBoundBMP(), Set.of(board));
×
321
        }
×
322

323
        /**
324
         * Read a register on a FPGA of a board, assuming the standard FPGA
325
         * configuration.
326
         *
327
         * @param fpga
328
         *            FPGA (0, 1 or 2) to communicate with.
329
         * @param register
330
         *            Register to read.
331
         * @param board
332
         *            which board to request the FPGA register from
333
         * @return the register data
334
         * @throws IOException
335
         *             If anything goes wrong with networking.
336
         * @throws ProcessException
337
         *             If SpiNNaker rejects a message.
338
         * @throws InterruptedException
339
         *             If the communications were interrupted.
340
         */
341
        @ParallelSafe
342
        @CheckReturnValue
343
        default int readFPGARegister(FPGA fpga, FPGAMainRegisters register,
344
                        @Valid BMPBoard board)
345
                        throws IOException, ProcessException, InterruptedException {
346
                return readFPGARegister(fpga, register, getBoundBMP(), board);
×
347
        }
348

349
        /**
350
         * Read a register on a FPGA of a board, assuming the standard FPGA
351
         * configuration.
352
         *
353
         * @param fpga
354
         *            FPGA (0, 1 or 2) to communicate with.
355
         * @param register
356
         *            Register to read.
357
         * @param bmp
358
         *            the coordinates of the BMP this is targeting
359
         * @param board
360
         *            which board to request the FPGA register from
361
         * @return the register data
362
         * @throws IOException
363
         *             If anything goes wrong with networking.
364
         * @throws ProcessException
365
         *             If SpiNNaker rejects a message.
366
         * @throws InterruptedException
367
         *             If the communications were interrupted.
368
         */
369
        @ParallelSafe
370
        @CheckReturnValue
371
        default int readFPGARegister(FPGA fpga, FPGAMainRegisters register,
372
                        @Valid BMPCoords bmp, @Valid BMPBoard board)
373
                        throws IOException, ProcessException, InterruptedException {
374
                return readFPGARegister(fpga, register.getAddress(), bmp, board);
×
375
        }
376

377
        /**
378
         * Read a register on a FPGA of a board, assuming the standard FPGA
379
         * configuration.
380
         *
381
         * @param fpga
382
         *            FPGA (0, 1 or 2) to communicate with.
383
         * @param registerBank
384
         *            Which bank of link registers to read from.
385
         * @param register
386
         *            Register to read.
387
         * @param board
388
         *            which board to request the FPGA register from
389
         * @return the register data
390
         * @throws IOException
391
         *             If anything goes wrong with networking.
392
         * @throws ProcessException
393
         *             If SpiNNaker rejects a message.
394
         * @throws InterruptedException
395
         *             If the communications were interrupted.
396
         */
397
        @ParallelSafe
398
        @CheckReturnValue
399
        default int readFPGARegister(FPGA fpga, int registerBank,
400
                        FPGALinkRegisters register, @Valid BMPBoard board)
401
                        throws IOException, ProcessException, InterruptedException {
402
                return readFPGARegister(fpga, registerBank, register, getBoundBMP(),
×
403
                                board);
404
        }
405

406
        /**
407
         * Read a register on a FPGA of a board, assuming the standard FPGA
408
         * configuration.
409
         *
410
         * @param fpga
411
         *            FPGA (0, 1 or 2) to communicate with.
412
         * @param registerBank
413
         *            Which bank of link registers to read from.
414
         * @param register
415
         *            Register to read.
416
         * @param bmp
417
         *            the coordinates of the BMP this is targeting
418
         * @param board
419
         *            which board to request the FPGA register from
420
         * @return the register data
421
         * @throws IOException
422
         *             If anything goes wrong with networking.
423
         * @throws ProcessException
424
         *             If SpiNNaker rejects a message.
425
         * @throws InterruptedException
426
         *             If the communications were interrupted.
427
         */
428
        @ParallelSafe
429
        @CheckReturnValue
430
        default int readFPGARegister(FPGA fpga, int registerBank,
431
                        FPGALinkRegisters register, @Valid BMPCoords bmp,
432
                        @Valid BMPBoard board)
433
                        throws IOException, ProcessException, InterruptedException {
434
                return readFPGARegister(fpga, register.address(registerBank), bmp,
×
435
                                board);
436
        }
437

438
        /**
439
         * Read a link counter on a FPGA of a board, assuming the standard FPGA
440
         * configuration.
441
         *
442
         * @param fpga
443
         *            FPGA (0, 1 or 2) to communicate with.
444
         * @param linkNumber
445
         *            Which bank of link counters to read from.
446
         * @param counter
447
         *            Counter to read.
448
         * @param board
449
         *            which board to request the FPGA register from
450
         * @return the register data
451
         * @throws IOException
452
         *             If anything goes wrong with networking.
453
         * @throws ProcessException
454
         *             If SpiNNaker rejects a message.
455
         * @throws InterruptedException
456
         *             If the communications were interrupted.
457
         */
458
        @ParallelSafe
459
        @CheckReturnValue
460
        default int readFPGALinkCounter(FPGA fpga, int linkNumber,
461
                        FPGARecevingLinkCounters counter, @Valid BMPBoard board)
462
                        throws IOException, ProcessException, InterruptedException {
463
                return readFPGALinkCounter(fpga, linkNumber, counter, getBoundBMP(),
×
464
                                board);
465
        }
466

467
        /**
468
         * Read a register on a FPGA of a board, assuming the standard FPGA
469
         * configuration.
470
         *
471
         * @param fpga
472
         *            FPGA (0, 1 or 2) to communicate with.
473
         * @param linkNumber
474
         *            Which bank of link counters to read from.
475
         * @param counter
476
         *            Counter to read.
477
         * @param bmp
478
         *            the coordinates of the BMP this is targeting
479
         * @param board
480
         *            which board to request the FPGA register from
481
         * @return the register data
482
         * @throws IOException
483
         *             If anything goes wrong with networking.
484
         * @throws ProcessException
485
         *             If SpiNNaker rejects a message.
486
         * @throws InterruptedException
487
         *             If the communications were interrupted.
488
         */
489
        @ParallelSafe
490
        @CheckReturnValue
491
        default int readFPGALinkCounter(FPGA fpga, int linkNumber,
492
                        FPGARecevingLinkCounters counter, @Valid BMPCoords bmp,
493
                        @Valid BMPBoard board)
494
                        throws IOException, ProcessException, InterruptedException {
495
                return readFPGARegister(fpga, counter.address(linkNumber), bmp, board);
×
496
        }
497

498
        /**
499
         * Read a link counter on a FPGA of a board, assuming the standard FPGA
500
         * configuration.
501
         *
502
         * @param fpga
503
         *            FPGA (0, 1 or 2) to communicate with.
504
         * @param linkNumber
505
         *            Which bank of link counters to read from.
506
         * @param counter
507
         *            Counter to read.
508
         * @param board
509
         *            which board to request the FPGA register from
510
         * @return the register data
511
         * @throws IOException
512
         *             If anything goes wrong with networking.
513
         * @throws ProcessException
514
         *             If SpiNNaker rejects a message.
515
         * @throws InterruptedException
516
         *             If the communications were interrupted.
517
         */
518
        @ParallelSafe
519
        @CheckReturnValue
520
        default int readFPGALinkCounter(FPGA fpga, int linkNumber,
521
                        FPGASendingLinkCounters counter, @Valid BMPBoard board)
522
                        throws IOException, ProcessException, InterruptedException {
523
                return readFPGALinkCounter(fpga, linkNumber, counter, getBoundBMP(),
×
524
                                board);
525
        }
526

527
        /**
528
         * Read a register on a FPGA of a board, assuming the standard FPGA
529
         * configuration.
530
         *
531
         * @param fpga
532
         *            FPGA (0, 1 or 2) to communicate with.
533
         * @param linkNumber
534
         *            Which bank of link counters to read from.
535
         * @param counter
536
         *            Counter to read.
537
         * @param bmp
538
         *            the coordinates of the BMP this is targeting
539
         * @param board
540
         *            which board to request the FPGA register from
541
         * @return the register data
542
         * @throws IOException
543
         *             If anything goes wrong with networking.
544
         * @throws ProcessException
545
         *             If SpiNNaker rejects a message.
546
         * @throws InterruptedException
547
         *             If the communications were interrupted.
548
         */
549
        @ParallelSafe
550
        @CheckReturnValue
551
        default int readFPGALinkCounter(FPGA fpga, int linkNumber,
552
                        FPGASendingLinkCounters counter, @Valid BMPCoords bmp,
553
                        @Valid BMPBoard board)
554
                        throws IOException, ProcessException, InterruptedException {
555
                return readFPGARegister(fpga, counter.address(linkNumber), bmp, board);
×
556
        }
557

558
        /**
559
         * Read a register on a FPGA of a board. The meaning of the register's
560
         * contents will depend on the FPGA's configuration.
561
         *
562
         * @param fpga
563
         *            FPGA (0, 1 or 2) to communicate with.
564
         * @param register
565
         *            Register address to read to (will be rounded down to the
566
         *            nearest 32-bit word boundary).
567
         * @param board
568
         *            which board to request the FPGA register from
569
         * @return the register data
570
         * @throws IOException
571
         *             If anything goes wrong with networking.
572
         * @throws ProcessException
573
         *             If SpiNNaker rejects a message.
574
         * @throws InterruptedException
575
         *             If the communications were interrupted.
576
         */
577
        @ParallelSafe
578
        @CheckReturnValue
579
        default int readFPGARegister(FPGA fpga, @NotNull MemoryLocation register,
580
                        @Valid BMPBoard board)
581
                        throws IOException, ProcessException, InterruptedException {
582
                return readFPGARegister(fpga, register, getBoundBMP(), board);
×
583
        }
584

585
        /**
586
         * Read a register on a FPGA of a board. The meaning of the register's
587
         * contents will depend on the FPGA's configuration.
588
         *
589
         * @param fpga
590
         *            FPGA (0, 1 or 2) to communicate with.
591
         * @param register
592
         *            Register address to read to (will be rounded down to the
593
         *            nearest 32-bit word boundary).
594
         * @param bmp
595
         *            the coordinates of the BMP this is targeting
596
         * @param board
597
         *            which board to request the FPGA register from
598
         * @return the register data
599
         * @throws IOException
600
         *             If anything goes wrong with networking.
601
         * @throws ProcessException
602
         *             If SpiNNaker rejects a message.
603
         * @throws InterruptedException
604
         *             If the communications were interrupted.
605
         */
606
        @ParallelSafe
607
        @CheckReturnValue
608
        int readFPGARegister(FPGA fpga, @NotNull MemoryLocation register,
609
                        @Valid BMPCoords bmp, @Valid BMPBoard board)
610
                        throws IOException, ProcessException, InterruptedException;
611

612
        /**
613
         * Write a register on a FPGA of a board, assuming the standard FPGA
614
         * configuration.
615
         *
616
         * @param fpga
617
         *            FPGA (0, 1 or 2) to communicate with.
618
         * @param register
619
         *            Register to write.
620
         * @param value
621
         *            the value to write into the FPGA register
622
         * @param board
623
         *            which board to write the FPGA register to
624
         * @throws IOException
625
         *             If anything goes wrong with networking.
626
         * @throws ProcessException
627
         *             If SpiNNaker rejects a message.
628
         * @throws InterruptedException
629
         *             If the communications were interrupted.
630
         */
631
        @ParallelSafe
632
        default void writeFPGARegister(FPGA fpga, FPGAMainRegisters register,
633
                        int value, @Valid BMPBoard board)
634
                        throws IOException, ProcessException, InterruptedException {
635
                writeFPGARegister(fpga, register, value, getBoundBMP(), board);
×
636
        }
×
637

638
        /**
639
         * Write a register on a FPGA of a board, assuming the standard FPGA
640
         * configuration.
641
         *
642
         * @param fpga
643
         *            FPGA (0, 1 or 2) to communicate with.
644
         * @param register
645
         *            Register to write.
646
         * @param value
647
         *            the value to write into the FPGA register
648
         * @param bmp
649
         *            the coordinates of the BMP this is targeting
650
         * @param board
651
         *            which board to write the FPGA register to
652
         * @throws IOException
653
         *             If anything goes wrong with networking.
654
         * @throws ProcessException
655
         *             If SpiNNaker rejects a message.
656
         * @throws InterruptedException
657
         *             If the communications were interrupted.
658
         */
659
        @ParallelSafe
660
        default void writeFPGARegister(FPGA fpga, FPGAMainRegisters register,
661
                        int value, @Valid BMPCoords bmp, @Valid BMPBoard board)
662
                        throws IOException, ProcessException, InterruptedException {
663
                writeFPGARegister(fpga, register.getAddress(), value, bmp, board);
×
664
        }
×
665

666
        /**
667
         * Write a register on a FPGA of a board, assuming the standard FPGA
668
         * configuration.
669
         *
670
         * @param fpga
671
         *            FPGA (0, 1 or 2) to communicate with.
672
         * @param registerBank
673
         *            Which bank of link registers to read from.
674
         * @param register
675
         *            Register to write.
676
         * @param value
677
         *            the value to write into the FPGA register
678
         * @param board
679
         *            which board to write the FPGA register to
680
         * @throws IOException
681
         *             If anything goes wrong with networking.
682
         * @throws ProcessException
683
         *             If SpiNNaker rejects a message.
684
         * @throws InterruptedException
685
         *             If the communications were interrupted.
686
         */
687
        @ParallelSafe
688
        default void writeFPGARegister(FPGA fpga, int registerBank,
689
                        FPGALinkRegisters register, int value, @Valid BMPBoard board)
690
                        throws IOException, ProcessException, InterruptedException {
691
                writeFPGARegister(fpga, registerBank, register, value, getBoundBMP(),
×
692
                                board);
693
        }
×
694

695
        /**
696
         * Write a register on a FPGA of a board, assuming the standard FPGA
697
         * configuration.
698
         *
699
         * @param fpga
700
         *            FPGA (0, 1 or 2) to communicate with.
701
         * @param registerBank
702
         *            Which bank of link registers to read from.
703
         * @param register
704
         *            Register to write.
705
         * @param value
706
         *            the value to write into the FPGA register
707
         * @param bmp
708
         *            the coordinates of the BMP this is targeting
709
         * @param board
710
         *            which board to write the FPGA register to
711
         * @throws IOException
712
         *             If anything goes wrong with networking.
713
         * @throws ProcessException
714
         *             If SpiNNaker rejects a message.
715
         * @throws InterruptedException
716
         *             If the communications were interrupted.
717
         */
718
        @ParallelSafe
719
        default void writeFPGARegister(FPGA fpga, int registerBank,
720
                        FPGALinkRegisters register, int value, @Valid BMPCoords bmp,
721
                        @Valid BMPBoard board)
722
                        throws IOException, ProcessException, InterruptedException {
723
                writeFPGARegister(fpga, register.address(registerBank), value, bmp,
×
724
                                board);
725
        }
×
726

727
        /**
728
         * Write a register on a FPGA of a board. The meaning of setting the
729
         * register's contents will depend on the FPGA's configuration.
730
         *
731
         * @param fpga
732
         *            FPGA (0, 1 or 2) to communicate with.
733
         * @param register
734
         *            Register address to read to (will be rounded down to the
735
         *            nearest 32-bit word boundary).
736
         * @param value
737
         *            the value to write into the FPGA register
738
         * @param board
739
         *            which board to write the FPGA register to
740
         * @throws IOException
741
         *             If anything goes wrong with networking.
742
         * @throws ProcessException
743
         *             If SpiNNaker rejects a message.
744
         * @throws InterruptedException
745
         *             If the communications were interrupted.
746
         */
747
        @ParallelSafe
748
        default void writeFPGARegister(FPGA fpga, @NotNull MemoryLocation register,
749
                        int value, @Valid BMPBoard board)
750
                        throws IOException, ProcessException, InterruptedException {
751
                writeFPGARegister(fpga, register, value, getBoundBMP(), board);
×
752
        }
×
753

754
        /**
755
         * Write a register on a FPGA of a board. The meaning of setting the
756
         * register's contents will depend on the FPGA's configuration.
757
         *
758
         * @param fpga
759
         *            FPGA (0, 1 or 2) to communicate with.
760
         * @param register
761
         *            Register address to read to (will be rounded down to the
762
         *            nearest 32-bit word boundary).
763
         * @param value
764
         *            the value to write into the FPGA register
765
         * @param bmp
766
         *            the coordinates of the BMP this is targeting
767
         * @param board
768
         *            which board to write the FPGA register to
769
         * @throws IOException
770
         *             If anything goes wrong with networking.
771
         * @throws ProcessException
772
         *             If SpiNNaker rejects a message.
773
         * @throws InterruptedException
774
         *             If the communications were interrupted.
775
         */
776
        @ParallelSafe
777
        void writeFPGARegister(FPGA fpga, @NotNull MemoryLocation register,
778
                        int value, @Valid BMPCoords bmp, @Valid BMPBoard board)
779
                        throws IOException, ProcessException, InterruptedException;
780

781
        /**
782
         * Read the ADC data.
783
         *
784
         * @param board
785
         *            which board to request the ADC data from
786
         * @return the FPGA's ADC data object
787
         * @throws IOException
788
         *             If anything goes wrong with networking.
789
         * @throws ProcessException
790
         *             If SpiNNaker rejects a message.
791
         * @throws InterruptedException
792
         *             If the communications were interrupted.
793
         */
794
        @ParallelSafe
795
        @CheckReturnValue
796
        default ADCInfo readADCData(@Valid BMPBoard board)
797
                        throws IOException, ProcessException, InterruptedException {
798
                return readADCData(getBoundBMP(), board);
×
799
        }
800

801
        /**
802
         * Read the ADC data.
803
         *
804
         * @param bmp
805
         *            the coordinates of the BMP this is targeting
806
         * @param board
807
         *            which board to request the ADC data from
808
         * @return the FPGA's ADC data object
809
         * @throws IOException
810
         *             If anything goes wrong with networking.
811
         * @throws ProcessException
812
         *             If SpiNNaker rejects a message.
813
         * @throws InterruptedException
814
         *             If the communications were interrupted.
815
         */
816
        @ParallelSafe
817
        @CheckReturnValue
818
        ADCInfo readADCData(@Valid BMPCoords bmp, @Valid BMPBoard board)
819
                        throws IOException, ProcessException, InterruptedException;
820

821
        /**
822
         * Read the BMP version.
823
         *
824
         * @param boards
825
         *            which board to request the data from; the first board in the
826
         *            collection will be queried
827
         * @return the parsed SVER from the BMP
828
         * @throws IOException
829
         *             If anything goes wrong with networking.
830
         * @throws ProcessException
831
         *             If SpiNNaker rejects a message.
832
         * @throws InterruptedException
833
         *             If the communications were interrupted.
834
         */
835
        @ParallelUnsafe
836
        @CheckReturnValue
837
        default VersionInfo readBMPVersion(Iterable<@Valid BMPBoard> boards)
838
                        throws IOException, ProcessException, InterruptedException {
839
                return readBMPVersion(getBoundBMP(), boards.iterator().next());
×
840
        }
841

842
        /**
843
         * Read the BMP version.
844
         *
845
         * @param board
846
         *            which board to request the data from
847
         * @return the parsed SVER from the BMP
848
         * @throws IOException
849
         *             If anything goes wrong with networking.
850
         * @throws ProcessException
851
         *             If SpiNNaker rejects a message.
852
         * @throws InterruptedException
853
         *             If the communications were interrupted.
854
         */
855
        @ParallelSafe
856
        @CheckReturnValue
857
        default VersionInfo readBMPVersion(@Valid BMPBoard board)
858
                        throws IOException, ProcessException, InterruptedException {
859
                return readBMPVersion(getBoundBMP(), board);
×
860
        }
861

862
        /**
863
         * Read the BMP version.
864
         *
865
         * @param bmp
866
         *            the coordinates of the BMP this is targeting
867
         * @param boards
868
         *            which board to request the data from; the first board in the
869
         *            collection will be queried
870
         * @return the parsed SVER from the BMP
871
         * @throws IOException
872
         *             If anything goes wrong with networking.
873
         * @throws ProcessException
874
         *             If SpiNNaker rejects a message.
875
         * @throws InterruptedException
876
         *             If the communications were interrupted.
877
         */
878
        @ParallelUnsafe
879
        @CheckReturnValue
880
        default VersionInfo readBMPVersion(@Valid BMPCoords bmp,
881
                        Iterable<@Valid BMPBoard> boards)
882
                        throws IOException, ProcessException, InterruptedException {
883
                return readBMPVersion(bmp, boards.iterator().next());
×
884
        }
885

886
        /**
887
         * Read the BMP version.
888
         *
889
         * @param bmp
890
         *            the coordinates of the BMP this is targeting
891
         * @param board
892
         *            which board to request the data from
893
         * @return the parsed SVER from the BMP
894
         * @throws IOException
895
         *             If anything goes wrong with networking.
896
         * @throws ProcessException
897
         *             If SpiNNaker rejects a message.
898
         * @throws InterruptedException
899
         *             If the communications were interrupted.
900
         */
901
        @ParallelSafeWithCare
902
        @CheckReturnValue
903
        VersionInfo readBMPVersion(@Valid BMPCoords bmp, @Valid BMPBoard board)
904
                        throws IOException, ProcessException, InterruptedException;
905

906
        /**
907
         * Read the BMP firmware descriptor.
908
         *
909
         * @param board
910
         *            which board to request the descriptor from
911
         * @param type
912
         *            Which firmware descriptor to read
913
         * @return the firmware descriptor
914
         * @throws IOException
915
         *             If anything goes wrong with networking.
916
         * @throws ProcessException
917
         *             If SpiNNaker rejects a message.
918
         * @throws InterruptedException
919
         *             If the communications were interrupted.
920
         */
921
        @ParallelSafeWithCare
922
        @CheckReturnValue
923
        default FirmwareDescriptor readBMPFirmwareDescriptor(
924
                        @Valid BMPBoard board, FirmwareDescriptors type)
925
                        throws IOException, ProcessException, InterruptedException {
926
                return readBMPFirmwareDescriptor(getBoundBMP(), board, type);
×
927
        }
928

929
        /**
930
         * Read the BMP firmware descriptor.
931
         *
932
         * @param bmp
933
         *            the coordinates of the BMP this is targeting
934
         * @param board
935
         *            which board to request the descriptor from
936
         * @param type
937
         *            Which firmware descriptor to read
938
         * @return the firmware descriptor
939
         * @throws IOException
940
         *             If anything goes wrong with networking.
941
         * @throws ProcessException
942
         *             If SpiNNaker rejects a message.
943
         * @throws InterruptedException
944
         *             If the communications were interrupted.
945
         */
946
        @ParallelSafeWithCare
947
        @CheckReturnValue
948
        default FirmwareDescriptor readBMPFirmwareDescriptor(@Valid BMPCoords bmp,
949
                        @Valid BMPBoard board, FirmwareDescriptors type)
950
                        throws IOException, ProcessException, InterruptedException {
951
                return new FirmwareDescriptor(type,
×
952
                                readBMPMemory(bmp, board, type.address, type.blockSize));
×
953
        }
954

955
        /**
956
         * Get the FPGA reset status.
957
         *
958
         * @param board
959
         *            Which board are the FPGAs on?
960
         * @return What the state of the reset line is.
961
         * @throws IOException
962
         *             If anything goes wrong with networking.
963
         * @throws ProcessException
964
         *             If SpiNNaker rejects a message.
965
         * @throws InterruptedException
966
         *             If the communications were interrupted.
967
         */
968
        @ParallelSafeWithCare
969
        @CheckReturnValue
970
        default boolean getResetStatus(@Valid BMPBoard board)
971
                        throws IOException, ProcessException, InterruptedException {
972
                return getResetStatus(getBoundBMP(), board);
×
973
        }
974

975
        /**
976
         * Get the FPGA reset status.
977
         *
978
         * @param bmp
979
         *            Which BMP are we talking to?
980
         * @param board
981
         *            Which board are the FPGAs on?
982
         * @return What the state of the reset line is.
983
         * @throws IOException
984
         *             If anything goes wrong with networking.
985
         * @throws ProcessException
986
         *             If SpiNNaker rejects a message.
987
         * @throws InterruptedException
988
         *             If the communications were interrupted.
989
         */
990
        @ParallelSafeWithCare
991
        @CheckReturnValue
992
        boolean getResetStatus(@Valid BMPCoords bmp, @Valid BMPBoard board)
993
                        throws IOException, ProcessException, InterruptedException;
994

995
        /**
996
         * Get the address of the serial flash buffer.
997
         *
998
         * @param board
999
         *            Which BMP's buffer do we want the address of?
1000
         * @return The adress of the serial flash buffer.
1001
         * @throws IOException
1002
         *             If anything goes wrong with networking.
1003
         * @throws ProcessException
1004
         *             If SpiNNaker rejects a message.
1005
         * @throws InterruptedException
1006
         *             If the communications were interrupted.
1007
         */
1008
        @ParallelSafeWithCare
1009
        default MemoryLocation getSerialFlashBuffer(@Valid BMPBoard board)
1010
                        throws IOException, ProcessException, InterruptedException {
1011
                return getSerialFlashBuffer(getBoundBMP(), board);
×
1012
        }
1013

1014
        /**
1015
         * Get the address of the serial flash buffer.
1016
         *
1017
         * @param bmp
1018
         *            Which BMP are we talking to?
1019
         * @param board
1020
         *            Which BMP's buffer do we want the address of?
1021
         * @return The adress of the serial flash buffer.
1022
         * @throws IOException
1023
         *             If anything goes wrong with networking.
1024
         * @throws ProcessException
1025
         *             If SpiNNaker rejects a message.
1026
         * @throws InterruptedException
1027
         *             If the communications were interrupted.
1028
         */
1029
        @ParallelSafeWithCare
1030
        MemoryLocation getSerialFlashBuffer(@Valid BMPCoords bmp,
1031
                        @Valid BMPBoard board)
1032
                        throws IOException, ProcessException, InterruptedException;
1033

1034
        /** The type of reset to perform. */
1035
        enum FPGAResetType {
3✔
1036
                // NB: The order of these values is important
1037
                /** Reset by taking the reset line low. */
1038
                LOW,
3✔
1039
                /** Reset by taking the reset line high. */
1040
                HIGH,
3✔
1041
                /** Reset by sending a pulse on the reset line. */
1042
                PULSE
3✔
1043
        }
1044

1045
        /**
1046
         * Reset the FPGAs on a board.
1047
         *
1048
         * @param board
1049
         *            Which board are the FPGAs on?
1050
         * @param resetType
1051
         *            What kind of reset to perform.
1052
         * @throws IOException
1053
         *             If anything goes wrong with networking.
1054
         * @throws ProcessException
1055
         *             If SpiNNaker rejects a message.
1056
         * @throws InterruptedException
1057
         *             If the communications were interrupted.
1058
         */
1059
        @ParallelSafeWithCare
1060
        default void resetFPGA(@Valid BMPBoard board, FPGAResetType resetType)
1061
                        throws IOException, ProcessException, InterruptedException {
1062
                resetFPGA(getBoundBMP(), board, resetType);
×
1063
        }
×
1064

1065
        /**
1066
         * Reset the FPGAs on a board.
1067
         *
1068
         * @param bmp
1069
         *            Which BMP are we talking to?
1070
         * @param board
1071
         *            Which board are the FPGAs on?
1072
         * @param resetType
1073
         *            What kind of reset to perform.
1074
         * @throws IOException
1075
         *             If anything goes wrong with networking.
1076
         * @throws ProcessException
1077
         *             If SpiNNaker rejects a message.
1078
         * @throws InterruptedException
1079
         *             If the communications were interrupted.
1080
         */
1081
        @ParallelSafeWithCare
1082
        void resetFPGA(@Valid BMPCoords bmp, @Valid BMPBoard board,
1083
                        FPGAResetType resetType)
1084
                        throws IOException, ProcessException, InterruptedException;
1085

1086
        /**
1087
         * Read BMP memory.
1088
         *
1089
         * @param board
1090
         *            Which board's BMP are we reading?
1091
         * @param baseAddress
1092
         *            The address in the BMP's memory where the region of memory to
1093
         *            be read starts
1094
         * @param length
1095
         *            The length of the data to be read in bytes
1096
         * @return A little-endian buffer of data read, positioned at the start of
1097
         *         the data. The buffer will be writable, but writes will not be
1098
         *         automatically reflected anywhere.
1099
         * @throws IOException
1100
         *             If anything goes wrong with networking.
1101
         * @throws ProcessException
1102
         *             If SpiNNaker rejects a message.
1103
         * @throws InterruptedException
1104
         *             If the communications were interrupted.
1105
         */
1106
        @ParallelSafeWithCare
1107
        @CheckReturnValue
1108
        default ByteBuffer readBMPMemory(@Valid BMPBoard board,
1109
                        @NotNull MemoryLocation baseAddress, @Positive int length)
1110
                        throws IOException, ProcessException, InterruptedException {
1111
                return readBMPMemory(getBoundBMP(), board, baseAddress, length);
×
1112
        }
1113

1114
        /**
1115
         * Read BMP memory.
1116
         *
1117
         * @param bmp
1118
         *            Which BMP are we talking to?
1119
         * @param board
1120
         *            Which board's BMP are we reading?
1121
         * @param baseAddress
1122
         *            The address in the BMP's memory where the region of memory to
1123
         *            be read starts
1124
         * @param length
1125
         *            The length of the data to be read in bytes
1126
         * @return A little-endian buffer of data read, positioned at the start of
1127
         *         the data. The buffer will be writable, but writes will not be
1128
         *         automatically reflected anywhere.
1129
         * @throws IOException
1130
         *             If anything goes wrong with networking.
1131
         * @throws ProcessException
1132
         *             If SpiNNaker rejects a message.
1133
         * @throws InterruptedException
1134
         *             If the communications were interrupted.
1135
         */
1136
        @ParallelSafeWithCare
1137
        @CheckReturnValue
1138
        ByteBuffer readBMPMemory(@Valid BMPCoords bmp, @Valid BMPBoard board,
1139
                        @NotNull MemoryLocation baseAddress, @Positive int length)
1140
                        throws IOException, ProcessException, InterruptedException;
1141

1142
        /**
1143
         * Read BMP memory.
1144
         *
1145
         * @param board
1146
         *            Which board's BMP are we reading?
1147
         * @param address
1148
         *            The address in the BMP's memory where the region of memory to
1149
         *            be read starts
1150
         * @return The little-endian word at the given address.
1151
         * @throws IOException
1152
         *             If anything goes wrong with networking.
1153
         * @throws ProcessException
1154
         *             If SpiNNaker rejects a message.
1155
         * @throws InterruptedException
1156
         *             If the communications were interrupted.
1157
         */
1158
        @ParallelSafeWithCare
1159
        @CheckReturnValue
1160
        default int readBMPMemoryWord(@Valid BMPBoard board,
1161
                        @NotNull MemoryLocation address)
1162
                        throws IOException, ProcessException, InterruptedException {
1163
                return readBMPMemoryWord(getBoundBMP(), board, address);
×
1164
        }
1165

1166
        /**
1167
         * Read BMP memory.
1168
         *
1169
         * @param bmp
1170
         *            Which BMP are we talking to?
1171
         * @param board
1172
         *            Which board's BMP are we reading?
1173
         * @param address
1174
         *            The address in the BMP's memory where the region of memory to
1175
         *            be read starts
1176
         * @return The little-endian word at the given address.
1177
         * @throws IOException
1178
         *             If anything goes wrong with networking.
1179
         * @throws ProcessException
1180
         *             If SpiNNaker rejects a message.
1181
         * @throws InterruptedException
1182
         *             If the communications were interrupted.
1183
         */
1184
        @ParallelSafeWithCare
1185
        @CheckReturnValue
1186
        default int readBMPMemoryWord(@Valid BMPCoords bmp, @Valid BMPBoard board,
1187
                        @NotNull MemoryLocation address)
1188
                        throws IOException, ProcessException, InterruptedException {
1189
                var b = readBMPMemory(bmp, board, address, WORD_SIZE);
×
1190
                return b.getInt(0);
×
1191
        }
1192

1193
        /**
1194
         * Write BMP memory.
1195
         *
1196
         * @param board
1197
         *            Which board's BMP are we writing?
1198
         * @param baseAddress
1199
         *            The address in the BMP's memory where the region of memory to
1200
         *            be written starts
1201
         * @param data
1202
         *            The data to be written, extending from the <i>position</i> to
1203
         *            the <i>limit</i>. The contents of this buffer will be
1204
         *            unchanged.
1205
         * @throws IOException
1206
         *             If anything goes wrong with networking.
1207
         * @throws ProcessException
1208
         *             If SpiNNaker rejects a message.
1209
         * @throws InterruptedException
1210
         *             If the communications were interrupted.
1211
         */
1212
        default void writeBMPMemory(@Valid BMPBoard board,
1213
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1214
                        throws IOException, ProcessException, InterruptedException {
1215
                writeBMPMemory(getBoundBMP(), board, baseAddress, data);
×
1216
        }
×
1217

1218
        /**
1219
         * Write BMP memory.
1220
         *
1221
         * @param bmp
1222
         *            Which BMP are we talking to?
1223
         * @param board
1224
         *            Which board's BMP are we writing?
1225
         * @param baseAddress
1226
         *            The address in the BMP's memory where the region of memory to
1227
         *            be written starts
1228
         * @param data
1229
         *            The data to be written, extending from the <i>position</i> to
1230
         *            the <i>limit</i>. The contents of this buffer will be
1231
         *            unchanged.
1232
         * @throws IOException
1233
         *             If anything goes wrong with networking.
1234
         * @throws ProcessException
1235
         *             If SpiNNaker rejects a message.
1236
         * @throws InterruptedException
1237
         *             If the communications were interrupted.
1238
         */
1239
        void writeBMPMemory(@Valid BMPCoords bmp, @Valid BMPBoard board,
1240
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1241
                        throws IOException, ProcessException, InterruptedException;
1242

1243
        /**
1244
         * Write BMP memory.
1245
         *
1246
         * @param board
1247
         *            Which board's BMP are we writing?
1248
         * @param baseAddress
1249
         *            The address in the BMP's memory where the region of memory to
1250
         *            be written starts
1251
         * @param dataWord
1252
         *            The data to be written as a 4-byte little-endian value.
1253
         * @throws IOException
1254
         *             If anything goes wrong with networking.
1255
         * @throws ProcessException
1256
         *             If SpiNNaker rejects a message.
1257
         * @throws InterruptedException
1258
         *             If the communications were interrupted.
1259
         */
1260
        default void writeBMPMemory(@Valid BMPBoard board,
1261
                        @NotNull MemoryLocation baseAddress, int dataWord)
1262
                        throws IOException, ProcessException, InterruptedException {
1263
                writeBMPMemory(getBoundBMP(), board, baseAddress, dataWord);
×
1264
        }
×
1265

1266
        /**
1267
         * Write BMP memory.
1268
         *
1269
         * @param bmp
1270
         *            Which BMP are we talking to?
1271
         * @param board
1272
         *            Which board's BMP are we writing?
1273
         * @param baseAddress
1274
         *            The address in the BMP's memory where the region of memory to
1275
         *            be written starts
1276
         * @param dataWord
1277
         *            The data to be written as a 4-byte little-endian value.
1278
         * @throws IOException
1279
         *             If anything goes wrong with networking.
1280
         * @throws ProcessException
1281
         *             If SpiNNaker rejects a message.
1282
         * @throws InterruptedException
1283
         *             If the communications were interrupted.
1284
         */
1285
        default void writeBMPMemory(@Valid BMPCoords bmp, @Valid BMPBoard board,
1286
                        @NotNull MemoryLocation baseAddress, int dataWord)
1287
                        throws IOException, ProcessException, InterruptedException {
1288
                writeBMPMemory(bmp, board, baseAddress, wordAsBuffer(dataWord));
×
1289
        }
×
1290

1291
        /**
1292
         * Write BMP memory from a file.
1293
         *
1294
         * @param board
1295
         *            Which board's BMP are we writing?
1296
         * @param baseAddress
1297
         *            The address in the BMP's memory where the region of memory to
1298
         *            be written starts
1299
         * @param file
1300
         *            The file containing the data to be written.
1301
         * @throws IOException
1302
         *             If anything goes wrong with networking or file I/O.
1303
         * @throws ProcessException
1304
         *             If SpiNNaker rejects a message.
1305
         * @throws InterruptedException
1306
         *             If the communications were interrupted.
1307
         */
1308
        default void writeBMPMemory(@Valid BMPBoard board,
1309
                        @NotNull MemoryLocation baseAddress, @NotNull File file)
1310
                        throws IOException, ProcessException, InterruptedException {
1311
                writeBMPMemory(getBoundBMP(), board, baseAddress, file);
×
1312
        }
×
1313

1314
        /**
1315
         * Write BMP memory from a file.
1316
         *
1317
         * @param bmp
1318
         *            Which BMP are we talking to?
1319
         * @param board
1320
         *            Which board's BMP are we writing?
1321
         * @param baseAddress
1322
         *            The address in the BMP's memory where the region of memory to
1323
         *            be written starts
1324
         * @param file
1325
         *            The file containing the data to be written.
1326
         * @throws IOException
1327
         *             If anything goes wrong with networking or file I/O.
1328
         * @throws ProcessException
1329
         *             If SpiNNaker rejects a message.
1330
         * @throws InterruptedException
1331
         *             If the communications were interrupted.
1332
         */
1333
        void writeBMPMemory(@Valid BMPCoords bmp, @Valid BMPBoard board,
1334
                        @NotNull MemoryLocation baseAddress, @NotNull File file)
1335
                        throws IOException, ProcessException, InterruptedException;
1336

1337
        /**
1338
         * Read BMP serial flash memory.
1339
         *
1340
         * @param board
1341
         *            Which board's BMP are we reading?
1342
         * @param baseAddress
1343
         *            The address in the BMP's serial flash where the region of
1344
         *            memory to be read starts
1345
         * @param length
1346
         *            The length of the data to be read in bytes
1347
         * @return A little-endian buffer of data read, positioned at the start of
1348
         *         the data. The buffer will be writable, but writes will not be
1349
         *         automatically reflected anywhere.
1350
         * @throws IOException
1351
         *             If anything goes wrong with networking.
1352
         * @throws ProcessException
1353
         *             If SpiNNaker rejects a message.
1354
         * @throws InterruptedException
1355
         *             If the communications were interrupted.
1356
         */
1357
        @ParallelSafeWithCare
1358
        @CheckReturnValue
1359
        default ByteBuffer readSerialFlash(@Valid BMPBoard board,
1360
                        @NotNull MemoryLocation baseAddress, @Positive int length)
1361
                        throws IOException, ProcessException, InterruptedException {
1362
                return readSerialFlash(getBoundBMP(), board, baseAddress, length);
×
1363
        }
1364

1365
        /**
1366
         * Read BMP serial flash memory.
1367
         *
1368
         * @param bmp
1369
         *            Which BMP are we talking to?
1370
         * @param board
1371
         *            Which board's BMP are we reading?
1372
         * @param baseAddress
1373
         *            The address in the BMP's serial flash where the region of
1374
         *            memory to be read starts
1375
         * @param length
1376
         *            The length of the data to be read in bytes
1377
         * @return A little-endian buffer of data read, positioned at the start of
1378
         *         the data. The buffer will be writable, but writes will not be
1379
         *         automatically reflected anywhere.
1380
         * @throws IOException
1381
         *             If anything goes wrong with networking.
1382
         * @throws ProcessException
1383
         *             If SpiNNaker rejects a message.
1384
         * @throws InterruptedException
1385
         *             If the communications were interrupted.
1386
         */
1387
        @ParallelSafeWithCare
1388
        @CheckReturnValue
1389
        ByteBuffer readSerialFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1390
                        @NotNull MemoryLocation baseAddress, @Positive int length)
1391
                        throws IOException, ProcessException, InterruptedException;
1392

1393
        /**
1394
         * Read the BMP serial number from a board.
1395
         *
1396
         * @param bmp
1397
         *            Which BMP are we sending messages to directly?
1398
         * @param board
1399
         *            Which board's BMP (of those managed by the BMP we send the
1400
         *            message to) are we getting the serial number from?
1401
         * @return The LPC1768 serial number.
1402
         * @throws IOException
1403
         *             If anything goes wrong with networking.
1404
         * @throws ProcessException
1405
         *             If SpiNNaker rejects a message.
1406
         * @throws InterruptedException
1407
         *             If the communications were interrupted.
1408
         */
1409
        @ParallelSafeWithCare
1410
        @CheckReturnValue
1411
        String readBoardSerialNumber(@Valid BMPCoords bmp, @Valid BMPBoard board)
1412
                        throws IOException, ProcessException, InterruptedException;
1413

1414
        /**
1415
         * Read the BMP serial number from a board.
1416
         *
1417
         * @param board
1418
         *            Which board's BMP are we reading the serial number of? Must
1419
         *            be one controlled by the current bound BMP.
1420
         * @return The LPC1768 serial number.
1421
         * @throws IOException
1422
         *             If anything goes wrong with networking.
1423
         * @throws ProcessException
1424
         *             If SpiNNaker rejects a message.
1425
         * @throws InterruptedException
1426
         *             If the communications were interrupted.
1427
         */
1428
        @CheckReturnValue
1429
        default String readBoardSerialNumber(@Valid BMPBoard board)
1430
                        throws ProcessException, IOException, InterruptedException {
1431
                return readBoardSerialNumber(getBoundBMP(), board);
×
1432
        }
1433

1434
        /**
1435
         * Read the blacklist from a board.
1436
         *
1437
         * @param bmp
1438
         *            Which BMP are we sending messages to directly?
1439
         * @param board
1440
         *            Which board's blacklist are we reading?
1441
         * @return The contents of the blacklist.
1442
         * @throws IOException
1443
         *             If anything goes wrong with networking.
1444
         * @throws ProcessException
1445
         *             If SpiNNaker rejects a message.
1446
         * @throws InterruptedException
1447
         *             If the communications were interrupted.
1448
         */
1449
        @CheckReturnValue
1450
        default Blacklist readBlacklist(@Valid BMPCoords bmp, @Valid BMPBoard board)
1451
                        throws IOException, ProcessException, InterruptedException {
1452
                return new Blacklist(
×
1453
                                readSerialFlash(bmp, board, SF_BL_ADDR, SF_BL_LEN));
×
1454
        }
1455

1456
        /**
1457
         * Read the blacklist from a board.
1458
         *
1459
         * @param board
1460
         *            Which board's blacklist are we reading? Must
1461
         *            be one controlled by the current bound BMP.
1462
         * @return The contents of the blacklist.
1463
         * @throws IOException
1464
         *             If anything goes wrong with networking.
1465
         * @throws ProcessException
1466
         *             If SpiNNaker rejects a message.
1467
         * @throws InterruptedException
1468
         *             If the communications were interrupted.
1469
         */
1470
        @CheckReturnValue
1471
        default Blacklist readBlacklist(@Valid BMPBoard board)
1472
                        throws IOException, ProcessException, InterruptedException {
1473
                return readBlacklist(getBoundBMP(), board);
×
1474
        }
1475

1476
        /**
1477
         * Write a blacklist to a board. Note that this is a non-transactional
1478
         * operation!
1479
         *
1480
         * @param board
1481
         *            Which board's BMP to write to.
1482
         * @param blacklist
1483
         *            The blacklist to write.
1484
         * @throws ProcessException
1485
         *             If a BMP rejects a message.
1486
         * @throws IOException
1487
         *             If anything goes wrong with networking.
1488
         * @throws InterruptedException
1489
         *             If interrupted. Interruption can happen <em>prior</em> to
1490
         *             commencing the actual writes.
1491
         */
1492
        default void writeBlacklist(@Valid BMPBoard board,
1493
                        @Valid Blacklist blacklist)
1494
                        throws ProcessException, IOException, InterruptedException {
1495
                writeBlacklist(getBoundBMP(), board, blacklist);
×
1496
        }
×
1497

1498
        /**
1499
         * Write a blacklist to a board. Note that this is a non-transactional
1500
         * operation!
1501
         *
1502
         * @param bmp
1503
         *            The BMP to send communications via.
1504
         * @param board
1505
         *            Which board's BMP to write to.
1506
         * @param blacklist
1507
         *            The blacklist to write.
1508
         * @throws ProcessException
1509
         *             If a BMP rejects a message.
1510
         * @throws IOException
1511
         *             If anything goes wrong with networking.
1512
         * @throws InterruptedException
1513
         *             If interrupted. Interruption can happen <em>prior</em> to
1514
         *             commencing the actual writes.
1515
         */
1516
        default void writeBlacklist(@Valid BMPCoords bmp, @Valid BMPBoard board,
1517
                        @Valid Blacklist blacklist)
1518
                        throws ProcessException, IOException, InterruptedException {
1519
                // Clear the interrupt status
1520
                interrupted();
×
1521

1522
                // Prepare the boot data
1523
                var data = allocate(BMP_BOOT_SECTOR_SIZE);
×
1524
                data.order(LITTLE_ENDIAN);
×
1525
                data.put(readBMPMemory(bmp, board, BMP_BOOT_SECTOR_ADDR,
×
1526
                                BMP_BOOT_SECTOR_SIZE));
1527
                fill(data, BMP_BOOT_BLACKLIST_OFFSET, SF_BL_LEN, BLACKLIST_BLANK);
×
1528
                data.position(BMP_BOOT_BLACKLIST_OFFSET);
×
1529
                data.put(blacklist.getRawData());
×
1530
                data.putInt(BMP_BOOT_CRC_OFFSET, ~crc(data, 0, BMP_BOOT_CRC_OFFSET));
×
1531

1532
                if (interrupted()) {
×
1533
                        throw new InterruptedException(
×
1534
                                        "interrupted while reading boot data");
1535
                }
1536

1537
                // Prepare the serial flash update; must read part of the data first
1538
                var sfData = new byte[SF_BL_ADDR.address + SF_BL_LEN];
×
1539
                readSerialFlash(bmp, board, NULL, SF_BL_ADDR.address).get(sfData, 0,
×
1540
                                SF_BL_ADDR.address);
1541
                data.position(BMP_BOOT_BLACKLIST_OFFSET);
×
1542
                data.get(sfData, SF_BL_ADDR.address, SF_BL_LEN);
×
1543

1544
                data.position(0); // Prep for write
×
1545

1546
                if (interrupted()) {
×
1547
                        throw new InterruptedException(
×
1548
                                        "interrupted while reading serial flash");
1549
                }
1550

1551
                // Do the actual writes here; any failure before here is unimportant
1552
                writeFlash(bmp, board, BMP_BOOT_SECTOR_ADDR, data);
×
1553
                var sfBuffer = ByteBuffer.wrap(sfData);
×
1554
                writeSerialFlash(bmp, board, NULL, sfBuffer);
×
1555

1556
                // Read back data from both places
1557
                var readData = readBMPMemory(bmp, board, BMP_BOOT_SECTOR_ADDR,
×
1558
                                BMP_BOOT_SECTOR_SIZE);
1559
                var readDataEqual = data.position(0).equals(readData.position(0));
×
1560
                var sfReadData = readSerialFlash(bmp, board, NULL, sfData.length);
×
1561
                var readSfEqual = sfBuffer.position(0).equals(sfReadData.position(0));
×
1562

1563
                if (!readDataEqual && !readSfEqual) {
×
1564
                        throw new IOException(
×
1565
                                        "The write failed completely - try again"
1566
                                        + " (but careful as pressing read may lose the blacklist"
1567
                                        + " completely)");
1568
                } else if (!readDataEqual) {
×
1569
                        throw new IOException(
×
1570
                                        "The flash write failed - try the write again");
1571
                } else if (!readSfEqual) {
×
1572
                        throw new IOException(
×
1573
                                        "The serial flash write failed - try again"
1574
                                        + " (but careful as pressing read may lose the blacklist"
1575
                                        + " completely)");
1576
                }
1577
        }
×
1578

1579
        /**
1580
         * Read the CRC32 checksum of BMP serial flash memory.
1581
         *
1582
         * @param board
1583
         *            Which board's BMP are we reading?
1584
         * @param baseAddress
1585
         *            The address in the BMP's serial flash where the region of
1586
         *            memory to be checksummed starts
1587
         * @param length
1588
         *            The length of the data to be checksummed in bytes
1589
         * @return The CRC32 checksum
1590
         * @throws IOException
1591
         *             If anything goes wrong with networking.
1592
         * @throws ProcessException
1593
         *             If SpiNNaker rejects a message.
1594
         * @throws InterruptedException
1595
         *             If the communications were interrupted.
1596
         */
1597
        @ParallelSafeWithCare
1598
        @CheckReturnValue
1599
        default int readSerialFlashCRC(@Valid BMPBoard board,
1600
                        @NotNull MemoryLocation baseAddress, @Positive int length)
1601
                        throws IOException, ProcessException, InterruptedException {
1602
                return readSerialFlashCRC(getBoundBMP(), board, baseAddress, length);
×
1603
        }
1604

1605
        /**
1606
         * Read the CRC32 checksum of BMP serial flash memory.
1607
         *
1608
         * @param bmp
1609
         *            Which BMP are we talking to?
1610
         * @param board
1611
         *            Which board's BMP are we reading?
1612
         * @param baseAddress
1613
         *            The address in the BMP's serial flash where the region of
1614
         *            memory to be checksummed starts
1615
         * @param length
1616
         *            The length of the data to be checksummed in bytes
1617
         * @return The CRC32 checksum
1618
         * @throws IOException
1619
         *             If anything goes wrong with networking.
1620
         * @throws ProcessException
1621
         *             If SpiNNaker rejects a message.
1622
         * @throws InterruptedException
1623
         *             If the communications were interrupted.
1624
         */
1625
        @ParallelSafeWithCare
1626
        @CheckReturnValue
1627
        int readSerialFlashCRC(@Valid BMPCoords bmp, @Valid BMPBoard board,
1628
                        @NotNull MemoryLocation baseAddress, @Positive int length)
1629
                        throws IOException, ProcessException, InterruptedException;
1630

1631
        /**
1632
         * Write BMP serial flash memory from a file.
1633
         *
1634
         * @param board
1635
         *            Which board's BMP are we writing?
1636
         * @param baseAddress
1637
         *            The address in the BMP's serial flash where the region of
1638
         *            memory to be written starts
1639
         * @param file
1640
         *            The file containing the data to be written
1641
         * @throws IOException
1642
         *             If anything goes wrong with networking.
1643
         * @throws ProcessException
1644
         *             If SpiNNaker rejects a message.
1645
         * @throws InterruptedException
1646
         *             If the communications were interrupted.
1647
         */
1648
        default void writeSerialFlash(@Valid BMPBoard board,
1649
                        @NotNull MemoryLocation baseAddress, @NotNull File file)
1650
                        throws ProcessException, IOException, InterruptedException {
1651
                writeSerialFlash(getBoundBMP(), board, baseAddress, file);
×
1652
        }
×
1653

1654
        /**
1655
         * Write BMP serial flash memory from a file.
1656
         *
1657
         * @param bmp
1658
         *            Which BMP are we talking to?
1659
         * @param board
1660
         *            Which board's BMP are we writing?
1661
         * @param baseAddress
1662
         *            The address in the BMP's serial flash where the region of
1663
         *            memory to be written starts
1664
         * @param file
1665
         *            The file containing the data to be written
1666
         * @throws IOException
1667
         *             If anything goes wrong with networking.
1668
         * @throws ProcessException
1669
         *             If SpiNNaker rejects a message.
1670
         * @throws InterruptedException
1671
         *             If the communications were interrupted.
1672
         */
1673
        void writeSerialFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1674
                        @NotNull MemoryLocation baseAddress, @NotNull File file)
1675
                        throws ProcessException, IOException, InterruptedException;
1676

1677
        /**
1678
         * Write BMP serial flash memory from a stream.
1679
         *
1680
         * @param board
1681
         *            Which board's BMP are we writing?
1682
         * @param baseAddress
1683
         *            The address in the BMP's serial flash where the region of
1684
         *            memory to be written starts
1685
         * @param size
1686
         *            How many bytes to write from the stream
1687
         * @param stream
1688
         *            The file containing the data to be written
1689
         * @throws IOException
1690
         *             If anything goes wrong with networking.
1691
         * @throws ProcessException
1692
         *             If SpiNNaker rejects a message.
1693
         * @throws InterruptedException
1694
         *             If the communications were interrupted.
1695
         */
1696
        default void writeSerialFlash(@Valid BMPBoard board,
1697
                        @NotNull MemoryLocation baseAddress, @Positive int size,
1698
                        @NotNull InputStream stream)
1699
                        throws ProcessException, IOException, InterruptedException {
1700
                writeSerialFlash(getBoundBMP(), board, baseAddress, size, stream);
×
1701
        }
×
1702

1703
        /**
1704
         * Write BMP serial flash memory from a stream.
1705
         *
1706
         * @param bmp
1707
         *            Which BMP are we talking to?
1708
         * @param board
1709
         *            Which board's BMP are we writing?
1710
         * @param baseAddress
1711
         *            The address in the BMP's serial flash where the region of
1712
         *            memory to be written starts
1713
         * @param size
1714
         *            How many bytes to write from the stream
1715
         * @param stream
1716
         *            The file containing the data to be written
1717
         * @throws IOException
1718
         *             If anything goes wrong with networking.
1719
         * @throws ProcessException
1720
         *             If SpiNNaker rejects a message.
1721
         * @throws InterruptedException
1722
         *             If the communications were interrupted.
1723
         */
1724
        void writeSerialFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1725
                        @NotNull MemoryLocation baseAddress, @Positive int size,
1726
                        @NotNull InputStream stream)
1727
                        throws ProcessException, IOException, InterruptedException;
1728

1729
        /**
1730
         * Write BMP serial flash memory.
1731
         *
1732
         * @param board
1733
         *            Which board's BMP are we writing?
1734
         * @param baseAddress
1735
         *            The address in the BMP's serial flash where the region of
1736
         *            memory to be written starts
1737
         * @param data
1738
         *            The raw data to be written
1739
         * @throws IOException
1740
         *             If anything goes wrong with networking.
1741
         * @throws ProcessException
1742
         *             If SpiNNaker rejects a message.
1743
         * @throws InterruptedException
1744
         *             If the communications were interrupted.
1745
         */
1746
        default void writeSerialFlash(@Valid BMPBoard board,
1747
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1748
                        throws ProcessException, IOException, InterruptedException {
1749
                writeSerialFlash(getBoundBMP(), board, baseAddress, data);
×
1750
        }
×
1751

1752
        /**
1753
         * Write BMP serial flash memory.
1754
         *
1755
         * @param bmp
1756
         *            Which BMP are we talking to?
1757
         * @param board
1758
         *            Which board's BMP are we writing?
1759
         * @param baseAddress
1760
         *            The address in the BMP's serial flash where the region of
1761
         *            memory to be written starts
1762
         * @param data
1763
         *            The raw data to be written
1764
         * @throws IOException
1765
         *             If anything goes wrong with networking.
1766
         * @throws ProcessException
1767
         *             If SpiNNaker rejects a message.
1768
         * @throws InterruptedException
1769
         *             If the communications were interrupted.
1770
         */
1771
        void writeSerialFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1772
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1773
                        throws ProcessException, IOException, InterruptedException;
1774

1775
        /**
1776
         * Write a {@linkplain WriteFlashBuffer#FLASH_CHUNK_SIZE fixed size} chunk
1777
         * to flash memory of a BMP with erase. The data must have already been
1778
         * written to the flash buffer.
1779
         *
1780
         * @param board
1781
         *            Which board's BMP are we writing to?
1782
         * @param baseAddress
1783
         *            Where in flash will we write?
1784
         * @see #writeFlash(BMPCoords,BMPBoard,MemoryLocation,ByteBuffer)
1785
         * @throws IOException
1786
         *             If anything goes wrong with networking.
1787
         * @throws ProcessException
1788
         *             If SpiNNaker rejects a message.
1789
         * @throws InterruptedException
1790
         *             If the communications were interrupted.
1791
         */
1792
        default void writeBMPFlash(@Valid BMPBoard board,
1793
                        @NotNull MemoryLocation baseAddress)
1794
                        throws IOException, ProcessException, InterruptedException {
1795
                writeBMPFlash(getBoundBMP(), board, baseAddress);
×
1796
        }
×
1797

1798
        /**
1799
         * Write a {@linkplain WriteFlashBuffer#FLASH_CHUNK_SIZE fixed size} chunk
1800
         * to flash memory of a BMP with erase. The data must have already been
1801
         * written to the flash buffer.
1802
         *
1803
         * @param bmp
1804
         *            Which BMP are we talking to?
1805
         * @param board
1806
         *            Which board's BMP are we writing to?
1807
         * @param baseAddress
1808
         *            Where in flash will we write?
1809
         * @see #writeFlash(BMPCoords,BMPBoard,MemoryLocation,ByteBuffer)
1810
         * @throws IOException
1811
         *             If anything goes wrong with networking.
1812
         * @throws ProcessException
1813
         *             If SpiNNaker rejects a message.
1814
         * @throws InterruptedException
1815
         *             If the communications were interrupted.
1816
         */
1817
        void writeBMPFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1818
                        @NotNull MemoryLocation baseAddress)
1819
                        throws IOException, ProcessException, InterruptedException;
1820

1821
        /**
1822
         * Write a buffer to flash memory on the BMP. This is a composite operation.
1823
         *
1824
         * @param board
1825
         *            Which board's BMP are we writing to?
1826
         * @param baseAddress
1827
         *            Where in flash will we write?
1828
         * @param data
1829
         *            What data will we write?
1830
         * @throws IOException
1831
         *             If anything goes wrong with networking.
1832
         * @throws ProcessException
1833
         *             If SpiNNaker rejects a message.
1834
         * @throws InterruptedException
1835
         *             If the communications were interrupted.
1836
         */
1837
        default void writeFlash(@Valid BMPBoard board,
1838
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1839
                        throws ProcessException, IOException, InterruptedException {
1840
                writeFlash(getBoundBMP(), board, baseAddress, data);
×
1841
        }
×
1842

1843
        /**
1844
         * Write a buffer to flash memory on the BMP. This is a composite operation.
1845
         *
1846
         * @param bmp
1847
         *            Which BMP are we talking to?
1848
         * @param board
1849
         *            Which board's BMP are we writing to?
1850
         * @param baseAddress
1851
         *            Where in flash will we write?
1852
         * @param data
1853
         *            What data will we write?
1854
         * @throws IOException
1855
         *             If anything goes wrong with networking.
1856
         * @throws ProcessException
1857
         *             If SpiNNaker rejects a message.
1858
         * @throws InterruptedException
1859
         *             If the communications were interrupted.
1860
         */
1861
        void writeFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1862
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1863
                        throws ProcessException, IOException, InterruptedException;
1864

1865
        @Override
1866
        void close() throws IOException;
1867
}
1868

1869
interface BMPConstants {
1870
        /** Location in serial flash of blacklist. */
1871
        MemoryLocation SF_BL_ADDR = new MemoryLocation(0x100);
×
1872

1873
        /** Size of blacklist, in bytes. */
1874
        int SF_BL_LEN = 256;
1875

1876
        /** Offset of blacklist in boot sector of flash. */
1877
        int BMP_BOOT_BLACKLIST_OFFSET = 0xe00;
1878

1879
        /** Location of boot sector of flash. */
1880
        MemoryLocation BMP_BOOT_SECTOR_ADDR = new MemoryLocation(0x1000);
×
1881

1882
        /** Size of boot sector of flash. */
1883
        int BMP_BOOT_SECTOR_SIZE = 0x1000;
1884

1885
        /** Offset of CRC in boot sector of flash. */
1886
        int BMP_BOOT_CRC_OFFSET = BMP_BOOT_SECTOR_SIZE - WORD_SIZE;
1887

1888
        /** Byte used to blank out the space used for blacklists. */
1889
        byte BLACKLIST_BLANK = (byte) 255;
1890
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc