Page 1 of 2

Can not initialize STM32L476 UART

Posted: Sun Nov 10, 2019 11:21 pm
by HollowHead
Hello All,

I finally got the NUCLEO_L476RG-20191107-v1.11-563-g4be316fb0.dfu on to my Nucleo STM32L476.

using screen I can access the REPL!

I followed the tutorial and got the LED to flash and do other things.

The Nucleo-64 STM32L476RGT6 has a UART on pins PA2 PA3.

PA2 USART2_TX
PA3 USART2_RX

This is where I have hit a brick wall. I tried many of the UART examples to be returned
a rainbow of error messages like

>>> from machine import UART
>>> uart = UART(2, 9600)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: UART is static and can't be init'd
>>>


>>> import pyb
>>> uart = pyb.UART(2, 9600, timeout_char = 1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: UART is static and can't be init'd
>>>

I tried to import stm then tried the above replacing pyb with stm but no luck.
If I type dir(stm) from REPL there is a long list with USART2 on it.

Next tried

>>> dir(stm.USART2)
['__class__', 'from_bytes', 'to_bytes']

Not sure what this means?

I am at loss as to how to initialize USART2 or write to it?

Any info would be appreciated.

Please bear in mind that I am new to Python and best explain thing to me as you would a child.

Thanks Mike

Re: Can not initialize STM32L476 UART

Posted: Mon Nov 11, 2019 12:32 pm
by jimmo
Hi Mike,

On this board, the second UART is reserved for the REPL. Do you want to use the REPL at a different speed (in which case you'll need to compile your own firmware). But if your actual need is to connect to something else with the UART, then can you use a different UART? (the L476 has five of them I think).

However, for some reason the board configuration for the NUCLEO_L476RG doesn't configure the other UARTs. See https://github.com/micropython/micropyt ... figboard.h (it only has UART2 defined).

If you look at a different board, e.g. https://github.com/micropython/micropyt ... figboard.h you can see all hte UARTs defined. So if you wanted to fill this out for your board, the chip datasheet shows the pins, which you can cross-reference with the board schematics to figure out which ones are readily available on external headers.

As a start, I think this is what 1 and 3 should look like (in addition to the existing UART2).

Code: Select all

#define MICROPY_HW_UART1_TX     (pin_B6)
#define MICROPY_HW_UART1_RX     (pin_B7)
#define MICROPY_HW_UART2_TX     (pin_A2)
#define MICROPY_HW_UART2_RX     (pin_A3)
#define MICROPY_HW_UART3_TX     (pin_C4)
#define MICROPY_HW_UART3_RX     (pin_C5)
This means you'll have to build your own firmware to test this. Let us know if we can help with that. Otherwise I can probably do this for you and send a pull request, but I don't have this board to test it on.

The stm module contains a bunch of register defintions. So stm.USART2 will be one of the registers for controlling the USART2 peripheral. (You don't want this).

Re: Can not initialize STM32L476 UART

Posted: Tue Nov 12, 2019 1:21 am
by HollowHead
Hi Jimmo,

Thanks for your reply.

I had a look at the files you linked ie
micropython/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h and
micropython/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h

So then read a post/entry (viewtopic.php?f=12&t=2613) to try and compile this but we fell short as JF002 instructs to cd into unix which I did not have. I imagine something has change with the file structure. I let JF002 know.

This compiling etc is new to me and do find it all very confusing.

Is REPL on these pins? ie USART2 (Nucleo pins PA2 and PA3)? I connected a usb to uart (TTL logic ie 0-5v) to PA2 and PA3 but could not establish a connection using the terminal and the convertors designated device ie screen /dev/ttyUSB0 but nothing. It could be a different baud rate etc. This is not my intent. I am after UART comms between the NUCLEO and another device which is controlled with the Python script.

I currently use the /dev/ttyACM0 to REPL to the NUCLEO ie the USB pins to the STM32L476 exposed at PA11 and PA12 on the NUCLEO.

This was the same way the firmware was loaded (NUCLEO_L476RG-20191107-v1.11-563-g4be316fb0.dfu).

I have had a look at both the NUCLEO schematic and its processors datasheet.

From the NUCLEO board sheet;
PC10 (USART3_TX) are exposed (ie are connected through from the STM chip to a header pin)
PC11 (USART3_RX) are exposed

PB6 are exposed
PB7 are exposed

PC4 are exposed
PC5 are exposed

From the STM32L476 Data sheet (PIN FUNCTIONS);

PC10 USART3_TX, UART4_TX and many other items
PC11 USART3_RX, UART4_RX and more

PB6 USART1_TX and more
PB7 USART1_RX and more

PC4 USART3_TX and more
PC5 USART3_RX and more

I am not sure but thinking that a UART is needed instead of a USART ie PC10 and PC11 set up for UART4 but I do not know?

If you are offering to compile it, I would say yes Please but only if it does not take too much of your time.

I do worry though that in the future, if things like SPI I2C etc are needed that compilation is a must so I will try to learn more in the mean time.

Thanks again.

Re: Can not initialize STM32L476 UART

Posted: Tue Nov 12, 2019 2:13 am
by jimmo
HollowHead wrote:
Tue Nov 12, 2019 1:21 am
Is REPL on these pins? ie USART2 (Nucleo pins PA2 and PA3)? I connected a usb to uart (TTL logic ie 0-5v) to PA2 and PA3 but could not establish a connection using the terminal and the convertors designated device ie screen /dev/ttyUSB0 but nothing. It could be a different baud rate etc. This is not my intent. I am after UART comms between the NUCLEO and another device which is controlled with the Python script.
On your Nucleo board, the included ST-Link is providing the UART->USB adaptor for you (which gives you /dev/ttyACM0 on your PC). So when you plug another FTDI, you'll have multiple things driving the TX line.

So yeah, you need to use a different UART.

USART vs UART doesn't matter here, just think of them as UARTs.
HollowHead wrote:
Tue Nov 12, 2019 1:21 am
I do worry though that in the future, if things like SPI I2C etc are needed that compilation is a must so I will try to learn more in the mean time.
No, the I2C (1 & 2) and SPI (1 & 2) look like they're configured fine for this board.
HollowHead wrote:
Tue Nov 12, 2019 1:21 am
So then read a post/entry (viewtopic.php?f=12&t=2613) to try and compile this but we fell short as JF002 instructs to cd into unix which I did not have. I imagine something has change with the file structure. I let JF002 know.

This compiling etc is new to me and do find it all very confusing.
These instructions are quite out of date. Also you don't need to compile the unix port to build the stm32 port.

It looks like you're on Linux, so this should at least be more straightforward than Windows or Mac.

On Ubuntu you need the gcc-arm-none-eabi package (sudo apt install gcc-arm-none-eabi), other distributions are much the same.

Then, git clone the micropython repo and run this from the top-level directory

Code: Select all

cd mpy-cross
make -j
cd ../ports/stm32
make submodules
make -j BOARD=NUCLEO_L476RG
make deploy

Re: Can not initialize STM32L476 UART

Posted: Tue Nov 12, 2019 3:33 am
by HollowHead
Hi Jimmo,

There has got to be a better way! This really is a complex maze.

I have installed so much onto this computer and now believe that we have sufficient tools on this computer to compile but insufficient brain cells to use it!

Found a github page that I coul sort of follow. https://github.com/micropython/micropyt ... /README.md

From the shell, terminal, console or whatever the correct name is;

git clone https://github.com/micropython/micropython

I found the config file you talked of micropython/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h

The UART "stuff" in the file;

// UART config
#define MICROPY_HW_UART2_TX (pin_A2)
#define MICROPY_HW_UART2_RX (pin_A3)

#define MICROPY_HW_UART_REPL PYB_UART_2
#define MICROPY_HW_UART_REPL_BAUD 115200

Are all remmed out. So I added your lines and removed the # for UART1 TX RX

define MICROPY_HW_UART1_TX (pin_B6)
define MICROPY_HW_UART1_RX (pin_B7)
#define MICROPY_HW_UART2_TX (pin_A2)
#define MICROPY_HW_UART2_RX (pin_A3)
#define MICROPY_HW_UART3_TX (pin_C4)
#define MICROPY_HW_UART3_RX (pin_C5)

then saved. Changed directory back to 'micropython/ports/stm32' did a 'make submodules'
The next thing was to do a 'make deploy' but then get an error which seems to be the norm with all this mess.
I did note that a 'dfu' and 'hex' files were produced when doing the 'make submodules' ie message;

GEN build-PYBV10/firmware.dfu
GEN build-PYBV10/firmware.hex

I found the dfu file but could not use the dfu-util, comes with another error.

I tried;
dfu-util -a 0 --dfuse-address 0x08000000 -D firmware.hex
and that did do something, yet to see if it works.

Not sure if this is the "normal" way of doing things, seems obscure and complicated fraught with ways to break.
Let me know if I am doing something wrong.

Thanks Mike

Re: Can not initialize STM32L476 UART

Posted: Tue Nov 12, 2019 3:55 am
by HollowHead
Well that did not work, I now can not 'screen' to the board. Nor does the board show up as ttyACM0. Have to go.

Re: Can not initialize STM32L476 UART

Posted: Tue Nov 12, 2019 4:05 am
by jimmo
Yeah it's really unfortunate that when this particular board was added, they didn't include all the UARTs -- as you can see, the other boards do have this.

In C, the # symbol doesn't mean "comment" (or "rem") -- it needs to be there. "#define" is a preprocessor macro.

What was the error when you did a "make deploy"? Oh... I can probably guess... my fault. It should be "make BOARD=NUCLEO_L476RG deploy" (which is why you ended up with PYBV10 firmware, not NUCLEO_L476RG).

So the updated instructions are:

Code: Select all

# from wherever you cloned micropython:
cd mpy-cross
make -j
cd ../ports/stm32
make submodules
make -j BOARD=NUCLEO_L476RG
make BOARD=NUCLEO_L476RG deploy
And the NUCLEO_L476RG/mpconfigport.h, change only:

Code: Select all

#define MICROPY_HW_UART2_TX     (pin_A2)
#define MICROPY_HW_UART2_RX     (pin_A3)
to

Code: Select all

#define MICROPY_HW_UART1_TX (pin_B6)
#define MICROPY_HW_UART1_RX (pin_B7)
#define MICROPY_HW_UART2_TX (pin_A2)
#define MICROPY_HW_UART2_RX (pin_A3)
#define MICROPY_HW_UART3_TX (pin_C4)
#define MICROPY_HW_UART3_RX (pin_C5)

Re: Can not initialize STM32L476 UART

Posted: Tue Nov 12, 2019 4:37 am
by HollowHead
Hi Jimmo,

Thanks for your help, it is keeping me sane.

I have connected the nucleo directly to a USB cable ie PA11 to D- and PA12 to D+

Using both windows and linux.

I managed to transfer the newly compiled dfu file using the windows dfu utility.

If I plug the NUCLEO in via the mini USB plug, my linux box sees it as ttyACM0 but I still can not screen to it (it just goes blank and locks that screen) I tried with and without the ST Link jumpers. Out of desperation.

Do I have to enable the USB PA11 to D- and PA12 to D+ some how in the mpconfigboard.h??

Thanks again

Re: Can not initialize STM32L476 UART

Posted: Tue Nov 12, 2019 4:47 am
by jimmo
HollowHead wrote:
Tue Nov 12, 2019 4:37 am
I have connected the nucleo directly to a USB cable ie PA11 to D- and PA12 to D+
Uhh... UART is not USB!!

I thought you had a USB/UART adaptor? You mentioned /dev/ttyUSB0 earlier which sounds like an FTDI adaptor. You should be able to use that.
HollowHead wrote:
Tue Nov 12, 2019 4:37 am
I managed to transfer the newly compiled dfu file using the windows dfu utility.
OK so you were able to build build-NUCLEO_L476RG/firmware.dfu then use the Windows utility to copy that? And now you can get a REPL on the device etc using screen (like before)?

I'm a bit confused what you're trying to do...?

Re: Can not initialize STM32L476 UART

Posted: Tue Nov 12, 2019 4:51 am
by jimmo
Ohh... I misread... you're trying to use the USB interface on the STM32L476 directly... (PA11/PA12). Not as a UART.

Cool... ok so if it shows up as ttyACM0 (and you're not connected to the st-link at all) then that suggests it's working (i.e. no configuration changes required -- if the USB CDC-ACM mode is enabled, it duplicates the REPL). (But re-reading, it sounds like you only get ttyACM0 when you're using the st-link interface, not when you connect D+/D- directly)