diff --git a/stmhal/can.c b/stmhal/can.c
index b2330cd9c1b0e5ee510c88955400bf6195380a2d..6d582d44f38ab8a8f5f090db9aff04e61a005fbf 100644
--- a/stmhal/can.c
+++ b/stmhal/can.c
@@ -343,44 +343,61 @@ STATIC mp_obj_t pyb_can_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
-    // create object
-    pyb_can_obj_t *o = m_new_obj(pyb_can_obj_t);
-    o->base.type = &pyb_can_type;
-    o->is_enabled = false;
-
     // work out port
-    o->can_id = 0;
+    mp_uint_t can_idx;
     if (MP_OBJ_IS_STR(args[0])) {
         const char *port = mp_obj_str_get_str(args[0]);
         if (0) {
         #ifdef MICROPY_HW_CAN1_NAME
         } else if (strcmp(port, MICROPY_HW_CAN1_NAME) == 0) {
-            o->can_id = PYB_CAN_1;
+            can_idx = PYB_CAN_1;
         #endif
         #ifdef MICROPY_HW_CAN2_NAME
         } else if (strcmp(port, MICROPY_HW_CAN2_NAME) == 0) {
-            o->can_id = PYB_CAN_2;
+            can_idx = PYB_CAN_2;
         #endif
         } else {
-            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN port %s does not exist", port));
+            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN(%s) does not exist", port));
         }
     } else {
-        o->can_id = mp_obj_get_int(args[0]);
+        can_idx = mp_obj_get_int(args[0]);
+    }
+    if (can_idx < 1 || can_idx > MP_ARRAY_SIZE(MP_STATE_PORT(pyb_can_obj_all))) {
+        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "CAN(%d) does not exist", can_idx));
+    }
+
+    pyb_can_obj_t *self;
+    if (MP_STATE_PORT(pyb_can_obj_all)[can_idx - 1] == NULL) {
+        self = m_new_obj(pyb_can_obj_t);
+        self->base.type = &pyb_can_type;
+        self->can_id = can_idx;
+        self->is_enabled = false;
+        MP_STATE_PORT(pyb_can_obj_all)[can_idx - 1] = self;
+    } else {
+        self = MP_STATE_PORT(pyb_can_obj_all)[can_idx - 1];
     }
-    o->rxcallback0 = mp_const_none;
-    o->rxcallback1 = mp_const_none;
-    MP_STATE_PORT(pyb_can_obj_all)[o->can_id - 1] = o;
-    o->rx_state0 = RX_STATE_FIFO_EMPTY;
-    o->rx_state1 = RX_STATE_FIFO_EMPTY;
 
-    if (n_args > 1 || n_kw > 0) {
-        // start the peripheral
-        mp_map_t kw_args;
-        mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
-        pyb_can_init_helper(o, n_args - 1, args + 1, &kw_args);
+    if (!self->is_enabled || n_args > 1) {
+        if (self->is_enabled) {
+            // The caller is requesting a reconfiguration of the hardware
+            // this can only be done if the hardware is in init mode
+            pyb_can_deinit(self);
+        }
+
+        self->rxcallback0 = mp_const_none;
+        self->rxcallback1 = mp_const_none;
+        self->rx_state0 = RX_STATE_FIFO_EMPTY;
+        self->rx_state1 = RX_STATE_FIFO_EMPTY;
+
+        if (n_args > 1 || n_kw > 0) {
+            // start the peripheral
+            mp_map_t kw_args;
+            mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
+            pyb_can_init_helper(self, n_args - 1, args + 1, &kw_args);
+        }
     }
 
-    return o;
+    return self;
 }
 
 STATIC mp_obj_t pyb_can_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
diff --git a/tests/pyb/can.py b/tests/pyb/can.py
index cf8089a3bdb1aabeed71994178edce94be07e8ea..594d1d509314da2f98b5bbd67d6d54c946e72cb4 100644
--- a/tests/pyb/can.py
+++ b/tests/pyb/can.py
@@ -8,6 +8,7 @@ for bus in (-1, 0, 1, 2, 3, "YA", "YB", "YC"):
         print("CAN", bus)
     except ValueError:
         print("ValueError", bus)
+CAN(1).deinit()
 
 CAN.initfilterbanks(14)
 can = CAN(1)