void configureJTAGforCortexR4withICEPICKinScanchain(void) { JLINK_CORESIGHT_Configure("IRPre=0;DRPre=0;IRPost=6;DRPost=1;IRLenDevice=4;PerformTIFInit=0"); } void configureJTAGforICEPICKwithCortexR4inScanchain(void) { JLINK_CORESIGHT_Configure("IRPre=4;DRPre=1;IRPost=0;DRPost=0;IRLenDevice=6;PerformTIFInit=0"); } void configureJTAGonlyForICEPICK_C(void) { JLINK_CORESIGHT_Configure("IRPre=0;DRPre=0;IRPost=0;DRPost=0;IRLenDevice=6;PerformTIFInit=0"); } int getIDCODEofICEPICK_C(void) { int v; int BitPos; JTAG_WriteIR(4); // ICEPICK IDCODE instruction BitPos = JTAG_WriteDR(0x00000000, 32); v = JTAG_GetU32(BitPos); return v; } int getIDCODEfromJTAG_DP_Coresight(void) { int v; int BitPos; JTAG_WriteIR(0xE); // Read JTAG-DP IDCODE register BitPos = JTAG_WriteDR(0x00000000, 32); // Get ID v = JTAG_GetU32(BitPos); return v; } void addCortexR4toScanchain(void) { int v; JTAG_WriteIR(7); // ICEPICK CONNECT instruction JTAG_WriteDR(0x89, 8); // The ICEPick documentation (SPRUE64, 2.6 CONNECT instruction: Accessing the debug connect register). Bit 7 set means: Write debug connect register. We write 0x9 to the debug connect register which is the debug connect key. JTAG_WriteIR(2); // ICEPICK ROUTER instruction (Accessing the mapped registers) v = (1 << 31) // Write mapped register | (0x20 << 24) // SDTAP0 register | (1 << 13) // Debug connect | (1 << 8) // TAP select | (1 << 3); // Force active JTAG_WriteDR(v, 32); // Write register 0x20 (SDTAP0), value 0x002108 JTAG_WriteIR(0x3F); // ICEPICK Bypass instruction JTAG_WriteClocks(10); configureJTAGforCortexR4withICEPICKinScanchain(); } // Perform reset via ICEPick system control register, by setting the SysReset bit void doResetUsingICEPICK(void) { int v; int BitPos; JTAG_WriteIR(2); // Cmd: ROUTER v = 0x01000000; // Read SYS_CNTL JTAG_WriteDR(v, 32); BitPos = JTAG_WriteDR(v, 32); v = JTAG_GetU32(BitPos); v &= 0x00FFFFFF; v |= 0x81000001; // Write SYS_CNTL and set SysReset bit JTAG_WriteDR(v, 32); v &= 0xFFFFFFFE; v &= 0x00FFFFFF; v |= 0x81000000; // Write SYS_CNTL and clear SysReset bit JTAG_WriteDR(v, 32); } void prepareToUseDBGVCR(void) { int v; int base; JLINK_CORESIGHT_WriteDP(2, (1 << 24) | (0 << 4)); // Select AP[1], bank 0 base = 0x80001000; v = (2 << 0) // AP-access size. Fixed to 2: 32-bit | (1 << 4) // Auto increment TAR after read/write access. Increment is NOT performed on access to banked data registers 0-3. | (1 << 31); // Enable software access to the Debug APB bus. JLINK_CORESIGHT_WriteAP(0, v); JLINK_CORESIGHT_WriteAP(1, base + 0x1C); // требуемый адрес для следующей записи (DBGVCR) } void setResetCatch(void) { prepareToUseDBGVCR(); JLINK_CORESIGHT_WriteAP(3, 1); } void clearAnyCatch(void) { prepareToUseDBGVCR(); JLINK_CORESIGHT_WriteAP(3, 0); } void printAPBregister(int address) { int v; JLINK_CORESIGHT_WriteDP(2, (1 << 24) | (0x0 << 4)); // Select AP[1], bank 0 v = (2 << 0) // AP-access size. Fixed to 2: 32-bit | (1 << 4) // Auto increment TAR after read/write access. Increment is NOT performed on access to banked data registers 0-3. | (1 << 31); // Enable software access to the Debug APB bus. JLINK_CORESIGHT_WriteAP(0, v); JLINK_CORESIGHT_WriteAP(1, address); v = JLINK_CORESIGHT_ReadAP(3); MessageBox1("Register=", v); } /********************************************************************* * * _ResetViaIcePick * * Function description * Reset CPU core via Ice Pick. * This function can be used if the reset pin of the CPU is * not connected to the reset pin of the JTAG connector */ void _ResetViaIcePick(void) { int Speed; Speed = JTAG_Speed; JTAG_Speed = 100; // Use 100 kHz JTAG speed setResetCatch(); configureJTAGforICEPICKwithCortexR4inScanchain(); doResetUsingICEPICK(); configureJTAGforCortexR4withICEPICKinScanchain(); clearAnyCatch(); JTAG_Speed = Speed; } int isRM48L950revA(unsigned int code) {return code == 0x0B8A002F;} int isRM48L950revB(unsigned int code) {return code == 0x2B8A002F;} int isRM48L950revC(unsigned int code) {return code == 0x3B8A002F;} int isRM48L950revD(unsigned int code) {return code == 0x4B8A002F;} int isRM46L852revA(unsigned int code) {return code == 0x0B95502F;} int isRM46L852revB(unsigned int code) {return code == 0x2B95502F;} int isRM46L852revC(unsigned int code) {return code == 0x3B95502F;} int isCorrectIDCODEofHerculesMCU(unsigned int code) { if (isRM48L950revA(code)) { return 1; } else if (isRM48L950revB(code)) { return 1; } else if (isRM48L950revC(code)) { return 1; } else if (isRM48L950revD(code)) { return 1; } else if (isRM46L852revB(code)) { return 1; } else if (isRM46L852revC(code)) { return 1; } else { MessageBox1("Can not find ICE-Pick rev.C (IDCODE mismatch). Found: ", code); return 0; } } void _InitIcePick(void) { unsigned int Speed; unsigned int ID_ICEPICK; unsigned int ID_TAP_CR4F; Speed = JTAG_Speed; JTAG_Speed = 50; // Use 50 kHz JTAG speed for ICEPick initialization configureJTAGonlyForICEPICK_C(); ID_ICEPICK = getIDCODEofICEPICK_C(); if (isCorrectIDCODEofHerculesMCU(ID_ICEPICK)) { addCortexR4toScanchain(); CPU = CORTEX_R4; JTAG_AllowTAPReset = 0; // =0: enable autodetection of JTAG devices in chain ID_TAP_CR4F = getIDCODEfromJTAG_DP_Coresight(); if ((ID_TAP_CR4F & 0x00000FFF) != 0x00000477) { // ARM JEDEC ID MessageBox1("Can not find JTAG-DP (IDCODE mismatch), found:", ID_TAP_CR4F); } else { JTAG_SetDeviceId(0, ID_TAP_CR4F); // Cortex-R4 core is device [0] JTAG_SetDeviceId(1, ID_ICEPICK); // ICEPick is device [1] } } JTAG_Speed = Speed; // Restore original JTAG speed } void ResetTarget(void) { _ResetViaIcePick(); } void InitTarget(void) { JTAG_TRSTPin = 0; // Reset debug logic in order to make sure that ONLY the ICEPick is in the JTAG chain SYS_Sleep(50); JTAG_TRSTPin = 1; SYS_Sleep(50); JTAG_Write(0x1F, 0, 6); _InitIcePick(); CORESIGHT_IndexAHBAPToUse = 0; }