Initial sim implementation
This commit is contained in:
68
sim/state/analog.ts
Normal file
68
sim/state/analog.ts
Normal file
@ -0,0 +1,68 @@
|
||||
namespace pxsim {
|
||||
|
||||
enum AnalogOff {
|
||||
InPin1 = 0, // int16[4]
|
||||
InPin6 = 8, // int16[4]
|
||||
OutPin5 = 16, // int16[4]
|
||||
BatteryTemp = 24, // int16
|
||||
MotorCurrent = 26, // int16
|
||||
BatteryCurrent = 28, // int16
|
||||
Cell123456 = 30, // int16
|
||||
Pin1 = 32, // int16[300][4]
|
||||
Pin6 = 2432, // int16[300][4]
|
||||
Actual = 4832, // uint16[4]
|
||||
LogIn = 4840, // uint16[4]
|
||||
LogOut = 4848, // uint16[4]
|
||||
NxtCol = 4856, // uint16[36][4] - NxtColor*4
|
||||
OutPin5Low = 5144, // int16[4]
|
||||
Updated = 5152, // int8[4]
|
||||
InDcm = 5156, // int8[4]
|
||||
InConn = 5160, // int8[4]
|
||||
OutDcm = 5164, // int8[4]
|
||||
OutConn = 5168, // int8[4]
|
||||
Size = 5172
|
||||
}
|
||||
|
||||
export class EV3AnalogState {
|
||||
|
||||
constructor() {
|
||||
let data = new Uint8Array(5172)
|
||||
MMapMethods.register("/dev/lms_analog", {
|
||||
data,
|
||||
beforeMemRead: () => {
|
||||
//console.log("analog before read");
|
||||
const inputNodes = ev3board().getInputNodes();
|
||||
for (let port = 0; port < DAL.NUM_INPUTS; port++) {
|
||||
const node = inputNodes[port];
|
||||
if (node) {
|
||||
data[AnalogOff.InConn + port] = node.isUart() ? DAL.CONN_INPUT_UART : DAL.CONN_INPUT_DUMB;
|
||||
if (node.isAnalog() && node.hasData()) {
|
||||
//data[AnalogOff.InPin6 + 2 * port] = node.getValue();
|
||||
util.map16Bit(data, AnalogOff.InPin6 + 2 * port, node.getValue())
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
read: buf => {
|
||||
let v = "vSIM"
|
||||
for (let i = 0; i < buf.data.length; ++i)
|
||||
buf.data[i] = v.charCodeAt(i) || 0
|
||||
console.log("analog read");
|
||||
console.log(buf.data);
|
||||
return buf.data.length
|
||||
},
|
||||
write: buf => {
|
||||
console.log("analog write");
|
||||
console.log(buf);
|
||||
return 2
|
||||
},
|
||||
ioctl: (id, buf) => {
|
||||
console.log("analog ioctl");
|
||||
console.log(id);
|
||||
console.log(buf);
|
||||
return 2;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
27
sim/state/brick.ts
Normal file
27
sim/state/brick.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/// <reference path="./nodeTypes.ts"/>
|
||||
|
||||
namespace pxsim {
|
||||
|
||||
export class PortNode extends BaseNode {
|
||||
id = NodeType.Port;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class BrickNode extends BaseNode {
|
||||
id = NodeType.Brick;
|
||||
|
||||
buttonState: EV3ButtonState;
|
||||
lightState: EV3LightState;
|
||||
|
||||
constructor() {
|
||||
super(-1);
|
||||
|
||||
this.buttonState = new EV3ButtonState();
|
||||
this.lightState = new EV3LightState();
|
||||
}
|
||||
}
|
||||
}
|
46
sim/state/color.ts
Normal file
46
sim/state/color.ts
Normal file
@ -0,0 +1,46 @@
|
||||
/// <reference path="./sensor.ts"/>
|
||||
|
||||
namespace pxsim {
|
||||
|
||||
export enum ColorSensorMode {
|
||||
Reflected = 0,
|
||||
Ambient = 1,
|
||||
Colors = 2,
|
||||
RefRaw = 3,
|
||||
RgbRaw = 4,
|
||||
ColorCal = 5
|
||||
}
|
||||
|
||||
export enum ThresholdState {
|
||||
Normal = 1,
|
||||
High = 2,
|
||||
Low = 3,
|
||||
}
|
||||
|
||||
export class ColorSensorNode extends UartSensorNode {
|
||||
id = NodeType.ColorSensor;
|
||||
|
||||
private color: number;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
getDeviceType() {
|
||||
return DAL.DEVICE_TYPE_COLOR;
|
||||
}
|
||||
|
||||
setColor(color: number) {
|
||||
this.color = color;
|
||||
this.changed = true;
|
||||
this.valueChanged = true;
|
||||
|
||||
runtime.queueDisplayUpdate();
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.color;
|
||||
}
|
||||
}
|
||||
}
|
@ -63,7 +63,6 @@ namespace pxsim.MMapMethods {
|
||||
|
||||
export function write(m: MMap, data: Buffer): number {
|
||||
return m.impl.write(data)
|
||||
|
||||
}
|
||||
|
||||
export function read(m: MMap, data: Buffer): number {
|
||||
|
47
sim/state/gyro.ts
Normal file
47
sim/state/gyro.ts
Normal file
@ -0,0 +1,47 @@
|
||||
namespace pxsim {
|
||||
const enum GyroSensorMode {
|
||||
None = -1,
|
||||
Angle = 0,
|
||||
Rate = 1,
|
||||
}
|
||||
|
||||
export class GyroSensorNode extends UartSensorNode {
|
||||
id = NodeType.GyroSensor;
|
||||
|
||||
private angle: number = 0;
|
||||
private rate: number = 0;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
getDeviceType() {
|
||||
return DAL.DEVICE_TYPE_GYRO;
|
||||
}
|
||||
|
||||
setAngle(angle: number) {
|
||||
if (this.angle != angle) {
|
||||
this.angle = angle;
|
||||
this.changed = true;
|
||||
this.valueChanged = true;
|
||||
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
setRate(rate: number) {
|
||||
if (this.rate != rate) {
|
||||
this.rate = rate;
|
||||
this.changed = true;
|
||||
this.valueChanged = true;
|
||||
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.mode == GyroSensorMode.Angle ? this.angle :
|
||||
this.mode == GyroSensorMode.Rate ? this.rate : 0;
|
||||
}
|
||||
}
|
||||
}
|
18
sim/state/input.ts
Normal file
18
sim/state/input.ts
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
namespace pxsim.motors {
|
||||
|
||||
export function __motorUsed(port: number, large: boolean) {
|
||||
console.log("MOTOR INIT " + port);
|
||||
const motors = ev3board().getMotor(port, large);
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.sensors {
|
||||
|
||||
export function __sensorUsed(port: number, type: number) {
|
||||
console.log("SENSOR INIT " + port + ", type: " + type);
|
||||
const sensor = ev3board().getSensor(port, type);
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ namespace pxsim {
|
||||
namespace pxsim.output {
|
||||
|
||||
export function setLights(pattern: number) {
|
||||
const lightState = (board() as DalBoard).lightState;
|
||||
const lightState = ev3board().getBrickNode().lightState;
|
||||
lightState.lightPattern = pattern;
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
|
49
sim/state/motor.ts
Normal file
49
sim/state/motor.ts
Normal file
@ -0,0 +1,49 @@
|
||||
namespace pxsim {
|
||||
|
||||
enum MotorDataOff {
|
||||
TachoCounts = 0, // int32
|
||||
Speed = 4, // int8
|
||||
Padding = 5, // int8[3]
|
||||
TachoSensor = 8, // int32
|
||||
Size = 12
|
||||
}
|
||||
|
||||
export class EV3MotorState {
|
||||
|
||||
constructor() {
|
||||
let data = new Uint8Array(12 * DAL.NUM_OUTPUTS)
|
||||
MMapMethods.register("/dev/lms_motor", {
|
||||
data,
|
||||
beforeMemRead: () => {
|
||||
console.log("motor before read");
|
||||
for (let port = 0; port < DAL.NUM_OUTPUTS; ++port) {
|
||||
data[MotorDataOff.TachoCounts * port] = 0; // Tacho count
|
||||
data[MotorDataOff.Speed * port] = 50; // Speed
|
||||
data[MotorDataOff.TachoSensor * port] = 0; // Count
|
||||
}
|
||||
},
|
||||
read: buf => {
|
||||
let v = "vSIM"
|
||||
for (let i = 0; i < buf.data.length; ++i)
|
||||
buf.data[i] = v.charCodeAt(i) || 0
|
||||
console.log("motor read");
|
||||
console.log(buf.data);
|
||||
return buf.data.length
|
||||
},
|
||||
write: buf => {
|
||||
if (buf.data.length == 0) return 2;
|
||||
const cmd = buf.data[0];
|
||||
console.log("motor write");
|
||||
console.log(buf);
|
||||
return 2
|
||||
},
|
||||
ioctl: (id, buf) => {
|
||||
console.log("motor ioctl");
|
||||
console.log(id);
|
||||
console.log(buf);
|
||||
return 2;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
73
sim/state/motors.ts
Normal file
73
sim/state/motors.ts
Normal file
@ -0,0 +1,73 @@
|
||||
namespace pxsim {
|
||||
|
||||
export class MotorNode extends BaseNode {
|
||||
isOutput = true;
|
||||
|
||||
public angle: number = 0;
|
||||
|
||||
private speed: number;
|
||||
private large: boolean;
|
||||
private rotation: number;
|
||||
private polarity: boolean;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
setSpeed(speed: number) {
|
||||
if (this.speed != speed) {
|
||||
this.speed = speed;
|
||||
this.changed = true;
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
setLarge(large: boolean) {
|
||||
this.large = large;
|
||||
}
|
||||
|
||||
getSpeed() {
|
||||
return this.speed;
|
||||
}
|
||||
|
||||
stepSpeed(speed: number, angle: number, brake: boolean) {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
setPolarity(polarity: number) {
|
||||
// Either 1 or 255 (reverse)
|
||||
this.polarity = polarity === 255;
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
reset() {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
stop() {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
start() {
|
||||
// TODO: implement
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
export class MediumMotorNode extends MotorNode {
|
||||
id = NodeType.MediumMotor;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
}
|
||||
|
||||
export class LargeMotorNode extends MotorNode {
|
||||
id = NodeType.LargeMotor;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
36
sim/state/nodeTypes.ts
Normal file
36
sim/state/nodeTypes.ts
Normal file
@ -0,0 +1,36 @@
|
||||
namespace pxsim {
|
||||
export enum NodeType {
|
||||
Port = 0,
|
||||
Brick = 1,
|
||||
TouchSensor = 2,
|
||||
MediumMotor = 3,
|
||||
LargeMotor = 4,
|
||||
GyroSensor = 5,
|
||||
ColorSensor = 6,
|
||||
UltrasonicSensor = 7
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
id: number;
|
||||
didChange(): boolean;
|
||||
}
|
||||
|
||||
export class BaseNode implements Node {
|
||||
public id: number;
|
||||
public port: number;
|
||||
public isOutput = false;
|
||||
|
||||
private used = false;
|
||||
protected changed = true;
|
||||
|
||||
constructor(port: number) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
didChange() {
|
||||
const res = this.changed;
|
||||
this.changed = false;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
104
sim/state/output.ts
Normal file
104
sim/state/output.ts
Normal file
@ -0,0 +1,104 @@
|
||||
namespace pxsim {
|
||||
|
||||
export class EV3OutputState {
|
||||
|
||||
constructor() {
|
||||
let data = new Uint8Array(10)
|
||||
MMapMethods.register("/dev/lms_pwm", {
|
||||
data,
|
||||
beforeMemRead: () => {
|
||||
//console.log("pwm before read");
|
||||
for (let i = 0; i < 10; ++i)
|
||||
data[i] = 0
|
||||
},
|
||||
read: buf => {
|
||||
let v = "vSIM"
|
||||
for (let i = 0; i < buf.data.length; ++i)
|
||||
buf.data[i] = v.charCodeAt(i) || 0
|
||||
console.log("pwm read");
|
||||
return buf.data.length
|
||||
},
|
||||
write: buf => {
|
||||
if (buf.data.length == 0) return 2;
|
||||
const cmd = buf.data[0];
|
||||
switch (cmd) {
|
||||
case DAL.opProgramStart: {
|
||||
// init
|
||||
console.log('init');
|
||||
return 2;
|
||||
}
|
||||
case DAL.opOutputReset: {
|
||||
// reset
|
||||
const port = buf.data[1];
|
||||
const motors = ev3board().getMotor(port);
|
||||
motors.forEach(motor => motor.reset());
|
||||
return 2;
|
||||
}
|
||||
case DAL.opOutputStepSpeed: {
|
||||
// step speed
|
||||
const port = buf.data[1];
|
||||
const speed = buf.data[2];
|
||||
// note that b[3] is padding
|
||||
const step1 = buf.data[4];
|
||||
const step2 = buf.data[5]; // angle
|
||||
const step3 = buf.data[6];
|
||||
const brake = buf.data[7];
|
||||
//console.log(buf);
|
||||
const motors = ev3board().getMotor(port);
|
||||
motors.forEach(motor => motor.stepSpeed(speed, step2, brake === 1));
|
||||
return 2;
|
||||
}
|
||||
case DAL.opOutputStop: {
|
||||
// stop
|
||||
const port = buf.data[1];
|
||||
const brake = buf.data[2];
|
||||
const motors = ev3board().getMotor(port);
|
||||
motors.forEach(motor => motor.stop());
|
||||
return 2;
|
||||
}
|
||||
case DAL.opOutputSpeed: {
|
||||
// setSpeed
|
||||
const port = buf.data[1];
|
||||
const speed = buf.data[2];
|
||||
const motors = ev3board().getMotor(port);
|
||||
motors.forEach(motor => motor.setSpeed(speed));
|
||||
return 2;
|
||||
}
|
||||
case DAL.opOutputStart: {
|
||||
// start
|
||||
const port = buf.data[1];
|
||||
const motors = ev3board().getMotor(port);
|
||||
motors.forEach(motor => motor.start());
|
||||
return 2;
|
||||
}
|
||||
case DAL.opOutputPolarity: {
|
||||
// reverse
|
||||
const port = buf.data[1];
|
||||
const polarity = buf.data[2];
|
||||
const motors = ev3board().getMotor(port);
|
||||
motors.forEach(motor => motor.setPolarity(polarity));
|
||||
return 2;
|
||||
}
|
||||
case DAL.opOutputSetType: {
|
||||
const port = buf.data[1];
|
||||
const large = buf.data[2] == 0x07;
|
||||
const motors = ev3board().getMotor(port);
|
||||
motors.forEach(motor => motor.setLarge(large));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("pwm write");
|
||||
console.log(buf);
|
||||
return 2
|
||||
},
|
||||
ioctl: (id, buf) => {
|
||||
console.log("pwm ioctl");
|
||||
console.log(id);
|
||||
console.log(buf);
|
||||
return 2;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@ namespace pxsim {
|
||||
|
||||
|
||||
export class EV3ScreenState {
|
||||
shouldUpdate: boolean;
|
||||
points: Uint8Array;
|
||||
constructor() {
|
||||
this.points = new Uint8Array(visuals.SCREEN_WIDTH * visuals.SCREEN_HEIGHT)
|
||||
@ -24,13 +23,13 @@ namespace pxsim {
|
||||
|
||||
setPixel(x: number, y: number, v: number) {
|
||||
this.applyMode(OFF(x, y), v)
|
||||
this.shouldUpdate = true;
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
|
||||
clear() {
|
||||
for (let i = 0; i < this.points.length; ++i)
|
||||
this.points[i] = 0;
|
||||
this.shouldUpdate = true;
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
|
||||
blitLineCore(x: number, y: number, w: number, buf: RefBuffer, mode: Draw, offset = 0) {
|
||||
@ -59,7 +58,7 @@ namespace pxsim {
|
||||
}
|
||||
}
|
||||
|
||||
this.shouldUpdate = true;
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
|
||||
clearLine(x: number, y: number, w: number) {
|
||||
@ -82,12 +81,12 @@ namespace pxsim.screen {
|
||||
function YY(v: number) { return v >> 16 }
|
||||
|
||||
export function _setPixel(x: number, y: number, mode: Draw) {
|
||||
const screenState = (board() as DalBoard).screenState;
|
||||
const screenState = ev3board().screenState;
|
||||
screenState.setPixel(x, y, mode);
|
||||
}
|
||||
|
||||
export function _blitLine(xw: number, y: number, buf: RefBuffer, mode: Draw) {
|
||||
const screenState = (board() as DalBoard).screenState;
|
||||
const screenState = ev3board().screenState;
|
||||
screenState.blitLineCore(XX(xw), y, YY(xw), buf, mode)
|
||||
}
|
||||
|
||||
@ -99,7 +98,7 @@ namespace pxsim.screen {
|
||||
return ((x + 7) >> 3)
|
||||
}
|
||||
export function clear(): void {
|
||||
const screenState = (board() as DalBoard).screenState;
|
||||
const screenState = ev3board().screenState;
|
||||
screenState.clear()
|
||||
}
|
||||
|
||||
@ -240,7 +239,7 @@ namespace pxsim.ImageMethods {
|
||||
}
|
||||
|
||||
export function draw(buf: RefBuffer, x: number, y: number, mode: Draw): void {
|
||||
const screenState = (board() as DalBoard).screenState;
|
||||
const screenState = ev3board().screenState;
|
||||
|
||||
if (!screen.isValidImage(buf))
|
||||
return;
|
||||
|
73
sim/state/sensor.ts
Normal file
73
sim/state/sensor.ts
Normal file
@ -0,0 +1,73 @@
|
||||
|
||||
namespace pxsim {
|
||||
|
||||
export class SensorNode extends BaseNode {
|
||||
|
||||
protected mode: number;
|
||||
protected valueChanged: boolean;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
public isUart() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public isAnalog() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public getValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
setMode(mode: number) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
getDeviceType() {
|
||||
return DAL.DEVICE_TYPE_NONE;
|
||||
}
|
||||
|
||||
public hasData() {
|
||||
return true;
|
||||
}
|
||||
|
||||
valueChange() {
|
||||
const res = this.valueChanged;
|
||||
this.valueChanged = false;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
export class AnalogSensorNode extends SensorNode {
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
public isUart() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public isAnalog() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class UartSensorNode extends SensorNode {
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
hasChanged() {
|
||||
return this.changed;
|
||||
}
|
||||
}
|
||||
}
|
42
sim/state/touch.ts
Normal file
42
sim/state/touch.ts
Normal file
@ -0,0 +1,42 @@
|
||||
namespace pxsim {
|
||||
|
||||
export const TOUCH_SENSOR_ANALOG_PRESSED = 2600;
|
||||
|
||||
export class TouchSensorNode extends AnalogSensorNode {
|
||||
id = NodeType.TouchSensor;
|
||||
|
||||
private pressed: boolean[];
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
this.pressed = [];
|
||||
}
|
||||
|
||||
public setPressed(pressed: boolean) {
|
||||
this.pressed.push(pressed);
|
||||
this.changed = true;
|
||||
this.valueChanged = true;
|
||||
}
|
||||
|
||||
public isPressed() {
|
||||
return this.pressed;
|
||||
}
|
||||
|
||||
public getValue() {
|
||||
if (this.pressed.length) {
|
||||
if (this.pressed.pop())
|
||||
return TOUCH_SENSOR_ANALOG_PRESSED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
getDeviceType() {
|
||||
return DAL.DEVICE_TYPE_TOUCH;
|
||||
}
|
||||
|
||||
public hasData() {
|
||||
return this.pressed.length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
156
sim/state/uart.ts
Normal file
156
sim/state/uart.ts
Normal file
@ -0,0 +1,156 @@
|
||||
namespace pxsim {
|
||||
|
||||
enum UartOff {
|
||||
TypeData = 0, // Types[8][4]
|
||||
Repeat = 1792, // uint16[300][4]
|
||||
Raw = 4192, // int8[32][300][4]
|
||||
Actual = 42592, // uint16[4]
|
||||
LogIn = 42600, // uint16[4]
|
||||
Status = 42608, // int8[4]
|
||||
Output = 42612, // int8[32][4]
|
||||
OutputLength = 42740, // int8[4]
|
||||
Size = 42744
|
||||
}
|
||||
|
||||
enum UartStatus {
|
||||
UART_PORT_CHANGED = 1,
|
||||
UART_DATA_READY = 8
|
||||
}
|
||||
|
||||
enum IO {
|
||||
UART_SET_CONN = 0xc00c7500,
|
||||
UART_READ_MODE_INFO = 0xc03c7501,
|
||||
UART_NACK_MODE_INFO = 0xc03c7502,
|
||||
UART_CLEAR_CHANGED = 0xc03c7503,
|
||||
IIC_SET_CONN = 0xc00c6902,
|
||||
IIC_READ_TYPE_INFO = 0xc03c6903,
|
||||
IIC_SETUP = 0xc04c6905,
|
||||
IIC_SET = 0xc02c6906,
|
||||
TST_PIN_ON = 0xc00b7401,
|
||||
TST_PIN_OFF = 0xc00b7402,
|
||||
TST_PIN_READ = 0xc00b7403,
|
||||
TST_PIN_WRITE = 0xc00b7404,
|
||||
TST_UART_ON = 0xc0487405,
|
||||
TST_UART_OFF = 0xc0487406,
|
||||
TST_UART_EN = 0xc0487407,
|
||||
TST_UART_DIS = 0xc0487408,
|
||||
TST_UART_READ = 0xc0487409,
|
||||
TST_UART_WRITE = 0xc048740a,
|
||||
}
|
||||
|
||||
|
||||
enum DevConOff {
|
||||
Connection = 0, // int8[4]
|
||||
Type = 4, // int8[4]
|
||||
Mode = 8, // int8[4]
|
||||
Size = 12
|
||||
}
|
||||
|
||||
enum UartCtlOff {
|
||||
TypeData = 0, // Types
|
||||
Port = 56, // int8
|
||||
Mode = 57, // int8
|
||||
Size = 58
|
||||
}
|
||||
|
||||
enum TypesOff {
|
||||
Name = 0, // int8[12]
|
||||
Type = 12, // int8
|
||||
Connection = 13, // int8
|
||||
Mode = 14, // int8
|
||||
DataSets = 15, // int8
|
||||
Format = 16, // int8
|
||||
Figures = 17, // int8
|
||||
Decimals = 18, // int8
|
||||
Views = 19, // int8
|
||||
RawMin = 20, // float32
|
||||
RawMax = 24, // float32
|
||||
PctMin = 28, // float32
|
||||
PctMax = 32, // float32
|
||||
SiMin = 36, // float32
|
||||
SiMax = 40, // float32
|
||||
InvalidTime = 44, // uint16
|
||||
IdValue = 46, // uint16
|
||||
Pins = 48, // int8
|
||||
Symbol = 49, // int8[5]
|
||||
Align = 54, // uint16
|
||||
Size = 56
|
||||
}
|
||||
|
||||
export class EV3UArtState {
|
||||
|
||||
constructor() {
|
||||
let data = new Uint8Array(UartOff.Size);
|
||||
MMapMethods.register("/dev/lms_uart", {
|
||||
data,
|
||||
beforeMemRead: () => {
|
||||
//console.log("uart before read");
|
||||
const inputNodes = ev3board().getInputNodes();
|
||||
for (let port = 0; port < DAL.NUM_INPUTS; port++) {
|
||||
const node = inputNodes[port];
|
||||
if (node) {
|
||||
// Actual
|
||||
const index = 0; //UartOff.Actual + port * 2;
|
||||
data[UartOff.Raw + DAL.MAX_DEVICE_DATALENGTH * 300 * port + DAL.MAX_DEVICE_DATALENGTH * index] = node.getValue();
|
||||
// Status
|
||||
data[UartOff.Status + port] = node.valueChange() ? UartStatus.UART_PORT_CHANGED : UartStatus.UART_DATA_READY;
|
||||
}
|
||||
}
|
||||
},
|
||||
read: buf => {
|
||||
let v = "vSIM"
|
||||
// for (let i = 0; i < buf.data.length; ++i)
|
||||
// buf.data[i] = v.charCodeAt(i) || 0
|
||||
console.log("uart read");
|
||||
console.log(buf.data);
|
||||
return buf.data.length
|
||||
},
|
||||
write: buf => {
|
||||
console.log("uart write");
|
||||
console.log(buf);
|
||||
return 2
|
||||
},
|
||||
ioctl: (id, buf) => {
|
||||
switch (id) {
|
||||
case IO.UART_SET_CONN: {
|
||||
// Set mode
|
||||
console.log("IO.UART_SET_CONN");
|
||||
for (let port = 0; port < DAL.NUM_INPUTS; port++) {
|
||||
const connection = buf.data[DevConOff.Connection + port]; // CONN_NONE, CONN_INPUT_UART
|
||||
const type = buf.data[DevConOff.Type + port];
|
||||
const mode = buf.data[DevConOff.Mode + port];
|
||||
console.log(`${port}, mode: ${mode}`)
|
||||
const node = ev3board().getInputNodes()[port];
|
||||
if (node) node.setMode(mode);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
case IO.UART_CLEAR_CHANGED: {
|
||||
console.log("IO.UART_CLEAR_CHANGED")
|
||||
for (let port = 0; port < DAL.NUM_INPUTS; port++) {
|
||||
const connection = buf.data[DevConOff.Connection + port]; // CONN_NONE, CONN_INPUT_UART
|
||||
const type = buf.data[DevConOff.Type + port];
|
||||
const mode = buf.data[DevConOff.Mode + port];
|
||||
const node = ev3board().getInputNodes()[port];
|
||||
if (node) node.setMode(mode);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
case IO.UART_READ_MODE_INFO: {
|
||||
console.log("IO.UART_READ_MODE_INFO")
|
||||
const port = buf.data[UartCtlOff.Port];
|
||||
const mode = buf.data[UartCtlOff.Mode];
|
||||
const node = ev3board().getInputNodes()[port];
|
||||
if (node) buf.data[UartCtlOff.TypeData + TypesOff.Type] = node.getDeviceType(); // DEVICE_TYPE_NONE, DEVICE_TYPE_TOUCH,
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
console.log("uart ioctl");
|
||||
console.log(id);
|
||||
console.log(buf);
|
||||
return 2;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
31
sim/state/ultrasonic.ts
Normal file
31
sim/state/ultrasonic.ts
Normal file
@ -0,0 +1,31 @@
|
||||
/// <reference path="./sensor.ts"/>
|
||||
|
||||
namespace pxsim {
|
||||
export class UltrasonicSensorNode extends UartSensorNode {
|
||||
id = NodeType.UltrasonicSensor;
|
||||
|
||||
private distance: number = 50;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port);
|
||||
}
|
||||
|
||||
getDeviceType() {
|
||||
return DAL.DEVICE_TYPE_ULTRASONIC;
|
||||
}
|
||||
|
||||
setDistance(distance: number) {
|
||||
if (this.distance != distance) {
|
||||
this.distance = distance;
|
||||
this.changed = true;
|
||||
this.valueChanged = true;
|
||||
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.distance;
|
||||
}
|
||||
}
|
||||
}
|
7
sim/state/util.ts
Normal file
7
sim/state/util.ts
Normal file
@ -0,0 +1,7 @@
|
||||
namespace pxsim.util {
|
||||
|
||||
export function map16Bit(buffer: Uint8Array, index: number, value: number) {
|
||||
buffer[index] = (value >> 8) & 0xff;
|
||||
buffer[index+1] = value & 0xff;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user