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