Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for NXP MCXA153 #423

Merged
merged 7 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ jobs:
arch: ppc
config-file: ./config/examples/nxp-t2080.config

# MCXA test disabled until MCXA is available in mcux
# nxp_mcxa_test:
# uses: ./.github/workflows/test-build-mcux-sdk.yml
# with:
# arch: arm
# config-file: ./config/examples/mcxa.config

raspi3_test:
uses: ./.github/workflows/test-build.yml
with:
Expand Down
30 changes: 30 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,36 @@ ifeq ($(TARGET),kinetis)
endif
endif

ifeq ($(TARGET),mcxa)
CORTEX_M33=1
CFLAGS+=\
-I$(MCUXPRESSO_DRIVERS) \
-I$(MCUXPRESSO_DRIVERS)/drivers \
-I$(MCUXPRESSO)/drivers \
-I$(MCUXPRESSO)/drivers/common \
-I$(MCUXPRESSO_CMSIS)/Include \
-I$(MCUXPRESSO_CMSIS)/Core/Include
CFLAGS+=-DCPU_$(MCUXPRESSO_CPU) -DDEBUG_CONSOLE_ASSERT_DISABLE=1
CFLAGS+=-DWOLFSSL_SP_NO_UMAAL
CFLAGS+=-Wno-old-style-declaration
CFLAGS+=-mcpu=cortex-m33 -DCORTEX_M33 -U__ARM_FEATURE_DSP
LDFLAGS+=-mcpu=cortex-m33
OBJS+=\
$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o \
$(MCUXPRESSO_DRIVERS)/drivers/fsl_spc.o

ifeq ($(MCUXSDK),1)
CFLAGS+=\
-I$(MCUXPRESSO)/drivers/flash \
-I$(MCUXPRESSO)/drivers/sysmpu \
-I$(MCUXPRESSO)/drivers/ltc \
-I$(MCUXPRESSO)/drivers/port \
-I$(MCUXPRESSO)/drivers/gpio

else
endif
endif

ifeq ($(TARGET),imx_rt)
CFLAGS+=\
-I$(MCUXPRESSO_DRIVERS) \
Expand Down
40 changes: 40 additions & 0 deletions config/examples/mcxa.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
ARCH?=ARM
TARGET?=mcxa
SIGN?=ECC256
HASH?=SHA256
MCUXSDK?=0
MCUXPRESSO?=$(PWD)/../NXP/MCXA153
MCUXPRESSO_CMSIS?=$(MCUXPRESSO)/CMSIS
MCUXPRESSO_CPU?=MCXA153VLH
MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/MCXA153
DEBUG?=0
VTOR?=1
CORTEX_M0?=0
NO_ASM?=0
EXT_FLASH?=0
SPI_FLASH?=0
ALLOW_DOWNGRADE?=0
NVM_FLASH_WRITEONCE?=0
WOLFBOOT_VERSION?=0
V?=0
SPMATH?=1
RAM_CODE?=1
DUALBANK_SWAP?=0
PKA?=1

# 8KB sectors
WOLFBOOT_SECTOR_SIZE?=0x2000

# Default configuration
# 32KB boot, 44KB partitions, 8KB swap
WOLFBOOT_PARTITION_SIZE?=0xB000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x8000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x13000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x1E000

# Alternate larger configuration for debugging or SP ASM
# 40KB boot, 40KB partitions, 8KB swap
#WOLFBOOT_PARTITION_SIZE?=0xA000
#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xA000
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x14000
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x1E000
80 changes: 80 additions & 0 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This README describes configuration of supported targets.
* [NXP P1021 PPC](#nxp-qoriq-p1021-ppc)
* [NXP T1024 PPC](#nxp-qoriq-t1024-ppc)
* [NXP T2080 PPC](#nxp-qoriq-t2080-ppc)
* [NXP MCXA153](#nxp-mcxa153)
* [SiFive HiFive1 RISC-V](#sifive-hifive1-risc-v)
* [STM32F4](#stm32f4)
* [STM32F7](#stm32f7)
Expand Down Expand Up @@ -1710,6 +1711,85 @@ Executing Initialization File: /opt/Freescale/CodeWarrior_PA_10.5.1/PA/PA_Suppor
thread break: Stopped, 0x0, 0x0, cpuPowerPCBig, Connected (state, tid, pid, cpu, target)
```

## NXP MCXA153

NXP MCXA153 is a Cortex-M33 microcontroller running at 96MHz.
The support has been tested using FRDM-MCXA153 with the onboard MCU-Link configured in JLink mode.

This requires the MCXA SDK from the NXP MCUXpresso SDK Builder. We tested using `SDK_2.14.2_MCXA153` and placed into `../NXP/MCXA153` by default (see .config or set with `MCUXPRESSO`).
MCUXpresso SDK Builder

### MCX A: Configuring and compiling

Copy the example configuration file and build with make:

```sh
cp config/examples/mcxa.config .config`
make
```

### MCX A: Loading the firmware

The NXP Freedom MCX A board debugger comes loaded with MCU Link, but it can be updated to JLink. See https://docs.nxp.com/bundle/UM12012/page/topics/Updating_MCU_Link_firmware.html

Use JLinkExe tool to upload the initial firmware: `JLinkExe -if swd -Device MCXA153`

At the Jlink prompt, type:

```
loadbin factory.bin 0
Downloading file [factory.bin]...
J-Link: Flash download: Bank 0 @ 0x00000000: Skipped. Contents already match
O.K.
```

Reset or power cycle board.

Once wolfBoot has performaed validation of the partition and booted the D15 Green LED on P3_13 will illuminate.

### MCX A: Testing firmware update

1) Sign the test-app with version 2:

```sh
./tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 2
```

2) Create a bin footer with wolfBoot trailer "BOOT" and "p" (ASCII for 0x70 == IMG_STATE_UPDATING):

```sh
echo -n "pBOOT" > trigger_magic.bin
```

3) Assembly new factory update.bin:

```sh
./tools/bin-assemble/bin-assemble \
update.bin \
0x0 test-app/image_v2_signed.bin \
0xAFFB trigger_magic.bin
```

4) Flash update.bin to 0x13000 (`loadbin update.bin 0x13000`). The D15 RGB LED Blue P3_0 will show if version is > 1.

Note: For alternate larger scheme flash `update.bin` to `0x14000` and place trigger_magic.bin at `0x9FFB`.

### MCX A: Debugging

Debugging with JLink:

Note: We include a `.gdbinit` in the wolfBoot root that loads the wolfboot and test-app elf files.

In one terminal: `JLinkGDBServer -if swd -Device MCXA153 -port 3333`

In another terminal use `gdb`:

```
b main
mon reset
c
```


## TI Hercules TMS570LC435

Expand Down
173 changes: 173 additions & 0 deletions hal/mcxa.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/* mcxa.c
*
* Copyright (C) 2021 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 2 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 <target.h>
#include "image.h"
/* FSL includes */
#include "fsl_common.h"

/* Clock + RAM voltage settings */
#include "fsl_clock.h"
#include "fsl_spc.h"

/* Flash driver */
#include "fsl_romapi.h"

/*!< Core clock frequency: 96000000Hz */
#define BOARD_BOOTCLOCKFRO96M_CORE_CLOCK 96000000UL

static flash_config_t pflash;
static int flash_init = 0;

#ifdef __WOLFBOOT
/* Assert hook needed by Kinetis SDK */
void __assert_func(const char *a, int b, const char *c, const char *d)
{
while(1)
;
}

/* The following clock setting function is autogenerated by the MCUXpresso IDE */
void BOARD_BootClockFRO96M(void)
{
uint32_t coreFreq;
spc_active_mode_core_ldo_option_t ldoOption;
spc_sram_voltage_config_t sramOption;

/* Get the CPU Core frequency */
coreFreq = CLOCK_GetCoreSysClkFreq();

/* The flow of increasing voltage and frequency */
if (coreFreq <= BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) {
/* Set the LDO_CORE VDD regulator level */
ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage;
ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength;
(void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption);
/* Configure Flash to support different voltage level and frequency */
FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U));
/* Specifies the operating voltage for the SRAM's read/write timing margin */
sramOption.operateVoltage = kSPC_sramOperateAt1P1V;
sramOption.requestVoltageUpdate = true;
(void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption);
}

CLOCK_SetupFROHFClocking(96000000U); /*!< Enable FRO HF(96MHz) output */

CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */

CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */

/* The flow of decreasing voltage and frequency */
if (coreFreq > BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) {
/* Configure Flash to support different voltage level and frequency */
FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U));
/* Specifies the operating voltage for the SRAM's read/write timing margin */
sramOption.operateVoltage = kSPC_sramOperateAt1P1V;
sramOption.requestVoltageUpdate = true;
(void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption);
/* Set the LDO_CORE VDD regulator level */
ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage;
ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength;
(void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption);
}

/*!< Set up clock selectors - Attach clocks to the peripheries */

/*!< Set up dividers */
CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */
CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */
}

void hal_init(void)
{
/* Clock setting */
BOARD_BootClockFRO96M();

/* Clear the FLASH configuration structure */
memset(&pflash, 0, sizeof(pflash));
/* FLASH driver init */
FLASH_Init(&pflash);
}

void hal_prepare_boot(void)
{
}

#endif /* __WOLFBOOT */

int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
{
int ret;
int w = 0;
const uint8_t empty_qword[16] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

while (len > 0) {
if ((len < 16) || address & 0x0F) {
uint8_t aligned_qword[16];
uint32_t address_align = address - (address & 0x0F);
uint32_t start_off = address - address_align;
int i;

memcpy(aligned_qword, (void*)address_align, 16);
for (i = start_off; ((i < 16) && (i < len + (int)start_off)); i++) {
aligned_qword[i] = data[w++];
}
if (memcmp(aligned_qword, empty_qword, 16) != 0) {
ret = FLASH_ProgramPhrase(&pflash, address_align, aligned_qword, 16);
if (ret != kStatus_Success)
return -1;
}
address += i;
len -= i;
}
else {
uint32_t len_align = len - (len & 0x0F);
ret = FLASH_ProgramPhrase(&pflash, address, (uint8_t*)data + w, len_align);
if (ret != kStatus_Success)
return -1;
len -= len_align;
address += len_align;
}
}
return 0;
}

void RAMFUNCTION hal_flash_unlock(void)
{
}

void RAMFUNCTION hal_flash_lock(void)
{
}


int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
{
while ((address % 4) != 0)
address --;
if (FLASH_EraseSector(&pflash, address, len, kFLASH_ApiEraseKey) != kStatus_Success)
return -1;
return 0;
}
Loading
Loading