Skip to content

Commit 8d45be1

Browse files
committed
canio: Split RemoteTransmissionRequest to its own class
It reuses most of canio.Message's implementation, and structure
1 parent 48bda58 commit 8d45be1

File tree

6 files changed

+99
-63
lines changed

6 files changed

+99
-63
lines changed

shared-bindings/canio/CAN.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_restart_obj, canio_can_restart);
265265
//|
266266
//| An empty filter list causes all messages to be accepted.
267267
//|
268-
//| Timeout dictates how long readinto, read and next() will block."""
268+
//| Timeout dictates how long receive() and next() will block."""
269269
//| ...
270270
//|
271271
STATIC mp_obj_t canio_can_listen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -334,8 +334,8 @@ STATIC mp_obj_t canio_can_send(mp_obj_t self_in, mp_obj_t message_in) {
334334
canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in);
335335
common_hal_canio_can_check_for_deinit(self);
336336
mp_obj_type_t *message_type = mp_obj_get_type(message_in);
337-
if (message_type != &canio_message_type) {
338-
mp_raise_TypeError_varg(translate("expected '%q' but got '%q'"), MP_QSTR_Message, message_type->name);
337+
if (message_type != &canio_message_type && message_type != &canio_remote_transmission_request_type) {
338+
mp_raise_TypeError_varg(translate("expected '%q' or '%q' but got '%q'"), MP_QSTR_Message, MP_QSTR_RemoteTransmissionRequest, message_type->name);
339339
}
340340

341341
canio_message_obj_t *message = message_in;

shared-bindings/canio/Listener.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,13 @@ STATIC mp_obj_t canio_listener_receive(mp_obj_t self_in) {
5050
common_hal_canio_listener_check_for_deinit(self);
5151

5252
canio_message_obj_t *message = m_new_obj(canio_message_obj_t);
53-
message->base.type = &canio_message_type;
5453

5554
if (common_hal_canio_listener_receiveinto(self, message)) {
55+
if (message->rtr) {
56+
message->base.type = &canio_remote_transmission_request_type;
57+
} else {
58+
message->base.type = &canio_message_type;
59+
}
5660
return message;
5761
} else {
5862
m_free(message); // message did not escape into vm

shared-bindings/canio/Message.c

Lines changed: 82 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -31,63 +31,39 @@
3131
#include "py/runtime.h"
3232

3333
//| class Message:
34-
//| def __init__(self, id: int=0, data: Optional[bytes] = None, *, size: Optional[int] = None, rtr: bool = False, extended: bool = False):
35-
//| """Construct a Message to use with a CAN bus. Provide arguments to create a message to send. Otherwise, use Listener.readinto() to read a message.
34+
//| def __init__(self, id: int, data: bytes, *, extended: bool = False):
35+
//| """Construct a Message to send on a CAN bus.
3636
//|
3737
//| :param int id: The numeric ID of the message
3838
//| :param bytes data: The content of the message
39-
//| :param int size: The amount of data requested, for an rtr
40-
//| :param bool rtr: True if the message represents an rtr (Remote Transmission Request)
4139
//| :param bool extended: True if the message has an extended identifier, False if it has a standard identifier
4240
//|
43-
//| In CAN, messages can have a size from 0 to 8 bytes.
44-
//|
45-
//| For a non-rtr message, specify ``data``. For an rtr-message, specify either ``data`` (a dummy buffer of the requested size) or ``size``.
41+
//| In CAN, messages can have a length from 0 to 8 bytes.
4642
//| """
4743
//| ...
4844
//|
4945
STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
50-
enum { ARG_id, ARG_data, ARG_size, ARG_rtr, ARG_extended, NUM_ARGS };
46+
enum { ARG_id, ARG_data, ARG_extended, NUM_ARGS };
5147
static const mp_arg_t allowed_args[] = {
52-
{ MP_QSTR_id, MP_ARG_INT, {.u_obj = 0} },
53-
{ MP_QSTR_data, MP_ARG_OBJ, {.u_obj = 0} },
54-
{ MP_QSTR_size, MP_ARG_INT, {.u_int = -1} },
55-
{ MP_QSTR_rtr, MP_ARG_BOOL, {.u_bool = false} },
48+
{ MP_QSTR_id, MP_ARG_INT | MP_ARG_REQUIRED },
49+
{ MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED },
5650
{ MP_QSTR_extended, MP_ARG_BOOL, {.u_bool = false} },
5751
};
5852
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
5953
MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS );
6054

6155
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
6256

63-
bool rtr = args[ARG_rtr].u_bool;
64-
bool extended = args[ARG_extended].u_bool;
65-
size_t size = (size_t)args[ARG_size].u_int;
66-
bool specified_size = (size != (size_t)-1);
67-
bool specified_data = (args[ARG_data].u_obj != NULL);
68-
69-
if (specified_size && specified_data) {
70-
mp_raise_TypeError(translate("specify size or data, but not both"));
71-
}
72-
7357
mp_buffer_info_t data;
74-
if (specified_data) {
75-
mp_get_buffer_raise(args[ARG_data].u_obj, &data, MP_BUFFER_READ);
76-
} else if (specified_size) {
77-
data.buf = 0;
78-
data.len = size;
79-
} else {
80-
data.buf = 0;
81-
data.len = 0;
82-
}
58+
mp_get_buffer_raise(args[ARG_data].u_obj, &data, MP_BUFFER_READ);
8359

8460
if (data.len > 8) {
8561
mp_raise_ValueError(translate("Messages limited to 8 bytes"));
8662
}
8763

8864
canio_message_obj_t *self = m_new_obj(canio_message_obj_t);
8965
self->base.type = &canio_message_type;
90-
common_hal_canio_message_construct(self, args[ARG_id].u_int, data.buf, data.len, rtr, extended);
66+
common_hal_canio_message_construct(self, args[ARG_id].u_int, data.buf, data.len, args[ARG_extended].u_bool);
9167
return self;
9268
}
9369

@@ -115,13 +91,11 @@ STATIC const mp_obj_property_t canio_message_id_obj = {
11591
};
11692

11793
//| data: bytes
118-
//| """The content of the message, or dummy content in the case of an rtr.
119-
//|
120-
//| Assigning to data also clears the rtr flag, if it was set."""
94+
//| """The content of the message"""
12195
//|
12296
STATIC mp_obj_t canio_message_data_get(const mp_obj_t self_in) {
12397
canio_message_obj_t *self = self_in;
124-
return mp_obj_new_bytes((const byte*)common_hal_canio_message_get_data(self), common_hal_canio_message_get_size(self));
98+
return mp_obj_new_bytes((const byte*)common_hal_canio_message_get_data(self), common_hal_canio_message_get_length(self));
12599
}
126100
MP_DEFINE_CONST_FUN_OBJ_1(canio_message_data_get_obj, canio_message_data_get);
127101

@@ -147,7 +121,7 @@ STATIC const mp_obj_property_t canio_message_data_obj = {
147121

148122

149123
//| extended: bool
150-
//| """True if the message represents a remote transmission request (RTR)"""
124+
//| """True if the message's id is an extended id"""
151125
//|
152126
STATIC mp_obj_t canio_message_extended_get(const mp_obj_t self_in) {
153127
canio_message_obj_t *self = self_in;
@@ -170,36 +144,80 @@ STATIC const mp_obj_property_t canio_message_extended_obj = {
170144
(mp_obj_t)&mp_const_none_obj},
171145
};
172146

147+
//| class RemoteTransmissionRequest:
148+
//| def __init__(self, id: int, length: int, *, extended: bool = False):
149+
//| """Construct a Message to send on a CAN bus.
150+
//|
151+
//| :param int id: The numeric ID of the requested message
152+
//| :param int length: The length of the requested message
153+
//| :param bool extended: True if the message has an extended identifier, False if it has a standard identifier
154+
//|
155+
//| In CAN, messages can have a length from 0 to 8 bytes.
156+
//| """
157+
//| ...
158+
//|
159+
STATIC mp_obj_t canio_remote_transmission_request_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
160+
enum { ARG_id, ARG_length, ARG_extended, NUM_ARGS };
161+
static const mp_arg_t allowed_args[] = {
162+
{ MP_QSTR_id, MP_ARG_INT | MP_ARG_REQUIRED },
163+
{ MP_QSTR_length, MP_ARG_INT | MP_ARG_REQUIRED },
164+
{ MP_QSTR_extended, MP_ARG_BOOL, {.u_bool = false} },
165+
};
166+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
167+
MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS );
168+
169+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
170+
171+
int length = args[ARG_length].u_int;
172+
if (length < 0 || length > 8) {
173+
mp_raise_ValueError(translate("Messages limited to 8 bytes"));
174+
}
173175

174-
//| rtr: bool
175-
//| """True if the message represents a remote transmission request (RTR). Setting rtr to true zeros out data"""
176+
canio_message_obj_t *self = m_new_obj(canio_message_obj_t);
177+
self->base.type = &canio_remote_transmission_request_type;
178+
common_hal_canio_message_construct(self, args[ARG_id].u_int, NULL, length, args[ARG_extended].u_bool);
179+
return self;
180+
}
181+
182+
//| extended: bool
183+
//| """True if the message's id is an extended id"""
184+
//|
185+
186+
//| id: int
187+
//| """The numeric ID of the message"""
188+
//|
189+
190+
//| length: int
191+
//| """The length of the requested message."""
176192
//|
177-
STATIC mp_obj_t canio_message_rtr_get(const mp_obj_t self_in) {
193+
STATIC mp_obj_t canio_remote_transmission_request_length_get(const mp_obj_t self_in) {
178194
canio_message_obj_t *self = self_in;
179-
return mp_obj_new_bool(common_hal_canio_message_get_rtr(self));
195+
return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_get_length(self));
180196
}
181-
MP_DEFINE_CONST_FUN_OBJ_1(canio_message_rtr_get_obj, canio_message_rtr_get);
197+
MP_DEFINE_CONST_FUN_OBJ_1(canio_remote_transmission_request_length_get_obj, canio_remote_transmission_request_length_get);
182198

