Skip to main content

p50x/
protocol.rs

1/*
2 * File: protocol.rs
3 * Date: 04.05.2020
4 * Author: MarkAtk
5 *
6 * MIT License
7 *
8 * Copyright (c) 2020 MarkAtk
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in all
18 * copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29use std::convert::From;
30use std::fmt;
31
32use super::error::Result;
33use super::utils::bool_arr_to_string;
34
35#[derive(Debug, PartialEq, Copy, Clone)]
36#[repr(u8)]
37pub enum LokProtocol {
38    Motorola = 0,
39    Selectrix = 1,
40    DCC = 2,
41    FMZ = 3
42}
43
44impl From<u8> for LokProtocol {
45    fn from(value: u8) -> LokProtocol {
46        match value {
47            1 => LokProtocol::Selectrix,
48            2 => LokProtocol::DCC,
49            3 => LokProtocol::FMZ,
50            0 | _ => LokProtocol::Motorola
51        }
52    }
53}
54
55#[derive(Debug, Copy, Clone)]
56pub struct DeviceStatus {
57    pub stop_pressed: bool,
58    pub go_pressed: bool,
59    pub hot: bool,
60    pub power: bool,
61    pub halt: bool,
62    pub external_central_unit: bool,
63    pub voltage_regulation: bool
64}
65
66impl fmt::Display for DeviceStatus {
67    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68        write!(f, "Stop: {}\nGo: {}\nHot: {}\nPower: {}\nHalt: {}\nExternal Central Unit: {}\nVoltage Regulation: {}",
69            self.stop_pressed,
70            self.go_pressed,
71            self.hot,
72            self.power,
73            self.halt,
74            self.external_central_unit,
75            self.voltage_regulation
76        )
77    }
78}
79
80#[derive(Debug, Copy, Clone, Default)]
81pub struct XLokOptions {
82    pub emergency_stop: bool,
83    pub force: bool,
84    pub light: bool,
85    pub functions: Option<[bool; 4]>
86}
87
88#[derive(Debug, Copy, Clone)]
89pub struct XLokStatus {
90    pub speed: i8,
91    pub real_speed: i8,
92    pub options: XLokOptions,
93}
94
95impl fmt::Display for XLokStatus {
96    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97        write!(f, "Speed: {}\nReal speed: {}\nEmergency stop: {}\nForce: {}\nLight: {}\nFunctions: {}",
98            self.speed,
99            self.real_speed,
100            self.options.emergency_stop,
101            self.options.force,
102            self.options.light,
103            bool_arr_to_string(&self.options.functions.unwrap())
104        )
105    }
106}
107
108#[derive(Debug, Copy, Clone)]
109pub struct XLokConfig {
110    pub protocol: LokProtocol,
111    pub speed_steps: u8,
112    pub virtual_address: Option<u16>
113}
114
115impl fmt::Display for XLokConfig {
116    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117        write!(f, "Protocol: {:?}\nSpeed steps: {}\nVirtual address: {:?}", self.protocol, self.speed_steps, self.virtual_address)
118    }
119}
120
121pub trait P50XBinary {
122    fn xpower_off(&mut self) -> Result<()>;
123    fn xpower_on(&mut self) -> Result<()>;
124    fn xhalt(&mut self) -> Result<()>;
125    fn xso_set(&mut self, special_option: u16, value: u8) -> Result<()>;
126    fn xso_get(&mut self, special_option: u16) -> Result<u8>;
127    fn xversion(&mut self) -> Result<Vec<u8>>;
128    fn xp50xch(&mut self, extended_character: u8) -> Result<()>;
129    fn xstatus(&mut self) -> Result<DeviceStatus>;
130    fn xnop(&mut self) -> Result<()>;
131
132    fn xlok(&mut self, address: u16, speed: i8, options: XLokOptions) -> Result<()>;
133    fn xlok_status(&mut self, address: u16) -> Result<XLokStatus>;
134    fn xlok_config(&mut self, address: u16) -> Result<XLokConfig>;
135    fn xlok_dispatch(&mut self, address: u16) -> Result<Option<u8>>;
136    fn xfunc(&mut self, address: u16, functions: [bool; 8]) -> Result<()>;
137    fn xfunc_status(&mut self, address: u16) -> Result<[bool; 8]>;
138    fn xfuncx(&mut self, address: u16, functions: [bool; 8]) -> Result<()>;
139    fn xfuncx_status(&mut self, address: u16) -> Result<[bool; 8]>;
140}