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

SpiNNakerManchester / JavaSpiNNaker / 6233274834

19 Sep 2023 08:46AM UTC coverage: 36.409% (-0.6%) from 36.982%
6233274834

Pull #658

github

dkfellows
Merge branch 'master' into java-17
Pull Request #658: Update Java version to 17

1656 of 1656 new or added lines in 260 files covered. (100.0%)

8373 of 22997 relevant lines covered (36.41%)

0.36 hits per line

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

4.12
/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 uk.ac.manchester.spinnaker.machine.MemoryLocation.NULL;
20
import static uk.ac.manchester.spinnaker.messages.Constants.WORD_SIZE;
21
import static uk.ac.manchester.spinnaker.messages.model.PowerCommand.POWER_OFF;
22
import static uk.ac.manchester.spinnaker.messages.model.PowerCommand.POWER_ON;
23
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BLACKLIST_BLANK;
24
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BMP_BOOT_BLACKLIST_OFFSET;
25
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BMP_BOOT_CRC_OFFSET;
26
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BMP_BOOT_SECTOR_ADDR;
27
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.BMP_BOOT_SECTOR_SIZE;
28
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.SF_BL_ADDR;
29
import static uk.ac.manchester.spinnaker.transceiver.BMPConstants.SF_BL_LEN;
30
import static uk.ac.manchester.spinnaker.transceiver.Utils.crc;
31
import static uk.ac.manchester.spinnaker.transceiver.Utils.fill;
32
import static uk.ac.manchester.spinnaker.utils.ByteBufferUtils.alloc;
33
import static uk.ac.manchester.spinnaker.utils.ByteBufferUtils.wordAsBuffer;
34

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1542
                data.position(0); // Prep for write
×
1543

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

1549
                // Do the actual writes here; any failure before here is unimportant
1550
                writeFlash(bmp, board, BMP_BOOT_SECTOR_ADDR, data);
×
1551
                writeSerialFlash(bmp, board, NULL, ByteBuffer.wrap(sfData));
×
1552
        }
×
1553

1554
        /**
1555
         * Read the CRC32 checksum of BMP serial flash memory.
1556
         *
1557
         * @param board
1558
         *            Which board's BMP are we reading?
1559
         * @param baseAddress
1560
         *            The address in the BMP's serial flash where the region of
1561
         *            memory to be checksummed starts
1562
         * @param length
1563
         *            The length of the data to be checksummed in bytes
1564
         * @return The CRC32 checksum
1565
         * @throws IOException
1566
         *             If anything goes wrong with networking.
1567
         * @throws ProcessException
1568
         *             If SpiNNaker rejects a message.
1569
         * @throws InterruptedException
1570
         *             If the communications were interrupted.
1571
         */
1572
        @ParallelSafeWithCare
1573
        @CheckReturnValue
1574
        default int readSerialFlashCRC(@Valid BMPBoard board,
1575
                        @NotNull MemoryLocation baseAddress, @Positive int length)
1576
                        throws IOException, ProcessException, InterruptedException {
1577
                return readSerialFlashCRC(getBoundBMP(), board, baseAddress, length);
×
1578
        }
1579

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

1606
        /**
1607
         * Write BMP serial flash memory from a file.
1608
         *
1609
         * @param board
1610
         *            Which board's BMP are we writing?
1611
         * @param baseAddress
1612
         *            The address in the BMP's serial flash where the region of
1613
         *            memory to be written starts
1614
         * @param file
1615
         *            The file containing the data to be written
1616
         * @throws IOException
1617
         *             If anything goes wrong with networking.
1618
         * @throws ProcessException
1619
         *             If SpiNNaker rejects a message.
1620
         * @throws InterruptedException
1621
         *             If the communications were interrupted.
1622
         */
1623
        default void writeSerialFlash(@Valid BMPBoard board,
1624
                        @NotNull MemoryLocation baseAddress, @NotNull File file)
1625
                        throws ProcessException, IOException, InterruptedException {
1626
                writeSerialFlash(getBoundBMP(), board, baseAddress, file);
×
1627
        }
×
1628

1629
        /**
1630
         * Write BMP serial flash memory from a file.
1631
         *
1632
         * @param bmp
1633
         *            Which BMP are we talking to?
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
        void writeSerialFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1649
                        @NotNull MemoryLocation baseAddress, @NotNull File file)
1650
                        throws ProcessException, IOException, InterruptedException;
1651

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

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

1704
        /**
1705
         * Write BMP serial flash memory.
1706
         *
1707
         * @param board
1708
         *            Which board's BMP are we writing?
1709
         * @param baseAddress
1710
         *            The address in the BMP's serial flash where the region of
1711
         *            memory to be written starts
1712
         * @param data
1713
         *            The raw data to be written
1714
         * @throws IOException
1715
         *             If anything goes wrong with networking.
1716
         * @throws ProcessException
1717
         *             If SpiNNaker rejects a message.
1718
         * @throws InterruptedException
1719
         *             If the communications were interrupted.
1720
         */
