Initial commit.

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-08-12 14:50:05 +08:00
commit 48330f7989
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
13 changed files with 554 additions and 0 deletions

12
.clang-format Normal file
View File

@ -0,0 +1,12 @@
BasedOnStyle: Google
IndentWidth: 4
AlignConsecutiveMacros: Consecutive
AlignConsecutiveDeclarations: Consecutive
AlignConsecutiveAssignments: Consecutive
AllowShortFunctionsOnASingleLine: None
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: false
AfterStruct: false
SplitEmptyFunction: false
ColumnLimit: 120

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/board/*.bak
/build
/cmake-build-*
/.vscode
/*.jdebug*
/*.jflash

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "SDK"]
path = SDK
url = https://git.minori.work/Embedded_SDK/PY32F0xx_SDK.git

83
CMakeLists.txt Normal file
View File

@ -0,0 +1,83 @@
cmake_minimum_required(VERSION 3.10)
project(py32f0xx_32k_flm)
enable_language(CXX)
enable_language(ASM)
# Different linker scripts
set(TARGET_LDSCRIPT_RAM "${CMAKE_SOURCE_DIR}/GCC/pic_app.ld")
set(TARGET_SOURCES
"src/FlashDev.c"
"src/FlashOperations.c"
"src/FlashPrg.c"
)
set(TARGET_C_DEFINES
"PY32F030x6"
)
set(TARGET_C_INCLUDES
"SDK/Drivers/PY32F0xx_HAL_Driver/Inc"
"SDK/Drivers/CMSIS/Include"
"SDK/Drivers/CMSIS/Device/PY32F0xx/Include"
"include"
)
# Shared libraries linked with application
set(TARGET_LIBS
"c"
"m"
"nosys"
)
# Shared library and linker script search paths
set(TARGET_LIB_DIRECTORIES
)
# Conditional flags
# DEBUG
set(CMAKE_C_FLAGS_DEBUG "-DDEBUG -O0 -g")
set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -O0 -g")
set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG -O0 -g")
# RELEASE
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -Os")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Os")
set(CMAKE_ASM_FLAGS_RELEASE "-DNDEBUG -Os")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "")
# Final compiler flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fPIC -fno-common -fno-builtin -ffreestanding -fdata-sections -ffunction-sections")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -fno-common -fno-builtin -ffreestanding -fdata-sections -ffunction-sections")
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections -nostartfiles")
# Shared sources, includes and definitions
add_compile_definitions(${TARGET_C_DEFINES})
include_directories(${TARGET_C_INCLUDES})
link_directories(${TARGET_LIB_DIRECTORIES})
link_libraries(${TARGET_LIBS})
# Main targets are added here
# Create ELF
add_executable("${CMAKE_PROJECT_NAME}_RAM.elf" ${TARGET_SOURCES})
target_link_options("${CMAKE_PROJECT_NAME}_RAM.elf"
PRIVATE "-T${TARGET_LDSCRIPT_RAM}"
PRIVATE "-Wl,--Map=${CMAKE_PROJECT_NAME}_RAM.map"
)
set_property(TARGET "${CMAKE_PROJECT_NAME}_RAM.elf" APPEND
PROPERTY ADDITIONAL_CLEAN_FILES "${CMAKE_PROJECT_NAME}_RAM.map"
)
add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_RAM.hex"
COMMAND ${CMAKE_OBJCOPY} "-O" "ihex" "${CMAKE_PROJECT_NAME}_RAM.elf" "${CMAKE_PROJECT_NAME}_RAM.hex"
DEPENDS "${CMAKE_PROJECT_NAME}_RAM.elf"
)
add_custom_target("${CMAKE_PROJECT_NAME}_RAM_HEX" DEPENDS "${CMAKE_PROJECT_NAME}_RAM.hex")
if(DEFINED TARGET_TOOLCHAIN_SIZE)
add_custom_command(TARGET "${CMAKE_PROJECT_NAME}_RAM.elf" POST_BUILD
COMMAND ${TARGET_TOOLCHAIN_SIZE} "${CMAKE_PROJECT_NAME}_RAM.elf"
)
endif()

61
GCC/pic_app.ld Normal file
View File

@ -0,0 +1,61 @@
/* Flash OS Routines
* Copyright (c) 2009-2015 ARM Limited
*
* 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.
*/
/*
* The PrgCode and PrgData output section names come from the CMSIS-Pack flash algo
* templates and armlink. It is used here because several tools that work
* with these flash algos expect this section name.
*/
SECTIONS
{
PrgCode 0 : ALIGN_WITH_INPUT
{
*(.text*)
KEEP (*(.text.Init))
KEEP (*(.text.UnInit))
KEEP (*(.text.EraseChip))
KEEP (*(.text.EraseSector))
KEEP (*(.text.ProgramPage))
KEEP (*(.text.Verify))
*(EXCLUDE_FILE (*FlashDev.*) .rodata)
*(EXCLUDE_FILE (*FlashDev.*) .rodata*)
. = ALIGN(16);
}
PrgData : ALIGN_WITH_INPUT
{
*(.data*)
*(.bss*)
*(.got*)
*(COMMON)
. = ALIGN(16);
}
DevDscr :
{
KEEP(*(.rodata.FlashDevice))
}
/DISCARD/ : {
/* Unused exception related info that only wastes space */
*(.ARM.exidx);
*(.ARM.exidx.*);
*(.ARM.extab.*);
}
}