183-
STATIC mp_obj_t canio_message_rtr_set(const mp_obj_t self_in, const mp_obj_t rtr) {
199+
STATIC mp_obj_t canio_remote_transmission_request_length_set(const mp_obj_t self_in, const mp_obj_t length_in) {
184200
canio_message_obj_t *self = self_in;
185-
common_hal_canio_message_set_rtr(self, mp_obj_is_true(rtr));
201+
int length = mp_obj_get_int(length_in);
202+
if (length < 0 || length > 8) {
203+
mp_raise_ValueError(translate("Messages limited to 8 bytes"));
204+
}
205+
common_hal_canio_remote_transmission_request_set_length(self, length);
186206
return mp_const_none;
187207
}
188-
MP_DEFINE_CONST_FUN_OBJ_2(canio_message_rtr_set_obj, canio_message_rtr_set);
208+
MP_DEFINE_CONST_FUN_OBJ_2(canio_remote_transmission_request_length_set_obj, canio_remote_transmission_request_length_set);
189209

190210

191-
STATIC const mp_obj_property_t canio_message_rtr_obj = {
211+
STATIC const mp_obj_property_t canio_remote_transmission_request_length_obj = {
192212
.base.type = &mp_type_property,
193-
.proxy = {(mp_obj_t)&canio_message_rtr_get_obj,
194-
(mp_obj_t)&canio_message_rtr_set_obj,
213+
.proxy = {(mp_obj_t)&canio_remote_transmission_request_length_get_obj,
214+
(mp_obj_t)&canio_remote_transmission_request_length_set_obj,
195215
(mp_obj_t)&mp_const_none_obj},
196216
};
197217

198-
199218
STATIC const mp_rom_map_elem_t canio_message_locals_dict_table[] = {
200219
{ MP_ROM_QSTR(MP_QSTR_id), MP_ROM_PTR(&canio_message_id_obj) },
201220
{ MP_ROM_QSTR(MP_QSTR_data), MP_ROM_PTR(&canio_message_data_obj) },
202-
{ MP_ROM_QSTR(MP_QSTR_rtr), MP_ROM_PTR(&canio_message_rtr_obj) },
203221
{ MP_ROM_QSTR(MP_QSTR_extended), MP_ROM_PTR(&canio_message_extended_obj) },
204222
};
205223
STATIC MP_DEFINE_CONST_DICT(canio_message_locals_dict, canio_message_locals_dict_table);
@@ -210,3 +228,17 @@ const mp_obj_type_t canio_message_type = {
210228
.make_new = canio_message_make_new,
211229
.locals_dict = (mp_obj_t)&canio_message_locals_dict,
212230
};
231+
232+
STATIC const mp_rom_map_elem_t canio_remote_transmission_request_locals_dict_table[] = {
233+
{ MP_ROM_QSTR(MP_QSTR_id), MP_ROM_PTR(&canio_message_id_obj) },
234+
{ MP_ROM_QSTR(MP_QSTR_length), MP_ROM_PTR(&canio_remote_transmission_request_length_obj) },
235+
{ MP_ROM_QSTR(MP_QSTR_extended), MP_ROM_PTR(&canio_message_extended_obj) },
236+
};
237+
STATIC MP_DEFINE_CONST_DICT(canio_remote_transmission_request_locals_dict, canio_remote_transmission_request_locals_dict_table);
238+
239+
const mp_obj_type_t canio_remote_transmission_request_type = {
240+
{ &mp_type_type },
241+
.name = MP_QSTR_RemoteTransmissionRequest,
242+
.make_new = canio_remote_transmission_request_make_new,
243+
.locals_dict = (mp_obj_t)&canio_remote_transmission_request_locals_dict,
244+
};

shared-bindings/canio/Message.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@
3030
#include "shared-module/canio/Message.h"
3131

3232
extern const mp_obj_type_t canio_message_type;
33+
extern const mp_obj_type_t canio_remote_transmission_request_type;
3334

34-
void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr, bool extended);
35+
void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool extended);
3536
const void *common_hal_canio_message_get_data(const canio_message_obj_t *self);
3637
void common_hal_canio_message_set_data(canio_message_obj_t *self, const void *data, size_t size);
3738
bool common_hal_canio_message_get_extended(const canio_message_obj_t *self);
@@ -40,5 +41,5 @@ int common_hal_canio_message_get_id(const canio_message_obj_t *self);
4041
void common_hal_canio_message_set_id(canio_message_obj_t *self, int id);
4142
bool common_hal_canio_message_get_rtr(const canio_message_obj_t *self);
4243
void common_hal_canio_message_set_rtr(canio_message_obj_t *self, bool rtr);
43-
size_t common_hal_canio_message_get_size(const canio_message_obj_t *self);
44-
void common_hal_canio_message_set_size(canio_message_obj_t *self, size_t size);
44+
size_t common_hal_canio_message_get_length(const canio_message_obj_t *self);
45+
void common_hal_canio_remote_transmission_request_set_length(canio_message_obj_t *self, size_t length);

shared-bindings/canio/__init__.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ STATIC const mp_rom_map_elem_t canio_module_globals_table[] = {
113113
{ MP_ROM_QSTR(MP_QSTR_Listener), MP_ROM_PTR(&canio_listener_type) },
114114
{ MP_ROM_QSTR(MP_QSTR_Match), MP_ROM_PTR(&canio_match_type) },
115115
{ MP_ROM_QSTR(MP_QSTR_Message), MP_ROM_PTR(&canio_message_type) },
116+
{ MP_ROM_QSTR(MP_QSTR_RemoteTransmissionRequest), MP_ROM_PTR(&canio_remote_transmission_request_type) },
116117
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__canio) },
117118
};
118119

shared-module/canio/Message.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,14 @@
2828

2929
#include <string.h>
3030

31-
void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool rtr, bool extended)
31+
void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool extended)
3232
{
3333
self->id = id;
3434
self->size = size;
35-
self->rtr = rtr;
35+
self->rtr = !data;
3636
self->extended = extended;
3737
if (data) {
3838
memcpy(self->data, data, size);
39-
} else {
40-
memset(self->data, 0, size);
4139
}
4240
}
4341

@@ -65,12 +63,12 @@ const void common_hal_canio_message_set_data(canio_message_obj_t *self, const vo
6563
}
6664

6765

68-
size_t common_hal_canio_message_get_size(const canio_message_obj_t *self)
66+
size_t common_hal_canio_message_get_length(const canio_message_obj_t *self)
6967
{
7068
return self->size;
7169
}
7270

73-
void common_hal_canio_message_set_size(canio_message_obj_t *self, size_t size)
71+
void common_hal_canio_remote_transmission_request_set_length(canio_message_obj_t *self, size_t size)
7472
{
7573
memset(self->data, 0, size);
7674
self->size = size;

0 commit comments

Comments
 (0)