Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bcm283x (or new pkg): support alternate functions of the bcm2711 #24

Closed
knieriem opened this issue Dec 14, 2022 · 3 comments · Fixed by #25
Closed

bcm283x (or new pkg): support alternate functions of the bcm2711 #24

knieriem opened this issue Dec 14, 2022 · 3 comments · Fixed by #25

Comments

@knieriem
Copy link
Contributor

In an RPi 4 project I needed to switch pin functions of GPIO4/5 at runtime between the Input function and the ALT4 alternate function TXD3/RXD3.

While rpi and bcm283x packages mostly appear to work fine on an RPi 4 regarding GPIO functionality, the RPi 4, which is based on the bcm2711, provides quite some more alternate functions that are not covered by the mapping table in bcm283x/gpio.c.

As a workaround, I simply added entries for UART3_TX and UART3_RX to that table:

--- a/bcm283x/gpio.go
+++ b/bcm283x/gpio.go
@@ -975,8 +975,8 @@ var mapping = [][6]pin.Func{
 	{"I2C0_SCL"},
 	{"I2C1_SDA"},
 	{"I2C1_SCL"},
-	{"CLK0"},
-	{"CLK1"}, // 5
+	{"CLK0", "", "", "", "UART3_TX"},
+	{"CLK1", "", "", "", "UART3_RX"}, // 5
 	{"CLK2"},
 	{"SPI0_CS1"},
 	{"SPI0_CS0"},

What would be an appropriate way to add the more extensive settings for the bcm2711?
Alternate function tables of bcm2835 and bcm2711 suggest that the bcm2711 is mostly compatible, an extension, to the bcm2835 in this regard. So the mapping table could just be extended to contain the additional functions of the bcm2711. The problem with this approach is that the table then would be misleading for users of RPis smaller than 4, as it would contain alternate functions that are not available on the bcm2835. Code calling rpi.P1_7.(pin.PinFunc).SetFunc("UART_TX") would not work as expected when running it on an RPi 3.

Perhaps an approach could be to extend mapping table entries by a prefix, like in the following example:

	{"CLK0", "", "", "", "bcm2711:UART3_TX"},
	{"CLK1", "", "", "", "bcm2711:UART3_RX"}, // 5

// or, less verbose:

	{"CLK0", "", "", "", "+UART3_TX"},
	{"CLK1", "", "", "", "+UART3_RX"}, // 5

... with prefixes bcm2711: or + meaning available only on the bcm2711 resp. extended MCUs.
Depending on a package bcm283x global variable, configured during host.Init(), the additional alt functions then would be available, or not.
(Additional code would be needed to strip the prefix within bcm283x/gpio.go where needed)

Do you see another approach that you would prefer?

@maruel
Copy link
Member

maruel commented Dec 15, 2022

The mapping is intentionally a private variable. Duplicate it, and chose the right table based on the CPU. Better than trying to make one table address both configurations.

Something like:

var mapping = [][6]pin.Func
var mapping2835 = [...][6]pin.Func{...}
var mapping2711 = [...][6]pin.Func{...}

if isRPi4 {
  mapping = mapping2711
} else {
  mapping = mapping2835
}

It's just simpler for everyone IMO.

knieriem added a commit to knieriem/periph-host that referenced this issue Dec 19, 2022
The BCM2711 provides more alternate pin functions than
the BCM283x. An extra mapping table mapping2711 is
added by this change, which gets assigned to the `mapping`
variable conditionally during driverGPIO.Init().
The existing mapping is renamed to mapping283x, and used as
default to keep tests working.

This change enables selecting alternate functions at runtime
on a BCM2711 that were not supported by the existing BCM283x
specific mapping, like GPIO4's UART3_TX;
toggling between UART_TX and IN at runtime can be useful
e.g. when sharing a single CAN transceiver between
a CAN controller and a UART peripheral.

Resolves periph#24
@knieriem
Copy link
Contributor Author

Thanks for suggesting to create a second table. I have tried to implement that approach in the commit linked above.
If appropriate, I will create a pull request from it.
The new mapping2711 table has been generated from the specification using scripts from knieriem/bcm2711-alt-funcs-gen.

@maruel
Copy link
Member

maruel commented Dec 19, 2022

Please send as a PR, it's hard for me to visualize the end result. Thanks.

@maruel maruel closed this as completed in #25 Jul 6, 2023
maruel pushed a commit that referenced this issue Jul 6, 2023
The BCM2711 provides more alternate pin functions than
the BCM283x. An extra mapping table mapping2711 is
added by this change, which gets assigned to the `mapping`
variable conditionally during driverGPIO.Init().
The existing mapping is renamed to mapping283x, and used as
default to keep tests working.

This change enables selecting alternate functions at runtime
on a BCM2711 that were not supported by the existing BCM283x
specific mapping, like GPIO4's UART3_TX;
toggling between UART_TX and IN at runtime can be useful
e.g. when sharing a single CAN transceiver between
a CAN controller and a UART peripheral.

Resolves #24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants