ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c File Reference

NimBLE-based Battery Service peripheral on top of ThreadX (RA8D2). More...

#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_board_ek_ra8d2.h"
#include "ra8_boot_entry.h"
#include "ra8_cgc.h"
#include "ra8_err.h"
#include "ra8_isr.h"
#include "ra8_time.h"
#include "ble_hci_ra8_ble.h"
#include "nimble_npl_threadx.h"
#include "ra8_ble.h"
#include "tx_api.h"
Include dependency graph for main.c:

Go to the source code of this file.

Enumerations

enum  demo_config_t : uint32_t {
  k_demo_baud = 115200U ,
  k_demo_thread_stack = 8192U ,
  k_demo_tick_ms = 10000U ,
  k_demo_thread_prio = 8U
}
 Numeric configuration constants. More...
enum  demo_battery_t : uint8_t {
  k_demo_battery_max = 100U ,
  k_demo_battery_min = 0U ,
  k_demo_battery_step = 1U ,
  k_demo_battery_init = 50U
}
 Battery Level characteristic policy. More...
enum  demo_uuid_t : uint16_t {
  k_demo_uuid_battery_service = 0x180FU ,
  k_demo_uuid_battery_level = 0x2A19U
}
 16-bit UUID handles for the Battery Service. More...

Functions

static void internal_demo_panic_halt (void)
 Park the CPU forever in WFI on fatal init failure.
static void internal_demo_log (const char *s)
 Send a NUL-terminated ASCII line over SCI8 (best-effort).
static void internal_demo_clocks_or_halt (void)
 Bring CGC + SysTick + SCI8 + GPIO basics up.
static void internal_demo_ble_or_halt (void)
 Bring the BLE controller + NimBLE adapter up.
static void internal_demo_tick_battery (void)
 Tick the battery shadow value.
static void internal_demo_thread_entry (ULONG arg)
 Worker thread: bring NimBLE up and run the battery loop.
void tx_application_define (void *first_unused_memory)
 ThreadX system-define hook: build the worker thread.
void main (void)
 Application entry.

Variables

static const char s_demo_local_name [] = "EK-RA8D2"
 Local-name string broadcast in adv-data.
static const char * s_demo_tag = "ble_nimble"
 Tag used in SCI8 / ra8_log output to identify this app.
static TX_THREAD s_demo_thread
 Worker thread control block (statically allocated).
static UCHAR s_demo_stack [k_demo_thread_stack]
 Worker thread stack.
static CHAR s_demo_thread_name [] = "nimble_demo"
 Persistent mutable name retained by the ThreadX thread control block.
static uint8_t s_demo_battery_level = k_demo_battery_init
 Current battery percentage value (mirrored to GATT cache).

Detailed Description

NimBLE-based Battery Service peripheral on top of ThreadX (RA8D2).

Tag
[Ring 6 / APP] {World: S}

NimBLE replacement for the hand-rolled examples/ble_peripheral demo. The bring-up path is:

  1. Bare-metal init (CGC + SCI8 + SysTick) – identical to examples/ek_ra8d2/hw_validated/hil/threadx_fs_demo.
  2. ra8_ble_init clocks the radio block and opens the HCI mailbox.
  3. tx_kernel_enter hands the CPU over to ThreadX.
  4. tx_application_define spawns one worker thread which calls ble_hci_ra8_ble_init to attach the NimBLE -> ra8_ble bridge, then nimble_port_init to bring the host stack up, then drives the Battery Service: advertise as EK-RA8D2, decrement the battery level by one every 10 s, push a Handle Value Notification on every change.

Bluetooth profile pointers (Bluetooth Core 5.3):

  • Battery Service – UUID 0x180F (Vol 3 Part G 3.3.1.1).
  • Battery Level char. – UUID 0x2A19, Read | Notify.
  • CCCD – UUID 0x2902 (Vol 3 Part F 3.3.3.3).
Verification
Open nRF Connect for Mobile, scan for EK-RA8D2, connect, subscribe to Battery Level notifications, watch the value tick down once every ten seconds.
No on-chip BLE radio
This demo cannot pass a smoke test on a stock EK-RA8D2: the RA8D2 has no on-chip BLE radio (established by commit 6f6209a95), so there is no controller here to bring up and no vendor patch image that would supply one. BLE on this board means an ESP32-C6 companion carrying the controller across the ra8_ble HCI transport seam. Only the software path is wired – see README.md alongside this file.
Author
Brighton Sikarskie
Date
2026-04-29
Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ demo_battery_t

enum demo_battery_t : uint8_t

Battery Level characteristic policy.

Battery Level is a percentage in the range 0..100 (Bluetooth Core 5.3 Service Specifications – Battery Service 1.0 sec 3.1).

Enumerator
k_demo_battery_max 

Maximum percentage.

k_demo_battery_min 

Minimum percentage (rolls to max).

k_demo_battery_step 

Decrement amount per tick.

k_demo_battery_init 

Initial reading at boot.

Definition at line 96 of file main.c.

◆ demo_config_t

enum demo_config_t : uint32_t

Numeric configuration constants.

Matches examples/ble_peripheral so the verification flow is unchanged. SCI8 lives on PD_02 / PD_03 (J-Link OB CDC bridge).

Enumerator
k_demo_baud 

J-Link OB CDC log baud.

k_demo_thread_stack 

Worker thread stack bytes.

k_demo_tick_ms 

Battery decrement period.

k_demo_thread_prio 

ThreadX priority + threshold.

Definition at line 81 of file main.c.

◆ demo_uuid_t

enum demo_uuid_t : uint16_t

16-bit UUID handles for the Battery Service.

Enumerator
k_demo_uuid_battery_service 

Battery Service.

k_demo_uuid_battery_level 

Battery Level char.

Definition at line 107 of file main.c.

Function Documentation

◆ internal_demo_ble_or_halt()

void internal_demo_ble_or_halt ( void )
static

Bring the BLE controller + NimBLE adapter up.

  1. ra8_ble_open powers up the radio block and opens the HCI mailbox.
  2. ble_hci_ra8_ble_init attaches our NimBLE <-> ra8_ble bridge.
  3. nimble_port_init brings the host stack's default eventq up.
Precondition
Clocks + SCI8 are already initialized.
The BLE controller is not already open in another context.
Postcondition
On success the HCI mailbox is reachable from NimBLE.
On failure a diagnostic is attempted before the CPU parks.
Note
NimBLE host initialization occurs only after the RA8 HCI bridge is live.
Since
0.1.0

Definition at line 227 of file main.c.

References ble_hci_ra8_ble_init(), internal_demo_log(), internal_demo_panic_halt(), k_ra8_ok, nimble_port_init(), ra8_ble_open(), and RA8_INTERNAL.

Referenced by internal_demo_thread_entry().

◆ internal_demo_clocks_or_halt()

void internal_demo_clocks_or_halt ( void )
static

Bring CGC + SysTick + SCI8 + GPIO basics up.

Panic-halts on fail.

Initializes clocks, obtains CPUCLK0, starts the timebase, and opens LED1 and the console in their dependency order.

Precondition
Reset_Handler / SystemInit complete.
The application remains in single-threaded boot context.
Postcondition
On success SCI8 is sending at 115200 8N1 and LED1 is ready.
On any driver error the CPU is parked before ThreadX starts.
Note
The measured CPU rate is used only to configure the system timebase.
Since
0.1.0

Definition at line 188 of file main.c.

References internal_demo_panic_halt(), k_demo_baud, k_ra8_board_led1, k_ra8_clock_id_cpuclk0, k_ra8_ok, ra8_board_led_init(), ra8_board_uart_console_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), RA8_INTERNAL, and ra8_time_init().

Referenced by main().

◆ internal_demo_log()

void internal_demo_log ( const char * s)
static

Send a NUL-terminated ASCII line over SCI8 (best-effort).

Measures the string and submits exactly its payload bytes to the BSP console without dynamic allocation or a terminator write.

Parameters
[in]sASCII string (NUL-terminated). May be nullptr.
Precondition
ra8_board_uart_console_init() succeeded for the SCI8 console.
A non-NULL s points to a readable NUL-terminated string.
Postcondition
Bytes have been polled out of TXD8 (or silently discarded on backpressure – this is logging only).
NULL input returns without touching the console.
Note
Diagnostic write errors do not alter BLE control flow.
Since
0.1.0

Definition at line 166 of file main.c.

References ra8_board_uart_console_write(), RA8_INTERNAL, and strlen().

Referenced by internal_demo_ble_or_halt(), internal_demo_thread_entry(), internal_demo_tick_battery(), and main().

◆ internal_demo_panic_halt()

void internal_demo_panic_halt ( void )
static

Park the CPU forever in WFI on fatal init failure.

Preserves the failed bring-up state for debugger inspection while preventing further radio, console, or scheduler activity.

