Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 129 additions & 1 deletion app/demo-stm32h7-nucleo/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,129 @@
# STM32H7 demo application
# STM32H7 Nucleo-144 Demo Application

Hubris application configurations for the STM32H7 Nucleo-144
development boards:

- `app-h743.toml` -- NUCLEO-H743ZI (order code NUCLEO-H743ZI2)
- `app-h753.toml` -- NUCLEO-H753ZI

The Nucleo boards are readily available development boards for general
Hubris development. Although they are not part of any Oxide Computer
product, they are configured to work with the Management Gateway Service
to allow over-the-network update and testing.

## Board differences

Both boards use the same Nucleo-144 form factor and share identical
pin assignments. The STM32H753 includes a hardware hash accelerator
supported by Hubris that the STM32H743 lacks.

## VLAN

Unlike Oxide designed boards, the Nucleo boards do not have a KSZ8463
Ethernet switch chip and have no need for 802.1q VLAN tags. The `vlan`
feature is omitted through conditional compilation, i.e. `#[cfg(feature =
"vlan")]` and does not affect production code.

## Pin assignments

[Reference: UM2407 Rev 2, "STM32H7 Nucleo-144 boards (MB1364)"](https://www.st.com/resource/en/user_manual/um2407-stm32h7-nucleo144-boards-mb1364-stmicroelectronics.pdf)):

### Ethernet (RMII, active)

| Pin | Function | Connector |
|------|-----------------|------------------|
| PA1 | RMII Ref Clock | -- |
| PA2 | RMII MDIO | -- |
| PA7 | RMII RX DV | -- |
| PC1 | RMII MDC | -- |
| PC4 | RMII RXD0 | -- |
| PC5 | RMII RXD1 | -- |
| PG11 | RMII TX Enable | -- |
| PG13 | RMII TXD0 | -- |
| PB13 | RMII TXD1 | CN7 pin 5 (Zio) |

### SPI3 -- SP-to-RoT connection (active, no peer)

In the past, developers have connected an NXP LPC55S69 xPresso board to
emulate an RoT. We do not make any effort to support this configuration.
It is more complicated to get it right than just using jumper wires.

We still reserve the pins to make sure that we can run the CPA and its
required `sprot` task without modifications or interfering with other
signals. In this configuration, the non-existent "RoT" just won't respond.


| Pin | Function | AF | Connector |
|------|-----------|----|----------------------------|
| PC10 | SPI3_SCK | 6 | CN11 pin 1, CN8 pin 6 |
| PC11 | SPI3_MISO | 6 | CN11 pin 2, CN8 pin 8 |
| PC12 | SPI3_MOSI | 6 | CN11 pin 3, CN8 pin 10 |
| PA15 | SPI3_NSS | -- | CN11 pin 17, CN7 pin 9 |

The Zio connector labels these as SDMMC_D2/D3/CK (CN8). SDMMC is
not used. The SPI3 alternate function is selected in firmware.

### GPIO -- RoT signals

| Pin | Function | Direction | Connector |
|------|-------------|-----------|-------------|
| PD0 | rot_irq | Input | CN11 pin 57 |
| PE6 | sprot debug | Output | CN11 pin 62 |

PD0 is labeled CAN_RX on the Zio connector (CN9 pin 25); CAN is not
used. PE6 is labeled SAI_A_SD (CN9 pin 20); SAI is not used.

### SPI1 -- General purpose header

| Pin | Function | AF | H743 | H753 |
|------|------------|----|--------------|--------------|
| PA5 | SPI1_SCK | 5 | Used | -- |
| PA3 | SPI1_SCK | 5 | -- | Used |
| PB5 | SPI1_MOSI | 5 | Used | Used |
| PA6 | SPI1_MISO | 5 | Used | Used |
| PD14 | SPI1_CS | -- | Used | Used |

### I2C2

| Pin | Function | AF |
|-----|-----------|----|
| PF1 | I2C2_SCL | 4 |
| PF0 | I2C2_SDA | 4 |

### USART1 -- Host UART (active, no peer)

| Pin | Function | Connector |
|------|------------|-------------|
| PA9 | USART1_TX | CN11 pin 21 |
| PA10 | USART1_RX | CN11 pin 33 |

Reserved by CPA for host-SP communication. No host CPU on the
Nucleo; the UART is idle.

### On-board hardware (do not reassign)

| Pin | Function | Notes |
|------|-------------------------|-------------------------|
| PC13 | User button B1 | GPIO IRQ |
| PB0 | User LED LD1 (green) | Default SB39/SB47 config|
| PE1 | User LED LD2 (yellow) | -- |
| PB14 | User LED LD3 (red) | -- |
| PA13 | ST-Link SWDIO | Do not use as GPIO |
| PA14 | ST-Link SWCLK | Do not use as GPIO |
| PD8 | USART3 TX (VCP default) | ST-Link virtual COM |
| PD9 | USART3 RX (VCP default) | ST-Link virtual COM |

## Connecting an LPC55S69-EVK as RoT

The sprot SPI3 pins and GPIO signals are accessible on the ST morpho
connector CN11. To connect an LPC55S69-EVK board:

| Nucleo (CN11) | Signal | LPC55S69-EVK |
|-------------------|-----------|---------------------|
| Pin 1 (PC10) | SPI_SCK | SPI CS/SCK pin |
| Pin 2 (PC11) | SPI_MISO | SPI MISO pin |
| Pin 3 (PC12) | SPI_MOSI | SPI MOSI pin |
| Pin 17 (PA15) | SPI_CS | SPI CS pin |
| Pin 57 (PD0) | ROT_IRQ | GPIO IRQ output |
| Pin 19/GND | GND | GND |

157 changes: 146 additions & 11 deletions app/demo-stm32h7-nucleo/app-h743.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ name = "demo-stm32h7-nucleo"
requires = {flash = 24736, ram = 5120}
features = ["h743", "dump"]

[caboose]
tasks = ["control_plane_agent"]
region = "flash"
size = 256

[tasks.jefe]
name = "task-jefe"
priority = 0
max-sizes = {flash = 16384, ram = 4096}
start = true
features = ["dump"]
stacksize = 2000
Expand All @@ -22,7 +26,7 @@ extern-regions = [ "sram1", "sram2", "sram3", "sram4" ]

[tasks.jefe.config.allowed-callers]
set_reset_reason = ["sys"]
request_reset = ["hiffy"]
request_reset = ["hiffy", "control_plane_agent"]

[tasks.sys]
name = "drv-stm32xx-sys"
Expand All @@ -47,6 +51,11 @@ port = "C"
pin = 13
owner = {name = "user_button", notification = "button"}

[tasks.sys.config.gpio-irqs.rot_irq]
port = "D"
pin = 0
owner = {name = "sprot", notification = "rot_irq"}

[tasks.i2c_driver]
name = "drv-stm32xx-i2c-server"
stacksize = 1048
Expand All @@ -67,10 +76,16 @@ notifications = ["i2c1-irq", "i2c2-irq", "i2c3-irq", "i2c4-irq"]
"i2c4.event" = "i2c4-irq"
"i2c4.error" = "i2c4-irq"

[tasks.packrat]
name = "task-packrat"
priority = 2
start = true
# task-slots is explicitly empty: packrat should not send IPCs!
task-slots = []

[tasks.spi_driver]
name = "drv-stm32h7-spi-server"
priority = 2
max-sizes = {flash = 16384, ram = 4096}
features = ["spi1", "h743"]
uses = ["spi1"]
start = true
Expand All @@ -83,7 +98,7 @@ task-slots = ["sys"]
name = "task-net"
stacksize = 4000
priority = 2
max-sizes = {flash = 65536, ram = 8192, sram1_mac = 32768}
max-sizes = {flash = 131072, ram = 32768, sram1_mac = 32768}
features = ["h743"]
sections = {eth_bulk = "sram1_mac"}
uses = ["eth", "tim16"]
Expand All @@ -96,7 +111,6 @@ task-slots = ["sys", "jefe"]
name = "drv-user-leds"
features = ["stm32h7"]
priority = 2
max-sizes = {flash = 2048, ram = 1024}
start = true
task-slots = ["sys"]
notifications = ["timer"]
Expand All @@ -113,7 +127,22 @@ config = { led = 1, edge = "Edge::Rising" }
[tasks.udpecho]
name = "task-udpecho"
priority = 3
max-sizes = {flash = 16384, ram = 8192}
stacksize = 4096
start = true
task-slots = ["net"]
notifications = ["socket"]

[tasks.udpbroadcast]
name = "task-udpbroadcast"
priority = 3
stacksize = 4096
start = true
task-slots = ["net", "packrat"]
notifications = ["socket"]

[tasks.udprpc]
name = "task-udprpc"
priority = 3
stacksize = 4096
start = true
task-slots = ["net"]
Expand All @@ -122,16 +151,89 @@ notifications = ["socket"]
[tasks.hiffy]
name = "task-hiffy"
features = ["h743", "stm32h7", "i2c", "gpio", "spi", "turbo"]
priority = 4
max-sizes = {flash = 32768, ram = 65536 }
priority = 5
stacksize = 2048
start = true
task-slots = ["sys", "i2c_driver"]

[tasks.hf]
name = "drv-mock-gimlet-hf-server"
features = ["h743"]
priority = 4
stacksize = 2048
start = true
uses = ["quadspi"]
notifications = ["qspi-irq"]
interrupts = {"quadspi.irq" = "qspi-irq"}
task-slots = ["sys"]

[tasks.gimlet_seq]
name = "drv-mock-gimlet-seq-server"
priority = 2
start = true
task-slots = ["jefe"]

[tasks.update_server]
name = "stm32h7-update-server"
priority = 3
stacksize = 2048
start = true
uses = ["flash_controller"]
extern-regions = ["bank2"]
notifications = ["flash-irq"]
interrupts = {"flash_controller.irq" = "flash-irq"}

[tasks.validate]
name = "task-validate"
priority = 3
stacksize = 1024
start = true
task-slots = ["i2c_driver"]

[tasks.sensor]
name = "task-sensor"
priority = 5
stacksize = 1024
start = true

[tasks.sprot]
name = "drv-stm32h7-sprot-server"
priority = 5
stacksize = 16384
start = true
task-slots = ["sys"]
features = ["sink_test", "use-spi-core", "h743", "spi3"]
uses = ["spi3"]
notifications = ["spi-irq", "rot-irq", "timer"]
interrupts = {"spi3.irq" = "spi-irq"}

[tasks.control_plane_agent]
name = "task-control-plane-agent"
priority = 7
stacksize = 6256
start = true
uses = ["usart1"]
task-slots = [
"jefe",
"net",
"dump_agent",
"update_server",
"sys",
"hf",
{ cpu_seq = "gimlet_seq" },
"validate",
"sensor",
"sprot",
"packrat",
"user_leds",
]
features = ["gimlet", "usart1-gimletlet", "baud_rate_3M"]
notifications = ["usart-irq", "socket", "timer"]
interrupts = {"usart1.irq" = "usart-irq"}

[tasks.idle]
name = "task-idle"
priority = 6
max-sizes = {flash = 128, ram = 256}
priority = 9
stacksize = 256
start = true

Expand All @@ -148,7 +250,6 @@ uses = ["rng"]
name = "task-dump-agent"
features = ["no-rot"]
priority = 4
max-sizes = {flash = 32768, ram = 2048 }
start = true
task-slots = ["jefe"]
stacksize = 1200
Expand Down Expand Up @@ -187,6 +288,19 @@ mux = "cn7_arduino"
cs = [{port = "D", pin = 14}]
clock_divider = "DIV16"

[config.spi.spi3]
controller = 3

[config.spi.spi3.mux_options.port_c]
outputs = [
{port = "C", pins = [10, 12], af = 6},
]
input = {port = "C", pin = 11, af = 6}

[config.spi.spi3.devices.spi3_header]
mux = "port_c"
cs = [{port = "A", pin = 15}]
clock_divider = "DIV256"

[config.net]
# UDP ports in sockets below are assigned in oxidecomputer/oana
Expand All @@ -197,3 +311,24 @@ owner = {name = "udpecho", notification = "socket"}
port = 7
tx = { packets = 3, bytes = 1024 }
rx = { packets = 3, bytes = 1024 }

[config.net.sockets.broadcast]
kind = "udp"
owner = {name = "udpbroadcast", notification = "socket"}
port = 997
tx = { packets = 3, bytes = 1024 }
rx = { packets = 3, bytes = 1024 }

[config.net.sockets.rpc]
kind = "udp"
owner = {name = "udprpc", notification = "socket"}
port = 998
tx = { packets = 3, bytes = 1024 }
rx = { packets = 3, bytes = 1024 }

[config.net.sockets.control_plane_agent]
kind = "udp"
owner = {name = "control_plane_agent", notification = "socket"}
port = 11111
tx = { packets = 3, bytes = 2048 }
rx = { packets = 3, bytes = 2048 }
Loading