Commit 250ff884 authored by Jake Read's avatar Jake Read

hardware abstraction

parent 39aef02e
......@@ -15,6 +15,14 @@ This project serves the developement environment / api we use to write and repre
## For MW
- serial link OK, attach
- routes have route, test send
- thru route, append route
- thru link, to send.
- callback key subscribe fn's
- then: route change propogation?
- test with test: callback
- then draw something, and how does UI hook up, and when route changes ?
- change /src to /modules or /units ?
......
//
//
// new node controller / VIEW
// reconfigurable unviersal numeric dataflow machine controller
// 'RUN DMC'
// dataflow numeric controller
// DNC
//
// client.js
//
......@@ -404,6 +408,8 @@ onwheel = function(evt) {
onmousedown = function(evt) {
var el = document.elementFromPoint(evt.pageX, evt.pageY)
if (elementIsNotModule(el)) {
evt.preventDefault()
evt.stopPropagation()
window.addEventListener('mousemove', mouseMoveDragListener)
window.addEventListener('mouseup', mouseUpDragListener)
}
......@@ -492,14 +498,14 @@ function writeModuleOptionMenu(modRep) {
if (opts[i] == 'delete') {
li.addEventListener('click', function(evt) {
var data = {
id: modRep.description.id
id: modRep.description.id
}
socketSend('remove module', data)
wrapper.removeChild(document.getElementById('perModuleMenu'))
})
} else if (opts[i] == 'copy') {
li.addEventListener('click', function(evt) {
var data = modRep.description.path
var data = modRep.description.path
socketSend('put module', data)
wrapper.removeChild(document.getElementById('perModuleMenu'))
})
......
// object to extend for things-that-are-hardware
// and pass f'n to call on received messages
function ATKPort(route, calls) {
var atkport = {
isAtkPort: true,
function ATKRoute(route, calls) {
var atkroute = {
isAtkRoute: true,
link: null, // pls, deliver 2 me a hw outlet
route: route,
calls: calls
calls: {}
}
atkport.send = function(msg) {
atkroute.send = function(msg) {
if (this.link != null) {
// CHECKS and append route, then send
this.link.send(msg, this)
} else {
console.log("NO LINK NO SEND")
}
}
atkport.onMessage = function(msg){
this.calls(msg)
atkroute.subscribe = function(key, callback){
this.calls[key.toString()] = callback
}
return atkport
atkroute.onMessage = function(msg){
// one key at a time, for now
var key = msg[0].toString()
if(this.calls[key] != null){
this.calls[key](msg)
}
}
return atkroute
}
module.exports = ATKPort
\ No newline at end of file
module.exports = ATKRoute
\ No newline at end of file
// software object for reciprocal hardware object
// boilerplate atkapi header
const InOut = require('./jsunit.js')
let Input = InOut.Input
let Output = InOut.Output
let State = InOut.State
let Button = InOut.Button
const ATKRoute = require('./atkroute.js')
function Hardware(route){
var hardware = {
description:{
name: 'hardwareUnit',
alt: 'software representation of networked hardware object',
isHardware: true
},
route: ATKRoute(route)
}
hardware.state = State()
var state = hardware.state
state.test = Button('test network', onNetworkTest)
state.message = 'click above to test network'
state.route = route
state.onChange('route', function(){
console.log("route change, need to git it thru")
})
function onNetworkTest(){
var tstpck = new Array()
tstpck.push(127)
state.message = 'test packet out'
hardware.route.send(tstpck)
}
hardware.route.subscribe(127, testReturn)
function testReturn(msg){
state.message = 'test OK'
console.log('test returns with msg', msg)
}
return hardware
}
module.exports = Hardware
\ No newline at end of file
......@@ -27,9 +27,24 @@ programs are assemblies of modules
const Reps = require('./reps.js')
const Programs = require('./programs.js')
var program = {}
var program = Programs.new('hw unit test')
program = Programs.open('programs/default.json')
var link = Programs.loadModuleFromSource(program, './modules/hardware/atkseriallink.js')
var atkbbs = Programs.loadModuleFromSource(program, './modules/hardware/atkbbs.js')
atkbbs.description.position = {
left: 10,
top: 200
}
link.description.position = {
left:475,
top: 100
}
link.attach(atkbbs.route)
//program = Programs.open('programs/default.json')
// UI
const View = require('./views.js')
......
......@@ -5,36 +5,40 @@ let Output = InOut.Output
let State = InOut.State
let Button = InOut.Button
const ATKPort = require('../../lib/atkport.js')
const Hardware = require('../../lib/atkunit.js')
const PCKT = require('../../lib/packets.js')
// a constructor, a fn, a javascript mess
function ATKBreadBoardServo() {
var atkbbs = {
description: {
name: 'Breadboard Servo Signal Generator',
alt: 'servo',
isHardware: true
},
port: ATKPort('0', onPacket), // inputs / outputs to external hw
inputs: {
servoVal: Input('number', onServoValChange)
},
outputs: {
conf: Output('event')
},
// we make the module, starting from this base
// '0,1' is the route to our piece of hardware
// 'onPacket' is the function that will be called
// when data arrives from that port
var atkbbs = Hardware('0,1')
// change the name ...
atkbbs.description.name = 'ATKBBB-Servo'
// inputs and outputs as usual
atkbbs.inputs = {
servoVal: Input('number', onServoValChange)
}
atkbbs.outputs = {
conf: Output('event')
}
atkbbs.state = State()
// alias !
var state = atkbbs.state
// and state as well
var state = atkbbs.state
state.button = Button('SEND')
state.onChange('button', onServoValChange)
state.button = Button('SEND VALUE', onServoValChange)
state.servoVal = 0 // 0->100 does 1 -> 2ms duty on 20ms period
state.onChange('servoVal', onServoValChange)
// to send things down the well, we can use
// atkbbs.route.send(packet)
// where packet is a byte array
function onServoValChange(evt) {
var pwm = state.servoVal
if (pwm > 100) {
......@@ -49,12 +53,14 @@ function ATKBreadBoardServo() {
var pwmpack = PCKT.pack32(microval)
pwmpack.unshift(141)
atkbbs.port.send(pwmpack)
atkbbs.route.send(pwmpack)
}
function onPacket(pckt) {
console.log('ATKBBBS Packet Return', pckt)
}
// to get replies to certain packets, we can
atkbbs.route.subscribe(141, function(msg){
console.log('logging return', msg)
})
return atkbbs
}
......
......@@ -8,23 +8,22 @@ let Button = InOut.Button
const SerialPort = require('serialport')
function SerialATKLink() {
var serialATKLink = {
function ATKSerialLink() {
var atkSerialLink = {
description: {
isHardware: true,
name: 'Serialport ATK Link',
alt: 'window into hardware world'
},
ports: new Array()
routes: new Array()
}
var state = State()
serialATKLink.state = state
atkSerialLink.state = state
state.serialPortName = '---'
state.connect = Button('click to find and connect')
state.onChange('connect', findSerialPort)
state.serialPortStatus = 'closed' // or we hope it will be
state.portName = '---'
state.connect = Button('click to find and connect', findSerialPort)
state.portStatus = 'closed' // or we hope it will be
/*
------------------------------------------------------
......@@ -32,10 +31,10 @@ function SerialATKLink() {
------------------------------------------------------
*/
serialATKLink.attach = function(port) {
console.log('PORT->LINK HOOKUP', port.route)
this.ports.push(port)
port.link = this
atkSerialLink.attach = function(route) {
console.log('PORT->LINK HOOKUP', route.route)
this.routes.push(route)
route.link = this
}
/*
......@@ -52,7 +51,7 @@ function SerialATKLink() {
ports.forEach(function(serialport) {
if (serialport.manufacturer == 'Silicon Labs') {
console.log('found cp2102 serialport')
state.serialPortName = serialport.comName
state.portName = serialport.comName
openSerialPort()
}
})
......@@ -60,18 +59,18 @@ function SerialATKLink() {
}
function openSerialPort() {
if (state.serialPortName == '---') {
if (state.portName == '---') {
findSerialPort()
} else {
if (serialport == null) {
serialport = new SerialPort(state.serialPortName, {
serialport = new SerialPort(state.portName, {
baudRate: 250000
})
serialport.on('open', function() {
state.serialPortStatus = 'open'
state.portStatus = 'open'
})
serialport.on('error', function(err) {
state.serialPortStatus = err.message
state.portStatus = err.message
})
serialport.on('data', onSerialPortData)
}
......@@ -84,24 +83,30 @@ function SerialATKLink() {
------------------------------------------------------
*/
serialATKLink.send = function(msg, port) {
atkSerialLink.send = function(msg, route) {
// it would be responsible to check this over now, but hey
console.log('send', msg, 'on', port)
console.log('send', msg, 'on', route.route)
// dereference this
var pckt = JSON.parse(JSON.stringify(msg))
if (Array.isArray(pckt)) {
pckt.unshift(255) // end delimiter
pckt.unshift(254) // ptr
var route = port.route.split(',')
pckt = route.concat(pckt) // add route
var literalRoute = route.route.split(',')
pckt = literalRoute.concat(pckt) // add route
pckt.unshift(pckt.length + 1) // add length byte
if (writeToSerialPort(pckt)) {
console.log('PCKT OOT >>', pckt.toString())
} else {
console.log('ERR: attempt to send to hardware, port not writable')
// try to open ?
openSerialPort()
if (writeToSerialPort(pckt)) {
console.log('PCKT OOT >>', pckt.toString())
} else {
console.log('ERR: attempt to send to hardware, port not writable')
}
}
} else {
console.log('non-array on serialATKLink input')
console.log('non-array on atkSerialLink input')
}
}
......@@ -132,7 +137,7 @@ function SerialATKLink() {
var thisPacket = new Array()
function onSerialPort(data) {
function onSerialPortData(data) {
// we'll make sure it's what we think it will be
// console.log("PORT DATA")
var dtArray = new Array()
......@@ -180,20 +185,20 @@ function SerialATKLink() {
returnRoute[i] = incomingRoute[incomingRoute.length - 1 - i]
}
// now we'll look for a reciprocal port from our list
var match = null
for (key in serialATKLink.ports) {
if (returnRoute.toString() === serialATKLink.ports[key].route.toString()) {
console.log('RETURN LINK AT', serialATKLink.ports[key])
var match = false
for (key in atkSerialLink.routes) {
if (returnRoute.toString() === atkSerialLink.routes[key].route.toString()) {
console.log('RETURN LINK AT', atkSerialLink.routes[key])
// strip header and return message
var msg = pckt.slice(pckt.indexOf(255))
var msg = pckt.slice(pckt.indexOf(255) + 1)
console.log("RETURN MSG", msg)
serialATKLink.ports[key].onMessage(msg)
match = true
atkSerialLink.routes[key].onMessage(msg)
}
}
if (match == null) {
if (!match) {
console.log("PACKET RETURN AND NO KEY FOUND")
console.log(pckt)
console.log(serialATKLink.pairs)
}
}
......@@ -216,7 +221,7 @@ function SerialATKLink() {
// console.log('shifted', pckt)
}
return serialATKLink
return atkSerialLink
}
module.exports = SerialATKLink
\ No newline at end of file
module.exports = ATKSerialLink
\ No newline at end of file
......@@ -5,6 +5,18 @@ const Reps = require('./reps.js')
const JSUnit = require('./lib/jsunit.js')
let isStateKey = JSUnit.isStateKey
function newProgram(name){
var program = {
description: {
name: name,
id: name
},
modules: {}
}
return program
}
function loadModuleFromSource(program, path, id) {
// source -> heap
if (fs.existsSync(path)) {
......@@ -224,6 +236,7 @@ function openProgram(path) {
}
module.exports = {
new: newProgram,
open: openProgram,
save: saveProgram,
loadModuleFromSource: loadModuleFromSource,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment