AdaCore / Ada_Drivers_Library

Ada source code and complete sample GNAT projects for selected bare-board platforms supported by GNAT.
BSD 3-Clause "New" or "Revised" License
240 stars 141 forks source link

Support ST-LINK VCOM port on latest STM32F429 Discovery kits #253

Closed byzantic closed 6 years ago

byzantic commented 6 years ago

The latest version of the STM32F429 Discovery kit (STM32F429-DISCO1, Board Rev C) connects USART1 pins to the on-board ST-LINK device, which now supports a VCOM connection over the USB.

This means that it is possible to use the serial ports without needing a supplementary UART cable. However, the GPIO pins currently used in the serial_ports is not correct - I think they just go to the header pins.

The changes required are simple: in the file examples/shared/serial_ports/src/peripherals_blocking.adb change the pin allocation in the Peripheral variable initialisation:

   --  the specific port, pins, and USART selections are arbitrary.
   Peripheral : aliased Serial_IO.Peripheral_Descriptor :=
                  (Transceiver    => USART_1'Access,
                   Transceiver_AF => GPIO_AF_USART1_7,
                   Tx_Pin         => PA9,
                   Rx_Pin         => PA10);

and similarly for

examples/shared/serial_ports/src/peripherals_nonblocking.adb and examples/shared/serial_ports/src/peripherals_streaming.adb

You then need to connect to the VCOM port using a terminal program (I used PuTTY), ensuring the comms parameters match the example.

Because this is a new rev of the board, I'm not sure whether this should require a new set of board examples, or just assume that its better to use the new board if you want easy serial access ..

pat-rogers commented 6 years ago

Ideally the examples would work with either revision of the board, with a cable not required if the new revision is used, so it seems best to change the pin assignments in the examples to use pins that will work either way. The pin selections are not truly arbitrary because they are mapped to the TX and RX alternate functions for USART1 per the datasheet, so I am assuming that another set of similarly mapped pins also works with the VCOM port. Is that correct?

byzantic commented 6 years ago

Well, I only have the one board here to check. I think I found older versions of the board schematic for the STM32F429-DISCO1 (Rev B) on the web, and as far as I can tell, it also has TX => PA9, RX => PA10.

I also looked up the schematics for the STM32F469 discovery board, and it has TX=> PB11, RX => PB10 connected to the ST-LINK chip.

USART1 looks like it can be mapped to several sets of pins for each of the controller device types. In the case of the STM32F429-DISCO1 board one of these pinsets goes to the ST-LINK, the other to header pins. For development purposes, it is more useful to use the connection to the ST-LINK.

In fairness, I just re-read the comments, and the code is not specific to any one board, and indicates that the pin assignment is 'arbitrary'. If that's going to continue to be the case, a few lines of explanation in the comments might help people?

Longer term, I would push for the inclusion of peripherals in a board package, that includes their default pin assignment. I'm still trying to understand how the structure of the library separates out the components / devices / board hierarchy ..

But frankly, I'm pretty knocked out that it works at all, so don't take that as a criticism ..

pat-rogers commented 6 years ago

On 4/6/2018 11:01 AM, byzantic wrote:

Well, I only have the one board here to check. I think I found older versions of the board schematic for the STM32F429-DISCO1 (Rev B) on the web, and as far as I can tell, it also has TX => PA9, RX => PA10.

I see what you mean now, the new board revision permanently attaches PA9 and PA10 via solder bridges to USART1 TX and RX. (I found the new user manual.) They did something similar with the F4 Disco board, using a solder bridge to connect PA0 to the blue user button.

In fairness, I just re-read the comments, and the code is not specific to any one board, and indicates that the pin assignment is 'arbitrary'.

The pin assignments, like the USART selection, are arbitrary in the sense that the application itself doesn't depend on the selection. But you're right that it isn't arbitrary at the hardware level, and now there is a difference in the board revisions too. In the older rev we could have used PB6 and PB7 instead.

If that's going to continue to be the case, a few lines of explanation in the comments might help people?

Yes, I agree. Something along the lines that the user should examine and verify the pin mappings for their specific board, making changes as necessary and being cognizant of newer board revisions. And noting that the example peripheral is configured for a specific revision of a specific board. Is that what you had in mind?

Longer term, I would push for the inclusion of peripherals in a board package, that includes their default pin assignment. I'm still trying to understand how the structure of the library separates out the components / devices / board hierarchy ..

I'd like to have a way of capturing the possible valid pin-device combinations, and for the developers to select among them, without having to look up the alternate function mappings each time. It is too easy to make a mistake originally, and as in this case, to not catch hardware changes. Maybe in a child package under the Board package.

