Claude
Skills
Sign in
Back

aeris10-plfm-radar

Included with Lifetime
$97 forever

```markdown

Writing & Docs

What this skill does

```markdown
---
name: aeris10-plfm-radar
description: Open-source 10.5 GHz Pulse Linear Frequency Modulated phased array radar system (AERIS-10) with FPGA signal processing, STM32 control, and Python GUI
triggers:
  - "set up AERIS-10 radar"
  - "configure PLFM radar firmware"
  - "radar beamforming phased array"
  - "FPGA radar signal processing"
  - "STM32 radar control firmware"
  - "pulse compression doppler radar"
  - "ADAR1000 phase shifter configuration"
  - "radar chirp waveform generation"
---

# AERIS-10 PLFM Phased Array Radar

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

AERIS-10 is an open-source 10.5 GHz Pulse Linear Frequency Modulated (PLFM) phased array radar. It comes in two versions: **AERIS-10N (Nexus)** with 3 km range using an 8×16 patch antenna array, and **AERIS-10E (Extended)** with 20 km range using a 32×16 slotted waveguide array and 10 W GaN amplifiers. The system uses an XC7A100T FPGA for signal processing, an STM32F746xx MCU for system management, and a Python GUI for visualization.

---

## Repository Structure

```
PLFM_RADAR/
├── 4_Schematics and Boards Layout/
│   └── 4_7_Production Files/   # Gerber files, BOM
├── 9_Firmware/
│   ├── 9_1_FPGA/               # VHDL/Verilog (Vivado project)
│   ├── 9_2_STM32/              # STM32F746 C firmware
│   └── 9_3_GUI/                # Python GUI
├── 10_docs/
│   ├── assembly_guide.md
│   └── Hardware/Enclosure/     # 3D printable files
└── 8_Utils/                    # Images, utilities
```

---

## Hardware Overview

| Subsystem | Key ICs |
|---|---|
| Clock distribution | AD9523-1 |
| TX/RX frequency synthesis | ADF4382 |
| Chirp generation | High-speed DAC |
| Phase shifting (beamforming) | ADAR1000 (4× 4-ch) |
| Front-end LNA/PA | ADTR1107 (16×) |
| Extended-range PA | QPA2962 GaN (16× 10 W) |
| FPGA | Xilinx XC7A100T (Artix-7) |
| MCU | STM32F746xx |
| ADC (power monitoring) | ADS7830 |
| DAC (bias control) | DAC5578 |

---

## Getting Started

### Prerequisites

```bash
# Python GUI
python --version   # 3.8+ required

# FPGA toolchain
# Install Xilinx Vivado (2022.x or later recommended)
# https://www.xilinx.com/support/download.html

# STM32 firmware
# Install STM32CubeIDE or arm-none-eabi-gcc toolchain
arm-none-eabi-gcc --version
```

### Python GUI Setup

```bash
git clone https://github.com/NawfalMotii79/PLFM_RADAR.git
cd PLFM_RADAR/9_Firmware/9_3_GUI

pip install -r requirements.txt
python radar_gui.py
```

### Building STM32 Firmware (GCC)

```bash
cd 9_Firmware/9_2_STM32

# Using Make (if Makefile present)
make all

# Flash via ST-Link
make flash
# or
st-flash write build/aeris10.bin 0x08000000
```

### Building FPGA Bitstream (Vivado TCL)

```bash
cd 9_Firmware/9_1_FPGA

# Non-interactive build
vivado -mode batch -source build.tcl

# Open project interactively
vivado aeris10_fpga.xpr
```

---

## STM32 Firmware — Key Patterns

### Power Sequencing

The STM32 controls power-up order to protect components. Follow the sequencing defined in the Power Management Excel file.

```c
/* power_seq.h */
typedef enum {
    PWR_STATE_OFF = 0,
    PWR_STATE_DIGITAL,   /* 3.3V / 1.8V digital rails */
    PWR_STATE_SYNTH,     /* ADF4382 VCC */
    PWR_STATE_RF,        /* ADTR1107 / ADAR1000 */
    PWR_STATE_PA,        /* QPA2962 GaN (Extended only) */
    PWR_STATE_READY
} PowerState_t;

void PowerSeq_Up(void);
void PowerSeq_Down(void);
```

```c
/* power_seq.c */
#include "power_seq.h"
#include "stm32f7xx_hal.h"

#define DELAY_MS(x)  HAL_Delay(x)

/* GPIO bank aliases — match your schematic net names */
#define EN_3V3_PIN   GPIO_PIN_0
#define EN_3V3_PORT  GPIOB
#define EN_RF_PIN    GPIO_PIN_4
#define EN_RF_PORT   GPIOC
#define EN_PA_PIN    GPIO_PIN_5
#define EN_PA_PORT   GPIOC

static PowerState_t current_state = PWR_STATE_OFF;

void PowerSeq_Up(void) {
    /* Step 1: Digital rails */
    HAL_GPIO_WritePin(EN_3V3_PORT, EN_3V3_PIN, GPIO_PIN_SET);
    DELAY_MS(50);

    /* Step 2: Initialize clock generator */
    AD9523_Init();
    DELAY_MS(10);

    /* Step 3: Frequency synthesizers */
    ADF4382_Init(ADF4382_TX);
    ADF4382_Init(ADF4382_RX);
    DELAY_MS(20);

    /* Step 4: RF front-end */
    HAL_GPIO_WritePin(EN_RF_PORT, EN_RF_PIN, GPIO_PIN_SET);
    DELAY_MS(30);

    /* Step 5: Phase shifters */
    for (uint8_t i = 0; i < 4; i++) {
        ADAR1000_Init(i);
    }

    /* Step 6: PA boards (Extended version only) */
#ifdef AERIS10_EXTENDED
    HAL_GPIO_WritePin(EN_PA_PORT, EN_PA_PIN, GPIO_PIN_SET);
    DELAY_MS(100);
    PA_SetBias(); /* DAC5578 Vg control */
#endif

    current_state = PWR_STATE_READY;
}

void PowerSeq_Down(void) {
    /* Reverse order */
#ifdef AERIS10_EXTENDED
    HAL_GPIO_WritePin(EN_PA_PORT, EN_PA_PIN, GPIO_PIN_RESET);
    DELAY_MS(50);
#endif
    HAL_GPIO_WritePin(EN_RF_PORT, EN_RF_PIN, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(EN_3V3_PORT, EN_3V3_PIN, GPIO_PIN_RESET);
    current_state = PWR_STATE_OFF;
}
```

