diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..b8d7fd7 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,25 @@ +on: + push: + +jobs: + build: + runs-on: ubuntu-22.04 + + steps: + - name: arm-none-eabi-gcc + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '10.3-2021.10' + + - name: Checkout + uses: actions/checkout@v3 + + - name: Make + run: make + + - name: 'Upload Artifact' + uses: actions/upload-artifact@v3 + with: + name: 'Flash Loader' + path: dp32-fl.elf + diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..c28ee4b --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,32 @@ +on: + push: + tags: + - '*' + +jobs: + build: + runs-on: ubuntu-22.04 + + steps: + - name: arm-none-eabi-gcc + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '10.3-2021.10' + + - name: Checkout + uses: actions/checkout@v3 + + - name: Make + run: make + + - name: 'Upload Artifact' + uses: actions/upload-artifact@v3 + with: + name: 'Flash Loader' + path: dp32-fl.elf + + - name: 'Create Release' + uses: ncipollo/release-action@v1 + with: + artifacts: "dp32-fl.elf,Devices.xml" + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6020452 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.d +*.o +*.elf diff --git a/Devices.xml b/Devices.xml new file mode 100644 index 0000000..050fd61 --- /dev/null +++ b/Devices.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..31bf51a --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +TARGET = dp32-fl + +OBJS = $(TARGET).o + +ifeq ($(OS),Windows_NT) +TOP := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +else +TOP := $(shell pwd) +endif + +AS = arm-none-eabi-as +CC = arm-none-eabi-gcc +LD = arm-none-eabi-gcc +OBJCOPY = arm-none-eabi-objcopy +SIZE = arm-none-eabi-size + +ASFLAGS = -mcpu=cortex-m0 +CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD -fno-toplevel-reorder +CFLAGS += -DPRINTF_INCLUDE_CONFIG_H +CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\" +LDFLAGS = -mcpu=cortex-m0 -nostartfiles -Wl,-T,dp32-fl.ld -Wl,-x + +INC = +LIBS = + +DEPS = $(OBJS:.o=.d) + +all: $(TARGET).elf + $(SIZE) $< + +$(TARGET).elf: $(OBJS) + $(LD) $(LDFLAGS) $^ -o $@ $(LIBS) + +%.o: %.c | $(BSP_HEADERS) + $(CC) $(CFLAGS) $(INC) -c $< -o $@ + +%.o: %.S + $(AS) $(ASFLAGS) $< -o $@ + +-include $(DEPS) + +clean: + rm -f $(TARGET).elf $(OBJS) $(DEPS) + diff --git a/README.md b/README.md index 281c5b8..553f87f 100644 --- a/README.md +++ b/README.md @@ -1 +1,41 @@ -# dp32g030-flash-loader \ No newline at end of file +# Flash Loader for Segger JLink software to support the DP32G030 + +This flash loader supports flashing to the DP32G030 as used in the [UV-K5](https://github.com/DualTachyon/uv-k5-firmware) class of radio transceivers. + +# Build + +``` +make +``` + +# Usage on Windows + +Create a folder: + +``` +md "%USERPROFILE%\AppData\Roaming\SEGGER\JLinkDevices" +md "%USERPROFILE%\AppData\Roaming\SEGGER\JLinkDevices\DualTachyon" +md "%USERPROFILE%\AppData\Roaming\SEGGER\JLinkDevices\DualTachyon\DP32G030" +copy Devices.xml "%USERPROFILE%\AppData\Roaming\SEGGER\JLinkDevices\DualTachyon\DP32G030\" +copy dp32-fl.elf "%USERPROFILE%\AppData\Roaming\SEGGER\JLinkDevices\DualTachyon\DP32G030\" +``` + +For Linux, you'll have to figure out the paths, but should be a similar approach as Windows. + +# License + +Copyright 2023 Dual Tachyon +https://github.com/DualTachyon + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/dp32-fl.c b/dp32-fl.c new file mode 100644 index 0000000..a85c17c --- /dev/null +++ b/dp32-fl.c @@ -0,0 +1,194 @@ +#include "flash.h" + +#define BLOCK_SIZE 512 + +typedef struct { + uint32_t Size; + uint32_t Address; +} SectorInfo_t; + +typedef struct { + uint16_t AlgoVer; + uint8_t Name[128]; + uint16_t Type; + uint32_t BaseAddr; + uint32_t TotalSize; + uint32_t PageSize; + uint32_t Reserved; + uint8_t ErasedVal; + uint8_t Padding[3]; + uint32_t TimeoutProg; + uint32_t TimeoutErase; + SectorInfo_t SectorInfo[2]; +} FlashDevice_t; + +extern const FlashDevice_t FlashDevice __attribute__((section(".constdata"))); + +const FlashDevice_t FlashDevice = { + 0x0101, + "DP32G030 Internal Flash", + 1, + 0x00000000, + 0x0000F000, + 0x00000200, + 0x00000000, + 0xFF, + { 0x00, 0x00, 0x00}, + 500, + 500, + { + { 0x00000200, 0x00000000 }, + { 0xFFFFFFFF, 0xFFFFFFFF }, + } +}; + +static void WaitNotBusy(void) +{ + while (1) { + if ((FLASH_ST & FLASH_ST_BUSY_MASK) == FLASH_ST_BUSY_BITS_READY) { + return; + } + } +} + +static void WaitForEmpty(void) +{ + while (1) { + if ((FLASH_ST & FLASH_ST_PROG_BUF_EMPTY_MASK) == FLASH_ST_PROG_BUF_EMPTY_BITS_EMPTY) { + return; + } + } +} + +static void FlashLock(void) +{ + FLASH_LOCK = FLASH_LOCK_LOCK_BITS_LOCK; +} + +static void FlashUnlock(void) +{ + FLASH_UNLOCK = FLASH_UNLOCK_UNLOCK_BITS_UNLOCK; +} + +static void FlashStart(void) +{ + FlashUnlock(); + + FLASH_START = FLASH_START_START_BITS_START; +} + +static void FlashStop(void) +{ + FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_MODE_MASK) | FLASH_CFG_MODE_VALUE_READ_AHB; +} + +static void FlashHalfSector(uint32_t Address, const uint8_t *pBuffer, uint32_t WordCount) +{ + const uint32_t *pWord = (const uint32_t *)pBuffer; + uint32_t i; + + WaitNotBusy(); + + FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_MODE_MASK) | FLASH_CFG_MODE_BITS_PROGRAM; + FLASH_ADDR = Address >> 2; + FLASH_WDATA = *pWord++; + + FlashStart(); + + for (i = 1; i < WordCount; i++) { + WaitForEmpty(); + FLASH_WDATA = *pWord++; + } + + WaitNotBusy(); + + FlashStop(); + FlashLock(); +} + +// -------- + +int Init(uint32_t Addr, uint32_t Freq, uint32_t Func) __attribute__((section("PrgCode"))); +int UnInit(uint32_t Func) __attribute__((section("PrgCode"))); +int EraseChip(void) __attribute__((section("PrgCode"))); +int EraseSector(uint32_t SectorAddr) __attribute__((section("PrgCode"))); +int ProgramPage(uint32_t DestAddr, uint32_t NumBytes, const uint8_t *pSrcBuff) __attribute__((section("PrgCode"))); +int CheckBlank(uint32_t Addr, uint32_t NumBytes, uint8_t BlankValue) __attribute__((section("PrgCode"))); + +int Init(uint32_t Addr, uint32_t Freq, uint32_t Func) +{ + if (FLASH_MASK != 6) { + FLASH_MASK = 0; + WaitNotBusy(); + FLASH_MASK = 6; + WaitNotBusy(); + if (FLASH_MASK != 6) { + return 1; + } + } + + return 0; +} + +int UnInit(uint32_t Func) +{ + // restore the MCU + + return 0; +} + +int EraseChip(void) +{ + uint16_t i; + + for (i = 0; i < 0xF000; i += 512) { + int ret = EraseSector(i); + + if (ret) { + return ret; + } + } + + return 0; +} + +int EraseSector(uint32_t SectorAddr) +{ + + if (SectorAddr % 512 || SectorAddr >= 0xF000) { + return 1; + } + + WaitNotBusy(); + + FLASH_CFG = (FLASH_CFG & ~FLASH_CFG_MODE_MASK) | FLASH_CFG_MODE_BITS_ERASE; + + FLASH_ADDR = SectorAddr >> 2; + + FlashStart(); + WaitNotBusy(); + FlashStop(); + FlashLock(); + + return 0; +} + + +int ProgramPage(uint32_t DestAddr, uint32_t NumBytes, const uint8_t *pBuffer) +{ + if (DestAddr % BLOCK_SIZE || DestAddr >= 0xF000 || NumBytes % BLOCK_SIZE || NumBytes > 0xF000 || (DestAddr + NumBytes) > 0xF000) { + return 1; + } + + while (NumBytes >= BLOCK_SIZE) { + FlashHalfSector(DestAddr + 0x0000, pBuffer + 0x0000, BLOCK_SIZE / 4); + FlashHalfSector(DestAddr + 0x0100, pBuffer + 0x0100, BLOCK_SIZE / 4); + NumBytes -= BLOCK_SIZE; + pBuffer += BLOCK_SIZE; + } + + FlashStop(); + FlashLock(); + + return 0; +} diff --git a/dp32-fl.ld b/dp32-fl.ld new file mode 100644 index 0000000..520a923 --- /dev/null +++ b/dp32-fl.ld @@ -0,0 +1,51 @@ +ENTRY(Init) + +MEMORY +{ + RAM (xrw) : ORIGIN = 0x00000000, LENGTH = 1K +} + +SECTIONS +{ + PrgCode : + { + . = ALIGN(4); + *(.PrgCode) + *(.PrgCode*) + *(.text) + *(.text*) + . = ALIGN(4); + } >RAM + + PrgData : + { + . = ALIGN(4); + *(.PrgData) + *(.PrgData*) + *(.data) + *(.data*) + *(.rodata) + *(.rodata*) + _sbss = .; + *(.bss) + *(.bss*) + . = ALIGN(4); + } >RAM + + DevDscr : + { + . = ALIGN(4); + *(.DevDscr) + *(.DevDscr*) + *(.constdata) + *(.constdata*) + . = ALIGN(4); + } >RAM + + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/flash.h b/flash.h new file mode 100644 index 0000000..f17b3d0 --- /dev/null +++ b/flash.h @@ -0,0 +1,165 @@ +/* Copyright 2023 Dual Tachyon + * https://github.com/DualTachyon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HARDWARE_DP32G030_FLASH_H +#define HARDWARE_DP32G030_FLASH_H + +#if !defined(__ASSEMBLY__) +#include +#endif + +/* -------- FLASH -------- */ +#define FLASH_BASE_ADDR 0x4006F000U +#define FLASH_BASE_SIZE 0x00000800U + +#define FLASH_CFG_ADDR (FLASH_BASE_ADDR + 0x0000U) +#define FLASH_CFG (*(volatile uint32_t *)FLASH_CFG_ADDR) +#define FLASH_CFG_READ_MD_SHIFT 0 +#define FLASH_CFG_READ_MD_WIDTH 1 +#define FLASH_CFG_READ_MD_MASK (((1U << FLASH_CFG_READ_MD_WIDTH) - 1U) << FLASH_CFG_READ_MD_SHIFT) +#define FLASH_CFG_READ_MD_VALUE_1_CYCLE 0U +#define FLASH_CFG_READ_MD_BITS_1_CYCLE (FLASH_CFG_READ_MD_VALUE_1_CYCLE << FLASH_CFG_READ_MD_SHIFT) +#define FLASH_CFG_READ_MD_VALUE_2_CYCLE 1U +#define FLASH_CFG_READ_MD_BITS_2_CYCLE (FLASH_CFG_READ_MD_VALUE_2_CYCLE << FLASH_CFG_READ_MD_SHIFT) + +#define FLASH_CFG_NVR_SEL_SHIFT 1 +#define FLASH_CFG_NVR_SEL_WIDTH 1 +#define FLASH_CFG_NVR_SEL_MASK (((1U << FLASH_CFG_NVR_SEL_WIDTH) - 1U) << FLASH_CFG_NVR_SEL_SHIFT) +#define FLASH_CFG_NVR_SEL_VALUE_MAIN 0U +#define FLASH_CFG_NVR_SEL_BITS_MAIN (FLASH_CFG_NVR_SEL_VALUE_MAIN << FLASH_CFG_NVR_SEL_SHIFT) +#define FLASH_CFG_NVR_SEL_VALUE_NVR 1U +#define FLASH_CFG_NVR_SEL_BITS_NVR (FLASH_CFG_NVR_SEL_VALUE_NVR << FLASH_CFG_NVR_SEL_SHIFT) + +#define FLASH_CFG_MODE_SHIFT 2 +#define FLASH_CFG_MODE_WIDTH 3 +#define FLASH_CFG_MODE_MASK (((1U << FLASH_CFG_MODE_WIDTH) - 1U) << FLASH_CFG_MODE_SHIFT) +#define FLASH_CFG_MODE_VALUE_READ_AHB 0U +#define FLASH_CFG_MODE_BITS_READ_AHB (FLASH_CFG_MODE_VALUE_READ_AHB << FLASH_CFG_MODE_SHIFT) +#define FLASH_CFG_MODE_VALUE_PROGRAM 1U +#define FLASH_CFG_MODE_BITS_PROGRAM (FLASH_CFG_MODE_VALUE_PROGRAM << FLASH_CFG_MODE_SHIFT) +#define FLASH_CFG_MODE_VALUE_ERASE 2U +#define FLASH_CFG_MODE_BITS_ERASE (FLASH_CFG_MODE_VALUE_ERASE << FLASH_CFG_MODE_SHIFT) +#define FLASH_CFG_MODE_VALUE_READ_APB 5U +#define FLASH_CFG_MODE_BITS_READ_APB (FLASH_CFG_MODE_VALUE_READ_APB << FLASH_CFG_MODE_SHIFT) + +#define FLASH_CFG_DEEP_PD_SHIFT 31 +#define FLASH_CFG_DEEP_PD_WIDTH 1 +#define FLASH_CFG_DEEP_PD_MASK (((1U << FLASH_CFG_DEEP_PD_WIDTH) - 1U) << FLASH_CFG_DEEP_PD_SHIFT) +#define FLASH_CFG_DEEP_PD_VALUE_NORMAL 0U +#define FLASH_CFG_DEEP_PD_BITS_NORMAL (FLASH_CFG_DEEP_PD_VALUE_NORMAL << FLASH_CFG_DEEP_PD_SHIFT) +#define FLASH_CFG_DEEP_PD_VALUE_LOW_POWER 1U +#define FLASH_CFG_DEEP_PD_BITS_LOW_POWER (FLASH_CFG_DEEP_PD_VALUE_LOW_POWER << FLASH_CFG_DEEP_PD_SHIFT) + +#define FLASH_ADDR_ADDR (FLASH_BASE_ADDR + 0x0004U) +#define FLASH_ADDR (*(volatile uint32_t *)FLASH_ADDR_ADDR) +#define FLASH_WDATA_ADDR (FLASH_BASE_ADDR + 0x0008U) +#define FLASH_WDATA (*(volatile uint32_t *)FLASH_WDATA_ADDR) +#define FLASH_RDATA_ADDR (FLASH_BASE_ADDR + 0x000CU) +#define FLASH_RDATA (*(volatile uint32_t *)FLASH_RDATA_ADDR) + +#define FLASH_START_ADDR (FLASH_BASE_ADDR + 0x0010U) +#define FLASH_START (*(volatile uint32_t *)FLASH_START_ADDR) +#define FLASH_START_START_SHIFT 0 +#define FLASH_START_START_WIDTH 1 +#define FLASH_START_START_MASK (((1U << FLASH_START_START_WIDTH) - 1U) << FLASH_START_START_SHIFT) +#define FLASH_START_START_VALUE_START 1U +#define FLASH_START_START_BITS_START (FLASH_START_START_VALUE_START << FLASH_START_START_SHIFT) + +#define FLASH_ST_ADDR (FLASH_BASE_ADDR + 0x0014U) +#define FLASH_ST (*(volatile uint32_t *)FLASH_ST_ADDR) +#define FLASH_ST_INIT_BUSY_SHIFT 0 +#define FLASH_ST_INIT_BUSY_WIDTH 1 +#define FLASH_ST_INIT_BUSY_MASK (((1U << FLASH_ST_INIT_BUSY_WIDTH) - 1U) << FLASH_ST_INIT_BUSY_SHIFT) +#define FLASH_ST_INIT_BUSY_VALUE_COMPLETE 0U +#define FLASH_ST_INIT_BUSY_BITS_COMPLETE (FLASH_ST_INIT_BUSY_VALUE_COMPLETE << FLASH_ST_INIT_BUSY_SHIFT) +#define FLASH_ST_INIT_BUSY_VALUE_BUSY 1U +#define FLASH_ST_INIT_BUSY_BITS_BUSY (FLASH_ST_INIT_BUSY_VALUE_BUSY << FLASH_ST_INIT_BUSY_SHIFT) + +#define FLASH_ST_BUSY_SHIFT 1 +#define FLASH_ST_BUSY_WIDTH 1 +#define FLASH_ST_BUSY_MASK (((1U << FLASH_ST_BUSY_WIDTH) - 1U) << FLASH_ST_BUSY_SHIFT) +#define FLASH_ST_BUSY_VALUE_READY 0U +#define FLASH_ST_BUSY_BITS_READY (FLASH_ST_BUSY_VALUE_READY << FLASH_ST_BUSY_SHIFT) +#define FLASH_ST_BUSY_VALUE_BUSY 1U +#define FLASH_ST_BUSY_BITS_BUSY (FLASH_ST_BUSY_VALUE_BUSY << FLASH_ST_BUSY_SHIFT) + +#define FLASH_ST_PROG_BUF_EMPTY_SHIFT 2 +#define FLASH_ST_PROG_BUF_EMPTY_WIDTH 1 +#define FLASH_ST_PROG_BUF_EMPTY_MASK (((1U << FLASH_ST_PROG_BUF_EMPTY_WIDTH) - 1U) << FLASH_ST_PROG_BUF_EMPTY_SHIFT) +#define FLASH_ST_PROG_BUF_EMPTY_VALUE_NOT_EMPTY 0U +#define FLASH_ST_PROG_BUF_EMPTY_BITS_NOT_EMPTY (FLASH_ST_PROG_BUF_EMPTY_VALUE_NOT_EMPTY << FLASH_ST_PROG_BUF_EMPTY_SHIFT) +#define FLASH_ST_PROG_BUF_EMPTY_VALUE_EMPTY 1U +#define FLASH_ST_PROG_BUF_EMPTY_BITS_EMPTY (FLASH_ST_PROG_BUF_EMPTY_VALUE_EMPTY << FLASH_ST_PROG_BUF_EMPTY_SHIFT) + +#define FLASH_LOCK_ADDR (FLASH_BASE_ADDR + 0x0018U) +#define FLASH_LOCK (*(volatile uint32_t *)FLASH_LOCK_ADDR) +#define FLASH_LOCK_LOCK_SHIFT 0 +#define FLASH_LOCK_LOCK_WIDTH 8 +#define FLASH_LOCK_LOCK_MASK (((1U << FLASH_LOCK_LOCK_WIDTH) - 1U) << FLASH_LOCK_LOCK_SHIFT) +#define FLASH_LOCK_LOCK_VALUE_LOCK 85U +#define FLASH_LOCK_LOCK_BITS_LOCK (FLASH_LOCK_LOCK_VALUE_LOCK << FLASH_LOCK_LOCK_SHIFT) + +#define FLASH_UNLOCK_ADDR (FLASH_BASE_ADDR + 0x001CU) +#define FLASH_UNLOCK (*(volatile uint32_t *)FLASH_UNLOCK_ADDR) +#define FLASH_UNLOCK_UNLOCK_SHIFT 0 +#define FLASH_UNLOCK_UNLOCK_WIDTH 8 +#define FLASH_UNLOCK_UNLOCK_MASK (((1U << FLASH_UNLOCK_UNLOCK_WIDTH) - 1U) << FLASH_UNLOCK_UNLOCK_SHIFT) +#define FLASH_UNLOCK_UNLOCK_VALUE_UNLOCK 170U +#define FLASH_UNLOCK_UNLOCK_BITS_UNLOCK (FLASH_UNLOCK_UNLOCK_VALUE_UNLOCK << FLASH_UNLOCK_UNLOCK_SHIFT) + +#define FLASH_MASK_ADDR (FLASH_BASE_ADDR + 0x0020U) +#define FLASH_MASK (*(volatile uint32_t *)FLASH_MASK_ADDR) +#define FLASH_MASK_SEL_SHIFT 0 +#define FLASH_MASK_SEL_WIDTH 2 +#define FLASH_MASK_SEL_MASK (((1U << FLASH_MASK_SEL_WIDTH) - 1U) << FLASH_MASK_SEL_SHIFT) +#define FLASH_MASK_SEL_VALUE_NONE 0U +#define FLASH_MASK_SEL_BITS_NONE (FLASH_MASK_SEL_VALUE_NONE << FLASH_MASK_SEL_SHIFT) +#define FLASH_MASK_SEL_VALUE_2KB 1U +#define FLASH_MASK_SEL_BITS_2KB (FLASH_MASK_SEL_VALUE_2KB << FLASH_MASK_SEL_SHIFT) +#define FLASH_MASK_SEL_VALUE_4KB 2U +#define FLASH_MASK_SEL_BITS_4KB (FLASH_MASK_SEL_VALUE_4KB << FLASH_MASK_SEL_SHIFT) +#define FLASH_MASK_SEL_VALUE_8KB 3U +#define FLASH_MASK_SEL_BITS_8KB (FLASH_MASK_SEL_VALUE_8KB << FLASH_MASK_SEL_SHIFT) + +#define FLASH_MASK_LOCK_SHIFT 2 +#define FLASH_MASK_LOCK_WIDTH 1 +#define FLASH_MASK_LOCK_MASK (((1U << FLASH_MASK_LOCK_WIDTH) - 1U) << FLASH_MASK_LOCK_SHIFT) +#define FLASH_MASK_LOCK_VALUE_NOT_SET 0U +#define FLASH_MASK_LOCK_BITS_NOT_SET (FLASH_MASK_LOCK_VALUE_NOT_SET << FLASH_MASK_LOCK_SHIFT) +#define FLASH_MASK_LOCK_VALUE_SET 1U +#define FLASH_MASK_LOCK_BITS_SET (FLASH_MASK_LOCK_VALUE_SET << FLASH_MASK_LOCK_SHIFT) + +#define FLASH_ERASETIME_ADDR (FLASH_BASE_ADDR + 0x0024U) +#define FLASH_ERASETIME (*(volatile uint32_t *)FLASH_ERASETIME_ADDR) +#define FLASH_ERASETIME_TERASE_SHIFT 0 +#define FLASH_ERASETIME_TERASE_WIDTH 19 +#define FLASH_ERASETIME_TERASE_MASK (((1U << FLASH_ERASETIME_TERASE_WIDTH) - 1U) << FLASH_ERASETIME_TERASE_SHIFT) +#define FLASH_ERASETIME_TRCV_SHIFT 19 +#define FLASH_ERASETIME_TRCV_WIDTH 12 +#define FLASH_ERASETIME_TRCV_MASK (((1U << FLASH_ERASETIME_TRCV_WIDTH) - 1U) << FLASH_ERASETIME_TRCV_SHIFT) + +#define FLASH_PROGTIME_ADDR (FLASH_BASE_ADDR + 0x0028U) +#define FLASH_PROGTIME (*(volatile uint32_t *)FLASH_PROGTIME_ADDR) +#define FLASH_PROGTIME_TPROG_SHIFT 0 +#define FLASH_PROGTIME_TPROG_WIDTH 11 +#define FLASH_PROGTIME_TPROG_MASK (((1U << FLASH_PROGTIME_TPROG_WIDTH) - 1U) << FLASH_PROGTIME_TPROG_SHIFT) +#define FLASH_PROGTIME_TPGS_SHIFT 11 +#define FLASH_PROGTIME_TPGS_WIDTH 11 +#define FLASH_PROGTIME_TPGS_MASK (((1U << FLASH_PROGTIME_TPGS_WIDTH) - 1U) << FLASH_PROGTIME_TPGS_SHIFT) + + +#endif +