Custom embedded RF platform for the 868 MHz ISM band
IRIS-868 is a custom embedded RF platform based on the STM32F303RET6 microcontroller and an Ebyte E22-900M22S (Semtech SX1262) sub-GHz LoRa module, designed for 868 MHz ISM-band wireless communication and data logging.
| π§ MCU | STM32F303RET6 Β· Cortex-M4F @ 72 MHz Β· 512 KB flash Β· 64 + 16 KB RAM |
| π» Radio | Ebyte E22-900M22S Β· SX1262 Β· +22 dBm Β· LoRa / (G)FSK |
| πΎ Storage | Winbond W25Q128JV Β· 128 Mbit (16 MiB) SPI NOR flash for data logging |
| π Power | USB micro-B β AP2112K-3.3 LDO, filtered analog and RF rails, VBUS voltage monitoring on the ADC |
| π§© Expansion | 2 Γ 12-pin edge headers Β· IΒ²C header for 128Γ64 OLED Β· 5-pin SWD with NRST Β· BOOT0 jumper Β· user button |
| π Board | 2-layer FR4 Β· 78.8 Γ 36.6 mm Β· green mask, white silk Β· components on both sides |
| π οΈ Tooling | KiCad 10, footprints and symbols embedded in the project files |
Warning
Revision B is design-complete but has not been bring-up tested. Fabrication files are released as-is. No firmware is included in this repository yet.
- What's new in revision B
- Gallery
- System architecture
- Repository layout
- Hardware overview
- Pin assignment
- Board specification
- Bill of materials
- Getting started
- Releases
| Area | Revision A | Revision B |
|---|---|---|
| Expansion | Most GPIOs unrouted | Two 1Γ12 edge headers (J5, J7) bring out power, reset, BOOT0, USART1 and 13 GPIOs |
| Debug | 4-pin SWD, no NRST | 5-pin SWD with NRST β "connect under reset" now works |
| Storage | β | 16 MiB W25Q128JV SPI flash on SPI3 (bottom side) |
| User input | Reset button only | Additional user button on PC13 with RC debounce |
| Monitoring | β | VBUS divider (47 kΞ© / 15 kΞ©) on PC0 for USB voltage measurement |
| USB | D+ pull-up fixed to +3.3 V | D+ pull-up driven by PB8 β firmware-controlled attach/detach |
| Radio | E220-900M22S (LLCC68) | E22-900M22S (SX1262), same MCU connections |
| Boot | BOOT0 floats with no jumper | 100 kΞ© pull-down (R13), boots from flash with no jumper |
| Board | 74.2 Γ 32.0 mm, single-sided assembly | 78.8 Γ 36.6 mm, bottom-side SMD parts and headers |
A design review before release added these changes:
- RF feed: the antenna trace no longer runs under the module, and J6 moved to suit (see RF chain).
- Decoupling: C10 now sits next to the NRST pin, and C8 next to the VDDA pin.
- Clean-up: the unused test pad under IC1 was removed.
- Fabrication: design constraints follow JLCPCB's limits, with a green mask so the solder dams between LQFP pins can be kept.
π Full schematic: docs/schematics/IRIS-868.pdf
flowchart LR
USB["USB micro-B<br/>J2"] -->|VBUS 5 V| LDO["AP2112K-3.3<br/>600 mA LDO"]
USB -.->|"D+ / D-"| ESD["USBLC6-2SC6<br/>ESD"]
ESD -.-> MCU
USB -->|"VBUS Γ· 4.13"| VMON["V_MON<br/>PC0 / ADC"]
VMON --> MCU
LDO --> RAIL(("3.3 V"))
RAIL -->|"FB1 120 Ξ©"| VDDA["+3.3VA"]
RAIL -->|"FB2 120 Ξ©"| VRF["VRF"]
RAIL --> MCU
VDDA --> MCU
VRF --> MOD
MCU["STM32F303RET6<br/>Cortex-M4F @ 72 MHz"]
MCU <-->|"SPI1 Β· NSS Β· BUSY Β· DIO1 Β· NRST"| MOD["E22-900M22S<br/>SX1262 Β· +22 dBm"]
MCU -->|"RXEN / TXEN"| MOD
MOD -->|ANT| SMA["SMA edge<br/>J6"]
MCU <-->|"SPI3 Β· CS"| FLASH["W25Q128JV<br/>16 MiB flash"]
MCU <-->|"IΒ²C1"| OLED["128Γ64 OLED<br/>header"]
MCU <-->|"SWD + NRST"| DBG["ST-Link<br/>J3"]
MCU <-->|"GPIO Β· USART1"| HDR["Edge headers<br/>J5 / J7"]
BTN["User button<br/>PC13"] --> MCU
MCU -.->|BOOT0| JMP["Boot jumper"]
style MCU fill:#03234B,color:#fff
style MOD fill:#2ea44f,color:#fff
style FLASH fill:#8e44ad,color:#fff
style RAIL fill:#f39c12,color:#fff
IRIS-868/
βββ CHANGELOG.md Release history
βββ hardware/
β βββ kicad/ KiCad 10 project (schematic, PCB, design rules)
β β βββ libs/ Source symbols, footprints, 3D models
β βββ gerbers/
β βββ rev.A/ Gerber and Excellon files, revision A
β βββ rev.B/ Gerber and Excellon files, revision B
βββ production/BOM/ Interactive BOM for assembly
βββ docs/
βββ schematics/ Schematic PDF
βββ images/ Board renders by revision
βββ datasheets/ Component reference documents
The schematic uses four top-level sheets, a KiCad 10 feature: MCU, crystal, reset, VBUS monitor and edge headers (IRIS-868.kicad_sch), power and USB (pwr.kicad_sch), the radio (rf.kicad_sch), and connectors, flash and the user button (interfaces.kicad_sch).
USB VBUS feeds an AP2112K-3.3 LDO (SOT-23-5, 600 mA) that generates the single 3.3 V system rail. Three domains branch from it:
| Rail | Source | Decoupling | Purpose |
|---|---|---|---|
+3.3V |
LDO output | 10 Β΅F + 7 Γ 100 nF + 2 Γ 1 Β΅F | MCU digital, I/O, flash, headers |
+3.3VA |
via FB1 (120 Ξ© ferrite) | 1 Β΅F + 10 nF | STM32 VDDA / analog reference |
VRF |
via FB2 (120 Ξ© ferrite) | 22 Β΅F + 1 Β΅F + 2 Γ 100 nF | RF module supply |
The ferrite beads isolate the analog and RF domains from digital switching noise on the main rail, and C7 and C8 sit next to the VDDA pin. The 22 Β΅F bulk capacitor on VRF supplies the current burst drawn by the module during transmission.
VBUS and +3.3 V are both available on header J5, so the board can supply a small carrier or add-on board.
A 47 kΞ© / 15 kΞ© divider (R6 / R7) scales VBUS onto V_MON (PC0, ADC12_IN6), filtered by C20 (100 nF). The divider ratio is 15 / 62, so 5.0 V on VBUS reads as about 1.21 V, and firmware recovers VBUS as V_MON Γ 4.133. The divider draws roughly 80 Β΅A from VBUS, and its ~11 kΞ© source impedance combined with C20 gives a stable input for the ADC sample-and-hold.
The E22-900M22S connects to the MCU over SPI1 plus four control lines. RXEN and TXEN drive the module's internal RF switch and must be managed by firmware around every transmit/receive transition. The antenna net (ANT) leaves the module's stamp-hole RF pad away from the module body and reaches the SMA edge connector as a 7.4 mm, 1.0 mm-wide coplanar trace on F.Cu, over an unbroken ground plane on B.Cu. A project design rule sets a 0.15 mm gap to the surrounding copper, which gives a calculated impedance of about 50 Ξ© with a 1.51 mm dielectric and Ξ΅r 4.5. GND vias flank the feed.
A Winbond W25Q128JVSIQ (SOIC-8, 208 mil) on the bottom side provides 16 MiB of non-volatile storage on SPI3 (PC10 / PC11 / PC12) with chip select on PD2. The CS line has a 10 kΞ© pull-up (R8) so the flash stays deselected while the MCU is in reset. /WP and /HOLD are tied high through R9 and R10, so the device operates in standard single-bit SPI mode; dual/quad I/O is not available on this revision. C21 decouples the flash locally.
| Button | Net | Circuit |
|---|---|---|
| SW1 (RST) | NRST (pin 7) | Pulls NRST low. 100 nF (C10) sits next to the pin on the bottom side. NRST is also on the SWD header and J5 |
| SW2 (PC13) | PC13 (pin 2) | Active-low. 10 kΞ© pull-up (R11), 10 kΞ© series (R12), 100 nF (C22) to GND β about 1 ms fall / 2 ms rise debounce |
The USB D+ 1.5 kΞ© pull-up (R2) is connected to PB8 rather than to +3.3 V. Firmware must drive PB8 high to signal device attach to the host, and can drive it low to force a clean disconnect/re-enumeration without unplugging the cable.
| Connector | Type | Pinout |
|---|---|---|
| J2 USB | micro-B | USB FS device on PA11/PA12, D+ pull-up switched by PB8, ESD-protected |
| J3 SWD | 1Γ5 @ 2.54 mm | GND Β· NRST Β· SWCLK Β· SWDIO Β· +3.3V |
| J1 (BOOT0) | 1Γ3 @ 2.54 mm | GND Β· BOOT0 Β· +3.3V β no jumper or 1β2 = flash, 2β3 = bootloader |
| J4 (OLED) | 1Γ4 @ 2.54 mm | GND Β· +3.3V Β· SCL Β· SDA (1.5 kΞ© pull-ups on board) |
| J5 | 1Γ12 @ 2.54 mm, bottom-mounted | Power, reset, BOOT0, USART1, GPIO β see below |
| J7 | 1Γ12 @ 2.54 mm, bottom-mounted | GPIO β see below |
| J6 SMA | edge-mount | Antenna |
J5 and J7 run along the long edges of the board with a row-to-row spacing of 31.75 mm (1.25 in). The header bodies are mounted on the bottom side, so the board can be plugged into a carrier with the components facing up. Pin 1 of each header is at the USB end.
| Pin | J5 | J7 |
|---|---|---|
| 1 | GND |
PB9 |
| 2 | +3.3V |
GND |
| 3 | VBUS (5 V) |
PB0 |
| 4 | NRST |
PB1 |
| 5 | BOOT0 |
PC4 |
| 6 | PA9 (USART1_TX) |
PC5 |
| 7 | PA10 (USART1_RX) |
PC6 |
| 8 | GND |
PC7 |
| 9 | PB4 |
PC8 |
| 10 | PB5 |
GND |
| 11 | PB6 |
not connected |
| 12 | PB8 |
not connected |
| STM32 pin | Signal | Module pin | Direction | Function |
|---|---|---|---|---|
PA5 |
SPI1_SCK | 18 (SCK) | β | SPI clock |
PA6 |
SPI1_MISO | 16 (MISO) | β | SPI data out |
PA7 |
SPI1_MOSI | 17 (MOSI) | β | SPI data in |
PA4 |
NSS | 19 (NSS) | β | Chip select, active low |
PA3 |
NRST | 15 (NRST) | β | Module reset, active low |
PA2 |
BUSY | 14 (BUSY) | β | Transceiver busy status |
PA8 |
DIO1 | 13 (DIO1) | β | Primary interrupt line |
PB10 |
RXEN | 6 (RXEN) | β | RF switch, receive enable |
PB11 |
TXEN | 7 (TXEN) | β | RF switch, transmit enable |
Module pin 8 (DIO2) is left unconnected in revision B.
| STM32 pin | Signal | Flash pin | Direction |
|---|---|---|---|
PC10 |
SPI3_SCK | 6 (CLK) | β |
PC11 |
SPI3_MISO | 2 (DO) | β |
PC12 |
SPI3_MOSI | 5 (DI) | β |
PD2 |
FLASH_CS | 1 (/CS) | β |
Other pin assignments
| STM32 pin | Function |
|---|---|
PA11 / PA12 |
USB Dβ / D+ |
PB8 |
USB D+ pull-up control (also on J5 pin 12) |
PA13 / PA14 |
SWDIO / SWCLK |
PA15 |
IΒ²C1 SCL (AF4) |
PB7 |
IΒ²C1 SDA (AF4) |
PC0 |
V_MON β VBUS voltage divider (ADC) |
PC13 |
User button, active low |
PF0 / PF1 |
16 MHz crystal (OSC_IN / OSC_OUT) |
NRST (pin 7) |
Reset button + 100 nF, SWD header, J5 |
BOOT0 (pin 60) |
J1 via 10 kΞ© (R1), 100 kΞ© pull-down (R13), J5 (direct) |
PA9, PA10, PB4βPB6 |
J5 |
PB0, PB1, PB9, PC4βPC8 |
J7 |
The remaining GPIOs β PA0, PA1, PB2, PB3, PB12βPB15, PC1βPC3, PC9, PC14, PC15 β are not routed in revision B.
| Parameter | Value |
|---|---|
| Dimensions | 78.8 Γ 36.6 mm, 2 mm corner radius |
| Layers | 2 (F.Cu / B.Cu), GND pour on both |
| Stackup | 1.6 mm FR4, 35 Β΅m copper, Ξ΅r 4.5 |
| Finish | HASL, green solder mask, white silkscreen |
| Vias | 327, 0.6 mm with 0.3 mm drill, tented |
| Minimum rules | Track 0.15 mm, clearance 0.2 mm, annular ring 0.13 mm, hole-to-hole 0.5 mm, copper-to-edge 0.2 mm |
| Assembly | Double-sided (U4, R8βR10, R13, C10, C21 and header bodies on the bottom) |
| Special rules | 0.15 mm clearance on the ANT coplanar feedline |
Full BOM β 53 components
| Ref | Qty | Value | Package | Notes |
|---|---|---|---|---|
| U1 | 1 | STM32F303RET6 | LQFP-64 | 0.5 mm pitch |
| U2 | 1 | AP2112K-3.3 | SOT-23-5 | 600 mA LDO |
| U3 | 1 | USBLC6-2SC6 | SOT-23-6 | USB ESD protection |
| U4 | 1 | W25Q128JVSIQ | SOIC-8 5.3 Γ 5.3 mm | 128 Mbit SPI flash, bottom side |
| IC1 | 1 | E22-900M22S | Ebyte SMD module | SX1262, +22 dBm |
| Y1 | 1 | 16 MHz | 3225-4pin | CL β 10 pF, β€20 ppm recommended |
| C1βC5, C10, C16, C17, C19, C21 | 10 | 100 nF | 0402 | 16 V X7R β C10 and C21 on bottom side |
| C20, C22 | 2 | 100 nF | 0805 | 16 V X7R β V_MON filter, PC13 debounce |
| C8, C9, C14, C15 | 4 | 1 Β΅F | 0402 | 16 V X5R/X7R |
| C13 | 1 | 1 Β΅F | 0402 | 25 V β sits on the 5 V VBUS rail |
| C6 | 1 | 10 Β΅F | 0603 | 16 V X5R |
| C18 | 1 | 22 Β΅F | 0805 | 16 V X5R, RF bulk |
| C7 | 1 | 10 nF | 0402 | 16 V X7R, VDDA filter |
| C11, C12 | 2 | 12 pF | 0402 | 50 V C0G/NP0 Β±5%, crystal load |
| R1 | 1 | 10 kΞ© | 0402 | BOOT0 series |
| R2 | 1 | 1.5 kΞ© | 0402 | USB D+ pull-up (to PB8) |
| R3 | 1 | 1.5 kΞ© | 0402 | Power LED series |
| R4, R5 | 2 | 1.5 kΞ© | 0402 | IΒ²C pull-ups |
| R6 | 1 | 47 kΞ© | 0402 | VBUS divider, top β 1% recommended |
| R7 | 1 | 15 kΞ© | 0402 | VBUS divider, bottom β 1% recommended |
| R8, R9, R10 | 3 | 10 kΞ© | 0402 | Flash /CS, /WP, /HOLD pull-ups, bottom side |
| R11, R12 | 2 | 10 kΞ© | 0402 | PC13 button pull-up / series |
| R13 | 1 | 100 kΞ© | 0402 | BOOT0 pull-down, bottom side |
| FB1, FB2 | 2 | 120 Ξ© @ 100 MHz | 0402 | Analog / RF rail filtering, rated β₯ 500 mA |
| D1 | 1 | Red LED | 0603 | Power indicator |
| SW1, SW2 | 2 | Tactile switch | 6 mm THT | 4-pin, 4.5 Γ 6.5 mm, marked RST and PC13 |
| J1 | 1 | Pin header 1Γ3 | 2.54 mm | BOOT0 select, marked BOOT0 |
| J2 | 1 | USB micro-B | WΓΌrth 629105150521 | |
| J3 | 1 | Pin header 1Γ5 | 2.54 mm | SWD + NRST |
| J4 | 1 | Pin header 1Γ4 | 2.54 mm | IΒ²C / OLED, marked OLED |
| J5, J7 | 2 | Pin header 1Γ12 | 2.54 mm | Edge headers, bottom side |
| J6 | 1 | SMA edge-mount | RF Solutions CON-SMA-EDGE-S |
For assembly, open the interactive BOM after downloading it.
Tip
Capacitor voltage ratings account for MLCC DC bias derating β class II ceramics lose a large fraction of their nominal capacitance near their rated voltage, so ratings are specified at roughly 4β5Γ the working voltage. A 2.54 mm jumper shunt on J1 is needed only to enter the bootloader, and it isn't part of the PCB BOM.
1 Β· Fabricate the board
Fabrication files for revision B are in hardware/gerbers/rev.B/, as Gerber and Excellon drill files. A ready-to-upload zip is attached to the v2.0.0 release.
- Process: standard 2-layer, 1.6 mm FR4, 1 oz copper, HASL or ENIG, green mask
- No controlled impedance is specified
- Revision B has SMD parts on both sides. If using assembly service, request double-sided assembly or have the bottom-side parts (U4, R8βR10, R13, C10, C21) left unpopulated and fit them by hand
- Suggested hand-assembly order: bottom-side SMD parts first, then the STM32 (drag solder, then inspect with flux and a loupe), then the remaining ICs, then passives, then the module, then through-hole parts last β edge headers J5/J7 go in from the bottom
2 Β· Open the design
The project requires KiCad 10 or later, because it uses multiple top-level sheets. Symbols and footprints are embedded in the project files, so it opens without any library setup. Sources for the non-standard parts (E22 module, SMA edge connector) and the 3D models are under hardware/kicad/libs/. DRC reports one library warning on J6, because its source library is not registered in the project.
git clone https://github.com/StringLess80/IRIS-868.git
cd IRIS-868
kicad hardware/kicad/IRIS-868.kicad_pro3 Β· Program it
Via SWD (recommended) β connect an ST-Link or any CMSIS-DAP probe to J3, including the NRST line. Because NRST is on the header, "connect under reset" works, so a board with firmware that disables SWD or enters low-power mode early can still be recovered from the debugger.
st-flash --reset write firmware.bin 0x08000000Via UART bootloader β connect a 3.3 V USB-serial adapter to J5 (PA9 = MCU TX, PA10 = MCU RX, GND), fit the J1 jumper on pins 2β3 and reset:
stm32flash -w firmware.bin -v -g 0x0 /dev/ttyUSB0Via USB DFU β the ROM bootloader does not drive PB8, so the D+ pull-up is inactive and the host will not see the device. Tie J5 pin 12 (PB8) to J5 pin 2 (+3.3V) for the duration of the DFU session, fit the J1 jumper on pins 2β3, reset, then:
dfu-util -a 0 -s 0x08000000:leave -D firmware.bin[!CAUTION] Remove the PB8 link before running application firmware β if firmware drives PB8 low while it is tied to +3.3 V, the pin is shorted.
Remove the jumper, or move it to pins 1β2, and reset to run from flash.
| Version | Hardware | Status |
|---|---|---|
v2.0.0 |
Revision B | Released for fabrication, not bring-up tested |
v1.0.0 |
Revision A | Superseded |
The major version changes with each PCB revision. Minor and patch versions cover compatible changes to the BOM, documentation or fabrication outputs. See the changelog for details.
Made with KiCad π οΈ

