Mistake on this page?
Report an issue in GitHub or email us
MbedTester.h
1 /*
2  * Copyright (c) 2019, Arm Limited and affiliates.
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef MBED_TESTER_H
19 #define MBED_TESTER_H
20 
21 #include "DynamicPinList.h"
22 #include "platform/FileHandle.h"
23 #include "platform/Callback.h"
24 #include "drivers/DigitalInOut.h"
25 
26 /**
27  * The base class for controlling the FPGA CI Test Shield
28  *
29  * This is the primary interface to the FPGA CI Test Shield. It contains
30  * all the code to communicate with the FPGA. It also provides high level
31  * helper functions, such as functions to setup pin multiplexing, to
32  * select the currently active peripheral and to perform software updates.
33  *
34  * Subclasses can inherit from this class and provide further functionality,
35  * such as the ability to test SPI.
36  *
37  * @note Synchronization level: Not protected
38  *
39  * Example of how to toggle Arduino pin D6 from the FPGA cI Test Shield:
40  * @code
41  * #include "mbed.h"
42  * #include "MbedTester.h"
43  *
44  * const PinList *form_factor = pinmap_ff_default_pins();
45  * const PinList *restricted = pinmap_restricted_pins();
46  * MbedTester tester(form_factor, restricted);
47  *
48  * int main() {
49  * // Reset the FPGA CI Test Shield to put it into a known state
50  * tester.reset();
51  *
52  * // Select the GPIO peripheral
53  * tester.select_peripheral(MbedTester::PeripheralGPIO);
54  *
55  * // Map D6 to LogicalPinGPIO0
56  * tester.pin_map_set(D6, MbedTester::LogicalPinGPIO0);
57  *
58  * // Toggle pin D6
59  * int toggle = 0;
60  * while (1) {
61  * tester.gpio_write(MbedTester::LogicalPinGPIO0, toggle, true);
62  * wait(0.5);
63  * toggle = !toggle;
64  * }
65  * }
66  * @endcode
67  */
68 class MbedTester {
69 public:
70 
71  /*
72  * This type represents the index of a physical pin on the FPGA.
73  * This can be any value from 0 to 127. A form factor is used to
74  * map a PinName to a physical pin index.
75  */
76  typedef uint8_t PhysicalIndex;
77 
78  /*
79  * There are 8 logical pins connected to the peripherals inside the FPGA.
80  * These are logical pins 0 through 7. All peripherals can read from these
81  * pins and the currently active peripheral can output on these pins.
82  *
83  * Each logical pin has a fixed function for a given peripheral which is
84  * why the same value is defined multiple times. For example logical pin
85  * 2 is SPI clock (SPISclk) when SPI is the active peripheral and
86  * UART clear to send (UARTCts) when UART is the active peripheral.
87  *
88  * A logic pin can be mapped to any physical pin (PinName type) by calling
89  * the function MbedTester::pin_map_set.
90  */
91  enum LogicalPin {
92 
93  LogicalPinGPIO0 = 0,
94  LogicalPinGPIO1 = 1,
95  LogicalPinGPIO2 = 2,
96  LogicalPinGPIO3 = 3,
97  LogicalPinGPIO4 = 4,
98  LogicalPinGPIO5 = 5,
99  LogicalPinGPIO6 = 6,
100  LogicalPinGPIO7 = 7,
101 
102  LogicalPinSPIMosi = 0,
103  LogicalPinSPIMiso = 1,
104  LogicalPinSPISclk = 2,
105  LogicalPinSPISsel = 3,
106 
107  LogicalPinIOMetrics0 = 0,
108  LogicalPinIOMetrics1 = 1,
109  LogicalPinIOMetrics2 = 2,
110  LogicalPinIOMetrics3 = 3,
111  LogicalPinIOMetrics4 = 4,
112  LogicalPinIOMetrics5 = 5,
113  LogicalPinIOMetrics6 = 6,
114  LogicalPinIOMetrics7 = 7,
115 
116  LogicalPinUARTTx = 0,
117  LogicalPinUARTRx = 1,
118  LogicalPinUARTCts = 2,
119  LogicalPinUARTRts = 3,
120 
121  LogicalPinI2CSda = 0,
122  LogicalPinI2CScl = 1,
123 
124  LogicalPinCount = 8,
125  LogicalPinBanks = 2,
126  LogicalPinTotal = LogicalPinCount * LogicalPinBanks
127  };
128 
129  /*
130  * These are the peripherals internal to the FPGA. A peripheral can be
131  * selected by calling MbedTester::select_peripheral.
132  */
133  enum Peripheral {
134  PeripheralGPIO = 1,
135  PeripheralSPI = 2,
136  PeripheralUART = 4,
137  PeripheralI2C = 5,
138  PeripheralSPISlave = 6
139  };
140 
141  /**
142  * Construct a new MbedTester object
143  *
144  * The form factor pins passed into this class must match the
145  * physical MbedTester shield connected to this board or testing
146  * will not work correctly. The order of pins in this list must
147  * match the order of the shield.
148  *
149  * The exclude pins list should be used to exclude pins which you either
150  * don't want to be tested or are not suitable for use as a control
151  * channel. This list is allowed to contain pins that are not in the
152  * form factor.
153  *
154  * @param form_factor The pins that are available on this form factor
155  * @param exclude_pins The pins that must not be used
156  */
157  MbedTester(const PinList *form_factor, const PinList *exclude_pins);
158 
159  /**
160  * Destroy and cleanup resources associated with this object
161  */
162  ~MbedTester();
163 
164  /**
165  * Enable automatic selection and update of control pins
166  *
167  * Calling this function configures MbedTester to automatically select
168  * and update the control pins. The control pins are moved if the
169  * function MbedTester::pin_map_set is called and maps a pin that is being used
170  * for control.
171  *
172  * @note Automatic selection and update of control pins is the default.
173  * Unless MbedTester::set_control_pins_manual has been called to manually
174  * set the control pins this function has no effect.
175  */
176  void set_control_pins_auto();
177 
178  /**
179  * Set the control pins to use for communication
180  *
181  * Manually set the control pins. Calling this function
182  * disables automatic control pin selection and updates.
183  * The function MbedTester::pin_map_set must not be used to map over
184  * control pins when in this mode.
185  *
186  * @param clk Clock pin to use as the control channel
187  * @param mosi Mosi pin to use as the control channel
188  * @param miso Miso pin to use as the control channel
189  * @param aux Auxillary pin to use as the control cannel
190  */
191  void set_control_pins_manual(PinName clk, PinName mosi, PinName miso, PinName aux);
192 
193  /**
194  * Read FPGA CI Test Shield firmware
195  *
196  * Read the firmware on the FPGA CI Test Shield. An optional progress callback
197  * can be supplied to display progress while the firmware is being read.
198  *
199  * @param dest File to write the firmware to. This file must have been opened as writeable
200  * @param progress Optional progress callback called when the percent complete changes
201  * @return true if firmware was successfully read, false otherwise
202  */
203  bool firmware_dump(mbed::FileHandle *dest, mbed::Callback<void(uint8_t)> progress = mbed::Callback<void(uint8_t)>());
204 
205  /**
206  * Read FPGA CI Test Shield flash
207  *
208  * Read the entire flash contents of the FPGA CI Test Shield. An optional progress callback
209  * can be supplied to display progress while the firmware is being read.
210  *
211  * @param dest File to write the firmware to. This file must have been opened as writeable
212  * @param progress Optional progress callback called when the percent complete changes
213  * @return true if firmware was successfully read, false otherwise
214  */
215  bool firmware_dump_all(mbed::FileHandle *dest, mbed::Callback<void(uint8_t)> progress = mbed::Callback<void(uint8_t)>());
216 
217  /**
218  * Program new FPGA CI Test Shield firmware
219  *
220  * Program firmware from the file given. The binary bitstream must be in the correct format
221  * and contain a correct CRC or the update will fail. To correctly format a bitstream binary
222  * the post_process_bitstream.py script in the fpga-ci-test-shield repository should be used.
223  *
224  * Note - release binaries for the FPGA CI Test Shield have already been formatted and
225  * can be loaded directly with this function
226  *
227  * @param src File containing the new firmware to program
228  * @param progress Optional progress callback called when the percent complete changes
229  * @return true if firmware was successfully applied, false otherwise
230  */
231  bool firmware_update(mbed::FileHandle *src, mbed::Callback<void(uint8_t)> progress = mbed::Callback<void(uint8_t)>());
232 
233  /**
234  * Map a physical pin to the given logical pin
235  *
236  * This function will automatically move the control channel
237  * pins to avoid interfering with the mapped pin.
238  *
239  * @param physical Physical pin on the board
240  * @param logical Logical pin to map to
241  */
242  void pin_map_set(PinName physical, LogicalPin logical);
243 
244  /**
245  * Reset all pin mappings
246  *
247  * After this call all pins will be unmapped
248  */
249  void pin_map_reset();
250 
251  /**
252  * Reset all peripherals
253  *
254  * This does not reset the pin mappings
255  */
256  void peripherals_reset();
257 
258  /**
259  * Reset everything
260  *
261  * This function resets the state of both the FPGA CI Test Shield
262  * and the MbedTester object itself.
263  *
264  * Reset effects on the FPGA CI Test Shield include:
265  * - All pins are tristated
266  * - All pin mappings are reset
267  * - All pullup/pulldown settings are reset
268  * - All peripherals are reset
269  *
270  * Reset effects on the MbedTester object include
271  * - Control channels tristated and freed
272  * - Control channel selection set to automatic
273  * - Most internal state reinitialized
274  */
275  void reset();
276 
277  /**
278  * Reprogram the FPGA
279  *
280  * This function causes the FPGA to reboot and reload RAM contents.
281  * This should be used after MbedTester::firmware_update to load the
282  * new image.
283  */
284  void reprogram();
285 
286  /**
287  * Get the running FPGA firmware version
288  *
289  * @return The version of firmware running on the FPGA.
290  *
291  */
292  uint32_t version();
293 
294  /**
295  * Select the currently active peripheral
296  *
297  * @param peripheral Active peripheral
298  */
299  void select_peripheral(Peripheral peripheral);
300 
301  /* **GPIO peripheral functions** */
302 
303  /**
304  * Read a gpio pin
305  *
306  * @param gpio Logical pin to read from
307  * @return 1 if the pin is high 0 if the pin is low
308  */
309  int gpio_read(LogicalPin gpio);
310 
311  /**
312  * Set value and drive of a gpio pin
313  *
314  * @param gpio Logical pin to write to
315  * @param value 0 to set the pin low or non-zero to set it high
316  * @param driver 0 to set the pin to Hi-Z or non-zero to drive the pin
317  */
318  void gpio_write(LogicalPin gpio, int value, bool drive);
319 
320  /* **IO Metrics functions** */
321 
322  /**
323  * Start recording metrics on all logical pins
324  *
325  * This function resets all past metrics to 0. To
326  * preserve these call io_metrics_continue instead.
327  */
328  void io_metrics_start();
329 
330  /**
331  * Stop recording metrics on all logical pins
332  *
333  * This function should be called before any metrics
334  * are read to ensure the value does not change while
335  * they are being read.
336  */
337  void io_metrics_stop();
338 
339  /**
340  * Continue recording metrics on all logical pins
341  *
342  * Resume recording metrics.
343  */
344  void io_metrics_continue();
345 
346  /**
347  * Get the shortest low pulse recorded
348  *
349  * @param pin Pin to read the metrics for
350  * @return The shortest number of 100MHz clock cycles the pin was low
351  */
352  uint32_t io_metrics_min_pulse_low(LogicalPin pin);
353 
354  /**
355  * Get the shortest high pulse recorded
356  *
357  * @param pin Pin to read the metrics for
358  * @return The shortest number of 100MHz clock cycles the pin was high
359  */
360  uint32_t io_metrics_min_pulse_high(LogicalPin pin);
361 
362  /**
363  * Get the longest low pulse recorded
364  *
365  * @param pin Pin to read the metrics for
366  * @return The longest number of 100MHz clock cycles the pin was low
367  */
368  uint32_t io_metrics_max_pulse_low(LogicalPin pin);
369 
370  /**
371  * Get the longest high pulse recorded
372  *
373  * @param pin Pin to read the metrics for
374  * @return The longest number of 100MHz clock cycles the pin was high
375  */
376  uint32_t io_metrics_max_pulse_high(LogicalPin pin);
377 
378  /**
379  * Get the number of rising edges
380  *
381  * @param pin Pin to read the metrics for
382  * @return The number of rising edges
383  */
384  uint32_t io_metrics_rising_edges(LogicalPin pin);
385 
386  /**
387  * Get the number of falling edges
388  *
389  * @param pin Pin to read the metrics for
390  * @return The number of falling edges
391  */
392  uint32_t io_metrics_falling_edges(LogicalPin pin);
393 
394  /**
395  * Reset the IO expander modules
396  *
397  */
398  void pin_pull_reset_all();
399 
400  /**
401  * FPGA Pullup mode
402  */
403  enum PullMode {
404  PullUp,
405  PullDown,
406  PullNone
407  };
408 
409  /**
410  * Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode via PinName
411  *
412  * @param pin Mbed pin whose mode is being set
413  * @param mode (MbedTester::PullUp, MbedTester::PullDown, or MbedTester::PullNone)
414  * @return 0 on success, nonzero on failure
415  */
416  int pin_set_pull(PinName pin, PullMode mode);
417 
418  /**
419  * Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode via pin index
420  *
421  * @param index Mbed pin index whose mode is being set
422  * @param mode (MbedTester::PullUp, MbedTester::PullDown, or MbedTester::PullNone)
423  * @return 0 on success, nonzero on failure
424  */
425  int pin_set_pull_index(int index, PullMode mode);
426 
427  /*
428  * Register of the IO expander
429  */
430  enum IOExpanderReg {
431  RegInput,
432  RegOutput,
433  RegConfig
434  };
435 
436  /**
437  * Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers inside of the IO expander via PinName
438  *
439  * @param pin Mbed pin whose register bit is being read
440  * @param reg_type Pin register to access, options are: MbedTester::RegInput, MbedTester::RegOutput, or MbedTester::RegConfig
441  * @return The value of the bit read
442  */
443  uint8_t io_expander_read(PinName pin, IOExpanderReg reg_type);
444 
445  /**
446  * Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers inside of the IO expander via pin index
447  *
448  * @param index Mbed pin index whose register bit is being read
449  * @param reg_type Pin register to access, options are: MbedTester::RegInput, MbedTester::RegOutput, or MbedTester::RegConfig
450  * @return The value of the bit read
451  */
452  uint8_t io_expander_read_index(int index, IOExpanderReg reg_type);
453 
454  /**
455  * Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode
456  * (this version of the function uses io_expander_i2c_read_bb and io_expander_i2c_write_bb)
457  *
458  * @param pin Mbed pin whose mode is being set
459  * @param mode (MbedTester::PullUp, MbedTester::PullDown, or MbedTester::PullNone)
460  * @return 0 on success, nonzero on failure
461  */
462  int pin_set_pull_bb(PinName pin, PullMode mode);
463 
464  /**
465  * Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers inside of the IO expander
466  * (this version of the function uses io_expander_i2c_read_bb)
467  *
468  * @param pin Mbed pin whose register bit is being read
469  * @param reg_type Pin register to access, options are: MbedTester::RegInput, MbedTester::RegOutput, or MbedTester::RegConfig
470  * @return The value of the bit read
471  */
472  uint8_t io_expander_read_bb(PinName pin, IOExpanderReg reg_type);
473 
474  /**
475  * Create an analog voltage via the FPGA sys pwm in order to test Mbed AnalogIn
476  *
477  * @param enable Enable the FPGA system PWM (false: of, true: on)
478  * @param voltage The analog voltage that will be created by the FPGA CI test shield (float: 0.0 to 1.0)
479  */
480  void set_analog_out(bool enable, float voltage);
481 
482  /**
483  * Turn the FPGA ADC on and off (power management data will be collected while the ADC is on)
484  *
485  * @param val FPGA ADC enable bit (false: off, true: on)
486  */
487  void set_sample_adc(bool val);
488 
489  /**
490  * Get the result of the analog to digital conversion computed on the FPGA in the form of a voltage reading. The FPGA ADC operates on 0V-1V, which means this function will only ever return a float ranging from 0.0-1.0.
491  *
492  * @return The conversion result in the form of a voltage measurement for AnalogMuxIn, Eg. a return value of 0.7 means the ADC on the FPGA read 0.7 volts on its analog input
493  */
494  float get_analog_in();
495 
496  /**
497  * Similar to 'get_analog_in' but returns a voltage reading from ANIN0-3
498  *
499  * @param index ANIN pin to read (0-3)
500  * @return The conversion result in the form of a voltage measurement for ANIN0-3
501  */
502  float get_anin_voltage(int index);
503 
504  /* **Mid level system access** */
505 
506  /*
507  * These are the pins on the FPGA that are not connected to the Mbed board.
508  * These can be controlled by using MbedTester::sys_pin_read and MbedTester::sys_pin_write.
509  * These should not be used directly when using the FPGA CI Test Shield. The higher layer
510  * APIs should be used instead.
511  */
512  enum SystemPin {
513  Reset,
514  Reprogram,
515 
516  DigitalID0,
517  DigitalID1,
518  DigitalID2,
519 
520  Led0,
521  Led1,
522  Led2,
523  Led3,
524 
525  SPIIO0,
526  SPIIO1,
527  SPIIO2,
528  SPIIO3,
529  SPIClk,
530  SPICS,
531 
532  I2CReset,
533  I2CSda0,
534  I2CSda1,
535  I2CSda2,
536  I2CScl0,
537  I2CScl1,
538  I2CScl2,
539 
540  AnalogMuxEnable,
541  AnalogMuxPwmOut,
542  AnalogMuxIn,
543  AnalogMuxAddr0,
544  AnalogMuxAddr1,
545  AnalogMuxAddr2,
546  AnalogMuxAddr3,
547  AnalogMuxAddr4,
548  AnalogMuxAddr5,
549  AnalogMuxAddr6,
550  AnalogMuxAddr7,
551 
552  AnalogInP0,
553  AnalogInP1,
554  AnalogInP2,
555  AnalogInP3,
556  AnalogInN0,
557  AnalogInN1,
558  AnalogInN2,
559  AnalogInN3,
560 
561  SystemPinCount
562  };
563 
564  /**
565  * Read from the given system pin
566  *
567  * @param pin The pin to read from
568  * @return true if 1 was read, false if 0
569  */
570  bool sys_pin_read(SystemPin pin);
571 
572  /**
573  * Write to the given system pin
574  *
575  * @param pin The pin to write to
576  * @param value The value to output on the pin when driven
577  * @param true to drive the output, false to set the output high-z
578  * @return true if 1 was read, false if 0
579  */
580  void sys_pin_write(SystemPin pin, int value, bool drive);
581 
582  /**
583  * I2C read on I2C system channels 0, 1, or 2
584  *
585  * @param i2c_index The number corresponding to the system i2c bus being used (0, 1, or 2)
586  * @param dev_addr The I2C address of the device being read from
587  * @param start_reg The internal device address where the read will start
588  * @param data Data buffer for data to be read into
589  * @param length The number of bytes to read
590  * @return 0 on success (ACK), nonzero on failure (NACK)
591  */
592  int io_expander_i2c_read(uint8_t i2c_index, uint8_t dev_addr, uint8_t start_reg, uint8_t *data, int length);
593 
594  /**
595  * I2C write on I2C system channels 0, 1, or 2
596  *
597  * @param i2c_index The number corresponding to the system i2c bus being used (0, 1, or 2)
598  * @param dev_addr The I2C address of the device being written to
599  * @param data The data to be written
600  * @param length The number of bytes to be written
601  * @return 0 on success (ACK), nonzero on failure (NACK)
602  */
603  int io_expander_i2c_write(uint8_t i2c_index, uint8_t dev_addr, uint8_t *data, int length);
604 
605  /**
606  * I2C read on I2C system channels 0, 1, or 2
607  * (bit banged version of function, bit banged over control channel)
608  *
609  * @param sda System pin used for sda
610  * @param scl System pin used for scl
611  * @param dev_addr The I2C address of the device being read from
612  * @param start_reg The internal device address where the read will start
613  * @param data Data buffer for data to be read into
614  * @param length The number of bytes to read
615  * @return 0 on success (ACK), nonzero on failure (NACK)
616  */
617  int io_expander_i2c_read_bb(SystemPin sda, SystemPin scl, uint8_t dev_addr, uint8_t start_reg, uint8_t *data, int length);
618 
619  /**
620  * I2C write on I2C system channels 0, 1, or 2
621  * (bit banged version of function, bit banged over control channel)
622  *
623  * @param sda System pin used for sda
624  * @param scl System pin used for scl
625  * @param dev_addr The I2C address of the device being written to
626  * @param data The data to be written
627  * @param length The number of bytes to be written
628  * @return 0 on success (ACK), nonzero on failure (NACK)
629  */
630  int io_expander_i2c_write_bb(SystemPin sda, SystemPin scl, uint8_t dev_addr, uint8_t *data, int length);
631 
632  /**
633  * Set the AnalogMuxAddr pins on the FPGA via PinName
634  *
635  * @param pin The Mbed pin that the analog signal will be routed to
636  * @return 0 on success, nonzero on failure
637  */
638  int set_mux_addr(PinName pin);
639 
640  /**
641  * Set the AnalogMuxAddr pins on the FPGA via pin index
642  *
643  * @param index The Mbed pin index that the analog signal will be routed to
644  * @return 0 on success, nonzero on failure
645  */
646  int set_mux_addr_index(int index);
647 
648  /* **AnalogIn peripheral functions** */
649 
650  /**
651  * Turn on/off the analog muxes
652  *
653  * @param val false: off, true: on
654  */
655  void set_mux_enable(bool val);
656 
657  /**
658  * Turn on/off pwm output on FPGA to test Mbed AnalogIn
659  *
660  * @param val false: off, true: on
661  */
662  void set_pwm_enable(bool val);
663 
664  /**
665  * Check if FPGA pwm out is on or off
666  *
667  * @return FPGA enable bit (false: off, true: on)
668  */
669  bool get_pwm_enable();
670 
671  /**
672  * Set the pwm output period and number of cycles high (duty cycle) on the FPGA
673  *
674  * @param period In units of clk cycles
675  * @param cycles_high In units of clk cycles
676  */
677  void set_pwm_period_and_cycles_high(uint32_t period, uint32_t cycles_high);
678 
679  /**
680  * Get the pwm output period of the FPGA
681  *
682  * @return FPGA pwm output period in units of clk cycles
683  */
684  uint32_t get_pwm_period();
685 
686  /**
687  * Get the number of cycles that are high (duty cycle) from FPGA pwm
688  *
689  * @return FPGA pwm output cycles high
690  */
691  uint8_t get_pwm_cycles_high();
692 
693  /**
694  * Get the 12-bit analog to digital conversion result from the FPGA
695  *
696  * @return 12-bit FPGA ADC result for AnalogMuxIn
697  */
698  uint16_t get_analogmuxin_measurement();
699 
700  /**
701  * Similar to 'get_analogmuxin_measurement' but returns the current XADC measurement for ANIN0-3
702  *
703  * @param index ANIN pin to read (0-3)
704  * @return 12-bit FPGA ADC result for ANIN0-3
705  */
706  uint16_t get_anin_measurement(int index);
707 
708  /**
709  * Gets (by reference) the sum of all ANIN ADC results for any of the 4 ANIN pins specified by the index,
710  * number of ADC sample sequences that have completed since the XADC was turned on, and the number of FPGA clk cycles
711  * that have taken place since the ADC was turned on.
712  *
713  * @param index ANIN pin of which to get sum of results (0-3)
714  * @param sum The sum of all specified ANIN pin's ADC results
715  * @param samples The number of ADC sample sequences that have completed since the XADC was turned on
716  * @param cycles The number of FPGA clk cycles that have taken place since the ADC was turned on
717  */
718  void get_anin_sum_samples_cycles(int index, uint64_t *sum, uint32_t *samples, uint64_t *cycles);
719 
720  /**
721  * Allows safe reading of FPGA ADC related values while the FPGA ADC is on
722  * If snapshot is set then the ADC values will be safely latched in the FPGA and safe to read.
723  * The RTL will set snapshot to 0 after 1 clk cycle.
724  */
725  void set_snapshot();
726 
727  /**
728  * Set the current system pin mode to disabled
729  *
730  * This releases any pin mappings that were set by the previous pin mode.
731  */
732  void sys_pin_mode_disabled();
733 
734  /**
735  * Set the current system pin mode to serial flash
736  *
737  * Remap physical pins to the serial flash the FPGA boots from.
738  * This is used for firmware updates.
739  *
740  * @param mosi The physical pin index to connect to serial flash mosi
741  * @param miso The physical pin index to connect to serial flash miso
742  * @param clk The physical pin index to connect to serial flash clk
743  * @param ssel The physical pin index to connect to serial flash cs
744  */
745  void sys_pin_mode_spi_serial_flash(PhysicalIndex mosi, PhysicalIndex miso, PhysicalIndex clk, PhysicalIndex ssel);
746 
747  /**
748  * Set the current system pin mode to io expander I2C bus
749  *
750  * Remap physical pins to the io expander I2C bus. The IO expanders
751  * are used for setting pullups and pulldowns.
752  *
753  * @param index The index of the I2C bus to connect to
754  * @param sda_in Physical pin index for the FPGA to output the state of SDA on
755  * @param sda_val Physical pin index for the FPGA to read SDA from. When in this mode the Mbed board
756  * must always drive this pin. Driving a 0 causes the FPGA to pull the SDA on the I2C bus low. Setting
757  * a 1 causes the FPGA to let SDA on the I2C bus float (and get pulled to 1).
758  * @param scl_in Physical pin index for the FPGA to output the state of SCL on
759  * @param scl_val Physical pin index for the FPGA to read SCL from. When in this mode the Mbed board
760  * must always drive this pin. Driving a 0 causes the FPGA to pull the SCL on the I2C bus low. Setting
761  * a 1 causes the FPGA to let SDA on the SCL bus float (and get pulled to 1).
762  */
763  void sys_pin_mode_i2c_io_expander(int index, PhysicalIndex sda_in, PhysicalIndex sda_val, PhysicalIndex scl_in, PhysicalIndex scl_val);
764 
765  /**
766  * Map a physical pin index to the given logical pin
767  *
768  * This function will automatically move the control channel
769  * pins to avoid interfering with the mapped pin. The physical
770  * pin index does not need to be part of the form factor.
771  *
772  * @param physical_index Index of the physical pin on the board
773  * @param logical Logical pin to map to
774  */
775  void pin_map_index(PhysicalIndex physical_index, LogicalPin logical);
776 
777 
778  /* **Low level memory access** */
779 
780  /**
781  * Write to tester memory
782  *
783  * @addr addr Address to write to
784  * @param data Data to write
785  * @param size Number of bytes to write
786  */
787  void write(uint32_t addr, const uint8_t *data, uint32_t size);
788 
789  /**
790  * Read from tester memory
791  *
792  * @addr addr Address to read from
793  * @param data Buffer to fill with data
794  * @param size Number of bytes to read
795  */
796  void read(uint32_t addr, uint8_t *data, uint32_t size);
797 
798  /* **Self tests** */
799 
800  /**
801  * Run all self tests
802  *
803  * @return true if all self tests pass, false otherwise
804  */
805  bool self_test_all();
806 
807  /**
808  * Test that all allowed control channels can be used
809  *
810  * Check that all pairs of clk and mosi which aren't in
811  * the restricted list can be used.
812  *
813  * @note CLK and MOSI lines are paired, where CLK is always
814  * on an even index and MOSI is always on an oddd index:
815  * clk_index_N = N * 2
816  * mosi_index_N = N * 2 + 1
817  *
818  * @note This functions sets the control pin management mode
819  * to automatic when it completes.
820  *
821  * @return true if all control channel pairs (clk and mosi) of this
822  * configuration can be used, false otherwise
823  */
825 
826  /**
827  * Test that all allowed control miso lines can be used
828  *
829  * Check that every pin of this form factor aside from the
830  * pins in the restricted list can be used as miso.
831  *
832  * @note This functions sets the control pin management mode
833  * to automatic when it completes.
834  *
835  * @return true if all control channel miso lines of this
836  * configuration can be used, false otherwise
837  */
838  bool self_test_control_miso();
839 
840  /**
841  * Test that the current control channel works
842  *
843  * @return true if communication is successful, false otherwise
844  */
846 
847 private:
848 
849  /*
850  * Find suitable control pins
851  *
852  * This function finds the appropriate set of pins and test to ensure that communication with
853  * the FPGA can be performed over them. Before calling this function MbedTester pins must be
854  * freed by calling MbedTester::_free_control_pins.
855  *
856  * @param clk_out Clock pin to find and set
857  * @param mosi_out Mosi pin to find and set
858  * @param miso_out Miso pin to find and set
859  * @param aux_out Aux pin to find and set
860  * @return true if all pins were found, false otherwise
861  */
862  bool _find_control_indexes(PhysicalIndex &clk_out, PhysicalIndex &mosi_out, PhysicalIndex &miso_out, PhysicalIndex &aux_out);
863 
864  /*
865  * Allocate control pins
866  *
867  * The pin indexes must already have been found
868  */
869  void _setup_control_pins();
870 
871  /*
872  * Free control pins
873  *
874  * This function is safe to call even if the pins have been freed
875  */
876  void _free_control_pins();
877 
878  /*
879  * Update the control channel if needed
880  *
881  * Open a control channel using allowed pins:
882  * - Pin must be in the form factor
883  * - Pin must not be in the exclude list
884  * - Pin must not be mapped already
885  */
886  void _update_control_pins();
887 
888  /*
889  * Check if this control channel needs to be updated
890  *
891  * @return true if the control channel needs to be updated, false otherwise
892  */
893  bool _update_needed();
894 
895  /*
896  * Reset the state of the MbedTester class
897  *
898  * This does not effect the state of the FPGA in any way.
899  */
900  void _reset();
901 
902  PhysicalIndex _mapping[LogicalPinCount * (LogicalPinBanks + 1)];
903  DynamicPinList _form_factor;
904  DynamicPinList _exclude_pins;
905  bool _control_auto;
906  bool _control_valid;
907  PhysicalIndex _clk_index;
908  PhysicalIndex _mosi_index;
909  PhysicalIndex _miso_index;
910  PhysicalIndex _aux_index;
911  mbed::DigitalInOut *_clk;
912  mbed::DigitalInOut *_mosi;
913  mbed::DigitalInOut *_miso;
914  mbed::DigitalInOut *_aux;
915  /*
916  * Used to reset IO expander chips only once the first time
917  * any IO expander is accessed as well as during an io_exp_test
918  */
919  int _init_io_exp_rst_flag;
920 };
921 
922 #endif
uint16_t get_anin_measurement(int index)
Similar to &#39;get_analogmuxin_measurement&#39; but returns the current XADC measurement for ANIN0-3...
bool self_test_all()
Run all self tests.
bool self_test_control_miso()
Test that all allowed control miso lines can be used.
bool self_test_control_current()
Test that the current control channel works.
bool firmware_dump(mbed::FileHandle *dest, mbed::Callback< void(uint8_t)> progress=mbed::Callback< void(uint8_t)>())
Read FPGA CI Test Shield firmware.
void sys_pin_mode_spi_serial_flash(PhysicalIndex mosi, PhysicalIndex miso, PhysicalIndex clk, PhysicalIndex ssel)
Set the current system pin mode to serial flash.
Definition: pinmap.h:36
int io_expander_i2c_read_bb(SystemPin sda, SystemPin scl, uint8_t dev_addr, uint8_t start_reg, uint8_t *data, int length)
I2C read on I2C system channels 0, 1, or 2 (bit banged version of function, bit banged over control c...
bool firmware_update(mbed::FileHandle *src, mbed::Callback< void(uint8_t)> progress=mbed::Callback< void(uint8_t)>())
Program new FPGA CI Test Shield firmware.
void reprogram()
Reprogram the FPGA.
bool sys_pin_read(SystemPin pin)
Read from the given system pin.
void get_anin_sum_samples_cycles(int index, uint64_t *sum, uint32_t *samples, uint64_t *cycles)
Gets (by reference) the sum of all ANIN ADC results for any of the 4 ANIN pins specified by the index...
void io_metrics_start()
Start recording metrics on all logical pins.
uint32_t version()
Get the running FPGA firmware version.
uint16_t get_analogmuxin_measurement()
Get the 12-bit analog to digital conversion result from the FPGA.
PullMode
FPGA Pullup mode.
Definition: MbedTester.h:403
void set_pwm_enable(bool val)
Turn on/off pwm output on FPGA to test Mbed AnalogIn.
uint32_t io_metrics_falling_edges(LogicalPin pin)
Get the number of falling edges.
Class FileHandle.
Definition: FileHandle.h:46
void set_snapshot()
Allows safe reading of FPGA ADC related values while the FPGA ADC is on If snapshot is set then the A...
void gpio_write(LogicalPin gpio, int value, bool drive)
Set value and drive of a gpio pin.
int set_mux_addr_index(int index)
Set the AnalogMuxAddr pins on the FPGA via pin index.
A digital input/output, used for setting or reading a bi-directional pin.
Definition: DigitalInOut.h:33
void set_control_pins_auto()
Enable automatic selection and update of control pins.
void peripherals_reset()
Reset all peripherals.
int gpio_read(LogicalPin gpio)
Read a gpio pin.
void set_sample_adc(bool val)
Turn the FPGA ADC on and off (power management data will be collected while the ADC is on) ...
void write(uint32_t addr, const uint8_t *data, uint32_t size)
Write to tester memory.
void set_mux_enable(bool val)
Turn on/off the analog muxes.
void pin_map_set(PinName physical, LogicalPin logical)
Map a physical pin to the given logical pin.
void select_peripheral(Peripheral peripheral)
Select the currently active peripheral.
uint8_t io_expander_read_index(int index, IOExpanderReg reg_type)
Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers insid...
void set_analog_out(bool enable, float voltage)
Create an analog voltage via the FPGA sys pwm in order to test Mbed AnalogIn.
MbedTester(const PinList *form_factor, const PinList *exclude_pins)
Construct a new MbedTester object.
void sys_pin_write(SystemPin pin, int value, bool drive)
Write to the given system pin.
void pin_map_reset()
Reset all pin mappings.
void set_control_pins_manual(PinName clk, PinName mosi, PinName miso, PinName aux)
Set the control pins to use for communication.
void reset()
Reset everything.
float get_analog_in()
Get the result of the analog to digital conversion computed on the FPGA in the form of a voltage read...
~MbedTester()
Destroy and cleanup resources associated with this object.
int pin_set_pull_index(int index, PullMode mode)
Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode via pin index...
int io_expander_i2c_read(uint8_t i2c_index, uint8_t dev_addr, uint8_t start_reg, uint8_t *data, int length)
I2C read on I2C system channels 0, 1, or 2.
bool get_pwm_enable()
Check if FPGA pwm out is on or off.
uint32_t io_metrics_max_pulse_low(LogicalPin pin)
Get the longest low pulse recorded.
void io_metrics_continue()
Continue recording metrics on all logical pins.
int io_expander_i2c_write_bb(SystemPin sda, SystemPin scl, uint8_t dev_addr, uint8_t *data, int length)
I2C write on I2C system channels 0, 1, or 2 (bit banged version of function, bit banged over control ...
uint8_t get_pwm_cycles_high()
Get the number of cycles that are high (duty cycle) from FPGA pwm.
void io_metrics_stop()
Stop recording metrics on all logical pins.
void sys_pin_mode_disabled()
Set the current system pin mode to disabled.
void read(uint32_t addr, uint8_t *data, uint32_t size)
Read from tester memory.
uint32_t get_pwm_period()
Get the pwm output period of the FPGA.
int set_mux_addr(PinName pin)
Set the AnalogMuxAddr pins on the FPGA via PinName.
int pin_set_pull_bb(PinName pin, PullMode mode)
Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode (this version of the...
void pin_map_index(PhysicalIndex physical_index, LogicalPin logical)
Map a physical pin index to the given logical pin.
uint32_t io_metrics_min_pulse_high(LogicalPin pin)
Get the shortest high pulse recorded.
uint32_t io_metrics_min_pulse_low(LogicalPin pin)
Get the shortest low pulse recorded.
float get_anin_voltage(int index)
Similar to &#39;get_analog_in&#39; but returns a voltage reading from ANIN0-3.
void set_pwm_period_and_cycles_high(uint32_t period, uint32_t cycles_high)
Set the pwm output period and number of cycles high (duty cycle) on the FPGA.
void pin_pull_reset_all()
Reset the IO expander modules.
int io_expander_i2c_write(uint8_t i2c_index, uint8_t dev_addr, uint8_t *data, int length)
I2C write on I2C system channels 0, 1, or 2.
bool firmware_dump_all(mbed::FileHandle *dest, mbed::Callback< void(uint8_t)> progress=mbed::Callback< void(uint8_t)>())
Read FPGA CI Test Shield flash.
The base class for controlling the FPGA CI Test Shield.
Definition: MbedTester.h:68
uint32_t io_metrics_rising_edges(LogicalPin pin)
Get the number of rising edges.
bool self_test_control_channels()
Test that all allowed control channels can be used.
Callback class based on template specialization.
Definition: Callback.h:39
uint8_t io_expander_read_bb(PinName pin, IOExpanderReg reg_type)
Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers insid...
int pin_set_pull(PinName pin, PullMode mode)
Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode via PinName...
uint8_t io_expander_read(PinName pin, IOExpanderReg reg_type)
Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers insid...
void sys_pin_mode_i2c_io_expander(int index, PhysicalIndex sda_in, PhysicalIndex sda_val, PhysicalIndex scl_in, PhysicalIndex scl_val)
Set the current system pin mode to io expander I2C bus.
uint32_t io_metrics_max_pulse_high(LogicalPin pin)
Get the longest high pulse recorded.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.