quartus-flash.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #!/usr/bin/env python3
  2. # SPDX-License-Identifier: Apache-2.0
  3. import subprocess
  4. import tempfile
  5. import argparse
  6. import os
  7. import string
  8. import sys
  9. quartus_cpf_template = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
  10. <cof>
  11. <output_filename>${OUTPUT_FILENAME}</output_filename>
  12. <n_pages>1</n_pages>
  13. <width>1</width>
  14. <mode>14</mode>
  15. <sof_data>
  16. <user_name>Page_0</user_name>
  17. <page_flags>1</page_flags>
  18. <bit0>
  19. <sof_filename>${SOF_FILENAME}<compress_bitstream>1</compress_bitstream></sof_filename>
  20. </bit0>
  21. </sof_data>
  22. <version>10</version>
  23. <create_cvp_file>0</create_cvp_file>
  24. <create_hps_iocsr>0</create_hps_iocsr>
  25. <auto_create_rpd>0</auto_create_rpd>
  26. <rpd_little_endian>1</rpd_little_endian>
  27. <options>
  28. <map_file>1</map_file>
  29. </options>
  30. <MAX10_device_options>
  31. <por>0</por>
  32. <io_pullup>1</io_pullup>
  33. <config_from_cfm0_only>0</config_from_cfm0_only>
  34. <isp_source>0</isp_source>
  35. <verify_protect>0</verify_protect>
  36. <epof>0</epof>
  37. <ufm_source>2</ufm_source>
  38. <ufm_filepath>${KERNEL_FILENAME}</ufm_filepath>
  39. </MAX10_device_options>
  40. <advanced_options>
  41. <ignore_epcs_id_check>2</ignore_epcs_id_check>
  42. <ignore_condone_check>2</ignore_condone_check>
  43. <plc_adjustment>0</plc_adjustment>
  44. <post_chain_bitstream_pad_bytes>-1</post_chain_bitstream_pad_bytes>
  45. <post_device_bitstream_pad_bytes>-1</post_device_bitstream_pad_bytes>
  46. <bitslice_pre_padding>1</bitslice_pre_padding>
  47. </advanced_options>
  48. </cof>
  49. """
  50. # XXX Do we care about FileRevision, DefaultMfr, PartName? Do they need
  51. # to be parameters? So far seems to work across 2 different boards, leave
  52. # this alone for now.
  53. quartus_pgm_template = """/* Quartus Prime Version 16.0.0 Build 211 04/27/2016 SJ Lite Edition */
  54. JedecChain;
  55. FileRevision(JESD32A);
  56. DefaultMfr(6E);
  57. P ActionCode(Cfg)
  58. Device PartName(10M50DAF484ES) Path("${POF_DIR}/") File("${POF_FILE}") MfrSpec(OpMask(1));
  59. ChainEnd;
  60. AlteraBegin;
  61. ChainType(JTAG);
  62. AlteraEnd;"""
  63. def create_pof(input_sof, kernel_hex):
  64. """given an input CPU .sof file and a kernel binary, return a file-like
  65. object containing .pof data suitable for flashing onto the device"""
  66. t = string.Template(quartus_cpf_template)
  67. output_pof = tempfile.NamedTemporaryFile(suffix=".pof")
  68. input_sof = os.path.abspath(input_sof)
  69. kernel_hex = os.path.abspath(kernel_hex)
  70. # These tools are very stupid and freak out if the desired filename
  71. # extensions are used. The kernel image must have extension .hex
  72. with tempfile.NamedTemporaryFile(suffix=".cof") as temp_xml:
  73. xml = t.substitute(SOF_FILENAME=input_sof,
  74. OUTPUT_FILENAME=output_pof.name,
  75. KERNEL_FILENAME=kernel_hex)
  76. temp_xml.write(bytes(xml, 'UTF-8'))
  77. temp_xml.flush()
  78. cmd = ["quartus_cpf", "-c", temp_xml.name]
  79. try:
  80. subprocess.check_output(cmd)
  81. except subprocess.CalledProcessError as cpe:
  82. sys.exit(cpe.output.decode("utf-8") +
  83. "\nFailed to create POF file")
  84. return output_pof
  85. def flash_kernel(device_id, input_sof, kernel_hex):
  86. pof_file = create_pof(input_sof, kernel_hex)
  87. with tempfile.NamedTemporaryFile(suffix=".cdf") as temp_cdf:
  88. dname, fname = os.path.split(pof_file.name)
  89. t = string.Template(quartus_pgm_template)
  90. cdf = t.substitute(POF_DIR=dname, POF_FILE=fname)
  91. temp_cdf.write(bytes(cdf, 'UTF-8'))
  92. temp_cdf.flush()
  93. cmd = ["quartus_pgm", "-c", device_id, temp_cdf.name]
  94. try:
  95. subprocess.check_output(cmd)
  96. except subprocess.CalledProcessError as cpe:
  97. sys.exit(cpe.output.decode("utf-8") +
  98. "\nFailed to flash image")
  99. pof_file.close()
  100. def main():
  101. parser = argparse.ArgumentParser(description="Flash zephyr onto Altera boards")
  102. parser.add_argument("-s", "--sof",
  103. help=".sof file with Nios II CPU configuration")
  104. parser.add_argument("-k", "--kernel",
  105. help="Zephyr kernel image to place into UFM in Intel HEX format")
  106. parser.add_argument("-d", "--device",
  107. help="Remote device identifier / cable name. Default is "
  108. "USB-BlasterII. Run jtagconfig -n if unsure.",
  109. default="USB-BlasterII")
  110. args = parser.parse_args()
  111. flash_kernel(args.device, args.sof, args.kernel)
  112. if __name__ == "__main__":
  113. main()