xilinx-xadc.cfg 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. # SPDX-License-Identifier: GPL-2.0-or-later
  2. # Xilinx XADC support for 7 Series FPGAs
  3. #
  4. # The 7 Series FPGAs contain an on-chip 12 bit ADC that can probe die
  5. # temperature, internal power supply rail voltages as well as external
  6. # voltages. The XADC is available both from fabric as well as through the
  7. # JTAG TAP.
  8. #
  9. # This code implements access through the JTAG TAP.
  10. #
  11. # https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf
  12. # build a 32 bit DRP command for the XADC DR
  13. proc xadc_cmd {cmd addr data} {
  14. array set cmds {
  15. NOP 0x00
  16. READ 0x01
  17. WRITE 0x02
  18. }
  19. return [expr {($cmds($cmd) << 26) | ($addr << 16) | ($data << 0)}]
  20. }
  21. # XADC register addresses
  22. # Some addresses (status registers 0-3) have special function when written to.
  23. proc XADC {key} {
  24. array set addrs {
  25. TEMP 0x00
  26. LOCK 0x00
  27. VCCINT 0x01
  28. VCCAUX 0x02
  29. VAUXEN 0x02
  30. VPVN 0x03
  31. RESET 0x03
  32. VREFP 0x04
  33. VREFN 0x05
  34. VCCBRAM 0x06
  35. SUPAOFFS 0x08
  36. ADCAOFFS 0x09
  37. ADCAGAIN 0x0a
  38. VCCPINT 0x0d
  39. VCCPAUX 0x0e
  40. VCCODDR 0x0f
  41. VAUX0 0x10
  42. VAUX1 0x11
  43. VAUX2 0x12
  44. VAUX3 0x13
  45. VAUX4 0x14
  46. VAUX5 0x15
  47. VAUX6 0x16
  48. VAUX7 0x17
  49. VAUX8 0x18
  50. VAUX9 0x19
  51. VAUX10 0x1a
  52. VAUX11 0x1b
  53. VAUX12 0x1c
  54. VAUX13 0x1d
  55. VAUX14 0x1e
  56. VAUX15 0x1f
  57. SUPBOFFS 0x30
  58. ADCBOFFS 0x31
  59. ADCBGAIN 0x32
  60. FLAG 0x3f
  61. CFG0 0x40
  62. CFG1 0x41
  63. CFG2 0x42
  64. SEQ0 0x48
  65. SEQ1 0x49
  66. SEQ2 0x4a
  67. SEQ3 0x4b
  68. SEQ4 0x4c
  69. SEQ5 0x4d
  70. SEQ6 0x4e
  71. SEQ7 0x4f
  72. ALARM0 0x50
  73. ALARM1 0x51
  74. ALARM2 0x52
  75. ALARM3 0x53
  76. ALARM4 0x54
  77. ALARM5 0x55
  78. ALARM6 0x56
  79. ALARM7 0x57
  80. ALARM8 0x58
  81. ALARM9 0x59
  82. ALARM10 0x5a
  83. ALARM11 0x5b
  84. ALARM12 0x5c
  85. ALARM13 0x5d
  86. ALARM14 0x5e
  87. ALARM15 0x5f
  88. }
  89. return $addrs($key)
  90. }
  91. # Select the XADC DR
  92. proc xadc_select {tap} {
  93. set XADC_IR 0x37
  94. irscan $tap $XADC_IR
  95. runtest 10
  96. }
  97. # XADC transfer
  98. proc xadc_xfer {tap cmd addr data} {
  99. set ret [drscan $tap 32 [xadc_cmd $cmd $addr $data]]
  100. runtest 10
  101. return [expr "0x$ret"]
  102. }
  103. # XADC register write
  104. proc xadc_write {tap addr data} {
  105. xadc_xfer $tap WRITE $addr $data
  106. }
  107. # XADC register read, non-pipelined
  108. proc xadc_read {tap addr} {
  109. xadc_xfer $tap READ $addr 0
  110. return [xadc_xfer $tap NOP 0 0]
  111. }
  112. # convert 16 bit register code from ADC measurement on
  113. # external voltages (VAUX) to Volt
  114. proc xadc_volt {code} {
  115. return [expr {$code * 1./(1 << 16)}]
  116. }
  117. # convert 16 bit temperature measurement to Celsius
  118. proc xadc_temp {code} {
  119. return [expr {$code * 503.975/(1 << 16) - 273.15}]
  120. }
  121. # convert 16 bit suppply voltage measurement to Volt
  122. proc xadc_sup {code} {
  123. return [expr {$code * 3./(1 << 16)}]
  124. }
  125. # perform a single channel measurement using default settings
  126. proc xadc_single {tap ch} {
  127. set cfg0 [xadc_read $tap [XADC CFG0]]
  128. set cfg1 [xadc_read $tap [XADC CFG1]]
  129. # set channel
  130. xadc_write $tap [XADC CFG0] $cfg0
  131. # single channel, disable the sequencer
  132. xadc_write $tap [XADC CFG1] 0x3000
  133. # leave some time for the conversion
  134. runtest 100
  135. set ret [xadc_read $tap [XADC $ch]]
  136. # restore CFG0/1
  137. xadc_write $tap [XADC CFG0] $cfg0
  138. xadc_write $tap [XADC CFG1] $cfg1
  139. return $ret
  140. }
  141. # measure all internal voltages
  142. proc xadc_report {tap} {
  143. xadc_select $tap
  144. echo "TEMP [format %.2f [xadc_temp [xadc_single $tap TEMP]]] C"
  145. foreach ch [list VCCINT VCCAUX VCCBRAM VPVN VREFP VREFN \
  146. VCCPINT VCCPAUX VCCODDR] {
  147. echo "$ch [format %.3f [xadc_sup [xadc_single $tap $ch]]] V"
  148. }
  149. }