1
SDK Submodule

@ -0,0 +1 @@
Subproject commit c87caf25cde7c3b2deb90f15896d6cb52dba0989

17
arm-none-eabi.cmake Normal file
View File

@ -0,0 +1,17 @@
# Poor old Windows...
if(WIN32)
set(CMAKE_SYSTEM_NAME "Generic")
endif()
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
# Optionally set size binary name, for elf section size reporting.
set(TARGET_TOOLCHAIN_SIZE arm-none-eabi-size)
set(CMAKE_C_FLAGS_INIT "-mcpu=cortex-m0plus -mthumb -mfloat-abi=soft")
set(CMAKE_CXX_FLAGS_INIT "-mcpu=cortex-m0plus -mthumb -mfloat-abi=soft")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nano.specs -specs=nosys.specs -Wl,--print-memory-usage -Wl,--no-warn-rwx-segments")
# Make CMake happy about those compilers
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")

12
include/FlashConfig.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef FLASH_CONFIG_H
#define FLASH_CONFIG_H
#define APP_FLASH_BASE (0x08000000) /* Base flash */
#define APP_FLASH_SIZE (32 * 1024) /* 32kB */
#define APP_FLASH_PAGE_SIZE (128) /* Strange */
#define APP_FLASH_SECTOR_SIZE (4 * 1024) /* 4kB */
#define APP_FLASH_SECTOR_ERASE_TIMEOUT (100) /* 100ms (3ms in manual) */
#define APP_FLASH_PAGE_PROGRAM_TIMEOUT (50) /* 50ms (1ms in manual) */
#define APP_FLASH_CHIP_ERASE_TIMEOUT (100) /* 100ms (4.5ms in manual) */
#endif // FLASH_CONFIG_H

84
include/FlashOS.h Normal file
View File

