SVD parser and generator, DVF/PER/DSLite/... to SVD converter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
3.2 KiB

4 months ago
  1. #!/usr/bin/env python3
  2. import argparse, sys, os
  3. sys.path.append(os.path.dirname(os.path.abspath(__file__))+"/svd")
  4. from dvf import dvfparse
  5. #from svd import svd, svdparse, svdgen
  6. import svd, svdparse, svdgen
  7. from typing import *
  8. WIDTHS = {
  9. dvfparse.Dvf.MCU_78K0: 16,
  10. dvfparse.Dvf.MCU_78K0R: 20,
  11. dvfparse.Dvf.MCU_RL78x1y: 20,
  12. dvfparse.Dvf.MCU_RL78x2y: 20,
  13. }
  14. SERIES = {
  15. # TODO: better categorization in subtypes and stuff
  16. dvfparse.Dvf.MCU_78K0: "78K0(S)",
  17. dvfparse.Dvf.MCU_78K0R: "78K0R",
  18. dvfparse.Dvf.MCU_RL78x1y: "RL78/x1y",
  19. dvfparse.Dvf.MCU_RL78x2y: "RL78/x2y",
  20. }
  21. CPUS = {
  22. # TODO: better categorization in subtypes and stuff
  23. dvfparse.Dvf.MCU_78K0: "78K0(S)",
  24. dvfparse.Dvf.MCU_78K0R: "78K0R",
  25. dvfparse.Dvf.MCU_RL78x1y: "RL78/S[13]",
  26. dvfparse.Dvf.MCU_RL78x2y: "RL78/S3",
  27. }
  28. def conv_per(dvf: dvfparse.Dvf) -> List[svd.SvdPeripheral]:
  29. r=[]
  30. base = 0xFFF00 & ((1<<WIDTHS[dvf.mcutype])-1)
  31. r.append(svd.SvdPeripheral(
  32. name="SFR",
  33. description="Special Function Register space",
  34. baseAddress=base,
  35. registers=[
  36. # fields, properties, widths, etc etc etc are still to be reversed...
  37. svd.SvdRegister(
  38. name=r.name,
  39. addressOffset=(r.address|base)-base
  40. ) for r in dvf.sections[dvfparse.DvfSect.SN]
  41. ]
  42. ))
  43. if dvfparse.DvfSect.ES in dvf.sections: # 78K0 has none
  44. base = 0xF0000
  45. r.append(svd.SvdPeripheral(
  46. name="SFR2",
  47. description="Extended Special Function Register space",
  48. baseAddress=base,
  49. registers=[
  50. svd.SvdRegister(
  51. name=r.name,
  52. addressOffset=(r.address|base)-base
  53. ) for r in dvf.sections[dvfparse.DvfSect.ES]
  54. ]
  55. ))
  56. return r
  57. def conv(dvf: dvfparse.Dvf) -> svd.SvdDevice:
  58. md = dvf.sections[dvfparse.DvfSect.MD][0]
  59. return svd.SvdDevice(
  60. vendor="Renesas",
  61. vendorID="Renesas",
  62. name=dvf.chipname_disp,
  63. series=SERIES[dvf.mcutype],
  64. description=md.version + " " + md.timestamp,
  65. licenseText=dvf.copyright_notice,
  66. addressUnitBits=8,
  67. width=16,#WIDTHS[dvf.mcutype],
  68. cpu=svd.SvdCpu(
  69. name=CPUS[dvf.mcutype],
  70. endian='little',
  71. deviceNumInterrupts=len(dvf.sections[dvfparse.DvfSect.VN]),
  72. ),
  73. peripherals=conv_per(dvf),
  74. # TODO: MI to memory map somehow?
  75. )
  76. if __name__ == '__main__':
  77. parser = argparse.ArgumentParser(prog="dvf2h",
  78. description="Convert NEC/Renesas Device "+\
  79. "Files to CMSIS-SVD files")
  80. parser.add_argument('input', type=argparse.FileType('rb'))
  81. #parser.add_argument('output', type=argparse.FileType('w'))
  82. parser.add_argument('output', type=str, default=None)
  83. args = parser.parse_args()
  84. output = sys.stdout if args.output is None else open(args.output, 'w')
  85. try:
  86. dvffile = dvfparse.Dvf.parse(args.input.read())
  87. svdc = conv(dvffile)
  88. svdgen.generate(output, svdc)
  89. finally:
  90. if args.output is not None:
  91. output.close()