summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--docs/library/pyb.CAN.rst29
-rw-r--r--stmhal/can.c14
-rw-r--r--stmhal/qstrdefsport.h3
3 files changed, 33 insertions, 13 deletions
diff --git a/docs/library/pyb.CAN.rst b/docs/library/pyb.CAN.rst
index 9ee5a0a695..094d263628 100644
--- a/docs/library/pyb.CAN.rst
+++ b/docs/library/pyb.CAN.rst
@@ -44,9 +44,32 @@ Methods
Initialise the CAN bus with the given parameters:
- ``mode`` is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
-
- If ``extframe`` is True then the bus uses extended identifiers in the frames (29 bits).
- Otherwise it uses standard 11 bit identifiers.
+ - if ``extframe`` is True then the bus uses extended identifiers in the frames
+ (29 bits); otherwise it uses standard 11 bit identifiers
+ - ``prescaler`` is used to set the duration of 1 time quanta; the time quanta
+ will be the input clock (PCLK1, see :meth:`pyb.freq()`) divided by the prescaler
+ - ``sjw`` is the resynchronisation jump width in units of the time quanta;
+ it can be 1, 2, 3, 4
+ - ``bs1`` defines the location of the sample point in units of the time quanta;
+ it can be between 1 and 1024 inclusive
+ - ``bs2`` defines the location of the transmit point in units of the time quanta;
+ it can be between 1 and 16 inclusive
+
+ The time quanta tq is the basic unit of time for the CAN bus. tq is the CAN
+ prescaler value divided by PCLK1 (the frequency of internal peripheral bus 1);
+ see :meth:`pyb.freq()` to determine PCLK1.
+
+ A single bit is made up of the synchronisation segment, which is always 1 tq.
+ Then follows bit segment 1, then bit segment 2. The sample point is after bit
+ segment 1 finishes. The transmit point is after bit segment 2 finishes.
+ The baud rate will be 1/bittime, where the bittime is 1 + BS1 + BS2 multiplied
+ by the time quanta tq.
+
+ For example, with PCLK1=42MHz, prescaler=100, sjw=1, bs1=6, bs2=8, the value of
+ tq is 2.38 microseconds. The bittime is 35.7 microseconds, and the baudrate
+ is 28kHz.
+
+ See page 680 of the STM32F405 datasheet for more details.
.. method:: can.deinit()
diff --git a/stmhal/can.c b/stmhal/can.c
index de1ef3ecd9..4b06b13eda 100644
--- a/stmhal/can.c
+++ b/stmhal/can.c
@@ -162,21 +162,15 @@ STATIC void pyb_can_print(void (*print)(void *env, const char *fmt, ...), void *
}
}
-/// \method init(mode, extframe=False, prescaler=100, *, sjw=1, bs1=6, bs2=8)
-///
-/// Initialise the CAN bus with the given parameters:
-///
-/// - `mode` is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
+// init(mode, extframe=False, prescaler=100, *, sjw=1, bs1=6, bs2=8)
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) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_MODE_NORMAL} },
{ MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_prescaler, MP_ARG_INT, {.u_int = 100} },
- /*
{ MP_QSTR_sjw, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
{ MP_QSTR_bs1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 6} },
{ MP_QSTR_bs2, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
- */
};
// parse args
@@ -190,9 +184,9 @@ STATIC mp_obj_t pyb_can_init_helper(pyb_can_obj_t *self, mp_uint_t n_args, const
CAN_InitTypeDef *init = &self->can.Init;
init->Mode = args[0].u_int << 4; // shift-left so modes fit in a small-int
init->Prescaler = args[2].u_int;
- init->SJW = CAN_SJW_1TQ; // TODO set from args
- init->BS1 = CAN_BS1_6TQ; // TODO set from args
- init->BS2 = CAN_BS2_8TQ; // TODO set from args
+ init->SJW = ((args[3].u_int - 1) & 3) << 24;
+ init->BS1 = ((args[4].u_int - 1) & 0xf) << 16;
+ init->BS2 = ((args[5].u_int - 1) & 7) << 20;
init->TTCM = DISABLE;
init->ABOM = DISABLE;
init->AWUM = DISABLE;
diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h
index fc7942689c..e7ef1ef297 100644
--- a/stmhal/qstrdefsport.h
+++ b/stmhal/qstrdefsport.h
@@ -171,6 +171,9 @@ Q(addr)
Q(fifo)
Q(timeout)
Q(extframe)
+Q(sjw)
+Q(bs1)
+Q(bs2)
Q(NORMAL)
Q(LOOPBACK)
Q(SILENT)