Compare commits

..

19 Commits
v1.0.18 ... hid

Author SHA1 Message Date
48e2456bec hid support 2018-04-16 06:43:08 -07:00
196ca79aa3 1.0.23 2018-04-04 08:59:37 -07:00
d17dd09c59 updated pxt ref 2018-04-04 08:54:49 -07:00
75dc59978e 1.0.22 2018-03-29 15:43:54 -07:00
abe06d1594 adding locales 2018-03-29 15:43:44 -07:00
72c6e7086e 1.0.21 2018-03-29 15:11:50 -07:00
46951d44c8 updated package lock 2018-03-29 15:11:37 -07:00
1339d3f579 updating pxt 2018-03-29 15:07:15 -07:00
34af44d299 badge does not work 2017-12-15 14:54:29 -08:00
1199845c52 added build status 2017-12-15 14:53:51 -08:00
003150643d run latest bump build until live 2017-12-15 14:49:36 -08:00
500de7fb13 1.0.20 2017-12-15 14:47:23 -08:00
88934881f9 upgrading various simulator parts 2017-12-15 14:45:38 -08:00
433e8c8805 adding neopixel/microturtle 2017-12-15 14:42:11 -08:00
b8b7d3d1b8 1.0.19 2017-12-14 13:31:15 -08:00
052cca94a2 UI changes to be inline with latest v0 (#16) 2017-12-14 13:30:47 -08:00
93dd793fb7 Merge branch 'master' of https://github.com/Microsoft/pxt-calliope 2017-12-14 11:50:29 -08:00
41c2012d42 windows app squeleton 2017-12-14 11:50:24 -08:00
d4934b19d1 Update README.md 2017-12-14 11:24:44 -08:00
38 changed files with 6029 additions and 1216 deletions

View File

@ -1,10 +1,9 @@
# Calliope target for Microsoft MakeCode
This target is hosted at https://makecode.calliope.cc.
This target is hosted at https://makecode.calliope.cc.
## Hosted editor and build
Hosted at: https://c371bd6d-007a-42fb-a45c-39891824b813.pxt.io</br>
Jenkins build: https://ci2.dot.net/job/Private/job/pxt_project_teal/job/master/

View File

@ -1,3 +1,3 @@
{
"appref": "v1.0.13"
"appref": "v"
}

421
editor/dapjs.d.ts vendored Normal file
View File

@ -0,0 +1,421 @@
declare namespace DapJS {
export interface IHID {
write(data: ArrayBuffer): Promise<void>;
read(): Promise<Uint8Array>;
close(): Promise<void>;
// sends each of commands and expects one packet in response
// this makes for better performance when HID access is proxied
sendMany?(commands: Uint8Array[]): Promise<Uint8Array[]>;
}
export class DAP {
constructor(device: IHID);
reconnect(): Promise<void>;
init(): Promise<void>;
close(): Promise<void>;
}
/**
* # Memory Interface
*
* Controls access to the target's memory.
*
* ## Usage
*
* Using an instance of `CortexM`, as described before, we can simply read and
* write numbers to memory as follows:
*
* ```typescript
* const mem = core.memory;
*
* // NOTE: the address parameter must be word (4-byte) aligned.
* await mem.write32(0x200000, 12345);
* const val = await mem.read32(0x200000);
*
* // val === 12345
*
* // NOTE: the address parameter must be half-word (2-byte) aligned
* await mem.write16(0x2000002, 65534);
* const val16 = await mem.read16(0x2000002);
*
* // val16 === 65534
* ```
*
* To write a larger block of memory, we can use `readBlock` and `writeBlock`. Again,
* these blocks must be written to word-aligned addresses in memory.
*
* ```typescript
* const data = new Uint32Array([0x1234, 0x5678, 0x9ABC, 0xDEF0]);
* await mem.writeBlock(0x200000, data);
*
* const readData = await mem.readBlock(0x200000, data.length, 0x100);
* ```
*
* ## See also
*
* `PreparedMemoryCommand` provides an equivalent API with better performance (in some
* cases) by enabling batched memory operations.
*/
export class Memory {
private dev;
constructor(dev: DAP);
/**
* Write a 32-bit word to the specified (word-aligned) memory address.
*
* @param addr Memory address to write to
* @param data Data to write (values above 2**32 will be truncated)
*/
write32(addr: number, data: number): Promise<void>;
/**
* Write a 16-bit word to the specified (half word-aligned) memory address.
*
* @param addr Memory address to write to
* @param data Data to write (values above 2**16 will be truncated)
*/
write16(addr: number, data: number): Promise<void>;
/**
* Read a 32-bit word from the specified (word-aligned) memory address.
*
* @param addr Memory address to read from.
*/
read32(addr: number): Promise<number>;
/**
* Read a 16-bit word from the specified (half word-aligned) memory address.
*
* @param addr Memory address to read from.
*/
read16(addr: number): Promise<number>;
/**
* Reads a block of memory from the specified memory address.
*
* @param addr Address to read from
* @param words Number of words to read
* @param pageSize Memory page size
*/
readBlock(addr: number, words: number, pageSize: number): Promise<Uint8Array>;
/**
* Write a block of memory to the specified memory address.
*
* @param addr Memory address to write to.
* @param words Array of 32-bit words to write to memory.
*/
writeBlock(addr: number, words: Uint32Array): Promise<void>;
private readBlockCore(addr, words);
private writeBlockCore(addr, words);
}
/**
* # 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`.
*/
export class CortexM {
/**
* Read and write to on-chip memory associated with this CPU core.
*/
memory: Memory;
/**
* Control the CPU's debugging features.
*/
debug: Debug;
/**
* Underlying Debug Access Port (DAP).
*/
private dev;
constructor(device: DAP);
/**
* Initialise the debug access port on the device, and read the device type.
*/
init(): Promise<void>;
/**
* Read the current state of the CPU.
*
* @returns A member of the `CoreState` enum corresponding to the current status of the CPU.
*/
getState(): Promise<CoreState>;
/**
* 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.
*/
readCoreRegister(no: CortexReg): Promise<number>;
/**
* 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.
*/
writeCoreRegister(no: CortexReg, val: number): Promise<void>;
/**
* Halt the CPU core.
*/
halt(): Promise<void>;
/**
* Resume the CPU core.
*/
resume(): Promise<void>;
/**
* Find out whether the CPU is halted.
*/
isHalted(): Promise<boolean>;
/**
* 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.
*/
status(): Promise<{
dfsr: number;
dhscr: number;
isHalted: boolean;
}>;
/**
* 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.
*/
reset(halt?: boolean): Promise<void>;
/**
* 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.
*/
runCode(code: Uint32Array, address: number, pc: number, lr: number, sp: number, upload: boolean, ...args: number[]): Promise<number>;
/**
* Spin until the chip has halted.
*/
waitForHalt(timeout?: number): Promise<void>;
prepareCommand(): PreparedCortexMCommand;
private softwareReset();
}
/**
* # Cortex M: Prepared Command
*
* Allows batching of Cortex M-related commands, such as writing to a register,
* halting and resuming the core.
*
* ## Example
*
* When preparing the sequence of commands, we can use the same API to prepare
* a command as we would to execute them immediately.
*
* ```typescript
* // Note that only the .go method is asynchronous.
*
* const prep = core.prepareCommand();
* prep.writeCoreRegister(CortexReg.R0, 0x1000);
* prep.writeCoreRegister(CortexReg.R1, 0x0);
* prep.writeCoreRegister(CortexReg.PC, 0x2000000);
* prep.resume();
* ```
*
* We can then execute them as efficiently as possible by combining them together
* and executing them like so.
*
* ```typescript
* await prep.go();
* ```
*
* The code above is equivalent to the following _non-prepared_ command:
*
* ```typescript
* await core.writeCoreRegister(CortexReg.R0, 0x1000);
* await core.writeCoreRegister(CortexReg.R1, 0x0);
* await core.writeCoreRegister(CortexReg.PC, 0x2000000);
* await core.resume();
* ```
*
* Since the batched version of this code avoids making three round-trips to the
* target, we are able to significantly improve performance. This is especially
* noticable when uploading a binary to flash memory, where are large number of
* repetetive commands are being used.
*
* ## Explanation
*
* For a detailed explanation of why prepared commands are used in DAP.js, see the
* documentation for `PreparedDapCommand`.
*/
export class PreparedCortexMCommand {
private cmd;
constructor(dap: DAP);
/**
* Schedule a 32-bit integer to be written to a core register.
*
* @param no Core register to be written.
* @param val Value to write.
*/
writeCoreRegister(no: CortexReg, val: number): void;
/**
* Schedule a halt command to be written to the CPU.
*/
halt(): void;
/**
* Schedule a resume command to be written to the CPU.
*/
resume(): void;
/**
* Execute all scheduled commands.
*/
go(): Promise<void>;
}
export const enum CortexReg {
R0 = 0,
R1 = 1,
R2 = 2,
R3 = 3,
R4 = 4,
R5 = 5,
R6 = 6,
R7 = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
SP = 13,
LR = 14,
PC = 15,
XPSR = 16,
MSP = 17,
PSP = 18,
PRIMASK = 20,
CONTROL = 20,
}
export const enum CoreState {
TARGET_RESET = 0,
TARGET_LOCKUP = 1,
TARGET_SLEEPING = 2,
TARGET_HALTED = 3,
TARGET_RUNNING = 4,
}
/**
* # 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);
* ```
*/
export class Debug {
private core;
private breakpoints;
private availableHWBreakpoints;
private totalHWBreakpoints;
private enabled;
constructor(core: CortexM);
init(): Promise<void>;
/**
* Enable debugging on the target CPU
*/
enable(): Promise<void>;
/**
* Set breakpoints at specified memory addresses.
*
* @param addrs An array of memory addresses at which to set breakpoints.
*/
setBreakpoint(addr: number): Promise<void>;
deleteBreakpoint(addr: number): Promise<void>;
/**
* Step the processor forward by one instruction.
*/
step(): Promise<void>;
/**
* 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.
*/
private setupFpb();
/**
* Enable or disable the Flash Patch and Breakpoint unit (FPB).
*
* @param enabled
*/
private setFpbEnabled(enabled?);
}
}

412
editor/extension.ts Normal file
View File

@ -0,0 +1,412 @@
/// <reference path="../node_modules/pxt-core/built/pxteditor.d.ts" />
interface Math {
imul(x: number, y: number): number;
}
namespace pxt.editor {
import UF2 = pxtc.UF2;
const pageSize = 1024;
const numPages = 256;
function murmur3_core(data: Uint8Array) {
let h0 = 0x2F9BE6CC;
let h1 = 0x1EC3A6C8;
for (let i = 0; i < data.length; i += 4) {
let k = HF2.read32(data, i) >>> 0
k = Math.imul(k, 0xcc9e2d51);
k = (k << 15) | (k >>> 17);
k = Math.imul(k, 0x1b873593);
h0 ^= k;
h1 ^= k;
h0 = (h0 << 13) | (h0 >>> 19);
h1 = (h1 << 13) | (h1 >>> 19);
h0 = (Math.imul(h0, 5) + 0xe6546b64) >>> 0;
h1 = (Math.imul(h1, 5) + 0xe6546b64) >>> 0;
}
return [h0, h1]
}
class DAPWrapper {
cortexM: DapJS.CortexM
packetIo: HF2.PacketIO;
constructor(h: HF2.PacketIO) {
this.packetIo = h;
let pbuf = new U.PromiseBuffer<Uint8Array>();
let sendMany = (cmds: Uint8Array[]) => {
return h.talksAsync(cmds.map(c => ({ cmd: 0, data: c })));
}
if (!h.talksAsync)
sendMany = null;
let dev = new DapJS.DAP({
write: writeAsync,
close: this.disconnectAsync,
read: readAsync,
sendMany: sendMany
});
this.cortexM = new DapJS.CortexM(dev);
h.onData = buf => {
pbuf.push(buf);
}
function writeAsync(data: ArrayBuffer) {
return h.sendPacketAsync(new Uint8Array(data));
}
function readAsync() {
return pbuf.shiftAsync();
}
}
reconnectAsync(first: boolean) {
if (!first)
return this.packetIo.reconnectAsync()
.then(() => this.cortexM.init())
else
return this.cortexM.init();
}
disconnectAsync() {
return this.packetIo.disconnectAsync();
}
}
let packetIoPromise: Promise<pxt.HF2.PacketIO>;
function initPacketIOAsync(): Promise<pxt.HF2.PacketIO> {
if (!packetIoPromise) {
packetIoPromise = pxt.HF2.mkPacketIOAsync()
.catch(err => {
packetIoPromise = null;
return Promise.reject(err);
});
return packetIoPromise;
} else {
let packetIo: pxt.HF2.PacketIO;
return packetIoPromise
.then((io) => {
packetIo = io;
return io.reconnectAsync();
})
.then(() => packetIo);
}
}
let previousDapWrapper: DAPWrapper;
function dapAsync() {
if (previousDapWrapper)
return Promise.resolve(previousDapWrapper)
return Promise.resolve()
.then(() => {
if (previousDapWrapper) {
return previousDapWrapper.disconnectAsync()
.finally(() => {
previousDapWrapper = null;
});
}
return Promise.resolve();
})
.then(() => initPacketIOAsync())
.then(h => {
let w = new DAPWrapper(h)
previousDapWrapper = w;
return w.reconnectAsync(true)
.then(() => w)
})
}
function canHID(): boolean {
let r = false
if (pxt.usb.isEnabled) {
r = true
} else if (U.isNodeJS) {
r = true
} else {
const forceHexDownload = /forceHexDownload/i.test(window.location.href);
const isUwp = !!(window as any).Windows;
if (Cloud.isLocalHost() && Cloud.localToken && !forceHexDownload || isUwp)
r = true
}
return r;
}
function initAsync() {
if (canHID()) {
return dapAsync();
} else {
return Promise.reject(new Error("no HID"))
}
}
function pageAlignBlocks(blocks: UF2.Block[], pageSize: number) {
U.assert(pageSize % 256 == 0)
let res: UF2.Block[] = []
for (let i = 0; i < blocks.length;) {
let b0 = blocks[i]
let newbuf = new Uint8Array(pageSize)
let startPad = b0.targetAddr & (pageSize - 1)
let newAddr = b0.targetAddr - startPad
for (; i < blocks.length; ++i) {
let b = blocks[i]
if (b.targetAddr + b.payloadSize > newAddr + pageSize)
break
U.memcpy(newbuf, b.targetAddr - newAddr, b.data, 0, b.payloadSize)
}
let bb = U.flatClone(b0)
bb.data = newbuf
bb.targetAddr = newAddr
bb.payloadSize = pageSize
res.push(bb)
}
return res
}
const flashPageBINquick = new Uint32Array([
0xbe00be00, // bkpt - LR is set to this
0x2480b5f0, 0x00e42300, 0x58cd58c2, 0xd10342aa, 0x42a33304, 0xbdf0d1f8,
0x4b162502, 0x509d4a16, 0x2d00591d, 0x24a1d0fc, 0x511800e4, 0x3cff3c09,
0x591e0025, 0xd0fc2e00, 0x509c2400, 0x2c00595c, 0x2401d0fc, 0x509c2580,
0x595c00ed, 0xd0fc2c00, 0x00ed2580, 0x002e2400, 0x5107590f, 0x2f00595f,
0x3404d0fc, 0xd1f742ac, 0x50992100, 0x2a00599a, 0xe7d0d0fc, 0x4001e000,
0x00000504,
])
// doesn't check if data is already there - for timing
const flashPageBIN = new Uint32Array([
0xbe00be00, // bkpt - LR is set to this
0x2402b5f0, 0x4a174b16, 0x2480509c, 0x002500e4, 0x2e00591e, 0x24a1d0fc,
0x511800e4, 0x2c00595c, 0x2400d0fc, 0x2480509c, 0x002500e4, 0x2e00591e,
0x2401d0fc, 0x595c509c, 0xd0fc2c00, 0x00ed2580, 0x002e2400, 0x5107590f,
0x2f00595f, 0x3404d0fc, 0xd1f742ac, 0x50992100, 0x2a00599a, 0xbdf0d0fc,
0x4001e000, 0x00000504,
])
// void computeHashes(uint32_t *dst, uint8_t *ptr, uint32_t pageSize, uint32_t numPages)
const computeChecksums2 = new Uint32Array([
0x4c27b5f0, 0x44a52680, 0x22009201, 0x91004f25, 0x00769303, 0x24080013,
0x25010019, 0x40eb4029, 0xd0002900, 0x3c01407b, 0xd1f52c00, 0x468c0091,
0xa9044665, 0x506b3201, 0xd1eb42b2, 0x089b9b01, 0x23139302, 0x9b03469c,
0xd104429c, 0x2000be2a, 0x449d4b15, 0x9f00bdf0, 0x4d149e02, 0x49154a14,
0x3e01cf08, 0x2111434b, 0x491341cb, 0x405a434b, 0x4663405d, 0x230541da,
0x4b10435a, 0x466318d2, 0x230541dd, 0x4b0d435d, 0x2e0018ed, 0x6002d1e7,
0x9a009b01, 0x18d36045, 0x93003008, 0xe7d23401, 0xfffffbec, 0xedb88320,
0x00000414, 0x1ec3a6c8, 0x2f9be6cc, 0xcc9e2d51, 0x1b873593, 0xe6546b64,
])
let startTime = 0
function log(msg: string) {
let now = Date.now()
if (!startTime) startTime = now
now -= startTime
let ts = ("00000" + now).slice(-5)
pxt.log(`HID ${ts}: ${msg}`)
}
const membase = 0x20000000
const loadAddr = membase
const dataAddr = 0x20002000
const stackAddr = 0x20001000
export const bufferConcat = (bufs: Uint8Array[]) => {
let len = 0;
for (const b of bufs) {
len += b.length;
}
const r = new Uint8Array(len);
len = 0;
for (const b of bufs) {
r.set(b, len);
len += b.length;
}
return r;
};
function getFlashChecksumsAsync(wrap: DAPWrapper) {
log("getting existing flash checksums")
let pages = numPages
return wrap.cortexM.runCode(computeChecksums2, loadAddr, loadAddr + 1, 0xffffffff, stackAddr, true,
dataAddr, 0, pageSize, pages)
.then(() => wrap.cortexM.memory.readBlock(dataAddr, pages * 2, pageSize))
}
function onlyChanged(blocks: UF2.Block[], checksums: Uint8Array) {
return blocks.filter(b => {
let idx = b.targetAddr / pageSize
U.assert((idx | 0) == idx)
U.assert(b.data.length == pageSize)
if (idx * 8 + 8 > checksums.length)
return true // out of range?
let c0 = HF2.read32(checksums, idx * 8)
let c1 = HF2.read32(checksums, idx * 8 + 4)
let ch = murmur3_core(b.data)
if (c0 == ch[0] && c1 == ch[1])
return false
return true
})
}
export function deployCoreAsync(resp: pxtc.CompileResult, d: pxt.commands.DeployOptions = {}): Promise<void> {
let saveHexAsync = () => {
return pxt.commands.saveOnlyAsync(resp)
}
startTime = 0
let wrap: DAPWrapper
log("init")
let logV = (msg: string) => { }
//let logV = log
const runFlash = (b: UF2.Block, dataAddr: number) => {
const cmd = wrap.cortexM.prepareCommand();
cmd.halt();
cmd.writeCoreRegister(DapJS.CortexReg.PC, loadAddr + 4 + 1);
cmd.writeCoreRegister(DapJS.CortexReg.LR, loadAddr + 1);
cmd.writeCoreRegister(DapJS.CortexReg.SP, stackAddr);
cmd.writeCoreRegister(0, b.targetAddr);
cmd.writeCoreRegister(1, dataAddr);
return Promise.resolve()
.then(() => {
logV("setregs")
return cmd.go()
})
.then(() => {
logV("dbg en")
// starts the program
return wrap.cortexM.debug.enable()
})
}
let checksums: Uint8Array
pxt.tickEvent("hid.flash.start");
return initAsync()
.then(w => {
wrap = w
log("reset")
return wrap.cortexM.reset(true)
.catch(e => {
log("trying re-connect")
return wrap.reconnectAsync(false)
.then(() => wrap.cortexM.reset(true))
})
})
.then(() => wrap.cortexM.memory.readBlock(0x10001014, 1, pageSize))
.then(v => {
if (HF2.read32(v, 0) != 0x3C000) {
pxt.tickEvent("hid.flash.uicrfail");
U.userError(U.lf("Please flash any MakeCode hex file using drag and drop. Flashing from app will work afterwards."))
}
})
.then(() => getFlashChecksumsAsync(wrap))
.then(buf => {
checksums = buf
log("write code")
return wrap.cortexM.memory.writeBlock(loadAddr, flashPageBIN)
})
.then(() => {
log("convert")
// TODO this is seriously inefficient (130ms on a fast machine)
let uf2 = UF2.newBlockFile()
UF2.writeHex(uf2, resp.outfiles[pxtc.BINARY_HEX].split(/\r?\n/))
let bytes = U.stringToUint8Array(UF2.serializeFile(uf2))
let parsed = UF2.parseFile(bytes)
let aligned = pageAlignBlocks(parsed, pageSize)
log(`initial: ${aligned.length} pages`)
aligned = onlyChanged(aligned, checksums)
log(`incremental: ${aligned.length} pages`)
return Promise.mapSeries(U.range(aligned.length),
i => {
let b = aligned[i]
if (b.targetAddr >= 0x10000000)
return Promise.resolve()
logV("about to write at 0x" + b.targetAddr.toString(16))
let writeBl = Promise.resolve()
let thisAddr = (i & 1) ? dataAddr : dataAddr + pageSize
let nextAddr = (i & 1) ? dataAddr + pageSize : dataAddr
if (i == 0) {
let u32data = new Uint32Array(b.data.length / 4)
for (let i = 0; i < b.data.length; i += 4)
u32data[i >> 2] = HF2.read32(b.data, i)
writeBl = wrap.cortexM.memory.writeBlock(thisAddr, u32data)
}
return writeBl
.then(() => runFlash(b, thisAddr))
.then(() => {
let next = aligned[i + 1]
if (!next)
return Promise.resolve()
logV("write next")
let buf = new Uint32Array(next.data.buffer)
return wrap.cortexM.memory.writeBlock(nextAddr, buf)
})
.then(() => {
logV("wait")
return wrap.cortexM.waitForHalt(500)
})
.then(() => {
logV("done block")
})
})
.then(() => {
log("flash done")
pxt.tickEvent("hid.flash.done");
return wrap.cortexM.reset(false)
})
})
.catch(e => {
if (e.type === "devicenotfound" && d.reportDeviceNotFoundAsync) {
pxt.tickEvent("hid.flash.devicenotfound");
return d.reportDeviceNotFoundAsync("/device/windows-app/troubleshoot", resp);
} else {
return saveHexAsync()
}
})
}
initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
pxt.debug('loading microbit target extensions...')
if (!Math.imul)
Math.imul = (a, b) => {
var ah = (a >>> 16) & 0xffff;
var al = a & 0xffff;
var bh = (b >>> 16) & 0xffff;
var bl = b & 0xffff;
// the shift by 0 fixes the sign on the high part
// the final |0 converts the unsigned value into a signed value
return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0) | 0);
};
const res: pxt.editor.ExtensionResult = {};
pxt.usb.setFilters([{
vendorId: 0, // TODO
productId: 0, // TODO
classCode: 0xff,
subclassCode: 0x03
}])
if (canHID())
pxt.commands.deployCoreAsync = deployCoreAsync;
return Promise.resolve<pxt.editor.ExtensionResult>(res);
}
}

