Merge branch 'master' into newgfx

This commit is contained in:
Michal Moskal
2017-07-11 12:49:38 +02:00
30 changed files with 4519 additions and 18 deletions

View File

@ -0,0 +1,30 @@
{
"control": "Program controls and events.",
"control.allocateNotifyEvent": "Allocates the next user notification event",
"control.deviceFirmwareVersion": "Determine the version of system software currently running.",
"control.dmesg": "Write data to DMESG debugging buffer.",
"control.mmap": "Create new file mapping in memory",
"control.raiseEvent": "Announce that an event happened to registered handlers.",
"control.raiseEvent|param|src": "ID of the Component that generated the event",
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
"input.Button": "Generic button class, for device buttons and sensors.",
"input.buttonDown": "Down button.",
"input.buttonEnter": "Enter button.",
"input.buttonLeft": "Left button.",
"input.buttonRight": "Right button.",
"input.buttonUp": "Up button.",
"input.remoteBottomLeft": "Remote bottom-left button.",
"input.remoteBottomRight": "Remote bottom-right button.",
"input.remoteCenter": "Remote beacon (center) button.",
"input.remoteTopLeft": "Remote top-left button.",
"input.remoteTopRight": "Remote top-right button.",
"output.createBuffer": "Create a new zero-initialized buffer.",
"output.createBuffer|param|size": "number of bytes in the buffer",
"output.setLights": "Set lights.",
"screen.clear": "Clear screen and reset font to normal.",
"screen.drawText": "Draw text.",
"screen.scroll": "Scroll screen vertically.",
"screen.setFont": "Set font for drawText()",
"serial": "Reading and writing data over a serial connection.",
"serial.writeDmesg": "Send DMESG debug buffer over serial."
}

View File

@ -0,0 +1,28 @@
{
"ButtonEvent.Click|block": "click",
"ButtonEvent.Down|block": "down",
"ButtonEvent.LongClick|block": "long click",
"ButtonEvent.Up|block": "up",
"control.raiseEvent|block": "raise event|from %src|with value value",
"control|block": "control",
"input.buttonDown|block": "button down",
"input.buttonEnter|block": "button enter",
"input.buttonLeft|block": "button left",
"input.buttonRight|block": "button right",
"input.buttonUp|block": "button up",
"input.remoteBottomLeft|block": "remote bottom-left",
"input.remoteBottomRight|block": "remote bottom-right",
"input.remoteCenter|block": "remote center",
"input.remoteTopLeft|block": "remote top-left",
"input.remoteTopRight|block": "remote top-right",
"input|block": "input",
"output.setLights|block": "set lights %pattern",
"output|block": "output",
"screen|block": "screen",
"serial|block": "serial",
"{id:category}Control": "Control",
"{id:category}Input": "Input",
"{id:category}Output": "Output",
"{id:category}Screen": "Screen",
"{id:category}Serial": "Serial"
}

View File

