Skip to content

Commit a0f52fc

Browse files
committed
Update README with details of I/O expansion.
Also has new STM32 pinout that is more portable.
1 parent 5301f93 commit a0f52fc

File tree

1 file changed

+100
-28
lines changed

1 file changed

+100
-28
lines changed

README.md

Lines changed: 100 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ The main processor module is the Raspberry Pi Pico, which features:
5252
* USB 2.0 Full-speed OTG micro-AB port
5353
* 4.00 USD / 3.60 GBP retail price
5454

55-
The limited I/O on the Pico (we are using half the available pins just for the video output) is supplemented using a Microchip MCP23S17 SPI to GPIO expander, an octal buffer. The buffer allows the Pico to send its SPI bus data to either the MCP23S17 (to set a specific Chip Select line), or the rest of the system. Without the buffer, it would be impossible to command the MCP23S17 to disable a chip-select line once it had been set, without the traffic also going to the selected expansion slot!
55+
The limited I/O on the Pico (we are using half the available pins just for the video output) is supplemented using a Microchip MCP23S17 SPI to GPIO expander, and an octal buffer. See the [I/O Expanders](#io-expanders) section for more details.
5656

5757
| Pin | Name | Signal | Function |
5858
| :--- | :--- | :------------- | :------------------------------------------------- |
@@ -133,33 +133,47 @@ Power-on Reset sequencing, soft shutdown, voltage monitoring and PS/2 interfacin
133133
* Runs from 3.3V stand-by regulator
134134
* I²C interface (with dedicated IRQ line) with main CPU
135135

136-
| Pin | Name | Signal | Function |
137-
| :--- | :--- | :------------ | :------------------------------------------------------ |
138-
| 14 | PB0 | - | Spare |
139-
| 15 | PB1 | - | Spare |
140-
| 26 | PB3 | - | Spare |
141-
| 27 | PB4 | PS2_CLK1 | Mouse Clock Input |
142-
| 28 | PB5 | PS2_DAT1 | Mouse Data Input |
143-
| 29 | PB6 | I2C_SCL | I²C Clock |
144-
| 30 | PB7 | I2C_SDA | I²C Data |
145-
| 2 | PF0 | - | Spare |
146-
| 3 | PF1 | - | Spare |
147-
| 6 | PA0 | MON_3V3 | 3.3V rail monitor Input (1.65V nominal) |
148-
| 7 | PA1 | MON_5V | 5.0V rail monitor Input (1.65V nominal) |
149-
| 8 | PA2 | UART_TX | UART Data Output |
150-
| 9 | PA3 | UART_RX | UART Data Input |
151-
| 10 | PA4 | /BUTTON_PWR | Power Button Input |
152-
| 11 | PA5 | STATUS_LED | Status LED Output |
153-
| 12 | PA6 | /BUTTON_RST | Reset Button Input |
154-
| 13 | PA7 | - | Spare |
155-
| 18 | PA8 | /IRQ | Interrupt Output |
156-
| 19 | PA9 | PS2_DAT0 | Keyboard Data Input |
157-
| 20 | PA10 | PS2_CLK0 | Keyboard Clock Input |
158-
| 21 | PA11 | /RESET | System Reset Output |
159-
| 22 | PA12 | DC_ON | PSU Enable Output |
160-
| 23 | PA13 | SWDIO | SWD Progamming Data Input |
161-
| 24 | PA14 | SWCLK_BOOT_TX | SWD Programming Clock Input OR Bootloader UART RX Input |
162-
| 25 | PA15 | BOOT_RX | Bootloader UART TX Output |
136+
| Pin | Name | Signal | Function |
137+
| :--- | :--- | :--------- | :------------------------------------------- |
138+
| 02 | PF0 | BUTTON_PWR | Power Button Input (active low) |
139+
| 03 | PF1 | HOST_RST | Reset Output to reset the rest of the system |
140+
| 06 | PA0 | MON_3V3 | 3.3V rail monitor Input (1.65V nominal) |
141+
| 07 | PA1 | MON_5V | 5.0V rail monitor Input (1.65V nominal) |
142+
| 08 | PA2 | LED0 | PWM output for first Status LED |
143+
| 09 | PA3 | LED1 | PWM output for second Status LED |
144+
| 10 | PA4 | SPI1_NSS | SPI Chip Select Input (active low) |
145+
| 11 | PA5 | SPI1_SCK | SPI Clock Input |
146+
| 12 | PA6 | SPI1_CIPO | SPI Data Output |
147+
| 13 | PA7 | SPI1_COPI | SPI Data Input |
148+
| 14 | PB0 | BUTTON_RST | Reset Button Input (active low) |
149+
| 15 | PB1 | DC_ON | PSU Enable Output |
150+
| 18 | PA8 | HOST_NIRQ | Interrupt Output to the Host (active low) |
151+
| 19 | PA9 | I2C1_SCL | I²C Clock |
152+
| 20 | PA10 | I2C1_SDA | I²C Data |
153+
| 21 | PA11 | USART1_CTS | UART Clear-to-Send Output |
154+
| 22 | PA12 | USART1_RTS | UART Ready-to-Receive Input |
155+
| 23 | PA13 | SWDIO | SWD Progamming Data Input |
156+
| 24 | PA14 | SWCLK | SWD Programming Clock Input |
157+
| 25 | PA15 | PS2_CLK0 | Keyboard Clock Input |
158+
| 26 | PB3 | PS2_CLK1 | Mouse Clock Input |
159+
| 27 | PB4 | PS2_DAT0 | Keyboard Data Input |
160+
| 28 | PB5 | PS2_DAT1 | Mouse Data Input |
161+
| 29 | PB6 | USART1_TX | UART Transmit Output |
162+
| 30 | PB7 | USART1_TX | UART Receive Input |
163+
164+
Note that in the above table, the UART signals are wired as _Data Terminal Equipment (DTE)_.
165+
166+
This design should also be pin-compatible with the following SoCs (although the software may need recompiling):
167+
168+
* STM32F042K4Tx
169+
* STM32F042K6Tx
170+
* STM32L071KBTx
171+
* STM32L071KZTx
172+
* STM32L072KZTx
173+
* STM32L081KZTx
174+
* STM32L082KZTx
175+
176+
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!
163177

164178
### PS/2 Keyboard and Mouse
165179

@@ -175,6 +189,64 @@ Power-on Reset sequencing, soft shutdown, voltage monitoring and PS/2 interfacin
175189
* 1A 3.3V regulator (a high-power 1117 type linear regulator)
176190
* Controlled by the Board Management Controller
177191

192+
### I/O Expanders
193+
194+
Because we used so many pins on the Pico for Audio and Video, we don't have enough pins to use for _Chip Select_ lines. Each device we wish to communicate with on the SPI bus must have a unique chip select line and so have limited lines means we could only have a limited number of SPI devices.
195+
196+
However, in this design, we cheat and use a Microchip MCP23S17 I/O expander. This is an SPI peripheral with 16 GPIO pins that can be controlled by sending it commands over SPI. It also has an IRQ output which be programmed to fire when the input pins match a certain state.
197+
198+
The problem would come when the Pico has finished talking to our select SPI device - how does it tell the MCP23S17 to release the current chip select, without the SPI bus traffic also going to the currently selected expansion slot? We resolve this by using a simple 8-bit buffer with an enable pin. This allows the Pico to disconnect all of the chip select signals at once, regardless of the output of the MCP23S17. Once this is disabled, we know we are talking to only the MCP23S17 and the Pico can command it to select the next chip select of interest to us.
199+
200+
Interrupts are also processed through the MCP23S17. We configure the device to provide an IRQ (edge, active low) whenever any of the eight IRQ inputs are active (programmable for edge or level, active high/rising or low/falling). When the Pico receives an IRQ from the MCP23S17, it must do a read of the pins (using SPI) to find out which device actually raised the interrupt. This model is similar to that used in the IBM PC - where the Intel 8088 must talk to an Intel 8259A programmable interrupt controller over the ISA bus to find out which interrupt was raised - except that in our case, our CPU is very fast and our bus is pretty slow, so our interrupt latency isn't very good. Worse, if there is a big SPI transaction happening (such as transferring a 512 byte block from an SD card) when an interrupt fires, the Pico will have to wait for that to complete before it can talk to the MCP23S17 to handle the IRQ. That or it could just drop the SPI transaction mid-way through and re-try it later (if your expansion device can tolerate such rudeness).
201+
202+
```
203+
+------+ +-----+
204+
| |----------BUFFER_EN-------------->| |
205+
| | | |
206+
| | +----------+ | |
207+
| | | | | |
208+
| | | |----CS0--->| |----CS0----------------------------------+
209+
| | | | | | |
210+
| | | |----CS1--->| B |----CS1------------------------------+ |
211+
| | | | | U | | |
212+
| | | |----CS2--->| F |----CS2--------------------------+ | |
213+
| | | | | F | | | |
214+
| | | |----CS3--->| E |----CS3----------------------+ | | |
215+
| | | | | R | | | | |
216+
| | | |----CS4--->| |----CS4------------------+ | | | |
217+
| | | | | | | | | | |
218+
| | | |----CS5--->| |----CS5--------------+ | | | | |
219+
| | | | | | | | | | | |
220+
| | | |----CS6--->| |----CS6----------+ | | | | | |
221+
| Pico | | MCP23S17 | | | | | | | | | |
222+
| | | |----CS7--->| |----CS7------+ | | | | | | |
223+
| | | | +-----+ v v v v v v v v
224+
| | | | +---+---+---+---+---+---+---+---+
225+
| |----CS---->| | | S | S | S | S | S | S | S | S |
226+
| |<---IRQ----| | | l | l | l | l | l | l | l | l |
227+
| |<===SPI===>| |<============SPI============>| o | o | o | o | o | o | o | o |
228+
| | | | | t | t | t | t | t | t | t | t |
229+
| | | | | | | | | | | | |
230+
| | | | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
231+
| | | | +---+---+---+---+---+---+---+---+
232+
| | | |<---IRQ7-----------------------+ | | | | | | |
233+
| | | | | | | | | | |
234+
| | | |<---IRQ6---------------------------+ | | | | | |
235+
| | | | | | | | | |
236+
| | | |<---IRQ5-------------------------------+ | | | | |
237+
| | | | | | | | |
238+
| | | |<---IRQ4-----------------------------------+ | | | |
239+
| | | | | | | |
240+
| | | |<---IRQ3---------------------------------------+ | | |
241+
| | | | | | |
242+
| | | |<---IRQ2-------------------------------------------+ | |
243+
| | | | | |
244+
| | | |<---IRQ1-----------------------------------------------+ |
245+
| | | | |
246+
| | | |<---IRQ0---------------------------------------------------+
247+
+------+ +----------+
248+
```
249+
178250
## Expansion
179251

180252
The seven expansion sockets allow you to add on I²C or SPI based devices at a later date. Each provides a single chip-select and a single IRQ line - the motherboard design should ensure each socket gets a unique signal for each of these. Each expansion device should also contain a AT24C256 or similar EEPROM device. To allow these EEPROM devices to be scanned, each slot also contains three `EEPROM_ADDRESS` pins, tied to Vcc or GND in a unique combination. These should be connected through to the EEPROM address lines on your AT24C256, thus ensuring that each expansion card has its EEPROM at a unique address - 0x50 on Slot 0 through to a maximum possible 0x57 for Slot 7. Where your board has on-board devices, you should fit an AT24C256 EEPROM for each device so that the on-board devices can be discovered, exactly as if they were on an expansion card.

0 commit comments

Comments
 (0)