You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -4,7 +4,7 @@ Firmware for the Neotron Board Management Controller (NBMC).
4
4
5
5
## Introduction
6
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.
7
+
The NBMC 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
8
9
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
10
@@ -71,66 +71,91 @@ This design should also be pin-compatible with the following SoCs (although this
71
71
72
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
73
74
-
## Communications Protocol - SPI Frames
74
+
## SPI Communications Protocol
75
75
76
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
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.
78
+
To communicate with the NBMC, the Host Processor must first take the Chip Select line (`SPI1_nCS`) low, then send a Header. SPI is a full-duplex system, but in this system only one side is actually transferring useful data at any time, so whilst the Header is being sent the Host will receive Padding Bytes in return (which can be discarded).
79
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.
80
+
A Header specifies which direction the transfer is occurring (a read or a write), which register address is being access, and how many bytes are being transferred.
After the Header comes the Payload, and the Response Code. The Host must clock out the number of bytes specified in the header, plus one extra (for the response code). If the Host is performing a write, it must supply the data to be written (plus one padding byte for the response code). If the Host is performing a read, it must supply only padding bytes (which will be discarded), and it will receive the desired bytes in exchange, plus the response code.
83
+
84
+
The Host must leave at least (*TODO*) XXX microseconds between a Header Packet and a Payload Packet in order for the NBMC to construct and prepare the Payload.
89
85
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.
86
+
Once the Header, Payload and Response Code have been exchange, the Host may send another Header, or it may raise the Chip Select line to indicate that the transfers are complete.
91
87
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.
88
+
A 'write' exchange looks like this:
93
89
94
-
## Communications Protocol - Commands and Responses
90
+
```
91
+
Host NBMC
92
+
| |
93
+
|-------Header (2)---->|
94
+
|<-----Padding-(2)-----|
95
+
| |
96
+
|------Payload-(N)---->|
97
+
|<-----Padding-(N)-----|
98
+
| |
99
+
|------Padding-(1)---->|
100
+
|<--Response Code-(1)--|
101
+
```
95
102
96
-
### Table of Commands
103
+
A 'read' exchange looks like this:
97
104
98
-
| Command Byte | Name |
99
-
| ------------ | ----- |
100
-
| 0x00 | PING |
101
-
| 0x01 | READ |
102
-
| 0x02 | WRITE |
105
+
```
106
+
Host NBMC
107
+
| |
108
+
|-------Header (2)---->|
109
+
|<-----Padding-(2)-----|
110
+
| |
111
+
|------Padding-(N)---->|
112
+
|<-----Payload-(N)-----|
113
+
| |
114
+
|------Padding-(1)---->|
115
+
|<--Response Code-(1)--|
116
+
```
103
117
104
-
### Table of Responses
118
+
A Header is comprised of 16 bits (or two bytes), and is described in the following table.
105
119
106
-
|Response Byte |Name|
107
-
| -------------|--------------- |
108
-
|0x80| OK |
109
-
|0x81| Unknown Command|
110
-
|0xFF| Busy |
120
+
| Byte |Bits | Meaning |
121
+
| ----|----|------------------------------ |
122
+
|0| 7| Direction: 1 = read, 0 = write|
123
+
|0| 6-0 | Register Address (0..128) |
124
+
|1| 7-0 | Transfer Length (0..255)|
111
125
112
-
### PING Command
126
+
Note that a *Transfer Length* of 0 is interpreted as being 256 bytes, rather than zero bytes (because that wouldn't make any sense - you can't request to transfer nothing).
113
127
114
-
This command just checks the NBMC is awake. There is no payload. A OK response is sent in return.
128
+
Here are some example headers:
115
129
116
-
### READ Command
130
+
*`0x8520` is a Read from Register Address 5 (0x05), of length 33 bytes.
131
+
*`0x9700` is a Read from Register Address 23 (0x17), of length 256 bytes.
132
+
*`0x7FFF` is a Write from Register Address 127 (0x7F), of length 255 bytes.
117
133
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.
134
+
A Payload is simply the number of desired data bytes (as specified in the Header Packet). The meaning of these bytes will depend on the Register Address that was given in the Header.
119
135
120
-
### WRITE Command
136
+
The possible values of the 'Response Code' byte are:
121
137
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.
| 0x00 | Firmware Version | RO | The NBMC firmware version, as a null-padded UTF-8 string | 64 |
129
150
| 0x01 | Interrupt Status | R/W1C | Which interrupts are currently active, as a bitmask. | 2 |
130
151
| 0x02 | Interrupt Control | R/W | Which interrupts are currently enabled, as a bitmask. | 2 |
131
-
| 0x03 | LED Control | R/W | Settings for the LED outputs | 1 |
132
-
| 0x04 | Button Status | RO | The current state of the buttons | 1 |
133
-
| 0x05 | System Temperature | RO | Temperature in °C, as an `i8`| 1 |
152
+
| 0x03 | LED 0 Control | R/W | Settings for the LED 0 output | 1 |
153
+
| 0x04 | LED 1 Control | R/W | Settings for the LED 1 output | 1 |
154
+
| 0x05 | Button Status | RO | The current state of the buttons | 1 |
155
+
| 0x06 | System Temperature | RO | Temperature in °C, as an `i8`| 1 |
156
+
| 0x07 | System Voltage (3.3V rail) | RO | Voltage in Volts/32, as a `u8`| 1 |
157
+
| 0x08 | System Voltage (5.0V rail) | RO | Voltage in Volts/32, as a `u8`| 1 |
158
+
| 0x09 | Power Control | RW | Enable/disable the power supply | 1 |
134
159
| 0x10 | UART Receive/Transmit Buffer | FIFO | Data received/to be sent over the UART | max 64 |
135
160
| 0x11 | UART FIFO Control | R/W | Settings for the UART FIFO | 1 |
136
161
| 0x12 | UART Control | R/W | Settings for the UART | 1 |
@@ -161,6 +186,164 @@ This read-only register returns the firmware version of the NBMC, as a UTF-8 str
161
186
162
187
An official release will have a version string of the form `tags/v1.2.3`. An unofficial release might be `heads/develop-dirty`. It is not recommended that you rely on these formats or attempt to parse the version string. It is however useful if you can quote this string when reporting issues with the firmware.
163
188
189
+
### Address 0x01 - Interrupt Status
190
+
191
+
This eight bit register indicates which Interrupts are currently 'active'. An Interrupt will remain 'active' until a word is written to this register with a 1 bit in the relevant position.
192
+
193
+
| Bit | Interrupt |
194
+
| --- | -------------------------- |
195
+
| 7 | Voltage Alarm |
196
+
| 6 | Button State Change |
197
+
| 5 | UART TX Empty |
198
+
| 4 | UART RX Not Empty |
199
+
| 3 | I²C TX Empty |
200
+
| 2 | I²C RX Not Empty |
201
+
| 1 | PS/2 Mouse RX Not Empty |
202
+
| 0 | PS/2 Keyboard RX Not Empty |
203
+
204
+
### Address 0x02 - Interrupt Control
205
+
206
+
This eight bit register indicates which Interrupts are currently 'enabled'. The IRQ_nHOST signal is a level interrupt and it will be active (LOW) whenever the value in the Interrupt Control register ANDed with the Interrupt Status register is non-zero.
207
+
208
+
The bits have the same ordering as the Interrupt Status register.
209
+
210
+
### Address 0x03 - LED 0 Control
211
+
212
+
This eight-bit register controls the LED 0 attached to the NBMC
One-shot mode means that if the LED is set to 'on', it will automatically set itself to 'off' after the specified period. This can be useful for creating activity indicators - you could set an LED to 'one-shot' and set it 'on' whenever disk activity occurs, knowing that it will turn off automatically soon after if there is no further activity. Writing a value to this register whilst a one-shot is in progress will cancel the existing one-shot and start a new one (if the new value indicates it should do so).
221
+
222
+
A Blink Ratio of 90/10, means that the LED will be on for 10% of the given cycle duration, and off for the other 90%.
223
+
224
+
A Blink Ratio of 50/50, means that the LED will be on for 50% of the given cycle duration, and off for the other 50%.
225
+
226
+
The Cycle Duration is the total time of an LED Cycle or, in one-shot mode, the timeout after which the LED sets itself to off. Note that because '0 ms' doesn't make sense, we take a value of zero in this register to be a value of 16 (i.e. 1600ms).
227
+
228
+
#### Example 1
229
+
230
+
* LED Cycle Duration = 5 (500ms)
231
+
* LED Blink Ratio = 2 (50/50)
232
+
* LED Enabled = 1 (on)
233
+
234
+
The LED will blink twice a second, 250ms at a time.
235
+
236
+
#### Example 2
237
+
238
+
* LED Cycle Duration = 2 (200ms)
239
+
* LED Blink Ratio = 1 (10/90)
240
+
* LED Enabled = 1 (on)
241
+
242
+
The LED will blink five times a second, 20ms at a time.
243
+
244
+
### Address 0x04 - LED 1 Control
245
+
246
+
See *Address 0x03 - LED 0 Control*
247
+
248
+
### Address 0x05 - Button Status
249
+
250
+
This eight-bit register indicates the state of the power button.
251
+
252
+
Note that if the power button is held down for three seconds, the system will power-off instantly, regardless of what the host does.
253
+
254
+
Note also that is it not possible to sample the reset button - pressing the reset button will instantly assert the system reset line, rebooting the Host.
255
+
256
+
| Bits | Meaning |
257
+
| ---- | ------------------------------------- |
258
+
| 7-1 | Reserved for future use |
259
+
| 0 | Power Button: 0 = normal, 1 = pressed |
260
+
261
+
### Address 0x06 - System Temperature
262
+
263
+
This eight-bit register provides the current system temperature in °C, as measured on the STM32's internal temperature sensor. It is updated around once a second.
264
+
265
+
### Address 0x07 - System Voltage (3.3V rail)
266
+
267
+
This eight-bit register provides the current 3.3V rail voltage in units of 1/32 of a Volt. It is updated around once a second. A value of 105 (3.28V) to 106 (3.31V) is nominal. An interrupt is raised when the value exceeds 3.63V (116) or is lower than 2.97V (95).
268
+
269
+
### Address 0x08 - System Voltage (5.0V rail)
270
+
271
+
This eight-bit register provides the current 3.3V rail voltage in units of 1/32 of a Volt. It is updated around once a second. A value of 160 (5.00V) is nominal. An interrupt is raised when the value exceeds 5.5V (176) or is lower than 4.5V (144).
272
+
273
+
### Address 0x09 - Power Control
274
+
275
+
This eight-bit register controls the main DC/DC power supply unit. The Host should disable the DC/DC supply (by writing zero here) if it wishes to power down.
0 commit comments