]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - sitara-dss-files/am335x-dss-files.git/blobdiff - am335x-ddr-analysis.dss
[DDR] Full decoding of SDRAM_CONFIG register
[sitara-dss-files/am335x-dss-files.git] / am335x-ddr-analysis.dss
index f24455973572d9b89f69cce2b5f834fe65bc9e54..48cf00adcc7284675547abca1424c96a67677421 100644 (file)
-/*\r
- * Copyright (c) 2006-2014, Texas Instruments Incorporated\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * *  Redistributions of source code must retain the above copyright\r
- *    notice, this list of conditions and the following disclaimer.\r
- *\r
- * *  Redistributions in binary form must reproduce the above copyright\r
- *    notice, this list of conditions and the following disclaimer in the\r
- *    documentation and/or other materials provided with the distribution.\r
- *\r
- * *  Neither the name of Texas Instruments Incorporated nor the names of\r
- *    its contributors may be used to endorse or promote products derived\r
- *    from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- */\r
-\r
-function d2h(d) {return ("00000000" + (d).toString(16)).slice(-8);}\r
-\r
-function printRegisterValue(ds, name, addr)\r
-{\r
-       value = debugSessionDAP.memory.readWord(0,addr,false);\r
-       value_string = d2h(value);\r
-       file.write(name + " = 0x" + value_string + "\n");\r
-       return value; // return the register value for interrogation\r
-}\r
-\r
-function interpret_cmd_phy_macro(value, index)\r
-{\r
-       WD1 = (value >> (21+index)) & 1;\r
-       WD0 = (value >> (10+index)) & 1;\r
-       WD = (WD1 << 1) | WD0;\r
-       if (WD == 0) return_string = "Pullup/Pulldown disabled\n";\r
-       if (WD == 1) return_string = "Weak pullup enabled\n";\r
-       if (WD == 2) return_string = "Weak pulldown enabled\n";\r
-       if (WD == 3) return_string = "Weak keeper enabled\n"; \r
-       return return_string;\r
-}\r
-\r
-function interpret_data_phy_macro(value, index)\r
-{\r
-       WD1 = (value >> (20+index)) & 1;\r
-       WD0 = (value >> (10+index)) & 1;\r
-       WD = (WD1 << 1) | WD0;\r
-       if (WD == 0) return_string = "Pullup/Pulldown disabled\n";\r
-       if (WD == 1) return_string = "Weak pullup enabled\n";\r
-       if (WD == 2) return_string = "Weak pulldown enabled\n";\r
-       if (WD == 3) return_string = "Weak keeper enabled\n"; \r
-       return return_string;\r
-}\r
-\r
-// Build a filename that includes date/time\r
-var today = new Date();\r
-var year4digit = today.getFullYear();\r
-var month2digit = ("0" + (today.getMonth()+1)).slice(-2);\r
-var day2digit = ("0" + today.getDate()).slice(-2);\r
-var hour2digit = ("0" + today.getHours()).slice(-2);\r
-var minutes2digit = ("0" + today.getMinutes()).slice(-2);\r
-var seconds2digit = ("0" + today.getSeconds()).slice(-2);\r
-var filename_date = '_' + year4digit + '-' + month2digit + '-' + day2digit + '_' + hour2digit + minutes2digit + seconds2digit; \r
-var userHomeFolder = System.getProperty("user.home");\r
-var filename = userHomeFolder + '/Desktop/' + 'am335x-ddr-analysis' + filename_date + '.txt';\r
-\r
-file = new java.io.FileWriter(filename);\r
-\r
-debugSessionDAP = ds.openSession("*","CS_DAP_DebugSS");\r
-debugSessionDAP.target.connect();\r
-\r
-var reg_val;\r
-\r
-// EMIF: SDRAM_CONFIG\r
-reg_val = printRegisterValue(debugSessionDAP, "EMIF: SDRAM_CONFIG", 0x4C000008);\r
-var is_ddr3=0;\r
-var is_ddr2=0;\r
-var is_lpddr=0;\r
-if ( (reg_val & 0xE0000000) == (0 << 29) ) {file.write("  * ERROR! Unsupported memory type (DDR1)\n");}\r
-if ( (reg_val & 0xE0000000) == (1 << 29) ) {is_lpddr=1;}\r
-if ( (reg_val & 0xE0000000) == (2 << 29) ) {is_ddr2=1;}\r
-if ( (reg_val & 0xE0000000) == (3 << 29) ) {is_ddr3=1;}\r
-if (is_ddr3 == 1) {\r
-       file.write("  * Bits 26:24 (reg_ddr_term) set for ");\r
-       if ( (reg_val & 0x07000000) == (0 << 24) ) {file.write("termination disabled (000b)\n");}\r
-       if ( (reg_val & 0x07000000) == (1 << 24) ) {file.write("RZQ/4 (001b)\n");}\r
-       if ( (reg_val & 0x07000000) == (2 << 24) ) {file.write("RZQ/2 (010b)\n");}\r
-       if ( (reg_val & 0x07000000) == (3 << 24) ) {file.write("RZQ/6 (011b)\n");}\r
-       if ( (reg_val & 0x07000000) == (4 << 24) ) {file.write("RZQ/12 (100b)\n");}\r
-       if ( (reg_val & 0x07000000) == (5 << 24) ) {file.write("RZQ/8  (101b)\n");}\r
-       if ( (reg_val & 0x07000000) == (6 << 24) ) {file.write("ERROR\n");}\r
-       if ( (reg_val & 0x07000000) == (7 << 24) ) {file.write("ERROR\n");}\r
-}\r
-if (is_ddr2 == 1) {\r
-       file.write("  * Bits 26:24 (reg_ddr_term) set for ");\r
-       if ( (reg_val & 0x07000000) == (0 << 24) ) {file.write("termination disabled (000b)\n");}\r
-       if ( (reg_val & 0x07000000) == (1 << 24) ) {file.write("75 Ohm (001b)\n");}\r
-       if ( (reg_val & 0x07000000) == (2 << 24) ) {file.write("150 Ohm (010b)\n");}\r
-       if ( (reg_val & 0x07000000) == (3 << 24) ) {file.write("50 Ohm (011b)\n");}\r
-       if ( (reg_val & 0x07000000) == (4 << 24) ) {file.write("ERROR\n");}\r
-       if ( (reg_val & 0x07000000) == (5 << 24) ) {file.write("ERROR\n");}\r
-       if ( (reg_val & 0x07000000) == (6 << 24) ) {file.write("ERROR\n");}\r
-       if ( (reg_val & 0x07000000) == (7 << 24) ) {file.write("ERROR\n");}\r
-}\r
-if (is_ddr3 == 1) {\r
-       file.write("  * Bits 19:18 (reg_sdram_drive) set for ");\r
-       if ( (reg_val & 0x000C0000) == (0 << 18) ) {file.write("RZQ/6 (00b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (1 << 18) ) {file.write("RZQ/7 (01b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (2 << 18) ) {file.write("ERROR (10b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (3 << 18) ) {file.write("ERROR (11b)\n");}\r
-}\r
-if (is_ddr2 == 1) {\r
-       file.write("  * Bits 19:18 (reg_sdram_drive) set for ");\r
-       if ( (reg_val & 0x000C0000) == (0 << 18) ) {file.write("normal drive (00b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (1 << 18) ) {file.write("weak drive (01b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (2 << 18) ) {file.write("ERROR (10b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (3 << 18) ) {file.write("ERROR (11b)\n");}\r
-}\r
-if (is_lpddr == 1) {\r
-       file.write("  * Bits 19:18 (reg_sdram_drive) set for ");\r
-       if ( (reg_val & 0x000C0000) == (0 << 18) ) {file.write("full strength (00b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (1 << 18) ) {file.write("half strength (01b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (2 << 18) ) {file.write("quarter strength (10b)\n");}\r
-       if ( (reg_val & 0x000C0000) == (3 << 18) ) {file.write("eighth strength (11b)\n");}\r
-}\r
-\r
-// EMIF: PWR_MGMT_CTRL\r
-reg_val = printRegisterValue(debugSessionDAP, "EMIF: PWR_MGMT_CTRL", 0x4C000038);\r
-if ( (reg_val & 0xF0) < 0x90 ) {\r
-       file.write(" * ERROR: Bits 7:4 (reg_sr_tim) are in violation of Maximum Self-Refresh Command Limit\n");\r
-       file.write(" * Please see the silicon errata for more details.\n");\r
-}\r
-\r
-// DDR PHY: DDR_PHY_CTRL_1\r
-reg_val = printRegisterValue(debugSessionDAP, "DDR PHY: DDR_PHY_CTRL_1", 0x4C0000E4);\r
-if ( (reg_val & 1<<20) == 0 ) {file.write("  * WARNING: reg_phy_enable_dynamic_pwrdn disabled.\n");}\r
-file.write("  * Bits 9:8 (reg_phy_rd_local_odt) configured as ");\r
-if ( (reg_val & 0x300) == (0 << 8) ) {file.write("no termination (00b)\n");}\r
-if ( (reg_val & 0x300) == (1 << 8) ) {file.write("no termination (01b)\n");}\r
-if ( (reg_val & 0x300) == (2 << 8) ) {file.write("full thevenin termination\n");}\r
-if ( (reg_val & 0x300) == (3 << 8) ) {file.write("half thevenin termination\n");}\r
-\r
-// Close (Main) DAP session and use M3 DAP to view Control Registers\r
-debugSessionDAP.target.disconnect();\r
-debugSessionDAP = ds.openSession("*","CS_DAP_M3");\r
-debugSessionDAP.target.connect();\r
-\r
-// CONTROL: DDR_CMD0_IOCTRL\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD0_IOCTRL", 0x44E11404);\r
-file.write("  * ddr_ba2 " + interpret_cmd_phy_macro(reg_val, 0));\r
-file.write("  * ddr_wen " + interpret_cmd_phy_macro(reg_val, 1));\r
-file.write("  * ddr_ba0 " + interpret_cmd_phy_macro(reg_val, 2));\r
-file.write("  * ddr_a5 " + interpret_cmd_phy_macro(reg_val, 3));\r
-file.write("  * ddr_ck " + interpret_cmd_phy_macro(reg_val, 4));\r
-file.write("  * ddr_ckn " + interpret_cmd_phy_macro(reg_val, 5));\r
-file.write("  * ddr_a3 " + interpret_cmd_phy_macro(reg_val, 6));\r
-file.write("  * ddr_a4 " + interpret_cmd_phy_macro(reg_val, 7));\r
-file.write("  * ddr_a8 " + interpret_cmd_phy_macro(reg_val, 8));\r
-file.write("  * ddr_a9 " + interpret_cmd_phy_macro(reg_val, 9));\r
-file.write("  * ddr_a6 " + interpret_cmd_phy_macro(reg_val, 10));\r
-file.write("  * Bits 9:5 control ddr_ck and ddr_ckn\n");\r
-file.write("    - Slew ");\r
-if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}\r
-if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}\r
-if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}\r
-if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}\r
-var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;\r
-file.write("    - Drive Strength " + drive_strength_mA + " mA\n");\r
-file.write("  * Bits 4:0 control ddr_ba0, ddr_ba2, ddr_wen, ddr_a[9:8], ddr_a[6:3]\n");\r
-file.write("    - Slew ");\r
-if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}\r
-if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}\r
-if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}\r
-if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}\r
-var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;\r
-file.write("    - Drive Strength " + drive_strength_mA + " mA\n");\r
-\r
-// CONTROL: DDR_CMD1_IOCTRL\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD1_IOCTRL", 0x44E11408);\r
-file.write("  * ddr_a15 " + interpret_cmd_phy_macro(reg_val, 1));\r
-file.write("  * ddr_a2 " + interpret_cmd_phy_macro(reg_val, 2));\r
-file.write("  * ddr_a12 " + interpret_cmd_phy_macro(reg_val, 3));\r
-file.write("  * ddr_a7 " + interpret_cmd_phy_macro(reg_val, 4));\r
-file.write("  * ddr_ba1 " + interpret_cmd_phy_macro(reg_val, 5));\r
-file.write("  * ddr_a10 " + interpret_cmd_phy_macro(reg_val, 6));\r
-file.write("  * ddr_a0 " + interpret_cmd_phy_macro(reg_val, 7));\r
-file.write("  * ddr_a11 " + interpret_cmd_phy_macro(reg_val, 8));\r
-file.write("  * ddr_casn " + interpret_cmd_phy_macro(reg_val, 9));\r
-file.write("  * ddr_rasn " + interpret_cmd_phy_macro(reg_val, 10));\r
-file.write("  * Bits 4:0 control ddr_15, ddr_a[12:10], ddr_a7, ddr_a2, ddr_a0, ddr_ba1, ddr_casn, ddr_rasn\n");\r
-file.write("    - Slew ");\r
-if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}\r
-if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}\r
-if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}\r
-if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}\r
-var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;\r
-file.write("    - Drive Strength " + drive_strength_mA + " mA\n");\r
-\r
-// CONTROL: DDR_CMD2_IOCTRL\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD2_IOCTRL", 0x44E1140C);\r
-file.write("  * ddr_cke " + interpret_cmd_phy_macro(reg_val, 0));\r
-file.write("  * ddr_resetn " + interpret_cmd_phy_macro(reg_val, 1));\r
-file.write("  * ddr_odt " + interpret_cmd_phy_macro(reg_val, 2));\r
-file.write("  * ddr_a14 " + interpret_cmd_phy_macro(reg_val, 4));\r
-file.write("  * ddr_a13 " + interpret_cmd_phy_macro(reg_val, 5));\r
-file.write("  * ddr_csn0 " + interpret_cmd_phy_macro(reg_val, 6));\r
-file.write("  * ddr_a1 " + interpret_cmd_phy_macro(reg_val, 8));\r
-file.write("  * Bits 4:0 control ddr_cke, ddr_resetn, ddr_odt, ddr_csn0, ddr_[a14:13], ddr_a1\n");\r
-file.write("    - Slew ");\r
-if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}\r
-if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}\r
-if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}\r
-if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}\r
-var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;\r
-file.write("    - Drive Strength " + drive_strength_mA + " mA\n");\r
-\r
-// CONTROL: DDR_DATA0_IOCTRL\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_DATA0_IOCTRL", 0x44E11440);\r
-file.write("  * ddr_d8 " + interpret_data_phy_macro(reg_val, 0));\r
-file.write("  * ddr_d9 " + interpret_data_phy_macro(reg_val, 1));\r
-file.write("  * ddr_d10 " + interpret_data_phy_macro(reg_val, 2));\r
-file.write("  * ddr_d11 " + interpret_data_phy_macro(reg_val, 3));\r
-file.write("  * ddr_d12 " + interpret_data_phy_macro(reg_val, 4));\r
-file.write("  * ddr_d13 " + interpret_data_phy_macro(reg_val, 5));\r
-file.write("  * ddr_d14 " + interpret_data_phy_macro(reg_val, 6));\r
-file.write("  * ddr_d15 " + interpret_data_phy_macro(reg_val, 7));\r
-file.write("  * ddr_dqm1 " + interpret_data_phy_macro(reg_val, 8));\r
-file.write("  * ddr_dqs1 and ddr_dqsn1 " + interpret_data_phy_macro(reg_val, 9));\r
-file.write("  * Bits 9:5 control ddr_dqs1, ddr_dqsn1\n");\r
-file.write("    - Slew ");\r
-if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}\r
-if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}\r
-if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}\r
-if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}\r
-var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;\r
-file.write("    - Drive Strength " + drive_strength_mA + " mA\n");\r
-file.write("  * Bits 4:0 control ddr_d[15:8], ddr_dqm1\n");\r
-file.write("    - Slew ");\r
-if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}\r
-if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}\r
-if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}\r
-if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}\r
-var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;\r
-file.write("    - Drive Strength " + drive_strength_mA + " mA\n");\r
-\r
-// CONTROL: DDR_DATA1_IOCTRL\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_DATA1_IOCTRL", 0x44E11444);\r
-file.write("  * ddr_d0 " + interpret_data_phy_macro(reg_val, 0));\r
-file.write("  * ddr_d1 " + interpret_data_phy_macro(reg_val, 1));\r
-file.write("  * ddr_d2 " + interpret_data_phy_macro(reg_val, 2));\r
-file.write("  * ddr_d3 " + interpret_data_phy_macro(reg_val, 3));\r
-file.write("  * ddr_d4 " + interpret_data_phy_macro(reg_val, 4));\r
-file.write("  * ddr_d5 " + interpret_data_phy_macro(reg_val, 5));\r
-file.write("  * ddr_d6 " + interpret_data_phy_macro(reg_val, 6));\r
-file.write("  * ddr_d7 " + interpret_data_phy_macro(reg_val, 7));\r
-file.write("  * ddr_dqm0 " + interpret_data_phy_macro(reg_val, 8));\r
-file.write("  * ddr_dqs0 and ddr_dqsn0 " + interpret_data_phy_macro(reg_val, 9));\r
-file.write("  * Bits 9:5 control ddr_dqs0, ddr_dqsn0\n");\r
-file.write("    - Slew ");\r
-if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}\r
-if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}\r
-if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}\r
-if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}\r
-var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;\r
-file.write("    - Drive Strength " + drive_strength_mA + " mA\n");\r
-file.write("  * Bits 4:0 control ddr_d[7:0], dqm0\n");\r
-file.write("    - Slew ");\r
-if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}\r
-if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}\r
-if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}\r
-if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}\r
-var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;\r
-file.write("    - Drive Strength " + drive_strength_mA + " mA\n");\r
-\r
-// CONTROL: DDR_IO_CTRL\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_IO_CTRL", 0x44E10E04);\r
-if ( (reg_val & (1 << 31)) == (1<<31) ) {\r
-       file.write("  * Bit 31: Overriding DDR_RESETn (expected for DS0).\n");\r
-} else {\r
-       file.write("  * Bit 31: DDR_RESETn controlled by EMIF.\n");\r
-}\r
-if ( (reg_val & (1 << 28)) == 0) {\r
-       file.write("  * Bit 28 (mddr_sel) configured for SSTL, i.e. DDR2/DDR3/DDR3L operation.\n");\r
-       if (is_lpddr == 1) {file.write("ERROR!  Mismatch with SDRAM_CONFIG.\n");}\r
-}\r
-else {\r
-       file.write("  * Bit 28 (mddr_sel) configured for LVCMOS, i.e. LPDDR/mDDR operation.\n");\r
-       if (is_ddr2 == 1) {file.write("ERROR!  Mismatch with SDRAM_CONFIG.\n");}\r
-       if (is_ddr3 == 1) {file.write("ERROR!  Mismatch with SDRAM_CONFIG.\n");}\r
-}\r
-\r
-\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: VTP_CTRL", 0x44E10E0C);\r
-if ( reg_val == 0 ) {\r
-       file.write("  * VTP disabled (expected in DS0).\n");\r
-} else {\r
-       file.write("  * VTP not disabled (expected in normal operation, but not DS0).\n");\r
-}\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: VREF_CTRL", 0x44E10E14);\r
-reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CKE_CTRL", 0x44E1131C);\r
-\r
-file.close();\r
-print("Created file " + filename);\r
-debugSessionDAP.target.disconnect();\r
-\r
+/*
+ * Copyright (c) 2006-2014, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+function d2h(d) {return ("00000000" + (d).toString(16)).slice(-8);}
+
+// helper function to create decimal numbers in ascii format
+function d2d(d) {return ((+d).toString());}
+
+function printRegisterValue(ds, name, addr)
+{
+       value = debugSessionDAP.memory.readWord(0,addr,false);
+       value_string = d2h(value);
+       file.write(name + " = 0x" + value_string + "\n");
+       return value; // return the register value for interrogation
+}
+
+function getRegisterValue(debug, addr)
+{
+       return debug.memory.readWord(0,addr,false);
+}
+
+function interpret_cmd_phy_macro(value, index)
+{
+       WD1 = (value >> (21+index)) & 1;
+       WD0 = (value >> (10+index)) & 1;
+       WD = (WD1 << 1) | WD0;
+       if (WD == 0) return_string = "Pullup/Pulldown disabled\n";
+       if (WD == 1) return_string = "Weak pullup enabled\n";
+       if (WD == 2) return_string = "Weak pulldown enabled\n";
+       if (WD == 3) return_string = "Weak keeper enabled\n"; 
+       return return_string;
+}
+
+function interpret_data_phy_macro(value, index)
+{
+       WD1 = (value >> (20+index)) & 1;
+       WD0 = (value >> (10+index)) & 1;
+       WD = (WD1 << 1) | WD0;
+       if (WD == 0) return_string = "Pullup/Pulldown disabled\n";
+       if (WD == 1) return_string = "Weak pullup enabled\n";
+       if (WD == 2) return_string = "Weak pulldown enabled\n";
+       if (WD == 3) return_string = "Weak keeper enabled\n"; 
+       return return_string;
+}
+
+// Inputs:
+//   Data - 32-bit register value
+//   Upper - Highest bit to keep
+//   Lower - Lowest bit to keep
+//   (bit 0 refers to LSB, bit 31 to MSB)
+// Return: right aligned data
+function bits32(data, upper, lower)
+{
+       data = data >>> lower; // unsigned right-shift
+       upper = upper - lower;
+       bitmask =  0xFFFFFFFF >>> (31 - upper);
+       return (data & bitmask);
+}
+
+// Build a filename that includes date/time
+var today = new Date();
+var year4digit = today.getFullYear();
+var month2digit = ("0" + (today.getMonth()+1)).slice(-2);
+var day2digit = ("0" + today.getDate()).slice(-2);
+var hour2digit = ("0" + today.getHours()).slice(-2);
+var minutes2digit = ("0" + today.getMinutes()).slice(-2);
+var seconds2digit = ("0" + today.getSeconds()).slice(-2);
+var filename_date = '_' + year4digit + '-' + month2digit + '-' + day2digit + '_' + hour2digit + minutes2digit + seconds2digit; 
+var userHomeFolder = System.getProperty("user.home");
+var filename = userHomeFolder + '/Desktop/' + 'am335x-ddr-analysis' + filename_date + '.txt';
+
+debugSessionDAP = ds.openSession("*","CS_DAP_M3");
+use_dap_m3 = 1;
+
+try {
+       debugSessionDAP.target.connect();
+} catch (ex) {
+       print("\n ERROR: Could not connect to DAP_M3.\n");
+}
+
+// Do a test read of Device_ID register at 0x44e10600
+value = debugSessionDAP.memory.readWord(0,0x44e10600,false);
+
+// If it is zero, switch to CS_DAP_DebugSS
+if (value == 0)
+{
+       debugSessionDAP.target.disconnect();
+       debugSessionDAP = ds.openSession("*","CS_DAP_DebugSS");
+       debugSessionDAP.target.connect();
+       use_dap_m3 = 0;
+}
+
+var original_CM_WKUP_DEBUGSS_CLKCTRL = debugSessionDAP.memory.readWord(0,0x44e00414,false);
+var original_CM_PER_L3_CLKSTCTRL = debugSessionDAP.memory.readWord(0,0x44E0000C,false);
+var newline = "\n";
+
+file = new java.io.FileWriter(filename);
+
+// Only try to read EMIF registers if EMIF clock is enabled
+if (original_CM_PER_L3_CLKSTCTRL & 1<<2) {
+
+       // CM_WKUP_DEBUGSS_CLKCTRL[MODULEMODE] = ENABLED
+       debugSessionDAP.expression.evaluate(
+               "*((unsigned int*) 0x44e00414 ) |= 0x2;");
+
+       debugSessionDAP.target.disconnect();  // disconnect from DAP_M3
+       
+       // Connect to DAP_DebugSS for L3 visibility (EMIF regs)
+       debugSessionDAP = ds.openSession("*","CS_DAP_DebugSS");
+       debugSessionDAP.target.connect();
+       
+       var reg_val;
+
+       // CONTROL: device_id
+       reg_val = printRegisterValue(debugSessionDAP, "CONTROL: device_id", 0x44E10600);
+       if ( (reg_val & 0x0FFFFFFF) == 0xb94402e ) {file.write("  * AM335x family" + newline);}
+       if ( (reg_val & 0xF0000000) == (0 << 28) ) {file.write("  * Silicon Revision 1.0" + newline);}
+       if ( (reg_val & 0xF0000000) == (1 << 28) ) {file.write("  * Silicon Revision 2.0" + newline);}
+       if ( (reg_val & 0xF0000000) == (2 << 28) ) {file.write("  * Silicon Revision 2.1" + newline);}
+
+       // CONTROL: control_status
+       file.write(newline);
+       reg_val = printRegisterValue(debugSessionDAP, "CONTROL: control_status", 0x44E10040);
+       speedselect_pins = bits32(reg_val, 23, 22);
+       switch (speedselect_pins) {
+               case 0:
+                       file.write("  * SYSBOOT[15:14] = 00b (19.2 MHz)" + newline);
+                       input_clock = 19.2;
+                       break;
+               case 1:
+                       file.write("  * SYSBOOT[15:14] = 01b (24 MHz)" + newline);
+                       input_clock = 24;
+                       break;
+               case 2:
+                       file.write("  * SYSBOOT[15:14] = 10b (25 MHz)" + newline);
+                       input_clock = 25;
+                       break;
+               case 3:
+                       file.write("  * SYSBOOT[15:14] = 11b (26 MHz)" + newline);
+                       input_clock = 26;
+                       break;
+       }
+       
+       // CM_CLKSEL_DPLL_DDR
+       reg_val = printRegisterValue(debugSessionDAP, "CM_CLKSEL_DPLL_DDR", 0x44E00440);
+       dpll_mult = bits32(reg_val, 18, 8);
+       file.write("  * DPLL_MULT = " + d2d(dpll_mult) + " (x" + d2d(dpll_mult) + ")" + newline);
+       dpll_div = bits32(reg_val, 6, 0);
+       file.write("  * DPLL_DIV = " + d2d(dpll_div) + " (/" + d2d(dpll_div+1) + ")" + newline);
+       f_dpll_ddr = input_clock*2*dpll_mult/(dpll_div+1);
+
+       // CM_DIV_M2_DPLL_DDR
+       reg_val = printRegisterValue(debugSessionDAP, "CM_DIV_M2_DPLL_DDR", 0x44E004A0);
+       if (reg_val & (1<<9))  // CLKST = 1
+               file.write("  * CLKST = 1: M2 output clock enabled" + newline);
+       else
+               file.write("  * CLKST = 0: M2 output clock disabled" + newline);;
+       div_m2 = reg_val & 0x1F;
+       file.write("  * DIVHS = " + d2d(div_m2) + " (/" + d2d(div_m2) + ")" + newline);
+
+       file.write(newline + "DPLL_DDR Summary" + newline);
+       file.write(" -> F_input = " + d2d(input_clock) + " MHz" + newline);
+       file.write(" -> CLKOUT_M2 = DDR_PLL_CLKOUT = " + f_dpll_ddr / 2 / div_m2 + " MHz" + newline);
+
+       // EMIF: SDRAM_CONFIG
+       file.write(newline);
+       reg_val = printRegisterValue(debugSessionDAP, "EMIF: SDRAM_CONFIG", 0x4C000008);
+       reg_sdram_type = bits32(reg_val, 31, 29);
+       reg_ibank_pos = bits32(reg_val, 28, 27);
+       reg_ddr_term = bits32(reg_val, 26, 24);
+       reg_ddr2_ddqs = bits32(reg_val, 23, 23);
+       reg_dyn_odt = bits32(reg_val, 22, 21);
+       reg_ddr_disable_dll = bits32(reg_val, 20, 20);
+       reg_sdram_drive = bits32(reg_val, 19, 18);
+       reg_cwl = bits32(reg_val, 17, 16);
+       reg_narrow_mode = bits32(reg_val, 15, 14);
+       reg_cl = bits32(reg_val, 13, 10);
+       reg_rowsize = bits32(reg_val, 9, 7);
+       reg_ibank = bits32(reg_val, 6, 4);
+       reg_ebank = bits32(reg_val, 3, 3);
+       reg_pagesize = bits32(reg_val, 2, 0);
+
+       var is_ddr3=0;
+       var is_ddr2=0;
+       var is_lpddr=0;
+
+       switch (reg_sdram_type) {
+               case 0:
+                       file.write("  * ERROR! Unsupported memory type (DDR1)" + newline);
+                       break;
+               case 1:
+                       file.write("  * Bits 31:29 (reg_sdram_type) set for LPDDR" + newline);
+                       is_lpddr=1;
+                       break;
+               case 2:
+                       file.write("  * Bits 31:29 (reg_sdram_type) set for DDR2" + newline);
+                       is_ddr2=1;
+                       break;
+               case 3:
+                       file.write("  * Bits 31:29 (reg_sdram_type) set for DDR3" + newline);
+                       is_ddr3=1;
+                       break;
+               default:
+                       file.write("  * Bits 31:29 (reg_sdram_type) set to invalid selection!" + newline);
+       }
+       file.write("  * Bits 28:27 (reg_ibank_pos) set to " + d2d(reg_ibank_pos) + newline);
+       if (is_ddr3 == 1) {
+               file.write("  * Bits 26:24 (reg_ddr_term) set for ");
+               if ( reg_ddr_term == 0 ) {file.write("termination disabled (000b)\n");}
+               if ( reg_ddr_term == 1 ) {file.write("RZQ/4 (001b)\n");}
+               if ( reg_ddr_term == 2 ) {file.write("RZQ/2 (010b)\n");}
+               if ( reg_ddr_term == 3 ) {file.write("RZQ/6 (011b)\n");}
+               if ( reg_ddr_term == 4 ) {file.write("RZQ/12 (100b)\n");}
+               if ( reg_ddr_term == 5 ) {file.write("RZQ/8  (101b)\n");}
+               if ( reg_ddr_term == 6 ) {file.write("ERROR\n");}
+               if ( reg_ddr_term == 7 ) {file.write("ERROR\n");}
+       }
+       if (is_ddr2 == 1) {
+               file.write("  * Bits 26:24 (reg_ddr_term) set for ");
+               if ( reg_ddr_term == 0 ) {file.write("termination disabled (000b)\n");}
+               if ( reg_ddr_term == 1 ) {file.write("75 Ohm (001b)\n");}
+               if ( reg_ddr_term == 2 ) {file.write("150 Ohm (010b)\n");}
+               if ( reg_ddr_term == 3 ) {file.write("50 Ohm (011b)\n");}
+               if ( reg_ddr_term == 4 ) {file.write("ERROR\n");}
+               if ( reg_ddr_term == 5 ) {file.write("ERROR\n");}
+               if ( reg_ddr_term == 6 ) {file.write("ERROR\n");}
+               if ( reg_ddr_term == 7 ) {file.write("ERROR\n");}
+       }
+       if (is_ddr2 == 1) {
+               file.write("  * Bit  23    (reg_ddr2_ddqs) set to ");
+               if ( bits32(reg_val, 23, 23) == 0 ) {
+                       file.write("single ended DQS." + newline);
+               } else {
+                       file.write("differential DQS." + newline);
+               }
+       }
+       if (is_ddr3 == 1) {
+               file.write("  * Bits 22:21 (reg_dyn_odt) DDR3 dynamic ODT ");
+               if (reg_dyn_odt == 0)
+                       file.write("disabled" + newline);
+               else if (reg_dyn_odt == 1)
+                       file.write("set to RZQ / 4" + newline);
+               else if (reg_dyn_odt == 2)
+                       file.write("set to RZQ / 2" + newline);
+               else
+                       file.write("ERROR (illegal value)" + newline);
+               if (reg_ddr_disable_dll == 0)
+                       file.write("  * Bit  20    (reg_ddr_disable_dll) set to 0, DDR3 DLL enabled" + newline);
+               else
+                       file.write("  * Bit  20    (reg_ddr_disable_dll) set to 1, DDR3 DLL disabled" + newline);
+               file.write("  * Bits 19:18 (reg_sdram_drive) set for ");
+               if ( reg_sdram_drive == 0 ) {file.write("RZQ/6 (00b)\n");}
+               if ( reg_sdram_drive == 1 ) {file.write("RZQ/7 (01b)\n");}
+               if ( reg_sdram_drive == 2 ) {file.write("ERROR (10b)\n");}
+               if ( reg_sdram_drive == 3 ) {file.write("ERROR (11b)\n");}
+       }
+       if (is_lpddr == 1) {
+               file.write("  * Bits 19:18 (reg_sdram_drive) set for ");
+               if ( reg_sdram_drive == 0 ) {file.write("full strength (00b)\n");}
+               if ( reg_sdram_drive == 1 ) {file.write("half strength (01b)\n");}
+               if ( reg_sdram_drive == 2 ) {file.write("quarter strength (10b)\n");}
+               if ( reg_sdram_drive == 3 ) {file.write("eighth strength (11b)\n");}
+       }
+       if (is_ddr2 == 1) {
+               file.write("  * Bits 19:18 (reg_sdram_drive) set for ");
+               if ( reg_sdram_drive == 0 ) {file.write("normal drive (00b)\n");}
+               if ( reg_sdram_drive == 1 ) {file.write("weak drive (01b)\n");}
+               if ( reg_sdram_drive == 2 ) {file.write("ERROR (10b)\n");}
+               if ( reg_sdram_drive == 3 ) {file.write("ERROR (11b)\n");}
+       }
+       if (is_ddr3 == 1) {
+               file.write("  * Bits 17:16 (reg_cwl) set for " + d2d(reg_cwl) + ", CWL = " + d2d(reg_cwl+5) + newline);
+       }
+       if (reg_narrow_mode == 1)
+               file.write("  * Bits 15:14 (reg_narrow_mode) set to 1 -> 16-bit EMIF interface" + newline);
+       else
+               file.write("  * Bits 15:14 (reg_narrow_mode) set to ILLEGAL VALUE" + newline);
+       file.write("  * Bits 13:10 (reg_cl) set to " + d2d(reg_cl) + " -> CL = ");
+       decoded_CL = 0;
+       if (is_ddr2 == 1) {
+               switch (reg_cl) {
+                       case 2:
+                       case 3:
+                       case 4:
+                       case 5:
+                               decoded_CL = reg_cl;
+                               file.write(d2d(decoded_CL) + newline);
+                               break;
+                       default:
+                               file.write("ILLEGAL VALUE" + newline);
+                               break;
+               }
+       }
+       if (is_ddr3 == 1) {
+               switch (reg_cl) {
+                       case 2:
+                       case 4:
+                       case 6:
+                       case 8:
+                       case 10:
+                       case 12:
+                       case 14:
+                               decoded_CL = reg_cl/2 + 4;
+                               file.write(d2d(decoded_CL) + newline);
+                               break;
+                       default:
+                               file.write("ILLEGAL VALUE" + newline);
+                               break;
+               }
+       }
+       if (is_lpddr == 1) {
+               switch (reg_cl) {
+                       case 2:
+                       case 3:
+                               decoded_CL = reg_cl;
+                               file.write(d2d(decoded_CL) + newline);
+                               break;
+                       default:
+                               file.write("ILLEGAL VALUE" + newline);
+                               break;
+               }
+       }
+       file.write("  * Bits 09:07 (reg_rowsize) set to " + d2d(reg_rowsize) + " -> " + d2d(reg_rowsize+9) + " row bits" + newline);
+       file.write("  * Bits 06:04 (reg_ibank) set to " + d2d(reg_ibank) + " -> ");
+       switch (reg_ibank) {
+               case 0:
+               case 1:
+               case 2:
+               case 3:
+                       file.write(d2d(Math.pow(2,reg_ibank)) + " banks" + newline);
+                       break;
+               default:
+                       file.write("ILLEGAL VALUE" + newline);
+                       break;
+       }
+       if (reg_ebank == 1)
+               file.write("  * Bit  03    ERROR, only 1 chip select allowed!" + newline);
+       file.write("  * Bits 02:00 (reg_pagesize) set to " + d2d(reg_pagesize) + " -> ");
+       switch (reg_pagesize) {
+               case 0:
+               case 1:
+               case 2:
+               case 3:
+                       file.write(d2d(reg_pagesize+8) + " column bits" + newline);
+                       break;
+               default:
+                       file.write("ILLEGAL VALUE" + newline);
+                       break;
+       }
+
+       // EMIF: PWR_MGMT_CTRL
+       reg_val = printRegisterValue(debugSessionDAP, "EMIF: PWR_MGMT_CTRL", 0x4C000038);
+       if ( (reg_val & 0xF0) < 0x90 ) {
+               file.write(" * ERROR: Bits 7:4 (reg_sr_tim) are in violation of Maximum Self-Refresh Command Limit\n");
+               file.write(" * Please see the silicon errata for more details.\n");
+       }
+       
+       // DDR PHY: DDR_PHY_CTRL_1
+       reg_val = printRegisterValue(debugSessionDAP, "DDR PHY: DDR_PHY_CTRL_1", 0x4C0000E4);
+       if ( (reg_val & 1<<20) == 0 ) {file.write("  * WARNING: reg_phy_enable_dynamic_pwrdn disabled.\n");}
+       file.write("  * Bits 9:8 (reg_phy_rd_local_odt) configured as ");
+       if ( (reg_val & 0x300) == (0 << 8) ) {file.write("no termination (00b)\n");}
+       if ( (reg_val & 0x300) == (1 << 8) ) {file.write("no termination (01b)\n");}
+       if ( (reg_val & 0x300) == (2 << 8) ) {file.write("full thevenin termination\n");}
+       if ( (reg_val & 0x300) == (3 << 8) ) {file.write("half thevenin termination\n");}
+
+       file.write("\n");
+       file.write("*********************\n");
+       file.write("*** Register Dump ***\n")
+       file.write("*********************\n\n");
+
+       var ddr_config_regs = [
+               0x4C000000,
+               0x4C000004,
+               0x4C000008,
+               0x4C00000C,
+               0x4C000010,
+               0x4C000014,
+               0x4C000018,
+               0x4C00001C,
+               0x4C000020,
+               0x4C000024,
+               0x4C000028,
+               0x4C00002C,
+               0x4C000038,
+               0x4C00003C,
+               0x4C000054,
+               0x4C000058,
+               0x4C00005C,
+               0x4C000080,
+               0x4C000084,
+               0x4C000088,
+               0x4C00008C,
+               0x4C000090,
+               0x4C000098,
+               0x4C00009C,
+               0x4C0000A4,
+               0x4C0000AC,
+               0x4C0000B4,
+               0x4C0000BC,
+               0x4C0000C8,
+               0x4C0000D4,
+               0x4C0000D8,
+               0x4C0000DC,
+               0x4C0000E4,
+               0x4C0000E8,
+               0x4C000100,
+               0x4C000104,
+               0x4C000108,
+               0x4C000120];
+
+       for (i=0; i<ddr_config_regs.length; i++)
+       {
+               reg_val = getRegisterValue(debugSessionDAP, ddr_config_regs[i]);
+               file.write("*(0x" + d2h(ddr_config_regs[i]) + ")"); // Address
+               file.write(" = 0x" + d2h(reg_val) + "\n"); // Raw Reg Val
+       }
+
+       if ( use_dap_m3 == 1 ) {
+               // Close (Main) DAP session and use M3 DAP to view Control Registers
+               debugSessionDAP.target.disconnect();
+               debugSessionDAP = ds.openSession("*","CS_DAP_M3");
+               debugSessionDAP.target.connect();
+       }
+       
+       // Restore CM_WKUP_DEBUGSS_CLKCTRL[MODULEMODE]
+       if ( (original_CM_WKUP_DEBUGSS_CLKCTRL & 3) == 0 ) {
+               debugSessionDAP.memory.writeWord(0,0x44e00414,original_CM_WKUP_DEBUGSS_CLKCTRL);
+       }
+} else {
+       file.write("Skipping read of EMIF registers since EMIF clock disabled.\n");
+       file.write(" * EMIF registers are not readable when in DS0 state\n");
+       file.write(" * If you are attempting to enter DS0 this is normal.\n");
+}
+
+file.write("\n");
+file.write("************************\n");
+file.write("*** IOCTRL Registers ***\n")
+file.write("************************\n\n");
+
+// CONTROL: DDR_CMD0_IOCTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD0_IOCTRL", 0x44E11404);
+file.write("  * ddr_ba2 " + interpret_cmd_phy_macro(reg_val, 0));
+file.write("  * ddr_wen " + interpret_cmd_phy_macro(reg_val, 1));
+file.write("  * ddr_ba0 " + interpret_cmd_phy_macro(reg_val, 2));
+file.write("  * ddr_a5 " + interpret_cmd_phy_macro(reg_val, 3));
+file.write("  * ddr_ck " + interpret_cmd_phy_macro(reg_val, 4));
+file.write("  * ddr_ckn " + interpret_cmd_phy_macro(reg_val, 5));
+file.write("  * ddr_a3 " + interpret_cmd_phy_macro(reg_val, 6));
+file.write("  * ddr_a4 " + interpret_cmd_phy_macro(reg_val, 7));
+file.write("  * ddr_a8 " + interpret_cmd_phy_macro(reg_val, 8));
+file.write("  * ddr_a9 " + interpret_cmd_phy_macro(reg_val, 9));
+file.write("  * ddr_a6 " + interpret_cmd_phy_macro(reg_val, 10));
+file.write("  * Bits 9:5 control ddr_ck and ddr_ckn\n");
+file.write("    - Slew ");
+if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}
+if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}
+if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}
+if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}
+var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;
+file.write("    - Drive Strength " + drive_strength_mA + " mA\n");
+file.write("  * Bits 4:0 control ddr_ba0, ddr_ba2, ddr_wen, ddr_a[9:8], ddr_a[6:3]\n");
+file.write("    - Slew ");
+if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
+if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
+if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
+if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
+var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
+file.write("    - Drive Strength " + drive_strength_mA + " mA\n");
+
+// CONTROL: DDR_CMD1_IOCTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD1_IOCTRL", 0x44E11408);
+file.write("  * ddr_a15 " + interpret_cmd_phy_macro(reg_val, 1));
+file.write("  * ddr_a2 " + interpret_cmd_phy_macro(reg_val, 2));
+file.write("  * ddr_a12 " + interpret_cmd_phy_macro(reg_val, 3));
+file.write("  * ddr_a7 " + interpret_cmd_phy_macro(reg_val, 4));
+file.write("  * ddr_ba1 " + interpret_cmd_phy_macro(reg_val, 5));
+file.write("  * ddr_a10 " + interpret_cmd_phy_macro(reg_val, 6));
+file.write("  * ddr_a0 " + interpret_cmd_phy_macro(reg_val, 7));
+file.write("  * ddr_a11 " + interpret_cmd_phy_macro(reg_val, 8));
+file.write("  * ddr_casn " + interpret_cmd_phy_macro(reg_val, 9));
+file.write("  * ddr_rasn " + interpret_cmd_phy_macro(reg_val, 10));
+file.write("  * Bits 4:0 control ddr_15, ddr_a[12:10], ddr_a7, ddr_a2, ddr_a0, ddr_ba1, ddr_casn, ddr_rasn\n");
+file.write("    - Slew ");
+if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
+if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
+if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
+if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
+var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
+file.write("    - Drive Strength " + drive_strength_mA + " mA\n");
+
+// CONTROL: DDR_CMD2_IOCTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD2_IOCTRL", 0x44E1140C);
+file.write("  * ddr_cke " + interpret_cmd_phy_macro(reg_val, 0));
+file.write("  * ddr_resetn " + interpret_cmd_phy_macro(reg_val, 1));
+file.write("  * ddr_odt " + interpret_cmd_phy_macro(reg_val, 2));
+file.write("  * ddr_a14 " + interpret_cmd_phy_macro(reg_val, 4));
+file.write("  * ddr_a13 " + interpret_cmd_phy_macro(reg_val, 5));
+file.write("  * ddr_csn0 " + interpret_cmd_phy_macro(reg_val, 6));
+file.write("  * ddr_a1 " + interpret_cmd_phy_macro(reg_val, 8));
+file.write("  * Bits 4:0 control ddr_cke, ddr_resetn, ddr_odt, ddr_csn0, ddr_[a14:13], ddr_a1\n");
+file.write("    - Slew ");
+if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
+if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
+if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
+if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
+var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
+file.write("    - Drive Strength " + drive_strength_mA + " mA\n");
+
+// CONTROL: DDR_DATA0_IOCTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_DATA0_IOCTRL", 0x44E11440);
+file.write("  * ddr_d8 " + interpret_data_phy_macro(reg_val, 0));
+file.write("  * ddr_d9 " + interpret_data_phy_macro(reg_val, 1));
+file.write("  * ddr_d10 " + interpret_data_phy_macro(reg_val, 2));
+file.write("  * ddr_d11 " + interpret_data_phy_macro(reg_val, 3));
+file.write("  * ddr_d12 " + interpret_data_phy_macro(reg_val, 4));
+file.write("  * ddr_d13 " + interpret_data_phy_macro(reg_val, 5));
+file.write("  * ddr_d14 " + interpret_data_phy_macro(reg_val, 6));
+file.write("  * ddr_d15 " + interpret_data_phy_macro(reg_val, 7));
+file.write("  * ddr_dqm1 " + interpret_data_phy_macro(reg_val, 8));
+file.write("  * ddr_dqs1 and ddr_dqsn1 " + interpret_data_phy_macro(reg_val, 9));
+file.write("  * Bits 9:5 control ddr_dqs1, ddr_dqsn1\n");
+file.write("    - Slew ");
+if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}
+if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}
+if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}
+if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}
+var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;
+file.write("    - Drive Strength " + drive_strength_mA + " mA\n");
+file.write("  * Bits 4:0 control ddr_d[15:8], ddr_dqm1\n");
+file.write("    - Slew ");
+if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
+if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
+if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
+if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
+var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
+file.write("    - Drive Strength " + drive_strength_mA + " mA\n");
+
+// CONTROL: DDR_DATA1_IOCTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_DATA1_IOCTRL", 0x44E11444);
+file.write("  * ddr_d0 " + interpret_data_phy_macro(reg_val, 0));
+file.write("  * ddr_d1 " + interpret_data_phy_macro(reg_val, 1));
+file.write("  * ddr_d2 " + interpret_data_phy_macro(reg_val, 2));
+file.write("  * ddr_d3 " + interpret_data_phy_macro(reg_val, 3));
+file.write("  * ddr_d4 " + interpret_data_phy_macro(reg_val, 4));
+file.write("  * ddr_d5 " + interpret_data_phy_macro(reg_val, 5));
+file.write("  * ddr_d6 " + interpret_data_phy_macro(reg_val, 6));
+file.write("  * ddr_d7 " + interpret_data_phy_macro(reg_val, 7));
+file.write("  * ddr_dqm0 " + interpret_data_phy_macro(reg_val, 8));
+file.write("  * ddr_dqs0 and ddr_dqsn0 " + interpret_data_phy_macro(reg_val, 9));
+file.write("  * Bits 9:5 control ddr_dqs0, ddr_dqsn0\n");
+file.write("    - Slew ");
+if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}
+if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}
+if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}
+if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}
+var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;
+file.write("    - Drive Strength " + drive_strength_mA + " mA\n");
+file.write("  * Bits 4:0 control ddr_d[7:0], dqm0\n");
+file.write("    - Slew ");
+if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
+if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
+if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
+if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
+var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
+file.write("    - Drive Strength " + drive_strength_mA + " mA\n");
+
+// CONTROL: DDR_IO_CTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_IO_CTRL", 0x44E10E04);
+if ( (reg_val & (1 << 31)) == (1<<31) ) {
+       file.write("  * Bit 31: Overriding DDR_RESETn (expected for DS0).\n");
+} else {
+       file.write("  * Bit 31: DDR_RESETn controlled by EMIF.\n");
+}
+if ( (reg_val & (1 << 28)) == 0) {
+       file.write("  * Bit 28 (mddr_sel) configured for SSTL, i.e. DDR2/DDR3/DDR3L operation.\n");
+       if (is_lpddr == 1) {file.write("ERROR!  Mismatch with SDRAM_CONFIG.\n");}
+}
+else {
+       file.write("  * Bit 28 (mddr_sel) configured for LVCMOS, i.e. LPDDR/mDDR operation.\n");
+       if (is_ddr2 == 1) {file.write("ERROR!  Mismatch with SDRAM_CONFIG.\n");}
+       if (is_ddr3 == 1) {file.write("ERROR!  Mismatch with SDRAM_CONFIG.\n");}
+}
+
+// CONTROL: VTP_CTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: VTP_CTRL", 0x44E10E0C);
+if ( reg_val == 0 ) {
+       file.write("  * VTP disabled (expected in DS0).\n");
+} else {
+       file.write("  * VTP not disabled (expected in normal operation, but not DS0).\n");
+}
+
+// CONTROL: VREF_CTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: VREF_CTRL", 0x44E10E14);
+if ( (reg_val & 1) == 0 ) {
+       file.write("  * VREF supplied externally (typical).\n");
+} else {
+       file.write("  * Internal VREF (unusual).\n");
+}
+
+// CONTROL: DDR_CKE_CTRL
+reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CKE_CTRL", 0x44E1131C);
+if ( (reg_val & 1) == 0 ) {
+       file.write("  * CKE gated (forces pin low).\n");
+} else {
+       file.write("  * CKE controlled by EMIF (normal/ungated operation).\n");
+}
+
+file.close();
+print("Created file " + filename);
+debugSessionDAP.target.disconnect();
+
+
+
+//****************************************************************************
+// getErrorCode
+//****************************************************************************
+function getErrorCode(exception)
+{
+   var ex2 = exception.javaException;
+   if (ex2 instanceof Packages.com.ti.ccstudio.scripting.environment.ScriptingException)
+   {
+      return ex2.getErrorID();
+   }
+   return 0;
+}