@ -1,9 +1,11 @@
namespace control {
let nextComponentId = 20000;
let nextComponentId: number;
export class Component {
protected _id: number;
constructor(id = 0) {
if (!nextComponentId)
nextComponentId = 20000
if (!id) id = ++nextComponentId
this._id = id
}

View File

@ -1,10 +1,28 @@
namespace input.internal {
//% shim=pxt::unsafePollForChanges
export function unsafePollForChanges(
periodMs: int32,
query: () => int32,
changeHandler: (prev: int32, curr: int32) => void
) { }
periodMs: number,
query: () => number,
changeHandler: (prev: number, curr: number) => void
) {
// This is implemented in C++ without blocking the regular JS when query() is runnning
// which is generally unsafe. Query should not update globally visible state, and cannot
// call any yielding functions, like sleep().
// This is implementation for the simulator.
control.runInBackground(() => {
let prev = query()
while (true) {
loops.pause(periodMs)
let curr = query()
if (prev !== curr) {
changeHandler(prev, curr)
prev = curr
}
}
})
}
let analogMM: MMap
let uartMM: MMap

View File

@ -0,0 +1,81 @@
namespace pxsim {
enum ThresholdState {
High,
Low,
Normal
}
export class AnalogSensorState {
public sensorUsed: boolean = false;
private level: number;
private state = ThresholdState.Normal;
constructor(public id: number, private min = 0, private max = 255, private lowThreshold = 64, private highThreshold = 192) {
this.level = Math.ceil((max - min) / 2);
}
public setUsed() {
if (!this.sensorUsed) {
this.sensorUsed = true;
runtime.queueDisplayUpdate();
}
}
public setLevel(level: number) {
this.level = this.clampValue(level);
if (this.level >= this.highThreshold) {
this.setState(ThresholdState.High);
}
else if (this.level <= this.lowThreshold) {
this.setState(ThresholdState.Low);
}
else {
this.setState(ThresholdState.Normal);
}
}
public getLevel(): number {
return this.level;
}
public setLowThreshold(value: number) {
this.lowThreshold = this.clampValue(value);
this.highThreshold = Math.max(this.lowThreshold + 1, this.highThreshold);
}
public setHighThreshold(value: number) {
this.highThreshold = this.clampValue(value);
this.lowThreshold = Math.min(this.highThreshold - 1, this.lowThreshold);
}
private clampValue(value: number) {
if (value < this.min) {
return this.min;
}
else if (value > this.max) {
return this.max;
}
return value;
}
private setState(state: ThresholdState) {
if (this.state === state) {
return;
}
this.state = state;
switch (state) {
case ThresholdState.High:
board().bus.queue(this.id, DAL.ANALOG_THRESHOLD_HIGH);
break;
case ThresholdState.Low:
board().bus.queue(this.id, DAL.ANALOG_THRESHOLD_LOW);
break;
case ThresholdState.Normal:
break;
}
}
}
}

177
libs/core/sim/pins.ts Normal file
View File

@ -0,0 +1,177 @@
namespace pxsim.pins {
export class CommonPin extends Pin {
used: boolean;
}
export class DigitalPin extends CommonPin {
}
export class AnalogPin extends CommonPin {
}
export function markUsed(name: CommonPin) {
if (!name.used) {
name.used = true;
runtime.queueDisplayUpdate();
}
}
}
namespace pxsim.DigitalPinMethods {
export function digitalRead(name: pins.DigitalPin): number {
return name.digitalReadPin();
}
/**
* Set a pin or connector value to either 0 or 1.
* @param value value to set on the pin, 1 eg,0
*/
export function digitalWrite(name: pins.DigitalPin, value: number): void {
name.digitalWritePin(value);
}
/**
* Configures this pin to a digital input, and generates events where the timestamp is the duration
* that this pin was either ``high`` or ``low``.
*/
export function onPulsed(name: pins.DigitalPin, pulse: number, body: RefAction): void {
// TODO
}
/**
* Returns the duration of a pulse in microseconds
* @param value the value of the pulse (default high)
* @param maximum duration in micro-seconds
*/
export function pulseIn(name: pins.DigitalPin, pulse: number, maxDuration = 2000000): number {
// TODO
return 500;
}
/**
* Configures the pull of this pin.
* @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
*/
export function setPull(name: pins.DigitalPin, pull: number): void {
name.setPull(pull);
}
/**
* Do something when a pin is pressed.
* @param body the code to run when the pin is pressed
*/
export function onPressed(name: pins.DigitalPin, body: RefAction): void {
}
/**
* Do something when a pin is released.
* @param body the code to run when the pin is released
*/
export function onReleased(name: pins.DigitalPin, body: RefAction): void {
}
/**
* Get the pin state (pressed or not). Requires to hold the ground to close the circuit.
* @param name pin used to detect the touch
*/
export function isPressed(name: pins.DigitalPin): boolean {
return name.isTouched();
}
}
namespace pxsim.AnalogPinMethods {
/**
* Read the connector value as analog, that is, as a value comprised between 0 and 1023.
*/
export function analogRead(name: pins.AnalogPin): number {
pins.markUsed(name);
return name.analogReadPin();
}
/**
* Set the connector value as analog. Value must be comprised between 0 and 1023.
* @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0
*/
export function analogWrite(name: pins.AnalogPin, value: number): void {
pins.markUsed(name);
name.analogWritePin(value);
}
/**
* Configures the Pulse-width modulation (PWM) of the analog output to the given value in
* **microseconds** or `1/1000` milliseconds.
* If this pin is not configured as an analog output (using `analog write pin`), the operation has
* no effect.
* @param micros period in micro seconds. eg:20000
*/
export function analogSetPeriod(name: pins.AnalogPin, micros: number): void {
pins.markUsed(name);
name.analogSetPeriod(micros);
}
/**
* Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will
* set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous
* rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one
* direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).
* @param value angle or rotation speed, eg:180,90,0
*/
export function servoWrite(name: pins.AnalogPin, value: number): void {
pins.markUsed(name);
name.servoWritePin(value);
}
/**
* Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the
* pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds.
* @param micros pulse duration in micro seconds, eg:1500
*/
export function servoSetPulse(name: pins.AnalogPin, micros: number): void {
pins.markUsed(name);
// TODO fix pxt
// name.servoSetPulse(micros);
}
}
namespace pxsim.PwmPinMethods {
export function analogSetPeriod(name: pins.AnalogPin, micros: number): void {
name.analogSetPeriod(micros);
}
export function servoWrite(name: pins.AnalogPin, value: number): void {
name.servoWritePin(value);
}
export function servoSetPulse(name: pins.AnalogPin, micros: number): void {
name.servoSetPulse(name.id, micros);
}
}
namespace pxsim.pins {
export function pulseDuration(): number {
// bus last event timestamp
return 500;
}
export function createBuffer(sz: number) {
return pxsim.BufferMethods.createBuffer(sz)
}
export function spiWrite(value: number): number {
// TODO
return 0;
}
export function i2cReadBuffer(address: number, size: number, repeat?: boolean): RefBuffer {
// fake reading zeros
return createBuffer(size)
}
export function i2cWriteBuffer(address: number, buf: RefBuffer, repeat?: boolean): void {
// fake - noop
}
}