wolfBoot/test-app/app_lpc55s69.c

307 lines
7.8 KiB
C

/* app_lpc55s69.c
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <stdint.h>
#include "fsl_clock.h"
#include "fsl_gpio.h"
#include "fsl_iocon.h"
#include "target.h"
#include "wolfboot/wolfboot.h"
#include "printf.h"
/* wolfCrypt test/benchmark support */
#ifdef WOLFCRYPT_TEST
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfcrypt/test/test.h>
int wolfcrypt_test(void *args);
#endif
#ifdef WOLFCRYPT_BENCHMARK
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfcrypt/benchmark/benchmark.h>
int benchmark_test(void *args);
#endif
#define RED_LED 6
#define GREEN_LED 7
#define BLUE_LED 4
extern void hal_init(void);
volatile uint64_t SysTick_time_ms;
void SysTick_Handler(void)
{
SysTick_time_ms++;
}
#ifdef WOLFCRYPT_BENCHMARK
static void systick_init(void)
{
SysTick_Config(CLOCK_GetCoreSysClkFreq() / 1000U); /* 1 ms period */
}
#endif
#define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */
#define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */
#define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard mode, output slew rate control is enabled */
#define IOCON_PIO_INV_DI 0x00u /*!<@brief Input function is not inverted */
#define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */
#define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */
static void leds_init(void)
{
#ifndef TZEN
CLOCK_EnableClock(kCLOCK_Iocon);
CLOCK_EnableClock(kCLOCK_Gpio1);
#endif
/* red output off */
GPIO->SET[1] = 1UL << RED_LED;
GPIO->DIR[1] |= 1UL << RED_LED;
/* green output off */
GPIO->SET[1] = 1UL << GREEN_LED;
GPIO->DIR[1] |= 1UL << GREEN_LED;
/* blue output off */
GPIO->SET[1] = 1UL << BLUE_LED;
GPIO->DIR[1] |= 1UL << BLUE_LED;
const uint32_t LED_PINMUX_CONFIG = (/* Pin is configured as PIO */
IOCON_PIO_FUNC0 |
/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
IOCON_PinMuxSet(IOCON, 1, RED_LED, LED_PINMUX_CONFIG);
IOCON_PinMuxSet(IOCON, 1, GREEN_LED, LED_PINMUX_CONFIG);
IOCON_PinMuxSet(IOCON, 1, BLUE_LED, LED_PINMUX_CONFIG);
}
static void check_parts(
uint32_t *pboot_ver, uint32_t *pupdate_ver,
uint8_t *pboot_state, uint8_t *pupdate_state
)
{
#ifdef WOLFCRYPT_SECURE_MODE
*pboot_ver = wolfBoot_nsc_current_firmware_version();
*pupdate_ver = wolfBoot_nsc_update_firmware_version();
if (wolfBoot_nsc_get_partition_state(PART_BOOT, pboot_state) != 0)
*pboot_state = IMG_STATE_NEW;
if (wolfBoot_nsc_get_partition_state(PART_UPDATE, pupdate_state) != 0)
*pupdate_state = IMG_STATE_NEW;
#else
*pboot_ver = wolfBoot_current_firmware_version();
*pupdate_ver = wolfBoot_update_firmware_version();
if (wolfBoot_get_partition_state(PART_BOOT, pboot_state) != 0)
*pboot_state = IMG_STATE_NEW;
if (wolfBoot_get_partition_state(PART_UPDATE, pupdate_state) != 0)
*pupdate_state = IMG_STATE_NEW;
#endif
wolfBoot_printf(" boot: ver=0x%lx state=0x%02x\n", *pboot_ver, *pboot_state);
wolfBoot_printf(" update: ver=0x%lx state=0x%02x\n", *pupdate_ver, *pupdate_state);
}
void main(void)
{
uint32_t boot_ver, update_ver;
uint8_t boot_state, update_state;
hal_init();
leds_init();
#ifdef WOLFCRYPT_BENCHMARK
systick_init();
__enable_irq();
#endif
wolfBoot_printf("\n==================================\n");
wolfBoot_printf("LPC55S69 wolfBoot demo Application\n");
wolfBoot_printf("Copyright 2026 wolfSSL Inc\n");
wolfBoot_printf("==================================\n");
check_parts(&boot_ver, &update_ver, &boot_state, &update_state);
if (
boot_ver != 0 &&
(boot_state == IMG_STATE_TESTING || boot_state == IMG_STATE_NEW)
)
{
#ifdef WOLFCRYPT_SECURE_MODE
wolfBoot_printf("Calling wolfBoot_nsc_success()\n");
wolfBoot_nsc_success();
#else
wolfBoot_printf("Calling wolfBoot_success()\n");
wolfBoot_success();
#endif
check_parts(&boot_ver, &update_ver, &boot_state, &update_state);
}
if (boot_ver == 1)
{
/* blue on */
GPIO_PinWrite(GPIO, 1, BLUE_LED, 0);
if (update_ver != 0) {
wolfBoot_printf("Update detected, version: 0x%lx\n", update_ver);
wolfBoot_printf("Triggering update...\n");
#ifdef WOLFCRYPT_SECURE_MODE
wolfBoot_nsc_update_trigger();
#else
wolfBoot_update_trigger();
#endif
check_parts(&boot_ver, &update_ver, &boot_state, &update_state);
wolfBoot_printf("...done. Reboot to apply.\n");
}
}
else {
/* green on */
GPIO_PinWrite(GPIO, 1, GREEN_LED, 0);
}
#if defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK)
wolfCrypt_Init();
# ifdef WOLFCRYPT_TEST
wolfBoot_printf("\nRunning wolfCrypt tests...\n");
wolfcrypt_test(NULL);
wolfBoot_printf("Tests complete.\n\n");
# endif
# ifdef WOLFCRYPT_BENCHMARK
wolfBoot_printf("\nRunning wolfCrypt benchmarks...\n");
benchmark_test(NULL);
wolfBoot_printf("Benchmarks complete.\n\n");
# endif
wolfCrypt_Cleanup();
#endif
while (1) {
__asm__ volatile ("wfi");
}
}
#ifndef ENOMEM
#define ENOMEM 12
#endif
#ifndef EBADF
#define EBADF 9
#endif
#ifndef EINVAL
#define EINVAL 22
#endif
int errno;
#include "sys/stat.h"
int WEAKFUNCTION _getpid(void)
{
return 1;
}
int WEAKFUNCTION _kill(int pid, int sig)
{
(void)pid;
(void)sig;
return -1;
}
void WEAKFUNCTION _exit(int status)
{
_kill(status, -1);
while (1) {}
}
int WEAKFUNCTION _read(int file, char *ptr, int len)
{
(void)file;
(void)ptr;
(void)len;
return -1;
}
int WEAKFUNCTION _write(int file, char *ptr, int len)
{
(void)file;
(void)ptr;
return len;
}
int WEAKFUNCTION _close(int file)
{
(void)file;
return -1;
}
int WEAKFUNCTION _isatty(int file)
{
(void)file;
return 1;
}
int WEAKFUNCTION _lseek(int file, int ptr, int dir)
{
(void)file;
(void)ptr;
(void)dir;
return 0;
}
int WEAKFUNCTION _fstat(int file, struct stat *st)
{
(void)file;
st->st_mode = S_IFCHR;
return 0;
}
/* Heap management */
extern char _end; /* Defined by linker */
extern char _Min_Heap_Size; /* Linker symbol: address is the value */
void WEAKFUNCTION *_sbrk(int incr)
{
static char *heap_end = 0;
char *prev_heap_end;
char *heap_limit;
if (heap_end == 0) {
heap_end = &_end;
}
prev_heap_end = heap_end;
heap_limit = &_end + (uintptr_t)&_Min_Heap_Size;
if (heap_end + incr > heap_limit) {
errno = ENOMEM;
return (void *)-1;
}
heap_end += incr;
return prev_heap_end;
}