UNPKG

pxt-common-packages

Version:
242 lines (201 loc) 7.19 kB
namespace pxsim { export enum PinFlags { Unused = 0, Digital = 0x0001, Analog = 0x0002, Input = 0x0004, Output = 0x0008, Touch = 0x0010 } export class Pin { constructor(public id: number) { } touched = false; value = 0; period = 0; servoAngle = 0; mode = PinFlags.Unused; pitch = false; pull = 0; // PullDown eventMode = 0; used: boolean = false; servoContinuous: boolean; setValue(value: number) { // value set from the simulator const old = this.value; this.value = value; const b = board(); if (b && this.eventMode == DAL.DEVICE_PIN_EVENT_ON_EDGE && old != this.value) b.bus.queue(this.id, this.value > 0 ? DAL.DEVICE_PIN_EVT_RISE : DAL.DEVICE_PIN_EVT_FALL); } digitalReadPin(): number { this.mode = PinFlags.Digital | PinFlags.Input; return this.value > 100 ? 1 : 0; } digitalWritePin(value: number) { const b = board(); this.mode = PinFlags.Digital | PinFlags.Output; const v = this.value; this.value = value > 0 ? 1023 : 0; runtime.queueDisplayUpdate(); } setPull(pull: number) { this.pull = pull; switch(pull) { case 2 /*PinPullMode.PullDown*/: this.value = 0; break; case 1 /*PinPullMode.PullUp*/: this.value = 1023; break; default: this.value = Math_.randomRange(0, 1023); break; } } analogReadPin(): number { this.mode = PinFlags.Analog | PinFlags.Input; return this.value || 0; } analogWritePin(value: number) { const b = board(); this.mode = PinFlags.Analog | PinFlags.Output; const v = this.value; this.value = Math.max(0, Math.min(1023, value)); runtime.queueDisplayUpdate(); } analogSetPeriod(micros: number) { this.mode = PinFlags.Analog | PinFlags.Output; this.period = micros; runtime.queueDisplayUpdate(); } servoWritePin(value: number) { this.analogSetPeriod(20000); this.servoAngle = Math.max(0, Math.min(180, value)); runtime.queueDisplayUpdate(); } servoSetContinuous(continuous: boolean) { this.servoContinuous = continuous; } servoSetPulse(pinId: number, micros: number) { // TODO } isTouched(): boolean { this.mode = PinFlags.Touch | PinFlags.Analog | PinFlags.Input; return this.touched; } onEvent(ev: number, handler: RefAction) { const b = board(); switch (ev) { case DAL.DEVICE_PIN_EVT_PULSE_HI: case DAL.DEVICE_PIN_EVT_PULSE_LO: this.eventMode = DAL.DEVICE_PIN_EVENT_ON_PULSE; break; case DAL.DEVICE_PIN_EVT_RISE: case DAL.DEVICE_PIN_EVT_FALL: this.eventMode = DAL.DEVICE_PIN_EVENT_ON_EDGE; break; default: return; } b.bus.listen(this.id, ev, handler); } } export class SerialDevice { private baudRate: number; private rxBuffer: RefBuffer; private txBuffer: RefBuffer; constructor(public tx: pins.DigitalInOutPin, public rx: pins.DigitalInOutPin, private id: number) { this.baudRate = 115200; this.setRxBufferSize(64); this.setTxBufferSize(64); } setTxBufferSize(size: number) { this.txBuffer = control.createBuffer(size); } setRxBufferSize(size: number) { this.rxBuffer = control.createBuffer(size); } read(): number { return -1; } readBuffer(): RefBuffer { const buf = control.createBuffer(0); return buf; } writeBuffer(buffer: any) { } setBaudRate(rate: number) { this.baudRate = rate; } redirect(tx: pins.DigitalInOutPin, rx: pins.DigitalInOutPin, rate: number) { this.tx = tx; this.rx = rx; this.baudRate = rate; } onEvent(event: number, handler: RefAction) { pxsim.control.internalOnEvent(this.id, event, handler); } onDelimiterReceived(delimiter: number, handler: RefAction): void { // TODO } } export class SPI { frequency: number; mode: number; constructor(public mosi: pins.DigitalInOutPin, public miso: pins.DigitalInOutPin, public sck: pins.DigitalInOutPin) { this.frequency = 250000; this.mode = 0; } write(value: number) { return 0; } transfer(command: RefBuffer, response: RefBuffer) { } setFrequency(frequency: number) { this.frequency = frequency; } setMode(mode: number) { this.mode = mode; } } export class I2C { constructor(public sda: pins.DigitalInOutPin, public scl: pins.DigitalInOutPin) { } readBuffer(address: number, size: number, repeat?: boolean): RefBuffer { return control.createBuffer(0); } writeBuffer(address: number, buf: RefBuffer, repeat?: boolean): number { return 0; } } export interface EdgeConnectorProps { pins: number[]; servos?: { [name: string]: number; } } export class EdgeConnectorState { pins: Pin[]; private _i2cs: I2C[] = []; private _spis: SPI[] = []; private _serials: SerialDevice[] = []; constructor(public props: EdgeConnectorProps) { this.pins = props.pins.map(id => id != undefined ? new Pin(id) : null); } public getPin(id: number) { return this.pins.filter(p => p && p.id == id)[0] || null } createI2C(sda: pins.DigitalInOutPin, scl: pins.DigitalInOutPin) { let ser = this._i2cs.filter(s => s.sda == sda && s.scl == scl)[0]; if (!ser) this._i2cs.push(ser = new I2C(sda, scl)); return ser; } createSPI(mosi: pins.DigitalInOutPin, miso: pins.DigitalInOutPin, sck: pins.DigitalInOutPin) { let ser = this._spis.filter(s => s.mosi == mosi && s.miso == miso && s.sck == sck)[0]; if (!ser) this._spis.push(ser = new SPI(mosi, miso, sck)); return ser; } createSerialDevice(tx: pins.DigitalInOutPin, rx: pins.DigitalInOutPin, id: number): SerialDevice { let ser = this._serials.filter(s => s.tx == tx && s.rx == rx)[0]; if (!ser) this._serials.push(ser = new SerialDevice(tx, rx, id)); return ser; } } }