1721
        default void writeSerialFlash(@Valid BMPBoard board,
1722
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1723
                        throws ProcessException, IOException, InterruptedException {
1724
                writeSerialFlash(getBoundBMP(), board, baseAddress, data);
×
1725
        }
×
1726

1727
        /**
1728
         * Write BMP serial flash memory.
1729
         *
1730
         * @param bmp
1731
         *            Which BMP are we talking to?
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
        void writeSerialFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1747
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1748
                        throws ProcessException, IOException, InterruptedException;
1749

1750
        /**
1751
         * Write a {@linkplain WriteFlashBuffer#FLASH_CHUNK_SIZE fixed size} chunk
1752
         * to flash memory of a BMP with erase. The data must have already been
1753
         * written to the flash buffer.
1754
         *
1755
         * @param board
1756
         *            Which board's BMP are we writing to?
1757
         * @param baseAddress
1758
         *            Where in flash will we write?
1759
         * @see #writeFlash(BMPCoords,BMPBoard,MemoryLocation,ByteBuffer)
1760
         * @throws IOException
1761
         *             If anything goes wrong with networking.
1762
         * @throws ProcessException
1763
         *             If SpiNNaker rejects a message.
1764
         * @throws InterruptedException
1765
         *             If the communications were interrupted.
1766
         */
1767
        default void writeBMPFlash(@Valid BMPBoard board,
1768
                        @NotNull MemoryLocation baseAddress)
1769
                        throws IOException, ProcessException, InterruptedException {
1770
                writeBMPFlash(getBoundBMP(), board, baseAddress);
×
1771
        }
×
1772

1773
        /**
1774
         * Write a {@linkplain WriteFlashBuffer#FLASH_CHUNK_SIZE fixed size} chunk
1775
         * to flash memory of a BMP with erase. The data must have already been
1776
         * written to the flash buffer.
1777
         *
1778
         * @param bmp
1779
         *            Which BMP are we talking to?
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
        void writeBMPFlash(@Valid BMPCoords bmp, @Valid BMPBoard board,
1793
                        @NotNull MemoryLocation baseAddress)
1794
                        throws IOException, ProcessException, InterruptedException;
1795

1796
        /**
1797
         * Write a buffer to flash memory on the BMP. This is a composite operation.
1798
         *
1799
         * @param board
1800
         *            Which board's BMP are we writing to?
1801
         * @param baseAddress
1802
         *            Where in flash will we write?
1803
         * @param data
1804
         *            What data will we write?
1805
         * @throws IOException
1806
         *             If anything goes wrong with networking.
1807
         * @throws ProcessException
1808
         *             If SpiNNaker rejects a message.
1809
         * @throws InterruptedException
1810
         *             If the communications were interrupted.
1811
         */
1812
        default void writeFlash(@Valid BMPBoard board,
1813
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1814
                        throws ProcessException, IOException, InterruptedException {
1815
                writeFlash(getBoundBMP(), board, baseAddress, data);
×
1816
        }
×
1817

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

1840
        @Override
1841
        void close() throws IOException;
1842
}
1843

1844
interface BMPConstants {
1845
        /** Location in serial flash of blacklist. */
1846
        MemoryLocation SF_BL_ADDR = new MemoryLocation(0x100);
×
1847

1848
        /** Size of blacklist, in bytes. */
1849
        int SF_BL_LEN = 256;
1850

1851
        /** Offset of blacklist in boot sector of flash. */
1852
        int BMP_BOOT_BLACKLIST_OFFSET = 0xe00;
1853

1854
        /** Location of boot sector of flash. */
1855
        MemoryLocation BMP_BOOT_SECTOR_ADDR = new MemoryLocation(0x1000);
×
1856

1857
        /** Size of boot sector of flash. */
1858
        int BMP_BOOT_SECTOR_SIZE = 0x1000;
1859

1860
        /** Offset of CRC in boot sector of flash. */
1861
        int BMP_BOOT_CRC_OFFSET = BMP_BOOT_SECTOR_SIZE - WORD_SIZE;
1862

1863
        /** Byte used to blank out the space used for blacklists. */
1864
        byte BLACKLIST_BLANK = (byte) 255;
1865
}
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