But frankly, I'm pretty knocked out that it works at all, so don't take that as a criticism ..

Comments and suggestions are absolutely always welcome!

Do you want to take a shot at revising the comments into a pull request?

Fabien-Chouteau commented 6 years ago

Hi @byzantic

Longer term, I would push for the inclusion of peripherals in a board package, that includes their default pin assignment.

We already have that in the boards/* directories. For instance there are packages to initialize the components and features of the boards like touch screens.

Initialization of the debug UART and pins would be a perfectly be suited in the STM32.Board package.

I'm still trying to understand how the structure of the library separates out the components / devices / board hierarchy ..

This means we need to improve the design doc to include this kind of information.

pat-rogers commented 6 years ago

On 4/6/2018 1:18 PM, Fabien Chouteau wrote:

Hi @byzantic https://github.com/byzantic

Longer term, I would push for the inclusion of peripherals in a board package, that includes their default pin assignment.

We already have that in the |boards/*| directories. For instance there are packages to initialize the components and features of the boards like touch screens.

I was thinking of something revision-specific, it even more specific than the Boards packages, that would capture the differences like this.

byzantic commented 6 years ago

We already have that in the boards/* directories. For instance there are packages to initialize the components and features of the boards like touch screens.

Initialization of the debug UART and pins would be a perfectly be suited in the STM32.Board package.

Yes, that sounds like the correct approach. I'll spend some time trying to work out the hierarchy.

At a quick inspection, it looks as though the serial ports example builds a high level API for the serial ports that encapsulates the blocking/non-blocking/streaming behaviour, and this is why it does not use facilities from the board package. Ideally, the USARTs and UARTs would be declared in the board package in the same way that, say, the SDRAM is declared, and higher level abstractions would refer to these.

The fact that the USARTs can be connected to different pins might be handled by declaring different names with different pins, but this does not guard against two clients trying to use them simultaneously.

I was thinking of something revision-specific, it even more specific than the Boards packages, that would capture the differences like this.

Actually, I have a fairly hard-line approach to this sort of issue; if a revision has different functionality, its a different board. Obviously, the best approach is to use an extension/subclass approach so that one doesn't have to completely rewrite the original, but it is a different board even so.

Having said that, I think I may have jumped the gun originally, and that the revisions are not different in connectivity, but they may have had different firmware versions in the ST-LINK device.

Given that I may have been over-zealous in raising the issue, do you want me to close it?

Fabien-Chouteau commented 6 years ago

I was thinking of something revision-specific, it even more specific than the Boards packages, that would capture the differences like this.

This could be handled with configuration scripts.

pat-rogers commented 6 years ago

On 4/7/2018 11:10 AM, byzantic wrote:

We already have that in the boards/* directories. For instance there
are packages to initialize the components and features of the boards
like touch screens.

Initialization of the debug UART and pins would be a perfectly be
suited in the STM32.Board package.

Yes, that sounds like the correct approach. I'll spend some time trying to work out the hierarchy.

At a quick inspection, it looks as though the serial ports example builds a high level API for the serial ports that encapsulates the blocking/non-blocking/streaming behaviour, and this is why it does not use facilities from the board package.

That's correct, it is not meant to be specific to any given board.

Ideally, the USARTs and UARTs would be declared in the board package in the same way that, say, the SDRAM is declared, and higher level abstractions would refer to these.

They are declared in the *.Device packages since the MCU determines how many there are and at what addresses, but that is the idea indeed.

The fact that the USARTs can be connected to different pins might be handled by declaring different names with different pins, but this does not guard against two clients trying to use them simultaneously.

I was thinking of something revision-specific, it even more specific
than the Boards packages, that would capture the differences like this.

Actually, I have a fairly hard-line approach to this sort of issue; if a revision has different functionality, its a different board. Obviously, the best approach is to use an extension/subclass approach so that one doesn't have to completely rewrite the original, but it is a different board even so.

Arguably so, yes.

Having said that, I think I may have jumped the gun originally, and that the revisions are not different in connectivity, but they /may/ have had different firmware versions in the ST-LINK device.

Given that I may have been over-zealous in raising the issue, do you want me to close it?

That works for me, if you are satisfied with that.

pat-rogers commented 6 years ago

On 4/9/2018 8:17 AM, Fabien Chouteau wrote:

I was thinking of something revision-specific, it even more specific
than the Boards packages, that would capture the differences like this.

This could be handled with configuration scripts.

Agreed, and sounds good.

byzantic commented 6 years ago

Closing the issue, since it was based on a misunderstanding on my part.