Adding multi device support
This commit is contained in:
+46
@@ -3,6 +3,8 @@ package cmd
|
||||
import (
|
||||
"esdi/peripheral"
|
||||
"esdi/repl"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -37,8 +39,52 @@ func replCmdAction(cmd *cobra.Command, args []string) {
|
||||
},
|
||||
}
|
||||
|
||||
listDeviceAPIREPLCmd := repl.Command{
|
||||
Name: "v-api",
|
||||
Usage: "shows API of a device - pass its ID",
|
||||
Action: func(r *repl.REPL, args []string) error {
|
||||
// We should add this to the REPL instead
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("requires at least on argument")
|
||||
}
|
||||
|
||||
// First and only argument should be the ID of the device we want to use
|
||||
targetID, err := strconv.ParseInt(args[0], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = perClerk.ListDeviceAPI(uint8(targetID))
|
||||
if err != nil {
|
||||
fmt.Println("failed to view device API: ", err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
// selectDeviceREPLCmd := repl.Command{
|
||||
// Name: "select",
|
||||
// Usage: "Selects a given device - pass its ID",
|
||||
// Action: func(r *repl.REPL, args []string) error {
|
||||
// // We should add this to the REPL instead
|
||||
// if len(args) < 1 {
|
||||
// return fmt.Errorf("requires at least on argument")
|
||||
// }
|
||||
//
|
||||
// // First and only argument should be the ID of the device we want to use
|
||||
// targetID, err := strconv.ParseInt(args[0], 10, 0)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
// },
|
||||
// }
|
||||
|
||||
r.RegisterCMD(discoverDevicesREPLCmd)
|
||||
r.RegisterCMD(listDevicesREPLCmd)
|
||||
// r.RegisterCMD(selectDeviceREPLCmd)
|
||||
r.RegisterCMD(listDeviceAPIREPLCmd)
|
||||
|
||||
r.Start()
|
||||
r.Close()
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// Package helper
|
||||
package helper
|
||||
|
||||
func B32(s string) [32]byte {
|
||||
var b [32]byte
|
||||
copy(b[:], s)
|
||||
return b
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package peripheral
|
||||
|
||||
import (
|
||||
"esdi/peripheral/devices"
|
||||
"time"
|
||||
|
||||
"github.com/tarm/serial"
|
||||
@@ -39,6 +40,7 @@ type PeripheralDevice struct {
|
||||
ID uint8
|
||||
Name string
|
||||
WT *WalkieTalkie
|
||||
DeviceAPI *devices.Device
|
||||
}
|
||||
|
||||
func NewPeripheralDevice(port string) *PeripheralDevice {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package devices
|
||||
|
||||
import helper "esdi/helpers"
|
||||
|
||||
const (
|
||||
newWindowCMDID = iota
|
||||
destroyWindowCMDID
|
||||
)
|
||||
|
||||
var CDashDisplay = Device{
|
||||
ID: CDashDisplayDevID,
|
||||
Name: helper.B32("ESLabs CDashDisplay"),
|
||||
API: map[string]DeviceCMD{
|
||||
"new-window": {
|
||||
Identifier: newWindowCMDID,
|
||||
Name: "new-window",
|
||||
Desc: "Creates a new window - pass the window name and dimensions",
|
||||
Fn: createWindow,
|
||||
},
|
||||
"destroy-window": {
|
||||
Identifier: destroyWindowCMDID,
|
||||
Name: "destroy-window",
|
||||
Desc: "Destroys a window by its ID",
|
||||
Fn: destroyWindow,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func createWindow(data []byte) {
|
||||
// Parse the command
|
||||
}
|
||||
|
||||
func destroyWindow(data []byte) {
|
||||
// Parse the command
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Package devices will define the available devices we can communicate with
|
||||
package devices
|
||||
|
||||
import "esdi/peripheral/types"
|
||||
|
||||
// IDs for our devices. They need to be correctly mapped on the devices
|
||||
// themselves so we can discover them
|
||||
const (
|
||||
CDashDisplayDevID = 0x01
|
||||
ESBtnBoxDevID = 0x02
|
||||
)
|
||||
|
||||
// DeviceMap maps the implemented devices
|
||||
// When adding a new device we append it here too
|
||||
var DeviceMap = map[int]Device{
|
||||
CDashDisplayDevID: CDashDisplay,
|
||||
ESBtnBoxDevID: ESBtnBox,
|
||||
}
|
||||
|
||||
type Device struct {
|
||||
ID uint8
|
||||
Name [32]byte
|
||||
API map[string]DeviceCMD
|
||||
}
|
||||
|
||||
type DeviceCMDHeader struct {
|
||||
Payload [64]byte
|
||||
}
|
||||
|
||||
type DeviceCMDPayload struct {
|
||||
Payload [64]byte
|
||||
}
|
||||
|
||||
// DeviceCMDFn defines the basic type for the functions the devices can have
|
||||
// The function will receive a []byte that should be the arguments the user
|
||||
// types in the REPL - or however this will be used
|
||||
type DeviceCMDFn func(data []byte)
|
||||
|
||||
type DeviceCMD struct {
|
||||
Identifier types.CommandID
|
||||
Name string
|
||||
Desc string
|
||||
Header DeviceCMDHeader
|
||||
Data DeviceCMDPayload
|
||||
Fn DeviceCMDFn
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package devices
|
||||
|
||||
import helper "esdi/helpers"
|
||||
|
||||
var ESBtnBox = Device{
|
||||
ID: ESBtnBoxDevID,
|
||||
Name: helper.B32("ESLabs Button Box"),
|
||||
API: map[string]DeviceCMD{},
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
package peripheral
|
||||
|
||||
import (
|
||||
"esdi/peripheral/devices"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
@@ -14,12 +15,12 @@ const (
|
||||
|
||||
type PeripheralDeviceClerk struct {
|
||||
// mu sync.RWMutex
|
||||
Devices map[string]*PeripheralDevice
|
||||
Devices map[uint8]*PeripheralDevice
|
||||
}
|
||||
|
||||
func NewPeripheralDeviceClerk() *PeripheralDeviceClerk {
|
||||
return &PeripheralDeviceClerk{
|
||||
Devices: make(map[string]*PeripheralDevice),
|
||||
Devices: make(map[uint8]*PeripheralDevice),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +34,17 @@ func (clerk *PeripheralDeviceClerk) listPorts() ([]string, error) {
|
||||
}
|
||||
|
||||
func (clerk *PeripheralDeviceClerk) addDevice(dev *PeripheralDevice) {
|
||||
clerk.Devices[string(dev.Name[:])] = dev
|
||||
clerk.Devices[dev.ID] = dev
|
||||
}
|
||||
|
||||
func (clerk *PeripheralDeviceClerk) FindDeviceAPI(ID uint8) *devices.Device {
|
||||
for _, d := range devices.DeviceMap {
|
||||
if d.ID == ID {
|
||||
return &d
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clerk *PeripheralDeviceClerk) FindDevices() error {
|
||||
@@ -51,6 +62,13 @@ func (clerk *PeripheralDeviceClerk) FindDevices() error {
|
||||
continue
|
||||
}
|
||||
|
||||
// Look for the device on our device list - we need its API
|
||||
newDevice.DeviceAPI = clerk.FindDeviceAPI(newDevice.ID)
|
||||
if newDevice.DeviceAPI == nil {
|
||||
fmt.Printf("Failed to acquire API for device: [%2d] %s\n",
|
||||
newDevice.ID, newDevice.Name)
|
||||
}
|
||||
|
||||
clerk.addDevice(newDevice)
|
||||
fmt.Println(p, string(newDevice.Name[:]))
|
||||
}
|
||||
@@ -62,7 +80,19 @@ func (clerk *PeripheralDeviceClerk) FindDevices() error {
|
||||
|
||||
func (clerk *PeripheralDeviceClerk) ListDevices() error {
|
||||
for _, d := range clerk.Devices {
|
||||
fmt.Printf("[%d] %s\n", d.ID, d.Name)
|
||||
fmt.Printf("[%2d] %s\n", d.ID, d.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clerk *PeripheralDeviceClerk) ListDeviceAPI(ID uint8) error {
|
||||
if _, ok := clerk.Devices[ID]; !ok {
|
||||
return fmt.Errorf("device with ID %d not found", ID)
|
||||
}
|
||||
|
||||
for _, f := range clerk.Devices[ID].DeviceAPI.API {
|
||||
fmt.Printf("%s\t%s\n", f.Name, f.Desc)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// Package types defines the types necessary to handle peripherals
|
||||
package types
|
||||
|
||||
type CommandID uint8
|
||||
@@ -47,6 +47,10 @@ func (r *REPL) printPrompt() {
|
||||
_, _ = os.Stdout.Write([]byte(r.Cfg.PS1))
|
||||
}
|
||||
|
||||
func (r *REPL) SetPS1(s string) {
|
||||
r.Cfg.PS1 = s
|
||||
}
|
||||
|
||||
func (r *REPL) mainLoop() {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
|
||||
Reference in New Issue
Block a user