Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
e3cd1543
Commit
e3cd1543
authored
Apr 17, 2015
by
Henrik
Committed by
Damien George
Apr 18, 2015
Browse files
stmhal: Add support for sending and receiving CAN RTR messages.
parent
259eaab9
Changes
5
Hide whitespace changes
Inline
Side-by-side
docs/library/pyb.CAN.rst
View file @
e3cd1543
...
...
@@ -82,7 +82,7 @@ Methods
Turn off the CAN bus.
.. method:: can.setfilter(bank, mode, fifo, params)
.. method:: can.setfilter(bank, mode, fifo, params
, \*, rtr
)
Configure a filter bank:
...
...
@@ -107,6 +107,23 @@ Methods
|CAN.MASK32 |As with CAN.MASK16 but with only one 32 bit id/mask pair.|
+-----------+---------------------------------------------------------+
- ``rtr`` is an array of booleans that states if a filter should accept a
remote transmission request message. If this argument is not given
then it defaults to False for all entries. The length of the array
depends on the ``mode`` argument.
+-----------+----------------------+
|``mode`` |length of rtr array |
+===========+======================+
|CAN.LIST16 |4 |
+-----------+----------------------+
|CAN.LIST32 |2 |
+-----------+----------------------+
|CAN.MASK16 |2 |
+-----------+----------------------+
|CAN.MASK32 |1 |
+-----------+----------------------+
.. method:: can.clearfilter(bank)
Clear and disables a filter bank:
...
...
@@ -124,15 +141,24 @@ Methods
- ``fifo`` is an integer, which is the FIFO to receive on
- ``timeout`` is the timeout in milliseconds to wait for the receive.
Return value: buffer of data bytes.
Return value: A tuple containing four values.
- The id of the message.
- A boolean that indicates if the message is an RTR message.
- The FMI (Filter Match Index) value.
- An array containing the data.
.. method:: can.send(
send, addr
, \*, timeout=0)
.. method:: can.send(
data, id
, \*, timeout=0
, rtr=False
)
Send a message on the bus:
- ``
send
`` is the data to send (an integer to send, or a buffer object).
- ``
addr
`` is the
address to send to
- ``
data
`` is the data to send (an integer to send, or a buffer object).
- ``
id
`` is the
id of the message to be sent.
- ``timeout`` is the timeout in milliseconds to wait for the send.
- ``rtr`` is a boolean that specifies if the message shall be sent as
a remote transmission request. If ``rtr`` is True then only the length
of ``data`` is used to fill in the DLC slot of the frame; the actual
bytes in ``data`` are unused.
If timeout is 0 the message is placed in a buffer in one of three hardware
buffers and the method returns immediately. If all three buffers are in use
...
...
stmhal/can.c
View file @
e3cd1543
...
...
@@ -436,9 +436,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_can_any_obj, pyb_can_any);
/// Return value: `None`.
STATIC
mp_obj_t
pyb_can_send
(
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_
send
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_
addr
,
MP_ARG_REQUIRED
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_
data
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_
id
,
MP_ARG_REQUIRED
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_timeout
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_rtr
,
MP_ARG_KW_ONLY
|
MP_ARG_BOOL
,
{.
u_bool
=
false
}
},
};
// parse args
...
...
@@ -464,11 +465,16 @@ STATIC mp_obj_t pyb_can_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
tx_msg
.
StdId
=
args
[
1
].
u_int
&
0x7FF
;
tx_msg
.
IDE
=
CAN_ID_STD
;
}
tx_msg
.
RTR
=
CAN_RTR_DATA
;
if
(
args
[
3
].
u_bool
==
false
)
{
tx_msg
.
RTR
=
CAN_RTR_DATA
;
}
else
{
tx_msg
.
RTR
=
CAN_RTR_REMOTE
;
}
tx_msg
.
DLC
=
bufinfo
.
len
;
for
(
mp_uint_t
i
=
0
;
i
<
bufinfo
.
len
;
i
++
)
{
tx_msg
.
Data
[
i
]
=
((
byte
*
)
bufinfo
.
buf
)[
i
];
// Data is uint32_t but holds only 1 byte
}
self
->
can
.
pTxMsg
=
&
tx_msg
;
HAL_StatusTypeDef
status
=
CAN_Transmit
(
&
self
->
can
,
args
[
2
].
u_int
);
...
...
@@ -543,7 +549,7 @@ STATIC mp_obj_t pyb_can_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
}
else
{
tuple
->
items
[
0
]
=
MP_OBJ_NEW_SMALL_INT
(
rx_msg
.
ExtId
);
}
tuple
->
items
[
1
]
=
MP_OBJ_NEW_SMALL_INT
(
rx_msg
.
RTR
)
;
tuple
->
items
[
1
]
=
rx_msg
.
RTR
==
CAN_RTR_REMOTE
?
mp_const_true
:
mp_const_false
;
tuple
->
items
[
2
]
=
MP_OBJ_NEW_SMALL_INT
(
rx_msg
.
FMI
);
vstr_t
vstr
;
vstr_init_len
(
&
vstr
,
rx_msg
.
DLC
);
...
...
@@ -597,6 +603,7 @@ STATIC mp_obj_t pyb_can_setfilter(mp_uint_t n_args, const mp_obj_t *pos_args, mp
{
MP_QSTR_mode
,
MP_ARG_REQUIRED
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_fifo
,
MP_ARG_REQUIRED
|
MP_ARG_INT
,
{.
u_int
=
CAN_FILTER_FIFO0
}
},
{
MP_QSTR_params
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_rtr
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
};
// parse args
...
...
@@ -605,8 +612,14 @@ STATIC mp_obj_t pyb_can_setfilter(mp_uint_t n_args, const mp_obj_t *pos_args, mp
mp_arg_parse_all
(
n_args
-
1
,
pos_args
+
1
,
kw_args
,
MP_ARRAY_SIZE
(
allowed_args
),
allowed_args
,
args
);
mp_uint_t
len
;
mp_uint_t
rtr_len
;
mp_uint_t
rtr_masks
[
4
]
=
{
0
,
0
,
0
,
0
};
mp_obj_t
*
rtr_flags
;
mp_obj_t
*
params
;
mp_obj_get_array
(
args
[
3
].
u_obj
,
&
len
,
&
params
);
if
(
args
[
4
].
u_obj
!=
MP_OBJ_NULL
){
mp_obj_get_array
(
args
[
4
].
u_obj
,
&
rtr_len
,
&
rtr_flags
);
}
CAN_FilterConfTypeDef
filter
;
if
(
args
[
1
].
u_int
==
MASK16
||
args
[
1
].
u_int
==
LIST16
)
{
...
...
@@ -615,15 +628,41 @@ STATIC mp_obj_t pyb_can_setfilter(mp_uint_t n_args, const mp_obj_t *pos_args, mp
}
filter
.
FilterScale
=
CAN_FILTERSCALE_16BIT
;
if
(
self
->
extframe
)
{
filter
.
FilterIdLow
=
EXTENDED_ID_TO_16BIT_FILTER
(
mp_obj_get_int
(
params
[
0
]));
// id1
filter
.
FilterMaskIdLow
=
EXTENDED_ID_TO_16BIT_FILTER
(
mp_obj_get_int
(
params
[
1
]));
// mask1
filter
.
FilterIdHigh
=
EXTENDED_ID_TO_16BIT_FILTER
(
mp_obj_get_int
(
params
[
2
]));
// id2
filter
.
FilterMaskIdHigh
=
EXTENDED_ID_TO_16BIT_FILTER
(
mp_obj_get_int
(
params
[
3
]));
// mask2
}
else
{
filter
.
FilterIdLow
=
mp_obj_get_int
(
params
[
0
])
<<
5
;
// id1
filter
.
FilterMaskIdLow
=
mp_obj_get_int
(
params
[
1
])
<<
5
;
// mask1
filter
.
FilterIdHigh
=
mp_obj_get_int
(
params
[
2
])
<<
5
;
// id2
filter
.
FilterMaskIdHigh
=
mp_obj_get_int
(
params
[
3
])
<<
5
;
// mask2
if
(
args
[
4
].
u_obj
!=
MP_OBJ_NULL
)
{
if
(
args
[
1
].
u_int
==
MASK16
)
{
rtr_masks
[
0
]
=
mp_obj_get_int
(
rtr_flags
[
0
])
?
0x02
:
0
;
rtr_masks
[
1
]
=
0x02
;
rtr_masks
[
2
]
=
mp_obj_get_int
(
rtr_flags
[
1
])
?
0x02
:
0
;
rtr_masks
[
3
]
=
0x02
;
}
else
{
// LIST16
rtr_masks
[
0
]
=
mp_obj_get_int
(
rtr_flags
[
0
])
?
0x02
:
0
;
rtr_masks
[
1
]
=
mp_obj_get_int
(
rtr_flags
[
1
])
?
0x02
:
0
;
rtr_masks
[
2
]
=
mp_obj_get_int
(
rtr_flags
[
2
])
?
0x02
:
0
;
rtr_masks
[
3
]
=
mp_obj_get_int
(
rtr_flags
[
3
])
?
0x02
:
0
;
}
}
filter
.
FilterIdLow
=
EXTENDED_ID_TO_16BIT_FILTER
(
mp_obj_get_int
(
params
[
0
]))
|
rtr_masks
[
0
];
// id1
filter
.
FilterMaskIdLow
=
EXTENDED_ID_TO_16BIT_FILTER
(
mp_obj_get_int
(
params
[
1
]))
|
rtr_masks
[
1
];
// mask1
filter
.
FilterIdHigh
=
EXTENDED_ID_TO_16BIT_FILTER
(
mp_obj_get_int
(
params
[
2
]))
|
rtr_masks
[
2
];
// id2
filter
.
FilterMaskIdHigh
=
EXTENDED_ID_TO_16BIT_FILTER
(
mp_obj_get_int
(
params
[
3
]))
|
rtr_masks
[
3
];
// mask2
}
else
{
// Basic frames
if
(
args
[
4
].
u_obj
!=
MP_OBJ_NULL
)
{
if
(
args
[
1
].
u_int
==
MASK16
)
{
rtr_masks
[
0
]
=
mp_obj_get_int
(
rtr_flags
[
0
])
?
0x10
:
0
;
rtr_masks
[
1
]
=
0x10
;
rtr_masks
[
2
]
=
mp_obj_get_int
(
rtr_flags
[
1
])
?
0x10
:
0
;
rtr_masks
[
3
]
=
0x10
;
}
else
{
// LIST16
rtr_masks
[
0
]
=
mp_obj_get_int
(
rtr_flags
[
0
])
?
0x10
:
0
;
rtr_masks
[
1
]
=
mp_obj_get_int
(
rtr_flags
[
1
])
?
0x10
:
0
;
rtr_masks
[
2
]
=
mp_obj_get_int
(
rtr_flags
[
2
])
?
0x10
:
0
;
rtr_masks
[
3
]
=
mp_obj_get_int
(
rtr_flags
[
3
])
?
0x10
:
0
;
}
}
filter
.
FilterIdLow
=
(
mp_obj_get_int
(
params
[
0
])
<<
5
)
|
rtr_masks
[
0
];
// id1
filter
.
FilterMaskIdLow
=
(
mp_obj_get_int
(
params
[
1
])
<<
5
)
|
rtr_masks
[
1
];
// mask1
filter
.
FilterIdHigh
=
(
mp_obj_get_int
(
params
[
2
])
<<
5
)
|
rtr_masks
[
2
];
// id2
filter
.
FilterMaskIdHigh
=
(
mp_obj_get_int
(
params
[
3
])
<<
5
)
|
rtr_masks
[
3
];
// mask2
}
if
(
args
[
1
].
u_int
==
MASK16
)
{
filter
.
FilterMode
=
CAN_FILTERMODE_IDMASK
;
...
...
@@ -636,12 +675,20 @@ STATIC mp_obj_t pyb_can_setfilter(mp_uint_t n_args, const mp_obj_t *pos_args, mp
if
(
len
!=
2
)
{
goto
error
;
}
filter
.
FilterScale
=
CAN_FILTERSCALE_32BIT
;
filter
.
FilterScale
=
CAN_FILTERSCALE_32BIT
;
if
(
args
[
4
].
u_obj
!=
MP_OBJ_NULL
)
{
if
(
args
[
1
].
u_int
==
MASK32
)
{
rtr_masks
[
0
]
=
mp_obj_get_int
(
rtr_flags
[
0
])
?
0x02
:
0
;
rtr_masks
[
1
]
=
0x02
;
}
else
{
// LIST32
rtr_masks
[
0
]
=
mp_obj_get_int
(
rtr_flags
[
0
])
?
0x02
:
0
;
rtr_masks
[
1
]
=
mp_obj_get_int
(
rtr_flags
[
1
])
?
0x02
:
0
;
}
}
filter
.
FilterIdHigh
=
(
mp_obj_get_int
(
params
[
0
])
&
0xFF00
)
>>
13
;
filter
.
FilterIdLow
=
((
mp_obj_get_int
(
params
[
0
])
&
0x00FF
)
<<
3
)
|
4
;
filter
.
FilterIdLow
=
((
(
mp_obj_get_int
(
params
[
0
])
&
0x00FF
)
<<
3
)
|
4
)
|
rtr_masks
[
0
]
;
filter
.
FilterMaskIdHigh
=
(
mp_obj_get_int
(
params
[
1
])
&
0xFF00
)
>>
13
;
filter
.
FilterMaskIdLow
=
((
mp_obj_get_int
(
params
[
1
])
&
0x00FF
)
<<
3
)
|
4
;
filter
.
FilterMaskIdLow
=
((
(
mp_obj_get_int
(
params
[
1
])
&
0x00FF
)
<<
3
)
|
4
)
|
rtr_masks
[
1
]
;
if
(
args
[
1
].
u_int
==
MASK32
)
{
filter
.
FilterMode
=
CAN_FILTERMODE_IDMASK
;
}
...
...
stmhal/qstrdefsport.h
View file @
e3cd1543
...
...
@@ -213,6 +213,7 @@ Q(initfilterbanks)
Q
(
clearfilter
)
Q
(
setfilter
)
Q
(
rxcallback
)
Q
(
rtr
)
Q
(
NORMAL
)
Q
(
LOOPBACK
)
Q
(
SILENT
)
...
...
tests/pyb/can.py
View file @
e3cd1543
...
...
@@ -151,3 +151,40 @@ except OSError as e:
pyb
.
delay
(
500
)
while
can
.
any
(
0
):
print
(
can
.
recv
(
0
))
# Testing rtr messages
bus1
=
CAN
(
1
,
CAN
.
LOOPBACK
)
bus2
=
CAN
(
2
,
CAN
.
LOOPBACK
,
extframe
=
True
)
while
bus1
.
any
(
0
):
bus1
.
recv
(
0
)
while
bus2
.
any
(
0
):
bus2
.
recv
(
0
)
bus1
.
setfilter
(
0
,
CAN
.
LIST16
,
0
,
(
1
,
2
,
3
,
4
))
bus1
.
setfilter
(
1
,
CAN
.
LIST16
,
0
,
(
5
,
6
,
7
,
8
),
rtr
=
(
True
,
True
,
True
,
True
))
bus1
.
setfilter
(
2
,
CAN
.
MASK16
,
0
,
(
64
,
64
,
32
,
32
),
rtr
=
(
False
,
True
))
bus2
.
setfilter
(
0
,
CAN
.
LIST32
,
0
,
(
1
,
2
),
rtr
=
(
True
,
True
))
bus2
.
setfilter
(
1
,
CAN
.
LIST32
,
0
,
(
3
,
4
),
rtr
=
(
True
,
False
))
bus2
.
setfilter
(
2
,
CAN
.
MASK32
,
0
,
(
16
,
16
),
rtr
=
(
False
,))
bus2
.
setfilter
(
2
,
CAN
.
MASK32
,
0
,
(
32
,
32
),
rtr
=
(
True
,))
bus1
.
send
(
''
,
1
,
rtr
=
True
)
print
(
bus1
.
any
(
0
))
bus1
.
send
(
''
,
5
,
rtr
=
True
)
print
(
bus1
.
recv
(
0
))
bus1
.
send
(
''
,
6
,
rtr
=
True
)
print
(
bus1
.
recv
(
0
))
bus1
.
send
(
''
,
7
,
rtr
=
True
)
print
(
bus1
.
recv
(
0
))
bus1
.
send
(
''
,
16
,
rtr
=
True
)
print
(
bus1
.
any
(
0
))
bus1
.
send
(
''
,
32
,
rtr
=
True
)
print
(
bus1
.
recv
(
0
))
bus2
.
send
(
''
,
1
,
rtr
=
True
)
print
(
bus2
.
recv
(
0
))
bus2
.
send
(
''
,
2
,
rtr
=
True
)
print
(
bus2
.
recv
(
0
))
bus2
.
send
(
''
,
3
,
rtr
=
True
)
print
(
bus2
.
recv
(
0
))
bus2
.
send
(
''
,
4
,
rtr
=
True
)
print
(
bus2
.
any
(
0
))
tests/pyb/can.py.exp
View file @
e3cd1543
...
...
@@ -2,9 +2,9 @@ CAN(1)
CAN(1, CAN.LOOPBACK, extframe=False)
False
True
(123,
0
, 0, b'abcd')
(2047,
0
, 0, b'abcd')
(0,
0
, 0, b'abcd')
(123,
False
, 0, b'abcd')
(2047,
False
, 0, b'abcd')
(0,
False
, 0, b'abcd')
passed
CAN(1, CAN.LOOPBACK, extframe=True)
passed
...
...
@@ -20,21 +20,31 @@ cb1
full
cb1a
overflow
(1,
0
, 0, b'11111111')
(2,
0
, 1, b'22222222')
(4,
0
, 3, b'44444444')
(5,
0
, 0, b'55555555')
(6,
0
, 1, b'66666666')
(8,
0
, 3, b'88888888')
(1,
False
, 0, b'11111111')
(2,
False
, 1, b'22222222')
(4,
False
, 3, b'44444444')
(5,
False
, 0, b'55555555')
(6,
False
, 1, b'66666666')
(8,
False
, 3, b'88888888')
cb0a
pending
cb1a
pending
(1,
0
, 0, b'11111111')
(5,
0
, 0, b'55555555')
(1,
False
, 0, b'11111111')
(5,
False
, 0, b'55555555')
False
(1,
0
, 0, b'abcde')
(1,
False
, 0, b'abcde')
passed
(2, 0, 0, b'abcde')
(3, 0, 0, b'abcde')
(4, 0, 0, b'abcde')
(2, False, 0, b'abcde')
(3, False, 0, b'abcde')
(4, False, 0, b'abcde')
False
(5, True, 4, b'')
(6, True, 5, b'')
(7, True, 6, b'')
False
(32, True, 9, b'')
(1, True, 0, b'')
(2, True, 1, b'')
(3, True, 2, b'')
False
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment