Skip to content
david-sun-rtk edited this page Mar 26, 2026 · 2 revisions

RTL8752H First Mile Wiki

Welcome to the RTL8752H First Mile tutorial wiki. The First Mile is a simple demo project to help get you started. This guide walks you through setting up and using the key peripherals on the Realtek RTL8752H chipset.


Table of Contents

  1. Introduction
  2. Getting Started
  3. Project Structure
  4. SPI Demo
  5. GPIO Demo
  6. I2C Demo
  7. DLPS (Deep Low Power Sleep)
  8. Troubleshooting
  9. Resources

Introduction

The RTL8752H is a powerful Bluetooth LE microcontroller from Realtek. This tutorial covers the fundamentals of working with the key peripherals that we'll be looking into:

  • SPI: For high-speed communication with displays and flash storage
  • GPIO: For general-purpose input/output and interrupt handling
  • I2C: For communicating with sensors like temperature/pressure

Later, we'll introduce how to setup DLPS for power saving mode:

  • DLPS: Deep Low Power Sleep mode for battery-powered applications

Prerequisites

  • Keil MDK-ARM development environment
  • RTL8752H evaluation board (EVB)

Getting Started

Setting Up Your Development Environment

  1. Install Keil MDK-ARM (version 5.36 or later recommended)
  2. Download RTL8752H SDK

Building the Project

  1. Open the project file (.uvprojx) in Keil MDK
  2. Select your target configuration
  3. Build with Project > Build Target (or F7)
  4. Download with MPTool

Project Structure

RTL8752H_Github_Repo/
├── board/evb/io_sample/
│   ├── SPI/Interrupt/
│   │   ├── mdk/              # Keil project files
│   │   ├── Config/           # Hardware configuration (DEV_Config)
│   │   ├── Fonts/            # Font files for epaper display
│   │   ├── GUI/              # Epaper Graphics library
│   │   └── Example/          # Epaper Image data
│   ├── GPIO/                 # GPIO examples
│   ├── I2C/Self_Test/        # I2C BMP sensor demo
│   └── RTC/Dlps/             # RTC and DLPS demos
├── src/
│   ├── sample/io_sample/
│   │   ├── SPI/Interrupt/    # SPI implementation
│   │   ├── GPIO/             # GPIO implementation
│   │   └── I2C/Self_Test/    # I2C implementation
│   └── mcu/peripheral/       # SDK peripheral drivers
└── tool/                     # Utility tools

Key Files Explained

File Purpose
main.c Application entry point and initialization
io_spi.c/h SPI driver implementation
io_spi.h SPI driver header with function declarations
board.h Board-level pin and peripheral definitions
app_task.c RTOS task management
dlps.h Power management definitions

SPI Demo

Overview

The SPI demo implements master mode communication with an e-paper display. SPI (Serial Peripheral Interface) provides high-speed full-duplex communication.

Hardware Configuration

Pins Used:

Pin Function
SPI0_SCK Clock (P4_0)
SPI0_MOSI Master Out Slave In (P4_1)
SPI0_MISO Master In Slave Out (P4_2)
SPI0_CS Chip Select (P4_3)

Configuration Details

SPI Mode Settings:

  • Direction: Tx Only (Transmit)
  • Mode: Master
  • Data Size: 8 bits
  • Clock Polarity (CPOL): Low
  • Clock Phase (CPHA): 1st Edge
  • Baud Rate Prescaler: 64
  • Frame Format: Motorola

Key Functions

// Board-level initialization (pinmux and pad settings)
void board_spi_init(void);

// Driver initialization (SPI peripheral setup)
void driver_spi_init(void);

// SPI interrupt handler
void SPI0_Handler(void);

// DLPS callbacks
void io_spi_dlps_enter(void);
void io_spi_dlps_exit(void);
PMCheckResult io_spi_dlps_check(void);

Understanding the Code Flow

  1. board_spi_init(): Configures pins for SPI function using Pinmux_Config and sets pad properties
  2. driver_spi_init(): Enables SPI clock, configures SPI registers, and enables the peripheral
  3. SPI0_Handler(): Called on RX FIFO interrupt, reads received data and sends to app task

Example: Initializing SPI

void driver_spi_init(void)
{
    RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE);

    SPI_InitTypeDef SPI_InitStruct;
    SPI_StructInit(&SPI_InitStruct);

    SPI_InitStruct.SPI_Direction   = SPI_Direction_TxOnly;
    SPI_InitStruct.SPI_Mode        = SPI_Mode_Master;
    SPI_InitStruct.SPI_DataSize    = SPI_DataSize_8b;
    SPI_InitStruct.SPI_CPOL        = SPI_CPOL_Low;
    SPI_InitStruct.SPI_CPHA        = SPI_CPHA_1Edge;
    SPI_InitStruct.SPI_BaudRatePrescaler  = 64;
    SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola;

    SPI_Init(SPI0, &SPI_InitStruct);
    SPI_Cmd(SPI0, ENABLE);
}

GPIO Demo

Overview

GPIO is needed for input/output and handle external interrupts. This is essential for reading buttons and controlling external components.

Hardware Configuration

Pins Used:

Pin Direction Purpose
GPIO_BTN_PIN Input (with interrupt) User button
GPIO_DC_PIN Output E-paper data/command control
GPIO_RST_PIN Output E-paper reset
GPIO_PWR_PIN Output E-paper power control
GPIO_BUSY_PIN Input E-paper busy status

Interrupt Configuration

  • Trigger: Falling edge (button press)
  • Debounce: 10ms
  • Priority: 3
  • ** NVIC Channel**: Corresponding GPIO interrupt

Key Functions

// Initialize GPIO pads and pinmux
void board_gpio_init(void);

// Initialize GPIO peripheral and interrupts
void driver_gpio_init(void);

// GPIO interrupt handler
void GPIO_Input_Handler(void);

Understanding the Code Flow

  1. board_gpio_init(): Configures all GPIO pads with pull settings and enables pinmux
  2. driver_gpio_init(): Sets up GPIO direction, enables interrupts with debounce
  3. GPIO_Input_Handler(): Called on button press, clears interrupt flag, sends message to app task

Example: Configuring Button Interrupt

void driver_gpio_init(void)
{
    RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);

    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_StructInit(&GPIO_InitStruct);

    // Button pin configuration
    GPIO_InitStruct.GPIO_Pin    = BTN_PIN;
    GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_ITCmd  = ENABLE;
    GPIO_InitStruct.GPIO_ITTrigger  = GPIO_INT_Trigger_EDGE;
    GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
    GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE;
    GPIO_InitStruct.GPIO_DebounceTime = 10;  // 10ms debounce
    GPIO_Init(&GPIO_InitStruct);

    // Enable NVIC
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = BTN_PIN_IRQ;
    NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);
}

I2C Demo

Overview

The I2C demo implements master mode communication with a BMP180 pressure and temperature sensor. I2C is ideal for communicating with low-speed sensors.

Hardware Configuration

Pins Used:

Pin Function
I2C0_SCL (P0_6) Serial Clock
I2C0_SDA (P0_5) Serial Data

Sensor Configuration:

  • I2C Address: 0x77 (7-bit)
  • Clock Speed: 10 kHz

Key Functions

// Initialize I2C pads and pinmux
void board_i2c_master_init(void);

// Initialize I2C peripheral as master
void driver_i2c_master_init(void);

// Demo task that reads temperature
void i2c_demo(void *p_param);

// I2C interrupt handler
void I2C0_Handler(void);

Understanding the Code Flow

  1. board_i2c_master_init(): Configures SCL and SDA pins with pull-ups
  2. driver_i2c_master_init(): Sets up I2C0 as master with slave address 0x77
  3. i2c_demo(): OS task that connects to BMP sensor and reads temperature every 3 seconds

Example: Initializing I2C Master

void driver_i2c_master_init(void)
{
    RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE);

    I2C_InitTypeDef I2C_InitStruct;
    I2C_StructInit(&I2C_InitStruct);

    I2C_InitStruct.I2C_ClockSpeed       = 10000;        // 10 kHz
    I2C_InitStruct.I2C_DeviveMode       = I2C_DeviveMode_Master;
    I2C_InitStruct.I2C_AddressMode      = I2C_AddressMode_7BIT;
    I2C_InitStruct.I2C_SlaveAddress     = BMP180_ADDR;  // 0x77
    I2C_InitStruct.I2C_RxThresholdLevel = 0;
    I2C_InitStruct.I2C_Ack              = I2C_Ack_Enable;

    I2C_Init(I2C0, &I2C_InitStruct);
    I2C_Cmd(I2C0, ENABLE);
}

