Branch data Line data Source code
1 : : /*
2 : : * This file is part of the MicroPython project, http://micropython.org/
3 : : *
4 : : * The MIT License (MIT)
5 : : *
6 : : * Copyright (c) 2014-2015 Paul Sokolovsky
7 : : *
8 : : * Permission is hereby granted, free of charge, to any person obtaining a copy
9 : : * of this software and associated documentation files (the "Software"), to deal
10 : : * in the Software without restriction, including without limitation the rights
11 : : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : : * copies of the Software, and to permit persons to whom the Software is
13 : : * furnished to do so, subject to the following conditions:
14 : : *
15 : : * The above copyright notice and this permission notice shall be included in
16 : : * all copies or substantial portions of the Software.
17 : : *
18 : : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 : : * THE SOFTWARE.
25 : : */
26 : :
27 : : #if MICROPY_PY_TERMIOS
28 : :
29 : : #include <sys/types.h>
30 : : #include <termios.h>
31 : : #include <unistd.h>
32 : : #include <errno.h>
33 : :
34 : : #include "py/objlist.h"
35 : : #include "py/runtime.h"
36 : : #include "py/mphal.h"
37 : :
38 : 0 : static mp_obj_t mod_termios_tcgetattr(mp_obj_t fd_in) {
39 : 0 : struct termios term;
40 : 0 : int fd = mp_obj_get_int(fd_in);
41 : :
42 : 0 : int res = tcgetattr(fd, &term);
43 [ # # ]: 0 : RAISE_ERRNO(res, errno);
44 : :
45 : 0 : mp_obj_list_t *r = MP_OBJ_TO_PTR(mp_obj_new_list(7, NULL));
46 : 0 : r->items[0] = MP_OBJ_NEW_SMALL_INT(term.c_iflag);
47 : 0 : r->items[1] = MP_OBJ_NEW_SMALL_INT(term.c_oflag);
48 : 0 : r->items[2] = MP_OBJ_NEW_SMALL_INT(term.c_cflag);
49 : 0 : r->items[3] = MP_OBJ_NEW_SMALL_INT(term.c_lflag);
50 : 0 : r->items[4] = MP_OBJ_NEW_SMALL_INT(cfgetispeed(&term));
51 : 0 : r->items[5] = MP_OBJ_NEW_SMALL_INT(cfgetospeed(&term));
52 : :
53 : 0 : mp_obj_list_t *cc = MP_OBJ_TO_PTR(mp_obj_new_list(NCCS, NULL));
54 : 0 : r->items[6] = MP_OBJ_FROM_PTR(cc);
55 [ # # ]: 0 : for (int i = 0; i < NCCS; i++) {
56 [ # # ]: 0 : if (i == VMIN || i == VTIME) {
57 : 0 : cc->items[i] = MP_OBJ_NEW_SMALL_INT(term.c_cc[i]);
58 : : } else {
59 : : // https://docs.python.org/3/library/termios.html says value is *string*,
60 : : // but no way unicode chars could be there, if c_cc is defined to be a
61 : : // a "char". But it's type is actually cc_t, which can be anything.
62 : : // TODO: For now, we still deal with it like that.
63 : 0 : cc->items[i] = mp_obj_new_bytes((byte *)&term.c_cc[i], 1);
64 : : }
65 : : }
66 : 0 : return MP_OBJ_FROM_PTR(r);
67 : : }
68 : : static MP_DEFINE_CONST_FUN_OBJ_1(mod_termios_tcgetattr_obj, mod_termios_tcgetattr);
69 : :
70 : 0 : static mp_obj_t mod_termios_tcsetattr(mp_obj_t fd_in, mp_obj_t when_in, mp_obj_t attrs_in) {
71 : 0 : struct termios term;
72 : 0 : int fd = mp_obj_get_int(fd_in);
73 : 0 : int when = mp_obj_get_int(when_in);
74 : 0 : if (when == 0) {
75 : : // We don't export TCSANOW and friends to save on code space. Then
76 : : // common lazy sense says that passing 0 should be godo enough, and
77 : : // it is e.g. for glibc. But for other libc's it's not, so set just
78 : : // treat 0 as defaulting to TCSANOW.
79 : 0 : when = TCSANOW;
80 : : }
81 : :
82 [ # # # # : 0 : assert(mp_obj_is_type(attrs_in, &mp_type_list));
# # # # #
# # # ]
83 : 0 : mp_obj_list_t *attrs = MP_OBJ_TO_PTR(attrs_in);
84 : :
85 : 0 : term.c_iflag = mp_obj_get_int(attrs->items[0]);
86 : 0 : term.c_oflag = mp_obj_get_int(attrs->items[1]);
87 : 0 : term.c_cflag = mp_obj_get_int(attrs->items[2]);
88 : 0 : term.c_lflag = mp_obj_get_int(attrs->items[3]);
89 : :
90 : 0 : mp_obj_list_t *cc = MP_OBJ_TO_PTR(attrs->items[6]);
91 [ # # ]: 0 : for (int i = 0; i < NCCS; i++) {
92 [ # # ]: 0 : if (i == VMIN || i == VTIME) {
93 : 0 : term.c_cc[i] = mp_obj_get_int(cc->items[i]);
94 : : } else {
95 : 0 : term.c_cc[i] = *mp_obj_str_get_str(cc->items[i]);
96 : : }
97 : : }
98 : :
99 : 0 : int res = cfsetispeed(&term, mp_obj_get_int(attrs->items[4]));
100 [ # # ]: 0 : RAISE_ERRNO(res, errno);
101 : 0 : res = cfsetospeed(&term, mp_obj_get_int(attrs->items[5]));
102 [ # # ]: 0 : RAISE_ERRNO(res, errno);
103 : :
104 : 0 : res = tcsetattr(fd, when, &term);
105 [ # # ]: 0 : RAISE_ERRNO(res, errno);
106 : 0 : return mp_const_none;
107 : : }
108 : : static MP_DEFINE_CONST_FUN_OBJ_3(mod_termios_tcsetattr_obj, mod_termios_tcsetattr);
109 : :
110 : 0 : static mp_obj_t mod_termios_setraw(mp_obj_t fd_in) {
111 : 0 : struct termios term;
112 : 0 : int fd = mp_obj_get_int(fd_in);
113 : 0 : int res = tcgetattr(fd, &term);
114 [ # # ]: 0 : RAISE_ERRNO(res, errno);
115 : :
116 : 0 : term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
117 : 0 : term.c_oflag = 0;
118 : 0 : term.c_cflag = (term.c_cflag & ~(CSIZE | PARENB)) | CS8;
119 : 0 : term.c_lflag = 0;
120 : 0 : term.c_cc[VMIN] = 1;
121 : 0 : term.c_cc[VTIME] = 0;
122 : 0 : res = tcsetattr(fd, TCSAFLUSH, &term);
123 [ # # ]: 0 : RAISE_ERRNO(res, errno);
124 : 0 : return mp_const_none;
125 : : }
126 : : static MP_DEFINE_CONST_FUN_OBJ_1(mod_termios_setraw_obj, mod_termios_setraw);
127 : :
128 : : static const mp_rom_map_elem_t mp_module_termios_globals_table[] = {
129 : : { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_termios) },
130 : : { MP_ROM_QSTR(MP_QSTR_tcgetattr), MP_ROM_PTR(&mod_termios_tcgetattr_obj) },
131 : : { MP_ROM_QSTR(MP_QSTR_tcsetattr), MP_ROM_PTR(&mod_termios_tcsetattr_obj) },
132 : : { MP_ROM_QSTR(MP_QSTR_setraw), MP_ROM_PTR(&mod_termios_setraw_obj) },
133 : :
134 : : #define C(name) { MP_ROM_QSTR(MP_QSTR_##name), MP_ROM_INT(name) }
135 : : C(TCSANOW),
136 : :
137 : : C(B9600),
138 : : #ifdef B57600
139 : : C(B57600),
140 : : #endif
141 : : #ifdef B115200
142 : : C(B115200),
143 : : #endif
144 : : #ifdef B230400
145 : : C(B230400),
146 : : #endif
147 : : #ifdef B460800
148 : : C(B460800),
149 : : #endif
150 : : #ifdef B500000
151 : : C(B500000),
152 : : #endif
153 : : #ifdef B576000
154 : : C(B576000),
155 : : #endif
156 : : #ifdef B921600
157 : : C(B921600),
158 : : #endif
159 : : #ifdef B1000000
160 : : C(B1000000),
161 : : #endif
162 : : #ifdef B1152000
163 : : C(B1152000)
164 : : #endif
165 : : #undef C
166 : : };
167 : :
168 : : static MP_DEFINE_CONST_DICT(mp_module_termios_globals, mp_module_termios_globals_table);
169 : :
170 : : const mp_obj_module_t mp_module_termios = {
171 : : .base = { &mp_type_module },
172 : : .globals = (mp_obj_dict_t *)&mp_module_termios_globals,
173 : : };
174 : :
175 : : MP_REGISTER_MODULE(MP_QSTR_termios, mp_module_termios);
176 : :
177 : : #endif // MICROPY_PY_TERMIOS
|