10 type topology struct {
16 func newTopology(modules []Module) (topology, error) {
19 if len(modules) == 0 || len(modules) > 16 {
20 return result, fmt.Errorf("topology requires one through sixteen modules")
23 for slot, module := range modules {
24 inputs, outputs, analog := 0, 0, 0
27 case HostModel, MixedModel:
28 inputs, outputs = 8, 8
36 return topology{}, fmt.Errorf("unsupported module model in slot %d", slot)
39 if (slot == 0) != (module.Model == HostModel) {
40 return topology{}, fmt.Errorf("only slot zero must contain the host")
43 for channel, width := range module.PulseWidths {
44 if channel < 0 || channel >= outputs || width < 50*time.Millisecond || width > 65535*time.Millisecond || width%time.Millisecond != 0 {
45 return topology{}, fmt.Errorf("invalid pulse channel or width in slot %d", slot)
49 for channel := range inputs {
50 result.inputs = append(result.inputs, point{
51 id: fmt.Sprintf("m%d.di%d", slot, channel),
52 address: uint16(len(result.inputs)),
56 for channel := range outputs {
57 result.outputs = append(result.outputs, point{
58 id: fmt.Sprintf("m%d.do%d", slot, channel),
59 address: uint16(len(result.outputs)),
60 pulse: uint16(module.PulseWidths[channel] / time.Millisecond),
64 for channel := range analog {
65 result.analog = append(result.analog, point{
66 id: fmt.Sprintf("m%d.ao%d", slot, channel),
67 address: uint16(len(result.analog)),
75 func (t topology) descriptor() protocol.DescriptorPayload {
76 result := protocol.DescriptorPayload{
77 Manufacturer: "ebyte",
82 for _, input := range t.inputs {
83 result.Capabilities = append(result.Capabilities, protocol.Capability{
90 for _, output := range t.outputs {
92 if output.pulse != 0 {
96 result.Capabilities = append(result.Capabilities, protocol.Capability{
99 ReportsState: output.pulse == 0,
100 AcceptsCommands: true,
104 for _, output := range t.analog {
105 result.Capabilities = append(result.Capabilities, protocol.Capability{
109 AcceptsCommands: true,