Reading Temperature

void i2c_demo(void *p_param)
{
    while(!begin_bmp())
    {
        DBG_DIRECT("Failed to connect to BMP80");
    }

    for(int i = 0; i < 100; i++)
    {
        float temp = readTemperature();
        DBG_DIRECT("Temperature read: %f", temp);
        os_delay(3000);  // Read every 3 seconds
    }
}

DLPS (Deep Low Power Sleep)

Overview

DLPS (Deep Low Power Sleep) is a critical feature for battery-powered applications. It allows the MCU to enter a low-power state while still being able to wake up via interrupts.

How It Works

  1. Normal Operation: All peripherals active, consuming full power
  2. DLPS Entry: Peripherals save state, pins reconfigured for minimal power
  3. DLPS Exit: State restored, operation continues

DLPS Callbacks

To use DLPS with SPI (or any peripheral), you must register callbacks:

// Check if DLPS is allowed (e.g., SPI not in use)
PMCheckResult io_spi_dlps_check(void)
{
    return IO_SPI_DLPS_Enter_Allowed;
}

// Called before entering DLPS
void io_spi_dlps_enter(void)
{
    // Switch pins to software mode
    Pad_ControlSelectValue(SPI0_SCK_PIN, PAD_SW_MODE);
    Pad_ControlSelectValue(SPI0_MOSI_PIN, PAD_SW_MODE);
    Pad_ControlSelectValue(SPI0_MISO_PIN, PAD_SW_MODE);
    Pad_ControlSelectValue(SPI0_CS_PIN, PAD_SW_MODE);
}

// Called after waking from DLPS
void io_spi_dlps_exit(void)
{
    // Switch pins back to pinmux mode
    Pad_ControlSelectValue(SPI0_SCK_PIN, PAD_PINMUX_MODE);
    Pad_ControlSelectValue(SPI0_MOSI_PIN, PAD_PINMUX_MODE);
    Pad_ControlSelectValue(SPI0_MISO_PIN, PAD_PINMUX_MODE);
    Pad_ControlSelectValue(SPI0_CS_PIN, PAD_PINMUX_MODE);
}

Registering DLPS Callbacks

void pwr_mgr_init(void)
{
#if DLPS_EN
    dlps_check_cb_reg(io_spi_dlps_check);
    DLPS_IORegUserDlpsEnterCb(io_spi_dlps_enter);
    DLPS_IORegUserDlpsExitCb(io_spi_dlps_exit);
    DLPS_IORegister();
    lps_mode_set(PLATFORM_DLPS_PFM);

    // Enable wake-up pin (button)
    System_WakeUpPinEnable(DLPS_WAKEUP_PIN, PAD_WAKEUP_POL_LOW, 0, 0);
#else
    lps_mode_set(PLATFORM_ACTIVE);
#endif
}

Key Points

  • Always check peripheral state before allowing DLPS (use PM_CHECK_PASS/PM_CHECK_FAIL)
  • Save and restore pin configurations in enter/exit callbacks
  • Configure wake-up sources (GPIO pins, timer, etc.)

BLE Peripheral Application

Overview

The project includes a full BLE peripheral application that demonstrates:

  • GAP (Generic Access Profile) configuration
  • GATT server with custom services
  • Advertisement and connection management

Troubleshooting

Common Issues

1. SPI not communicating

  • Check pin connections (SCK, MOSI, MISO, CS)
  • Verify baud rate prescaler is appropriate for your slave device
  • Ensure slave device is powered and not in reset

2. GPIO interrupt not firing

  • Check that NVIC is enabled for the GPIO interrupt
  • Verify pull-up/pull-down settings match your circuit
  • Ensure interrupt trigger edge/polarity is correct

3. I2C communication fails

  • Verify pull-up resistors on SCL and SDA (typically 4.7kΩ)
  • Check that the slave address is correct
  • Ensure clock speed is appropriate for your bus length

4. DLPS not working

  • Confirm all peripherals report PM_CHECK_PASS before DLPS
  • Check wake-up pin configuration
  • Verify system clock settings

Debug Tips

  • Use DBG_DIRECT() for UART debug output
  • Check the NVIC pending bits to see which interrupts fired

Resources


License

Copyright (c) 2025, Realtek Semiconductor Corporation. All rights reserved.

SPDX-License-Identifier: LicenseRef-Realtek-5-Clause