13
editor/tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "es5",
"noImplicitAny": true,
"noImplicitReturns": true,
"declaration": true,
"out": "../built/editor.js",
"rootDir": ".",
"newLine": "LF",
"sourceMap": false
},
"prepend": ["../external/dapjs.js"]
}

3038
external/dapjs.js vendored Normal file

File diff suppressed because it is too large Load Diff

6
external/sha/.yotta.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"build": {
"target": "bbc-microbit-classic-gcc,*",
"targetSetExplicitly": true
}
}

5
external/sha/buildflash.sh vendored Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh
yotta build
arm-none-eabi-objdump -d `find -name main.c.o` > disasm
node genapplet.js disasm Reset_Handler
rm disasm

48
external/sha/genapplet.js vendored Normal file
View File

@ -0,0 +1,48 @@
let fs = require("fs")
let s = fs.readFileSync(process.argv[2], "utf8")
let infun = false
let words = []
for (let l of s.split(/\n/)) {
let m = /^00000000 <(.*)>:/.exec(l)
if (m && m[1] == process.argv[3]) infun = true
if (/^Disassembly/.test(l)) infun = false
if (!infun) continue
m = /^\s*[0-9a-f]+:\s+([0-9a-f]+)( ([0-9a-f]{4}))?\s+/.exec(l)
if (m) {
let n = m[1]
words.push(n)
if (m[3])
words.push(m[3])
if (n.length == 4 || n.length == 8) {
// ok
} else {
throw new Error()
}
}
}
let ww = []
let pref = ""
for (let w of words) {
if (w.length == 8) {
if (pref) throw new Error()
ww.push("0x" + w)
} else {
if (pref) {
ww.push("0x" + w + pref)
pref = ""
} else {
pref = w
}
}
}
words = ww
let r = ""
for (let i = 0; i < words.length; i++) {
if (i % 6 == 0) r += "\n"
r += words[i] + ", "
}
console.log(r)

