[fpga] Modify cw_spiflash.py to support the CW310 FPGA board

Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/util/fpga/cw_spiflash.py b/util/fpga/cw_spiflash.py
index ee35d6d..4d56435 100644
--- a/util/fpga/cw_spiflash.py
+++ b/util/fpga/cw_spiflash.py
@@ -53,6 +53,7 @@
     FRAME_NUMBER_SIZE: Size of the frame number field in bytes.
     FLASH_OFFSET_SIZE: Size of the flash offset field in bytes.
     PAYLOAD_SIZE: Size of the frame payload in bytes.
+    FRAME_SIZE: Size of the SPI Flash frame, depends on the Boot ROM, see spiflash_frame.h.
     is_second_frame: Indicates if this is the second frame.
     expected_ack: Expected acknowledgement value for a frame.
   """
@@ -60,7 +61,8 @@
   DIGEST_SIZE = HASH_FUNCTION().digest_size
   FRAME_NUMBER_SIZE = 4
   FLASH_OFFSET_SIZE = 4
-  PAYLOAD_SIZE = 2048 - DIGEST_SIZE - FRAME_NUMBER_SIZE - FLASH_OFFSET_SIZE
+  FRAME_SIZE = 2048
+  PAYLOAD_SIZE = FRAME_SIZE - DIGEST_SIZE - FRAME_NUMBER_SIZE - FLASH_OFFSET_SIZE
 
   def __init__(self, frame_number, flash_offset, payload):
     """Inits a _SpiFlashFrame.
@@ -106,7 +108,7 @@
     return self.HASH_FUNCTION(bytes(self)).digest()
 
 class _Bootstrap:
-  """Handles low-level details during programming OpenTitan using SAM3U on CW305.
+  """Handles low-level details during programming OpenTitan using SAM3X/U on CW310/305.
 
   Initializes pins, resets OpenTitan, transmits frames, and receives acknowledgements.
 
@@ -116,6 +118,7 @@
   >>>   ack = bootstrap.transfer(frame)
   >>>   ...
   """
+  # Default pin mapping for CW305 board.
   _PIN_SCK='USB_A13'
   _PIN_SDI='USB_A14'
   _PIN_SDO='USB_A15'
@@ -129,12 +132,25 @@
   _SECOND_FRAME_DELAY=0.2
   _INTER_FRAME_DELAY=0.02
 
-  def __init__(self, fpga):
-    """Inits a _Bootstrap with a CW305.
+  def __init__(self, fpga, board="CW305"):
+    """Inits a _Bootstrap with a CW310/305.
 
     Args:
-      fpga: CW305 to be programmed, a ``cw.capture.targets.CW305`` instance.
+      fpga: CW310/305 to be programmed, a ``cw.capture.targets.CW310/305`` instance.
+      board: can be ``CW310`` or ``CW305`` to distinguish the different board types.
     """
+
+    # Change pin mapping to CW310 board.
+    if board == "CW310":
+      self._PIN_SCK='USB_SPI_SCK'
+      self._PIN_SDI='USB_SPI_COPI'
+      self._PIN_SDO='USB_SPI_CIPO'
+      self._PIN_CS='USB_SPI_CS'
+      self._PIN_TRST='USB_A17'
+      self._PIN_SRST='USB_A18'
+      self._PIN_JTAG_SPI='USB_A19'
+      self._PIN_BOOTSTRAP='USB_A16'
+
     # Configure JTAG and bootstrap pins.
     self._fpga_io = fpga.gpio_mode()
     self._fpga_io.pin_set_output(self._PIN_TRST)
@@ -182,17 +198,18 @@
     return bytes(self._fpga_io.spi1_transfer(bytes(frame))[:_SpiFlashFrame.DIGEST_SIZE])
 
 
-class SAM3UProgrammer:
-  """Class for programming OpenTitan over the SPI interface of SAM3U on CW305."""
-  def __init__(self, firmware_path):
-    """Inits SAM3UProgrammer with the path of a firmware image."""
+class SPIProgrammer:
+  """Class for programming OpenTitan over the SPI interface of SAM3X/U on CW310/305."""
+  def __init__(self, firmware_path, board="CW305"):
+    """Inits SPIProgrammer with the path of a firmware image and board name."""
     self._firmware_path = firmware_path
+    self._board = board
 
   def run(self, fpga):
-    """Programs OpenTitan over the SPI interface of SAM3U on CW305.
+    """Programs OpenTitan over the SPI interface of SAM3X/U on CW310/305.
 
-    This implementation has two improvements over the `spiflash` tool in
-    lowRISC/opentitan:
+    This implementation has two improvements over the `spiflash` tool under
+    sw/host/spiflash:
     * Optimizes the happy path by checking the acknowledgement of frame N-1
       after transmitting frame N instead of transmitting an extra frame to check
       each frame's acknowledgement.
@@ -200,9 +217,9 @@
       frame gets corrupted and halts the bootstrapping process.
 
     Args:
-      fpga: CW305 to be programmed, a ``cw.capture.targets.CW305`` instance.
+      fpga: CW310/305 to be programmed, a ``cw.capture.targets.CW310/305`` instance.
     """
-    with _Bootstrap(fpga) as bootstrap:
+    with _Bootstrap(fpga, self._board) as bootstrap:
       frame_number = 0
       flash_offset = 0
       prev_frame = None