@ -0,0 +1,84 @@
/* -----------------------------------------------------------------------------
* Copyright (c) 2014 ARM Ltd.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software. Permission is granted to anyone to use this
* software for any purpose, including commercial applications, and to alter
* it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
*
* $Date: 14. Jan 2014
* $Revision: V1.00
*
* Project: FlashOS Headerfile for Flash drivers
* --------------------------------------------------------------------------- */
/* History:
* Version 1.00
* Initial release
*/
#define VERS 1 // Interface Version 1.01
#define UNKNOWN 0 // Unknown
#define ONCHIP 1 // On-chip Flash Memory
#define EXT8BIT 2 // External Flash Device on 8-bit Bus
#define EXT16BIT 3 // External Flash Device on 16-bit Bus
#define EXT32BIT 4 // External Flash Device on 32-bit Bus
#define EXTSPI 5 // External Flash Device on SPI
#define SECTOR_NUM 512 // Max Number of Sector Items
#define PAGE_MAX 65536 // Max Page Size for Programming
struct FlashSectors {
unsigned long szSector; // Sector Size in Bytes
unsigned long AddrSector; // Address of Sector
};
#define SECTOR_END 0xFFFFFFFF, 0xFFFFFFFF
struct FlashDevice {
unsigned short Vers; // Version Number and Architecture
char DevName[128]; // Device Name and Description
unsigned short DevType; // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...
unsigned long DevAdr; // Default Device Start Address
unsigned long szDev; // Total Size of Device
unsigned long szPage; // Programming Page Size
unsigned long Res; // Reserved for future Extension
unsigned char valEmpty; // Content of Erased Memory
unsigned long toProg; // Time Out of Program Page Function
unsigned long toErase; // Time Out of Erase Sector Function
struct FlashSectors sectors[SECTOR_NUM];
};
#define FLASH_DRV_VERS (0x0100+VERS) // Driver Version, do not modify!
// Flash Programming Functions (Called by FlashOS)
extern int Init (unsigned long adr, // Initialize Flash
unsigned long clk,
unsigned long fnc);
extern int UnInit (unsigned long fnc); // De-initialize Flash
extern int BlankCheck (unsigned long adr, // Blank Check
unsigned long sz,
unsigned char pat);
extern int EraseChip (void); // Erase complete Device
extern int EraseSector (unsigned long adr); // Erase Sector Function
extern int ProgramPage (unsigned long adr, // Program Page Function
unsigned long sz,
unsigned char *buf);
extern unsigned long Verify (unsigned long adr, // Verify Function
unsigned long sz,
unsigned char *buf);

14
include/FlashOperations.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef FLASH_OPERATIONS_H
#define FLASH_OPERATIONS_H
#include <stdint.h>
int Flash_Init(void);
int Flash_EraseSector(uint32_t addr);
int Flash_ProgramPage(uint32_t addr, uint8_t *data, uint32_t len);
int Flash_EraseChip(void);
int Flash_Map(void);
int Flash_UnMap(void);
int Flash_Deinit(void);
#endif // FLASH_OPERATIONS_H

23
src/FlashDev.c Normal file
View File

@ -0,0 +1,23 @@
#include "FlashConfig.h"
#include "FlashOS.h"
struct FlashDevice const FlashDevice = {
FLASH_DRV_VERS, // Driver Version, do not modify!
"PY32_PROGRAM", // Device Name
ONCHIP, // Device Type
APP_FLASH_BASE, // Device Start Address
APP_FLASH_SIZE, // Device Size in Bytes (64MB)
APP_FLASH_PAGE_SIZE, // Programming Page Size 512 Bytes (256 bytes per page * 2)
0x00, // Reserved, must be 0
0xFF, // Initial Content of Erased Memory
APP_FLASH_PAGE_PROGRAM_TIMEOUT, // Program Page Timeout 100 mSec
APP_FLASH_SECTOR_ERASE_TIMEOUT, // Erase Sector Timeout 6000 mSec
/* clang-format off */
// Specify Size and Address of Sectors
{
{APP_FLASH_SECTOR_SIZE, 0x000000,}, // Uniform sector/page layout
{SECTOR_END,},
},
/* clang-format on */
};

172
src/FlashOperations.c Normal file
View File

