Skip to content

Commit 5046368

Browse files
HenrikSolverdpgeorge
authored andcommitted
stmhal: Added support for extended CAN frames.
1 parent 0e557fa commit 5046368

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

stmhal/can.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,14 @@
6060
///
6161
/// from pyb import CAN
6262
/// can = pyb.CAN(1, pyb.CAN.LOOPBACK)
63-
/// can.send('message!', 123) # send message to id 123
63+
/// can.send('message!', 123) # send message with id 123
6464
/// can.recv(0) # receive message on FIFO 0
6565

6666
typedef struct _pyb_can_obj_t {
6767
mp_obj_base_t base;
6868
mp_uint_t can_id : 8;
6969
bool is_enabled : 1;
70+
bool extframe : 1;
7071
CAN_HandleTypeDef can;
7172
} pyb_can_obj_t;
7273

@@ -151,6 +152,12 @@ STATIC void pyb_can_print(void (*print)(void *env, const char *fmt, ...), void *
151152
case CAN_MODE_SILENT: mode = MP_QSTR_SILENT; break;
152153
case CAN_MODE_SILENT_LOOPBACK: default: mode = MP_QSTR_SILENT_LOOPBACK; break;
153154
}
155+
print(env, "%s, ", qstr_str(mode));
156+
if (self->extframe) {
157+
mode = MP_QSTR_True;
158+
} else {
159+
mode = MP_QSTR_False;
160+
}
154161
print(env, "%s)", qstr_str(mode));
155162
}
156163
}
@@ -162,8 +169,9 @@ STATIC void pyb_can_print(void (*print)(void *env, const char *fmt, ...), void *
162169
/// - `mode` is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
163170
STATIC mp_obj_t pyb_can_init_helper(pyb_can_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
164171
static const mp_arg_t allowed_args[] = {
165-
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} },
166-
{ MP_QSTR_prescaler, MP_ARG_INT, {.u_int = 100} },
172+
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} },
173+
{ MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false} },
174+
{ MP_QSTR_prescaler, MP_ARG_INT, {.u_int = 100} },
167175
/*
168176
{ MP_QSTR_sjw, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
169177
{ MP_QSTR_bs1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 6} },
@@ -175,11 +183,12 @@ STATIC mp_obj_t pyb_can_init_helper(pyb_can_obj_t *self, mp_uint_t n_args, const
175183
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
176184
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
177185

186+
self->extframe = args[1].u_bool;
178187
// set the CAN configuration values
179188
memset(&self->can, 0, sizeof(self->can));
180189
CAN_InitTypeDef *init = &self->can.Init;
181190
init->Mode = args[0].u_int << 4; // shift-left so modes fit in a small-int
182-
init->Prescaler = args[1].u_int;
191+
init->Prescaler = args[2].u_int;
183192
init->SJW = CAN_SJW_1TQ; // TODO set from args
184193
init->BS1 = CAN_BS1_6TQ; // TODO set from args
185194
init->BS2 = CAN_BS2_8TQ; // TODO set from args
@@ -317,13 +326,20 @@ STATIC mp_obj_t pyb_can_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
317326
mp_buffer_info_t bufinfo;
318327
uint8_t data[1];
319328
pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
320-
// TODO check bufinfo.len <= 8
329+
330+
if (bufinfo.len > 8) {
331+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN data field too long"));
332+
}
321333

322334
// send the data
323335
CanTxMsgTypeDef tx_msg;
324-
tx_msg.StdId = args[1].u_int & 0x7ff;
325-
tx_msg.ExtId = 0; // TODO support extended ids
326-
tx_msg.IDE = CAN_ID_STD;
336+
if (self->extframe){
337+
tx_msg.ExtId = args[1].u_int & 0x1FFFFFFF;
338+
tx_msg.IDE = CAN_ID_EXT;
339+
} else {
340+
tx_msg.StdId = args[1].u_int & 0x7FF;
341+
tx_msg.IDE = CAN_ID_STD;
342+
}
327343
tx_msg.RTR = CAN_RTR_DATA;
328344
tx_msg.DLC = bufinfo.len;
329345
for (mp_uint_t i = 0; i < bufinfo.len; i++) {

stmhal/qstrdefsport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ Q(recv)
167167
Q(addr)
168168
Q(fifo)
169169
Q(timeout)
170+
Q(extframe)
170171
Q(NORMAL)
171172
Q(LOOPBACK)
172173
Q(SILENT)

0 commit comments

Comments
 (0)