Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SWD mbed USBLocalFileSystem BaseDAP USBDAP
Diff: Target2.cpp
- Revision:
- 0:27d35fa263b5
- Child:
- 1:eb30547ba84d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Target2.cpp Sun Sep 01 08:25:28 2013 +0000
@@ -0,0 +1,231 @@
+// Target2.cpp 2013/9/1
+#include "Target2.h"
+#include "mydebug.h"
+
+#define DHCSR 0xe000edf0
+#define DCRSR (DHCSR+4)
+#define DCRDR (DHCSR+8)
+
+Target2::Target2(PinName swdio, PinName swclk, PinName reset, Serial* usbpc)
+ : _swd(swdio, swclk, reset), _pc(usbpc)
+{
+ r0.setup(this, 0);
+ r1.setup(this, 1);
+ r2.setup(this, 2);
+ r3.setup(this, 3);
+ r4.setup(this, 4);
+ r5.setup(this, 5);
+ r6.setup(this, 6);
+ r7.setup(this, 7);
+ r8.setup(this, 8);
+ r9.setup(this, 9);
+ r10.setup(this, 10);
+ r11.setup(this, 11);
+ r12.setup(this, 12);
+ sp.setup(this, 13);
+ lr.setup(this, 14);
+ pc.setup(this, 15);
+ xpsr.setup(this, 16);
+}
+
+bool Target2::setup()
+{
+ _swd.Setup();
+ _swd.JTAG2SWD();
+
+ uint32_t data;
+ uint8_t ack = _swd.Transfer(DP_IDCODE, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+ TEST_ASSERT(data == 0x0bb11477);
+
+ Abort();
+
+ data = 0x0;
+ ack = _swd.Transfer(DP_SELECT, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+
+ ack = _swd.Transfer(DP_RDBUFF, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+
+ data = CSYSPWRUPREQ | CDBGPWRUPREQ;
+ TEST_ASSERT(data == 0x50000000);
+ ack = _swd.Transfer(DP_CTRL_STAT, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+
+ ack = _swd.Transfer(DP_RDBUFF, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+
+ ack = _swd.Transfer(DP_CTRL_STAT_R, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+ TEST_ASSERT(data == 0xf0000040);
+
+ data = CSYSPWRUPREQ | CDBGPWRUPREQ | 0x04000000;
+ TEST_ASSERT(data == 0x54000000);
+ ack = _swd.Transfer(DP_CTRL_STAT, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+
+ ack = _swd.Transfer(DP_RDBUFF, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+
+ data = CSYSPWRUPREQ | CDBGPWRUPREQ | MASKLANE;
+ TEST_ASSERT(data == 0x50000f00);
+ ack = _swd.Transfer(DP_CTRL_STAT, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+
+ ack = _swd.Transfer(DP_RDBUFF, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ if (ack != SWD_OK) {
+ return false;
+ }
+ return true;
+}
+
+void Target2::Reset()
+{
+ _swd.reset();
+}
+
+uint32_t Target2::readMemory(uint32_t addr)
+{
+ _setaddr(addr);
+
+ uint32_t data;
+ uint8_t ack = _swd.Transfer(AP_DRW_R, &data); // dummy read
+ TEST_ASSERT(ack == SWD_OK);
+
+ ack = _swd.Transfer(DP_RDBUFF, &data);
+ TEST_ASSERT(ack == SWD_OK);
+ return data;
+}
+
+void Target2::readMemory(uint32_t addr, uint32_t* data, int count)
+{
+ if (count == 0) {
+ return;
+ }
+
+ _setaddr(addr);
+
+ uint8_t ack = _swd.Transfer(AP_DRW_R, NULL); // dummy read
+ TEST_ASSERT(ack == SWD_OK);
+
+ for(int i = 0; i < count-1; i++) {
+ ack = _swd.Transfer(AP_DRW_R, data++);
+ TEST_ASSERT(ack == SWD_OK);
+ }
+ ack = _swd.Transfer(DP_RDBUFF, data);
+ TEST_ASSERT(ack == SWD_OK);
+}
+
+void Target2::writeMemory(uint32_t addr, uint32_t data)
+{
+ writeMemory(addr, &data, 1);
+}
+
+void Target2::writeMemory(uint32_t addr, uint32_t* data, int count)
+{
+ _setaddr(addr);
+
+ while(count-- > 0) {
+ uint8_t ack = _swd.Transfer(AP_DRW_W, data);
+ TEST_ASSERT(ack == SWD_OK);
+ data++;
+ }
+}
+
+void Target2::_setaddr(uint32_t addr)
+{
+ uint32_t ctl = CSW_VALUE|CSW_SIZE32;
+ TEST_ASSERT(ctl == 0x23000052);
+ uint8_t ack = _swd.Transfer(AP_CSW, &ctl);
+ TEST_ASSERT(ack == SWD_OK);
+
+ ack = _swd.Transfer(DP_RDBUFF, NULL);
+ TEST_ASSERT(ack == SWD_OK);
+
+ ack = _swd.Transfer(AP_TAR, &addr);
+ TEST_ASSERT(ack == SWD_OK);
+
+ ack = _swd.Transfer(DP_RDBUFF, NULL);
+ TEST_ASSERT(ack == SWD_OK);
+}
+
+void Target2::Abort()
+{
+ uint32_t data = 0x1e;
+ uint8_t ack = _swd.Transfer(DP_ABORT, &data);
+ TEST_ASSERT(ack == SWD_OK);
+}
+
+int Target2::getStatus()
+{
+ return readMemory(DHCSR) & 6 ? TARGET_HALTED : TARGET_RUNNING;
+}
+
+bool Target2::wait_status(int status, int timeout_ms)
+{
+ Timer t;
+ t.reset();
+ t.start();
+ while(t.read_ms() < timeout_ms) {
+ if (getStatus() == status) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Target2::halt()
+{
+ writeMemory(DHCSR, 0xa05f0003);
+}
+
+void Target2::resume()
+{
+ writeMemory(DHCSR, 0xa05f0001);
+}
+
+uint32_t CoreReg::read()
+{
+ _target->writeMemory(DCRSR, _reg);
+ return _target->readMemory(DCRDR);
+}
+
+void CoreReg::write(uint32_t value)
+{
+ _target->writeMemory(DCRDR, value);
+ _target->writeMemory(DCRSR, _reg|0x10000);
+}
+
+void CoreReg::setup(Target2* target, uint8_t reg)
+{
+ _target = target;
+ _reg = reg;
+}