Compare commits

...

107 Commits

Author SHA1 Message Date
e31279938b 0.4.13 2016-09-20 22:13:15 -07:00
2655843b74 Bump pxt-core to 0.4.17 2016-09-20 22:13:08 -07:00
527d323ea7 New electron client (#256) 2016-09-20 22:02:18 -07:00
5d40a48477 Merge pull request #255 from Microsoft/browser-versions
More detailed information about which browser versions are supported
2016-09-20 11:54:59 +01:00
850fb54f52 missing shims for devices namespace 2016-09-19 09:49:58 -07:00
6bb35c1a72 More detailed information about which browser versions are supported 2016-09-19 09:31:03 +01:00
6569231ba6 0.4.12 2016-09-16 00:05:53 -07:00
a3a1c8a480 Bump pxt-core to 0.4.15 2016-09-16 00:05:51 -07:00
c90dfaa6e7 added headphone part 2016-09-15 23:50:52 -07:00
02cd0e1da3 remove "receivednumberat" from blocks 2016-09-15 23:49:50 -07:00
0f9dde0c4e convert event source/value into TD_ID shims 2016-09-15 23:49:14 -07:00
1e0cd48316 updated docs 2016-09-15 11:04:45 -07:00
d959282c68 0.4.11 2016-09-15 10:50:25 -07:00
d513ad7713 Bump pxt-core to 0.4.13 2016-09-15 10:50:23 -07:00
b7da28285e adding stubs for bluetooth functions 2016-09-15 09:40:58 -07:00
dbaf406703 splitted usb transfer instructions 2016-09-15 08:35:01 -07:00
2cb467f22b 0.4.10 2016-09-15 07:26:32 -07:00
9585e2276d Bump pxt-core to 0.4.12 2016-09-15 07:26:29 -07:00
a591d9f072 Release build of Mac client 2016-09-15 09:25:33 +01:00
471a30ca3d Minimise memory usage in Mac app directory watcher 2016-09-15 09:24:09 +01:00
205b94afe8 Launch editor menu item in Mac app 2016-09-15 09:23:48 +01:00
18caf554e9 Use micro:bit image for Mac app icon
I’m continuing to use the same menu bar image, as usually these are black and white on OS X, compared to coloured images being common on the Windows task bar.
2016-09-15 09:17:54 +01:00
67cdf16fe4 Remove redundant values from MainMenu.xib
A small section of this file is still required to build and run the app (it contains metadata that declares that AppDelegate.m is the main implementation, for example).
2016-09-15 08:51:49 +01:00
bdbe8371dd 0.4.9 2016-09-14 22:50:29 -07:00
21a36eb9ee fixing broken image paths 2016-09-14 22:43:59 -07:00
376b20b035 0.4.8 2016-09-14 22:28:23 -07:00
7ce41b52aa fixing path in docs 2016-09-14 22:28:05 -07:00
46f7831e7c 0.4.7 2016-09-14 22:21:00 -07:00
dda29a5cb6 Bump pxt-core to 0.4.11 2016-09-14 22:20:58 -07:00
6e4f4595a2 updated usb images 2016-09-14 22:18:01 -07:00
cdbe1e513b 0.4.6 2016-09-14 20:38:49 -07:00
ae15c9a656 Bump pxt-core to 0.4.9 2016-09-14 20:38:47 -07:00
d993ff3a9d 0.4.5 2016-09-14 11:33:54 -07:00
13785a2438 OS X uploader (#252)
* Source for OS X uploader

* Readme for OS X uploader

* Export image

* .gitignore for Xcode project

* Remove redundant data

* Update readme instructions

* List formatting

* Remove personal copyright notice added by Xcode

* Added release build and updated readme

* point to doc cdn
2016-09-14 11:33:11 -07:00
4dfb77fcd7 0.4.4 2016-09-14 08:16:32 -07:00
70deffb665 Bump pxt-core to 0.4.8 2016-09-14 08:16:29 -07:00
41a148de28 Merge branch 'master' of https://github.com/Microsoft/pxt-microbit 2016-09-14 08:14:41 -07:00
886e071d7f updated about to link to docs 2016-09-14 08:14:04 -07:00
8a58d664c3 adding clear image in stopanimation 2016-09-14 07:54:35 -07:00
71d1155f21 Add file forgotten in 50473255a8 2016-09-14 12:31:52 +03:00
167c1d8fce loading board definition from pxtarget.json 2016-09-13 15:32:12 -07:00
e59ae37954 moving neopixel state to pxt 2016-09-13 13:09:02 -07:00
72a621ec8b mvoing edge connector to pxt 2016-09-13 12:48:07 -07:00
d6ff930333 fix capitalized file names 2016-09-13 10:36:25 -07:00
54a7ac81ea Recommended browser documentation (#251)
* Documentation page for unsupported browsers

* Update unsupported documentation with mac info

* Blur irrelevant information in version screenshots

* Rename to Peli's suggested path

* Browser recommendation for each platform
2016-09-13 10:33:06 -07:00
e5d985dbf1 moving boardhost to pxt 2016-09-13 09:59:34 -07:00
9db91d89d6 refactor part global lists 2016-09-13 09:44:58 -07:00
1fa9bf12d5 refactoring dalboard 2016-09-12 21:29:55 -07:00
61bab257eb 0.4.3 2016-09-12 11:45:22 -07:00
2e90b351da updated other download picture 2016-09-12 11:33:16 -07:00
801bd6c7a0 udpated download pictures 2016-09-12 11:30:12 -07:00
777ba40899 0.4.2 2016-09-12 11:19:41 -07:00
0d11c16ecf Bump pxt-core to 0.4.3 2016-09-12 11:19:39 -07:00
9c1628b977 Merge branch 'master' of https://github.com/Microsoft/pxt-microbit 2016-09-12 11:11:12 -07:00
953b362b34 Download instructions (#250)
* Images of micro:bit attached t ostuff

* Cropped and enhanced USB images

* Define paths for USB images

* Added new matching criteria for images

* Help URL

* Add paths for all images

* Cropped images so they look better on dialog

* Add link to uploader
2016-09-12 11:10:30 -07:00
8b40850a94 tweaks to neopixel rendering 2016-09-11 21:55:54 -07:00
fc3a02cc41 0.4.1 2016-09-11 18:07:11 +01:00
80f2ff6757 Bump to 0.4 to match pxt-core 2016-09-11 18:07:05 +01:00
6f790d167c 0.3.89 2016-09-11 18:06:20 +01:00
ac7502074a Bump pxt-core to 0.4.2 2016-09-11 18:06:20 +01:00
50473255a8 Utylize the new target.css file 2016-09-11 17:51:41 +01:00
910772d54e refacotring various simulator features into pxt 2016-09-09 22:56:26 -07:00
33f12f9ecc 0.3.88 2016-09-09 16:41:31 -07:00
01fa4ef53a Bump pxt-core to 0.3.102 2016-09-09 16:41:14 -07:00
3858b0a0a0 moving wiring to pxt 2016-09-09 15:01:29 -07:00
da30afb121 Merge branch 'master' of https://github.com/Microsoft/pxt-microbit 2016-09-09 13:43:45 -07:00
086bcf372f remove dependencies on dal.d.ts 2016-09-09 13:43:41 -07:00
236e7337e2 0.3.87 2016-09-09 20:49:21 +01:00
4cf223271f Bump pxt-core to 0.3.100 2016-09-09 20:49:21 +01:00
10180f4729 Merge branch 'master' of github.com:Microsoft/pxt-microbit 2016-09-09 20:49:19 +01:00
618dd33221 No longer used 2016-09-09 20:33:11 +01:00
7356e5e52e New index.html expansion 2016-09-09 20:26:18 +01:00
a59d148eb5 0.3.86 2016-09-09 12:23:25 -07:00
34ce687bbd Bump pxt-core to 0.3.98 2016-09-09 12:23:24 -07:00
5e241ed566 Use new doc templates 2016-09-09 20:19:52 +01:00
dcb2b21e66 removing dal dependency 2016-09-09 11:36:36 -07:00
95669e174a Merge branch 'master' of https://github.com/Microsoft/pxt-microbit 2016-09-09 09:59:21 -07:00
aca7d6113d enable streams in pxtarget 2016-09-09 09:59:07 -07:00
ef4b06a087 Merge branch 'master' of https://github.com/Microsoft/pxt-microbit 2016-09-09 15:19:58 +01:00
afa69c23c4 0.3.85 2016-09-09 11:35:45 +01:00
8229e71d0a Bump pxt-core to 0.3.97 2016-09-09 11:35:45 +01:00
93770e5821 Merge branch 'master' of github.com:Microsoft/pxt-microbit 2016-09-09 10:17:35 +01:00
cb8e28beb0 Bump pxt-microbit-core to 0.5.0 2016-09-09 10:17:28 +01:00
8c7e6055ff enabling parts in target 2016-09-09 01:39:52 -07:00
8450db55ac 0.3.84 2016-09-09 01:25:28 -07:00
c63e2c85f1 new part definitions (#247)
* working on new part definitions

* draft of new part definitions

* updates comments

* starting new allocator

* starting from the old allocator

* alloc internals renaming

* alloc minor renaming

* alloc internal renaming

* progress on new parts definition

* progress on new part defs allocator

* refactors BBLoc; progress on new allocator

* more progress on new allocator

* finishing new allocator

* deleting old allocator

* moves new allocator and part definitions

* porting to new part definitions

* refactors instructions for new definitions

* debugging new allocator

* fixes ground and power wire colros

* fixing new part definition bugs

* fixes wire end offsets; fixes NeoPixel placement

* fixes colorGroup issue

* fixes led matrix wiring

* naming tweaks

* fixes instructions regressions

* typo
2016-09-09 01:23:39 -07:00
d8fc11a688 0.3.83 2016-09-09 01:20:45 -07:00
847a29848d Bump pxt-core to 0.3.96 2016-09-09 01:20:43 -07:00
39f4372ee5 0.3.82 2016-09-08 23:39:26 -07:00
a8bbbea8ed Bump pxt-core to 0.3.95 2016-09-08 23:39:24 -07:00
91a8d05e45 updated loc strings 2016-09-08 23:11:58 -07:00
3ecedd3a32 0.3.81 2016-09-08 01:02:46 -07:00
b6390d77dd Bump pxt-core to 0.3.94 2016-09-08 01:02:40 -07:00
e8f9e0f023 lighter rendering of breadboard in grayed 2016-09-08 00:54:19 -07:00
2bacb58fdd simpler instructions 2016-09-08 00:46:43 -07:00
af8babfea2 Merge branch 'master' of https://github.com/Microsoft/pxt-microbit 2016-09-08 00:03:33 -07:00
1ee6274100 added raspberry-pi instructions 2016-09-08 00:00:07 -07:00
7448db5b98 makes instruction panels inline-block 2016-09-07 15:00:42 -07:00
983645403b 0.3.80 2016-09-07 11:49:41 -07:00
7a9f382bee Merge pull request #240 from Microsoft/neopixel-improvement
improves neopixel simulator
2016-09-07 11:22:40 -07:00
e59fd8469b improves neopixel simulator 2016-09-07 10:58:44 -07:00
008c886de9 0.3.79 2016-09-07 16:51:08 +01:00
c87fa30738 Bump pxt-core to 0.3.93 2016-09-07 16:51:08 +01:00
dd9d1299fa Merge branch 'master' of github.com:Microsoft/pxt-microbit 2016-09-07 16:27:42 +01:00
6a7d1bd95c Support for object literals
bump pxt-microbit-core to 0.4.4
see https://github.com/Microsoft/pxt/issues/287
2016-09-07 16:27:28 +01:00
dfe270d259 Correct filename of data.csv in radio challenge 2016-09-07 11:32:41 +01:00
6deb0683b6 Add GitHub URL property 2016-09-07 10:33:36 +01:00
119 changed files with 2582 additions and 3609 deletions

2
clients/electron/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
projects

View File

@ -0,0 +1,5 @@
# PXT micro:bit Electron app
A very basic wrapper around the web app. To install, copy the contents of this
directory to somewhere outside the main `pxt-microbit` repository. Then run `npm
install && npm start`.

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>code the micro:bit</title>
</head>
<body>
<webview id="webview" style="position:absolute; left:0; top:0; right:0; bottom:0"/>
<script>
const webview = document.getElementById("webview")
const url = `http://localhost:3232/${window.location.hash}`
webview.src = url
</script>
</body>
</html>

View File

@ -1,67 +1,39 @@
const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow
// pxt toolchain
const {app, BrowserWindow, Menu} = require('electron')
const pxt = require('pxt-core')
const path = require('path')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
let win
function createWindow() {
console.log('starting app...')
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800, height: 600,
webPreferences: {
nodeIntegration: false,
}
const cliPath = path.join(process.cwd(), "node_modules/pxt-microbit")
function startServerAndCreateWindow() {
pxt.mainCli(cliPath, ["serve", "-no-browser"])
createWindow()
}
function createWindow () {
win = new BrowserWindow({
width: 800,
height: 600,
title: "code the micro:bit"
})
ts.pxt.Util.debug = true;
pxt.mainCli("C:/gh/pxt-microbit/clients/electron/node_modules/pxt-microbit", ["serve", "-just"]);
// no menu
mainWindow.setMenu(null);
// and load the index.html of the app.
mainWindow.loadURL(`http://localhost:3232/#local_token=08ba9b8f-6ccb-4202-296d-28fac7a553d9`)
// Open the DevTools.
mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
Menu.setApplicationMenu(null)
win.loadURL(`file://${__dirname}/index.html#local_token=${pxt.globalConfig.localToken}`)
win.on('closed', () => {
win = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
app.on('ready', startServerAndCreateWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
app.on('activate', () => {
if (win === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@ -1,19 +1,14 @@
{
"name": "codethemicrobit",
"version": "0.1.0",
"description": "A Blocks / JavaScript editor for the micro:bit",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"name" : "code-the-microbit",
"version" : "1.0.0",
"description": "Blocks / Javascript editor",
"author": "Microsoft",
"license": "MIT",
"devDependencies": {
"electron-prebuilt": "^1.2.0"
"main" : "main.js",
"scripts": {
"start": "node_modules/.bin/electron ."
},
"dependencies": {
"typescript": "1.8.7",
"pxt-core": "*",
"pxt-microbit": "*"
"devDependencies": {
"electron": "*",
"pxt-microbit": "*"
}
}
}

137
clients/macuploader/.gitignore vendored Normal file
View File

@ -0,0 +1,137 @@
# Created by https://www.gitignore.io/api/osx,xcode,objective-c,vim
### OSX ###
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Xcode ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint
### Objective-C ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xcuserstate
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/
### Objective-C Patch ###
*.xcscmblueprint
### Vim ###
# swap
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
# session
Session.vim
# temporary
.netrwhist
*~
# auto-generated tag files
tags

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

View File

@ -0,0 +1,307 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
E93040071D895D1F00D931CA /* DirectoryWatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = E93040061D895D1F00D931CA /* DirectoryWatcher.m */; };
E930400A1D89620900D931CA /* Uploader.m in Sources */ = {isa = PBXBuildFile; fileRef = E93040091D89620900D931CA /* Uploader.m */; };
E9F4FEE21D8709980071D783 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E9F4FEE11D8709980071D783 /* AppDelegate.m */; };
E9F4FEE51D8709980071D783 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E9F4FEE41D8709980071D783 /* main.m */; };
E9F4FEE71D8709980071D783 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E9F4FEE61D8709980071D783 /* Assets.xcassets */; };
E9F4FEEA1D8709980071D783 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9F4FEE81D8709980071D783 /* MainMenu.xib */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
E93040051D895D1F00D931CA /* DirectoryWatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryWatcher.h; sourceTree = "<group>"; };
E93040061D895D1F00D931CA /* DirectoryWatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DirectoryWatcher.m; sourceTree = "<group>"; };
E93040081D89620900D931CA /* Uploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uploader.h; sourceTree = "<group>"; };
E93040091D89620900D931CA /* Uploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Uploader.m; sourceTree = "<group>"; };
E9F4FEDD1D8709980071D783 /* Microbit Uploader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Microbit Uploader.app"; sourceTree = BUILT_PRODUCTS_DIR; };
E9F4FEE01D8709980071D783 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
E9F4FEE11D8709980071D783 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
E9F4FEE41D8709980071D783 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
E9F4FEE61D8709980071D783 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
E9F4FEE91D8709980071D783 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
E9F4FEEB1D8709980071D783 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
E9F4FEDA1D8709980071D783 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
E9F4FED41D8709980071D783 = {
isa = PBXGroup;
children = (
E9F4FEDF1D8709980071D783 /* Microbit Uploader */,
E9F4FEDE1D8709980071D783 /* Products */,
);
sourceTree = "<group>";
};
E9F4FEDE1D8709980071D783 /* Products */ = {
isa = PBXGroup;
children = (
E9F4FEDD1D8709980071D783 /* Microbit Uploader.app */,
);
name = Products;
sourceTree = "<group>";
};
E9F4FEDF1D8709980071D783 /* Microbit Uploader */ = {
isa = PBXGroup;
children = (
E9F4FEE01D8709980071D783 /* AppDelegate.h */,
E9F4FEE11D8709980071D783 /* AppDelegate.m */,
E9F4FEE61D8709980071D783 /* Assets.xcassets */,
E9F4FEE81D8709980071D783 /* MainMenu.xib */,
E9F4FEEB1D8709980071D783 /* Info.plist */,
E9F4FEE31D8709980071D783 /* Supporting Files */,
E93040051D895D1F00D931CA /* DirectoryWatcher.h */,
E93040061D895D1F00D931CA /* DirectoryWatcher.m */,
E93040081D89620900D931CA /* Uploader.h */,
E93040091D89620900D931CA /* Uploader.m */,
);
path = "Microbit Uploader";
sourceTree = "<group>";
};
E9F4FEE31D8709980071D783 /* Supporting Files */ = {
isa = PBXGroup;
children = (
E9F4FEE41D8709980071D783 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
E9F4FEDC1D8709980071D783 /* Microbit Uploader */ = {
isa = PBXNativeTarget;
buildConfigurationList = E9F4FEEE1D8709980071D783 /* Build configuration list for PBXNativeTarget "Microbit Uploader" */;
buildPhases = (
E9F4FED91D8709980071D783 /* Sources */,
E9F4FEDA1D8709980071D783 /* Frameworks */,
E9F4FEDB1D8709980071D783 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "Microbit Uploader";
productName = "Microbit Uploader";
productReference = E9F4FEDD1D8709980071D783 /* Microbit Uploader.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
E9F4FED51D8709980071D783 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = thomasdenney;
TargetAttributes = {
E9F4FEDC1D8709980071D783 = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = E9F4FED81D8709980071D783 /* Build configuration list for PBXProject "Microbit Uploader" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = E9F4FED41D8709980071D783;
productRefGroup = E9F4FEDE1D8709980071D783 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
E9F4FEDC1D8709980071D783 /* Microbit Uploader */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
E9F4FEDB1D8709980071D783 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E9F4FEE71D8709980071D783 /* Assets.xcassets in Resources */,
E9F4FEEA1D8709980071D783 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
E9F4FED91D8709980071D783 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E9F4FEE51D8709980071D783 /* main.m in Sources */,
E930400A1D89620900D931CA /* Uploader.m in Sources */,
E9F4FEE21D8709980071D783 /* AppDelegate.m in Sources */,
E93040071D895D1F00D931CA /* DirectoryWatcher.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
E9F4FEE81D8709980071D783 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
E9F4FEE91D8709980071D783 /* Base */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
E9F4FEEC1D8709980071D783 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
E9F4FEED1D8709980071D783 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
E9F4FEEF1D8709980071D783 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "Microbit Uploader/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.thomasdenney.Microbit-Uploader";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
E9F4FEF01D8709980071D783 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "Microbit Uploader/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.thomasdenney.Microbit-Uploader";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
E9F4FED81D8709980071D783 /* Build configuration list for PBXProject "Microbit Uploader" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E9F4FEEC1D8709980071D783 /* Debug */,
E9F4FEED1D8709980071D783 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
E9F4FEEE1D8709980071D783 /* Build configuration list for PBXNativeTarget "Microbit Uploader" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E9F4FEEF1D8709980071D783 /* Debug */,
E9F4FEF01D8709980071D783 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = E9F4FED51D8709980071D783 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Microbit Uploader.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,6 @@
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end

View File

@ -0,0 +1,130 @@
#import "AppDelegate.h"
#import "DirectoryWatcher.h"
#import "Uploader.h"
@interface AppDelegate ()<DirectoryWatcherDelegate, UploaderDelegate, NSUserNotificationCenterDelegate>
@property DirectoryWatcher * watcher;
@property Uploader * uploader;
@property NSStatusItem * menubarItem;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
self.watcher = [[DirectoryWatcher alloc] initWithPath:[self downloadsDirectory]];
self.watcher.delegate = self;
[self.watcher startWatching];
self.uploader = [[Uploader alloc] init];
self.uploader.delegate = self;
[NSUserNotificationCenter defaultUserNotificationCenter].delegate = self;
[self createMenuBarIcon];
[self configureVolumeMountNotifications];
[self showActiveMicroBits];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
[self.watcher stopWatching];
}
- (void)dealloc {
[[NSWorkspace sharedWorkspace].notificationCenter removeObserver:self];
}
#pragma mark - Directory
- (void)watcher:(DirectoryWatcher *)watcher observedNewFileAtPath:(NSString *)path {
NSString * fullPath = [watcher.path stringByAppendingPathComponent:path];
if ([self.uploader shouldUploadFileAtPath:fullPath]) {
[self.uploader uploadFile:fullPath];
}
}
- (NSString*)downloadsDirectory {
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES);
return paths.firstObject;
}
#pragma mark - Uploader delegate
- (void)uploader:(Uploader *)uploader transferredFile:(NSString *)file toMicroBit:(NSString *)microbit {
[self showNotification:@"micro:bit upload" withDescription:[NSString stringWithFormat:@"%@ uploaded to %@", file.lastPathComponent, microbit]];
}
- (void)uploader:(Uploader *)uploader failedToTransferFile:(NSString *)file toMicroBit:(NSString *)microbit {
[self showNotification:@"micro:bit upload failed" withDescription:[NSString stringWithFormat:@"Couldn't transfer %@ to %@", file.lastPathComponent, microbit]];
}
- (void)showNotification:(NSString*)title withDescription:(NSString*)description {
NSUserNotification * notification = [NSUserNotification new];
notification.title = title;
notification.informativeText = description;
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
#pragma mark - NSUserNotificationCenterDelegate
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification {
return YES;
}
#pragma mark - Volume mount/unmount notification
- (void)configureVolumeMountNotifications {
[[NSWorkspace sharedWorkspace].notificationCenter addObserver:self selector:@selector(volumeMountNotification:) name:NSWorkspaceDidRenameVolumeNotification object:nil];
[[NSWorkspace sharedWorkspace].notificationCenter addObserver:self selector:@selector(volumeMountNotification:) name:NSWorkspaceDidMountNotification object:nil];
[[NSWorkspace sharedWorkspace].notificationCenter addObserver:self selector:@selector(volumeMountNotification:) name:NSWorkspaceDidUnmountNotification object:nil];
}
- (void)volumeMountNotification:(NSNotification*)sender {
//Delay upadting the menu to give the chance for the disk to fully mount or unmount
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self showActiveMicroBits];
});
}
#pragma mark - Menu bar app
- (void)createMenuBarIcon {
self.menubarItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
self.menubarItem.button.image = [NSImage imageNamed:@"menubar"];
}
- (void)showActiveMicroBits {
NSMenu * menu = [NSMenu new];
NSString * countString;
NSUInteger count = self.uploader.microBitPaths.count;
if (count == 0) {
countString = @"No connect micro:bits";
}
else if (count == 1) {
countString = @"1 connected micro:bit";
}
else {
countString = [NSString stringWithFormat:@"%lu connected micro:bits", count];
}
NSMenuItem * microBitCount = [[NSMenuItem alloc] initWithTitle:countString action:nil keyEquivalent:@""];
microBitCount.enabled = NO;
[menu addItem:microBitCount];
NSMenuItem * websiteItem = [[NSMenuItem alloc] initWithTitle:@"Editor" action:@selector(launchEditor:) keyEquivalent:@"e"];
[menu addItem:websiteItem];
NSMenuItem * quitItem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
[menu addItem:quitItem];
self.menubarItem.menu = menu;
}
- (void)launchEditor:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://codethemicrobit.com/"]];
}
@end

View File

@ -0,0 +1,68 @@
{
"images" : [
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "icon_16x16.png",
"scale" : "1x"
},
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "icon_16x16@2x.png",
"scale" : "2x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "icon_32x32.png",
"scale" : "1x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "icon_32x32@2x.png",
"scale" : "2x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "icon_128x128.png",
"scale" : "1x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "icon_128x128@2x.png",
"scale" : "2x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "icon_256x256.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "icon_256x256@2x.png",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "icon_512x512.png",
"scale" : "1x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "icon_512x512@2x.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"idiom" : "mac",
"filename" : "menubar.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
</objects>
</document>

View File

@ -0,0 +1,24 @@
#import <Foundation/Foundation.h>
@class DirectoryWatcher;
@protocol DirectoryWatcherDelegate <NSObject>
- (void)watcher:(DirectoryWatcher*)watcher observedNewFileAtPath:(NSString*)path;
@end
@interface DirectoryWatcher : NSObject
- (instancetype)initWithPath:(NSString*)path;
@property (readonly) NSString * path;
@property id<DirectoryWatcherDelegate> delegate;
- (void)startWatching;
//Automatically called when deallocated
- (void)stopWatching;
@end

View File

@ -0,0 +1,75 @@
#import "DirectoryWatcher.h"
#import <CoreServices/CoreServices.h>
void callback(ConstFSEventStreamRef streamRef, void * info, size_t numEvents, void * eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]);
@interface DirectoryWatcher ()
@property NSString * path;
@property NSMutableSet<NSString*>* knownFiles;
@property FSEventStreamRef stream;
- (void)rescanPathWithEvents:(BOOL)sendEvents;
@end
@implementation DirectoryWatcher
- (instancetype)initWithPath:(NSString *)path {
if (!path) {
return nil;
}
self = [super init];
if (self) {
self.path = path;
}
return self;
}
- (void)dealloc {
[self stopWatching];
}
- (void)startWatching {
self.knownFiles = [NSMutableSet new];
[self rescanPathWithEvents:NO];
CFStringRef path = (__bridge CFStringRef)(self.path);
CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void**)&path, 1, NULL);
CFAbsoluteTime latency = 1;
FSEventStreamContext context = { 0, (__bridge void * _Nullable)(self), NULL, NULL, NULL };
self.stream = FSEventStreamCreate(NULL, &callback, &context, pathsToWatch, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagNone);
FSEventStreamScheduleWithRunLoop(self.stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(self.stream);
}
- (void)stopWatching {
if (self.stream) {
FSEventStreamStop(self.stream);
FSEventStreamInvalidate(self.stream);
FSEventStreamRelease(self.stream);
self.stream = nil;
}
}
- (void)rescanPathWithEvents:(BOOL)sendEvents {
NSArray<NSString*>* downloadFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.path error:nil];
NSMutableSet<NSString*>* fullSet = [NSMutableSet new];
for (NSString * file in downloadFiles) {
[fullSet addObject:file];
if (![self.knownFiles containsObject:file]) {
if (sendEvents) {
[self.delegate watcher:self observedNewFileAtPath:file];
}
}
}
self.knownFiles = fullSet;
}
@end
void callback(ConstFSEventStreamRef streamRef, void * info, size_t numEvents, void * eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) {
DirectoryWatcher * watcher = (__bridge DirectoryWatcher*)info;
[watcher rescanPathWithEvents:YES];
}

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.01</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>2</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Thomas Denney. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -0,0 +1,21 @@
#import <Foundation/Foundation.h>
@class Uploader;
@protocol UploaderDelegate <NSObject>
- (void)uploader:(Uploader*)uploader transferredFile:(NSString*)file toMicroBit:(NSString*)microbit;
- (void)uploader:(Uploader*)uploader failedToTransferFile:(NSString*)file toMicroBit:(NSString*)microbit;
@end
@interface Uploader : NSObject
@property id<UploaderDelegate> delegate;
- (BOOL)shouldUploadFileAtPath:(NSString*)path;
- (NSArray<NSString*>*)microBitPaths;
- (void)uploadFile:(NSString*)file;
- (void)uploadFile:(NSString*)file toMicroBit:(NSString*)path;
@end

View File

@ -0,0 +1,74 @@
#import "Uploader.h"
@interface Uploader ()
@property NSOperationQueue * backgroundCopyQueue;
@end
@implementation Uploader
- (instancetype)init {
self = [super init];
if (self) {
self.backgroundCopyQueue = [NSOperationQueue new];
}
return self;
}
- (BOOL)shouldUploadFileAtPath:(NSString *)path {
//Whilst Safari is downloading the file it appends .download to the name
NSRegularExpression * ignoreDownload = [NSRegularExpression regularExpressionWithPattern:@".download$" options:NSRegularExpressionCaseInsensitive error:nil];
if ([ignoreDownload numberOfMatchesInString:path.lastPathComponent options:0 range:NSMakeRange(0, path.lastPathComponent.length)] > 0) {
return NO;
}
//Chrome and Firefox create .hex files
NSRegularExpression * hexFiles = [NSRegularExpression regularExpressionWithPattern:@".hex$" options:NSRegularExpressionCaseInsensitive error:nil];
if ([hexFiles numberOfMatchesInString:path.lastPathComponent options:0 range:NSMakeRange(0, path.lastPathComponent.length)] > 0) {
return YES;
}
//Safari tends to just name files 'Unknown X'
NSRegularExpression * unknownFiles = [NSRegularExpression regularExpressionWithPattern:@"^Unknown(( |-)[0-9]+)?" options:NSRegularExpressionCaseInsensitive error:nil];
if ([unknownFiles numberOfMatchesInString:path.lastPathComponent options:0 range:NSMakeRange(0, path.lastPathComponent.length)]) {
return YES;
}
return NO;
}
- (NSArray<NSString*>*)microBitPaths {
NSArray<NSURL*>* allVolumes = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:nil options:NSVolumeEnumerationSkipHiddenVolumes];
NSMutableArray<NSString*>* microbitPaths = [NSMutableArray new];
NSRegularExpression * microbitRegex = [NSRegularExpression regularExpressionWithPattern:@"^MICROBIT" options:NSRegularExpressionCaseInsensitive error:nil];
for (NSURL * volume in allVolumes) {
NSString * lastPathComponent = volume.lastPathComponent;
if ([microbitRegex numberOfMatchesInString:lastPathComponent options:0 range:NSMakeRange(0, lastPathComponent.length)] > 0) {
[microbitPaths addObject:volume.path];
}
}
return microbitPaths;
}
- (void)uploadFile:(NSString *)file {
for (NSString * microbit in [self microBitPaths]) {
[self uploadFile:file toMicroBit:microbit];
}
}
- (void)uploadFile:(NSString *)file toMicroBit:(NSString *)path {
[self.backgroundCopyQueue addOperationWithBlock:^{
NSError * copyError;
NSString * destination = [path stringByAppendingPathComponent:file.lastPathComponent];
if (![[NSFileManager defaultManager] copyItemAtPath:file toPath:destination error:&copyError]) {
[self.delegate uploader:self failedToTransferFile:file toMicroBit:path.lastPathComponent];
}
else {
[self.delegate uploader:self transferredFile:file toMicroBit:path.lastPathComponent];
}
}];
}
@end

View File

@ -0,0 +1,5 @@
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
return NSApplicationMain(argc, argv);
}

View File

@ -0,0 +1,40 @@
# micro:bit uploader for OS X
![](Microbit Uploader/Assets.xcassets/AppIcon.appiconset/icon_256x256.png)
This project is a clone of the [Windows
uploader](https://codethemicrobit.com/uploader), but for OS X. Once launched,
the app runs in your menu bar and will automatically deploy any HEX files to
your `micro:bit`. Like the Windows version, it is compatible with any browser
that can run [codethemicrobit.com](http://codethemicrobit.com).
## Install the built version
1. Download the latest `.zip` release from the `Release` directory
2. Unzip it
3. Drag `Microbit Uploader` to your Applications folder and launch it
## Building
To build the project you'll need a copy of OS X 10.11 or higher and Xcode 8 or
higher (you may be able to build on earlier OSes or versions of Xcode, but this
remains untested). Once you have a development environment set up, just build
and run `Microbit Uploader.xcodeproj`.
## Distributing
1. Open the Xcode project
2. Product > Archive
3. Export:
![Export](Graphics/export.png)
4. You will then have the option of either signing or not-signing the
application:
a) If you have an Apple developer account, select 'Export a Developer
ID-signed Application'
b) If you don't have a developer ID, select 'Export as a macOS App'
5. Zip the produced app and upload to CDN or equivalent

Binary file not shown.

View File

@ -19,10 +19,3 @@
<link rel="shortcut icon" href="@appLogo@">
<meta name="theme-color" content="@accentColor@">
<style>
#root .avatar .avatar-image {
background-image: url(https://az851932.vo.msecnd.net/pub/jovrytni/microbit.simplified.svg);
background-size: contain;
background-repeat: no-repeat;
}
</style>

5
docfiles/target.css Normal file
View File

@ -0,0 +1,5 @@
#root .avatar .avatar-image {
background-image: url(https://az851932.vo.msecnd.net/pub/jovrytni/microbit.simplified.svg);
background-size: contain;
background-repeat: no-repeat;
}

13
docfiles/tracking.html Normal file
View File

@ -0,0 +1,13 @@
<script type="text/javascript">
var appInsights=window.appInsights||function(config){
function r(config){t[config]=function(){var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}var t={config:config},u=document,e=window,o="script",s=u.createElement(o),i,f;for(s.src=config.url||"//az416426.vo.msecnd.net/scripts/a/ai.0.js",u.getElementsByTagName(o)[0].parentNode.appendChild(s),t.cookie=u.cookie,t.queue=[],i=["Event","Exception","Metric","PageView","Trace"];i.length;)r("track"+i.pop());return r("setAuthenticatedUserContext"),r("clearAuthenticatedUserContext"),config.disableExceptionTracking||(i="onerror",r("_"+i),f=e[i],e[i]=function(config,r,u,e,o){var s=f&&f(config,r,u,e,o);return s!==!0&&t["_"+i](config,r,u,e,o),s}),t
}({
instrumentationKey:"e9ae05ca-350b-427a-9775-3ba3f6efabce"
});window.appInsights=appInsights;
</script>
<script type="text/javascript">
(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config reset people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" ");
for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,e,d])};b.__SV=1.2;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"===e.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f)}})(document,window.mixpanel||[]);
mixpanel.init("762fef19c053a0ea4cec43d2fecae76e");
</script>

View File

@ -1,3 +1,50 @@
![](/static/mb/device/pano.jpg)
# About
### @description A Blocks / Javascript code editor for the micro:bit, a pocket-size computer with 5x5 display, sensors and Bluetooth.
The [BBC micro:bit](https://www.microbit.co.uk) is a [pocket-size computer](/device) with a 5x5 display of 25 LEDs, Bluetooth and sensors that can be programmed by anyone.
The BBC micro:bit was made possible by many [partners](https://www.microbit.co.uk/partners).
The micro:bit provides an easy and fun introduction to programming and making switch on, program it to do something fun wear it, customize it.
Just like Arduino, the micro:bit can be connected to and interact with sensors, displays, and other devices.
* [Read the docs](/docs)
## [Hardware: The Device](/device)
The BBC micro:bit is packaged with sensors, radio and other goodies. Learn about the [hardware components](/device) of the micro:bit to make the most of it!
## Programming: [Blocks](/blocks) or [JavaScript](/javascript)
You can program the micro:bit using [Blocks](/blocks) or [JavaScript](/javascript) in your web browser via the [micro:bit APIs](/reference):
```block
input.onButtonPressed(Button.A, () => {
basic.showString("Hi!");
})
```
```typescript
input.onButtonPressed(Button.A, () => {
basic.showString("Hi!");
})
```
The editor work in [most modern browsers](/browsers), work [offline](/offline) once loaded and do not require any installation.
## [Compile and Flash: Your Program!](/device/usb)
When you have your code ready, you connect your micro:bit to a computer via a USB cable, so it appears as a mounted drive (named MICROBIT).
Compilation to ARM thumb machine code from [Blocks](/blocks) or [JavaScript](/javascript) happens in the browser. You save the ARM binary
program to a file, which you then copy to the micro:bit drive, which flashes the micro:bit device with the new program.
## Simulator: Test Your Code
You can run your code using the micro:bit simulator, all within the confines of a web browser.
The simulator has support for the LED screen, buttons, as well as compass, accelerometer, and digital I/O pins.
```sim
basic.forever(() => {
basic.showString("Hi!");
@ -20,43 +67,8 @@ input.onButtonPressed(Button.B, () => {
. # . # .
. . # . .`);
});
```
# About
### @description A Blocks / Javascript code editor for the micro:bit, a pocket-size computer with 5x5 display, sensors and Bluetooth.
The [BBC micro:bit](https://www.microbit.co.uk) is a [pocket-size computer](/device) with a 5x5 display of 25 LEDs, Bluetooth and sensors that can be programmed by anyone.
The BBC micro:bit was made possible by many [partners](https://www.microbit.co.uk/partners).
The micro:bit provides an easy and fun introduction to programming and making switch on, program it to do something fun wear it, customize it.
Just like Arduino, the micro:bit can be connected to and interact with sensors, displays, and other devices.
## Hardware: The Device
Learn about the [hardware components](/device) of the micro:bit to make the most of it!
## Programming: Blocks or JavaScript
You can program the micro:bit using [Blocks](/blocks) or [JavaScript](/javascript), via the [micro:bit APIs](/reference):
```blocks
input.onButtonPressed(Button.A, () => {
basic.showString("Hi!");
})
```
## Compile and Flash: Your Program!
When you have your code ready, you connect your micro:bit to a computer via a USB cable, so it appears as a mounted drive (named MICROBIT).
Compilation to ARM thumb machine code from [Blocks](/blocks) or [JavaScript](/javascript) happens in the browser. You save the ARM binary
program to a file, which you then copy to the micro:bit drive, which flashes the micro:bit device with the new program.
## Simulator: Test Your Code
You can run your code using the micro:bit simulator, all within the confines of a web browser.
The simulator has support for the LED screen, buttons, as well as compass, accelerometer, and digital I/O pins.
## C++ Runtime
The [C++ micro:bit runtime](http://lancaster-university.github.io/microbit-docs/), created at [Lancaster University](http://www.lancaster.ac.uk/), provides access to the hardware functions of the micro:bit,
@ -65,6 +77,15 @@ as well as a set of helper functions (such as displaying a number/image/string o
The [micro:bit library](/reference) mirrors the functions of the C++ library.
When code is compiled to ARM machine code, the calls to JavaScript micro:bit functions are replaced with calls to the corresponding C++ functions.
## Open Source
## [Command Line Tools](/cli)
Looking to use codethemicrobit.com in your favorite editor? Install the [command line tools](/cli) and get rolling!
## [Packages](/packages)
Create, edit and distribute your own blocks and JavaScript using [packages](/packages). Packages are hosted on GitHub and may be written
using C++, JavaScript and/or ARM thumb.
## [Open Source](/open-source)
The code for the micro:bit is [open source](/open-source) on GitHub. Contributors are welcome!

104
docs/browsers.md Normal file
View File

@ -0,0 +1,104 @@
# Unsupported configuration
[codethemicrobit.com](https://codethemicrobit.com) doesn't currently support
your browser or operating system. The following configurations are supported:
## Windows
You need one of these browsers running on Windows 7, Windows 8, Windows 8.1, or
Windows 10:
* Internet Explorer 11
* Microsoft Edge
* Google Chrome
* Mozilla Firefox
## Mac
You need one of these browsers running on OS X 10.9 Mavericks, OS X 10.10
Yosemite, OS X 10.11 El Capitan, or macOS 10.12 Sierra:
* Safari
* Google Chrome
* Mozilla Firefox
## Linux
If you're using a Raspberry Pi, please see [the documentation
here](/raspberry-pi).
You need to be running a Linux distribution recent enough to run the most recent
version of one of the following:
* Google Chrome, or Chromium
* Mozilla Firefox, Iceweasel, or Seamonkey
## How to check your OS or browser
### Windows
* Click on the Start menu
* Type 'System'
* Click on the app called 'System'
* The version of Windows you are using will be displayed:
![](/static/configurations/windows-version.png)
### Mac
* Click on the Apple icon in the top left
* Click on 'About this Mac'
* This window will be displayed:
![](/static/configurations/osx-version.png)
### Internet Explorer
* Click on the Settings icon in the top right
* Click 'About Internet Explorer'
* This window will be displayed:
![](/static/configurations/ie-version.png)
### Edge
Edge automatically updates, so you should always be using the latest version
* Click on the menu icon in the top right (three dots)
* Scroll to the bottom
* Information similar to the following will be displayed:
![](/static/configurations/edge-version.png)
### Google Chrome
Google Chrome automatically updates, so you should always be using the latest version
* Click on the menu icon in the top right (three dots)
* Click Help, and About Google Chrome
* Information similar to the following will be displayed:
![](/static/configurations/chrome-version.png)
### Firefox
Firefox automatically updates, so you should always be using the latest version
* Click on the menu icon in the top right (three horizontal lines)
* Click the question mark icon (help button)
* Click 'About Firefox'
![](/static/configurations/firefox-version.png)
### Safari
Safari updates when your operating system updates, so if you are using the
latest version of OS X then you'll be using the latest version of Safari.
* Click on the Safari menu in the top left
* Click 'About Safari'
![](/static/configurations/safari-version.png)
IT administrators should check which browser versions are supported
[here](/browsers/technical).

16
docs/browsers/linux.md Normal file
View File

@ -0,0 +1,16 @@
# Recommended browser for Linux
As you are using Linux, it is recommended that you use [Mozilla
Firefox][firefox] or [Google Chrome][chrome].
Please see [here][technical] for technical information on which browsers are
supported, or [here][versions] to check which version you are using.
[edge]: https://www.microsoft.com/en-us/windows/microsoft-edge
[ie]: https://www.microsoft.com/en-us/download/internet-explorer.aspx
[firefox]: https://www.mozilla.org/en-US/firefox/new/
[chrome]: https://www.google.com/chrome/
[opera]: https://www.opera.com
[safari]: http://www.apple.com/safari/
[technical]: /browsers/technical
[versions]: /browsers

16
docs/browsers/mac.md Normal file
View File

@ -0,0 +1,16 @@
# Recommended browser for Mac
As you are using a Mac, it is recommended that you use [Safari][]. Alternatively,
[Google Chrome][chrome] and [Mozilla Firefox][firefox] are also supported.
Please see [here][technical] for technical information on which browsers are
supported, or [here][versions] to check which version you are using.
[edge]: https://www.microsoft.com/en-us/windows/microsoft-edge
[ie]: https://www.microsoft.com/en-us/download/internet-explorer.aspx
[firefox]: https://www.mozilla.org/en-US/firefox/new/
[chrome]: https://www.google.com/chrome/
[opera]: https://www.opera.com
[safari]: http://www.apple.com/safari/
[technical]: /browsers/technical
[versions]: /browsers

View File

@ -0,0 +1,36 @@
# Technical information about browser support
[codethemicrobit.com][] requires that you use a recent version of a modern
browser, such as Microsoft Edge, Google Chrome, Mozilla Firefox, Safari, Opera,
or IE11. This is because the editor uses modern web technologies such as [web
workers][] to enable compiling [TypeScript][] in the browser, or the using the
same [Monaco][] editor that powers [Visual Studio Code][].
[codethemicrobit.com]: https://codethemicrobit.com
[web workers]: http://www.w3.org/TR/workers/
[typescript]: http://www.typescriptlang.org
[monaco]: https://microsoft.github.io/monaco-editor/
[visual studio code]: http://code.visualstudio.com
Most modern browsers automatically update themselves, but in some environments
such as schools these automatic updates are disabled for security. **We
strongly recommend that you use the most recent version of any of these
browsers**, but if you can't then you must use at least:
| Browser | Minimum version | Release date | Windows | Mac |
| ----------------- | --------------- | -------------- | ----------- | ---------- |
| Edge | 12 | March 2015 | Windows 10+ | N/A |
| Internet Explorer | 11 | October 2013 | Windows 7+ | N/A |
| Mozilla Firefox | 31 ESR | July 2014 | Windows XP+ | OS X 10.6+ |
| Google Chrome | 38 | October 2014 | Windows XP+ | OS X 10.6+ |
| Safari | 9 | September 2015 | N/A | OS X 10.9+ |
| Opera | 21 | May 2014 | Windows 7+ | OS X 10.9+ |
Please see our information for which browsers are recommended for [Windows][],
[Mac][], [Linux][], or [Raspberry Pi][].
[Windows]: /browsers/windows
[Mac]: /browsers/mac
[Linux]: /browsers/linux
[Raspberry Pi]: /raspberry-pi

18
docs/browsers/windows.md Normal file
View File

@ -0,0 +1,18 @@
# Recommended browser for Windows
We recommend [Microsoft Edge][edge] if you are running Windows 10, but users on
Windows 7 or higher can use [Internet Explorer 11][ie] or recent versions of
[Mozilla Firefox][firefox], [Google Chrome][chrome], or [Opera][opera].
Please see [here][technical] for technical information on which browsers are
supported, or [here][versions] to check which version you are using.
[edge]: https://www.microsoft.com/en-us/windows/microsoft-edge
[ie]: https://www.microsoft.com/en-us/download/internet-explorer.aspx
[firefox]: https://www.mozilla.org/en-US/firefox/new/
[chrome]: https://www.google.com/chrome/
[opera]: https://www.opera.com
[safari]: http://www.apple.com/safari/
[technical]: /browsers/technical
[versions]: /browsers

View File

@ -1,6 +1,4 @@
# Running programs on your micro:bit
How to compile, transfer, and run a program on your micro:bit.
# Uploading programs on your micro:bit
While you're writing and testing your programs, you'll mostly be [running them
in the simulator](/device/simulator), but once you've finished your program you
@ -12,169 +10,22 @@ The basic steps are:
2. Click **Download** and download the `.hex` file
3. Copy the `.hex` file from your computer onto the micro:bit drive
## Requirements
![](/static/mb/device/usb-thin.jpg)
You need the following things to transfer and run a script on your micro:bit:
## Instructions
* A-Male to Micro USB cable to connect your computer to your micro:bit. This is
the same cable that is commonly used to connect a smart phone to a computer.
* A PC running Windows 7 or later, or a Mac running OS X 10.6 or later
Pick the instructions for your operating system and browser:
## Step 1: Connect your micro:bit to your computer
* [Windows - Microsoft Edge](/device/usb/windows-edge)
* [Windows - Internet Explorer](/device/usb/windows-ie)
* [Windows - Chrome](/device/usb/windows-chrome)
* [Windows - Firefox](/device/usb/windows-firefox)
* [Mac - Safari](/device/usb/mac-safari)
* [Mac - Chrome](/device/usb/mac-chrome)
* [Mac - Firefox](/device/usb/mac-firefox)
First, connect the micro:bit:
### ~hint
1. Connect the small end of the USB cable to the micro USB port on your micro:bit.
2. Connect the other end of the USB cable to a USB port on your computer.
Your computer should recognise your micro:bit as a new drive. On computers
running Windows, `MICROBIT` appears as a drive under Devices and drives. On a Mac
it appears as a new drive under Devices.
**Windows**
![](/static/mb/device/usb-windows-device.jpg)
**Mac**
![](/static/mb/device/usb-osx-device.png)
## Step 2: Download your program
1. Open your project on [codethemicrobit.com](https://codethemicrobit.com)
2. Click **Download**
3. When prompted, choose to **save** the compiled file onto your computer. The
prompt will be different depending on which browser you are using, or
whether you are using a Windows computer or a Mac
### Windows
#### Chrome
Your `.hex` file appears as a download at the bottom of the browser. Click on
the arrow next to the name of the file and then click **Show in folder**.
![](/static/mb/device/usb-windows-chrome.png)
Drag and drop the `.hex` file from the download folder onto the `MICROBIT` drive.
#### Firefox
A window will appear asking whether you want to save or open the `.hex` file.
Select **Save File** and then select **OK**.
![](/static/mb/device/usb-windows-firefox-1.png)
The file will then appear in your downloads in the top right of your browser.
Click the **folder icon** next to the filename to open it in Windows Explorer.
![](/static/mb/device/usb-windows-firefox-2.png)
Drag and drop the `.hex` file from the download folder onto the `MICROBIT` drive.
#### Microsoft Edge
A message will appear at the bottom of the browser asking what you want to do
with the file. Click **Save**:
![](/static/mb/device/usb-windows-edge-1.png)
Then click **Open folder** and drag and drop the file from your Downloads to
your `MICROBIT` drive.
![](/static/mb/device/usb-windows-edge-2.png)
#### Internet Explorer
A message will appear at the bottom of the browser asking what you want to do
with the file. Click **Save**:
![](/static/mb/device/usb-windows-ie11-1.png)
Then click **Open folder** and drag and drop the file from your Downloads to
your `MICROBIT` drive.
![](/static/mb/device/usb-windows-ie11-2.png)
### Mac
#### Safari
When you select **Download** in Safari a file called `Unknown` will be
downloaded into your Downloads folder. Open your Downloads folder and drag and
drop the file onto your `MICROBIT` drive, under Devices:
![](/static/mb/device/usb-osx-dnd.png)
#### Firefox
A dialogue box will appear, asking whether you would like to open or save your
hex file. Select **Save file** and click **OK** and the file will then appear in
your downloads in the top right of your browser. Right click on the file and
click on **Show in Finder** and the file will appear in your downloads folder.
Select the file and drag and drop it onto your `MICROBIT` drive.
![](/static/mb/device/usb-osx-firefox-1.png)
![](/static/mb/device/usb-osx-firefox-2.png)
#### Chrome
When you select **Download** in Chrome, the file will appear at the bottom of
the browser. Click on the small arrow and select **Show in Finder**. This will
show the file in your download folder. Drag and drop the file onto your
`MICROBIT` drive.
![](/static/mb/device/usb-osx-chrome.png)
## Step 3: Transfer the file to your micro:bit
* Once you've found the folder containing your `.hex` file, drag and drop it
onto your `MICROBIT` drive
* If you're using Windows, you can use **Send to** as described below
* The LED on the back of your micro:bit flashes during the transfer (which
should only take a few seconds).
* Once transferred, the code will run automatically on your micro:bit. To rerun
your program, press the reset button on the back of your micro:bit. The reset
button automatically runs the newest file on the micro:bit.
**Send to**: If you're using Windows you use *Send to* in File Explorer:
- In File Explorer, right-click on the hex file (created in Step 2 above), choose **Send to**, and then **MICROBIT**.
![](/static/mb/device/usb-windows-sendto.jpg)
By copying the script onto the `MICROBIT` drive, you have programmed it into the
flash memory on the micro:bit, which means even after you unplug the micro:bit,
your program will still run if the micro:bit is powered by battery.
## Troubleshooting
You cant drag and drop more than one hex file at once onto your micro:bit. If
you try to drag and drop a second hex file onto your micro:bit before the first
file has finished downloading, then the second file may fail in different ways.
When the first program has been written to the micro:bit, the drive will
disengage. If you drag and drop a second file at this point it may not find the
drive and the second write will fail.
The errors may look like this:
**Windows**
![](/static/mb/device/usb-windows-copy-file-error.jpg)
**Mac**
![](/static/mb/device/usb-osx-copy-file-error.png)
Or it may appear that there are two hex files on your micro:bit so the micro:bit
wont be able to run multiple files. To rectify this, unplug your micro:bit and
plug it in again. Make sure that your micro:bit appears as `MICROBIT` and not
`MAINTENANCE`.
### See also
[Run code in a browser](/device/simulator)
Transfer not working? See some [troubleshooting tips](/device/usb/troubleshooting).
### ~

View File

@ -0,0 +1,69 @@
# Uploading from Chrome for Mac
While you're writing and testing your programs, you'll mostly be [running them
in the simulator](/device/simulator), but once you've finished your program you
can **compile** it and run it on your micro:bit.
The basic steps are:
1. Connect your micro:bit to your computer via USB
2. Click **Download** and download the `.hex` file
3. Copy the `.hex` file from your computer onto the micro:bit drive
## Requirements
You need the following things to transfer and run a script on your micro:bit:
* A-Male to Micro USB cable to connect your computer to your micro:bit. This is
the same cable that is commonly used to connect a smart phone to a computer.
* A PC running Windows 7 or later, or a Mac running OS X 10.6 or later
## Step 1: Connect your micro:bit to your computer
First, connect the micro:bit:
1. Connect the small end of the USB cable to the micro USB port on your micro:bit.
2. Connect the other end of the USB cable to a USB port on your computer.
Your computer should recognise your micro:bit as a new drive. On computers
running Windows, `MICROBIT` appears as a drive under Devices and drives. On a Mac
it appears as a new drive under Devices.
![](/static/mb/device/usb-osx-device.png)
## Step 2: Download your program
1. Open your project on [codethemicrobit.com](https://codethemicrobit.com)
2. Click **Download**
3. When prompted, choose to **save** the compiled file onto your computer. The
prompt will be different depending on which browser you are using, or
whether you are using a Windows computer or a Mac
When you select **Download** in Chrome, the file will appear at the bottom of
the browser. Click on the small arrow and select **Show in Finder**. This will
show the file in your download folder. Drag and drop the file onto your
`MICROBIT` drive.
![](/static/mb/device/usb-osx-chrome.png)
## Step 3: Transfer the file to your micro:bit
* Once you've found the folder containing your `.hex` file, drag and drop it
onto your `MICROBIT` drive
* The LED on the back of your micro:bit flashes during the transfer (which
should only take a few seconds).
* Once transferred, the code will run automatically on your micro:bit. To rerun
your program, press the reset button on the back of your micro:bit. The reset
button automatically runs the newest file on the micro:bit.
By copying the script onto the `MICROBIT` drive, you have programmed it into the
flash memory on the micro:bit, which means even after you unplug the micro:bit,
your program will still run if the micro:bit is powered by battery.
### ~hint
Transfer not working? See some [troubleshooting tips](/device/usb/troubleshooting).
### ~

View File

@ -0,0 +1,71 @@
# Uploading from Firefox for Mac
While you're writing and testing your programs, you'll mostly be [running them
in the simulator](/device/simulator), but once you've finished your program you
can **compile** it and run it on your micro:bit.
The basic steps are:
1. Connect your micro:bit to your computer via USB
2. Click **Download** and download the `.hex` file
3. Copy the `.hex` file from your computer onto the micro:bit drive
## Requirements
You need the following things to transfer and run a script on your micro:bit:
* A-Male to Micro USB cable to connect your computer to your micro:bit. This is
the same cable that is commonly used to connect a smart phone to a computer.
* A PC running Windows 7 or later, or a Mac running OS X 10.6 or later
## Step 1: Connect your micro:bit to your computer
First, connect the micro:bit:
1. Connect the small end of the USB cable to the micro USB port on your micro:bit.
2. Connect the other end of the USB cable to a USB port on your computer.
Your computer should recognise your micro:bit as a new drive. On computers
running Windows, `MICROBIT` appears as a drive under Devices and drives. On a Mac
it appears as a new drive under Devices.
![](/static/mb/device/usb-osx-device.png)
## Step 2: Download your program
1. Open your project on [codethemicrobit.com](https://codethemicrobit.com)
2. Click **Download**
3. When prompted, choose to **save** the compiled file onto your computer. The
prompt will be different depending on which browser you are using, or
whether you are using a Windows computer or a Mac
A dialogue box will appear, asking whether you would like to open or save your
hex file. Select **Save file** and click **OK** and the file will then appear in
your downloads in the top right of your browser. Right click on the file and
click on **Show in Finder** and the file will appear in your downloads folder.
Select the file and drag and drop it onto your `MICROBIT` drive.
![](/static/mb/device/usb-osx-firefox-1.jpg)
![](/static/mb/device/usb-osx-firefox-2.png)
## Step 3: Transfer the file to your micro:bit
* Once you've found the folder containing your `.hex` file, drag and drop it
onto your `MICROBIT` drive
* The LED on the back of your micro:bit flashes during the transfer (which
should only take a few seconds).
* Once transferred, the code will run automatically on your micro:bit. To rerun
your program, press the reset button on the back of your micro:bit. The reset
button automatically runs the newest file on the micro:bit.
By copying the script onto the `MICROBIT` drive, you have programmed it into the
flash memory on the micro:bit, which means even after you unplug the micro:bit,
your program will still run if the micro:bit is powered by battery.
### ~hint
Transfer not working? See some [troubleshooting tips](/device/usb/troubleshooting).
### ~

View File

@ -0,0 +1,68 @@
# Uploading from Safari for Mac
While you're writing and testing your programs, you'll mostly be [running them
in the simulator](/device/simulator), but once you've finished your program you
can **compile** it and run it on your micro:bit.
The basic steps are:
1. Connect your micro:bit to your computer via USB
2. Click **Download** and download the `.hex` file
3. Copy the `.hex` file from your computer onto the micro:bit drive
## Requirements
You need the following things to transfer and run a script on your micro:bit:
* A-Male to Micro USB cable to connect your computer to your micro:bit. This is
the same cable that is commonly used to connect a smart phone to a computer.
* A PC running Windows 7 or later, or a Mac running OS X 10.6 or later
## Step 1: Connect your micro:bit to your computer
First, connect the micro:bit:
1. Connect the small end of the USB cable to the micro USB port on your micro:bit.
2. Connect the other end of the USB cable to a USB port on your computer.
Your computer should recognise your micro:bit as a new drive. On computers
running Windows, `MICROBIT` appears as a drive under Devices and drives. On a Mac
it appears as a new drive under Devices.
![](/static/mb/device/usb-osx-device.png)
## Step 2: Download your program
1. Open your project on [codethemicrobit.com](https://codethemicrobit.com)
2. Click **Download**
3. When prompted, choose to **save** the compiled file onto your computer. The
prompt will be different depending on which browser you are using, or
whether you are using a Windows computer or a Mac
When you select **Download** in Safari a file called `Unknown` will be
downloaded into your Downloads folder. Open your Downloads folder and drag and
drop the file onto your `MICROBIT` drive, under Devices:
![](/static/mb/device/usb-osx-dnd.png)
## Step 3: Transfer the file to your micro:bit
* Once you've found the folder containing your `.hex` file, drag and drop it
onto your `MICROBIT` drive
* The LED on the back of your micro:bit flashes during the transfer (which
should only take a few seconds).
* Once transferred, the code will run automatically on your micro:bit. To rerun
your program, press the reset button on the back of your micro:bit. The reset
button automatically runs the newest file on the micro:bit.
By copying the script onto the `MICROBIT` drive, you have programmed it into the
flash memory on the micro:bit, which means even after you unplug the micro:bit,
your program will still run if the micro:bit is powered by battery.
### ~hint
Transfer not working? See some [troubleshooting tips](/device/usb/troubleshooting).
### ~

View File

@ -0,0 +1,24 @@
# Troubleshooting Transfer
You cant drag and drop more than one hex file at once onto your micro:bit. If
you try to drag and drop a second hex file onto your micro:bit before the first
file has finished downloading, then the second file may fail in different ways.
When the first program has been written to the micro:bit, the drive will
disengage. If you drag and drop a second file at this point it may not find the
drive and the second write will fail.
The errors may look like this:
**Windows**
![](/static/mb/device/usb-windows-copy-file-error.jpg)
**Mac**
![](/static/mb/device/usb-osx-copy-file-error.png)
Or it may appear that there are two hex files on your micro:bit so the micro:bit
wont be able to run multiple files. To rectify this, unplug your micro:bit and
plug it in again. Make sure that your micro:bit appears as `MICROBIT` and not
`MAINTENANCE`.

View File

@ -0,0 +1,79 @@
# Uploading from Chrome for Windows
While you're writing and testing your programs, you'll mostly be [running them
in the simulator](/device/simulator), but once you've finished your program you
can **compile** it and run it on your micro:bit.
The basic steps are:
1. Connect your micro:bit to your computer via USB
2. Click **Download** and download the `.hex` file
3. Copy the `.hex` file from your computer onto the micro:bit drive
### ~hint
You can use the [micro:bit uploader](/uploader) to automatically deploy ``.hex`` files to your micro:bit!
![](/static/uploader/tooltip.png)
### ~
## Requirements
You need the following things to transfer and run a script on your micro:bit:
* A-Male to Micro USB cable to connect your computer to your micro:bit. This is
the same cable that is commonly used to connect a smart phone to a computer.
* A PC running Windows 7 or later, or a Mac running OS X 10.6 or later
## Step 1: Connect your micro:bit to your computer
First, connect the micro:bit:
1. Connect the small end of the USB cable to the micro USB port on your micro:bit.
2. Connect the other end of the USB cable to a USB port on your computer.
Your computer should recognise your micro:bit as a new drive. On computers
running Windows, `MICROBIT` appears as a drive under Devices and drives. On a Mac
it appears as a new drive under Devices.
![](/static/mb/device/usb-windows-device.jpg)
## Step 2: Download your program
1. Open your project on [codethemicrobit.com](https://codethemicrobit.com)
2. Click **Download**
3. When prompted, choose to **save** the compiled file onto your computer. The
prompt will be different depending on which browser you are using, or
whether you are using a Windows computer or a Mac
Your `.hex` file appears as a download at the bottom of the browser. Click on
the arrow next to the name of the file and then click **Show in folder**.
![](/static/mb/device/usb-windows-chrome.png)
Drag and drop the `.hex` file from the download folder onto the `MICROBIT` drive.
## Step 3: Transfer the file to your micro:bit
* Once you've found the folder containing your `.hex` file, drag and drop it
onto your `MICROBIT` drive
* The LED on the back of your micro:bit flashes during the transfer (which
should only take a few seconds).
* Once transferred, the code will run automatically on your micro:bit. To rerun
your program, press the reset button on the back of your micro:bit. The reset
button automatically runs the newest file on the micro:bit.
In File Explorer, right-click on the hex file (created in Step 2 above), choose **Send to**, and then **MICROBIT**.
![](/static/mb/device/usb-windows-sendto.jpg)
By copying the script onto the `MICROBIT` drive, you have programmed it into the
flash memory on the micro:bit, which means even after you unplug the micro:bit,
your program will still run if the micro:bit is powered by battery.
### ~hint
Transfer not working? See some [troubleshooting tips](/device/usb/troubleshooting).
### ~

View File

@ -0,0 +1,89 @@
# Uploading from Edge on Windows
How to compile, transfer, and run a program on your micro:bit on **Microsoft Edge**.
While you're writing and testing your programs, you'll mostly be [running them
in the simulator](/device/simulator), but once you've finished your program you
can **compile** it and run it on your micro:bit.
The basic steps are:
1. Connect your micro:bit to your computer via USB
2. Click **Download** and download the `.hex` file
3. Copy the `.hex` file from your computer onto the micro:bit drive
### ~hint
You can use the [micro:bit uploader](/uploader) to automatically deploy ``.hex`` files to your micro:bit!
![](/static/uploader/tooltip.png)
### ~
## Requirements
You need the following things to transfer and run a script on your micro:bit:
* A-Male to Micro USB cable to connect your computer to your micro:bit. This is
the same cable that is commonly used to connect a smart phone to a computer.
* A PC running Windows 7 or later, or a Mac running OS X 10.6 or later
## Step 1: Connect your micro:bit to your computer
First, connect the micro:bit:
1. Connect the small end of the USB cable to the micro USB port on your micro:bit.
2. Connect the other end of the USB cable to a USB port on your computer.
Your computer should recognise your micro:bit as a new drive. On computers
running Windows, `MICROBIT` appears as a drive under Devices and drives. On a Mac
it appears as a new drive under Devices.
![](/static/mb/device/usb-windows-device.jpg)
## Step 2: Download your program
1. Open your project on [codethemicrobit.com](https://codethemicrobit.com)
2. Click **Download**
3. When prompted, choose to **save** the compiled file onto your computer. The
prompt will be different depending on which browser you are using, or
whether you are using a Windows computer or a Mac
A message will appear at the bottom of the browser asking what you want to do
with the file. Click **Save**:
![](/static/mb/device/usb-windows-edge-1.png)
Then click **Open folder** and drag and drop the file from your Downloads to
your `MICROBIT` drive.
![](/static/mb/device/usb-windows-edge-2.png)
## Step 3: Transfer the file to your micro:bit
* Once you've found the folder containing your `.hex` file, drag and drop it
onto your `MICROBIT` drive
* If you're using Windows, you can use **Send to** as described below
* The LED on the back of your micro:bit flashes during the transfer (which
should only take a few seconds).
* Once transferred, the code will run automatically on your micro:bit. To rerun
your program, press the reset button on the back of your micro:bit. The reset
button automatically runs the newest file on the micro:bit.
In File Explorer, right-click on the hex file (created in Step 2 above), choose **Send to**, and then **MICROBIT**.
![](/static/mb/device/usb-windows-sendto.jpg)
By copying the script onto the `MICROBIT` drive, you have programmed it into the
flash memory on the micro:bit, which means even after you unplug the micro:bit,
your program will still run if the micro:bit is powered by battery.
If you want to save time, you can use the [micro:bit uploader](/uploader) to
automatically deploy hex files to your micro:bit. It works on Windows and is
compatible with any browser.
### ~hint
Transfer not working? See some [troubleshooting tips](/device/usb/troubleshooting).
### ~

View File

@ -0,0 +1,86 @@
# Uploading from Firefox on Windows
How to compile, transfer, and run a program on your micro:bit on **Firefox for Windows**.
While you're writing and testing your programs, you'll mostly be [running them
in the simulator](/device/simulator), but once you've finished your program you
can **compile** it and run it on your micro:bit.
The basic steps are:
1. Connect your micro:bit to your computer via USB
2. Click **Download** and download the `.hex` file
3. Copy the `.hex` file from your computer onto the micro:bit drive
### ~hint
You can use the [micro:bit uploader](/uploader) to automatically deploy ``.hex`` files to your micro:bit!
![](/static/uploader/tooltip.png)
### ~
## Requirements
You need the following things to transfer and run a script on your micro:bit:
* A-Male to Micro USB cable to connect your computer to your micro:bit. This is
the same cable that is commonly used to connect a smart phone to a computer.
* A PC running Windows 7 or later, or a Mac running OS X 10.6 or later
## Step 1: Connect your micro:bit to your computer
First, connect the micro:bit:
1. Connect the small end of the USB cable to the micro USB port on your micro:bit.
2. Connect the other end of the USB cable to a USB port on your computer.
Your computer should recognise your micro:bit as a new drive. On computers
running Windows, `MICROBIT` appears as a drive under Devices and drives. On a Mac
it appears as a new drive under Devices.
![](/static/mb/device/usb-windows-device.jpg)
## Step 2: Download your program
1. Open your project on [codethemicrobit.com](https://codethemicrobit.com)
2. Click **Download**
3. When prompted, choose to **save** the compiled file onto your computer. The
prompt will be different depending on which browser you are using, or
whether you are using a Windows computer or a Mac
A window will appear asking whether you want to save or open the `.hex` file.
Select **Save File** and then select **OK**.
![](/static/mb/device/usb-windows-firefox-1.png)
The file will then appear in your downloads in the top right of your browser.
Click the **folder icon** next to the filename to open it in Windows Explorer.
![](/static/mb/device/usb-windows-firefox-2.jpg)
Drag and drop the `.hex` file from the download folder onto the `MICROBIT` drive.
## Step 3: Transfer the file to your micro:bit
* Once you've found the folder containing your `.hex` file, drag and drop it
onto your `MICROBIT` drive
* If you're using Windows, you can use **Send to** as described below
* The LED on the back of your micro:bit flashes during the transfer (which
should only take a few seconds).
* Once transferred, the code will run automatically on your micro:bit. To rerun
your program, press the reset button on the back of your micro:bit. The reset
button automatically runs the newest file on the micro:bit.
In File Explorer, right-click on the hex file (created in Step 2 above), choose **Send to**, and then **MICROBIT**.
![](/static/mb/device/usb-windows-sendto.jpg)
By copying the script onto the `MICROBIT` drive, you have programmed it into the
flash memory on the micro:bit, which means even after you unplug the micro:bit,
your program will still run if the micro:bit is powered by battery.
### ~hint
Transfer not working? See some [troubleshooting tips](/device/usb/troubleshooting).
### ~

View File

@ -0,0 +1,86 @@
# Uploading from Internet Explorer on Windows
While you're writing and testing your programs, you'll mostly be [running them
in the simulator](/device/simulator), but once you've finished your program you
can **compile** it and run it on your micro:bit.
The basic steps are:
1. Connect your micro:bit to your computer via USB
2. Click **Download** and download the `.hex` file
3. Copy the `.hex` file from your computer onto the micro:bit drive
### ~hint
You can use the [micro:bit uploader](/uploader) to automatically deploy ``.hex`` files to your micro:bit!
![](/static/uploader/tooltip.png)
### ~
## Requirements
You need the following things to transfer and run a script on your micro:bit:
* A-Male to Micro USB cable to connect your computer to your micro:bit. This is
the same cable that is commonly used to connect a smart phone to a computer.
* A PC running Windows 7 or later, or a Mac running OS X 10.6 or later
## Step 1: Connect your micro:bit to your computer
First, connect the micro:bit:
1. Connect the small end of the USB cable to the micro USB port on your micro:bit.
2. Connect the other end of the USB cable to a USB port on your computer.
Your computer should recognise your micro:bit as a new drive. On computers
running Windows, `MICROBIT` appears as a drive under Devices and drives. On a Mac
it appears as a new drive under Devices.
![](/static/mb/device/usb-windows-device.jpg)
## Step 2: Download your program
1. Open your project on [codethemicrobit.com](https://codethemicrobit.com)
2. Click **Download**
3. When prompted, choose to **save** the compiled file onto your computer. The
prompt will be different depending on which browser you are using, or
whether you are using a Windows computer or a Mac
A message will appear at the bottom of the browser asking what you want to do
with the file. Click **Save**:
![](/static/mb/device/usb-windows-ie11-1.png)
Then click **Open folder** and drag and drop the file from your Downloads to
your `MICROBIT` drive.
![](/static/mb/device/usb-windows-ie11-2.png)
## Step 3: Transfer the file to your micro:bit
* Once you've found the folder containing your `.hex` file, drag and drop it
onto your `MICROBIT` drive
* If you're using Windows, you can use **Send to** as described below
* The LED on the back of your micro:bit flashes during the transfer (which
should only take a few seconds).
* Once transferred, the code will run automatically on your micro:bit. To rerun
your program, press the reset button on the back of your micro:bit. The reset
button automatically runs the newest file on the micro:bit.
**Send to**: If you're using Windows you use *Send to* in File Explorer:
In File Explorer, right-click on the hex file (created in Step 2 above), choose **Send to**, and then **MICROBIT**.
![](/static/mb/device/usb-windows-sendto.jpg)
By copying the script onto the `MICROBIT` drive, you have programmed it into the
flash memory on the micro:bit, which means even after you unplug the micro:bit,
your program will still run if the micro:bit is powered by battery.
### ~hint
Transfer not working? See some [troubleshooting tips](/device/usb/troubleshooting).
### ~

View File

@ -58,7 +58,9 @@ After running this simulation several seconds by moving the micro:bit side to si
![](/static/mb/acc2.png)
### ~
Finally, you must open the Excel CSV file by clicking on the data.xls file that was downloaded to Downloads Folder.
Finally, you must open the Excel CSV file by clicking on the `data.csv` file
that was downloaded to Downloads Folder.
![](/static/mb/data3.png)
@ -93,4 +95,4 @@ NEXT: The Watch
```package
microbit-radio
```
```

