Skip to content

Commit bf1d3d1

Browse files
committed
First pass cleaning up template.
1 parent 3cb190d commit bf1d3d1

14 files changed

Lines changed: 461 additions & 10 deletions

File tree

.cargo/config.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2+
runner = "probe-run --chip STM32F031K6Tx"
3+
rustflags = [
4+
"-C", "linker=flip-link",
5+
"-C", "link-arg=-Tlink.x",
6+
"-C", "link-arg=-Tdefmt.x",
7+
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
8+
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
9+
"-C", "link-arg=--nmagic",
10+
]
11+
12+
[build]
13+
target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
14+
15+
[alias]
16+
rb = "run --bin"
17+
rrb = "run --release --bin"

.gitignore

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,2 @@
1-
# Generated by Cargo
2-
# will have compiled files and executables
3-
/target/
4-
5-
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6-
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
1+
/target
72
Cargo.lock
8-
9-
# These are backup files generated by rustfmt
10-
**/*.rs.bk

.vscode/launch.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Cortex Debug",
9+
"cwd": "${workspaceRoot}",
10+
"executable": "./target/thumbv6m-none-eabi/debug/neotron-bmc",
11+
"request": "launch",
12+
"type": "cortex-debug",
13+
"servertype": "openocd",
14+
"device": "stm32f031k6",
15+
"gdbPath": "gdb-multiarch",
16+
"configFiles": [ "./openocd.cfg" ]
17+
}
18+
]
19+
}

.vscode/settings.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
// override the default setting (`cargo check --all-targets`) which produces the following error
3+
// "can't find crate for `test`" when the default compilation target is a no_std target
4+
// with these changes RA will call `cargo check --bins` on save
5+
"rust-analyzer.checkOnSave.allTargets": false,
6+
"rust-analyzer.checkOnSave.extraArgs": [
7+
"--bins"
8+
]
9+
}

Cargo.toml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
[package]
2+
authors = ["Jonathan 'theJPster' Pallant <github@thejpster.org.uk>"]
3+
name = "neotron-bmc"
4+
edition = "2018"
5+
version = "0.1.0"
6+
7+
[workspace]
8+
members = ["testsuite"]
9+
10+
[dependencies]
11+
cortex-m = "0.7.1"
12+
cortex-m-rt = "0.6.13"
13+
defmt = "0.2.0"
14+
defmt-rtt = "0.2.0"
15+
panic-probe = { version = "0.2.0", features = ["print-defmt"] }
16+
stm32f0xx-hal = { version = "0.17", features = ["stm32f030x6"] }
17+
18+
[features]
19+
# set logging levels here
20+
default = [
21+
"defmt-default",
22+
# "dependency-a/defmt-trace",
23+
]
24+
25+
# do NOT modify these features
26+
defmt-default = []
27+
defmt-trace = []
28+
defmt-debug = []
29+
defmt-info = []
30+
defmt-warn = []
31+
defmt-error = []
32+
33+
# cargo build/run
34+
[profile.dev]
35+
codegen-units = 1
36+
debug = 2
37+
debug-assertions = true # <-
38+
incremental = false
39+
opt-level = 3 # <-
40+
overflow-checks = true # <-
41+
42+
# cargo test
43+
[profile.test]
44+
codegen-units = 1
45+
debug = 2
46+
debug-assertions = true # <-
47+
incremental = false
48+
opt-level = 3 # <-
49+
overflow-checks = true # <-
50+
51+
# cargo build/run --release
52+
[profile.release]
53+
codegen-units = 1
54+
debug = 2
55+
debug-assertions = false # <-
56+
incremental = false
57+
lto = 'fat'
58+
opt-level = 3 # <-
59+
overflow-checks = false # <-
60+
61+
# cargo test --release
62+
[profile.bench]
63+
codegen-units = 1
64+
debug = 2
65+
debug-assertions = false # <-
66+
incremental = false
67+
lto = 'fat'
68+
opt-level = 3 # <-
69+
overflow-checks = false # <-
70+
71+
# uncomment this to switch from the crates.io version of defmt to its git version
72+
# check app-template's README for instructions
73+
# [patch.crates-io]
74+
# defmt = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
75+
# defmt-rtt = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
76+
# defmt-test = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
77+
# panic-probe = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }

README.md

Lines changed: 191 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,192 @@
11
# Neotron-BMC
2-
Firmware for the Neotron Board Management Controller
2+
3+
Firmware for the Neotron Board Management Controller (NBMC).
4+
5+
## Introduction
6+
7+
The NMBC is an always-on microcontroller used on Neotron systems. It has very low idle power consumption, allowing it to remain powered up at all times. This lets it listen to button events from the Power and Reset buttons, and control the system LEDs, main `~RESET` signal and turn the main 5V Power Rail on and off. This lets your Neotron system have smart 'ATX PC' style features like a soft power button, and it also ensures that all power rails come up before the system is taken out of reset.
8+
9+
The NBMC appears to the main Neotron system processor as an Expansion Device. As such it sits on the SPI bus as a peripheral device, with a dedicated Chip Select line and a dedicated IRQ line. It provides to the system:
10+
11+
* an extra I²C bus,
12+
* a four-wire UART,
13+
* two PS/2 ports (one for keyboard, one for a mouse),
14+
* two analog inputs for monitoring for the 3.3V and 5.0V rails,
15+
* two GPIO inputs for a power button and a reset button, and
16+
* three GPIO outputs - nominally used for
17+
* the main DC/DC enable signal,
18+
* the power LED, and
19+
* a status LED.
20+
21+
## Hardware Interface
22+
23+
The NBMC firmware is designed to run on an ST Micro STM32F0 (STM32F031K6T6) microcontroller
24+
25+
* 32-bit Arm Cortex-M0+ Core
26+
* 3.3V I/O (5V tolerant)
27+
* 32 KiB Flash
28+
* 4 KiB SRAM
29+
* LQFP-32 package (0.8mm pitch)
30+
31+
32+
| Pin | Name | Signal | Function |
33+
| :--- | :--- | :---------- | :------------------------------------------- |
34+
| 02 | PF0 | BUTTON_nPWR | Power Button Input (active low) |
35+
| 03 | PF1 | HOST_nRST | Reset Output to reset the rest of the system |
36+
| 06 | PA0 | MON_3V3 | 3.3V rail monitor Input (1.65V nominal) |
37+
| 07 | PA1 | MON_5V | 5.0V rail monitor Input (1.65V nominal) |
38+
| 08 | PA2 | LED0 | PWM output for first Status LED |
39+
| 09 | PA3 | LED1 | PWM output for second Status LED |
40+
| 10 | PA4 | SPI1_nCS | SPI Chip Select Input (active low) |
41+
| 11 | PA5 | SPI1_SCK | SPI Clock Input |
42+
| 12 | PA6 | SPI1_CIPO | SPI Data Output |
43+
| 13 | PA7 | SPI1_COPI | SPI Data Input |
44+
| 14 | PB0 | BUTTON_nRST | Reset Button Input (active low) |
45+
| 15 | PB1 | DC_ON | PSU Enable Output |
46+
| 18 | PA8 | IRQ_nHOST | Interrupt Output to the Host (active low) |
47+
| 19 | PA9 | I2C1_SCL | I²C Clock |
48+
| 20 | PA10 | I2C1_SDA | I²C Data |
49+
| 21 | PA11 | USART1_CTS | UART Clear-to-Send Output |
50+
| 22 | PA12 | USART1_RTS | UART Ready-to-Receive Input |
51+
| 23 | PA13 | SWDIO | SWD Progamming Data Input |
52+
| 24 | PA14 | SWCLK | SWD Programming Clock Input |
53+
| 25 | PA15 | PS2_CLK0 | Keyboard Clock Input |
54+
| 26 | PB3 | PS2_CLK1 | Mouse Clock Input |
55+
| 27 | PB4 | PS2_DAT0 | Keyboard Data Input |
56+
| 28 | PB5 | PS2_DAT1 | Mouse Data Input |
57+
| 29 | PB6 | USART1_TX | UART Transmit Output |
58+
| 30 | PB7 | USART1_RX | UART Receive Input |
59+
60+
Note that in the above table, the UART signals are wired as _Data Terminal Equipment (DTE)_ (i.e. like a PC, not like a Modem).
61+
62+
This design should also be pin-compatible with the following SoCs (although this firmware may need changes):
63+
64+
* STM32F042K4Tx
65+
* STM32F042K6Tx
66+
* STM32L071KBTx
67+
* STM32L071KZTx
68+
* STM32L072KZTx
69+
* STM32L081KZTx
70+
* STM32L082KZTx
71+
72+
Note that not all STM32 pins are 5V-tolerant, and the PS/2 protocol is a 5V open-collector system, so ensure that whichever part you pick has 5V-tolerant pins (marked `FT` or `FTt` in the datasheet) for the PS/2 signals. All of the parts above _should_ be OK, but they haven't been tested. Let us know if you try one!
73+
74+
## Communications Protocol - SPI Frames
75+
76+
The SPI interface runs in SPI mode 0 (clock line idles low, data sampled on rising edge) at up to 16 MHz (TBD). It uses frames made up of 8-bit words.
77+
78+
To communicate with the NBMC, first take the Chip Select line (`SPI1_nCS`) low, then send the appropriate number of bytes. SPI is a full-duplex system, but in this system only one side is actually transferring useful data at any time.
79+
80+
Once the appropriate number of bytes have been exchange, the Chip Select line must be raised for at least XXX microseconds, before another transfer is started.
81+
82+
```
83+
+-----+-------------...-------------+----------------...---------------+
84+
| CMD | CLEN | Command Bytes 0..n | PADDING | Controller Out, Peripheral In (COPI)
85+
+-----+------+------...-------------+-----+------+---------...---------+
86+
| PADDING | RSP | RLEN | Response Bytes 0..n | Controller In, Peripheral Out (CIPO)
87+
+----------------...----------------+-----+------+---------...---------+
88+
```
89+
90+
The `CMD` byte is a command, given in the Table of Commands below. `RSP` is a response byte, given in the Table of Responses below.
91+
92+
Taking the Chip Select line low activates an Interrupt Routine. You must leave XXX microseconds (TBD) before starting the transfer in order to give the routine time to start. The various CMD bytes either read or write various registers in RAM. Once the Chip Select is raised, the system goes into its background processing, reading from the registers to set system outputs, and writing to registers based on system inputs.
93+
94+
## Communications Protocol - Commands and Responses
95+
96+
### Table of Commands
97+
98+
| Command Byte | Name |
99+
| ------------ | ----- |
100+
| 0x00 | PING |
101+
| 0x01 | READ |
102+
| 0x02 | WRITE |
103+
104+
### Table of Responses
105+
106+
| Response Byte | Name |
107+
| ------------- | --------------- |
108+
| 0x80 | OK |
109+
| 0x81 | Unknown Command |
110+
| 0xFF | Busy |
111+
112+
### PING Command
113+
114+
This command just checks the NBMC is awake. There is no payload. A OK response is sent in return.
115+
116+
### READ Command
117+
118+
This command reads from an address in the NBMC. The payload is the 8-bit register address, followed by the 8-bit number of bytes to read. The `CLEN` must therefore be two.
119+
120+
### WRITE Command
121+
122+
This command writes to an address in the NBMC. The payload is the 8-bit register address, followed by the 8-bit number of bytes to write, followed by the bytes themselves (up to 253). The `CLEN` must therefore be 2 + the number of bytes written.
123+
124+
### Table of Registers
125+
126+
| Address | Name | Type | Contains | Length |
127+
| ------- | ------------------------------------- | ----- | -------------------------------------------------------- | ------ |
128+
| 0x00 | Firmware Version | RO | The NBMC firmware version, as a null-padded UTF-8 string | 64 |
129+
| 0x01 | Hardware Version | RO | The NBMC firmware version, as a null-padded UTF-8 string | 64 |
130+
| 0x02 | Interrupt Status | R/W1C | Which interrupts are currently active, as a bitmask. | 2 |
131+
| 0x02 | Interrupt Control | R/W | Which interrupts are currently enabled, as a bitmask. | 2 |
132+
| 0x10 | UART Receive/Transmit Buffer | FIFO | Data received over the UART | max 64 |
133+
| 0x11 | UART FIFO Control | R/W | Settings for the UART FIFO | 1 |
134+
| 0x12 | UART Control | R/W | ... | 1 |
135+
| 0x13 | UART Status | R/W | ... | 1 |
136+
| 0x14 | UART Baud Rate | R/W | ... | 4 |
137+
| 0x20 | PS/2 Keyboard Receive/Transmit Buffer | FIFO | ... | max 16 |
138+
| 0x22 | PS/2 Keyboard Control | R/W | ... | 1 |
139+
| 0x23 | PS/2 Keyboard Status | R/W1C | ... | 1 |
140+
| 0x30 | PS/2 Mouse Receive/Transmit Buffer | FIFO | ... | max 16 |
141+
| 0x32 | PS/2 Mouse Control | R/W | ... | 1 |
142+
| 0x33 | PS/2 Mouse Status | R/W1C | ... | 1 |
143+
| 0x40 | LED Control | R/W | ... | 1 |
144+
| 0x41 | Button Status | RO | ... | 1 |
145+
146+
The register types are:
147+
148+
* `RO` - read only register, where writes will return an error
149+
* `R/W` - read/write register
150+
* `R/W1C` - when writing a 1 bit clears that bit position and a 0 bit is ignored, reads are as normal.
151+
* `FIFO` - a first-in, first-out buffer
152+
153+
## Build Requirements
154+
155+
1. rustup and Rust
156+
- see https://www.rust-lang.org
157+
2. The `thumbv6m-none-eabi` target
158+
- run `rustup target add thumbv6m-none-eabi`
159+
3. `probe-run`
160+
- run `cargo install probe-run` from your `$HOME` dir (not this folder!)
161+
4. `flip-link`
162+
- run `cargo install flip-link` from your `$HOME` dir (not this folder!)
163+
164+
Then to build and flash, connect a probe supported by probe-rs (such as a SEGGER J-Link, or an ST-Link) and run:
165+
166+
```
167+
$ cargo run --bin neotron-bmc --release
168+
```
169+
170+
## Licence
171+
172+
This code is licenced under the GNU Public Licence version 3. See:
173+
174+
* [The LICENSE file](./LICENSE)
175+
* [The GPL Website](http://www.gnu.org/licenses/gpl-3.0.html)
176+
177+
Our intent behind picking this licence is that you must ensure anyone who receives a programmed Neotron BMC processor, also receives:
178+
179+
* A note stating that the firmware is licenced under the GPL v3, and
180+
* Access to Complete and Corresponding Source Code (e.g. in the form of the URL of this repository, or the source repository the firmware was built from if not this one).
181+
182+
For the avoidance of doubt, it is not our intention to:
183+
184+
* prevent you from selling PCBs containing a programmed Neotron BMC processor, or
185+
* prevent you from making changes to the Neotron BMC source code.
186+
187+
It is however our intention to ensure that anyone who sells or distributes this firmware (or products that contain it):
188+
189+
* provides proper attribution, and
190+
* gives the customers/recipients access to the source code, including any changes that were made.
191+
192+
Note that this firmware image incorporates a number of third-party modules. You should review the output of `cargo tree` and ensure that any licence terms for those modules are upheld. You should also be aware that this application was based on the Knurling Template at https://github.com/knurling-rs/app-template.

build.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// This is the build-script for the Neotron BMC.
2+
///
3+
/// It just copies the memory.x file somewhere Cargo can fine it.
4+
use std::env;
5+
use std::fs::File;
6+
use std::io::Write;
7+
use std::path::PathBuf;
8+
9+
fn main() {
10+
// Put the linker script somewhere the linker can find it
11+
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
12+
File::create(out.join("memory.x"))
13+
.unwrap()
14+
.write_all(include_bytes!("memory.x"))
15+
.unwrap();
16+
println!("cargo:rustc-link-search={}", out.display());
17+
println!("cargo:rerun-if-changed=memory.x");
18+
}

memory.x

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
MEMORY
2+
{
3+
/* NOTE K = KiBi = 1024 bytes */
4+
FLASH : ORIGIN = 0x08000000, LENGTH = 16K
5+
RAM : ORIGIN = 0x20000000, LENGTH = 4K
6+
}
7+
8+
/* This is where the call stack will be allocated. */
9+
/* The stack is of the full descending type. */
10+
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
11+
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
12+

openocd.cfg

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This script assumes you have an ST-Link connected to the debug header on the Neotron BMC.
2+
3+
source [find interface/stlink.cfg]
4+
5+
transport select hla_swd
6+
7+
set WORKAREASIZE 0x2000
8+
source [find target/stm32f0x.cfg]
9+
10+
reset_config srst_only

0 commit comments

Comments
 (0)