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
4029f518
Commit
4029f518
authored
Oct 31, 2014
by
Damien George
Browse files
stmhal: Fix UART so bits counts number of data bits, not incl parity.
Addresses issue #950.
parent
1559a978
Changes
2
Hide whitespace changes
Inline
Side-by-side
docs/library/pyb.UART.rst
View file @
4029f518
...
...
@@ -13,7 +13,10 @@ UART objects can be created and initialised using::
uart = UART(1, 9600) # init with given baudrate
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
Bits can be 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1 or 2.
Bits can be 7, 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1 or 2.
*Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled,
only 7 and 8 bits are supported.
A UART object acts like a stream object and reading and writing is done
using the standard stream methods::
...
...
@@ -44,9 +47,9 @@ Constructors
initialised (it has the settings from the last initialisation of
the bus, if any). If extra arguments are given, the bus is initialised.
See ``init`` for parameters of initialisation.
The physical pins of the UART busses are:
- ``UART(4)`` is on ``XA``: ``(TX, RX) = (X1, X2) = (PA0, PA1)``
- ``UART(1)`` is on ``XB``: ``(TX, RX) = (X9, X10) = (PB6, PB7)``
- ``UART(6)`` is on ``YA``: ``(TX, RX) = (Y1, Y2) = (PC6, PC7)``
...
...
@@ -57,35 +60,44 @@ Constructors
Methods
-------
.. method:: uart.any()
Return ``True`` if any characters waiting, else ``False``.
.. method:: uart.deinit()
Turn off the UART bus.
.. method:: uart.init(baudrate, bits=8, parity=None, stop=1, \*, timeout=1000, timeout_char=0, read_buf_len=64)
Initialise the UART bus with the given parameters:
- ``baudrate`` is the clock rate.
- ``bits`` is the number of bits per
byte
, 8 or 9.
- ``bits`` is the number of bits per
character, 7
, 8 or 9.
- ``parity`` is the parity, ``None``, 0 (even) or 1 (odd).
- ``stop`` is the number of stop bits, 1 or 2.
- ``timeout`` is the timeout in milliseconds to wait for the first character.
- ``timeout_char`` is the timeout in milliseconds to wait between characters.
- ``read_buf_len`` is the character length of the read buffer (0 to disable).
*Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled,
only 7 and 8 bits are supported.
.. method:: uart.deinit()
Turn off the UART bus.
.. method:: uart.any()
Return ``True`` if any characters waiting, else ``False``.
.. method:: uart.read([nbytes])
Read characters. If ``nbytes`` is specified then read at most that many bytes.
*Note:* for 9 bit characters each character takes 2 bytes, ``nbytes`` must be even,
and the number of characters is ``nbytes/2``.
.. method:: uart.readall()
Read as much data as possible.
.. method:: uart.readchar()
Receive a single character on the bus.
Return value: The character read, as an integer. Returns -1 on timeout.
.. method:: uart.readinto(buf[, nbytes])
...
...
stmhal/uart.c
View file @
4029f518
...
...
@@ -80,13 +80,14 @@
struct
_pyb_uart_obj_t
{
mp_obj_base_t
base
;
pyb_uart_t
uart_id
;
bool
is_enabled
;
UART_HandleTypeDef
uart
;
UART_HandleTypeDef
uart
;
// this is 17 words big
IRQn_Type
irqn
;
pyb_uart_t
uart_id
:
8
;
bool
is_enabled
:
1
;
byte
char_width
;
// 0 for 7,8 bit chars, 1 for 9 bit chars
uint16_t
char_mask
;
// 0x7f for 7 bit, 0xff for 8 bit, 0x1ff for 9 bit
uint16_t
timeout
;
// timeout waiting for first char
uint16_t
timeout_char
;
// timeout waiting between chars
uint16_t
char_width
;
// 0 for 7,8 bit chars, 1 for 9 bit chars
uint16_t
read_buf_len
;
// len in chars; buf can hold len-1 chars
volatile
uint16_t
read_buf_head
;
// indexes first empty slot
uint16_t
read_buf_tail
;
// indexes first full slot (not full if equals head)
...
...
@@ -280,7 +281,7 @@ int uart_rx_char(pyb_uart_obj_t *self) {
return
data
;
}
else
{
// no buffering
return
self
->
uart
.
Instance
->
DR
;
return
self
->
uart
.
Instance
->
DR
&
self
->
char_mask
;
}
}
...
...
@@ -315,6 +316,7 @@ void uart_irq_handler(mp_uint_t uart_id) {
if
(
__HAL_UART_GET_FLAG
(
&
self
->
uart
,
UART_FLAG_RXNE
)
!=
RESET
)
{
int
data
=
self
->
uart
.
Instance
->
DR
;
// clears UART_FLAG_RXNE
data
&=
self
->
char_mask
;
if
(
self
->
read_buf_len
!=
0
)
{
uint16_t
next_head
=
(
self
->
read_buf_head
+
1
)
%
self
->
read_buf_len
;
if
(
next_head
!=
self
->
read_buf_tail
)
{
...
...
@@ -340,9 +342,12 @@ STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void
if
(
!
self
->
is_enabled
)
{
print
(
env
,
"UART(%u)"
,
self
->
uart_id
);
}
else
{
mp_int_t
bits
=
(
self
->
uart
.
Init
.
WordLength
==
UART_WORDLENGTH_8B
?
8
:
9
);
if
(
self
->
uart
.
Init
.
Parity
!=
UART_PARITY_NONE
)
{
bits
-=
1
;
}
print
(
env
,
"UART(%u, baudrate=%u, bits=%u, parity="
,
self
->
uart_id
,
self
->
uart
.
Init
.
BaudRate
,
self
->
uart
.
Init
.
WordLength
==
UART_WORDLENGTH_8B
?
8
:
9
);
self
->
uart_id
,
self
->
uart
.
Init
.
BaudRate
,
bits
);
if
(
self
->
uart
.
Init
.
Parity
==
UART_PARITY_NONE
)
{
print
(
env
,
"None"
);
}
else
{
...
...
@@ -359,7 +364,7 @@ STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void
/// Initialise the UART bus with the given parameters:
///
/// - `baudrate` is the clock rate.
/// - `bits` is the number of bits per byte, 8 or 9.
/// - `bits` is the number of bits per byte,
7,
8 or 9.
/// - `parity` is the parity, `None`, 0 (even) or 1 (odd).
/// - `stop` is the number of stop bits, 1 or 2.
/// - `timeout` is the timeout in milliseconds to wait for the first character.
...
...
@@ -384,20 +389,40 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
// set the UART configuration values
memset
(
&
self
->
uart
,
0
,
sizeof
(
self
->
uart
));
UART_InitTypeDef
*
init
=
&
self
->
uart
.
Init
;
// baudrate
init
->
BaudRate
=
args
[
0
].
u_int
;
init
->
WordLength
=
args
[
1
].
u_int
==
8
?
UART_WORDLENGTH_8B
:
UART_WORDLENGTH_9B
;
// parity
mp_int_t
bits
=
args
[
1
].
u_int
;
if
(
args
[
2
].
u_obj
==
mp_const_none
)
{
init
->
Parity
=
UART_PARITY_NONE
;
}
else
{
mp_int_t
parity
=
mp_obj_get_int
(
args
[
2
].
u_obj
);
init
->
Parity
=
(
parity
&
1
)
?
UART_PARITY_ODD
:
UART_PARITY_EVEN
;
bits
+=
1
;
// STs convention has bits including parity
}
// number of bits
if
(
bits
==
8
)
{
init
->
WordLength
=
UART_WORDLENGTH_8B
;
}
else
if
(
bits
==
9
)
{
init
->
WordLength
=
UART_WORDLENGTH_9B
;
}
else
{
nlr_raise
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"unsupported combination of bits and parity"
));
}
// stop bits
switch
(
args
[
3
].
u_int
)
{
case
1
:
init
->
StopBits
=
UART_STOPBITS_1
;
break
;
default:
init
->
StopBits
=
UART_STOPBITS_2
;
break
;
}
init
->
Mode
=
UART_MODE_TX_RX
;
// flow control
init
->
HwFlowCtl
=
args
[
4
].
u_int
;
// extra config (not yet configurable)
init
->
Mode
=
UART_MODE_TX_RX
;
init
->
OverSampling
=
UART_OVERSAMPLING_16
;
// init UART (if it fails, it's because the port doesn't exist)
...
...
@@ -412,8 +437,14 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
// setup the read buffer
m_del
(
byte
,
self
->
read_buf
,
self
->
read_buf_len
<<
self
->
char_width
);
if
(
init
->
WordLength
==
UART_WORDLENGTH_9B
&&
init
->
Parity
==
UART_PARITY_NONE
)
{
self
->
char_mask
=
0x1ff
;
self
->
char_width
=
CHAR_WIDTH_9BIT
;
}
else
{
if
(
init
->
WordLength
==
UART_WORDLENGTH_9B
||
init
->
Parity
==
UART_PARITY_NONE
)
{
self
->
char_mask
=
0xff
;
}
else
{
self
->
char_mask
=
0x7f
;
}
self
->
char_width
=
CHAR_WIDTH_8BIT
;
}
self
->
read_buf_head
=
0
;
...
...
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