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
6666typedef 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
163170STATIC 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 ++ ) {
0 commit comments