forked from dimitry-ishenko-cpp/firmata
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserial_port.hpp
97 lines (73 loc) · 2.67 KB
/
serial_port.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017 Dimitry Ishenko
// Contact: dimitry (dot) ishenko (at) (gee) mail (dot) com
//
// Distributed under the GNU GPL license. See the LICENSE.md file for details.
////////////////////////////////////////////////////////////////////////////////
#ifndef FIRMATA_SERIAL_PORT_HPP
#define FIRMATA_SERIAL_PORT_HPP
////////////////////////////////////////////////////////////////////////////////
#include "firmata/io_base.hpp"
#include "firmata/types.hpp"
#include "asio_or_boost.hpp"
#include <string>
#include <tuple>
#include <vector>
////////////////////////////////////////////////////////////////////////////////
namespace firmata
{
////////////////////////////////////////////////////////////////////////////////
namespace literals
{
enum baud_rate : unsigned { };
constexpr baud_rate operator"" _baud(unsigned long long n) noexcept
{ return static_cast<baud_rate>(n); }
using flow_control = asio::serial_port::flow_control::type;
using parity = asio::serial_port::parity::type;
using stop_bits = asio::serial_port::stop_bits::type;
using char_size = bits;
}
using namespace literals;
////////////////////////////////////////////////////////////////////////////////
// Firmata protocol I/O via serial port
//
class serial_port : public io_base
{
public:
////////////////////
serial_port(asio::io_service& io, const std::string& device);
virtual ~serial_port() noexcept;
serial_port(const serial_port&) = delete;
serial_port(serial_port&&) = delete;
serial_port& operator=(const serial_port&) = delete;
serial_port& operator=(serial_port&&) = delete;
////////////////////
void set(baud_rate);
void set(flow_control);
void set(parity);
void set(stop_bits);
void set(char_size);
////////////////////
// write message
virtual void write(msg_id, const payload& = { }) override;
// install read callback
virtual cid on_read(read_call) override;
// remove read callback
virtual bool remove_call(cid) override;
// block until condition
virtual bool wait_until(const condition&, const sec&) override;
private:
////////////////////
asio::serial_port port_;
asio::system_timer timer_;
std::vector<byte> overall_; // overall buffer
char one_[128]; // single read buffer
void sched_async();
void async_read(const asio::error_code&, std::size_t);
// parse one message from overall_ buffer
std::tuple<msg_id, payload> parse_one();
};
////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
#endif