@ -0,0 +1,172 @@
/* Config */
#include "FlashConfig.h"
/* HAL */
#include "py32f0xx.h"
/* Private */
#include "FlashOperations.h"
#define APP_HSI_CALIB_24M_ADDR (0x1FFF0110UL)
#define APP_HSI_CALIB_VAL (*(uint8_t *)APP_HSI_CALIB_24M_ADDR)
#define APP_FLASH_CALIB_24M_ADDR (0x1FFF0F6CUL)
#define APP_FLASH_KEY1 (0x45670123UL)
#define APP_FLASH_KEY2 (0xCDEF89ABUL)
static inline int RCC_Init(void) {
/* Calibrate HSI */
RCC->ICSCR = (RCC->ICSCR & ~RCC_ICSCR_HSI_FS_Msk) | (4U << RCC_ICSCR_HSI_FS_Pos);
RCC->ICSCR = (RCC->ICSCR & ~RCC_ICSCR_HSI_TRIM_Msk) | (APP_HSI_CALIB_VAL << RCC_ICSCR_HSI_TRIM_Pos);
/* Enable HSI */
RCC->CR |= RCC_CR_HSION_Msk;
while ((RCC->CR & RCC_CR_HSIRDY_Msk) == 0UL) {
/* -- Wait for HSI ready -- */
}
/* HSI DIV : /1 */
RCC->CR = (RCC->CR & ~RCC_CR_HSIDIV_Msk) | (0U << RCC_CR_HSIDIV_Pos);
/* Switch System Clock to HSI */
RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_SW_Msk)) | (0U << RCC_CFGR_SW_Pos);
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != (0U << RCC_CFGR_SWS_Pos)) {
/* -- Wait for switch complete -- */
}
/* AHB DIV: /1 */
RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE_Msk)) | (0U << RCC_CFGR_HPRE_Pos);
return 0;
}
static inline int FMU_Init(void) {
/* Calibrate FMU */
FLASH->TS0 = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x00U) >> 0U) & 0xFFU;
FLASH->TS1 = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x00U) >> 16U) & 0x1FFU;
FLASH->TS2P = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x04U) >> 0U) & 0xFFU;
FLASH->TS3 = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x00U) >> 8U) & 0xFFU;
FLASH->TPS3 = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x04U) >> 16U) & 0x7FFU;
FLASH->PERTPE = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x08U) >> 0U) & 0x1FFFFU;
FLASH->SMERTPE = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x0CU) >> 0U) & 0x1FFFFU;
FLASH->PRGTPE = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x10U) >> 0U) & 0xFFFFU;
FLASH->PRETPE = ((*(volatile uint32_t *)APP_FLASH_CALIB_24M_ADDR + 0x10U) >> 16U) & 0xFFFFU;
return 0;
}
static inline int Flash_CheckBusy(void) {
if (FLASH->SR & FLASH_SR_BSY_Msk) {
return -1;
}
return 0;
}
static int Flash_CheckEoP(void) {
while (FLASH->SR & FLASH_SR_BSY_Msk) {
/* -- */
}
/* Check end-of-process */
if ((FLASH->SR & FLASH_SR_EOP_Msk) == 0U) {
return -1;
}
FLASH->SR |= FLASH_SR_EOP_Msk;
return 0;
}
static inline int Flash_Unlock(void) {
/* Unlock CR register */
if (FLASH->CR & FLASH_CR_LOCK_Msk) {
FLASH->KEYR = APP_FLASH_KEY1;
FLASH->KEYR = APP_FLASH_KEY2;
}
/* Check unlock result */
if (FLASH->CR & FLASH_CR_LOCK_Msk) {
return -1;
}
return 0;
}
static inline void Flash_Lock(void) {
FLASH->CR |= FLASH_CR_LOCK_Msk;
}
int Flash_Init(void) {
RCC_Init();
FMU_Init();
return Flash_Unlock();
}
int Flash_EraseSector(uint32_t addr) {
/* Check FMU busy status */
if (Flash_CheckBusy() != 0) {
return -1;
}
/* Select sector erase mode, de-select all other modes */
FLASH->CR &= ~(FLASH_CR_PG_Msk | FLASH_CR_MER_Msk | FLASH_CR_PER_Msk);
FLASH->CR |= FLASH_CR_SER_Msk | FLASH_CR_EOPIE_Msk;
/* Write arbitrary data to the sector to begin erase operation */
*(volatile uint32_t *)addr = 0xFFFFFFFFUL;
if (Flash_CheckEoP() != 0) {
return -3;
}
return 0;
}
int Flash_ProgramPage(uint32_t addr, uint8_t *data, uint32_t len) {
/* Check FMU busy status */
if (Flash_CheckBusy() != 0) {
return -1;
}
/* Select page program mode, de-select all other modes */
FLASH->CR &= ~(FLASH_CR_SER_Msk | FLASH_CR_MER_Msk | FLASH_CR_PER_Msk);
FLASH->CR |= FLASH_CR_PG_Msk | FLASH_CR_EOPIE_Msk;
for (uint8_t i = 0U; i < 32; i++) {
if (i == 31) {
FLASH->CR |= FLASH_CR_PGSTRT_Msk;
}
*(volatile uint32_t *)(addr + i * 4) = ((uint32_t *)data)[i];
}
if (Flash_CheckEoP() != 0) {
return -3;
}
return 0;
}
int Flash_EraseChip(void) {
/* Check FMU busy status */
if (Flash_CheckBusy() != 0) {
return -1;
}
/* Select mass erase mode, de-select all other modes */
FLASH->CR &= ~(FLASH_CR_PG_Msk | FLASH_CR_SER_Msk | FLASH_CR_PER_Msk);
FLASH->CR |= FLASH_CR_MER_Msk | FLASH_CR_EOPIE_Msk;
/* Write arbitrary data to flash to begin erase operation */
*(uint32_t *)APP_FLASH_BASE = 0xFFFFFFFFUL;
if (Flash_CheckEoP() != 0) {
return -2;
}
return 0;
}
int Flash_Deinit(void) {
Flash_Lock();
return 0;
}