Precondition
Called only after a fatal error in boot.
The current boot has no safe recovery path.
Postcondition
CPU is parked; only a debugger or external reset wakes it.
No additional peripheral state is changed.
Note
The helper avoids logging because console initialization may have failed.
Since
0.1.0

Definition at line 143 of file main.c.

References RA8_INTERNAL.

◆ internal_demo_thread_entry()

void internal_demo_thread_entry ( ULONG arg)
static

Worker thread: bring NimBLE up and run the battery loop.

Starts the controller and host bridge, announces the local name, then dispatches HCI traffic and advances the battery shadow periodically.

Parameters
[in]argUnused.
Precondition
tx_kernel_enter() is running.
The static worker stack and BLE globals are exclusively assigned here.
Postcondition
Thread loops forever ticking the battery every 10 s.
Each loop iteration gives ThreadX a bounded sleep interval.
Note
The argument is reserved for future per-instance configuration.
Since
0.1.0

Definition at line 285 of file main.c.

References internal_demo_ble_or_halt(), internal_demo_log(), internal_demo_tick_battery(), k_demo_tick_ms, ra8_ble_dispatch(), RA8_INTERNAL, s_demo_local_name, and tx_thread_sleep.

◆ internal_demo_tick_battery()

void internal_demo_tick_battery ( void )
static

Tick the battery shadow value.

Wraps from 0 -> 100. Pushes the new value out as a Handle Value Notification through the upstream NimBLE GATT API once the host stack is wired up; for now we only update the shadow + log.

Precondition
internal_demo_ble_or_halt() succeeded.
The worker thread exclusively owns the battery shadow.
Postcondition
s_demo_battery_level has been decremented (with wrap).
LED1 is toggled and one diagnostic line is attempted.
Note
GATT notification remains a future integration step; this updates cache.
Since
0.1.0

Definition at line 259 of file main.c.

References internal_demo_log(), k_demo_battery_max, k_demo_battery_min, k_demo_battery_step, k_ra8_board_led1, ra8_board_led_toggle(), RA8_INTERNAL, and s_demo_battery_level.

Referenced by internal_demo_thread_entry().

◆ main()

void main ( void )

Application entry.

The application entry point Reset_Handler hands control to.

Brings up clocks + UART, then enters ThreadX.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
On clean entry the kernel runs the worker thread forever.
On any HAL init failure the function halts in WFI.
Since
0.1.0

Definition at line 340 of file main.c.

References internal_demo_clocks_or_halt(), internal_demo_log(), internal_demo_panic_halt(), ra8_isr_globals_enable(), and s_demo_tag.

◆ tx_application_define()

void tx_application_define ( void * first_unused_memory)

ThreadX system-define hook: build the worker thread.

Parameters
[in]first_unused_memoryUnused; we statically allocate.
Precondition
tx_kernel_enter() has been called.
Postcondition
One worker thread is created.
Since
0.1.0

Definition at line 314 of file main.c.

References internal_demo_thread_entry(), k_demo_thread_prio, s_demo_stack, s_demo_thread, s_demo_thread_name, TX_AUTO_START, TX_NO_TIME_SLICE, and tx_thread_create.

Variable Documentation

◆ s_demo_battery_level

uint8_t s_demo_battery_level = k_demo_battery_init
static

Current battery percentage value (mirrored to GATT cache).

Definition at line 128 of file main.c.

Referenced by internal_demo_tick_battery().

◆ s_demo_local_name

const char s_demo_local_name[] = "EK-RA8D2"
static

Local-name string broadcast in adv-data.

Definition at line 113 of file main.c.

Referenced by internal_demo_thread_entry().

◆ s_demo_stack

UCHAR s_demo_stack[k_demo_thread_stack]
static

Worker thread stack.

ThreadX requires non-zero static storage.

Definition at line 122 of file main.c.

◆ s_demo_tag

const char* s_demo_tag = "ble_nimble"
static

Tag used in SCI8 / ra8_log output to identify this app.

Definition at line 116 of file main.c.

Referenced by main().

◆ s_demo_thread

TX_THREAD s_demo_thread
static

Worker thread control block (statically allocated).

Definition at line 120 of file main.c.

◆ s_demo_thread_name

CHAR s_demo_thread_name[] = "nimble_demo"
static

Persistent mutable name retained by the ThreadX thread control block.

Definition at line 124 of file main.c.

Referenced by tx_application_define().