9
external/sha/module.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
"name": "sha",
"version": "0.0.0",
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {},
"bin": "./source"
}

240
external/sha/source/main.c vendored Normal file
View File

@ -0,0 +1,240 @@
#include <stdint.h>
static const uint32_t sha256_k[] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
#define rotr(v, b) (((uint32_t)v >> b) | (v << (32 - b)))
static inline void sha256round(uint32_t *hs, uint32_t *w) {
for (int i = 16; i < 64; ++i) {
uint32_t s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >> 3);
uint32_t s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >> 10);
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) | 0;
}
uint32_t a = hs[0];
uint32_t b = hs[1];
uint32_t c = hs[2];
uint32_t d = hs[3];
uint32_t e = hs[4];
uint32_t f = hs[5];
uint32_t g = hs[6];
uint32_t h = hs[7];
for (int i = 0; i < 64; ++i) {
uint32_t s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
uint32_t ch = (e & f) ^ (~e & g);
uint32_t temp1 = (h + s1 + ch + sha256_k[i] + w[i]);
uint32_t s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
uint32_t maj = (a & b) ^ (a & c) ^ (b & c);
uint32_t temp2 = (s0 + maj);
h = g;
g = f;
f = e;
e = (d + temp1);
d = c;
c = b;
b = a;
a = (temp1 + temp2);
}
hs[0] += a;
hs[1] += b;
hs[2] += c;
hs[3] += d;
hs[4] += e;
hs[5] += f;
hs[6] += g;
hs[7] += h;
}
#define INLINE __attribute__((always_inline)) static inline
INLINE void sha256block(uint8_t *buf, uint32_t len, uint32_t *dst) {
uint32_t hs[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
uint32_t w[64];
for (uint32_t i = 0; i < len; i += 64) {
for (uint32_t j = 0; j < 16; j++) {
uint32_t off = (j << 2) + i;
w[j] = (buf[off] << 24) | (buf[off + 1] << 16) | (buf[off + 2] << 8) |
buf[off + 3];
}
sha256round(hs, w);
}
dst[0] = hs[0];
dst[1] = hs[1];
}
#define POLYNOMIAL 0xEDB88320
INLINE void makeCRC32tab(uint32_t *table) {
for (uint32_t b = 0; b < 256; ++b) {
uint32_t r = b;
for (uint32_t j = 0; j < 8; ++j) {
if (r & 1)
r = (r >> 1) ^ POLYNOMIAL;
else
r = (r >> 1);
}
table[b] = r;
}
}
INLINE uint32_t crc(const uint8_t *p, uint32_t len, uint32_t *crcTable) {
uint32_t crc = ~0U;
for (uint32_t i = 0; i < len; ++i)
crc = crcTable[*p++ ^ (crc & 0xff)] ^ (crc >> 8);
return (~crc);
}
INLINE uint32_t murmur3_core(const uint8_t *data, uint32_t len) {
uint32_t h = 0x2F9BE6CC;
const uint32_t *data32 = (const uint32_t *)data;
uint32_t i = len >> 2;
do {
uint32_t k = *data32++;
k *= 0xcc9e2d51;
k = (k << 15) | (k >> 17);
k *= 0x1b873593;
h ^= k;
h = (h << 13) | (h >> 19);
h = (h * 5) + 0xe6546b64;
} while (--i);
return h;
}
INLINE void murmur3_core_2(const uint8_t *data, uint32_t len, uint32_t *dst) {
// compute two hashes with different seeds in parallel, hopefully reducing
// collisions
uint32_t h0 = 0x2F9BE6CC;
uint32_t h1 = 0x1EC3A6C8;
const uint32_t *data32 = (const uint32_t *)data;
uint32_t i = len >> 2;
do {
uint32_t k = *data32++;
k *= 0xcc9e2d51;
k = (k << 15) | (k >> 17);
k *= 0x1b873593;
h0 ^= k;
h1 ^= k;
h0 = (h0 << 13) | (h0 >> 19);
h1 = (h1 << 13) | (h1 >> 19);
h0 = (h0 * 5) + 0xe6546b64;
h1 = (h1 * 5) + 0xe6546b64;
} while (--i);
dst[0] = h0;
dst[1] = h1;
}
int Reset_Handler(uint32_t *dst, uint8_t *ptr, uint32_t pageSize,
uint32_t numPages) {
uint32_t crcTable[256];
makeCRC32tab(crcTable);
for (uint32_t i = 0; i < numPages; ++i) {
#if 0
sha256block(ptr, pageSize, dst);
#elif 0
dst[0] = crc(ptr, pageSize, crcTable);
dst[1] = murmur3_core(ptr, pageSize);
#else
murmur3_core_2(ptr, pageSize, dst);
#endif
dst += 2;
ptr += pageSize;
}
#ifdef __arm__
__asm__("bkpt 42");
#endif
return 0;
}
#if 0
#define PAGE_SIZE 0x400
#define SIZE_IN_WORDS (PAGE_SIZE / 4)
#define setConfig(v) \
do { \
NRF_NVMC->CONFIG = v; \
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) \
; \
} while (0)
void overwriteFlashPage(uint32_t *to, uint32_t *from) {
int same = 1;
for (int i = 0; i <= (SIZE_IN_WORDS - 1); i++) {
if (to[i] != from[i]) {
same = 0;
break;
}
}
if (same)
return;
// Turn on flash erase enable and wait until the NVMC is ready:
setConfig(NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos);
// Erase page:
NRF_NVMC->ERASEPAGE = (uint32_t)to;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
;
// Turn off flash erase enable and wait until the NVMC is ready:
setConfig(NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
// Turn on flash write enable and wait until the NVMC is ready:
setConfig(NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
for (int i = 0; i <= (SIZE_IN_WORDS - 1); i++) {
*(to + i) = *(from + i);
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
;
}
// Turn off flash write enable and wait until the NVMC is ready:
setConfig(NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
}
#endif
#ifndef __arm__
#define PS 1024
#define NP 10
#include <stdio.h>
#include <string.h>
int main() {
uint8_t buf[NP * PS];
uint32_t sums[NP * 2];
memset(buf, 0, sizeof(buf));
for (int i = 0; i < PS; ++i)
buf[i] = i;
for (int i = 0; i < PS; ++i)
buf[i + PS] = 108;
Reset_Handler(sums, buf, PS, NP);
for (int i = 0; i < NP; ++i) {
printf("%08x %08x\n", sums[i * 2], sums[i * 2 + 1]);
}
return 0;
}
#endif

View File

@ -4,8 +4,12 @@
"AcceleratorRange.OneG": "The accelerator measures forces up to 1 gravity",
"AcceleratorRange.TwoG": "The accelerator measures forces up to 2 gravity",
"Array": "Add, remove, and replace items in lists.\n\nAdd, remove, and replace items in lists.",
"Array.every": "Tests whether all elements in the array pass the test implemented by the provided function.",
"Array.every|param|callbackfn": "A function that accepts up to two arguments. The some method calls the callbackfn function one time for each element in the array.",
"Array.filter": "Return the elements of an array that meet the condition specified in a callback function.",
"Array.filter|param|callbackfn": "A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.",
"Array.forEach": "Call a defined callback function on each element of an array.",
"Array.forEach|param|callbackfn": "A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array.",
"Array.get": "Get the value at a particular index.",
"Array.get|param|index": "the zero-based position in the list of the item, eg: 0",
"Array.indexOf": "Return the index of the first occurrence of a value in an array.",
@ -14,6 +18,8 @@
"Array.insertAt": "Insert the value at a particular index, increase the array length by 1.",
"Array.insertAt|param|index": "the zero-based position in the list to insert the value, eg: 0",
"Array.insertAt|param|value": "to insert, eg: 0",
"Array.join": "joins all elements of an array into a string and returns this string.",
"Array.join|param|sep": "the string separator",
"Array.length": "Gets or sets the length of the array. This is a number one higher than the highest element defined in an array.",
"Array.map": "Call a defined callback function on each element of an array, and return an array containing the results.",
"Array.map|param|callbackfn": "A function that accepts up to two arguments. The map method calls the callbackfn function one time for each element in the array.",
@ -33,6 +39,8 @@
"Array.slice": "Return a section of an array.",
"Array.slice|param|end": "The end of the specified portion of the array. eg: 0",
"Array.slice|param|start": "The beginning of the specified portion of the array. eg: 0",
"Array.some": "Tests whether at least one element in the array passes the test implemented by the provided function.",
"Array.some|param|callbackfn": "A function that accepts up to two arguments. The some method calls the callbackfn function one time for each element in the array.",
"Array.sort": "Sort the elements of an array in place and returns the array. The sort is not necessarily stable.",
"Array.splice": "Remove elements from an array.",
"Array.splice|param|deleteCount": "The number of elements to remove. eg: 0",

2303
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "pxt-calliope",
"version": "1.0.18",
"version": "1.0.23",
"description": "Calliope Mini editor for PXT",
"keywords": [
"JavaScript",
@ -30,13 +30,13 @@
"typings": "built/pxtrequire.d.ts",
"devDependencies": {
"typescript": "^1.8.7",
"less": "^2.6.0",
"rtlcss": "^2.1.2",
"autoprefixer": "^6.7.6",
"semantic-ui-less": "^2.2.4"
"less": "2.7.3",
"semantic-ui-less": "2.2.14"
},
"dependencies": {
"pxt-core": "0.14.32"
"pxt-core": "0.18.2"
},
"scripts": {
"test": "node node_modules/pxt-core/built/pxt.js travis"

View File

@ -207,10 +207,11 @@
"organizationWideLogo": "./static/Microsoft-logo_rgb_c-white.png",
"boardName": "Calliope mini",
"driveDisplayName": "MINI",
"extendEditor": true,
"hideSideDocs": true,
"invertedMenu": true,
"invertedToolbox": true,
"monacoToolbox": false,
"monacoToolbox": true,
"hasAudio": true,
"highContrast": true,
"simAnimationEnter": "rotate in",
@ -224,7 +225,11 @@
}
},
"docMenu": [],
"hasReferenceDocs": false
"hasReferenceDocs": false,
"availableLocales": [
"de",
"en"
]
},
"ignoreDocsErrors": true
}

295
pxtwapp/.gitignore vendored Normal file
View File

@ -0,0 +1,295 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

48
pxtwapp/pxtwapp.sln Normal file
View File

@ -0,0 +1,48 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.15
MinimumVisualStudioVersion = 10.0.40219.1
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "pxtwapp", "pxtwapp\pxtwapp.jsproj", "{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|ARM.ActiveCfg = Debug|ARM
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|ARM.Build.0 = Debug|ARM
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|ARM.Deploy.0 = Debug|ARM
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x64.ActiveCfg = Debug|x64
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x64.Build.0 = Debug|x64
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x64.Deploy.0 = Debug|x64
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x86.ActiveCfg = Debug|x86
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x86.Build.0 = Debug|x86
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x86.Deploy.0 = Debug|x86
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|Any CPU.Build.0 = Release|Any CPU
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|Any CPU.Deploy.0 = Release|Any CPU
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|ARM.ActiveCfg = Release|ARM
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|ARM.Build.0 = Release|ARM
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|ARM.Deploy.0 = Release|ARM
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x64.ActiveCfg = Release|x64
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x64.Build.0 = Release|x64
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x64.Deploy.0 = Release|x64
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x86.ActiveCfg = Release|x86
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x86.Build.0 = Release|x86
{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,40 @@
body {
margin: 10px;
background-color: #6633cc;
color: #FFFFFF;
font-family: 'Open Sans', 'Helvetica Neue', Arial, Helvetica, sans-serif;
}
.paramName {
font-size: 10px;
font-weight: bold;
}
.paramValue {
font-size: 10px;
padding-left: 10px;
}
.param {
margin-bottom: 8px;
}
#retryButton {
box-shadow: 0px 0em 0px 0px rgba(34, 36, 38, 0.15) inset;
outline: none;
border: none;
vertical-align: baseline;
padding: 0.78571429em 1.5em 0.78571429em;
text-transform: none;
font-weight: bold;
font-style: normal;
text-align: center;
text-decoration: none;
border-radius: 0.28571429rem;
background-color: #ff8b27;
margin: 15px 10px 100px 10px;
width: 80px;
height: 35px;
font-size: 15px;
color: #FFFFFF;
}

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<title>Oops!</title>
<link href="msapp-error.css" rel="stylesheet" type="text/css" />
<script src="msapp-error.js" type="text/javascript"></script>
</head>
<body>
<h1>Oops! Please connect to the Internet.</h1>
<button id="retryButton">Retry</button>
<div id="failureUrl" class="param">
<span class="paramName">URL:</span>
<span id="failureUrlValue" class="paramValue"></span>
</div>
<div id="httpStatus" class="param">
<span class="paramName">HTTP status:</span>
<span id="httpStatusValue" class="paramValue"></span>
</div>
<div id="failureName">
<span class="paramName">Failure name:</span>
<span id="failureNameValue" class="paramValue"></span>
</div>
</body>
</html>

View File

@ -0,0 +1,47 @@
(function () {
var validParameterNames = ["httpStatus", "failureName", "failureUrl"];
function parseQueryParameters() {
var query = location.search.slice(1);
return query.split("&").reduce(function (queryParameters, rawPair) {
var pair = rawPair.split("=").map(decodeURIComponent);
queryParameters[pair[0]] = pair[1];
return queryParameters;
}, {});
}
function initialize() {
var queryParameters = parseQueryParameters();
var url = queryParameters["failureUrl"];
var retryButton = document.getElementById("retryButton");
if (url) {
retryButton.addEventListener("click", (e) => {
window.location.href = url;
});
} else {
retryButton.style.display = none;
}
validParameterNames.forEach(function (parameterName) {
var parameterValue = queryParameters[parameterName];
if (parameterValue) {
document.getElementById(parameterName + "Value").textContent = parameterValue;
} else {
document.getElementById(parameterName).remove();
}
});
}
function updateOnlineStatus(e) {
var queryParameters = parseQueryParameters();
var url = queryParameters["failureUrl"];
if (url) {
window.location.href = url;
}
}
window.addEventListener("online", updateOnlineStatus);
document.addEventListener("DOMContentLoaded", initialize);
}());

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" IgnorableNamespaces="uap uap3 mp">
<Identity Name="CalliopeMini" Version="1.0.0.0" Publisher="CN=calliope" />
<mp:PhoneIdentity PhoneProductId="5ddd542e-5ab4-48bc-b116-0782dc08ab97" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>Microsoft MakeCode for Calliope Mini</DisplayName>
<PublisherDisplayName>Calliope.cc</PublisherDisplayName>
<Logo>images\storelogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" StartPage="https://makecode.calliope.cc/">
<uap:ApplicationContentUriRules>
<uap:Rule Match="https://makecode.calliope.cc/" Type="include" WindowsRuntimeAccess="all" />
<uap:Rule Match="https://trg-calliope.userpxt.io/---simulator" Type="include" WindowsRuntimeAccess="none" />
<uap:Rule Match="https://makecode.calliope.cc/beta" Type="include" WindowsRuntimeAccess="all" />
<uap:Rule Match="https://trg-calliope.userpxt.io/beta---simulator" Type="include" WindowsRuntimeAccess="none" />
</uap:ApplicationContentUriRules>
<uap:VisualElements DisplayName="Microsoft MakeCode for Calliope Mini" Description="Microsoft MakeCode for Calliope Mini" BackgroundColor="#249899" Square150x150Logo="images\Square150x150Logo.png" Square44x44Logo="images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="images\Wide310x150Logo.png" Square71x71Logo="images\SmallTile.png">
</uap:DefaultTile>
<uap:SplashScreen Image="images\SplashScreen.png" BackgroundColor="#303030" />
</uap:VisualElements>
<Extensions>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="makecode">
<uap:DisplayName>Microsoft MakeCode binary file</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType ContentType="application/x-makecode-hex">.hex</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
<uap3:Extension Category="windows.appUriHandler">
<uap3:AppUriHandler>
<uap3:Host Name="makecode.calliope.cc" />
</uap3:AppUriHandler>
</uap3:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<DeviceCapability Name="serialcommunication">
<Device Id="any">
<Function Type="name:serialPort" />
</Device>
</DeviceCapability>
<DeviceCapability Name="humaninterfacedevice">
<Device Id="vidpid:0d28 0204">
<Function Type="usage:FF00 *" />
</Device>
</DeviceCapability>
</Capabilities>
</Package>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>34e8cde2-3991-414e-bb19-bff4bd5e031a</ProjectGuid>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0'">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.15063.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>$(VersionNumberMajor).$(VersionNumberMinor)</MinimumVisualStudioVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<PackageCertificateKeyFile>pxtwapp_TemporaryKey.pfx</PackageCertificateKeyFile>
<AppxAutoIncrementPackageRevision>true</AppxAutoIncrementPackageRevision>
<AppxBundle>Always</AppxBundle>
<AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms>
<PackageCertificateThumbprint>BA3D3E800661F789BAE7216F8D6F76608D1C4D62</PackageCertificateThumbprint>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<Content Include="images\logo.png" />
<Content Include="images\SmallTile.scale-200.png" />
<Content Include="images\Square44x44Logo.altform-unplated_targetsize-48.png" />
<Content Include="images\Square44x44Logo.targetsize-48.png" />
<Content Include="images\storelogo.scale-200.png" />
<Content Include="msapp-error.js" />
<Content Include="msapp-error.css" />
<Content Include="msapp-error.html" />
<Content Include="images\SplashScreen.scale-200.png" />
<Content Include="images\Square150x150Logo.scale-200.png" />
<Content Include="images\Square44x44Logo.scale-200.png" />
<Content Include="images\Wide310x150Logo.scale-200.png" />
<None Include="pxtwapp_TemporaryKey.pfx" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<!-- To modify your build process, add your task inside one of the targets below then uncomment
that target and the DisableFastUpToDateCheck PropertyGroup.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<PropertyGroup>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
-->
</Project>

View File

@ -18,6 +18,9 @@ namespace pxsim {
speakerState: SpeakerState;
fileSystem: FileSystemState;
// visual
view: SVGElement;
constructor() {
super()
@ -94,7 +97,7 @@ namespace pxsim {
break;
case "serial":
let data = (<SimulatorSerialMessage>msg).data || "";
this.serialState.recieveData(data);
this.serialState.receiveData(data);
break;
case "radiopacket":
let packet = <SimulatorRadioPacketMessage>msg;
@ -121,16 +124,22 @@ namespace pxsim {
fnArgs: fnArgs,
maxWidth: "100%",
maxHeight: "100%",
highContrast: msg.highContrast
};
const viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView({
visual: boardDef.visual
visual: boardDef.visual,
highContrast: msg.highContrast
}), opts);
document.body.innerHTML = ""; // clear children
document.body.appendChild(viewHost.getView());
document.body.appendChild(this.view = viewHost.getView());
return Promise.resolve();
}
screenshot(): string {
return svg.toDataUri(new XMLSerializer().serializeToString(this.view));
}
}
export function initRuntimeWithDalBoard() {

View File

@ -28,7 +28,7 @@ namespace pxsim {
this.data = data;
}
public print() {
console.log(`Image id:${this.id} refs:${this.refcnt} size:${this.width}x${Image.height}`)
// console.debug(`Image id:${this.id} refs:${this.refcnt} size:${this.width}x${Image.height}`)
}
public get(x: number, y: number): number {
if (x < 0 || x >= this.width || y < 0 || y >= 5) return 0;
@ -131,15 +131,33 @@ namespace pxsim.images {
namespace pxsim.ImageMethods {
export function showImage(leds: Image, offset: number, interval: number) {
pxtrt.nullCheck(leds)
leds.copyTo(offset, 5, board().ledMatrixState.image, 0)
runtime.queueDisplayUpdate()
basic.pause(interval);
let cb = getResume();
let first = true;
board().ledMatrixState.animationQ.enqueue({
interval,
frame: () => {
if (first) {
leds.copyTo(offset, 5, board().ledMatrixState.image, 0)
first = false;
return true;
}
return false;
},
whenDone: cb
})
}
export function plotImage(leds: Image, offset: number): void {
pxtrt.nullCheck(leds)
leds.copyTo(offset, 5, board().ledMatrixState.image, 0)
runtime.queueDisplayUpdate()
board().ledMatrixState.animationQ.enqueue({
interval: 0,
frame: () => {
leds.copyTo(offset, 5, board().ledMatrixState.image, 0)
return false;
}
})
}
export function height(leds: Image): number {
@ -216,15 +234,16 @@ namespace pxsim.ImageMethods {
namespace pxsim.basic {
export function showNumber(x: number, interval: number) {
if (interval < 0) return;
if (interval <= 0)
interval = 1;
let leds = createImageFromString(x.toString());
if (x < 0 || x >= 10) ImageMethods.scrollImage(leds, 1, interval);
else showLeds(leds, interval * 5);
}
export function showString(s: string, interval: number) {
if (interval < 0) return;
if (interval <= 0)
interval = 1;
if (s.length == 0) {
clearScreen();
pause(interval * 5);
@ -254,7 +273,16 @@ namespace pxsim.basic {
namespace pxsim.led {
export function plot(x: number, y: number) {
board().ledMatrixState.image.set(x, y, 255);
board().ledMatrixState.image.set(x, y, 0xff);
runtime.queueDisplayUpdate()
}
export function plotBrightness(x: number, y: number, brightness: number) {
const state = board().ledMatrixState;
brightness = Math.max(0, Math.min(0xff, brightness));
if (brightness != 0 && brightness != 0xff && state.displayMode != DisplayMode.greyscale)
state.displayMode = DisplayMode.greyscale;
state.image.set(x, y, brightness);
runtime.queueDisplayUpdate()
}
@ -272,7 +300,7 @@ namespace pxsim.led {
}
export function setBrightness(value: number): void {
board().ledMatrixState.brigthness = value;
board().ledMatrixState.brigthness = Math.max(0, Math.min(255, value));
runtime.queueDisplayUpdate()
}
@ -286,7 +314,7 @@ namespace pxsim.led {
runtime.queueDisplayUpdate()
}
export function displayMode() : DisplayMode {
export function displayMode(): DisplayMode {
return board().ledMatrixState.displayMode;
}

View File

@ -1,8 +1,9 @@
namespace pxsim {
const SERIAL_BUFFER_LENGTH = 16;
export class SerialState {
serialIn: string[] = [];
public recieveData(data: string) {
public receiveData(data: string) {
this.serialIn.push();
}
@ -13,18 +14,15 @@ namespace pxsim {
serialOutBuffer: string = "";
writeSerial(s: string) {
for (let i = 0; i < s.length; ++i) {
let c = s[i];
this.serialOutBuffer += c;
if (c == "\n") {
Runtime.postMessage(<SimulatorSerialMessage>{
type: "serial",
data: this.serialOutBuffer,
id: runtime.id
})
this.serialOutBuffer = ""
break;
}
this.serialOutBuffer += s;
if (/\n/.test(this.serialOutBuffer) || this.serialOutBuffer.length > SERIAL_BUFFER_LENGTH) {
Runtime.postMessage(<SimulatorSerialMessage>{
type: 'serial',
data: this.serialOutBuffer,
id: runtime.id,
sim: true
})
this.serialOutBuffer = '';
}
}
}
@ -51,4 +49,8 @@ namespace pxsim.serial {
export function redirect(tx: number, rx: number, rate: number) {
// TODO?
}
export function redirectToUSB() {
// TODO
}
}

View File

@ -11,6 +11,8 @@
"Tinkertanker/pxt-ssd1306-microbit"
],
"preferredRepos": [
"Microsoft/pxt-neopixel",
"Microsoft/pxt-microturtle",
"calliope-mini/pxt-calliope-modem",
"calliope-mini/pxt-calliope-bc95",
"calliope-mini/pxt-calliope-esp",

View File

@ -19,8 +19,6 @@ div.blocklyTreeRow {
border-radius:8px;
box-shadow: inset 0 -1px 0 0 #ecf0f1;
margin-bottom: 0px !important;
-webkit-transition-property: background-color; /* Safari */
-webkit-transition-duration: 1s; /* Safari */
transition-property: background-color;
@ -52,6 +50,10 @@ span.blocklyTreeLabel {
border-radius: 10px;
}
.blocklyFlyoutBackground {
fill: #42495F !important;
}
/* Mobile */
@media only screen and (max-width: @largestMobileScreen) {
.blocklyToolboxDiv, .monacoToolboxDiv {

View File

@ -4,10 +4,3 @@
@invertedBackground: #525A67;
@dropdownMenuDistance: 0px;
/*******************************
PXT Theme Overrides
*******************************/
@mainMenuHeight: 5rem;
@mainMenuMinHeight: (@itemVerticalPadding * 2) + 2em;

View File

@ -32,8 +32,6 @@
PXT Overrides
*******************************/
@mainMenuHeight: 5rem;
@mobileMenuHeight: 5rem;
@blocklyToolboxColor: #F6F4E6;
@blocklyFlyoutColor: #42495F;