66
src/FlashPrg.c Normal file
View File

@ -0,0 +1,66 @@
#include "FlashConfig.h"
#include "FlashOS.h"
#include "FlashOperations.h"
/*
* Initialize Flash Programming Functions
* Parameter: adr: Device Base Address
* clk: Clock Frequency (Hz)
* fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
* Return Value: 0 - OK, 1 - Failed
*/
int Init(unsigned long adr, unsigned long clk, unsigned long fnc) {
if (fnc == 3) return 0;
if (Flash_Init() != 0) return 1;
return 0;
}
/*
* De-Initialize Flash Programming Functions
* Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
* Return Value: 0 - OK, 1 - Failed
*/
int UnInit(unsigned long fnc) {
if (fnc == 3) return 0;
if (Flash_Deinit() != 0) return 1;
return 0;
}
/*
* Erase complete Flash Memory
* Return Value: 0 - OK, 1 - Failed
*/
int EraseChip(void) {
if (Flash_EraseChip() != 0) return 1;
return 0;
}
/*
* Erase Sector in Flash Memory
* Parameter: adr: Sector Address
* Return Value: 0 - OK, 1 - Failed
*/
int EraseSector(unsigned long adr) {
if (Flash_EraseSector(adr) != 0) return 1;
return 0;
}
/*
* Program Page in Flash Memory
* Parameter: adr: Page Start Address
* sz: Page Size
* buf: Page Data
* Return Value: 0 - OK, 1 - Failed
*/
int ProgramPage(unsigned long adr, unsigned long size, unsigned char *buffer) {
if (Flash_ProgramPage(adr, buffer, size) != 0) return 1;
return 0;
}
unsigned long Verify(unsigned long adr, unsigned long sz, unsigned char *buf) {
while (sz-- > 0) {
if (*(char *)adr++ != *((char *)buf++)) return (adr);
}
return adr;
}