Compare commits

...

106 Commits

Author SHA1 Message Date
355c341d36 0.6.32 2016-12-08 10:56:49 -08:00
1adb4a2bac Bump pxt-core to 0.5.95 2016-12-08 10:56:46 -08:00
03c0339e9a fixing docs snippets 2016-12-08 09:16:27 -08:00
1649811015 expose "delete" in blocks.
fix for https://github.com/Microsoft/pxt/issues/870
2016-12-08 08:54:05 -08:00
14f16f9b2c expose game.setScore in blocks
fix for https://github.com/Microsoft/pxt/issues/881
2016-12-08 08:51:18 -08:00
66d3c6c7e8 fix for https://github.com/Microsoft/pxt/issues/549 2016-12-08 08:28:28 -08:00
7f27432222 Merge branch 'master' of https://github.com/Microsoft/pxt-microbit 2016-12-08 00:12:49 -08:00
870b26a85a updated lessons to use radio 2016-12-08 00:10:00 -08:00
aa6cb58dca Merge pull request #320 from Microsoft/delete
Placement new occurances need explicit delete
2016-12-07 18:09:35 -08:00
6398a42dad Placement new occurances need explicit delete 2016-12-07 18:00:03 -08:00
21473f5b9b Fixing array deallocation leak (#317)
* Fixing array deallocation leak

* Moving delete down to the individual destroy methods
2016-12-07 15:44:35 -08:00
c85b6f9507 using calibrated powers for Eddystone 2016-12-07 11:37:33 -08:00
019b00209e moving blocks to advanced 2016-12-07 09:49:19 -08:00
6c11dbcdf4 added setTransmitPower in BLE 2016-12-07 09:05:03 -08:00
91197c5cec updated BLE settings 2016-12-07 08:07:08 -08:00
9e5d9787c7 linking to pxt issue tracker 2016-12-06 21:51:51 -08:00
1c11a4823b adjusting the blockly flyout opacity. 2016-12-06 21:48:21 -08:00
d457c3e8d0 exposing delete in blocks 2016-12-06 16:19:35 -08:00
2ae21efb7b Moving blockly toolbox button margins to target. 2016-12-06 15:06:16 -08:00
485a42758c 0.6.31 2016-12-06 11:32:24 -08:00
0da5a5a349 Bump pxt-core to 0.5.91 2016-12-06 11:32:22 -08:00
41ce2f66fa removing add package less variable 2016-12-05 23:55:46 -08:00
9393fc166e Styling add package and undo blockly buttons 2016-12-05 21:24:57 -08:00
cfb4382941 support for monaco toolbox 2016-12-05 19:01:14 -08:00
aaca24ff5b using add package color less variable 2016-12-05 18:09:23 -08:00
0ce9be1a2b removing toolbox right border. 2016-12-05 17:59:20 -08:00
a88eb7fe02 Changing main menu color, primary color and adding tiny borders around blockly toolbox 2016-12-05 17:30:04 -08:00
06e4f7fb5c Updated BLE project settings 2016-12-05 15:33:40 -08:00
1b36485208 0.6.30 2016-12-05 15:10:13 -08:00
3b54cefa95 Merge branch 'master' of https://github.com/Microsoft/pxt-microbit 2016-12-05 15:02:51 -08:00
52857c9541 added beacon configuration 2016-12-05 15:02:39 -08:00
d10c2a20bd More IE fixes. Using important to override blocky related CSS. 2016-12-05 13:43:57 -08:00
e2482cdf91 0.6.29 2016-12-05 13:22:06 -08:00
c045d87e4c Bump pxt-core to 0.5.90 2016-12-05 13:22:03 -08:00
34e23934b0 better bluetooth settings 2016-12-05 13:02:11 -08:00
354196e01e missing block annotation on led.enable 2016-12-05 09:17:42 -08:00
bb2e8d0aef 'devices' depends on 'bluetooth' 2016-12-05 09:05:54 -08:00
90f4e895d4 0.6.28 2016-12-03 23:22:42 -08:00
58c554caa6 Bump pxt-core to 0.5.88 2016-12-03 23:22:40 -08:00
6c688a7e59 Fix Edge / IE issue where the blockly toolbox background isn't respected. 2016-12-02 18:33:42 -08:00
71244065bb 0.6.27 2016-12-02 13:20:00 -08:00
bbb1bc3dd7 Merge pull request #314 from Microsoft/pr/theming
Theming the microbit target
2016-12-02 13:18:10 -08:00
806d0e2cff 0.6.26 2016-12-02 12:58:15 -08:00
e0c4af1cae Bump pxt-core to 0.5.87 2016-12-02 12:58:13 -08:00
475821564e fixing justworks support 2016-12-02 09:45:59 -08:00
9d65dd605b Monaco editor theming. 2016-12-01 22:05:37 -08:00
67eec44411 Minor fixes. 2016-12-01 21:58:16 -08:00
280b555f86 Theming the microbit target 2016-12-01 18:35:10 -08:00
2fcd32de0d 0.6.25 2016-11-30 23:36:40 -08:00
78694e86a2 0.6.24 2016-11-30 16:07:34 -08:00
aeaa3d7bc1 updated localization files 2016-11-30 16:07:04 -08:00
af8ce3fccf allow for double, breve note durations 2016-11-30 16:06:17 -08:00
47ef096b0f 0.6.23 2016-11-30 11:05:33 -08:00
86c5c27b12 Bump pxt-core to 0.5.85 2016-11-30 11:05:31 -08:00
520c9217a5 Merge pull request #313 from Microsoft/packageconfigs
support for specifying different pairings
2016-11-30 10:54:14 -08:00
4a34f2b932 support for specifying different pairings 2016-11-30 10:35:42 -08:00
034897b0a6 fixing docs issues 2016-11-30 05:00:34 -08:00
b504abc6da 0.6.22 2016-11-30 04:55:33 -08:00
6dbfb9e96e Bump pxt-core to 0.5.84 2016-11-30 04:55:31 -08:00
d1021a30ca Merge pull request #312 from Microsoft/eddystone
Eddystone
2016-11-30 04:55:08 -08:00
8d37be7cbe use optional config to allow override flags in referenced project 2016-11-30 04:35:24 -08:00
97066e1ba4 enabling justworks pairing mode for bluetooth 2016-11-30 04:30:53 -08:00
097564748c fixing simulator 2016-11-30 04:27:08 -08:00
d873cbb6c3 updated api definitions 2016-11-30 04:24:52 -08:00
adef3a6487 updated docs 2016-11-30 04:19:17 -08:00
be0984cc4a integrating eddystone into bluetooth package 2016-11-30 04:06:15 -08:00
f0947cddaa updated signatures 2016-11-29 23:39:52 -08:00
c5c5362b5d Merge branch 'master' into eddystone 2016-11-29 23:27:49 -08:00
bcbbb1366a Merge pull request #311 from Microsoft/coregone
merging ksbit.h into pxt.h
2016-11-29 23:26:24 -08:00
19fb5ecf01 merging ksbit.h into pxt.h 2016-11-29 21:35:26 -08:00
0401aa60d2 Merge pull request #310 from Microsoft/coregone
merging pxt-microbit-core into the target
2016-11-29 15:23:02 -08:00
e0c016fbf4 moving definition out of ksbit.h 2016-11-29 15:15:22 -08:00
f046f0e50c merging pxt-microbit-core into the target 2016-11-29 15:06:34 -08:00
90f48ac77a Enable reference help switch in javascript editor. 2016-11-29 14:53:26 -08:00
23f83df6df Merge pull request #309 from Microsoft/musicpin
support for setting music pin using analogSetPitchPin
2016-11-29 13:41:16 -08:00
98e4f80399 updated crowdin info 2016-11-29 13:12:32 -08:00
b1fcc51bc8 preparing support for eddystone 2016-11-29 09:21:23 -08:00
63e24ce90a support for setting music pin using analogSetPitchPin 2016-11-29 08:59:54 -08:00
63d0b86508 0.6.21 2016-11-29 00:04:43 -08:00
672f3b94ca Bump pxt-core to 0.5.81 2016-11-29 00:04:41 -08:00
f0b91b07c1 fix typo 2016-11-29 00:04:21 -08:00
2923d045b1 0.6.20 2016-11-28 22:59:39 -08:00
3cf36b4549 Bump pxt-core to 0.5.80 2016-11-28 22:59:38 -08:00
a42aa553e6 Merge pull request #308 from Microsoft/cmdsbuild
fixing imports in cmds.ts
2016-11-28 22:50:05 -08:00
b12598e421 working around import issue 2016-11-28 22:07:40 -08:00
9a85075456 0.6.19 2016-11-28 21:24:44 -08:00
ce7b630870 Bump pxt-core to 0.5.79 2016-11-28 21:24:41 -08:00
9ac308da92 0.6.18 2016-11-28 21:11:21 -08:00
6315ca90e5 Bump pxt-core to 0.5.78 2016-11-28 21:11:19 -08:00
ecfe0a7f16 0.6.17 2016-11-28 20:44:04 -08:00
f701bca23f Bump pxt-core to 0.5.77 2016-11-28 20:44:02 -08:00
7313c76e8b Updating with the MIT license text and contributing guideline 2016-11-28 17:11:45 -08:00
77003b30f2 fixed scroll-image reference 2016-11-28 11:38:37 -08:00
274bb9e042 0.6.16 2016-11-17 05:47:13 -08:00
e316f068e2 Bump pxt-core to 0.5.76 2016-11-17 05:47:11 -08:00
c75e77593a adding loc annotations 2016-11-17 05:30:10 -08:00
ecbf8409ea Merge pull request #307 from Microsoft/scrollimage
Fixing scrollImage to actually scroll
2016-11-17 04:44:44 -08:00
411fe52813 Fixing scrollimage to actually scroll. 2016-11-16 18:16:49 -08:00
0d04376413 0.6.15 2016-11-15 20:10:08 -08:00
5deffe832c Bump pxt-core to 0.5.75 2016-11-15 20:10:07 -08:00
528f696b8c Removing gettingStarted property from pxtarget.json. Using sideDoc instead. 2016-11-14 14:24:21 -08:00
dfb5f7dd11 0.6.14 2016-11-14 07:13:33 -08:00
a4fb934a18 Bump pxt-core to 0.5.73 2016-11-14 07:13:31 -08:00
59b11ec2a9 Updating the mutate attribute of radio block (#306) 2016-11-14 07:12:24 -08:00
d961e14e5c bumped to 0.6.13 2016-11-11 15:14:54 -08:00
22433317b9 Updating the mutate attribute of radio block 2016-11-11 08:16:27 -08:00
56 changed files with 2311 additions and 283 deletions

26
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,26 @@
# Contributing Code
PXT accepts bug fix pull requests. For a bug fix PR to be accepted, it must first have a tracking issue that has been marked approved. Your PR should link to the bug you are fixing. If you've submitted a PR for a bug, please post a comment in the bug to avoid duplication of effort.
PXT also accepts new feature pull requests. For a feature-level PR to be accepted, it first needs to have design discussion. Design discussion can take one of two forms a) a feature request in the issue tracker that has been marked as approved or b) the PR must be accompanied by a full design spec and this spec is later approved in the open design discussion. Features are evaluated against their complexity, impact on other features, roadmap alignment, and maintainability.
These two blogs posts on contributing code to open source projects are a good reference: [Open Source Contribution Etiquette](http://tirania.org/blog/archive/2010/Dec-31.html) by Miguel de Icaza and [Don't "Push" Your Pull Requests](https://www.igvita.com/2011/12/19/dont-push-your-pull-requests/) by Ilya Grigorik.
## Security
If you believe you have found a security issue in PXT, please share it with us privately following the guidance at the Microsoft [Security TechCenter](https://technet.microsoft.com/en-us/security/ff852094). Reporting it via this channel helps minimize risk to projects built with PXT.
## Legal
You will need to complete a Contributor License Agreement (CLA) before your pull request can be accepted. This agreement testifies that you are granting us permission to use the source code you are submitting, and that this work is being submitted under appropriate license that we can use it.
You can complete the CLA by going through the steps at https://cla.microsoft.com. Once we have received the signed CLA, we'll review the request. You will only need to do this once.
## Housekeeping
Your pull request should:
* Include a description of what your change intends to do
* Be a child commit of a reasonably recent commit in the master branch
* Pass all unit tests
* Have a clear commit message
* Include adequate tests

25
LICENSE.txt Normal file
View File

@ -0,0 +1,25 @@
PXT - Programming Experience Toolkit
The MIT License (MIT)
Copyright (c) Microsoft Corporation
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -7,6 +7,10 @@ PXT ([Microsoft Programming Experience Toolkit](https://github.com/Microsoft/pxt
[![Build Status](https://travis-ci.org/Microsoft/pxt-microbit.svg?branch=master)](https://travis-ci.org/Microsoft/pxt-microbit)
## Issue tracking
All issue tracking for this repo happens at https://github.com/Microsoft/pxt, see you there!
## Local server
The local server allows to run the editor and the documentation from your computer.

View File

@ -1,4 +1,5 @@
/// <reference path="../node_modules/pxt-core/built/pxt.d.ts"/>
/// <reference path="../node_modules/pxt-core/typings/node/node.d.ts"/>
/// <reference path="../node_modules/pxt-core/built/pxtlib.d.ts" />
import * as fs from "fs";
import * as path from "path";

View File

@ -1,6 +1,6 @@
# Blocks language
### @description Langugage constructs for the Block editor.
### @description Language constructs for the Block editor.
```namespaces
for (let i = 0;i<5;++i) {}

View File

@ -1,3 +1,3 @@
{
"appref": "v0.5.33"
"appref": "v0.6.13"
}

View File

@ -10,12 +10,10 @@ Welcome! This guided tutorial will show you how to program a script that display
### ~
## Step 1
Create a loop that will continuously update the reading of the compass.
```blocks
basic.forever(() => {

View File

@ -2,8 +2,7 @@
### ~avatar avatar
Use the LEDs to display a flashing heart, and then create
an animation of a broken heart. :(
Use the LEDs to display a flashing heart!
### ~
@ -38,19 +37,19 @@ basic.clearScreen();
## Step 3
Put a [forever loop](/reference/basic/forever) around it.
Put a [forever loop](/reference/basic/forever) around it to repeat the animation.
```blocks
basic.forever(() => {
basic.showLeds(`
. # . # .
# # # # #
# # # # #
. # # # .
. . # . .`
);
basic.pause(500);
basic.clearScreen();
basic.showLeds(`
. # . # .
# # # # #
# # # # #
. # # # .
. . # . .`
);
basic.pause(500);
basic.clearScreen();
})
```
@ -60,45 +59,50 @@ Add a [pause](/reference/basic/pause) to wait after clearing the screen.
```blocks
basic.forever(() => {
basic.showLeds(`
. # . # .
# # # # #
# # # # #
. # # # .
. . # . .`
);
basic.pause(500);
basic.clearScreen();
basic.pause(500);
basic.showLeds(`
. # . # .
# # # # #
# # # # #
. # # # .
. . # . .`
);
basic.pause(500);
basic.clearScreen();
basic.pause(500);
})
```
## Step 5
## Send your heartbeats over radio!
Add a second image of a broken heart.
Do you have a second @boardname@ at hand? You could use radio and send your heartbeats to other
@boardname@ and show a heart when you receive one.
* move the code in the **forever** inside
a [on data packet received](/reference/radio/on-data-packet-received) handler.
The handler will run whenever a message is received from another @boardname@.
* use [send number](/reference/radio/send-number) and [pause](/reference/basic/pause)
to broadcast a packet of data every second.
```blocks
basic.forever(() => {
basic.showLeds(`
. # . # .
# # # # #
# # # # #
. # # # .
. . # . .`
);
basic.pause(500);
basic.clearScreen();
basic.pause(500);
basic.showLeds(`
. # . # .
# . # # #
# . . . #
. # # # .
. . # . .`
);
basic.pause(500);
basic.clearScreen();
basic.pause(500);
radio.sendNumber(0)
basic.pause(1000)
})
radio.onDataPacketReceived(({receivedNumber}) => {
basic.showLeds(`
. # . # .
# # # # #
# # # # #
. # # # .
. . # . .`);
basic.pause(500)
basic.clearScreen()
basic.pause(500)
})
```
Download the .hex file onto both @boardname@ and try it out!
```package
radio
```

View File

@ -12,8 +12,8 @@ Use [show leds](/reference/basic/show-leds) to make a smiley face:
```blocks
basic.showLeds(`
. # . # .
. # . # .
# # . # #
# # . # #
. . . . .
# . . . #
. # # # .`
@ -22,56 +22,93 @@ basic.showLeds(`
## Step 2
Add an input block for when [button A is pressed](/reference/input/button-is-pressed), and put a
frowny face inside it:
Add an input block for when [button A is pressed](/reference/input/button-is-pressed),
and **move** the smiley face inside it:
```blocks
basic.showLeds(`
. # . # .
. # . # .
. . . . .
# . . . #
. # # # .`
);
input.onButtonPressed(Button.A, () => {
basic.showLeds(`
. # . # .
. # . # .
. . . . .
. # # # .
# . . . #`
);
});
```
## Step 3
Now add blocks so that when [button B is pressed](/reference/input/button-is-pressed), a smiley appears:
```blocks
basic.showLeds(`
. # . # .
. # . # .
. . . . .
# . . . #
. # # # .`
);
input.onButtonPressed(Button.A, () => {
basic.showLeds(`
. # . # .
. # . # .
. . . . .
. # # # .
# . . . #`
);
});
input.onButtonPressed(Button.B, () => {
basic.showLeds(`
. # . # .
. # . # .
# # . # #
# # . # #
. . . . .
# . . . #
. # # # .`
);
});
```
Try pressing button A!
## Step 3
Now add blocks so that when [button B is pressed](/reference/input/on-button-pressed),
a frowney appears:
```blocks
input.onButtonPressed(Button.A, () => {
basic.showLeds(`
# # . # #
# # . # #
. . . . .
# . . . #
. # # # .`
);
});
input.onButtonPressed(Button.B, () => {
basic.showLeds(`
# # . # #
# # . # #
. . . . .
. # # # .
# . . . #`
);
});
```
Try pressing ``A`` or ``B``!
## Send your smileys over radio
Do you have a second @boardname@ at hand? You could use radio and send your smileys or frownies to other
@boardname@.
Since radio can send numbers, we decide that ``0`` is the code for displaying a smiley
and ``1`` is the code for a frowney.
Change your code as follows:
* [radio send number](/reference/radio/send-number) sends a number
to any other @boardname@ in range
* [radio on data packet received](/reference/radio/on-data-packet-received) runs code
when data is received over radio
```blocks
input.onButtonPressed(Button.A, () => {
radio.sendNumber(0)
})
input.onButtonPressed(Button.B, () => {
radio.sendNumber(1)
})
radio.onDataPacketReceived(({receivedNumber}) => {
if (receivedNumber == 0) {
basic.showLeds(`
# # . # #
# # . # #
. . . . .
# . . . #
. # # # .
`)
} else {
basic.showLeds(`
# # . # #
# # . # #
. . . . .
. # # # .
# . . . #
`)
}
})
```
```package
radio
```

View File

@ -30,7 +30,7 @@ control.inBackground(() => {
```
## Bluetooth
```namespaces
devices.tellCameraTo(MesCameraEvent.TakePhoto);
bluetooth.onBluetoothConnected(() => {});

View File

@ -19,6 +19,7 @@ bluetooth.startMagnetometerService();
bluetooth.startTemperatureService();
bluetooth.onBluetoothConnected(() => {});
bluetooth.onBluetoothDisconnected(() => {});
bluetooth.setTransmitPower(7);
```
## UART
@ -31,6 +32,13 @@ bluetooth.uartWriteNumber(0);
bluetooth.uartWriteValue("", 0);
```
## Eddystone
```cards
bluetooth.advertiseUrl("https://pxt.microbit.org/", 7);
bluetooth.stopAdvertising();
```
```package
bluetooth
```
@ -47,4 +55,7 @@ For more advanced information on the @boardname@ Bluetooth UART service includin
[uartWriteString](/reference/bluetooth/uart-write-string),
[uartWriteNumber](/reference/bluetooth/uart-write-number),
[uartWriteValue](/reference/bluetooth/uart-write-value),
[onBluetoothConnected](/reference/bluetooth/on-bluetooth-connected), [onBluetoothDisconnected](/reference/bluetooth/on-bluetooth-disconnected)
[onBluetoothConnected](/reference/bluetooth/on-bluetooth-connected),
[onBluetoothDisconnected](/reference/bluetooth/on-bluetooth-disconnected),
[advertiseUrl](/reference/bluetooth/advertise-url),
[stopAdvertising](/reference/bluetooth/stop-advertising)

View File

@ -0,0 +1,41 @@
# Avertise Url
Advertises a URL via the Eddystone protocol over Bluetooth.
## ~hint
### Eddystone
Bluetooth beacons are used to indicate proximity to a place or object of interest.
Beacons use Bluetooth advertising to broadcast a small amount of data,
which can be received and acted upon by anyone in range with a suitable device and software, typically a smartphone and application.
There are various beacon message formats, which define the way Bluetooth advertising packets are used as containers for beacon data.
iBeacon is Apple's beacon message format. Eddystone comes from Google.
Read more at https://lancaster-university.github.io/microbit-docs/ble/eddystone/ .
## ~
```sig
bluetooth.advertiseUrl("https://pxt.microbit.org/", 7, true);
```
### Parameters
* ``url`` - a [string](/reference/types/string) containing the URL to broadcast, at most 18 characters long
* ``power`` - a [number](/reference/types/number) representing the power level between 0 (short) and 7 (maximum range).
### Example: Broadcast a secret code
```blocks
bluetooth.advertiseUrl("https://pxt.io?secret=42", 7, true);
```
## See Also
[stop-advertising](/reference/bluetooth/stop-advertising)
```package
bluetooth
```

View File

@ -0,0 +1,26 @@
# Bluetooth Set Transmit Power
### ~hint
![](/static/bluetooth/Bluetooth_SIG.png)
For another device like a smartphone to use any of the Bluetooth "services" which the @boardname@ has, it must first be [paired with the @boardname@](/reference/bluetooth/bluetooth-pairing). Once paired, the other device may connect to the @boardname@ and exchange data relating to many of the @boardname@'s features.
### ~
Change the output power level of the transmitter to the given value.
```sig
bluetooth.setTransmitPower(7);
```
### Parameters
* `power`: a [number](/reference/types/number) in the range ``0..7``, where ``0`` is the lowest power and ``7`` is the highest.
### See also
[About Bluetooth](/reference/bluetooth/about-bluetooth), [@boardname@ Bluetooth profile overview ](http://lancaster-university.github.io/microbit-docs/ble/profile/), [@boardname@ Bluetooth profile reference](http://lancaster-university.github.io/microbit-docs/resources/bluetooth/microbit-profile-V1.9-Level-2.pdf), [Bluetooth on @boardname@ resources](http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html), [Bluetooth SIG](https://www.bluetooth.com)
```package
bluetooth
```

View File

@ -0,0 +1,38 @@
# Stop Advertising
Stops advertising URL via the Eddystone protocol over Bluetooth.
## ~hint
### Eddystone
Bluetooth beacons are used to indicate proximity to a place or object of interest.
Beacons use Bluetooth advertising to broadcast a small amount of data,
which can be received and acted upon by anyone in range with a suitable device and software, typically a smartphone and application.
There are various beacon message formats, which define the way Bluetooth advertising packets are used as containers for beacon data.
iBeacon is Apple's beacon message format. Eddystone comes from Google.
Read more at https://lancaster-university.github.io/microbit-docs/ble/eddystone/ .
## ~
```sig
bluetooth.stopAdvertising();
```
### Example: stop advertising on button pressed
```blocks
input.onButtonPressed(Button.A, () => {
bluetooth.stopAdvertising();
})
```
## See Also
[advertise-url](/reference/bluetooth/advertise-url)
```package
bluetooth
```

View File

@ -25,6 +25,15 @@ let freq = music.noteFrequency(Note.C)
music.playTone(freq, 1000)
```
### Using other pins
Use [analogSetPitchPin](/reference/pins/analog-set-pitch-pin) to change that pin used to generate music.
```blocks
pins.analogSetPitchPin(AnalogPin.P1);
```
### See also
[rest](/reference/music/rest), [ring tone](/reference/music/ring-tone) , [tempo](/reference/music/tempo), [set tempo](/reference/music/set-tempo),

View File

@ -32,6 +32,14 @@ basic.forever(() => {
})
```
### Using other pins
Use [analogSetPitchPin](/reference/pins/analog-set-pitch-pin) to change that pin used to generate music.
```blocks
pins.analogSetPitchPin(AnalogPin.P1);
```
### See also
[rest](/reference/music/rest), [play tone](/reference/music/play-tone),

View File

@ -1,6 +1,7 @@
# Analog Pitch
Emits a Pulse With Modulation (PWM) signal to the current pitch [pin](/device/pins). Use [analog set pitch pin](/reference/pins/analog-set-pitch-pin) to set the current pitch pin.
Emits a Pulse With Modulation (PWM) signal to the pin ``P0``.
Use [analog set pitch pin](/reference/pins/analog-set-pitch-pin) to set the current pitch pin.
```sig
pins.analogPitch(440, 300)
@ -17,6 +18,7 @@ pins.analogPitch(440, 300)
pins.analogSetPitchPin("P0")
let frequency1 = 440
let duration = 1000
pins.analogSetPitchPin(AnalogPin.P1);
pins.analogPitch(frequency1, duration)
```

View File

@ -0,0 +1,28 @@
# Serial Read Until
Read a text from the serial port until a delimiter is found.
```sig
serial.readUntil(",");
```
### Returns
* a [string](/reference/types/string) containing input from the serial port, such as a response typed by a user
### Example
The following example reads strings separated by commands (``,``).
```blocks
basic.forever(() => {
let answer = serial.readUntil(",");
serial.writeLine(answer);
});
```
### See also
[serial](/device/serial),
[serial write line](/reference/serial/write-line),
[serial write value](/reference/serial/write-value)

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,9 +1,15 @@
{
"bluetooth": "Support for additional Bluetooth services.",
"bluetooth.advertiseUrl": "Advertise an Eddystone URL",
"bluetooth.advertiseUrl|param|connectable": "true to keep bluetooth connectable for other services, false otherwise.",
"bluetooth.advertiseUrl|param|power": "power level between 0 and 7, eg: 7",
"bluetooth.advertiseUrl|param|url": "the url to transmit. Must be no longer than the supported eddystone url length, eg: \"https://pxt.io/\"",
"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",
"bluetooth.onBluetoothDisconnected|param|body": "Code to run when a Bluetooth connection is lost",
"bluetooth.setTransmitPower": "Sets the bluetooth transmit power between 0 (minimal) and 7 (maximum).",
"bluetooth.setTransmitPower|param|power": "power level between 0 (minimal) and 7 (maximum), eg: 7.",
"bluetooth.startAccelerometerService": "Starts the Bluetooth accelerometer service",
"bluetooth.startButtonService": "Starts the Bluetooth button service",
"bluetooth.startIOPinService": "Starts the Bluetooth IO pin service.",
@ -11,6 +17,7 @@
"bluetooth.startMagnetometerService": "Starts the Bluetooth magnetometer service",
"bluetooth.startTemperatureService": "Starts the Bluetooth temperature service",
"bluetooth.startUartService": "Starts the Bluetooth UART service",
"bluetooth.stopAdvertising": "Stops advertising Eddystone end points",
"bluetooth.uartReadUntil": "Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.",
"bluetooth.uartWriteNumber": "Prints a numeric value to the serial",
"bluetooth.uartWriteString": "Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device.",

View File

@ -1,6 +1,8 @@
{
"bluetooth.advertiseUrl|block": "bluetooth advertise url %url|with power %power|connectable %connectable",
"bluetooth.onBluetoothConnected|block": "on bluetooth connected",
"bluetooth.onBluetoothDisconnected|block": "on bluetooth disconnected",
"bluetooth.setTransmitPower|block": "bluetooth set transmit power %power",
"bluetooth.startAccelerometerService|block": "bluetooth accelerometer service",
"bluetooth.startButtonService|block": "bluetooth button service",
"bluetooth.startIOPinService|block": "bluetooth io pin service",
@ -8,6 +10,7 @@
"bluetooth.startMagnetometerService|block": "bluetooth magnetometer service",
"bluetooth.startTemperatureService|block": "bluetooth temperature service",
"bluetooth.startUartService|block": "bluetooth uart service",
"bluetooth.stopAdvertising|block": "bluetooth stop advertising",
"bluetooth.uartReadUntil|block": "bluetooth uart|read until %del=serial_delimiter_conv",
"bluetooth.uartWriteNumber|block": "bluetooth uart|write number %value",
"bluetooth.uartWriteString|block": "bluetooth uart|write string %data",

View File

@ -11,7 +11,6 @@ using namespace pxt;
namespace bluetooth {
MicroBitUARTService *uart = NULL;
/**
* Starts the Bluetooth accelerometer service
*/
@ -119,5 +118,42 @@ namespace bluetooth {
//% parts="bluetooth"
void onBluetoothDisconnected(Action body) {
registerWithDal(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, body);
}
}
const int8_t CALIBRATED_POWERS[] = {-49, -37, -33, -28, -25, -20, -15, -10};
/**
* Advertise an Eddystone URL
* @param url the url to transmit. Must be no longer than the supported eddystone url length, eg: "https://pxt.io/"
* @param power power level between 0 and 7, eg: 7
* @param connectable true to keep bluetooth connectable for other services, false otherwise.
*/
//% blockId=eddystone_advertise_url block="bluetooth advertise url %url|with power %power|connectable %connectable"
//% parts=bluetooth weight=11 blockGap=8
//% help=bluetooth/advertise-url blockExternalInputs=1
void advertiseUrl(StringData* url, int power, bool connectable) {
power = min(MICROBIT_BLE_POWER_LEVELS-1, max(0, power));
int8_t level = CALIBRATED_POWERS[power];
uBit.bleManager.advertiseEddystoneUrl(ManagedString(url), level, connectable);
uBit.bleManager.setTransmitPower(power);
}
/**
* Sets the bluetooth transmit power between 0 (minimal) and 7 (maximum).
* @param power power level between 0 (minimal) and 7 (maximum), eg: 7.
*/
//% parts=bluetooth weight=5 help=bluetooth/set-transmit-power advanced=true
//% blockId=bluetooth_settransmitpower block="bluetooth set transmit power %power"
void setTransmitPower(int power) {
uBit.bleManager.setTransmitPower(min(MICROBIT_BLE_POWER_LEVELS-1, max(0, power)));
}
/**
* Stops advertising Eddystone end points
*/
//% blockId=eddystone_stop_advertising block="bluetooth stop advertising"
//% parts=bluetooth weight=10
//% help=bluetooth/stop-advertising advanced=true
void stopAdvertising() {
uBit.bleManager.stopAdvertising();
}
}

View File

@ -16,20 +16,70 @@
"config": {
"microbit-dal": {
"bluetooth": {
"enabled": 1,
"pairing_mode": 1,
"enabled": 1
}
}
},
"optionalConfig": {
"microbit-dal": {
"bluetooth": {
"private_addressing": 0,
"open": 0,
"whitelist": 1,
"advertising_timeout": 0,
"tx_power": 6,
"dfu_service": 1,
"event_service": 1,
"device_info_service": 1
},
"gatt_table_size": "0x700"
"device_info_service": 1,
"eddystone_url": 1,
"eddystone_uid": 0,
"open": 0,
"pairing_mode": 1,
"whitelist": 1,
"security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM"
}
},
"gatt_table_size": "0x700"
},
"userConfigs": [
{
"description": "Unsecure: Anyone can connect via Bluetooth.",
"config": {
"microbit-dal": {
"bluetooth": {
"open": 1,
"pairing_mode": 0,
"whitelist": 0,
"security_level": null
}
}
}
},
{
"description": "JustWorks pairing (default): Button press to pair.",
"config": {
"microbit-dal": {
"bluetooth": {
"open": null,
"pairing_mode": null,
"whitelist": null,
"security_level": null
}
}
}
},
{
"description": "Passkey pairing: Button press and 6 digit key to pair.",
"config": {
"microbit-dal": {
"bluetooth": {
"open": 0,
"pairing_mode": 1,
"whitelist": 1,
"security_level": "SECURITY_MODE_ENCRYPTION_WITH_MITM"
}
}
}
}
}
]
},
"installedVersion": "vzlhfd"
}

View File

@ -80,6 +80,33 @@ declare namespace bluetooth {
//% blockId=bluetooth_on_disconnected block="on bluetooth disconnected"
//% parts="bluetooth" shim=bluetooth::onBluetoothDisconnected
function onBluetoothDisconnected(body: () => void): void;
/**
* Advertise an Eddystone URL
* @param url the url to transmit. Must be no longer than the supported eddystone url length, eg: "https://pxt.io/"
* @param power power level between 0 and 7, eg: 7
* @param connectable true to keep bluetooth connectable for other services, false otherwise.
*/
//% blockId=eddystone_advertise_url block="bluetooth advertise url %url|with power %power|connectable %connectable"
//% parts=bluetooth weight=11 blockGap=8
//% help=bluetooth/advertise-url blockExternalInputs=1 shim=bluetooth::advertiseUrl
function advertiseUrl(url: string, power: number, connectable: boolean): void;
/**
* Sets the bluetooth transmit power between 0 (minimal) and 7 (maximum).
* @param power power level between 0 (minimal) and 7 (maximum), eg: 7.
*/
//% parts=bluetooth weight=5 help=bluetooth/set-transmit-power advanced=true
//% blockId=bluetooth_settransmitpower block="bluetooth set transmit power %power" shim=bluetooth::setTransmitPower
function setTransmitPower(power: number): void;
/**
* Stops advertising Eddystone end points
*/
//% blockId=eddystone_stop_advertising block="bluetooth stop advertising"
//% parts=bluetooth weight=10
//% help=bluetooth/stop-advertising advanced=true shim=bluetooth::stopAdvertising
function stopAdvertising(): void;
}
// Auto-generated. Do not edit. Really.

373
libs/core/ManagedBuffer.cpp Normal file
View File

@ -0,0 +1,373 @@
#include "MicroBit.h"
#include "ManagedBuffer.h"
#include <limits.h>
static const char empty[] __attribute__ ((aligned (4))) = "\xff\xff\0\0\0";
/**
* Internal constructor helper.
* Configures this ManagedBuffer to refer to the static empty buffer.
*/
void ManagedBuffer::initEmpty()
{
ptr = (BufferData*)(void*)empty;
}
/**
* Default Constructor.
* Creates an empty ManagedBuffer.
*
* Example:
* @code
* ManagedBuffer p();
* @endcode
*/
ManagedBuffer::ManagedBuffer()
{
initEmpty();
}
/**
* Constructor.
* Creates an empty ManagedBuffer of the given size.
*
* @param length The length of the buffer to create.
*
* Example:
* @code
* ManagedBuffer p(16); // Creates a ManagedBuffer 16 bytes long.
* @endcode
*/
ManagedBuffer::ManagedBuffer(int length)
{
this->init(NULL, length);
}
/**
* Constructor.
* Creates a new ManagedBuffer of the given size,
* and fills it with the data provided.
*
* @param data The data with which to fill the buffer.
* @param length The length of the buffer to create.
*
* Example:
* @code
* uint8_t buf = {13,5,2};
* ManagedBuffer p(buf, 3); // Creates a ManagedBuffer 3 bytes long.
* @endcode
*/
ManagedBuffer::ManagedBuffer(uint8_t *data, int length)
{
this->init(data, length);
}
/**
* Copy Constructor.
* Add ourselves as a reference to an existing ManagedBuffer.
*
* @param buffer The ManagedBuffer to reference.
*
* Example:
* @code
* ManagedBuffer p();
* ManagedBuffer p2(i); // Refers to the same buffer as p.
* @endcode
*/
ManagedBuffer::ManagedBuffer(const ManagedBuffer &buffer)
{
ptr = buffer.ptr;
ptr->incr();
}
/**
* Constructor.
* Create a buffer from a raw BufferData pointer. It will ptr->incr(). This is to be used by specialized runtimes.
*
* @param p The pointer to use.
*/
ManagedBuffer::ManagedBuffer(BufferData *p)
{
ptr = p;
ptr->incr();
}
/**
* Internal constructor-initialiser.
*
* @param data The data with which to fill the buffer.
* @param length The length of the buffer to create.
*
*/
void ManagedBuffer::init(uint8_t *data, int length)
{
if (length <= 0) {
initEmpty();
return;
}
ptr = (BufferData *) malloc(sizeof(BufferData) + length);
ptr->init();
ptr->length = length;
// Copy in the data buffer, if provided.
if (data)
memcpy(ptr->payload, data, length);
else
memset(ptr->payload, 0, length);
}
/**
* Destructor.
* Removes buffer resources held by the instance.
*/
ManagedBuffer::~ManagedBuffer()
{
ptr->decr();
}
/**
* Copy assign operation.
*
* Called when one ManagedBuffer is assigned the value of another using the '=' operator.
* Decrements our reference count and free up the buffer as necessary.
* Then, update our buffer to refer to that of the supplied ManagedBuffer,
* and increase its reference count.
*
* @param p The ManagedBuffer to reference.
*
* Example:
* @code
* uint8_t buf = {13,5,2};
* ManagedBuffer p1(16);
* ManagedBuffer p2(buf, 3);
*
* p1 = p2;
* @endcode
*/
ManagedBuffer& ManagedBuffer::operator = (const ManagedBuffer &p)
{
if(ptr == p.ptr)
return *this;
ptr->decr();
ptr = p.ptr;
ptr->incr();
return *this;
}
/**
* Equality operation.
*
* Called when one ManagedBuffer is tested to be equal to another using the '==' operator.
*
* @param p The ManagedBuffer to test ourselves against.
* @return true if this ManagedBuffer is identical to the one supplied, false otherwise.
*
* Example:
* @code
*
* uint8_t buf = {13,5,2};
* ManagedBuffer p1(16);
* ManagedBuffer p2(buf, 3);
*
* if(p1 == p2) // will be true
* uBit.display.scroll("same!");
* @endcode
*/
bool ManagedBuffer::operator== (const ManagedBuffer& p)
{
if (ptr == p.ptr)
return true;
else
return (ptr->length == p.ptr->length && (memcmp(ptr->payload, p.ptr->payload, ptr->length)==0));
}
/**
* Sets the byte at the given index to value provided.
* @param position The index of the byte to change.
* @param value The new value of the byte (0-255).
* @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
*
* Example:
* @code
* ManagedBuffer p1(16);
* p1.setByte(0,255); // Sets the firts byte in the buffer to the value 255.
* @endcode
*/
int ManagedBuffer::setByte(int position, uint8_t value)
{
if (0 <= position && position < ptr->length)
{
ptr->payload[position] = value;
return MICROBIT_OK;
}
else
{
return MICROBIT_INVALID_PARAMETER;
}
}
/**
* Determines the value of the given byte in the buffer.
*
* @param position The index of the byte to read.
* @return The value of the byte at the given position, or MICROBIT_INVALID_PARAMETER.
*
* Example:
* @code
* ManagedBuffer p1(16);
* p1.setByte(0,255); // Sets the firts byte in the buffer to the value 255.
* p1.getByte(0); // Returns 255.
* @endcode
*/
int ManagedBuffer::getByte(int position)
{
if (0 <= position && position < ptr->length)
return ptr->payload[position];
else
return MICROBIT_INVALID_PARAMETER;
}
/**
* Get current ptr, do not decr() it, and set the current instance to an empty buffer.
* This is to be used by specialized runtimes which pass BufferData around.
*/
BufferData *ManagedBuffer::leakData()
{
BufferData* res = ptr;
initEmpty();
return res;
}
int ManagedBuffer::fill(uint8_t value, int offset, int length)
{
if (offset < 0 || offset > ptr->length)
return MICROBIT_INVALID_PARAMETER;
if (length < 0)
length = ptr->length;
length = min(length, ptr->length - offset);
memset(ptr->payload + offset, value, length);
return MICROBIT_OK;
}
ManagedBuffer ManagedBuffer::slice(int offset, int length) const
{
offset = min(ptr->length, offset);
if (length < 0)
length = ptr->length;
length = min(length, ptr->length - offset);
return ManagedBuffer(ptr->payload + offset, length);
}
void ManagedBuffer::shift(int offset, int start, int len)
{
if (len < 0) len = ptr->length - start;
if (start < 0 || start + len > ptr->length || start + len < start
|| len == 0 || offset == 0 || offset == INT_MIN) return;
if (offset <= -len || offset >= len) {
fill(0);
return;
}
uint8_t *data = ptr->payload + start;
if (offset < 0) {
offset = -offset;
memmove(data + offset, data, len - offset);
memset(data, 0, offset);
} else {
len = len - offset;
memmove(data, data + offset, len);
memset(data + len, 0, offset);
}
}
void ManagedBuffer::rotate(int offset, int start, int len)
{
if (len < 0) len = ptr->length - start;
if (start < 0 || start + len > ptr-> length || start + len < start
|| len == 0 || offset == 0 || offset == INT_MIN) return;
if (offset < 0)
offset += len << 8; // try to make it positive
offset %= len;
if (offset < 0)
offset += len;
uint8_t *data = ptr->payload + start;
uint8_t *n_first = data + offset;
uint8_t *first = data;
uint8_t *next = n_first;
uint8_t *last = data + len;
while (first != next) {
uint8_t tmp = *first;
*first++ = *next;
*next++ = tmp;
if (next == last) {
next = n_first;
} else if (first == n_first) {
n_first = next;
}
}
}
int ManagedBuffer::writeBuffer(int dstOffset, const ManagedBuffer &src, int srcOffset, int length)
{
if (length < 0)
length = src.length();
if (srcOffset < 0 || dstOffset < 0 || dstOffset > ptr->length)
return MICROBIT_INVALID_PARAMETER;
length = min(src.length() - srcOffset, ptr->length - dstOffset);
if (length < 0)
return MICROBIT_INVALID_PARAMETER;
if (ptr == src.ptr) {
memmove(getBytes() + dstOffset, src.ptr->payload + srcOffset, length);
} else {
memcpy(getBytes() + dstOffset, src.ptr->payload + srcOffset, length);
}
return MICROBIT_OK;
}
int ManagedBuffer::writeBytes(int offset, uint8_t *src, int length, bool swapBytes)
{
if (offset < 0 || length < 0 || offset + length > ptr->length)
return MICROBIT_INVALID_PARAMETER;
if (swapBytes) {
uint8_t *p = ptr->payload + offset + length;
for (int i = 0; i < length; ++i)
*--p = src[i];
} else {
memcpy(ptr->payload + offset, src, length);
}
return MICROBIT_OK;
}
int ManagedBuffer::readBytes(uint8_t *dst, int offset, int length, bool swapBytes) const
{
if (offset < 0 || length < 0 || offset + length > ptr->length)
return MICROBIT_INVALID_PARAMETER;
if (swapBytes) {
uint8_t *p = ptr->payload + offset + length;
for (int i = 0; i < length; ++i)
dst[i] = *--p;
} else {
memcpy(dst, ptr->payload + offset, length);
}
return MICROBIT_OK;
}

257
libs/core/ManagedBuffer.h Normal file
View File

@ -0,0 +1,257 @@
#ifndef MICROBIT_MANAGED_BUFFER_H
#define MICROBIT_MANAGED_BUFFER_H
#include "mbed.h"
#include "RefCounted.h"
struct BufferData : RefCounted
{
uint16_t length; // The length of the payload in bytes
uint8_t payload[0]; // ManagedBuffer data
};
/**
* Class definition for a ManagedBuffer.
* A ManagedBuffer holds a series of bytes, used with MicroBitRadio channels and in other places.
* n.b. This is a mutable, managed type.
*/
class ManagedBuffer
{
BufferData *ptr; // Pointer to payload data
public:
/**
* Default Constructor.
* Creates an empty ManagedBuffer. The 'ptr' field in all empty buffers is shared.
*
* Example:
* @code
* ManagedBuffer p();
* @endcode
*/
ManagedBuffer();
/**
* Constructor.
* Creates a new ManagedBuffer of the given size.
*
* @param length The length of the buffer to create.
*
* Example:
* @code
* ManagedBuffer p(16); // Creates a ManagedBuffer 16 bytes long.
* @endcode
*/
ManagedBuffer(int length);
/**
* Constructor.
* Creates an empty ManagedBuffer of the given size,
* and fills it with the data provided.
*
* @param data The data with which to fill the buffer.
* @param length The length of the buffer to create.
*
* Example:
* @code
* uint8_t buf[] = {13,5,2};
* ManagedBuffer p(buf, 3); // Creates a ManagedBuffer 3 bytes long.
* @endcode
*/
ManagedBuffer(uint8_t *data, int length);
/**
* Copy Constructor.
* Add ourselves as a reference to an existing ManagedBuffer.
*
* @param buffer The ManagedBuffer to reference.
*
* Example:
* @code
* ManagedBuffer p();
* ManagedBuffer p2(i); // Refers to the same buffer as p.
* @endcode
*/
ManagedBuffer(const ManagedBuffer &buffer);
/**
* Constructor.
* Create a buffer from a raw BufferData pointer. It will ptr->incr(). This is to be used by specialized runtimes.
*
* @param p The pointer to use.
*/
ManagedBuffer(BufferData *p);
/**
* Internal constructor helper.
* Configures this ManagedBuffer to refer to the static empty buffer.
*/
void initEmpty();
/**
* Internal constructor-initialiser.
*
* @param data The data with which to fill the buffer.
* @param length The length of the buffer to create.
*
*/
void init(uint8_t *data, int length);
/**
* Destructor.
* Removes buffer resources held by the instance.
*/
~ManagedBuffer();
/**
* Provide an array containing the buffer data.
* @return The contents of this buffer, as an array of bytes.
*/
uint8_t *getBytes()
{
return ptr->payload;
}
/**
* Get current ptr, do not decr() it, and set the current instance to an empty buffer.
* This is to be used by specialized runtimes which pass BufferData around.
*/
BufferData *leakData();
/**
* Copy assign operation.
*
* Called when one ManagedBuffer is assigned the value of another using the '=' operator.
* Decrements our reference count and free up the buffer as necessary.
* Then, update our buffer to refer to that of the supplied ManagedBuffer,
* and increase its reference count.
*
* @param p The ManagedBuffer to reference.
*
* Example:
* @code
* uint8_t buf = {13,5,2};
* ManagedBuffer p1(16);
* ManagedBuffer p2(buf, 3);
*
* p1 = p2;
* @endcode
*/
ManagedBuffer& operator = (const ManagedBuffer& p);
/**
* Array access operation (read).
*
* Called when a ManagedBuffer is dereferenced with a [] operation.
* Transparently map this through to the underlying payload for elegance of programming.
*
* Example:
* @code
* ManagedBuffer p1(16);
* uint8_t data = p1[0];
* @endcode
*/
uint8_t operator [] (int i) const
{
return ptr->payload[i];
}
/**
* Array access operation (modify).
*
* Called when a ManagedBuffer is dereferenced with a [] operation.
* Transparently map this through to the underlying payload for elegance of programming.
*
* Example:
* @code
* ManagedBuffer p1(16);
* p1[0] = 42;
* @endcode
*/
uint8_t& operator [] (int i)
{
return ptr->payload[i];
}
/**
* Equality operation.
*
* Called when one ManagedBuffer is tested to be equal to another using the '==' operator.
*
* @param p The ManagedBuffer to test ourselves against.
* @return true if this ManagedBuffer is identical to the one supplied, false otherwise.
*
* Example:
* @code
*
* uint8_t buf = {13,5,2};
* ManagedBuffer p1(16);
* ManagedBuffer p2(buf, 3);
*
* if(p1 == p2) // will be true
* uBit.display.scroll("same!");
* @endcode
*/
bool operator== (const ManagedBuffer& p);
/**
* Sets the byte at the given index to value provided.
* @param position The index of the byte to change.
* @param value The new value of the byte (0-255).
* @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
*
* Example:
* @code
* ManagedBuffer p1(16);
* p1.setByte(0,255); // Sets the first byte in the buffer to the value 255.
* @endcode
*/
int setByte(int position, uint8_t value);
/**
* Determines the value of the given byte in the buffer.
*
* @param position The index of the byte to read.
* @return The value of the byte at the given position, or MICROBIT_INVALID_PARAMETER.
*
* Example:
* @code
* ManagedBuffer p1(16);
* p1.setByte(0,255); // Sets the first byte in the buffer to the value 255.
* p1.getByte(0); // Returns 255.
* @endcode
*/
int getByte(int position);
/**
* Gets number of bytes in this buffer
* @return The size of the buffer in bytes.
*
* Example:
* @code
* ManagedBuffer p1(16);
* p1.length(); // Returns 16.
* @endcode
*/
int length() const { return ptr->length; }
int fill(uint8_t value, int offset = 0, int length = -1);
ManagedBuffer slice(int offset = 0, int length = -1) const;
void shift(int offset, int start = 0, int length = -1);
void rotate(int offset, int start = 0, int length = -1);
int readBytes(uint8_t *dst, int offset, int length, bool swapBytes = false) const;
int writeBytes(int dstOffset, uint8_t *src, int length, bool swapBytes = false);
int writeBuffer(int dstOffset, const ManagedBuffer &src, int srcOffset = 0, int length = -1);
bool isReadOnly() const { return ptr->isReadOnly(); }
};
#endif

View File

@ -85,7 +85,7 @@
"game.setLife": "Sets the current life value",
"game.setLife|param|value": "TODO",
"game.setScore": "Sets the current score value",
"game.setScore|param|value": "TODO",
"game.setScore|param|value": "new score value.",
"game.showScore": "Displays the score on the screen.",
"game.startCountdown": "Starts a game countdown timer",
"game.startCountdown|param|ms": "countdown duration in milliseconds, eg: 10000",
@ -179,15 +179,15 @@
"music.tempo": "Returns the tempo in beats per minute. Tempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play.",
"pins": "Control currents in Pins for analog/digital signals, servos, i2c, ...",
"pins.analogPitch": "Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.",
"pins.analogPitch|param|frequency": "TODO",
"pins.analogPitch|param|ms": "TODO",
"pins.analogPitch|param|frequency": "frequency to modulate in Hz.",
"pins.analogPitch|param|ms": "duration of the pitch in milli seconds.",
"pins.analogReadPin": "Read the connector value as analog, that is, as a value comprised between 0 and 1023.",
"pins.analogReadPin|param|name": "pin to write to",
"pins.analogSetPeriod": "Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds.\nIf this pin is not configured as an analog output (using `analog write pin`), the operation has no effect.",
"pins.analogSetPeriod|param|micros": "period in micro seconds. eg:20000",
"pins.analogSetPeriod|param|name": "analog pin to set period to",
"pins.analogSetPitchPin": "Sets the pin used when using `pins->analog pitch`.",
"pins.analogSetPitchPin|param|name": "TODO",
"pins.analogSetPitchPin": "Sets the pin used when using `analog pitch` or music.",
"pins.analogSetPitchPin|param|name": "pin to modulate pitch from",
"pins.analogWritePin": "Set the connector value as analog. Value must be comprised between 0 and 1023.",
"pins.analogWritePin|param|name": "pin name to write to",
"pins.analogWritePin|param|value": "value to write to the pin between ``0`` and ``1023``. eg:1023,0",

View File

@ -9,6 +9,8 @@
"AcceleratorRange.TwoG|block": "2g",
"BaudRate.BaudRate115200|block": "115200",
"BaudRate.BaudRate9600|block": "9600",
"BeatFraction.Breve|block": "4",
"BeatFraction.Double|block": "2",
"BeatFraction.Eighth|block": "1/8",
"BeatFraction.Half|block": "1/2",
"BeatFraction.Quarter|block": "1/4",
@ -73,6 +75,8 @@
"PinPullMode.PullDown|block": "down",
"PinPullMode.PullNone|block": "none",
"PinPullMode.PullUp|block": "up",
"PulseValue.High|block": "high",
"PulseValue.Low|block": "low",
"Rotation.Pitch|block": "pitch",
"Rotation.Roll|block": "roll",
"String.charAt|block": "char from %this|at %pos",
@ -106,6 +110,7 @@
"game.createSprite|block": "create sprite at|x: %x|y: %y",
"game.gameOver|block": "game over",
"game.score|block": "score",
"game.setScore|block": "set score %points",
"game.startCountdown|block": "start countdown|(ms) %duration",
"game|block": "game",
"images.createBigImage|block": "create big image",
@ -127,6 +132,7 @@
"input.temperature|block": "temperature (°C)",
"input|block": "input",
"led.brightness|block": "brightness",
"led.enable|block": "led enable %on",
"led.plotBarGraph|block": "plot bar graph of %value |up to %high",
"led.plot|block": "plot|x %x|y %y",
"led.point|block": "point|x %x|y %y",
@ -144,8 +150,10 @@
"music.setTempo|block": "set tempo to (bpm)|%value",
"music.tempo|block": "tempo (bpm)",
"music|block": "music",
"pins.analogPitch|block": "analog pitch %frequency|for (ms) %ms",
"pins.analogReadPin|block": "analog read|pin %name",
"pins.analogSetPeriod|block": "analog set period|pin %pin|to (µs)%micros",
"pins.analogSetPitchPin|block": "analog set pitch pin %name",
"pins.analogWritePin|block": "analog write|pin %name|to %value",
"pins.digitalReadPin|block": "digital read|pin %name",
"pins.digitalWritePin|block": "digital write|pin %name|to %value",

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
/**

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
// keep in sync with github/pxt/pxtsim/libgeneric.ts
enum class NumberFormat {

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
/**
* How to create the event.

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
#include <limits.h>

116
libs/core/dal.d.ts vendored
View File

@ -1,11 +1,11 @@
// Auto-generated. Do not edit.
declare const enum DAL {
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\ExternalEvents.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/ExternalEvents.h
MICROBIT_ID_BLE = 1000,
MICROBIT_ID_BLE_UART = 1200,
MICROBIT_BLE_EVT_CONNECTED = 1,
MICROBIT_BLE_EVT_DISCONNECTED = 2,
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MESEvents.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MESEvents.h
MES_REMOTE_CONTROL_ID = 1001,
MES_REMOTE_CONTROL_EVT_PLAY = 1,
MES_REMOTE_CONTROL_EVT_PAUSE = 2,
@ -70,8 +70,8 @@ declare const enum DAL {
MES_DPAD_BUTTON_4_DOWN = 15,
MES_DPAD_BUTTON_4_UP = 16,
MES_BROADCAST_GENERAL_ID = 2000,
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitAccelerometerService.h
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitBLEManager.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitAccelerometerService.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitBLEManager.h
MICROBIT_BLE_PAIR_REQUEST = 0x01,
MICROBIT_BLE_PAIR_COMPLETE = 0x02,
MICROBIT_BLE_PAIR_PASSCODE = 0x04,
@ -79,27 +79,29 @@ declare const enum DAL {
MICROBIT_BLE_PAIRING_TIMEOUT = 90,
MICROBIT_BLE_POWER_LEVELS = 8,
MICROBIT_BLE_MAXIMUM_BONDS = 4,
MICROBIT_BLE_EDDYSTONE_URL_ADV_INTERVAL = 400,
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitButtonService.h
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitDFUService.h
MICROBIT_BLE_EDDYSTONE_ADV_INTERVAL = 400,
MICROBIT_BLE_EDDYSTONE_DEFAULT_POWER = 0xF0,
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitButtonService.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitDFUService.h
MICROBIT_DFU_OPCODE_START_DFU = 1,
MICROBIT_DFU_HISTOGRAM_WIDTH = 5,
MICROBIT_DFU_HISTOGRAM_HEIGHT = 5,
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitEventService.h
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitIOPinService.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitEddystone.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitEventService.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitIOPinService.h
MICROBIT_IO_PIN_SERVICE_PINCOUNT = 19,
MICROBIT_IO_PIN_SERVICE_DATA_SIZE = 10,
MICROBIT_PWM_PIN_SERVICE_DATA_SIZE = 2,
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitLEDService.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitLEDService.h
MICROBIT_BLE_MAXIMUM_SCROLLTEXT = 20,
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitMagnetometerService.h
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitTemperatureService.h
// built\yt\yotta_modules\microbit-dal\inc\bluetooth\MicroBitUARTService.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitMagnetometerService.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitTemperatureService.h
// built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitUARTService.h
MICROBIT_UART_S_DEFAULT_BUF_SIZE = 20,
MICROBIT_UART_S_EVT_DELIM_MATCH = 1,
MICROBIT_UART_S_EVT_HEAD_MATCH = 2,
MICROBIT_UART_S_EVT_RX_FULL = 3,
// built\yt\yotta_modules\microbit-dal\inc\core\ErrorNo.h
// built/yt/yotta_modules/microbit-dal/inc/core/ErrorNo.h
MICROBIT_OK = 0,
MICROBIT_INVALID_PARAMETER = -1001,
MICROBIT_NOT_SUPPORTED = -1002,
@ -114,10 +116,10 @@ declare const enum DAL {
MICROBIT_OOM = 20,
MICROBIT_HEAP_ERROR = 30,
MICROBIT_NULL_DEREFERENCE = 40,
// built\yt\yotta_modules\microbit-dal\inc\core\EventModel.h
// built\yt\yotta_modules\microbit-dal\inc\core\MemberFunctionCallback.h
// built\yt\yotta_modules\microbit-dal\inc\core\MicroBitCompat.h
// built\yt\yotta_modules\microbit-dal\inc\core\MicroBitComponent.h
// built/yt/yotta_modules/microbit-dal/inc/core/EventModel.h
// built/yt/yotta_modules/microbit-dal/inc/core/MemberFunctionCallback.h
// built/yt/yotta_modules/microbit-dal/inc/core/MicroBitCompat.h
// built/yt/yotta_modules/microbit-dal/inc/core/MicroBitComponent.h
MICROBIT_ID_BUTTON_A = 1,
MICROBIT_ID_BUTTON_B = 2,
MICROBIT_ID_BUTTON_RESET = 3,
@ -155,25 +157,25 @@ declare const enum DAL {
MICROBIT_ID_NOTIFY_ONE = 1022,
MICROBIT_ID_NOTIFY = 1023,
MICROBIT_COMPONENT_RUNNING = 0x01,
// built\yt\yotta_modules\microbit-dal\inc\core\MicroBitDevice.h
// built/yt/yotta_modules/microbit-dal/inc/core/MicroBitDevice.h
MICROBIT_NAME_LENGTH = 5,
MICROBIT_NAME_CODE_LETTERS = 5,
MICROBIT_PANIC_ERROR_CHARS = 4,
// built\yt\yotta_modules\microbit-dal\inc\core\MicroBitFiber.h
// built/yt/yotta_modules/microbit-dal/inc/core/MicroBitFiber.h
MICROBIT_SCHEDULER_RUNNING = 0x01,
MICROBIT_FIBER_FLAG_FOB = 0x01,
MICROBIT_FIBER_FLAG_PARENT = 0x02,
MICROBIT_FIBER_FLAG_CHILD = 0x04,
MICROBIT_FIBER_FLAG_DO_NOT_PAGE = 0x08,
// built\yt\yotta_modules\microbit-dal\inc\core\MicroBitFont.h
// built/yt/yotta_modules/microbit-dal/inc/core/MicroBitFont.h
MICROBIT_FONT_WIDTH = 5,
MICROBIT_FONT_HEIGHT = 5,
MICROBIT_FONT_ASCII_START = 32,
MICROBIT_FONT_ASCII_END = 126,
// built\yt\yotta_modules\microbit-dal\inc\core\MicroBitHeapAllocator.h
// built/yt/yotta_modules/microbit-dal/inc/core/MicroBitHeapAllocator.h
MICROBIT_MAXIMUM_HEAPS = 2,
MICROBIT_HEAP_BLOCK_FREE = 0x80000000,
// built\yt\yotta_modules\microbit-dal\inc\core\MicroBitListener.h
// built/yt/yotta_modules/microbit-dal/inc/core/MicroBitListener.h
MESSAGE_BUS_LISTENER_PARAMETERISED = 0x0001,
MESSAGE_BUS_LISTENER_METHOD = 0x0002,
MESSAGE_BUS_LISTENER_BUSY = 0x0004,
@ -183,17 +185,17 @@ declare const enum DAL {
MESSAGE_BUS_LISTENER_NONBLOCKING = 0x0040,
MESSAGE_BUS_LISTENER_URGENT = 0x0080,
MESSAGE_BUS_LISTENER_DELETING = 0x8000,
// built\yt\yotta_modules\microbit-dal\inc\core\MicroBitSystemTimer.h
// built\yt\yotta_modules\microbit-dal\inc\core\NotifyEvents.h
// built/yt/yotta_modules/microbit-dal/inc/core/MicroBitSystemTimer.h
// built/yt/yotta_modules/microbit-dal/inc/core/NotifyEvents.h
MICROBIT_DISPLAY_EVT_FREE = 1,
MICROBIT_SERIAL_EVT_TX_EMPTY = 2,
MICROBIT_UART_S_EVT_TX_EMPTY = 3,
// built\yt\yotta_modules\microbit-dal\inc\drivers\DynamicPwm.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/DynamicPwm.h
NO_PWMS = 3,
MICROBIT_DEFAULT_PWM_PERIOD = 20000,
PWM_PERSISTENCE_TRANSIENT = 1,
PWM_PERSISTENCE_PERSISTENT = 2,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitAccelerometer.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitAccelerometer.h
MICROBIT_ACCEL_PITCH_ROLL_VALID = 0x02,
MICROBIT_ACCEL_ADDED_TO_IDLE = 0x04,
MMA8653_DEFAULT_ADDR = 0x3A,
@ -233,7 +235,7 @@ declare const enum DAL {
MICROBIT_ACCELEROMETER_SHAKE_DAMPING = 10,
MICROBIT_ACCELEROMETER_SHAKE_RTX = 30,
MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitButton.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitButton.h
MICROBIT_BUTTON_EVT_DOWN = 1,
MICROBIT_BUTTON_EVT_UP = 2,
MICROBIT_BUTTON_EVT_CLICK = 3,
@ -253,7 +255,7 @@ declare const enum DAL {
MICROBIT_BUTTON_DOUBLE_CLICK_THRESH = 50,
MICROBIT_BUTTON_SIMPLE_EVENTS = 0,
MICROBIT_BUTTON_ALL_EVENTS = 1,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitCompass.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitCompass.h
MAG3110_DEFAULT_ADDR = 0x1D,
MAG_DR_STATUS = 0x00,
MAG_OUT_X_MSB = 0x01,
@ -284,8 +286,8 @@ declare const enum DAL {
MICROBIT_COMPASS_STATUS_CALIBRATING = 4,
MICROBIT_COMPASS_STATUS_ADDED_TO_IDLE = 8,
MAG3110_WHOAMI_VAL = 0xC4,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitCompassCalibrator.h
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitDisplay.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitCompassCalibrator.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitDisplay.h
MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE = 1,
MICROBIT_DISPLAY_EVT_LIGHT_SENSE = 2,
MICROBIT_DISPLAY_DEFAULT_AUTOCLEAR = 1,
@ -307,8 +309,8 @@ declare const enum DAL {
MICROBIT_DISPLAY_ROTATION_90 = 1,
MICROBIT_DISPLAY_ROTATION_180 = 2,
MICROBIT_DISPLAY_ROTATION_270 = 3,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitFile.h
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitFileSystem.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitFile.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitFileSystem.h
MBFS_FILENAME_LENGTH = 16,
MB_READ = 0x01,
MB_WRITE = 0x02,
@ -329,23 +331,23 @@ declare const enum DAL {
MBFS_BLOCK_TYPE_FILE = 1,
MBFS_BLOCK_TYPE_DIRECTORY = 2,
MBFS_BLOCK_TYPE_FILETABLE = 3,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitFlash.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitFlash.h
PAGE_SIZE = 1024,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitI2C.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitI2C.h
MICROBIT_I2C_MAX_RETRIES = 9,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitIO.h
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitLightSensor.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitIO.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitLightSensor.h
MICROBIT_LIGHT_SENSOR_CHAN_NUM = 3,
MICROBIT_LIGHT_SENSOR_AN_SET_TIME = 4000,
MICROBIT_LIGHT_SENSOR_TICK_PERIOD = 5,
MICROBIT_LIGHT_SENSOR_MAX_VALUE = 338,
MICROBIT_LIGHT_SENSOR_MIN_VALUE = 75,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitMatrixMaps.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitMatrixMaps.h
NO_CONN = 0,
MICROBIT_DISPLAY_WIDTH = 5,
MICROBIT_DISPLAY_HEIGHT = 5,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitMessageBus.h
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitMultiButton.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitMessageBus.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitMultiButton.h
MICROBIT_MULTI_BUTTON_STATE_1 = 0x01,
MICROBIT_MULTI_BUTTON_STATE_2 = 0x02,
MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1 = 0x04,
@ -353,7 +355,7 @@ declare const enum DAL {
MICROBIT_MULTI_BUTTON_SUPRESSED_1 = 0X10,
MICROBIT_MULTI_BUTTON_SUPRESSED_2 = 0x20,
MICROBIT_MULTI_BUTTON_ATTACHED = 0x40,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitPin.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitPin.h
IO_STATUS_DIGITAL_IN = 0x01,
IO_STATUS_DIGITAL_OUT = 0x02,
IO_STATUS_ANALOG_IN = 0x04,
@ -375,7 +377,7 @@ declare const enum DAL {
MICROBIT_PIN_EVT_PULSE_LO = 5,
PIN_CAPABILITY_DIGITAL = 0x01,
PIN_CAPABILITY_ANALOG = 0x02,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitRadio.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitRadio.h
MICROBIT_RADIO_STATUS_INITIALISED = 0x0001,
MICROBIT_RADIO_BASE_ADDRESS = 0x75626974,
MICROBIT_RADIO_DEFAULT_GROUP = 0,
@ -387,9 +389,9 @@ declare const enum DAL {
MICROBIT_RADIO_PROTOCOL_DATAGRAM = 1,
MICROBIT_RADIO_PROTOCOL_EVENTBUS = 2,
MICROBIT_RADIO_EVT_DATAGRAM = 1,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitRadioDatagram.h
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitRadioEvent.h
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitSerial.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitRadioDatagram.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitRadioEvent.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitSerial.h
MICROBIT_SERIAL_DEFAULT_BAUD_RATE = 115200,
MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE = 20,
MICROBIT_SERIAL_EVT_DELIM_MATCH = 1,
@ -402,31 +404,31 @@ declare const enum DAL {
ASYNC = 0,
SYNC_SPINWAIT = 1,
SYNC_SLEEP = 2,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitStorage.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitStorage.h
MICROBIT_STORAGE_MAGIC = 0xCAFE,
MICROBIT_STORAGE_BLOCK_SIZE = 48,
MICROBIT_STORAGE_KEY_SIZE = 16,
MICROBIT_STORAGE_STORE_PAGE_OFFSET = 17,
MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET = 19,
// built\yt\yotta_modules\microbit-dal\inc\drivers\MicroBitThermometer.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitThermometer.h
MICROBIT_THERMOMETER_PERIOD = 1000,
MICROBIT_THERMOMETER_EVT_UPDATE = 1,
MICROBIT_THERMOMETER_ADDED_TO_IDLE = 2,
// built\yt\yotta_modules\microbit-dal\inc\drivers\TimedInterruptIn.h
// built\yt\yotta_modules\microbit-dal\inc\platform\yotta_cfg_mappings.h
// built\yt\yotta_modules\microbit-dal\inc\types\ManagedString.h
// built\yt\yotta_modules\microbit-dal\inc\types\ManagedType.h
// built\yt\yotta_modules\microbit-dal\inc\types\Matrix4.h
// built\yt\yotta_modules\microbit-dal\inc\types\MicroBitCoordinateSystem.h
// built/yt/yotta_modules/microbit-dal/inc/drivers/TimedInterruptIn.h
// built/yt/yotta_modules/microbit-dal/inc/platform/yotta_cfg_mappings.h
// built/yt/yotta_modules/microbit-dal/inc/types/ManagedString.h
// built/yt/yotta_modules/microbit-dal/inc/types/ManagedType.h
// built/yt/yotta_modules/microbit-dal/inc/types/Matrix4.h
// built/yt/yotta_modules/microbit-dal/inc/types/MicroBitCoordinateSystem.h
RAW = 0,
SIMPLE_CARTESIAN = 1,
NORTH_EAST_DOWN = 2,
// built\yt\yotta_modules\microbit-dal\inc\types\MicroBitEvent.h
// built/yt/yotta_modules/microbit-dal/inc/types/MicroBitEvent.h
MICROBIT_ID_ANY = 0,
MICROBIT_EVT_ANY = 0,
CREATE_ONLY = 0,
CREATE_AND_FIRE = 1,
// built\yt\yotta_modules\microbit-dal\inc\types\MicroBitImage.h
// built\yt\yotta_modules\microbit-dal\inc\types\PacketBuffer.h
// built\yt\yotta_modules\microbit-dal\inc\types\RefCounted.h
// built/yt/yotta_modules/microbit-dal/inc/types/MicroBitImage.h
// built/yt/yotta_modules/microbit-dal/inc/types/PacketBuffer.h
// built/yt/yotta_modules/microbit-dal/inc/types/RefCounted.h
}

View File

@ -275,7 +275,9 @@ declare namespace led {
declare enum PulseValue {
//% block=high
High = 4, // MICROBIT_PIN_EVT_PULSE_HI
//% block=low
Low = 5, // MICROBIT_PIN_EVT_PULSE_LO
}

View File

@ -40,7 +40,7 @@ namespace game {
* @param x sprite horizontal coordinate, eg: 2
* @param y sprite vertical coordinate, eg: 2
*/
//% weight=60
//% weight=60 blockGap=8
//% blockId=game_create_sprite block="create sprite at|x: %x|y: %y"
//% parts="ledmatrix"
export function createSprite(x: number, y: number): LedSprite {
@ -146,8 +146,9 @@ namespace game {
/**
* Sets the current score value
* @param value TODO
* @param value new score value.
*/
//% blockId=game_set_score block="set score %points" blockGap=8
//% weight=10 help=game/set-score
export function setScore(value: number): void {
_score = Math.max(0, value);
@ -589,7 +590,7 @@ namespace game {
/**
* Turns on the sprite (on by default)
* @param this TODO
* @param this the sprite
*/
public on(): void {
this.setBrightness(255);
@ -597,7 +598,7 @@ namespace game {
/**
* Turns off the sprite (on by default)
* @param this TODO
* @param this the sprite
*/
public off(): void {
this.setBrightness(0);
@ -605,8 +606,8 @@ namespace game {
/**
* Set the ``brightness`` of a sprite
* @param this TODO
* @param brightness TODO
* @param this the sprite
* @param brightness the brightness from 0 (off) to 255 (on), eg: 255.
*/
//% parts="ledmatrix"
public setBrightness(brightness: number): void {
@ -616,8 +617,9 @@ namespace game {
/**
* Reports the ``brightness` of a sprite on the LED screen
* @param this TODO
* @param this the sprite
*/
//% parts="ledmatrix"
public brightness(): number {
let r: number;
return this._brightness;
@ -625,8 +627,8 @@ namespace game {
/**
* Changes the ``y`` position by the given amount
* @param this TODO
* @param value TODO
* @param this the sprite
* @param value the value to change brightness
*/
public changeBrightnessBy(value: number): void {
this.setBrightness(this._brightness + value);
@ -643,10 +645,12 @@ namespace game {
/**
* Deletes the sprite from the game engine. All further operation of the sprite will not have any effect.
* @param sprite TODO
* @param this sprite to delete
*/
public delete(sprite: LedSprite): void {
sprites.removeElement(sprite);
//% weight=59
//% blockId="game_delete_sprite" block="delete %this"
public delete(): void {
sprites.removeElement(this);
}
/**

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
/**
* Creation, manipulation and display of LED images.
@ -61,18 +61,15 @@ namespace ImageMethods {
/**
* Scrolls an image .
* @param frameOffset x offset moved on each animation step, eg: 5, 1, -1
* @param frameOffset x offset moved on each animation step, eg: 1, 2, 5
* @param interval time between each animation step in milli seconds, eg: 200
*/
//% help=images/show-image weight=79 async blockNamespace=images
//% help=images/scroll-image weight=79 async blockNamespace=images
//% blockId=device_scroll_image block="scroll image %sprite|with offset %frameoffset|and interval (ms) %delay" blockGap=8
//% parts="ledmatrix"
void scrollImage(Image id, int frameOffset, int interval) {
MicroBitImage i(id);
if (i.getWidth() <= 5)
showImage(id, 0);
else
uBit.display.animate(i, interval, frameOffset, 0);
uBit.display.animate(i, interval, frameOffset, MICROBIT_DISPLAY_WIDTH - 1);
}

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
enum class Button {
A = MICROBIT_ID_BUTTON_A,

View File

@ -1,12 +0,0 @@
#include "pxt.h"
#include "ManagedBuffer.h"
using namespace pxt;
MicroBitPin *getPin(int id);
typedef ImageData* Image;
typedef BufferData* Buffer;
namespace pxt {
uint32_t programSize();
uint32_t afterProgramPage();
}

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
enum class DisplayMode_ {
//% block="black and white"
@ -95,7 +95,7 @@ namespace led {
/**
* Turns on or off the display
*/
//% help=led/enable blockId=device_led_enable icon="\uf04d"
//% help=led/enable blockId=device_led_enable block="led enable %on" icon="\uf04d"
//% advanced=true parts="ledmatrix"
void enable(bool on) {
if (on) uBit.display.enable();

View File

@ -119,7 +119,11 @@ enum BeatFraction {
//% block="1/8"
Eighth = 8,
//% block="1/16"
Sixteenth = 16
Sixteenth = 16,
//% block="2"
Double = 32,
//% block="4",
Breve = 64
}
/**
@ -138,7 +142,6 @@ namespace music {
//% blockId=device_play_note block="play|tone %note=device_note|for %duration=device_beat" icon="\uf025" blockGap=8
//% parts="headphone"
export function playTone(frequency: number, ms: number): void {
pins.analogSetPitchPin(AnalogPin.P0);
pins.analogPitch(frequency, ms);
}
@ -150,7 +153,6 @@ namespace music {
//% blockId=device_ring block="ring tone (Hz)|%note=device_note" icon="\uf025" blockGap=8
//% parts="headphone"
export function ringTone(frequency: number): void {
pins.analogSetPitchPin(AnalogPin.P0);
pins.analogPitch(frequency, 0);
}
@ -190,11 +192,15 @@ namespace music {
init();
if (fraction == null) fraction = BeatFraction.Whole;
let beat = 60000 / beatsPerMinute;
if (fraction == BeatFraction.Whole) return beat;
else if (fraction == BeatFraction.Half) return beat / 2;
else if (fraction == BeatFraction.Quarter) return beat / 4
else if (fraction == BeatFraction.Eighth) return beat / 8;
else return beat / 16;
switch (fraction) {
case BeatFraction.Half: return beat / 2;
case BeatFraction.Quarter: return beat / 4;
case BeatFraction.Eighth: return beat / 8;
case BeatFraction.Sixteenth: return beat / 16;
case BeatFraction.Double: return beat * 2;
case BeatFraction.Breve: return beat * 4;
default: return beat;
}
}
/**

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
enum class DigitalPin {
P0 = MICROBIT_ID_IO_P0,
@ -32,7 +32,9 @@ enum class AnalogPin {
};
enum class PulseValue {
//% block=high
High = MICROBIT_PIN_EVT_PULSE_HI,
//% block=low
Low = MICROBIT_PIN_EVT_PULSE_LO
};
@ -145,7 +147,7 @@ namespace pins {
/**
* Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either ``high`` or ``low``.
*/
//% help=pins/on-pulsed weight=22 blockGap=8
//% help=pins/on-pulsed weight=22 blockGap=8 advanced=true
//% blockId=pins_on_pulsed block="on|pin %pin|pulsed %pulse"
void onPulsed(DigitalPin name, PulseValue pulse, Action body) {
MicroBitPin* pin = getPin((int)name);
@ -158,7 +160,7 @@ namespace pins {
/**
* Gets the duration of the last pulse in micro-seconds. This function should be called from a ``onPulsed`` handler.
*/
//% help=pins/pulse-duration
//% help=pins/pulse-duration advanced=true
//% blockId=pins_pulse_duration block="pulse duration (µs)"
//% weight=21 blockGap=8
int pulseDuration() {
@ -172,7 +174,7 @@ namespace pins {
* @param maximum duration in micro-seconds
*/
//% blockId="pins_pulse_in" block="pulse in (µs)|pin %name|pulsed %value"
//% weight=20
//% weight=20 advanced=true
int pulseIn(DigitalPin name, PulseValue value, int maxDuration = 2000000) {
MicroBitPin* pin = getPin((int)name);
if (!pin) return 0;
@ -221,22 +223,25 @@ namespace pins {
MicroBitPin* pitchPin = NULL;
/**
* Sets the pin used when using `pins->analog pitch`.
* @param name TODO
* Sets the pin used when using `analog pitch` or music.
* @param name pin to modulate pitch from
*/
//% help=pins/analog-set-pitch weight=12
//% blockId=device_analog_set_pitch_pin block="analog set pitch pin %name"
//% help=pins/analog-set-pitch weight=3 advanced=true
void analogSetPitchPin(AnalogPin name) {
pitchPin = getPin((int)name);
}
/**
* Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.
* @param frequency TODO
* @param ms TODO
* @param frequency frequency to modulate in Hz.
* @param ms duration of the pitch in milli seconds.
*/
//% help=pins/analog-pitch weight=14 async
//% blockId=device_analog_pitch block="analog pitch %frequency|for (ms) %ms"
//% help=pins/analog-pitch weight=4 async advanced=true blockGap=8
void analogPitch(int frequency, int ms) {
if (pitchPin == NULL) return;
if (pitchPin == NULL)
analogSetPitchPin(AnalogPin::P0);
if (frequency <= 0) {
pitchPin->setAnalogValue(0);
} else {
@ -258,7 +263,7 @@ namespace pins {
* @param name pin to set the pull mode on
* @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
*/
//% help=pins/set-pull weight=3
//% help=pins/set-pull weight=3 advanced=true
//% blockId=device_set_pull block="set pull|pin %pin|to %pull"
void setPull(DigitalPin name, PinPullMode pull) {
PinMode m = pull == PinPullMode::PullDown
@ -309,7 +314,7 @@ namespace pins {
* Write to the SPI slave and return the response
* @param value Data to be sent to the SPI slave
*/
//% help=pins/spi-write weight=5
//% help=pins/spi-write weight=5 advanced=true
//% blockId=spi_write block="spi write %value"
int spiWrite(int value) {
auto p = allocSPI();

View File

@ -21,7 +21,7 @@ namespace pins {
/**
* Read one number from 7-bit I2C address.
*/
//% help=pins/i2c-read-number blockGap=8
//% help=pins/i2c-read-number blockGap=8 advanced=true
//% blockId=pins_i2c_readnumber block="i2c read number|at address %address|of format %format=i2c_sizeof" weight=7
export function i2cReadNumber(address: number, format: NumberFormat): number {
let buf = pins.i2cReadBuffer(address, pins.sizeOf(format))
@ -31,7 +31,7 @@ namespace pins {
/**
* Write one number to a 7-bit I2C address.
*/
//% help=pins/i2c-write-number blockGap=8
//% help=pins/i2c-write-number blockGap=8 advanced=true
//% blockId=i2c_writenumber block="i2c write number|at address %address|with value %value|of format %format=i2c_sizeof" weight=6
export function i2cWriteNumber(address: number, value: number, format: NumberFormat): void {
let buf = createBuffer(pins.sizeOf(format))

481
libs/core/pxt.cpp Normal file
View File

@ -0,0 +1,481 @@
#include "pxt.h"
#include <map>
MicroBit uBit;
namespace pxt {
int incr(uint32_t e)
{
if (e) {
if (hasVTable(e))
((RefObject*)e)->ref();
else
((RefCounted*)e)->incr();
}
return e;
}
void decr(uint32_t e)
{
if (e) {
if (hasVTable(e))
((RefObject*)e)->unref();
else
((RefCounted*)e)->decr();
}
}
Action mkAction(int reflen, int totallen, int startptr)
{
check(0 <= reflen && reflen <= totallen, ERR_SIZE, 1);
check(reflen <= totallen && totallen <= 255, ERR_SIZE, 2);
check(bytecode[startptr] == 0xffff, ERR_INVALID_BINARY_HEADER, 3);
check(bytecode[startptr + 1] == 0, ERR_INVALID_BINARY_HEADER, 4);
uint32_t tmp = (uint32_t)&bytecode[startptr];
if (totallen == 0) {
return tmp; // no closure needed
}
void *ptr = ::operator new(sizeof(RefAction) + totallen * sizeof(uint32_t));
RefAction *r = new (ptr) RefAction();
r->len = totallen;
r->reflen = reflen;
r->func = (ActionCB)((tmp + 4) | 1);
memset(r->fields, 0, r->len * sizeof(uint32_t));
return (Action)r;
}
uint32_t runAction3(Action a, int arg0, int arg1, int arg2)
{
if (hasVTable(a))
return ((RefAction*)a)->runCore(arg0, arg1, arg2);
else {
check(*(uint16_t*)a == 0xffff, ERR_INVALID_BINARY_HEADER, 4);
return ((ActionCB)((a + 4) | 1))(NULL, arg0, arg1, arg2);
}
}
uint32_t runAction2(Action a, int arg0, int arg1)
{
return runAction3(a, arg0, arg1, 0);
}
uint32_t runAction1(Action a, int arg0)
{
return runAction3(a, arg0, 0, 0);
}
uint32_t runAction0(Action a)
{
return runAction3(a, 0, 0, 0);
}
RefRecord* mkClassInstance(int vtableOffset)
{
VTable *vtable = (VTable*)&bytecode[vtableOffset];
intcheck(vtable->methods[0] == &RefRecord_destroy, ERR_SIZE, 3);
intcheck(vtable->methods[1] == &RefRecord_print, ERR_SIZE, 4);
void *ptr = ::operator new(vtable->numbytes);
RefRecord *r = new (ptr) RefRecord(PXT_VTABLE_TO_INT(vtable));
memset(r->fields, 0, vtable->numbytes - sizeof(RefRecord));
return r;
}
uint32_t RefRecord::ld(int idx)
{
//intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, ERR_OUT_OF_BOUNDS, 1);
return fields[idx];
}
uint32_t RefRecord::ldref(int idx)
{
//printf("LD %p len=%d reflen=%d idx=%d\n", this, len, reflen, idx);
//intcheck(0 <= idx && idx < reflen, ERR_OUT_OF_BOUNDS, 2);
uint32_t tmp = fields[idx];
incr(tmp);
return tmp;
}
void RefRecord::st(int idx, uint32_t v)
{
//intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, ERR_OUT_OF_BOUNDS, 3);
fields[idx] = v;
}
void RefRecord::stref(int idx, uint32_t v)
{
//printf("ST %p len=%d reflen=%d idx=%d\n", this, len, reflen, idx);
//intcheck(0 <= idx && idx < reflen, ERR_OUT_OF_BOUNDS, 4);
decr(fields[idx]);
fields[idx] = v;
}
void RefObject::destroy() {
((RefObjectMethod)getVTable()->methods[0])(this);
}
void RefObject::print() {
((RefObjectMethod)getVTable()->methods[1])(this);
}
void RefRecord_destroy(RefRecord *r) {
auto tbl = r->getVTable();
uint8_t *refmask = (uint8_t*)&tbl->methods[tbl->userdata & 0xff];
int len = (tbl->numbytes >> 2) - 1;
for (int i = 0; i < len; ++i) {
if (refmask[i]) decr(r->fields[i]);
r->fields[i] = 0;
}
//RefRecord is allocated using placement new
r->~RefRecord();
::operator delete(r);
}
void RefRecord_print(RefRecord *r)
{
printf("RefRecord %p r=%d size=%d bytes\n", r, r->refcnt, r->getVTable()->numbytes);
}
void RefCollection::push(uint32_t x) {
if (isRef()) incr(x);
data.push_back(x);
}
uint32_t RefCollection::getAt(int x) {
if (in_range(x)) {
uint32_t tmp = data.at(x);
if (isRef()) incr(tmp);
return tmp;
}
else {
error(ERR_OUT_OF_BOUNDS);
return 0;
}
}
void RefCollection::removeAt(int x) {
if (!in_range(x))
return;
if (isRef()) decr(data.at(x));
data.erase(data.begin()+x);
}
void RefCollection::setAt(int x, uint32_t y) {
if (!in_range(x))
return;
if (isRef()) {
decr(data.at(x));
incr(y);
}
data.at(x) = y;
}
int RefCollection::indexOf(uint32_t x, int start) {
if (!in_range(start))
return -1;
if (isString()) {
StringData *xx = (StringData*)x;
for (uint32_t i = start; i < data.size(); ++i) {
StringData *ee = (StringData*)data.at(i);
if (xx->len == ee->len && memcmp(xx->data, ee->data, xx->len) == 0)
return (int)i;
}
} else {
for (uint32_t i = start; i < data.size(); ++i)
if (data.at(i) == x)
return (int)i;
}
return -1;
}
int RefCollection::removeElement(uint32_t x) {
int idx = indexOf(x, 0);
if (idx >= 0) {
removeAt(idx);
return 1;
}
return 0;
}
namespace Coll0 {
PXT_VTABLE_BEGIN(RefCollection, 0, 0)
PXT_VTABLE_END
}
namespace Coll1 {
PXT_VTABLE_BEGIN(RefCollection, 1, 0)
PXT_VTABLE_END
}
namespace Coll3 {
PXT_VTABLE_BEGIN(RefCollection, 3, 0)
PXT_VTABLE_END
}
RefCollection::RefCollection(uint16_t flags) : RefObject(0) {
switch (flags) {
case 0:
vtable = PXT_VTABLE_TO_INT(&Coll0::RefCollection_vtable);
break;
case 1:
vtable = PXT_VTABLE_TO_INT(&Coll1::RefCollection_vtable);
break;
case 3:
vtable = PXT_VTABLE_TO_INT(&Coll3::RefCollection_vtable);
break;
default:
error(ERR_SIZE);
break;
}
}
void RefCollection::destroy()
{
if (this->isRef())
for (uint32_t i = 0; i < this->data.size(); ++i) {
decr(this->data[i]);
this->data[i] = 0;
}
this->data.resize(0);
delete this;
}
void RefCollection::print()
{
printf("RefCollection %p r=%d flags=%d size=%d [%p, ...]\n", this, refcnt, getFlags(), data.size(), data.size() > 0 ? data[0] : 0);
}
PXT_VTABLE_CTOR(RefAction) {}
// fields[] contain captured locals
void RefAction::destroy()
{
for (int i = 0; i < this->reflen; ++i) {
decr(fields[i]);
fields[i] = 0;
}
//RefAction is allocated using placement new
this->~RefAction();
::operator delete(this);
}
void RefAction::print()
{
printf("RefAction %p r=%d pc=0x%lx size=%d (%d refs)\n", this, refcnt, (const uint8_t*)func - (const uint8_t*)bytecode, len, reflen);
}
void RefLocal::print()
{
printf("RefLocal %p r=%d v=%d\n", this, refcnt, v);
}
void RefLocal::destroy()
{
delete this;
}
PXT_VTABLE_CTOR(RefLocal) {
v = 0;
}
PXT_VTABLE_CTOR(RefRefLocal) {
v = 0;
}
void RefRefLocal::print()
{
printf("RefRefLocal %p r=%d v=%p\n", this, refcnt, (void*)v);
}
void RefRefLocal::destroy()
{
decr(v);
delete this;
}
PXT_VTABLE_BEGIN(RefMap, 0, RefMapMarker)
PXT_VTABLE_END
RefMap::RefMap() : PXT_VTABLE_INIT(RefMap) {}
void RefMap::destroy() {
for (unsigned i = 0; i < data.size(); ++i) {
if (data[i].key & 1) {
decr(data[i].val);
}
data[i].val = 0;
}
data.resize(0);
delete this;
}
int RefMap::findIdx(uint32_t key) {
for (unsigned i = 0; i < data.size(); ++i) {
if (data[i].key >> 1 == key)
return i;
}
return -1;
}
void RefMap::print()
{
printf("RefMap %p r=%d size=%d\n", this, refcnt, data.size());
}
#ifdef DEBUG_MEMLEAKS
std::set<RefObject*> allptrs;
void debugMemLeaks()
{
printf("LIVE POINTERS:\n");
for(std::set<RefObject*>::iterator itr = allptrs.begin();itr!=allptrs.end();itr++)
{
(*itr)->print();
}
printf("\n");
}
#else
void debugMemLeaks() {}
#endif
// ---------------------------------------------------------------------------
// An adapter for the API expected by the run-time.
// ---------------------------------------------------------------------------
map<pair<int, int>, Action> handlersMap;
MicroBitEvent lastEvent;
// We have the invariant that if [dispatchEvent] is registered against the DAL
// for a given event, then [handlersMap] contains a valid entry for that
// event.
void dispatchEvent(MicroBitEvent e) {
lastEvent = e;
Action curr = handlersMap[{ e.source, e.value }];
if (curr)
runAction1(curr, e.value);
curr = handlersMap[{ e.source, MICROBIT_EVT_ANY }];
if (curr)
runAction1(curr, e.value);
}
void registerWithDal(int id, int event, Action a) {
Action prev = handlersMap[{ id, event }];
if (prev)
decr(prev);
else
uBit.messageBus.listen(id, event, dispatchEvent);
incr(a);
handlersMap[{ id, event }] = a;
}
void fiberDone(void *a)
{
decr((Action)a);
release_fiber();
}
void runInBackground(Action a) {
if (a != 0) {
incr(a);
create_fiber((void(*)(void*))runAction0, (void*)a, fiberDone);
}
}
void error(ERROR code, int subcode)
{
printf("Error: %d [%d]\n", code, subcode);
uBit.panic(42);
}
uint16_t *bytecode;
uint32_t *globals;
int numGlobals;
uint32_t *allocate(uint16_t sz)
{
uint32_t *arr = new uint32_t[sz];
memset(arr, 0, sz * 4);
return arr;
}
void checkStr(bool cond, const char *msg)
{
if (!cond) {
while (true) {
uBit.display.scroll(msg, 100);
uBit.sleep(100);
}
}
}
int templateHash()
{
return ((int*)bytecode)[4];
}
int programHash()
{
return ((int*)bytecode)[6];
}
int getNumGlobals()
{
return bytecode[16];
}
void exec_binary(int32_t *pc)
{
// XXX re-enable once the calibration code is fixed and [editor/embedded.ts]
// properly prepends a call to [internal_main].
// ::touch_develop::internal_main();
// unique group for radio based on source hash
// ::touch_develop::micro_bit::radioDefaultGroup = programHash();
// repeat error 4 times and restart as needed
microbit_panic_timeout(4);
int32_t ver = *pc++;
checkStr(ver == 0x4209, ":( Bad runtime version");
bytecode = *((uint16_t**)pc++); // the actual bytecode is here
globals = allocate(getNumGlobals());
// just compare the first word
checkStr(((uint32_t*)bytecode)[0] == 0x923B8E70 &&
templateHash() == *pc,
":( Failed partial flash");
uint32_t startptr = (uint32_t)bytecode;
startptr += 48; // header
startptr |= 1; // Thumb state
((uint32_t (*)())startptr)();
#ifdef DEBUG_MEMLEAKS
pxt::debugMemLeaks();
#endif
return;
}
void start()
{
exec_binary((int32_t*)functionsAndBytecode);
}
}
// vim: ts=2 sw=2 expandtab

341
libs/core/pxt.h Normal file
View File

@ -0,0 +1,341 @@
#ifndef __PXT_H
#define __PXT_H
// #define DEBUG_MEMLEAKS 1
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include "MicroBit.h"
#include "MicroBitImage.h"
#include "ManagedString.h"
#include "ManagedType.h"
#include "ManagedBuffer.h"
#define printf(...) uBit.serial.printf(__VA_ARGS__)
// #define printf(...)
#define intcheck(...) check(__VA_ARGS__)
//#define intcheck(...) do {} while (0)
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stdint.h>
#ifdef DEBUG_MEMLEAKS
#include <set>
#endif
extern MicroBit uBit;
namespace pxt {
typedef uint32_t Action;
typedef uint32_t ImageLiteral;
typedef enum {
ERR_INVALID_BINARY_HEADER = 5,
ERR_OUT_OF_BOUNDS = 8,
ERR_REF_DELETED = 7,
ERR_SIZE = 9,
} ERROR;
extern const uint32_t functionsAndBytecode[];
extern uint32_t *globals;
extern uint16_t *bytecode;
class RefRecord;
// Utility functions
extern MicroBitEvent lastEvent;
void registerWithDal(int id, int event, Action a);
void runInBackground(Action a);
uint32_t runAction3(Action a, int arg0, int arg1, int arg2);
uint32_t runAction2(Action a, int arg0, int arg1);
uint32_t runAction1(Action a, int arg0);
uint32_t runAction0(Action a);
Action mkAction(int reflen, int totallen, int startptr);
void error(ERROR code, int subcode = 0);
void exec_binary(uint16_t *pc);
void start();
void debugMemLeaks();
// allocate [sz] words and clear them
uint32_t *allocate(uint16_t sz);
int templateHash();
int programHash();
uint32_t programSize();
uint32_t afterProgramPage();
int getNumGlobals();
RefRecord* mkClassInstance(int vtableOffset);
// The standard calling convention is:
// - when a pointer is loaded from a local/global/field etc, and incr()ed
// (in other words, its presence on stack counts as a reference)
// - after a function call, all pointers are popped off the stack and decr()ed
// This does not apply to the RefRecord and st/ld(ref) methods - they unref()
// the RefRecord* this.
int incr(uint32_t e);
void decr(uint32_t e);
inline void *ptrOfLiteral(int offset)
{
return &bytecode[offset];
}
inline ImageData* imageBytes(int offset)
{
return (ImageData*)(void*)&bytecode[offset];
}
// Checks if object has a VTable, or if its RefCounted* from the runtime.
inline bool hasVTable(uint32_t e)
{
return (*((uint32_t*)e) & 1) == 0;
}
inline void check(int cond, ERROR code, int subcode = 0)
{
if (!cond) error(code, subcode);
}
class RefObject;
#ifdef DEBUG_MEMLEAKS
extern std::set<RefObject*> allptrs;
#endif
typedef void (*RefObjectMethod)(RefObject *self);
typedef void *PVoid;
typedef void **PPVoid;
const PPVoid RefMapMarker = (PPVoid)(void*)43;
struct VTable {
uint16_t numbytes; // in the entire object, including the vtable pointer
uint16_t userdata;
PVoid *ifaceTable;
PVoid methods[2]; // we only use up to two methods here; pxt will generate more
// refmask sits at &methods[nummethods]
};
const int vtableShift = 2;
// A base abstract class for ref-counted objects.
class RefObject
{
public:
uint16_t refcnt;
uint16_t vtable;
RefObject(uint16_t vt)
{
refcnt = 2;
vtable = vt;
#ifdef DEBUG_MEMLEAKS
allptrs.insert(this);
#endif
}
inline VTable *getVTable() {
return (VTable*)(vtable << vtableShift);
}
void destroy();
void print();
// Call to disable pointer tracking on the current instance (in destructor or some other hack)
inline void untrack() {
#ifdef DEBUG_MEMLEAKS
allptrs.erase(this);
#endif
}
// Increment/decrement the ref-count. Decrementing to zero deletes the current object.
inline void ref()
{
check(refcnt > 0, ERR_REF_DELETED);
//printf("INCR "); this->print();
refcnt += 2;
}
inline void unref()
{
//printf("DECR "); this->print();
refcnt -= 2;
if (refcnt == 0) {
destroy();
}
}
};
// A ref-counted collection of either primitive or ref-counted objects (String, Image,
// user-defined record, another collection)
class RefCollection
: public RefObject
{
public:
// 1 - collection of refs (need decr)
// 2 - collection of strings (in fact we always have 3, never 2 alone)
inline uint32_t getFlags() { return getVTable()->userdata; }
inline bool isRef() { return getFlags() & 1; }
inline bool isString() { return getFlags() & 2; }
std::vector<uint32_t> data;
RefCollection(uint16_t f);
inline bool in_range(int x) {
return (0 <= x && x < (int)data.size());
}
inline int length() { return data.size(); }
void destroy();
void print();
void push(uint32_t x);
uint32_t getAt(int x);
void removeAt(int x);
void setAt(int x, uint32_t y);
int indexOf(uint32_t x, int start);
int removeElement(uint32_t x);
};
struct MapEntry {
uint32_t key;
uint32_t val;
};
class RefMap
: public RefObject
{
public:
std::vector<MapEntry> data;
RefMap();
void destroy();
void print();
int findIdx(uint32_t key);
};
// A ref-counted, user-defined JS object.
class RefRecord
: public RefObject
{
public:
// The object is allocated, so that there is space at the end for the fields.
uint32_t fields[];
RefRecord(uint16_t v) : RefObject(v) {}
uint32_t ld(int idx);
uint32_t ldref(int idx);
void st(int idx, uint32_t v);
void stref(int idx, uint32_t v);
};
// these are needed when constructing vtables for user-defined classes
void RefRecord_destroy(RefRecord *r);
void RefRecord_print(RefRecord *r);
class RefAction;
typedef uint32_t (*ActionCB)(uint32_t *captured, uint32_t arg0, uint32_t arg1, uint32_t arg2);
// Ref-counted function pointer. It's currently always a ()=>void procedure pointer.
class RefAction
: public RefObject
{
public:
// This is the same as for RefRecord.
uint8_t len;
uint8_t reflen;
ActionCB func; // The function pointer
// fields[] contain captured locals
uint32_t fields[];
void destroy();
void print();
RefAction();
inline void stCore(int idx, uint32_t v)
{
//printf("ST [%d] = %d ", idx, v); this->print();
intcheck(0 <= idx && idx < len, ERR_OUT_OF_BOUNDS, 10);
intcheck(fields[idx] == 0, ERR_OUT_OF_BOUNDS, 11); // only one assignment permitted
fields[idx] = v;
}
inline uint32_t runCore(int arg0, int arg1, int arg2) // internal; use runAction*() functions
{
this->ref();
uint32_t r = this->func(&this->fields[0], arg0, arg1, arg2);
this->unref();
return r;
}
};
// These two are used to represent locals written from inside inline functions
class RefLocal
: public RefObject
{
public:
uint32_t v;
void destroy();
void print();
RefLocal();
};
class RefRefLocal
: public RefObject
{
public:
uint32_t v;
void destroy();
void print();
RefRefLocal();
};
}
using namespace pxt;
MicroBitPin *getPin(int id);
typedef ImageData* Image;
typedef BufferData* Buffer;
// The ARM Thumb generator in the JavaScript code is parsing
// the hex file and looks for the magic numbers as present here.
//
// Then it fetches function pointer addresses from there.
#define PXT_SHIMS_BEGIN \
namespace pxt { \
const uint32_t functionsAndBytecode[] __attribute__((aligned(0x20))) = { \
0x08010801, 0x42424242, 0x08010801, 0x8de9d83e,
#define PXT_SHIMS_END }; }
#pragma GCC diagnostic ignored "-Wpmf-conversions"
#define PXT_VTABLE_TO_INT(vt) ((uint32_t)(vt) >> vtableShift)
#define PXT_VTABLE_BEGIN(classname, flags, iface) \
const VTable classname ## _vtable \
__attribute__((aligned(1 << vtableShift))) \
= { \
sizeof(classname), \
flags, \
iface, \
{ \
(void*)&classname::destroy, \
(void*)&classname::print,
#define PXT_VTABLE_END } };
#define PXT_VTABLE_INIT(classname) \
RefObject(PXT_VTABLE_TO_INT(&classname ## _vtable))
#define PXT_VTABLE_CTOR(classname) \
PXT_VTABLE_BEGIN(classname, 0, 0) PXT_VTABLE_END \
classname::classname() : PXT_VTABLE_INIT(classname)
#endif
// vim: ts=2 sw=2 expandtab

View File

@ -4,11 +4,14 @@
"installedVersion": "tsmdvf",
"files": [
"README.md",
"ManagedBuffer.cpp",
"ManagedBuffer.h",
"pxt.cpp",
"pxt.h",
"dal.d.ts",
"enums.d.ts",
"shims.d.ts",
"pxt-core.d.ts",
"ksbit.h",
"core.cpp",
"pxt-helpers.ts",
"helpers.ts",
@ -39,8 +42,7 @@
"public": true,
"dependencies": {},
"yotta": {
"configIsJustDefaults": true,
"config": {
"optionalConfig": {
"microbit-dal": {
"bluetooth": {
"enabled": 0

View File

@ -1,4 +1,4 @@
#include "ksbit.h"
#include "pxt.h"
enum SerialPin {
P0 = MICROBIT_ID_IO_P0,

30
libs/core/shims.d.ts vendored
View File

@ -53,10 +53,10 @@ declare interface Image {
/**
* Scrolls an image .
* @param frameOffset x offset moved on each animation step, eg: 5, 1, -1
* @param frameOffset x offset moved on each animation step, eg: 1, 2, 5
* @param interval time between each animation step in milli seconds, eg: 200
*/
//% help=images/show-image weight=79 async blockNamespace=images
//% help=images/scroll-image weight=79 async blockNamespace=images
//% blockId=device_scroll_image block="scroll image %sprite|with offset %frameoffset|and interval (ms) %delay" blockGap=8
//% parts="ledmatrix" shim=ImageMethods::scrollImage
scrollImage(frameOffset: number, interval: number): void;
@ -497,7 +497,7 @@ declare namespace led {
/**
* Turns on or off the display
*/
//% help=led/enable blockId=device_led_enable icon="\uf04d"
//% help=led/enable blockId=device_led_enable block="led enable %on" icon="\uf04d"
//% advanced=true parts="ledmatrix" shim=led::enable
function enable(on: boolean): void;
@ -557,14 +557,14 @@ declare namespace pins {
/**
* Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either ``high`` or ``low``.
*/
//% help=pins/on-pulsed weight=22 blockGap=8
//% help=pins/on-pulsed weight=22 blockGap=8 advanced=true
//% blockId=pins_on_pulsed block="on|pin %pin|pulsed %pulse" shim=pins::onPulsed
function onPulsed(name: DigitalPin, pulse: PulseValue, body: () => void): void;
/**
* Gets the duration of the last pulse in micro-seconds. This function should be called from a ``onPulsed`` handler.
*/
//% help=pins/pulse-duration
//% help=pins/pulse-duration advanced=true
//% blockId=pins_pulse_duration block="pulse duration (µs)"
//% weight=21 blockGap=8 shim=pins::pulseDuration
function pulseDuration(): number;
@ -576,7 +576,7 @@ declare namespace pins {
* @param maximum duration in micro-seconds
*/
//% blockId="pins_pulse_in" block="pulse in (µs)|pin %name|pulsed %value"
//% weight=20 maxDuration.defl=2000000 shim=pins::pulseIn
//% weight=20 advanced=true maxDuration.defl=2000000 shim=pins::pulseIn
function pulseIn(name: DigitalPin, value: PulseValue, maxDuration?: number): number;
/**
@ -599,18 +599,20 @@ declare namespace pins {
function servoSetPulse(name: AnalogPin, micros: number): void;
/**
* Sets the pin used when using `pins->analog pitch`.
* @param name TODO
* Sets the pin used when using `analog pitch` or music.
* @param name pin to modulate pitch from
*/
//% help=pins/analog-set-pitch weight=12 shim=pins::analogSetPitchPin
//% blockId=device_analog_set_pitch_pin block="analog set pitch pin %name"
//% help=pins/analog-set-pitch weight=3 advanced=true shim=pins::analogSetPitchPin
function analogSetPitchPin(name: AnalogPin): void;
/**
* Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.
* @param frequency TODO
* @param ms TODO
* @param frequency frequency to modulate in Hz.
* @param ms duration of the pitch in milli seconds.
*/
//% help=pins/analog-pitch weight=14 async shim=pins::analogPitch
//% blockId=device_analog_pitch block="analog pitch %frequency|for (ms) %ms"
//% help=pins/analog-pitch weight=4 async advanced=true blockGap=8 shim=pins::analogPitch
function analogPitch(frequency: number, ms: number): void;
/**
@ -618,7 +620,7 @@ declare namespace pins {
* @param name pin to set the pull mode on
* @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
*/
//% help=pins/set-pull weight=3
//% help=pins/set-pull weight=3 advanced=true
//% blockId=device_set_pull block="set pull|pin %pin|to %pull" shim=pins::setPull
function setPull(name: DigitalPin, pull: PinPullMode): void;
@ -645,7 +647,7 @@ declare namespace pins {
* Write to the SPI slave and return the response
* @param value Data to be sent to the SPI slave
*/
//% help=pins/spi-write weight=5
//% help=pins/spi-write weight=5 advanced=true
//% blockId=spi_write block="spi write %value" shim=pins::spiWrite
function spiWrite(value: number): number;
}

View File

@ -1,6 +1,6 @@
{
"name": "devices",
"description": "The BLE specific services",
"description": "Camera, remote control and other Bluetooth services",
"files": [
"README.md",
"enums.d.ts",
@ -9,16 +9,8 @@
],
"public": true,
"dependencies": {
"core": "file:../core"
},
"yotta": {
"config": {
"microbit-dal": {
"bluetooth": {
"enabled": 1
}
}
}
"core": "file:../core",
"bluetooth": "file:../bluetooth"
},
"installedVersion": "ljipgq"
}

View File

@ -33,7 +33,7 @@ namespace radio {
* received packet from the radio queue.
*/
//% help=radio/on-data-packet-received
//% mutate=true
//% mutate=objectdestructuring
//% mutateText=Packet
//% mutateDefaults="receivedNumber;receivedString:name,receivedNumber:value;receivedString"
//% blockId=radio_on_packet block="on radio received" blockGap=8

View File

@ -1,6 +1,6 @@
{
"name": "pxt-microbit",
"version": "0.6.13",
"version": "0.6.32",
"description": "micro:bit target for PXT",
"keywords": [
"JavaScript",
@ -34,6 +34,6 @@
"semantic-ui-less": "^2.2.4"
},
"dependencies": {
"pxt-core": "0.5.72"
"pxt-core": "0.5.95"
}
}

View File

@ -160,10 +160,10 @@
},
"compileService": {
"yottaTarget": "bbc-microbit-classic-gcc",
"yottaCorePackage": "pxt-microbit-core",
"githubCorePackage": "microsoft/pxt-microbit-core",
"gittag": "v0.5.1",
"serviceId": "ws"
"yottaCorePackage": "microbit",
"githubCorePackage": "lancaster-university/microbit",
"gittag": "v2.0.0-rc7",
"serviceId": "microbit"
},
"serial": {
"manufacturerFilter": "^mbed$",
@ -173,24 +173,25 @@
"appTheme": {
"accentColor": "#5C005C",
"logoUrl": "http://microbit.org/",
"logo": "./static/logo.portrait.black.svg",
"logo": "./static/logo.portrait.white.svg",
"docsLogo": "./static/logo.square.white.svg",
"portraitLogo": "./static/logo.square.black.svg",
"portraitLogo": "./static/logo.square.white.svg",
"footerLogo": "./static/logo.portrait.black.svg",
"cardLogo": "./static/icons/apple-touch-icon.png",
"appLogo": "./static/icons/apple-touch-icon.png",
"organization": "Microsoft",
"organizationUrl": "https://pxt.io/",
"organizationLogo": "./static/Microsoft-logo_rgb_c-gray.png",
"organizationWideLogo": "./static/Microsoft-logo_rgb_c-white.png",
"homeUrl": "https://pxt.microbit.org/",
"embedUrl": "https://pxt.microbit.org/",
"privacyUrl": "https://go.microsoft.com/fwlink/?LinkId=521839",
"termsOfUseUrl": "https://go.microsoft.com/fwlink/?LinkID=206977",
"githubUrl": "https://github.com/Microsoft/pxt-microbit",
"projectGallery": "projects",
"crowdinProject": "kindscript",
"boardName": "micro:bit",
"sideDoc": "getting-started",
"gettingStarted": "getting-started",
"browserSupport": [
{
"name": "unsupported",
@ -248,6 +249,7 @@
"path": "/device"
}
],
"hasReferenceDocs": true,
"usbDocs": "/device/usb",
"usbHelp": [
{
@ -310,6 +312,16 @@
"browser": "*",
"path": "/static/mb/device/usb-windows-sendto.jpg"
}
]
],
"invertedMenu": true,
"coloredToolbox": true,
"blocklyOptions": {
"grid": {
"spacing": 45,
"length": 7,
"colour": "rgba(189, 195, 199, 0.30)",
"snap": false
}
}
}
}

View File

@ -134,7 +134,7 @@ namespace pxsim.devices {
export function onSignalStrengthChanged(action: number) {
// TODO
}
export function signalStrength() : number {
export function signalStrength(): number {
// TODO
return 0;
}
@ -165,18 +165,20 @@ namespace pxsim.bluetooth {
export function startUartService(): void {
// TODO
}
export function uartWrite(s : string): void {
// TODO
export function uartWrite(s: string): void {
serial.writeString(s)
}
export function uartReadUntil(del: string): string {
// TODO
return ""
return serial.readUntil(del);
}
export function onBluetoothConnected(a : RefAction) {
export function onBluetoothConnected(a: RefAction) {
// TODO
}
export function onBluetoothDisconnected(a : RefAction) {
export function onBluetoothDisconnected(a: RefAction) {
// TODO
}
export function advertiseUrl(url: string, power: number, connectable: boolean) { }
export function stopAdvertising() { }
export function setTransmitPower(power: number) {}
}

View File

@ -1,3 +1,12 @@
/*******************************
User Variable Overrides
*******************************/
@invertedBackground: #3454D1;
/*******************************
PXT Theme Overrides
*******************************/
@mainMenuHeight: 5rem;
@mainMenuMinHeight: (@itemVerticalPadding * 2) + 2em;

View File

@ -1,3 +1,35 @@
/*******************************
User Global Variables
*******************************/
*******************************/
@importGoogleFonts: true;
@fontName : 'Roboto';
@emSize : 14px;
@fontSize : 13px;
@primaryColor: @purple;
@teal: #3891A6;
@blue: #456990;
@red: #EF767A;
@pink: #F46197;
@yellow: #FDE74C;
/* Microbit.org colors */
@orange: #ff8b27;
@purple: #6633cc;
@green: #00ED00;
@pageBackground: #fff;
/*******************************
PXT Overrides
*******************************/
@mainMenuHeight: 5rem;
@mobileMenuHeight: 5rem;
@simulatorBackground: #FDFDFF;
@blocklySvgColor: #ecf0f1;

View File

@ -13,7 +13,137 @@
*******************************/
.download-button {
&:extend(.ui all);
&:extend(.button all);
&:extend(.ui.button all);
&:extend(.purple all);
}
.download-button.download-button-full {
&:extend(.ui.inverted.purple.button all);
}
.download-button:hover {
&:extend(.green all);
}
color: black !important;
}
.play-button.play-button-full {
&:extend(.ui.inverted.button all);
}
.getting-started-btn {
&:extend(.ui.button all);
&:extend(.orange all);
}
#filelist {
background: #fff url(https://az742082.vo.msecnd.net/pub/psopafpj) 0 0 repeat !important;
}
/*******************************
Blockly
*******************************/
.blocklyTreeRow {
border-bottom: 1px solid #ecf0f1 !important;
margin-bottom: 0px !important;
}
/* Blockly toolbox font size same as the page font */
.blocklyTreeLabel {
font-family: @pageFont !important;
font-weight: 200;
}
.blocklyToolboxDiv, .monacoToolboxDiv {
background-color: white !important;
border-left: 1px solid #ecf0f1 !important;
}
.blocklyFlyoutBackground {
fill: #525A67 !important;
fill-opacity: 0.5 !important;
}
/* Remove shadow around blockly blocks */
.blocklyPathDark, .blocklyPathLight {
display: none;
}
.organization {
top: 1.6em;
}
/* Blockly Toolbox Buttons */
#blocklyToolboxButtons .blocklyAddPackageButton {
&:extend(.ui.inverted.pink.button all);
&:extend(.circular all);
}
#blocklyToolboxButtons .blocklyUndoButton {
&:extend(.ui.inverted.blue.button all);
&:extend(.circular all);
}
/*******************************
Monaco
*******************************/
.monaco-editor, .monaco-editor .inputarea {
background: #ecf0f1;
}
.monaco-editor-background {
background: #ecf0f1;
}
.monacoFlyout {
background: rgba(82, 90, 103, 0.8);
}
/* Mobile */
@media only screen and (max-width: @largestMobileScreen) {
#filelist {
background: transparent !important;
}
.organization {
top: auto;
}
}
/* Tablet */
@media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) {
.organization {
top: auto;
}
/* Blockly Toolbox buttons */
#blocklyToolboxButtons {
margin-right: 0.5rem;
margin-left: 0.5rem;
}
}
/* Small Monitor */
@media only screen and (min-width: @computerBreakpoint) and (max-width: @largestSmallMonitor) {
.organization {
top: auto;
}
/* Blockly Toolbox buttons */
#blocklyToolboxButtons {
margin-right: 1rem;
margin-left: 1rem;
}
}
/* Large Monitor */
@media only screen and (min-width: @largeMonitorBreakpoint) {
.blocklyTreeRow {
width: 230px;
padding-left: 1rem;
}
/* Blockly Toolbox buttons */
#blocklyToolboxButtons {
margin-right: 2rem;
margin-left: 2rem;
}
}

View File

@ -32,7 +32,7 @@
@input : 'pxt';
@label : 'pxt';
@list : 'pxt';
@loader : 'pxt';
@loader : 'pulsar';
@rail : 'pxt';
@reveal : 'pxt';
@segment : 'pxt';
@ -41,7 +41,7 @@
/* Collections */
@breadcrumb : 'default';
@form : 'default';
@grid : 'default';
@grid : 'pxt';
@menu : 'pxt';
@message : 'default';
@table : 'default';
@ -91,7 +91,9 @@
@fontPath : 'fonts';
/*
@headerFont : 'Segoe UI', 'Helvetica Neue', Arial, Helvetica, sans-serif;
@pageFont : 'Segoe UI', 'Helvetica Neue', Arial, Helvetica, sans-serif;
*/
/* End Config */