29
docs/raspberry-pi.md Normal file
View File

@ -0,0 +1,29 @@
# Raspberry Pi and Raspbian
It is possible to run the web editor or [command line interface](/cli) from Raspbian on Raspberry Pi 2 or 3.
## Web editor
The web editor requires to install IceWeasel (Firefox) as the built-in browser cannot handle it.
```
sudo apt-get install iceweasel
```
Once installed simply navigate to https://codethemicrobit.com or type
```
firefox https://codethemicrobit.com
```
## Command line
The PXT command line also works on Raspbian and allows to run a local server and/or edit programs from any text editor.
* Node.JS 6.0 needs installed
To install all the tools,
```
curl -s https://raw.githubusercontent.com/Microsoft/pxt-rpi/master/install.sh | sh -
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
docs/static/mb/device/pano.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
docs/static/mb/device/usb-generic.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
docs/static/mb/device/usb-mac.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

BIN
docs/static/mb/device/usb-thin.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -1,5 +1,4 @@
{
"bluetooth": "Support for additional Bluetooth services.",
"bluetooth.onBluetoothConnected": "Register code to run when the micro:bit is connected to over Bluetooth",
"bluetooth.onBluetoothConnected|param|body": "Code to run when a Bluetooth connection is established",
"bluetooth.onBluetoothDisconnected": "Register code to run when a bluetooth connection to the micro:bit is lost",
@ -10,6 +9,7 @@
"bluetooth.startLEDService": "Starts the Bluetooth LED service",
"bluetooth.startMagnetometerService": "Starts the Bluetooth magnetometer service",
"bluetooth.startTemperatureService": "Starts the Bluetooth temperature service",
"bluetooth.startUartService": "Starts the Bluetooth UART service",
"bluetooth.uartRead": "Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.",
"bluetooth.uartWrite": "Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device."
}

View File

@ -7,6 +7,7 @@
"bluetooth.startLEDService|block": "bluetooth led service",
"bluetooth.startMagnetometerService|block": "bluetooth magnetometer service",
"bluetooth.startTemperatureService|block": "bluetooth temperature service",
"bluetooth.startUartService|block": "bluetooth uart service",
"bluetooth.uartRead|block": "bluetooth uart read %del=bluetooth_uart_delimiter_conv",
"bluetooth.uartWrite|block": "bluetooth uart write %data",
"bluetooth|block": "bluetooth"

View File

@ -141,7 +141,6 @@ namespace radio {
*/
//% help=radio/received-number-at
//% weight=45 debug=true
//% blockId=radio_datagram_received_number_at block="radio receive number|at %VALUE" blockGap=8
int receivedNumberAt(int index) {
if (radioEnable() != MICROBIT_OK) return 0;
if (0 <= index && index < packet.length() / 4) {

View File

@ -46,8 +46,7 @@ declare namespace radio {
* @param index index of the number to read from 0 to 3. 1 eg
*/
//% help=radio/received-number-at
//% weight=45 debug=true
//% blockId=radio_datagram_received_number_at block="radio receive number|at %VALUE" blockGap=8 shim=radio::receivedNumberAt
//% weight=45 debug=true shim=radio::receivedNumberAt
function receivedNumberAt(index: number): number;
/**

View File

@ -22,6 +22,8 @@
"control": "Runtime and event utilities.",
"control.inBackground": "Schedules code that run in the background.",
"control.reset": "Resets the BBC micro:bit.",
"control.waitMicros": "Blocks the current fiber for the given microseconds",
"control.waitMicros|param|micros": "number of micro-seconds to wait. eg: 4",
"game": "A single-LED sprite game engine",
"game.addScore": "Adds points to the current score",
"game.addScore|param|points": "amount of points to change, eg: 1",
@ -52,9 +54,12 @@
"input.onLogoDown|param|body": "TODO",
"input.onLogoUp": "Attaches code to run when the logo is oriented upwards and the board is vertical.",
"input.onLogoUp|param|body": "TODO",
"input.onPinPressed": "Do something when a pin(``P0``, ``P1`` or both ``P2``) is pressed.",
"input.onPinPressed|param|body": "TODO",
"input.onPinPressed|param|name": "TODO",
"input.onPinPressed": "Do something when a pin is pressed.",
"input.onPinPressed|param|body": "the code to run when the pin is pressed",
"input.onPinPressed|param|name": "the pin that needs to be pressed",
"input.onPinReleased": "Do something when a pin is released.",
"input.onPinReleased|param|body": "the code to run when the pin is released",
"input.onPinReleased|param|name": "the pin that needs to be released",
"input.onScreenDown": "Attaches code to run when the screen is facing down.",
"input.onScreenDown|param|body": "TODO",
"input.onScreenUp": "Attaches code to run when the screen is facing up.",
@ -152,6 +157,8 @@
"pins.setPull": "Configures the pull of this pin.",
"pins.setPull|param|name": "pin to set the pull mode on",
"pins.setPull|param|pull": "one of the mbed pull configurations: PullUp, PullDown, PullNone ",
"pins.spiWrite": "Write to the SPI slave and return the response",
"pins.spiWrite|param|value": "Data to be sent to the SPI slave",
"serial": "Reading and writing data over a serial connection.",
"serial.readLine": "Reads a line of text from the serial port.",
"serial.redirect": "Dynamically configuring the serial instance to use pins other than USBTX and USBRX.",

View File

@ -12,6 +12,7 @@
"basic|block": "basic",
"control.inBackground|block": "run in background",
"control.reset|block": "reset",
"control.waitMicros|block": "wait (µs)%micros",
"control|block": "control",
"game.addScore|block": "change score by|%points",
"game.gameOver|block": "game over",
@ -28,7 +29,8 @@
"input.magneticForce|block": "magnetic force (µT)|%NAME",
"input.onButtonPressed|block": "on button|%NAME|pressed",
"input.onGesture|block": "on |%NAME",
"input.onPinPressed|block": "on pin|%NAME|pressed",
"input.onPinPressed|block": "on pin %NAME|pressed",
"input.onPinReleased|block": "on pin %NAME|released",
"input.pinIsPressed|block": "pin %NAME|is pressed",
"input.rotation|block": "rotation (°)|%NAME",
"input.runningTime|block": "running time (ms)",
@ -41,6 +43,7 @@
"led.point|block": "point|x %x|y %y",
"led.setBrightness|block": "set brightness %value",
"led.stopAnimation|block": "stop animation",
"led.toggle|block": "toggle|x %x|y %y",
"led.unplot|block": "unplot|x %x|y %y",
"led|block": "led",
"music.beat|block": "%fraction|beat",
@ -65,6 +68,7 @@
"pins.servoSetPulse|block": "servo set pulse|pin %value|to (µs) %micros",
"pins.servoWritePin|block": "servo write|pin %name|to %value",
"pins.setPull|block": "set pull|pin %pin|to %pull",
"pins.spiWrite|block": "spi write %value",
"pins|block": "pins",
"serial.readLine|block": "serial read line",
"serial.redirect|block": "serial redirect to|TX %tx|RX %rx|at baud rate %rate",

View File

@ -8,6 +8,7 @@ namespace control {
* Returns the value of a C++ runtime constant
*/
//% weight=2 weight=19 blockId="control_event_source_id" block="%id" blockGap=8
//% shim=TD_ID
export function eventSourceId(id: EventBusSource): number {
return id;
}
@ -15,6 +16,7 @@ namespace control {
* Returns the value of a C++ runtime constant
*/
//% weight=1 weight=19 blockId="control_event_value_id" block="%id"
//% shim=TD_ID
export function eventValueId(id: EventBusValue): number {
return id;
}
@ -42,6 +44,5 @@ namespace control {
* Display warning in the simulator.
*/
//% shim=pxtrt::runtimeWarning
export function runtimeWarning(message: string) {
}
export function runtimeWarning(message: string) { }
}

View File

@ -166,6 +166,7 @@ namespace Array_ {
int removeElement(RefCollection *c, uint32_t x) { return c->removeElement(x); }
}
// Import some stuff directly
namespace pxt {
//%
@ -181,10 +182,12 @@ namespace pxt {
//%
Action mkAction(int reflen, int totallen, int startptr);
//%
RefRecord* mkRecord(int reflen, int totallen);
//%
RefRecord* mkClassInstance(int offset);
//%
void RefRecord_destroy(RefRecord *r);
//%
void RefRecord_print(RefRecord *r);
//%
void debugMemLeaks();
//%
int incr(uint32_t e);
@ -308,6 +311,72 @@ namespace pxtrt {
}
}
//%
RefMap *mkMap() {
return new RefMap();
}
//%
uint32_t mapGet(RefMap *map, uint32_t key) {
int i = map->findIdx(key);
if (i < 0) {
map->unref();
return 0;
}
uint32_t r = map->data[i].val;
map->unref();
return r;
}
//%
uint32_t mapGetRef(RefMap *map, uint32_t key) {
int i = map->findIdx(key);
if (i < 0) {
map->unref();
return 0;
}
uint32_t r = incr(map->data[i].val);
map->unref();
return r;
}
//%
void mapSet(RefMap *map, uint32_t key, uint32_t val) {
int i = map->findIdx(key);
if (i < 0) {
map->data.push_back({
key << 1,
val
});
} else {
if (map->data[i].key & 1) {
decr(map->data[i].val);
map->data[i].key = key << 1;
}
map->data[i].val = val;
}
map->unref();
}
//%
void mapSetRef(RefMap *map, uint32_t key, uint32_t val) {
int i = map->findIdx(key);
if (i < 0) {
map->data.push_back({
(key << 1) | 1,
val
});
} else {
if (map->data[i].key & 1) {
decr(map->data[i].val);
} else {
map->data[i].key = (key << 1) | 1;
}
map->data[i].val = val;
}
map->unref();
}
//
// Debugger
//

View File

@ -135,7 +135,7 @@ namespace music {
*/
//% help=music/play-tone weight=90
//% blockId=device_play_note block="play|tone %note=device_note|for %duration=device_beat" icon="\uf025" blockGap=8
//% parts="speaker"
//% parts="headphone"
export function playTone(frequency: number, ms: number): void {
pins.analogSetPitchPin(AnalogPin.P0);
pins.analogPitch(frequency, ms);
@ -147,7 +147,7 @@ namespace music {
*/
//% help=music/ring-tone weight=80
//% blockId=device_ring block="ring tone (Hz)|%note=device_note" icon="\uf025" blockGap=8
//% parts="speaker"
//% parts="headphone"
export function ringTone(frequency: number): void {
pins.analogSetPitchPin(AnalogPin.P0);
pins.analogPitch(frequency, 0);
@ -159,7 +159,7 @@ namespace music {
*/
//% help=music/rest weight=79
//% blockId=device_rest block="rest(ms)|%duration=device_beat"
//% parts="speaker"
//% parts="headphone"
export function rest(ms: number): void {
playTone(0, ms);
}
@ -171,7 +171,6 @@ namespace music {
*/
//% weight=50 help=music/note-frequency
//% blockId=device_note block="%note"
//% parts="speaker"
//% shim=TD_ID
export function noteFrequency(name: Note): number {
return name;
@ -186,7 +185,6 @@ namespace music {
*/
//% help=music/beat weight=49
//% blockId=device_beat block="%fraction|beat"
//% parts="speaker"
export function beat(fraction?: BeatFraction): number {
init();
if (fraction == null) fraction = BeatFraction.Whole;
@ -203,7 +201,6 @@ namespace music {
*/
//% help=music/tempo weight=40
//% blockId=device_tempo block="tempo (bpm)" blockGap=8
//% parts="speaker"
export function tempo(): number {
init();
return beatsPerMinute;
@ -215,7 +212,6 @@ namespace music {
*/
//% help=music/change-tempo weight=39
//% blockId=device_change_tempo block="change tempo by (bpm)|%value" blockGap=8
//% parts="speaker"
export function changeTempoBy(bpm: number): void {
init();
setTempo(beatsPerMinute + bpm);
@ -227,7 +223,6 @@ namespace music {
*/
//% help=music/set-tempo weight=38
//% blockId=device_set_tempo block="set tempo to (bpm)|%value"
//% parts="speaker"
export function setTempo(bpm: number): void {
init();
if (bpm > 0) {

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="142" height="180" viewBox="0 0 142 180"><rect ry=".3" rx="1" y="58.615" x="-8.878" height="23.571" width="17.143" transform="rotate(-45)" fill="#b3b3b3"/><rect ry=".3" rx="1" y="32.043" x="-8.878" height="23.571" width="17.143" transform="rotate(-45)" fill="#b3b3b3"/><path d="M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z" fill="#b3b3b3"/><rect ry="6.85" rx="4.571" y="84.758" x="-20.128" height="75.571" width="39.643" transform="rotate(-45)"/><rect ry=".374" rx="1.038" y="29.442" x="-8.925" height="2.228" width="17.238" transform="rotate(-45)" fill="#fff"/><rect ry=".374" rx="1.038" y="55.939" x="-8.925" height="2.228" width="17.238" transform="rotate(-45)" fill="#fff"/><rect ry=".374" rx="1.038" y="82.392" x="-8.925" height="2.228" width="17.238" transform="rotate(-45)" fill="#fff"/><rect ry="2.317" rx="2.183" y="158.876" x="-9.774" height="25.568" width="18.935" transform="rotate(-45)"/><path d="M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653" fill="none" stroke="#000" stroke-width="6.6" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -29,6 +29,7 @@
"buffer.cpp",
"pxtparts.json",
"parts/speaker.svg",
"parts/headphone.svg",
"_locales/fr/microbit-jsdoc-strings.json"
],
"public": true,

View File

@ -1,78 +1,148 @@
{
"ledmatrix": {
"visual": "ledmatrix",
"breadboardColumnsNeeded": 8,
"breadboardStartRow": "h",
"pinAllocation": {
"type": "auto",
"gpioPinsNeeded": [5, 5]
"buttonpair": {
"simulationBehavior": "buttonpair",
"visual": {
"builtIn": "buttonpair",
"width": 75,
"height": 45,
"pinDistance": 15,
"pinLocations": [
{"x": 0, "y": 0},
{"x": 30, "y": 45},
{"x": 45, "y": 0},
{"x": 75, "y": 45}
]
},
"assemblyStep": 0,
"wires": [
{"start": ["breadboard", "j", 0], "end": ["GPIO", 5], "color": "purple", "assemblyStep": 1},
{"start": ["breadboard", "j", 1], "end": ["GPIO", 6], "color": "purple", "assemblyStep": 1},
{"start": ["breadboard", "j", 2], "end": ["GPIO", 7], "color": "purple", "assemblyStep": 1},
{"start": ["breadboard", "j", 3], "end": ["GPIO", 8], "color": "purple", "assemblyStep": 1},
{"start": ["breadboard", "a", 7], "end": ["GPIO", 9], "color": "purple", "assemblyStep": 1},
{"start": ["breadboard", "a", 0], "end": ["GPIO", 0], "color": "green", "assemblyStep": 2},
{"start": ["breadboard", "a", 1], "end": ["GPIO", 1], "color": "green", "assemblyStep": 2},
{"start": ["breadboard", "a", 2], "end": ["GPIO", 2], "color": "green", "assemblyStep": 2},
{"start": ["breadboard", "a", 3], "end": ["GPIO", 3], "color": "green", "assemblyStep": 2},
{"start": ["breadboard", "j", 4], "end": ["GPIO", 4], "color": "green", "assemblyStep": 2}
]
},
"buttonpair": {
"visual": "buttonpair",
"breadboardColumnsNeeded": 6,
"breadboardStartRow": "f",
"pinAllocation": {
"type": "predefined",
"pins": ["P13", "P12"]
"numberOfPins": 4,
"pinDefinitions": [
{"target": "P14", "style": "male", "orientation": "-Z"},
{"target": "ground", "style": "male", "orientation": "-Z"},
{"target": "P15", "style": "male", "orientation": "-Z"},
{"target": "ground", "style": "male", "orientation": "-Z"}
],
"instantiation": {
"kind": "singleton"
},
"assemblyStep": 0,
"wires": [
{"start": ["breadboard", "j", 0], "end": ["GPIO", 0], "color": "yellow", "assemblyStep": 1},
{"start": ["breadboard", "a", 2], "end": "ground", "color": "blue", "assemblyStep": 1},
{"start": ["breadboard", "j", 3], "end": ["GPIO", 1], "color": "orange", "assemblyStep": 2},
{"start": ["breadboard", "a", 5], "end": "ground", "color": "blue", "assemblyStep": 2}
"assembly": [
{"part": true},
{"pinIndices": [0, 1]},
{"pinIndices": [2, 3]}
]
},
"neopixel": {
"visual": "neopixel",
"breadboardColumnsNeeded": 5,
"breadboardStartRow": "h",
"pinAllocation": {
"type": "factoryfunction",
"functionName": "neopixel.create",
"pinArgPositions": [0],
"otherArgPositions": [1]
"simulationBehavior": "neopixel",
"visual": {
"builtIn": "neopixel",
"width": 58,
"height": 113,
"pinDistance": 9,
"pinLocations": [
{"x": 10, "y": 0},
{"x": 19, "y": 0},
{"x": 28, "y": 0}
]
},
"assemblyStep": 0,
"wires": [
{"start": ["breadboard", "j", 1], "end": "ground", "color": "blue", "assemblyStep": 1},
{"start": ["breadboard", "j", 2], "end": "threeVolt", "color": "red", "assemblyStep": 2},
{"start": ["breadboard", "j", 3], "end": ["GPIO", 0], "color": "green", "assemblyStep": 2}
"numberOfPins": 3,
"pinDefinitions": [
{"target": {"pinInstantiationIdx": 0}, "style": "solder", "orientation": "+Z"},
{"target": "threeVolt", "style": "solder", "orientation": "+Z"},
{"target": "ground", "style": "solder", "orientation": "+Z"}
],
"instantiation": {
"kind": "function",
"fullyQualifiedName": "neopixel.create",
"argumentRoles": [
{"pinInstantiationIdx": 0, "partParameter": "pin"},
{"partParameter": "mode"}
]
},
"assembly": [
{"part": true, "pinIndices": [2]},
{"pinIndices": [0, 1]}
]
},
"ledmatrix": {
"visual": {
"builtIn": "ledmatrix",
"width": 105,
"height": 105,
"pinDistance": 15,
"pinLocations": [
{"x": 0, "y": 0},
{"x": 15, "y": 0},
{"x": 30, "y": 0},
{"x": 45, "y": 0},
{"x": 105, "y": 105},
{"x": 0, "y": 105},
{"x": 15, "y": 105},
{"x": 30, "y": 105},
{"x": 45, "y": 105},
{"x": 60, "y": 0}
]
},
"simulationBehavior": "ledmatrix",
"numberOfPins": 10,
"instantiation": {"kind": "singleton"},
"pinDefinitions": [
{"target": "P6", "style": "male", "orientation": "-Z", "colorGroup": 0},
{"target": "P7", "style": "male", "orientation": "-Z", "colorGroup": 0},
{"target": "P8", "style": "male", "orientation": "-Z", "colorGroup": 0},
{"target": "P9", "style": "male", "orientation": "-Z", "colorGroup": 0},
{"target": "P10", "style": "male", "orientation": "-Z", "colorGroup": 0},
{"target": "P12", "style": "male", "orientation": "-Z", "colorGroup": 1},
{"target": "P13", "style": "male", "orientation": "-Z", "colorGroup": 1},
{"target": "P16", "style": "male", "orientation": "-Z", "colorGroup": 1},
{"target": "P19", "style": "male", "orientation": "-Z", "colorGroup": 1},
{"target": "P20", "style": "male", "orientation": "-Z", "colorGroup": 1}
],
"assembly": [
{"part": true},
{"pinIndices": [0, 1, 2, 3, 4]},
{"pinIndices": [5, 6, 7, 8, 9]}
]
},
"headphone": {
"numberOfPins": 2,
"visual": {
"image": "parts/headphone.svg",
"width": 142,
"height": 180,
"pinDistance": 20,
"pinLocations": [
{"x": 17, "y": 11},
{"x": 55, "y": 50}
]
},
"pinDefinitions": [
{"target": "P0", "style": "croc", "orientation": "Y"},
{"target": "ground", "style": "croc", "orientation": "Y"}
],
"instantiation": {"kind": "singleton"},
"assembly": [
{"part": true, "pinIndices": [0]},
{"pinIndices": [1]}
]
},
"speaker": {
"numberOfPins": 2,
"visual": {
"image": "/parts/speaker.svg",
"image": "parts/speaker.svg",
"width": 500,
"height": 500,
"firstPin": [180, 135],
"pinDist": 70,
"extraColumnOffset": 1
"pinDistance": 70,
"pinLocations": [
{"x": 180, "y": 135},
{"x": 320, "y": 135}
]
},
"breadboardColumnsNeeded": 5,
"breadboardStartRow": "f",
"pinAllocation": {
"type": "auto",
"gpioPinsNeeded": 1
},
"assemblyStep": 0,
"wires": [
{"start": ["breadboard", "j", 1], "end": ["GPIO", 0], "color": "#ff80fa", "assemblyStep": 1},
{"start": ["breadboard", "j", 3], "end": "ground", "color": "blue", "assemblyStep": 1}
"pinDefinitions": [
{"target": "P0", "style": "male", "orientation": "-Z"},
{"target": "ground", "style": "male", "orientation": "-Z"}
],
"instantiation": {"kind": "singleton"},
"assembly": [
{"part": true, "pinIndices": [0]},
{"pinIndices": [1]}
]
}
}

View File

@ -1,6 +1,6 @@
{
"name": "pxt-microbit",
"version": "0.3.78",
"version": "0.4.13",
"description": "micro:bit target for PXT",
"keywords": [
"JavaScript",
@ -29,6 +29,6 @@
"typescript": "^1.8.7"
},
"dependencies": {
"pxt-core": "0.3.92"
"pxt-core": "0.4.17"
}
}

View File

@ -75,7 +75,9 @@
},
"simulator": {
"autoRun": true,
"streams": true,
"aspectRatio": 1.22,
"parts": true,
"partsAspectRatio": 0.69,
"builtinParts": {
"accelerometer": true,
@ -85,13 +87,102 @@
"bluetooth": true,
"thermometer": true,
"compass": true
},
"boardDefinition": {
"visual": "microbit",
"gpioPinBlocks": [
[
"P0"
],
[
"P1"
],
[
"P2"
],
[
"P3"
],
[
"P4",
"P5",
"P6",
"P7"
],
[
"P8",
"P9",
"P10",
"P11",
"P12"
],
[
"P16"
]
],
"gpioPinMap": {
"P0": "P0",
"P1": "P1",
"P2": "P2",
"P3": "P3",
"P4": "P4",
"P5": "P5",
"P6": "P6",
"P7": "P7",
"P8": "P8",
"P9": "P9",
"P10": "P10",
"P11": "P11",
"P12": "P12",
"P13": "P13",
"P14": "P14",
"P15": "P15",
"P16": "P16",
"P19": "P19",
"P20": "P20"
},
"spiPins": {
"MOSI": "P15",
"MISO": "P14",
"SCK": "P13"
},
"i2cPins": {
"SDA": "P20",
"SCL": "P19"
},
"analogInPins": [
"P0",
"P1",
"P2",
"P3",
"P10"
],
"groundPins": [
"GND"
],
"threeVoltPins": [
"+3v3"
],
"attachPowerOnRight": true,
"onboardComponents": [
"buttonpair",
"ledmatrix",
"speaker"
],
"useCrocClips": true,
"marginWhenBreadboarding": [
0,
0,
80,
0
]
}
},
"compileService": {
"yottaTarget": "bbc-microbit-classic-gcc",
"yottaCorePackage": "pxt-microbit-core",
"githubCorePackage": "microsoft/pxt-microbit-core",
"gittag": "v0.4.2",
"gittag": "v0.5.0",
"serviceId": "ws"
},
"serial": {
@ -113,6 +204,34 @@
"embedUrl": "https://codethemicrobit.com/",
"privacyUrl": "https://go.microsoft.com/fwlink/?LinkId=521839",
"termsOfUseUrl": "https://go.microsoft.com/fwlink/?LinkID=206977",
"githubUrl": "https://github.com/Microsoft/pxt-microbit",
"browserSupport": [
{
"name": "unsupported",
"os": "*",
"path": "/browsers"
},
{
"name": "unsupported",
"os": "mac",
"path": "/browsers/mac"
},
{
"name": "unsupported",
"os": "linux",
"path": "browsers/linux"
},
{
"name": "unsupported",
"os": "rpi",
"path": "/raspberry-pi"
},
{
"name": "unsupported",
"os": "windows",
"path": "/browsers/windows"
}
],
"boardName": "BBC micro:bit",
"docMenu": [
{
@ -140,10 +259,73 @@
"path": "/device"
}
],
"sideDoc": "getting-started"
"sideDoc": "getting-started",
"usbDocs": "/device/usb",
"usbHelp": [
{
"name": "connection",
"os": "*",
"browser": "*",
"path": "/static/mb/device/usb-generic.jpg"
},
{
"name": "connection",
"os": "mac",
"browser": "*",
"path": "/static/mb/device/usb-mac.jpg"
},
{
"name": "save",
"os": "windows",
"browser": "firefox",
"path": "/static/mb/device/usb-windows-firefox-1.png"
},
{
"name": "save",
"os": "mac",
"browser": "firefox",
"path": "/static/mb/device/usb-osx-firefox-1.jpg"
},
{
"name": "save",
"os": "mac",
"browser": "chrome",
"path": "/static/mb/device/usb-osx-chrome.png"
},
{
"name": "save",
"os": "windows",
"browser": "edge",
"path": "/static/mb/device/usb-windows-edge-1.png"
},
{
"name": "save",
"os": "windows",
"browser": "ie",
"path": "/static/mb/device/usb-windows-ie11-1.png"
},
{
"name": "save",
"os": "windows",
"browser": "chrome",
"path": "/static/mb/device/usb-windows-chrome.png"
},
{
"name": "copy",
"os": "mac",
"browser": "*",
"path": "/static/mb/device/usb-osx-dnd.png"
},
{
"name": "copy",
"os": "windows",
"browser": "*",
"path": "/static/mb/device/usb-windows-sendto.jpg"
}
]
},
"analytics": {
"userVoiceApiKey": "WEkkIGaj1WtJnSUF59iwaA",
"userVoiceForumId": 402381
}
}
}

View File

@ -1,556 +0,0 @@
namespace pxsim {
export interface AllocatorOpts {
boardDef: BoardDefinition,
cmpDefs: Map<PartDefinition>,
fnArgs: any,
getBBCoord: (loc: BBRowCol) => visuals.Coord,
cmpList: string[]
};
export interface AllocatorResult {
powerWires: WireInst[],
components: CmpAndWireInst[]
}
export interface CmpAndWireInst {
component: CmpInst,
wires: WireInst[]
}
export interface CmpInst {
name: string,
breadboardStartColumn: number,
breadboardStartRow: string,
assemblyStep: number,
visual: string | PartVisualDefinition,
microbitPins: string[],
otherArgs?: string[],
}
export interface WireInst {
start: Loc,
end: Loc,
color: string,
assemblyStep: number
};
interface PartialCmpAlloc {
name: string,
def: PartDefinition,
pinsAssigned: string[],
pinsNeeded: number | number[],
breadboardColumnsNeeded: number,
otherArgs?: string[],
}
interface AllocLocOpts {
nearestBBPin?: BBRowCol,
startColumn?: number,
cmpGPIOPins?: string[],
};
interface AllocWireOpts {
startColumn: number,
cmpGPIOPins: string[],
}
interface AllocBlock {
cmpIdx: number,
cmpBlkIdx: number,
gpioNeeded: number,
gpioAssigned: string[]
}
interface PowerUsage {
topGround: boolean,
topThreeVolt: boolean,
bottomGround: boolean,
bottomThreeVolt: boolean,
singleGround: boolean,
singleThreeVolt: boolean,
}
function isOnBreadboardBottom(location: WireLocationDefinition) {
let isBot = false;
if (location[0] === "breadboard") {
let row = <string>location[1];
isBot = 0 <= ["a", "b", "c", "d", "e"].indexOf(row);
}
return isBot;
}
const arrCount = (a: boolean[]) => a.reduce((p, n) => p + (n ? 1 : 0), 0);
const arrAny = (a: boolean[]) => arrCount(a) > 0;
function computePowerUsage(wireDef: WireDefinition): PowerUsage {
let ends = [wireDef.start, wireDef.end];
let endIsGround = ends.map(e => e === "ground");
let endIsThreeVolt = ends.map(e => e === "threeVolt");
let endIsBot = ends.map(e => isOnBreadboardBottom(e));
let hasGround = arrAny(endIsGround);
let hasThreeVolt = arrAny(endIsThreeVolt);
let hasBot = arrAny(endIsBot);
return {
topGround: hasGround && !hasBot,
topThreeVolt: hasThreeVolt && !hasBot,
bottomGround: hasGround && hasBot,
bottomThreeVolt: hasThreeVolt && hasBot,
singleGround: hasGround,
singleThreeVolt: hasThreeVolt
};
}
function mergePowerUsage(powerUsages: PowerUsage[]) {
let finalPowerUsage = powerUsages.reduce((p, n) => ({
topGround: p.topGround || n.topGround,
topThreeVolt: p.topThreeVolt || n.topThreeVolt,
bottomGround: p.bottomGround || n.bottomGround,
bottomThreeVolt: p.bottomThreeVolt || n.bottomThreeVolt,
singleGround: n.singleGround ? p.singleGround === null : p.singleGround,
singleThreeVolt: n.singleThreeVolt ? p.singleThreeVolt === null : p.singleThreeVolt,
}), {
topGround: false,
topThreeVolt: false,
bottomGround: false,
bottomThreeVolt: false,
singleGround: null,
singleThreeVolt: null,
});
if (finalPowerUsage.singleGround)
finalPowerUsage.topGround = finalPowerUsage.bottomGround = false;
if (finalPowerUsage.singleThreeVolt)
finalPowerUsage.topThreeVolt = finalPowerUsage.bottomThreeVolt = false;
return finalPowerUsage;
}
function copyDoubleArray(a: string[][]) {
return a.map(b => b.map(p => p));
}
function readPin(arg: string): string {
U.assert(!!arg, "Invalid pin: " + arg);
let pin = arg.split("DigitalPin.")[1];
return pin;
}
function mkReverseMap(map: {[key: string]: string}) {
let origKeys: string[] = [];
let origVals: string[] = [];
for (let key in map) {
origKeys.push(key);
origVals.push(map[key]);
}
let newMap: {[key: string]: string} = {};
for (let i = 0; i < origKeys.length; i++) {
let newKey = origVals[i];
let newVal = origKeys[i];
newMap[newKey] = newVal;
}
return newMap;
}
class Allocator {
private opts: AllocatorOpts;
private availablePowerPins = {
top: {
threeVolt: mkRange(26, 51).map(n => <BBRowCol>["+", `${n}`]),
ground: mkRange(26, 51).map(n => <BBRowCol>["-", `${n}`]),
},
bottom: {
threeVolt: mkRange(1, 26).map(n => <BBRowCol>["+", `${n}`]),
ground: mkRange(1, 26).map(n => <BBRowCol>["-", `${n}`]),
},
};
private powerUsage: PowerUsage;
constructor(opts: AllocatorOpts) {
this.opts = opts;
}
private allocateLocation(location: WireLocationDefinition, opts: AllocLocOpts): Loc {
if (location === "ground" || location === "threeVolt") {
//special case if there is only a single ground or three volt pin in the whole build
if (location === "ground" && this.powerUsage.singleGround) {
let boardGroundPin = this.getBoardGroundPin();
return {type: "dalboard", pin: boardGroundPin};
} else if (location === "threeVolt" && this.powerUsage.singleThreeVolt) {
let boardThreeVoltPin = this.getBoardThreeVoltPin();
return {type: "dalboard", pin: boardThreeVoltPin};
}
U.assert(!!opts.nearestBBPin);
let nearestCoord = this.opts.getBBCoord(opts.nearestBBPin);
let firstTopAndBot = [
this.availablePowerPins.top.ground[0] || this.availablePowerPins.top.threeVolt[0],
this.availablePowerPins.bottom.ground[0] || this.availablePowerPins.bottom.threeVolt[0]
].map(loc => {
return this.opts.getBBCoord(loc);
});
if (!firstTopAndBot[0] || !firstTopAndBot[1]) {
console.debug(`No more available "${location}" locations!`);
//TODO
}
let nearTop = visuals.findClosestCoordIdx(nearestCoord, firstTopAndBot) == 0;
let barPins: BBRowCol[];
if (nearTop) {
if (location === "ground") {
barPins = this.availablePowerPins.top.ground;
} else if (location === "threeVolt") {
barPins = this.availablePowerPins.top.threeVolt;
}
} else {
if (location === "ground") {
barPins = this.availablePowerPins.bottom.ground;
} else if (location === "threeVolt") {
barPins = this.availablePowerPins.bottom.threeVolt;
}
}
let pinCoords = barPins.map(rowCol => {
return this.opts.getBBCoord(rowCol);
});
let closestPinIdx = visuals.findClosestCoordIdx(nearestCoord, pinCoords);
let pin = barPins[closestPinIdx];
if (nearTop) {
this.availablePowerPins.top.ground.splice(closestPinIdx, 1);
this.availablePowerPins.top.threeVolt.splice(closestPinIdx, 1);
} else {
this.availablePowerPins.bottom.ground.splice(closestPinIdx, 1);
this.availablePowerPins.bottom.threeVolt.splice(closestPinIdx, 1);
}
return {type: "breadboard", rowCol: pin};
} else if (location[0] === "breadboard") {
U.assert(!!opts.startColumn);
let row = <string>location[1];
let col = (<number>location[2] + opts.startColumn).toString();
return {type: "breadboard", rowCol: [row, col]}
} else if (location[0] === "GPIO") {
U.assert(!!opts.cmpGPIOPins);
let idx = <number>location[1];
let pin = opts.cmpGPIOPins[idx];
return {type: "dalboard", pin: pin};
} else if (location === "MOSI" || location === "MISO" || location === "SCK") {
if (!this.opts.boardDef.spiPins)
console.debug("No SPI pin mappings found!");
let pin = (<any>this.opts.boardDef.spiPins)[location as string] as string;
return {type: "dalboard", pin: pin};
} else if (location === "SDA" || location === "SCL") {
if (!this.opts.boardDef.i2cPins)
console.debug("No I2C pin mappings found!");
let pin = (<any>this.opts.boardDef.i2cPins)[location as string] as string;
return {type: "dalboard", pin: pin};
} else {
//TODO
U.assert(false);
return null;
}
}
private getBoardGroundPin() {
let boardGround = this.opts.boardDef.groundPins[0] || null;
if (!boardGround) {
console.log("No available ground pin on board!");
//TODO
}
return boardGround;
}
private getBoardThreeVoltPin() {
let threeVoltPin = this.opts.boardDef.threeVoltPins[0] || null;
if (!threeVoltPin) {
console.log("No available 3.3V pin on board!");
//TODO
}
return threeVoltPin;
}
private allocatePowerWires(powerUsage: PowerUsage): WireInst[] {
let boardGroundPin = this.getBoardGroundPin();
let threeVoltPin = this.getBoardThreeVoltPin();
let topLeft: BBRowCol = ["-", "26"];
let botLeft: BBRowCol = ["-", "1"];
let topRight: BBRowCol = ["-", "50"];
let botRight: BBRowCol = ["-", "25"];
let top: BBRowCol, bot: BBRowCol;
if (this.opts.boardDef.attachPowerOnRight) {
top = topRight;
bot = botRight;
} else {
top = topLeft;
bot = botLeft;
}
const GROUND_COLOR = "blue";
const POWER_COLOR = "red";
const wires: WireInst[] = [];
let groundStep = 0;
let threeVoltStep = (powerUsage.bottomGround || powerUsage.topGround) ? 1 : 0;
if (powerUsage.bottomGround && powerUsage.topGround) {
//bb top - <==> bb bot -
wires.push({
start: this.allocateLocation("ground", {nearestBBPin: top}),
end: this.allocateLocation("ground", {nearestBBPin: bot}),
color: GROUND_COLOR, assemblyStep: groundStep
});
}
if (powerUsage.topGround) {
//board - <==> bb top -
wires.push({
start: this.allocateLocation("ground", {nearestBBPin: top}),
end: {type: "dalboard", pin: boardGroundPin},
color: GROUND_COLOR, assemblyStep: groundStep
});
} else if (powerUsage.bottomGround) {
//board - <==> bb bot -
wires.push({
start: this.allocateLocation("ground", {nearestBBPin: bot}),
end: {type: "dalboard", pin: boardGroundPin},
color: GROUND_COLOR, assemblyStep: groundStep
});
}
if (powerUsage.bottomThreeVolt && powerUsage.bottomGround) {
//bb top + <==> bb bot +
wires.push({
start: this.allocateLocation("threeVolt", {nearestBBPin: top}),
end: this.allocateLocation("threeVolt", {nearestBBPin: bot}),
color: POWER_COLOR, assemblyStep: threeVoltStep
});
}
if (powerUsage.topThreeVolt) {
//board + <==> bb top +
wires.push({
start: this.allocateLocation("threeVolt", {nearestBBPin: top}),
end: {type: "dalboard", pin: threeVoltPin},
color: POWER_COLOR, assemblyStep: threeVoltStep
});
} else if (powerUsage.bottomThreeVolt) {
//board + <==> bb bot +
wires.push({
start: this.allocateLocation("threeVolt", {nearestBBPin: bot}),
end: {type: "dalboard", pin: threeVoltPin},
color: POWER_COLOR, assemblyStep: threeVoltStep
});
}
return wires;
}
private allocateWire(wireDef: WireDefinition, opts: AllocWireOpts): WireInst {
let ends = [wireDef.start, wireDef.end];
let endIsPower = ends.map(e => e === "ground" || e === "threeVolt");
//allocate non-power first so we know the nearest pin for the power end
let endInsts = ends.map((e, idx) => !endIsPower[idx] ? this.allocateLocation(e, opts) : null)
//allocate power pins closest to the other end of the wire
endInsts = endInsts.map((e, idx) => {
if (e)
return e;
let locInst = <BBLoc>endInsts[1 - idx]; // non-power end
let l = this.allocateLocation(ends[idx], {
nearestBBPin: locInst.rowCol,
startColumn: opts.startColumn,
cmpGPIOPins: opts.cmpGPIOPins,
});
return l;
});
return {start: endInsts[0], end: endInsts[1], color: wireDef.color, assemblyStep: wireDef.assemblyStep};
}
private allocatePartialCmps(): PartialCmpAlloc[] {
let cmpNmAndDefs = this.opts.cmpList.map(cmpName => <[string, PartDefinition]>[cmpName, this.opts.cmpDefs[cmpName]]).filter(d => !!d[1]);
let cmpNmsList = cmpNmAndDefs.map(p => p[0]);
let cmpDefsList = cmpNmAndDefs.map(p => p[1]);
let partialCmps: PartialCmpAlloc[] = [];
cmpDefsList.forEach((def, idx) => {
let nm = cmpNmsList[idx];
if (def.pinAllocation.type === "predefined") {
let mbPins = (<PredefinedPinAlloc>def.pinAllocation).pins;
let pinsAssigned = mbPins.map(p => this.opts.boardDef.gpioPinMap[p]);
partialCmps.push({
name: nm,
def: def,
pinsAssigned: pinsAssigned,
pinsNeeded: 0,
breadboardColumnsNeeded: def.breadboardColumnsNeeded,
});
} else if (def.pinAllocation.type === "factoryfunction") {
let fnPinAlloc = (<FactoryFunctionPinAlloc>def.pinAllocation);
let fnNm = fnPinAlloc.functionName;
let fnsAndArgs = <string[]>this.opts.fnArgs[fnNm];
let success = false;
if (fnsAndArgs && fnsAndArgs.length) {
let pinArgPoses = fnPinAlloc.pinArgPositions;
let otherArgPoses = fnPinAlloc.otherArgPositions || [];
fnsAndArgs.forEach(fnArgsStr => {
let fnArgsSplit = fnArgsStr.split(",");
let pinArgs: string[] = [];
pinArgPoses.forEach(i => {
pinArgs.push(fnArgsSplit[i]);
});
let mbPins = pinArgs.map(arg => readPin(arg));
let otherArgs: string[] = [];
otherArgPoses.forEach(i => {
otherArgs.push(fnArgsSplit[i]);
});
let pinsAssigned = mbPins.map(p => this.opts.boardDef.gpioPinMap[p]);
partialCmps.push({
name: nm,
def: def,
pinsAssigned: pinsAssigned,
pinsNeeded: 0,
breadboardColumnsNeeded: def.breadboardColumnsNeeded,
otherArgs: otherArgs.length ? otherArgs : null,
});
});
} else {
// failed to find pin allocation from callsites
console.debug("Failed to read pin(s) from callsite for: " + fnNm);
let pinsNeeded = fnPinAlloc.pinArgPositions.length;
partialCmps.push({
name: nm,
def: def,
pinsAssigned: [],
pinsNeeded: pinsNeeded,
breadboardColumnsNeeded: def.breadboardColumnsNeeded,
});
}
} else if (def.pinAllocation.type === "auto") {
let pinsNeeded = (<AutoPinAlloc>def.pinAllocation).gpioPinsNeeded;
partialCmps.push({
name: nm,
def: def,
pinsAssigned: [],
pinsNeeded: pinsNeeded,
breadboardColumnsNeeded: def.breadboardColumnsNeeded,
});
}
});
return partialCmps;
}
private allocateGPIOPins(partialCmps: PartialCmpAlloc[]): string[][] {
let availableGPIOBlocks = copyDoubleArray(this.opts.boardDef.gpioPinBlocks);
let sortAvailableGPIOBlocks = () => availableGPIOBlocks.sort((a, b) => a.length - b.length); //smallest blocks first
// determine blocks needed
let blockAssignments: AllocBlock[] = [];
let preassignedPins: string[] = [];
partialCmps.forEach((cmp, idx) => {
if (cmp.pinsAssigned && cmp.pinsAssigned.length) {
//already assigned
blockAssignments.push({cmpIdx: idx, cmpBlkIdx: 0, gpioNeeded: 0, gpioAssigned: cmp.pinsAssigned});
preassignedPins = preassignedPins.concat(cmp.pinsAssigned);
} else if (cmp.pinsNeeded) {
if (typeof cmp.pinsNeeded === "number") {
//individual pins
for (let i = 0; i < cmp.pinsNeeded; i++) {
blockAssignments.push(
{cmpIdx: idx, cmpBlkIdx: 0, gpioNeeded: 1, gpioAssigned: []});
}
} else {
//blocks of pins
let blocks = <number[]>cmp.pinsNeeded;
blocks.forEach((numNeeded, blkIdx) => {
blockAssignments.push(
{cmpIdx: idx, cmpBlkIdx: blkIdx, gpioNeeded: numNeeded, gpioAssigned: []});
});
}
}
});
// remove assigned blocks
availableGPIOBlocks.forEach(blks => {
for (let i = blks.length - 1; 0 <= i; i--) {
let pin = blks[i];
if (0 <= preassignedPins.indexOf(pin)) {
blks.splice(i, 1);
}
}
});
// sort by size of blocks
let sortBlockAssignments = () => blockAssignments.sort((a, b) => b.gpioNeeded - a.gpioNeeded); //largest blocks first
// allocate each block
if (0 < blockAssignments.length && 0 < availableGPIOBlocks.length) {
do {
sortBlockAssignments();
sortAvailableGPIOBlocks();
let assignment = blockAssignments[0];
let smallestAvailableBlockThatFits: string[];
for (let j = 0; j < availableGPIOBlocks.length; j++) {
smallestAvailableBlockThatFits = availableGPIOBlocks[j];
if (assignment.gpioNeeded <= availableGPIOBlocks[j].length) {
break;
}
}
if (!smallestAvailableBlockThatFits || smallestAvailableBlockThatFits.length <= 0) {
break; // out of pins
}
while (0 < assignment.gpioNeeded && 0 < smallestAvailableBlockThatFits.length) {
assignment.gpioNeeded--;
let pin = smallestAvailableBlockThatFits[0];
smallestAvailableBlockThatFits.splice(0, 1);
assignment.gpioAssigned.push(pin);
}
sortBlockAssignments();
} while (0 < blockAssignments[0].gpioNeeded);
}
if (0 < blockAssignments.length && 0 < blockAssignments[0].gpioNeeded) {
console.debug("Not enough GPIO pins!");
return null;
}
let cmpGPIOPinBlocks: string[][][] = partialCmps.map((def, cmpIdx) => {
if (!def)
return null;
let assignments = blockAssignments.filter(a => a.cmpIdx === cmpIdx);
let gpioPins: string[][] = [];
for (let i = 0; i < assignments.length; i++) {
let a = assignments[i];
let blk = gpioPins[a.cmpBlkIdx] || (gpioPins[a.cmpBlkIdx] = []);
a.gpioAssigned.forEach(p => blk.push(p));
}
return gpioPins;
});
let cmpGPIOPins = cmpGPIOPinBlocks.map(blks => blks.reduce((p, n) => p.concat(n), []));
return cmpGPIOPins;
}
private allocateColumns(partialCmps: PartialCmpAlloc[]): number[] {
let componentsCount = partialCmps.length;
let totalAvailableSpace = 30; //TODO allow multiple breadboards
let totalSpaceNeeded = partialCmps.map(d => d.breadboardColumnsNeeded).reduce((p, n) => p + n, 0);
let extraSpace = totalAvailableSpace - totalSpaceNeeded;
if (extraSpace <= 0) {
console.log("Not enough breadboard space!");
//TODO
}
let padding = Math.floor(extraSpace / (componentsCount - 1 + 2));
let componentSpacing = padding; //Math.floor(extraSpace/(componentsCount-1));
let totalCmpPadding = extraSpace - componentSpacing * (componentsCount - 1);
let leftPadding = Math.floor(totalCmpPadding / 2);
let rightPadding = Math.ceil(totalCmpPadding / 2);
let nextAvailableCol = 1 + leftPadding;
let cmpStartCol = partialCmps.map(cmp => {
let col = nextAvailableCol;
nextAvailableCol += cmp.breadboardColumnsNeeded + componentSpacing;
return col;
});
return cmpStartCol;
}
private allocateComponent(partialCmp: PartialCmpAlloc, startColumn: number, microbitPins: string[]): CmpInst {
return {
name: partialCmp.name,
breadboardStartColumn: startColumn,
breadboardStartRow: partialCmp.def.breadboardStartRow,
assemblyStep: partialCmp.def.assemblyStep,
visual: partialCmp.def.visual,
microbitPins: microbitPins,
otherArgs: partialCmp.otherArgs,
};
}
public allocateAll(): AllocatorResult {
let cmpList = this.opts.cmpList;
let basicWires: WireInst[] = [];
let cmpsAndWires: CmpAndWireInst[] = [];
if (cmpList.length > 0) {
let partialCmps = this.allocatePartialCmps();
let allWireDefs = partialCmps.map(p => p.def.wires).reduce((p, n) => p.concat(n), []);
let allPowerUsage = allWireDefs.map(w => computePowerUsage(w));
this.powerUsage = mergePowerUsage(allPowerUsage);
basicWires = this.allocatePowerWires(this.powerUsage);
let cmpGPIOPins = this.allocateGPIOPins(partialCmps);
let reverseMap = mkReverseMap(this.opts.boardDef.gpioPinMap);
let cmpMicrobitPins = cmpGPIOPins.map(pins => pins.map(p => reverseMap[p]));
let cmpStartCol = this.allocateColumns(partialCmps);
let cmps = partialCmps.map((c, idx) => this.allocateComponent(c, cmpStartCol[idx], cmpMicrobitPins[idx]));
let wires = partialCmps.map((c, idx) => c.def.wires.map(d => this.allocateWire(d, {
cmpGPIOPins: cmpGPIOPins[idx],
startColumn: cmpStartCol[idx],
})));
cmpsAndWires = cmps.map((c, idx) => {
return {component: c, wires: wires[idx]}
});
}
return {
powerWires: basicWires,
components: cmpsAndWires
};
}
}
export function allocateDefinitions(opts: AllocatorOpts): AllocatorResult {
return new Allocator(opts).allocateAll();
}
}

View File

@ -1,12 +1,7 @@
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
namespace pxsim {
export class DalBoard extends BaseBoard {
id: string;
// the bus
bus: EventBus;
export class DalBoard extends CoreBoard {
// state & update logic for component services
ledMatrixState: LedMatrixState;
edgeConnectorState: EdgeConnectorState;
@ -19,31 +14,58 @@ namespace pxsim {
radioState: RadioState;
neopixelState: NeoPixelState;
// updates
updateSubscribers: (() => void)[];
constructor() {
super()
this.id = "b" + Math_.random(2147483647);
this.bus = new EventBus(runtime);
// components
this.ledMatrixState = new LedMatrixState(runtime);
this.buttonPairState = new ButtonPairState();
this.edgeConnectorState = new EdgeConnectorState();
this.radioState = new RadioState(runtime);
this.accelerometerState = new AccelerometerState(runtime);
this.serialState = new SerialState();
this.thermometerState = new ThermometerState();
this.lightSensorState = new LightSensorState();
this.compassState = new CompassState();
this.neopixelState = new NeoPixelState();
this.builtinParts["ledmatrix"] = this.ledMatrixState = new LedMatrixState(runtime);
this.builtinParts["buttonpair"] = this.buttonPairState = new ButtonPairState({
ID_BUTTON_A: DAL.MICROBIT_ID_BUTTON_A,
ID_BUTTON_B: DAL.MICROBIT_ID_BUTTON_B,
ID_BUTTON_AB: DAL.MICROBIT_ID_BUTTON_AB,
BUTTON_EVT_UP: DAL.MICROBIT_BUTTON_EVT_UP,
BUTTON_EVT_CLICK: DAL.MICROBIT_BUTTON_EVT_CLICK
});
this.builtinParts["edgeconnector"] = this.edgeConnectorState = new EdgeConnectorState({
pins: [
DAL.MICROBIT_ID_IO_P0,
DAL.MICROBIT_ID_IO_P1,
DAL.MICROBIT_ID_IO_P2,
DAL.MICROBIT_ID_IO_P3,
DAL.MICROBIT_ID_IO_P4,
DAL.MICROBIT_ID_IO_P5,
DAL.MICROBIT_ID_IO_P6,
DAL.MICROBIT_ID_IO_P7,
DAL.MICROBIT_ID_IO_P8,
DAL.MICROBIT_ID_IO_P9,
DAL.MICROBIT_ID_IO_P10,
DAL.MICROBIT_ID_IO_P11,
DAL.MICROBIT_ID_IO_P12,
DAL.MICROBIT_ID_IO_P13,
DAL.MICROBIT_ID_IO_P14,
DAL.MICROBIT_ID_IO_P15,
DAL.MICROBIT_ID_IO_P16,
0,
0,
DAL.MICROBIT_ID_IO_P19,
DAL.MICROBIT_ID_IO_P20
]
});
this.builtinParts["radio"] = this.radioState = new RadioState(runtime);
this.builtinParts["accelerometer"] = this.accelerometerState = new AccelerometerState(runtime);
this.builtinParts["serial"] = this.serialState = new SerialState();
this.builtinParts["thermometer"] = this.thermometerState = new ThermometerState();
this.builtinParts["lightsensor"] = this.lightSensorState = new LightSensorState();
this.builtinParts["compass"] = this.compassState = new CompassState();
this.builtinParts["neopixel"] = this.neopixelState = new NeoPixelState();
// updates
this.updateSubscribers = []
this.updateView = () => {
this.updateSubscribers.forEach(sub => sub());
}
this.builtinVisuals["buttonpair"] = () => new visuals.ButtonPairView();
this.builtinVisuals["ledmatrix"] = () => new visuals.LedMatrixView();
this.builtinVisuals["neopixel"] = () => new visuals.NeoPixelView();
this.builtinPartVisuals["buttonpair"] = (xy: visuals.Coord) => visuals.mkBtnSvg(xy);
this.builtinPartVisuals["ledmatrix"] = (xy: visuals.Coord) => visuals.mkLedMatrixSvg(xy, 8, 8);
this.builtinPartVisuals["neopixel"] = (xy: visuals.Coord) => visuals.mkNeoPixelPart(xy);
}
receiveMessage(msg: SimulatorMessage) {
@ -65,31 +87,26 @@ namespace pxsim {
}
}
kill() {
super.kill();
AudioContextManager.stop();
}
initAsync(msg: SimulatorRunMessage): Promise<void> {
super.initAsync(msg);
let options = (msg.options || {}) as RuntimeOptions;
const options = (msg.options || {}) as RuntimeOptions;
let boardDef = CURRENT_BOARD; //TODO: read from pxt.json/pxttarget.json
const boardDef = msg.boardDefinition;
const cmpsList = msg.parts;
const cmpDefs = msg.partDefinitions || {};
const fnArgs = msg.fnArgs;
let cmpsList = msg.parts;
let cmpDefs = msg.partDefinitions || {}; //TODO: read from pxt.json/pxttarget.json
let fnArgs = msg.fnArgs;
let viewHost = new visuals.BoardHost({
const opts : visuals.BoardHostOpts = {
state: this,
boardDef: boardDef,
cmpsList: cmpsList,
cmpDefs: cmpDefs,
partsList: cmpsList,
partDefs: cmpDefs,
fnArgs: fnArgs,
maxWidth: "100%",
maxHeight: "100%",
});
};
const viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView(opts), opts);
document.body.innerHTML = ""; // clear children
document.body.appendChild(viewHost.getView());
@ -97,4 +114,37 @@ namespace pxsim {
return Promise.resolve();
}
}
export function initRuntimeWithDalBoard() {
U.assert(!runtime.board);
let b = new DalBoard();
runtime.board = b;
runtime.postError = (e) => {
led.setBrightness(255);
let img = board().ledMatrixState.image;
img.clear();
img.set(0, 4, 255);
img.set(1, 3, 255);
img.set(2, 3, 255);
img.set(3, 3, 255);
img.set(4, 4, 255);
img.set(0, 0, 255);
img.set(1, 0, 255);
img.set(0, 1, 255);
img.set(1, 1, 255);
img.set(3, 0, 255);
img.set(4, 0, 255);
img.set(3, 1, 255);
img.set(4, 1, 255);
runtime.updateDisplay();
}
}
if (!pxsim.initCurrentRuntime) {
pxsim.initCurrentRuntime = initRuntimeWithDalBoard;
}
export function board() {
return runtime.board as DalBoard;
}
}

View File

@ -1,81 +0,0 @@
/// <reference path="../node_modules/pxt-core/typings/bluebird/bluebird.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtparts.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
/// <reference path="../libs/microbit/dal.d.ts"/>
/// <reference path="./visuals/neopixel.ts"/>
namespace pxsim {
export const MICROBIT_DEF: BoardDefinition = {
visual: "microbit",
gpioPinBlocks: [
["P0"], ["P1"], ["P2"],
["P3"],
["P4", "P5", "P6", "P7"],
["P8", "P9", "P10", "P11", "P12"],
["P16"],
],
gpioPinMap: {
"P0": "P0",
"P1": "P1",
"P2": "P2",
"P3": "P3",
"P4": "P4",
"P5": "P5",
"P6": "P6",
"P7": "P7",
"P8": "P8",
"P9": "P9",
"P10": "P10",
"P11": "P11",
"P12": "P12",
"P13": "P13",
"P14": "P14",
"P15": "P15",
"P16": "P16",
"P19": "P19",
"P20": "P20",
},
spiPins: {
MOSI: "P15",
MISO: "P14",
SCK: "P13",
},
i2cPins: {
SDA: "P20",
SCL: "P19",
},
analogInPins: ["P0", "P1", "P2", "P3", "P10"],
groundPins: ["GND"],
threeVoltPins: ["+3v3"],
attachPowerOnRight: true,
onboardComponents: ["buttonpair", "ledmatrix", "speaker"],
useCrocClips: true,
marginWhenBreadboarding: [0, 0, 80, 0],
}
export const builtinComponentSimVisual: Map<() => visuals.IBoardComponent<any>> = {
"buttonpair": () => new visuals.ButtonPairView(),
"ledmatrix": () => new visuals.LedMatrixView(),
"neopixel": () => new visuals.NeoPixelView(),
};
export const builtinComponentSimState: Map<(d: DalBoard) => any> = {
"buttonpair": (d: DalBoard) => d.buttonPairState,
"ledmatrix": (d: DalBoard) => d.ledMatrixState,
"edgeconnector": (d: DalBoard) => d.edgeConnectorState,
"serial": (d: DalBoard) => d.serialState,
"radio": (d: DalBoard) => d.radioState,
"thermometer": (d: DalBoard) => d.thermometerState,
"accelerometer": (d: DalBoard) => d.accelerometerState,
"compass": (d: DalBoard) => d.compassState,
"lightsensor": (d: DalBoard) => d.lightSensorState,
"neopixel": (d: DalBoard) => d.neopixelState,
};
export const builtinComponentPartVisual: Map<(xy: visuals.Coord) => visuals.SVGElAndSize> = {
"buttonpair": (xy: visuals.Coord) => visuals.mkBtnSvg(xy),
"ledmatrix": (xy: visuals.Coord) => visuals.mkLedMatrixSvg(xy, 8, 8),
"neopixel": (xy: visuals.Coord) => visuals.mkNeoPixelPart(xy),
};
//TODO: add multiple board support
export const CURRENT_BOARD = MICROBIT_DEF;
}

Some files were not shown because too many files have changed in this diff Show More