---

### ADAR1000 Phase Shifter Driver

The ADAR1000 is a 4-channel X/Ku-band beamformer IC controlled over SPI.

```c
/* adar1000.h */
#define ADAR1000_COUNT       4
#define ADAR1000_CHANNELS    4

/* Register addresses (from ADAR1000 datasheet) */
#define ADAR1000_CH1_TX_GAIN   0x001
#define ADAR1000_CH1_TX_PHASE  0x002
#define ADAR1000_CH1_RX_GAIN   0x010
#define ADAR1000_CH1_RX_PHASE  0x011
#define ADAR1000_TX_ENABLES    0x038
#define ADAR1000_RX_ENABLES    0x039
#define ADAR1000_SW_CTRL       0x042

void ADAR1000_Init(uint8_t device_idx);
void ADAR1000_SetTxPhase(uint8_t dev, uint8_t ch, uint16_t phase_deg_x10);
void ADAR1000_SetRxPhase(uint8_t dev, uint8_t ch, uint16_t phase_deg_x10);
void ADAR1000_SetTxGain(uint8_t dev, uint8_t ch, uint8_t gain);
void ADAR1000_SetRxGain(uint8_t dev, uint8_t ch, uint8_t gain);
void ADAR1000_ApplyBeam(uint8_t dev);
```

```c
/* adar1000.c */
#include "adar1000.h"
#include "spi.h"

/* SPI chip-select lines per device */
static GPIO_TypeDef* cs_ports[ADAR1000_COUNT] = {GPIOA, GPIOA, GPIOB, GPIOB};
static uint16_t      cs_pins[ADAR1000_COUNT]  = {GPIO_PIN_4, GPIO_PIN_5,
                                                   GPIO_PIN_0, GPIO_PIN_1};

static void ADAR1000_Write(uint8_t dev, uint16_t reg, uint8_t data) {
    uint8_t tx[3];
    /* 3-byte SPI: [addr_high][addr_low][data] — write bit = 0 */
    tx[0] = (reg >> 8) & 0x7F;
    tx[1] = reg & 0xFF;
    tx[2] = data;

    HAL_GPIO_WritePin(cs_ports[dev], cs_pins[dev], GPIO_PIN_RESET);
    HAL_SPI_Transmit(&hspi1, tx, 3, HAL_MAX_DELAY);
    HAL_GPIO_WritePin(cs_ports[dev], cs_pins[dev], GPIO_PIN_SET);
}

void ADAR1000_Init(uint8_t dev) {
    /* Software reset */
    ADAR1000_Write(dev, 0x000, 0x81);
    HAL_Delay(1);
    /* Default: all channels enabled, TR switch to TX */
    ADAR1000_Write(dev, ADAR1000_TX_ENABLES, 0x0F);
    ADAR1000_Write(dev, ADAR1000_RX_ENABLES, 0x0F);
}

/* phase_deg_x10: phase in units of 0.1 degrees, 0–3599 */
void ADAR1000_SetTxPhase(uint8_t dev, uint8_t ch, uint16_t phase_deg_x10) {
    /* ADAR1000 phase word = phase(deg) / 360 * 128  (7-bit) */
    uint8_t phase_word = (uint8_t)((phase_deg_x10 * 128UL) / 3600UL);
    uint16_t reg = ADAR1000_CH1_TX_PHASE + (ch * 0x10);
    ADAR1000_Write(dev, reg, phase_word);
}

void ADAR1000_SetRxPhase(uint8_t dev, uint8_t ch, uint16_t phase_deg_x10) {
    uint8_t phase_word = (uint8_t)((phase_deg_x10 * 128UL) / 3600UL);
    uint16_t reg = ADAR1000_CH1_RX_PHASE + (ch * 0x10);
    ADAR1000_Write(dev, reg, phase_word);
}

void ADAR1000_ApplyBeam(uint8_t dev) {
    /* Latch all pending phase/gain updates */
    ADAR1000_Write(dev, ADAR1000_SW_CTRL, 0x01);
}
```

---

### Beamforming — Computing Phase Shifts

```c
/* beamforming.c
 * Computes per-element phase shifts for a linear array
 * to steer to azimuth angle `theta_deg`.
 */
#include <math.h>
#include <stdint.h>
#include "adar1000.h"

#define FREQ_HZ        10.5e9
#define C_MPS          3.0e8
#define LAMBDA_M       (C_MPS / FREQ_HZ)   /* ~0.02857 m */
#define ELEMENT_SPACING_M  (LAMBDA_M / 2.0) /* half-wavelength */

Related in Writing & Docs