pxt-ev3/sim/state/output.ts

145 lines
7.3 KiB
TypeScript
Raw Normal View History

2017-12-18 22:04:17 +01:00
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 => {
2018-01-06 09:00:04 +01:00
// console.log("pwm read");
if (buf.data.length == 0) return 2;
const cmd = buf.data[0];
switch (cmd) {
case DAL.opOutputTest:
const port = buf.data[1];
let r = 0;
ev3board().getMotor(port)
.filter(motor => !motor.isReady())
.forEach(motor => r |= (1 << motor.port));
pxsim.BufferMethods.setNumber(buf, BufferMethods.NumberFormat.UInt8LE, 2, r);
break;
default:
let v = "vSIM"
for (let i = 0; i < buf.data.length; ++i)
buf.data[i] = v.charCodeAt(i) || 0
break;
}
2017-12-18 22:04:17 +01:00
return buf.data.length
},
write: buf => {
if (buf.data.length == 0) return 2;
const cmd = buf.data[0];
switch (cmd) {
case DAL.opProgramStart: {
// 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.opOutputClearCount:
const port = buf.data[1];
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.clearCount());
break;
case DAL.opOutputStepPower:
case DAL.opOutputStepSpeed:
case DAL.opOutputTimePower:
case DAL.opOutputTimeSpeed: {
2017-12-18 22:04:17 +01:00
// step speed
const port = buf.data[1];
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2); // signed byte
// note that b[3] is padding
const step1 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 4);
const step2 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 8);
const step3 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 12);
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 16);
2017-12-18 22:04:17 +01:00
//console.log(buf);
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.setSpeedCmd(cmd, [speed, step1, step2, step3, brake]));
2017-12-18 22:04:17 +01:00
return 2;
}
case DAL.opOutputStepSync:
case DAL.opOutputTimeSync: {
const port = buf.data[1];
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2); // signed byte
// note that b[3] is padding
const turnRatio = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int16LE, 4);
// b[6], b[7] is padding
const stepsOrTime = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 8);
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 12);
const motors = ev3board().getMotor(port);
// cancel any other sync command
for(const motor of ev3board().getMotors().filter(motor => motors.indexOf(motor) < 0)) {
motor.clearSyncCmd()
}
// apply commands to all motors
for (const motor of motors) {
const otherMotor = motors.filter(m => m.port != motor.port)[0];
motor.setSyncCmd(
2018-01-05 17:40:49 +01:00
otherMotor,
cmd, [speed, turnRatio, stepsOrTime, brake]);
}
return 2;
}
2017-12-18 22:04:17 +01:00
case DAL.opOutputStop: {
// stop
const port = buf.data[1];
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2);
2017-12-18 22:04:17 +01:00
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.stop());
return 2;
}
case DAL.opOutputPower:
2017-12-18 22:04:17 +01:00
case DAL.opOutputSpeed: {
// setSpeed
const port = buf.data[1];
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2);
2017-12-18 22:04:17 +01:00
const motors = ev3board().getMotor(port);
motors.forEach(motor => motor.setSpeedCmd(cmd, [speed]));
2017-12-18 22:04:17 +01:00
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: {
console.error("opOutputPolarity not supported");
2017-12-18 22:04:17 +01:00
return 2;
}
case DAL.opOutputSetType: {
const portIndex = buf.data[1]; // not a port but a port index 0..3
2017-12-18 22:04:17 +01:00
const large = buf.data[2] == 0x07;
const motor = ev3board().getMotors()[portIndex];
if (motor)
motor.setLarge(large);
2017-12-18 22:04:17 +01:00
return 2;
}
default:
console.warn('unknown cmd: ' + cmd);
break;
2017-12-18 22:04:17 +01:00
}
return 2
},
ioctl: (id, buf) => {
return 2;
}
});
}
}
}