pxt-microbit
Version:
micro:bit target for Microsoft MakeCode (PXT)
1,196 lines (1,170 loc) • 188 kB
JavaScript
var DapJS =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 4);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var _this = this;
Object.defineProperty(exports, "__esModule", { value: true });
exports.readUInt32LE = function (b, idx) {
return (b[idx] |
(b[idx + 1] << 8) |
(b[idx + 2] << 16) |
(b[idx + 3] << 24)) >>> 0;
};
exports.bufferConcat = function (bufs) {
var len = 0;
for (var _i = 0, bufs_1 = bufs; _i < bufs_1.length; _i++) {
var b = bufs_1[_i];
len += b.length;
}
var r = new Uint8Array(len);
len = 0;
for (var _a = 0, bufs_2 = bufs; _a < bufs_2.length; _a++) {
var b = bufs_2[_a];
r.set(b, len);
len += b.length;
}
return r;
};
exports.delay = function (t) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, new Promise(function (resolve) {
setTimeout(resolve, t);
})];
});
}); };
exports.addInt32 = function (arr, val) {
if (!arr) {
arr = [];
}
arr.push(val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff, (val >> 24) & 0xff);
return arr;
};
exports.hex = function (v) {
return "0x" + v.toString(16);
};
exports.rid = function (v) {
var m = [
"DP_0x0",
"DP_0x4",
"DP_0x8",
"DP_0xC",
"AP_0x0",
"AP_0x4",
"AP_0x8",
"AP_0xC",
];
return m[v] || "?";
};
exports.bank = function (addr) {
var APBANKSEL = 0x000000f0;
return (addr & APBANKSEL) | (addr & 0xff000000);
};
exports.apReg = function (r, mode) {
var v = r | mode | 1 /* AP_ACC */;
return (4 + ((v & 0x0c) >> 2));
};
exports.bufToUint32Array = function (buf) {
exports.assert((buf.length & 3) === 0);
var r = [];
if (!buf.length) {
return r;
}
r[buf.length / 4 - 1] = 0;
for (var i = 0; i < r.length; ++i) {
r[i] = exports.readUInt32LE(buf, i << 2);
}
return r;
};
exports.assert = function (cond) {
if (!cond) {
throw new Error("assertion failed");
}
};
exports.regRequest = function (regId, isWrite) {
if (isWrite === void 0) { isWrite = false; }
var request = !isWrite ? 2 /* READ */ : 0 /* WRITE */;
if (regId < 4) {
request |= 0 /* DP_ACC */;
}
else {
request |= 1 /* AP_ACC */;
}
request |= (regId & 3) << 2;
return request;
};
exports.hexBytes = function (bytes) {
var chk = 0;
var r = ":";
bytes.forEach(function (b) { return chk += b; });
bytes.push((-chk) & 0xff);
bytes.forEach(function (b) { return r += ("0" + b.toString(16)).slice(-2); });
return r.toUpperCase();
};
exports.hex2bin = function (hexstr) {
var array = new Uint8Array(hexstr.length / 2);
for (var i = 0; i < hexstr.length / 2; i++) {
array[i] = parseInt(hexstr.substr(2 * i, 2), 16);
}
return array;
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* # Prepared Memory Command
*
* Allows multiple memory operations to be batched together to improve HID
* interface utilisation.
*
* ## Usage
*
* Similarly to `CortexMPreparedCommand` and `DapPreparedCommand`, a convenience
* function exists to quickly create a prepared memory command:
*
* ```typescript
* const prep = core.memory.prepareCommand();
* ```
*
* You can then construct the sequence of commands using the same API as `Memory`.
*
* ```typescript
* prep.write32(0x20000, 1234);
* prep.write32(0x12344, 5678);
* prep.write16(0x12346, 123);
* ```
*
* And then dispatch the prepared commands asynchronously:
*
* ```typescript
* await prep.go();
* ```
*/
var PreparedMemoryCommand = (function () {
function PreparedMemoryCommand(dap) {
this.cmd = dap.prepareCommand();
}
/**
* Schedule a 32-bit memory write operation.
*
* @param addr Word-aligned memory address to write to.
* @param data Number to be written.
*/
PreparedMemoryCommand.prototype.write32 = function (addr, data) {
this.cmd.writeAp(0 /* CSW */, 587202640 /* CSW_VALUE */ | 2 /* CSW_SIZE32 */);
this.cmd.writeAp(4 /* TAR */, addr);
this.cmd.writeAp(12 /* DRW */, data);
};
/**
* Schedule a 16-bit memory write operation.
*
* @param addr Half word-aligned memory address to write to.
* @param data Number to be written.
*/
PreparedMemoryCommand.prototype.write16 = function (addr, data) {
data = data << ((addr & 0x02) << 3);
this.cmd.writeAp(0 /* CSW */, 587202640 /* CSW_VALUE */ | 1 /* CSW_SIZE16 */);
this.cmd.writeAp(4 /* TAR */, addr);
this.cmd.writeAp(12 /* DRW */, data);
};
/**
* Schedule a 32-bit memory read operation.
*
* @param addr Word-aligned memory address to read from.
*/
PreparedMemoryCommand.prototype.read32 = function (addr) {
this.cmd.writeAp(0 /* CSW */, 587202640 /* CSW_VALUE */ | 2 /* CSW_SIZE32 */);
this.cmd.writeAp(4 /* TAR */, addr);
this.cmd.readAp(12 /* DRW */);
};
/**
* Schedule a 16-bit memory read operation.
*
* FIXME: the values need to be shifted after being read.
*
* @param addr Half word-aligned memory address to read from.
*/
PreparedMemoryCommand.prototype.read16 = function (addr) {
this.cmd.writeAp(0 /* CSW */, 587202640 /* CSW_VALUE */ | 1 /* CSW_SIZE16 */);
this.cmd.writeAp(4 /* TAR */, addr);
this.cmd.readAp(12 /* DRW */);
};
/**
* Execute all commands asynchronously.
*/
PreparedMemoryCommand.prototype.go = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.cmd.go()];
});
});
};
return PreparedMemoryCommand;
}());
exports.PreparedMemoryCommand = PreparedMemoryCommand;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var debug_1 = __webpack_require__(5);
var memory_1 = __webpack_require__(7);
var prepared_1 = __webpack_require__(1);
var util_1 = __webpack_require__(0);
var constants_1 = __webpack_require__(3);
var prepared_2 = __webpack_require__(8);
/**
* # Cortex M
*
* Manages access to a CPU core, and its associated memory and debug functionality.
*
* > **NOTE:** all of the methods that involve interaction with the CPU core
* > are asynchronous, so must be `await`ed, or explicitly handled as a Promise.
*
* ## Usage
*
* First, let's create an instance of `CortexM`, using an associated _Debug Access
* Port_ (DAP) instance that we created earlier.
*
* ```typescript
* const core = new CortexM(dap);
* ```
*
* Now, we can halt and resume the core just like this:
*
* > **NOTE:** If you're not using ES2017, you can replace the use of `async` and
* > `await` with direct use of Promises. These examples also need to be run within
* > an `async` function for `async` to be used.
*
* ```typescript
* await core.halt();
* await core.resume();
* ```
*
* Resetting the core is just as easy:
*
* ```typescript
* await core.reset();
* ```
*
* You can even halt immediately after reset:
*
* ```typescript
* await core.reset(true);
* ```
*
* We can also read and write 32-bit values to/from core registers:
*
* ```typescript
* const sp = await core.readCoreRegister(CortexReg.SP);
*
* await core.writeCoreRegister(CortexReg.R0, 0x1000);
* await core.writeCoreRegister(CortexReg.PC, 0x1234);
* ```
*
* ### See also
*
* For details on debugging and memory features, see the documentation for
* `Debug` and `Memory`.
*/
var CortexM = (function () {
function CortexM(device) {
this.dev = device;
this.memory = new memory_1.Memory(device);
this.debug = new debug_1.Debug(this);
}
/**
* Initialise the debug access port on the device, and read the device type.
*/
CortexM.prototype.init = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.dev.init()];
case 1:
_a.sent();
// FIXME: don't run this if security is enabled on the K64F
return [4 /*yield*/, this.debug.init()];
case 2:
// FIXME: don't run this if security is enabled on the K64F
_a.sent();
return [4 /*yield*/, this.readCoreType()];
case 3:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Read the current state of the CPU.
*
* @returns A member of the `CoreState` enum corresponding to the current status of the CPU.
*/
CortexM.prototype.getState = function () {
return __awaiter(this, void 0, void 0, function () {
var dhcsr, newDHCSR;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.memory.read32(3758157296 /* DHCSR */)];
case 1:
dhcsr = _a.sent();
if (!(dhcsr & 33554432 /* S_RESET_ST */)) return [3 /*break*/, 3];
return [4 /*yield*/, this.memory.read32(3758157296 /* DHCSR */)];
case 2:
newDHCSR = _a.sent();
if (newDHCSR & 33554432 /* S_RESET_ST */ && !(newDHCSR & 16777216 /* S_RETIRE_ST */)) {
return [2 /*return*/, 0 /* TARGET_RESET */];
}
_a.label = 3;
case 3:
if (dhcsr & 524288 /* S_LOCKUP */) {
return [2 /*return*/, 1 /* TARGET_LOCKUP */];
}
else if (dhcsr & 262144 /* S_SLEEP */) {
return [2 /*return*/, 2 /* TARGET_SLEEPING */];
}
else if (dhcsr & 131072 /* S_HALT */) {
return [2 /*return*/, 3 /* TARGET_HALTED */];
}
else {
return [2 /*return*/, 4 /* TARGET_RUNNING */];
}
return [2 /*return*/];
}
});
});
};
/**
* Read the CPUID register from the CPU, and interpret its meaning in terms of implementer,
* architecture and core type.
*/
CortexM.prototype.readCoreType = function () {
return __awaiter(this, void 0, void 0, function () {
var cpuid, implementer, arch, coreType;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.memory.read32(3758157056 /* CPUID */)];
case 1:
cpuid = _a.sent();
implementer = ((cpuid & constants_1.CPUID_IMPLEMENTER_MASK) >> constants_1.CPUID_IMPLEMENTER_POS);
arch = ((cpuid & constants_1.CPUID_ARCHITECTURE_MASK) >> constants_1.CPUID_ARCHITECTURE_POS);
coreType = ((cpuid & constants_1.CPUID_PARTNO_MASK) >> constants_1.CPUID_PARTNO_POS);
console.debug("Found an ARM " + constants_1.CoreNames.get(coreType));
return [2 /*return*/, [implementer, arch, coreType]];
}
});
});
};
CortexM.prototype.prepareCommand = function () {
return new prepared_2.PreparedCortexMCommand(this.dev);
};
/**
* Read a core register from the CPU (e.g. r0...r15, pc, sp, lr, s0...)
*
* @param no Member of the `CortexReg` enum - an ARM Cortex CPU general-purpose register.
*/
CortexM.prototype.readCoreRegister = function (no) {
return __awaiter(this, void 0, void 0, function () {
var v;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.memory.write32(3758157300 /* DCRSR */, no)];
case 1:
_a.sent();
return [4 /*yield*/, this.memory.read32(3758157296 /* DHCSR */)];
case 2:
v = _a.sent();
util_1.assert(v & 65536 /* S_REGRDY */);
return [4 /*yield*/, this.memory.read32(3758157304 /* DCRDR */)];
case 3: return [2 /*return*/, _a.sent()];
}
});
});
};
/**
* Write a 32-bit word to the specified CPU general-purpose register.
*
* @param no Member of the `CortexReg` enum - an ARM Cortex CPU general-purpose register.
* @param val Value to be written.
*/
CortexM.prototype.writeCoreRegister = function (no, val) {
return __awaiter(this, void 0, void 0, function () {
var prep, v;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
prep = new prepared_1.PreparedMemoryCommand(this.dev);
prep.write32(3758157304 /* DCRDR */, val);
prep.write32(3758157300 /* DCRSR */, no | 65536 /* DCRSR_REGWnR */);
prep.read32(3758157296 /* DHCSR */);
return [4 /*yield*/, prep.go()];
case 1:
v = (_a.sent())[0];
util_1.assert(v & 65536 /* S_REGRDY */);
return [2 /*return*/];
}
});
});
};
/**
* Halt the CPU core.
*/
CortexM.prototype.halt = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.memory.write32(3758157296 /* DHCSR */, -1604386816 /* DBGKEY */ | 1 /* C_DEBUGEN */ | 2 /* C_HALT */)];
});
});
};
/**
* Resume the CPU core.
*/
CortexM.prototype.resume = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.isHalted()];
case 1:
if (!_a.sent()) return [3 /*break*/, 4];
return [4 /*yield*/, this.memory.write32(3758157104 /* DFSR */, 4 /* DFSR_DWTTRAP */ | 2 /* DFSR_BKPT */ | 1 /* DFSR_HALTED */)];
case 2:
_a.sent();
return [4 /*yield*/, this.debug.enable()];
case 3:
_a.sent();
_a.label = 4;
case 4: return [2 /*return*/];
}
});
});
};
/**
* Find out whether the CPU is halted.
*/
CortexM.prototype.isHalted = function () {
return __awaiter(this, void 0, void 0, function () {
var s;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.status()];
case 1:
s = _a.sent();
return [2 /*return*/, s.isHalted];
}
});
});
};
/**
* Read the current status of the CPU.
*
* @returns Object containing the contents of the `DHCSR` register, the `DFSR` register, and a boolean value
* stating the current halted state of the CPU.
*/
CortexM.prototype.status = function () {
return __awaiter(this, void 0, void 0, function () {
var prep, results, dhcsr, dfsr;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
prep = new prepared_1.PreparedMemoryCommand(this.dev);
prep.read32(3758157296 /* DHCSR */);
prep.read32(3758157104 /* DFSR */);
return [4 /*yield*/, prep.go()];
case 1:
results = _a.sent();
dhcsr = results[0];
dfsr = results[1];
return [2 /*return*/, {
dfsr: dfsr,
dhscr: dhcsr,
isHalted: !!(dhcsr & 131072 /* S_HALT */),
}];
}
});
});
};
/**
* Reset the CPU core. This currently does a software reset - it is also technically possible to perform a 'hard'
* reset using the reset pin from the debugger.
*/
CortexM.prototype.reset = function (halt) {
if (halt === void 0) { halt = false; }
return __awaiter(this, void 0, void 0, function () {
var demcr;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!halt) return [3 /*break*/, 7];
return [4 /*yield*/, this.halt()];
case 1:
_a.sent();
return [4 /*yield*/, this.memory.read32(3758157308 /* DEMCR */)];
case 2:
demcr = _a.sent();
return [4 /*yield*/, this.memory.write32(3758157308 /* DEMCR */, demcr | 1 /* DEMCR_VC_CORERESET */)];
case 3:
_a.sent();
return [4 /*yield*/, this.softwareReset()];
case 4:
_a.sent();
return [4 /*yield*/, this.waitForHalt()];
case 5:
_a.sent();
// Unset the VC_CORERESET bit
return [4 /*yield*/, this.memory.write32(3758157308 /* DEMCR */, demcr)];
case 6:
// Unset the VC_CORERESET bit
_a.sent();
return [3 /*break*/, 9];
case 7: return [4 /*yield*/, this.softwareReset()];
case 8:
_a.sent();
_a.label = 9;
case 9: return [2 /*return*/];
}
});
});
};
/**
* Run specified machine code natively on the device. Assumes usual C calling conventions
* - returns the value of r0 once the program has terminated. The program _must_ terminate
* in order for this function to return. This can be achieved by placing a `bkpt`
* instruction at the end of the function.
*
* @param code array containing the machine code (32-bit words).
* @param address memory address at which to place the code.
* @param pc initial value of the program counter.
* @param lr initial value of the link register.
* @param sp initial value of the stack pointer.
* @param upload should we upload the code before running it.
* @param args set registers r0...rn before running code
*
* @returns A promise for the value of r0 on completion of the function call.
*/
CortexM.prototype.runCode = function (code, address, pc, lr, sp, upload) {
var args = [];
for (var _i = 6; _i < arguments.length; _i++) {
args[_i - 6] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
var cmd, i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
cmd = this.prepareCommand();
cmd.halt();
// Point the program counter to the start of the program
cmd.writeCoreRegister(15 /* PC */, pc);
cmd.writeCoreRegister(14 /* LR */, lr);
cmd.writeCoreRegister(13 /* SP */, sp);
for (i = 0; i < args.length; i++) {
cmd.writeCoreRegister(i, args[i]);
}
return [4 /*yield*/, cmd.go()];
case 1:
_a.sent();
if (!upload) return [3 /*break*/, 3];
return [4 /*yield*/, this.memory.writeBlock(address, code)];
case 2:
_a.sent();
_a.label = 3;
case 3:
// Run the program and wait for halt
return [4 /*yield*/, this.resume()];
case 4:
// Run the program and wait for halt
_a.sent();
return [4 /*yield*/, this.waitForHalt(constants_1.DEFAULT_RUNCODE_TIMEOUT)];
case 5:
_a.sent(); // timeout after 10s
return [4 /*yield*/, this.readCoreRegister(0 /* R0 */)];
case 6: return [2 /*return*/, _a.sent()];
}
});
});
};
/**
* Spin until the chip has halted.
*/
CortexM.prototype.waitForHalt = function (timeout) {
if (timeout === void 0) { timeout = 0; }
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var running, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
running = true;
if (timeout > 0) {
setTimeout(function () {
if (running) {
reject("waitForHalt timed out.");
running = false;
}
}, timeout);
}
_b.label = 1;
case 1:
_a = running;
if (!_a) return [3 /*break*/, 3];
return [4 /*yield*/, this.isHalted()];
case 2:
_a = !(_b.sent());
_b.label = 3;
case 3:
if (!_a) return [3 /*break*/, 4];
return [3 /*break*/, 1];
case 4:
if (running) {
running = false;
resolve();
}
return [2 /*return*/];
}
});
}); })];
});
});
};
CortexM.prototype.softwareReset = function () {
return __awaiter(this, void 0, void 0, function () {
var dhcsr;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.memory.write32(3758157068 /* NVIC_AIRCR */, 100270080 /* NVIC_AIRCR_VECTKEY */ | 4 /* NVIC_AIRCR_SYSRESETREQ */)];
case 1:
_a.sent();
return [4 /*yield*/, this.memory.read32(3758157296 /* DHCSR */)];
case 2:
dhcsr = _a.sent();
_a.label = 3;
case 3:
if (!((dhcsr & 33554432 /* S_RESET_ST */) !== 0)) return [3 /*break*/, 5];
return [4 /*yield*/, this.memory.read32(3758157296 /* DHCSR */)];
case 4:
dhcsr = _a.sent();
return [3 /*break*/, 3];
case 5: return [2 /*return*/];
}
});
});
};
return CortexM;
}());
exports.CortexM = CortexM;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_RUNCODE_TIMEOUT = 10000 /* ms */;
exports.CPUID_IMPLEMENTER_MASK = 0xff000000;
exports.CPUID_IMPLEMENTER_POS = 24;
exports.CPUID_VARIANT_MASK = 0x00f00000;
exports.CPUID_VARIANT_POS = 20;
exports.CPUID_ARCHITECTURE_MASK = 0x000f0000;
exports.CPUID_ARCHITECTURE_POS = 16;
exports.CPUID_PARTNO_MASK = 0x0000fff0;
exports.CPUID_PARTNO_POS = 4;
exports.CPUID_REVISION_MASK = 0x0000000f;
exports.CPUID_REVISION_POS = 0;
exports.ISANames = new Map();
exports.ISANames.set(12 /* ARMv6M */, "ARMv6M");
exports.ISANames.set(15 /* ARMv7M */, "ARMv7M");
exports.CoreNames = new Map();
exports.CoreNames.set(3104 /* CortexM0 */, "Cortex-M0");
exports.CoreNames.set(3105 /* CortexM1 */, "Cortex-M1");
exports.CoreNames.set(3107 /* CortexM3 */, "Cortex-M3");
exports.CoreNames.set(3108 /* CortexM4 */, "Cortex-M4");
exports.CoreNames.set(3168 /* CortexM0p */, "Cortex-M0+");
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var cortex_1 = __webpack_require__(2);
exports.CortexM = cortex_1.CortexM;
var constants_1 = __webpack_require__(3);
exports.CoreNames = constants_1.CoreNames;
exports.ISANames = constants_1.ISANames;
var dap_1 = __webpack_require__(9);
exports.DAP = dap_1.default;
var FlashTarget_1 = __webpack_require__(12);
exports.FlashTargets = FlashTarget_1.FlashTargets;
exports.FlashTarget = FlashTarget_1.FlashTarget;
var FlashProgram_1 = __webpack_require__(15);
exports.FlashProgram = FlashProgram_1.FlashProgram;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var breakpoint_1 = __webpack_require__(6);
/**
* # Debug Interface
*
* Keeps track of breakpoints set on the target, as well as deciding whether to
* use a hardware breakpoint or a software breakpoint.
*
* ## Usage
*
* ```typescript
* const dbg = core.debug;
*
* await dbg.setBreakpoint(0x123456);
*
* // resume the core and wait for the breakpoint
* await core.resume();
* await core.waitForHalt();
*
* // step forward one instruction
* await dbg.step();
*
* // remove the breakpoint
* await dbg.deleteBreakpoint(0x123456);
* ```
*/
var Debug = (function () {
function Debug(core) {
this.core = core;
this.enabled = false;
this.availableHWBreakpoints = [];
this.breakpoints = new Map();
}
Debug.prototype.init = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.setupFpb()];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Enable debugging on the target CPU
*/
Debug.prototype.enable = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.core.memory.write32(3758157296 /* DHCSR */, -1604386816 /* DBGKEY */ | 1 /* C_DEBUGEN */)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Set breakpoints at specified memory addresses.
*
* @param addrs An array of memory addresses at which to set breakpoints.
*/
Debug.prototype.setBreakpoint = function (addr) {
return __awaiter(this, void 0, void 0, function () {
var breakpoint, bkpt, regAddr;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.breakpoints.has(addr)) {
breakpoint = this.breakpoints.get(addr);
if (typeof breakpoint !== "number") {
// already enabled
console.warn("Breakpoint at " + addr.toString(16) + " already enabled.");
return [2 /*return*/];
}
}
if (!(addr < 0x20000000)) return [3 /*break*/, 5];
if (!(this.availableHWBreakpoints.length > 0)) return [3 /*break*/, 3];
if (!!this.enabled) return [3 /*break*/, 2];
console.log("enabling fpb");
return [4 /*yield*/, this.setFpbEnabled(true)];
case 1:
_a.sent();
_a.label = 2;
case 2:
regAddr = this.availableHWBreakpoints.pop();
console.log("using regAddr=" + regAddr.toString(16));
bkpt = new breakpoint_1.HWBreakpoint(regAddr, this.core, addr);
return [3 /*break*/, 4];
case 3:
bkpt = new breakpoint_1.SWBreakpoint(this.core, addr);
_a.label = 4;
case 4: return [3 /*break*/, 6];
case 5:
bkpt = new breakpoint_1.SWBreakpoint(this.core, addr);
_a.label = 6;
case 6: return [4 /*yield*/, bkpt.set()];
case 7:
_a.sent();
this.breakpoints.set(addr, bkpt);
return [2 /*return*/];
}
});
});
};
Debug.prototype.deleteBreakpoint = function (addr) {
return __awaiter(this, void 0, void 0, function () {
var bkpt;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.breakpoints.has(addr)) return [3 /*break*/, 3];
bkpt = this.breakpoints.get(addr);
if (!(typeof bkpt !== "number")) return [3 /*break*/, 2];
return [4 /*yield*/, bkpt.clear()];
case 1:
_a.sent();
if (bkpt instanceof breakpoint_1.HWBreakpoint) {
// return the register address to the pool
this.availableHWBreakpoints.push(bkpt.regAddr);
}
_a.label = 2;
case 2:
this.breakpoints.delete(addr);
return [3 /*break*/, 4];
case 3:
console.warn("Breakpoint at " + addr.toString(16) + " does not exist.");
_a.label = 4;
case 4: return [2 /*return*/];
}
});
});
};
/**
* Step the processor forward by one instruction.
*/
Debug.prototype.step = function () {
return __awaiter(this, void 0, void 0, function () {
var dhcsr, interruptsMasked;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.core.memory.read32(3758157296 /* DHCSR */)];
case 1:
dhcsr = _a.sent();
if (!(dhcsr & (4 /* C_STEP */ | 2 /* C_HALT */))) {
console.error("Target is not halted.");
return [2 /*return*/];
}
interruptsMasked = (8 /* C_MASKINTS */ & dhcsr) !== 0;
if (!!interruptsMasked) return [3 /*break*/, 3];
return [4 /*yield*/, this.core.memory.write32(3758157296 /* DHCSR */, -1604386816 /* DBGKEY */ |
1 /* C_DEBUGEN */ |
2 /* C_HALT */ |
8 /* C_MASKINTS */)];
case 2:
_a.sent();
_a.label = 3;
case 3: return [4 /*yield*/, this.core.memory.write32(3758157296 /* DHCSR */, -1604386816 /* DBGKEY */ |
1 /* C_DEBUGEN */ |
8 /* C_MASKINTS */ |
4 /* C_STEP */)];
case 4:
_a.sent();
return [4 /*yield*/, this.core.waitForHalt()];
case 5:
_a.sent();
return [4 /*yield*/, this.core.memory.write32(3758157296 /* DHCSR */, -1604386816 /* DBGKEY */ |
1 /* C_DEBUGEN */ |
2 /* C_HALT */)];
case 6:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Set up (and disable) the Flash Patch & Breakpoint unit. It will be enabled when
* the first breakpoint is set.
*
* Also reads the number of available hardware breakpoints.
*/
Debug.prototype.setupFpb = function () {
return __awaiter(this, void 0, void 0, function () {
var fpcr, nbCode, nbLit, i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.core.memory.read32(3758104576 /* FP_CTRL */)];
case 1:
fpcr = _a.sent();
nbCode = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xf);
nbLit = (fpcr >> 7) & 0xf;
this.totalHWBreakpoints = nbCode;
console.debug(nbCode + " hardware breakpoints, " + nbLit + " literal comparators");
return [4 /*yield*/, this.setFpbEnabled(false)];
case 2:
_a.sent();
i = 0;
_a.label = 3;
case 3:
if (!(i < nbCode)) return [3 /*break*/, 6];
this.availableHWBreakpoints.push(3758104584 /* FP_COMP0 */ + (4 * i));
return [4 /*yield*/, this.core.memory.write32(3758104584 /* FP_COMP0 */ + (i * 4), 0)];
case 4:
_a.sent();
_a.label = 5;
case 5:
i++;
return [3 /*break*/, 3];
case 6: return [2 /*return*/];
}
});
});
};
/**
* Enable or disable the Flash Patch and Breakpoint unit (FPB).
*
* @param enabled
*/
Debug.prototype.setFpbEnabled = function (enabled) {
if (enabled === void 0) { enabled = true; }
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.enabled = enabled;
return [4 /*yield*/, this.core.memory.write32(3758104576 /* FP_CTRL */, 2 /* FP_CTRL_KEY */ | (enabled ? 1 : 0))];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
return Debug;
}());
exports.Debug = Debug;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) &