Compare commits

...

10 Commits

Author SHA1 Message Date
zhji
e1aff431c0 [feat] update stach description in ld 2024-12-11 14:47:44 +08:00
zhji
0d6c458f31 [feat] add makefile for auto 2024-12-11 14:16:28 +08:00
2e86c7816c [feat] add uart_download 2024-11-20 22:20:01 +08:00
3de75b2326 [fix] update uart_log console 2024-11-20 22:19:36 +08:00
adef945b30 [feat] add qspi_flash driver 2024-11-17 22:04:45 +08:00
cb66bdd381 [feat] enable qspi module 2024-11-15 08:54:00 +08:00
d59a96bd51 [feat] enable interrupt 2024-11-15 08:53:29 +08:00
zhji
0e83ba9240 [feat] linker remove unused function 2024-11-11 11:21:06 +08:00
ac17c1662f [feat] add ltimer api 2024-11-10 17:14:44 +08:00
15dcf53e76 [update] update HSE_VALUE as 25MHz 2024-11-10 16:52:13 +08:00
16 changed files with 933 additions and 65 deletions

View File

@ -7,7 +7,7 @@ set(SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/..)
set(BOOTLOADER_PATH ${CMAKE_CURRENT_SOURCE_DIR})
# toolchain path
set(TOOLCHAIN "arm-none-eabi-")
# set(TOOLCHAIN ${CROSS_COMPILE})
set(CMAKE_C_COMPILER "${TOOLCHAIN}gcc")
set(CMAKE_ASM_COMPILER "${TOOLCHAIN}gcc")
set(CMAKE_OBJCOPY "${TOOLCHAIN}objcopy")
@ -16,17 +16,38 @@ set(CMAKE_AR "${TOOLCHAIN}ar")
set(CMAKE_RANLIB "${TOOLCHAIN}ranlib")
set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/flash.ld")
set(MCU_FLAGS "-mcpu=cortex-m7 -mthumb -g -O2 -Wall -nostartfiles -mfloat-abi=hard -mfpu=fpv5-d16 -fdata-sections -ffunction-sections -fdata-sections")
set(CMAKE_C_FLAGS "${MCU_FLAGS}")
set(CMAKE_ASM_FLAGS "${MCU_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${MCU_FLAGS} -T${LINKER_SCRIPT} -Wl,-Map=bootloader.map")
add_definitions(-DSTM32H750xx)
enable_language(ASM)
add_executable(${PROJ_NAME}.elf main.c)
target_sources(${PROJ_NAME}.elf PUBLIC start.S)
set(CMAKE_C_FLAGS " \
-mcpu=cortex-m7 \
-mthumb \
-g3 \
-O2 \
-Wall \
-nostartfiles \
-mfloat-abi=hard \
-mfpu=fpv5-d16 \
-ffunction-sections \
-fdata-sections \
")
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS " \
-ffunction-sections \
-fdata-sections \
-Wl,--gc-sections \
-T${LINKER_SCRIPT} \
-Wl,-Map=${PROJ_NAME}.map \
--specs=nano.specs \
-Wl,--print-memory-usage \
-Wl,--print-output-format \
")
add_definitions(-DSTM32H750xx)
add_subdirectory(${SDK_PATH}/driver driver)
add_subdirectory(${SDK_PATH}/component component)
add_subdirectory(${BOOTLOADER_PATH}/src src)
@ -38,5 +59,23 @@ target_link_libraries(${PROJ_NAME}.elf src)
add_custom_command(TARGET ${PROJ_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJ_NAME}.elf> ${BIN_FILE}
COMMAND ${CMAKE_OBJDUMP} -d -S $<TARGET_FILE:${PROJ_NAME}.elf> >${ASM_FILE}
COMMENT "Generate ${BIN_FILE}\r\n"
# COMMENT "Generate ${BIN_FILE}\r\n"
COMMAND echo "Calculating SHA-256 checksum for ${BIN_FILE}:"
COMMAND sha256sum ${BIN_FILE}
)
# get git tag
execute_process(
COMMAND git describe --abbrev=40 --tags --dirty --always
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(GIT_TAG)
set(PROJECT_SDK_VERSION ${GIT_TAG})
else()
message(WARNING "No Valid version info found for SDK!")
set(PROJECT_SDK_VERSION "version-unknown-panic")
endif()
message(STATUS "Project SDK Version: ${PROJECT_SDK_VERSION}")

18
bootloader/Makefile Normal file
View File

@ -0,0 +1,18 @@
CMAKE = cmake # use user cmake
cmake_generator = "Unix Makefiles"
RM = $(CMAKE) -E remove_directory
MAKEFLAGS += --no-print-directory
TOOLCHAIN ?= arm-none-eabi-
#cmake definition config
cmake_definition+= -DTOOLCHAIN=${TOOLCHAIN}
build:Makefile
$(CMAKE) -S . -B build -G $(cmake_generator) $(cmake_definition)
$(MAKE) -C build -j
clean::
$(RM) build
.PHONY:build clean

View File

@ -1,15 +1,16 @@
ENTRY(Reset_Handler)
StackSize = 0x4000; /* 16KB */
MEMORY
{
/*FLASH (rx) :ORIGIN = 0x08000000, LENGTH = 128K*/
/*ITCM (xrw) :ORIGIN = 0x00000000, LENGTH = 64K*/
FLASH (xr) :ORIGIN = 0x00000000, LENGTH = 64K
DTCM (xrw) :ORIGIN = 0x20000000, LENGTH = 112K
STACK (rw) :ORIGIN = 0x2001C000, LENGTH = 16K
DTCM (xrw) :ORIGIN = 0x20000000, LENGTH = 128K - StackSize
}
_stack_top = ORIGIN(STACK) + LENGTH(STACK);
_stack_top = ORIGIN(DTCM) + LENGTH(DTCM) + StackSize;
SECTIONS
{

View File

@ -1,12 +1,82 @@
#include "led.h"
#include "uart_log.h"
#include "ltimer.h"
#include "qspi_flash.h"
#include "uart_download.h"
#include "stdio.h"
void system_init(void)
{
/* Enable I-Cache */
SCB_EnableICache();
/* Enable D-Cache */
SCB_EnableDCache();
/* STM32H7xx HAL library initialization:
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Low Level Initialization
*/
HAL_Init();
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
HAL_StatusTypeDef ret = HAL_OK;
/*!< Supply configuration update enable */
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /* PWR set to LDO for the STM32H750B-DISCO board */
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 160;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLQ = 4;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
if(ret != HAL_OK) {
while(1);
}
/* Select PLL as system clock source and configure bus clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \
RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
if(ret != HAL_OK) {
while(1);
}
led_init(LED_PIN);
uart_log_init();
ltimer_init();
qspi_flash_init(3); /* 200MHz / (3 + 1) = 50MHz */
uart_download_init();
}
void led_blink(void)
@ -15,19 +85,54 @@ void led_blink(void)
led_off(LED_PIN);
}
extern UART_HandleTypeDef UartHandle;
uint8_t data[256];
int main(void)
{
// uint32_t ret;
system_init();
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// __enable_irq();
printf("Run start ...\r\n");
printf("SystemCoreClock = %ld\r\n", SystemCoreClock);
printf("SystemD2Clock = %ld\r\n", SystemD2Clock);
// ret = qspi_flash_erase_4kbytes(0);
// if (ret) {
// printf("qspi_flash_erase_4k error: 0x%08lX\r\n", ret);
// } else {
// printf("qspi_flash_erase_4k ok\r\n");
// }
// for (uint32_t i = 0; i < sizeof(data); i++) {
// data[i] = (uint8_t)(i & 0xFF);
// }
// ret = qspi_flash_write(0, data, sizeof(data));
// if (ret) {
// printf("qspi_flash_write error: 0x%08lX\r\n", ret);
// } else {
// printf("qspi_flash_write ok\r\n");
// }
while (1) {
static uint32_t count = 0;
printf("Hello World, count = %ld\r\n", count++);
uint64_t ms;
ms = ltimer_get_ms();
printf("Hello World, ms = %llu, tick = %ld\r\n", ms, HAL_GetTick());
// ret = qspi_flash_read(0, data, 30);
// if (ret) {
// printf("qspi_flash_read error: 0x%08lX\r\n", ret);
// } else {
// printf("qspi_flash_read ok\r\n");
// for (uint32_t i = 0; i < sizeof(data); i++) {
// if (i % 16 == 0) {
// printf("\r\n");
// }
// printf("%02X ", data[i]);
// }
// }
uart_download_send();
led_blink();
}
ltimer_delay_ms(1000);
}
return 0;
}

View File

@ -1,5 +1,6 @@
file(GLOB FILELIST
led.c
uart_download.c
)
add_library(src STATIC ${FILELIST})

View File

@ -0,0 +1,80 @@
#include "uart_download.h"
#include "stdio.h"
static UART_HandleTypeDef uart_download;
static void UART_DOWNLOAD_Msp_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
USART_DOWNLOAD_TX_GPIO_CLK_ENABLE();
USART_DOWNLOAD_RX_GPIO_CLK_ENABLE();
/* Select HSI as source of USARTx clocks */
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART_DOWNLOAD;
RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART_DOWNLOAD_CLKSOURCE_HSI;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
/* Enable USARTx clock */
USART_DOWNLOAD_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = USART_DOWNLOAD_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = USART_DOWNLOAD_TX_AF;
HAL_GPIO_Init(USART_DOWNLOAD_TX_GPIO_PORT, &GPIO_InitStruct);
/* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = USART_DOWNLOAD_RX_PIN;
GPIO_InitStruct.Alternate = USART_DOWNLOAD_RX_AF;
HAL_GPIO_Init(USART_DOWNLOAD_RX_GPIO_PORT, &GPIO_InitStruct);
/* NVIC for USART */
HAL_NVIC_SetPriority(USART_DOWNLOAD_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USART_DOWNLOAD_IRQn);
}
void uart_download_init(void)
{
uart_download.Instance = USART_DOWNLOAD;
uart_download.Init.BaudRate = UART_DOWNLOAD_BAUDRATE;
uart_download.Init.WordLength = UART_WORDLENGTH_8B;
uart_download.Init.StopBits = UART_STOPBITS_1;
uart_download.Init.Parity = UART_PARITY_NONE;
uart_download.Init.HwFlowCtl = UART_HWCONTROL_NONE;
uart_download.Init.Mode = UART_MODE_TX_RX;
uart_download.Init.ClockPrescaler = UART_PRESCALER_DIV1;
uart_download.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
uart_download.Init.OverSampling = UART_OVERSAMPLING_16;
UART_DOWNLOAD_Msp_Init();
if(HAL_UART_Init(&uart_download) != HAL_OK) {
printf("%s, %s, %d: HAL_UART_Init failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return;
}
/* Set the RXFIFO threshold */
HAL_UARTEx_SetRxFifoThreshold(&uart_download, UART_RXFIFO_THRESHOLD_1_2);
/* Enable the FIFO mode */
HAL_UARTEx_EnableFifoMode(&uart_download);
}
void uart_download_send(void)
{
if (__HAL_UART_GET_FLAG(&uart_download, UART_FLAG_TXFNF)) {
uart_download.Instance->TDR = 'A';
}
while (__HAL_UART_GET_FLAG(&uart_download, UART_FLAG_RXFNE)) {
printf("Recv: %02lX\r\n", uart_download.Instance->RDR);
}
}

View File

@ -0,0 +1,45 @@
#ifndef __UART_DOWNLOAD_H__
#define __UART_DOWNLOAD_H__
#include "stm32h7xx_hal.h"
#define UART_DOWNLOAD_BAUDRATE (500 * 1000)
#define HAL_TIMEOUT_VALUE 0xFFFFFFFF
#define USART_DOWNLOAD UART5
#define USART_DOWNLOAD_CLK_ENABLE() __HAL_RCC_UART5_CLK_ENABLE()
#define USART_DOWNLOAD_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define USART_DOWNLOAD_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define __HAL_RCC_UART_DOWNLOAD_CONFIG __HAL_RCC_UART5_CONFIG
#define RCC_UART_DOWNLOAD_CLKSOURCE_HSI RCC_USART234578CLKSOURCE_HSI
#define RCC_PERIPHCLK_USART_DOWNLOAD RCC_PERIPHCLK_UART5
#define RCC_USART_DOWNLOAD_CLKSOURCE_HSI RCC_USART234578CLKSOURCE_HSI
#define USART_DOWNLOAD_FORCE_RESET() __HAL_RCC_UART5_FORCE_RESET()
#define USART_DOWNLOAD_RELEASE_RESET() __HAL_RCC_UART5_RELEASE_RESET()
#define USART_DOWNLOAD_IRQn UART5_IRQn
#define USART_DOWNLOAD_IRQHandler UART5_IRQHandler
#define USART_DOWNLOAD_TX_PIN GPIO_PIN_13
#define USART_DOWNLOAD_TX_GPIO_PORT GPIOB
#define USART_DOWNLOAD_TX_AF GPIO_AF14_UART5
#define USART_DOWNLOAD_RX_PIN GPIO_PIN_12
#define USART_DOWNLOAD_RX_GPIO_PORT GPIOB
#define USART_DOWNLOAD_RX_AF GPIO_AF14_UART5
#ifdef __cplusplus
extern "C" {
#endif
void uart_download_init(void);
void uart_download_send(void);
#ifdef __cplusplus
}
#endif
#endif /* __UART_DOWNLOAD_H__ */

View File

@ -37,6 +37,11 @@ Reset_Handler:
blo 1b
2:
bl SystemInit
/* set vtor and enable interrupt */
ldr r0, =0xE000ED08
ldr r1, =0
str r1, [r0]
cpsie i
bl main
b .
.size Reset_Handler, .-Reset_Handler
@ -66,7 +71,7 @@ g_pfnVectors:
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word HAL_IncTick //SysTick_Handler
/* External Interrupts */
.word WWDG_IRQHandler /* Window WatchDog */

View File

@ -2,16 +2,11 @@
#include "stdarg.h"
#include "string.h"
UART_HandleTypeDef *console = NULL;
extern UART_HandleTypeDef UartHandle;
extern UART_HandleTypeDef console;
int putchar(int c)
{
if (console == NULL) {
return 0;
}
HAL_UART_Transmit(console, (uint8_t*)&c, 0, HAL_TIMEOUT_VALUE);
HAL_UART_Transmit(&console, (uint8_t*)&c, 0, HAL_TIMEOUT_VALUE);
return c;
}
@ -22,11 +17,7 @@ int puts(const char *c)
len = strlen(c);
if (console == NULL) {
return 0;
}
HAL_UART_Transmit(console, (uint8_t*)c, len, HAL_TIMEOUT_VALUE);
HAL_UART_Transmit(&console, (uint8_t*)c, len, HAL_TIMEOUT_VALUE);
return len;
}
@ -41,11 +32,7 @@ int putstring(const char *c)
len = strlen(c);
if (console == NULL) {
return 0;
}
HAL_UART_Transmit(console, (uint8_t*)c, len, HAL_TIMEOUT_VALUE);
HAL_UART_Transmit(&console, (uint8_t*)c, len, HAL_TIMEOUT_VALUE);
return len;
}
@ -63,7 +50,7 @@ int printf(const char *fmt, ...)
len = (len > sizeof(print_buf)) ? sizeof(print_buf) : len;
HAL_UART_Transmit(console, (uint8_t*)print_buf, len, HAL_TIMEOUT_VALUE);
HAL_UART_Transmit(&console, (uint8_t*)print_buf, len, HAL_TIMEOUT_VALUE);
return len;
}
@ -81,8 +68,3 @@ int printf(const char *fmt, ...)
return len;
}
#endif
void uart_log_set_console(void)
{
console = &UartHandle;
}

View File

@ -219,11 +219,11 @@ static inline void out_buffer(char character, void* buffer, size_t idx, size_t m
}
}
extern UART_HandleTypeDef *console;
extern UART_HandleTypeDef console;
static inline void out_console(char character, void* buffer, size_t idx, size_t maxlen)
{
while (!(__HAL_UART_GET_FLAG(console, UART_FLAG_TXFNF)));
console->Instance->TDR = (uint8_t)character;
while (!(__HAL_UART_GET_FLAG(&console, UART_FLAG_TXFNF)));
console.Instance->TDR = (uint8_t)character;
}

View File

@ -70,6 +70,7 @@
#define HAL_PCD_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_PSSI_MODULE_ENABLED
#define HAL_QSPI_MODULE_ENABLED
#define HAL_RAMECC_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_RNG_MODULE_ENABLED
@ -95,7 +96,7 @@
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)24000000) /*!< Value of the External oscillator in Hz */
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
@ -367,6 +368,10 @@
#include "stm32h7xx_hal_ospi.h"
#endif /* HAL_OSPI_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32h7xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_OTFDEC_MODULE_ENABLED
#include "stm32h7xx_hal_otfdec.h"
#endif /* HAL_OTFDEC_MODULE_ENABLED */

79
driver/board/ltimer.c Normal file
View File

@ -0,0 +1,79 @@
#include "ltimer.h"
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim4;
void ltimer_init(void)
{
__HAL_RCC_TIM2_CLK_ENABLE();
htim2.Instance = TIM2;
htim2.Init.Prescaler = (SystemD2Clock / 1000000) - 1; // 1us
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0xFFFFFFFF;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_Base_Init(&htim2);
__HAL_RCC_TIM4_CLK_ENABLE();
htim4.Instance = TIM4;
htim4.Init.Prescaler = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 0xFFFFFFFF;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_Base_Init(&htim4);
TIM_MasterConfigTypeDef sMasterConfig = {0};
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
sSlaveConfig.InputTrigger = TIM_TS_ITR1;
HAL_TIM_SlaveConfigSynchro(&htim4, &sSlaveConfig);
HAL_TIM_Base_Start(&htim2);
HAL_TIM_Base_Start(&htim4);
}
uint64_t ltimer_get_us(void)
{
uint32_t tim2_count;
uint32_t tim4_count_0, tim4_count_1;
uint64_t us;
do {
tim4_count_0 = __HAL_TIM_GET_COUNTER(&htim4);
tim2_count = __HAL_TIM_GET_COUNTER(&htim2);
tim4_count_1 = __HAL_TIM_GET_COUNTER(&htim4);
} while (tim4_count_0 != tim4_count_1);
us = (uint64_t)tim2_count | ((uint64_t)tim4_count_1 << 32);
return us;
}
uint64_t ltimer_get_ms(void)
{
return (ltimer_get_us() + 500) / 1000;
}
void ltimer_delay_us(uint32_t us)
{
uint64_t start;
start = ltimer_get_us();
while (ltimer_get_us() - start < us) {
}
}
void ltimer_delay_ms(uint32_t ms)
{
uint64_t start;
start = ltimer_get_us();
while (ltimer_get_us() - start < ms * 1000) {
}
}

20
driver/board/ltimer.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef __LTIMER_H__
#define __LTIMER_H__
#include "stm32h7xx_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
void ltimer_init(void);
uint64_t ltimer_get_us(void);
uint64_t ltimer_get_ms(void);
void ltimer_delay_us(uint32_t us);
void ltimer_delay_ms(uint32_t ms);
#ifdef __cplusplus
}
#endif
#endif /* __LTIMER_H__ */

387
driver/board/qspi_flash.c Normal file
View File

@ -0,0 +1,387 @@
#include "qspi_flash.h"
#include "stdio.h"
QSPI_HandleTypeDef QSPIHandle;
/**
* @brief This function polling for release busy status.
* @param hqspi: QSPI handle
* @retval error code
*/
static uint32_t QSPI_WaitforBusyRelease(QSPI_HandleTypeDef *hqspi)
{
QSPI_CommandTypeDef s_command;
QSPI_AutoPollingTypeDef s_config;
/* Configure automatic polling mode to wait for write enabling */
s_config.Match = 0x0;
s_config.Mask = (1 << 0); // BUSY
s_config.MatchMode = QSPI_MATCH_MODE_AND;
s_config.StatusBytesSize = 1;
s_config.Interval = 0x10;
s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = READ_STATUS_REG_CMD;
s_command.AddressMode = QSPI_ADDRESS_NONE;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"qspi auto polling for release busy\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((2 << 28) | s_config.Mask);
}
return 0;
}
/**
* @brief This function send a Write Enable and wait it is effective.
* @param hqspi: QSPI handle
* @retval None
*/
static uint32_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
{
QSPI_CommandTypeDef s_command;
QSPI_AutoPollingTypeDef s_config;
/* Enable write operations */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = WRITE_ENABLE_CMD;
s_command.AddressMode = QSPI_ADDRESS_NONE;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_NONE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"write enable\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((1 << 28) | s_command.Instruction);
}
/* Configure automatic polling mode to wait for write enabling */
s_config.Match = 0x2;
s_config.Mask = (1 << 1) | (1 << 0); // WEL | BUSY
s_config.MatchMode = QSPI_MATCH_MODE_AND;
s_config.StatusBytesSize = 1;
s_config.Interval = 0x10;
s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
s_command.Instruction = READ_STATUS_REG_CMD;
s_command.DataMode = QSPI_DATA_1_LINE;
if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"qspi auto polling for write enable\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((2 << 28) | s_config.Mask);
}
return 0;
}
void qspi_flash_init(uint32_t div)
{
GPIO_InitTypeDef gpio_init_structure;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable the QuadSPI memory interface clock */
QSPI_CLK_ENABLE();
/* Reset the QuadSPI memory interface */
QSPI_FORCE_RESET();
QSPI_RELEASE_RESET();
/* Enable GPIO clocks */
QSPI_CLK_GPIO_CLK_ENABLE();
QSPI_BK1_CS_GPIO_CLK_ENABLE();
QSPI_BK1_D0_GPIO_CLK_ENABLE();
QSPI_BK1_D1_GPIO_CLK_ENABLE();
QSPI_BK1_D2_GPIO_CLK_ENABLE();
QSPI_BK1_D3_GPIO_CLK_ENABLE();
/* Enable DMA clock */
QSPI_MDMA_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* QSPI CLK GPIO pin configuration */
gpio_init_structure.Pin = QSPI_CLK_PIN;
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
/* QSPI CS GPIO pin configuration */
gpio_init_structure.Pin = QSPI_BK1_CS_PIN;
gpio_init_structure.Pull = GPIO_PULLUP;
gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(QSPI_BK1_CS_GPIO_PORT, &gpio_init_structure);
/* QSPI D0 GPIO pin configuration */
gpio_init_structure.Pin = QSPI_BK1_D0_PIN;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(QSPI_BK1_D0_GPIO_PORT, &gpio_init_structure);
/* QSPI D1 GPIO pin configuration */
gpio_init_structure.Pin = QSPI_BK1_D1_PIN;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(QSPI_BK1_D1_GPIO_PORT, &gpio_init_structure);
/* QSPI D2 GPIO pin configuration */
gpio_init_structure.Pin = QSPI_BK1_D2_PIN;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(QSPI_BK1_D2_GPIO_PORT, &gpio_init_structure);
/* QSPI D3 GPIO pin configuration */
gpio_init_structure.Pin = QSPI_BK1_D3_PIN;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(QSPI_BK1_D3_GPIO_PORT, &gpio_init_structure);
/*##-3- Configure the NVIC for QSPI #########################################*/
/* NVIC configuration for QSPI interrupt */
// HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
// HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
/* Initialize QuadSPI structures ------------------------------------------- */
QSPIHandle.Instance = QUADSPI;
/* QSPI initialization */
/* ClockPrescaler set to 1, so QSPI clock = 200MHz / (1+1) = 100MHz */
QSPIHandle.Init.ClockPrescaler = div;
QSPIHandle.Init.FifoThreshold = 32;
QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
QSPIHandle.Init.FlashSize = QSPI_FLASH_SIZE;
QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_3_CYCLE;
QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;
QSPIHandle.Init.FlashID = QSPI_FLASH_ID_1;
QSPIHandle.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
/* Initialize QuadSPI ------------------------------------------------ */
HAL_QSPI_DeInit(&QSPIHandle);
if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) {
printf("%s: function %s, line %d, qspi init failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
while (1);
} else {
printf("qspi init succeed.\r\n");
}
}
void qspi_flash_deinit(void)
{
/*##-1- Disable the NVIC for QSPI ###########################################*/
HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
/*##-1- Disable peripherals ################################################*/
/* De-Configure QSPI pins */
HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
HAL_GPIO_DeInit(QSPI_BK1_CS_GPIO_PORT, QSPI_BK1_CS_PIN);
HAL_GPIO_DeInit(QSPI_BK1_D0_GPIO_PORT, QSPI_BK1_D0_PIN);
HAL_GPIO_DeInit(QSPI_BK1_D1_GPIO_PORT, QSPI_BK1_D1_PIN);
HAL_GPIO_DeInit(QSPI_BK1_D2_GPIO_PORT, QSPI_BK1_D2_PIN);
HAL_GPIO_DeInit(QSPI_BK1_D3_GPIO_PORT, QSPI_BK1_D3_PIN);
/*##-3- Reset peripherals ##################################################*/
/* Reset the QuadSPI memory interface */
QSPI_FORCE_RESET();
QSPI_RELEASE_RESET();
/* Disable the QuadSPI memory interface clock */
QSPI_CLK_DISABLE();
}
uint32_t qspi_flash_write(uint32_t addr, uint8_t *data, uint32_t length)
{
uint32_t ret;
QSPI_CommandTypeDef s_command;
ret = QSPI_WriteEnable(&QSPIHandle);
if (ret) {
return ret;
}
/* Initialize the read volatile configuration register command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = QUAD_IN_FAST_PROG_CMD;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = addr;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_4_LINES;
s_command.DummyCycles = 0;
s_command.NbData = length;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"QUAD_IN_FAST_PROG_CMD\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((1 << 28) | s_command.Instruction);
}
/* Writing of the data */
if (HAL_QSPI_Transmit(&QSPIHandle, data, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"HAL_QSPI_Transmit\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((3 << 28) | s_command.Instruction);
}
ret = QSPI_WaitforBusyRelease(&QSPIHandle);
if (ret) {
printf("%s: function %s, line %d, command \"busy after write\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ret;
}
return 0;
}
uint32_t qspi_flash_read(uint32_t addr, uint8_t *data, uint32_t length)
{
QSPI_CommandTypeDef s_command;
/* Initialize the read volatile configuration register command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = QUAD_OUT_FAST_READ_CMD;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = addr;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_4_LINES;
s_command.DummyCycles = 8;
s_command.NbData = length;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"QUAD_OUT_FAST_READ_CMD\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((1 << 28) | s_command.Instruction);
}
/* Reception of the data */
if (HAL_QSPI_Receive(&QSPIHandle, data, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"HAL_QSPI_Receive\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((3 << 28) | s_command.Instruction);
}
return 0;
}
uint32_t qspi_flash_erase_4kbytes(uint32_t addr)
{
uint32_t ret;
QSPI_CommandTypeDef s_command;
ret = QSPI_WriteEnable(&QSPIHandle);
if (ret) {
return ret;
}
/* Initialize the read volatile configuration register command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = SECTOR_ERASE_CMD;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = addr;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_NONE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"SECTOR_ERASE_CMD\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((1 << 28) | s_command.Instruction);
}
ret = QSPI_WaitforBusyRelease(&QSPIHandle);
if (ret) {
printf("%s: function %s, line %d, command \"busy after erasen 4K\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ret;
}
return 0;
}
uint32_t qspi_flash_erase_32kbytes(uint32_t addr)
{
uint32_t ret;
QSPI_CommandTypeDef s_command;
ret = QSPI_WriteEnable(&QSPIHandle);
if (ret) {
return ret;
}
/* Initialize the read volatile configuration register command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = SUBBLOCK_ERASE_CMD;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = addr;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_NONE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"SUBBLOCK_ERASE_CMD\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((1 << 28) | s_command.Instruction);
}
ret = QSPI_WaitforBusyRelease(&QSPIHandle);
if (ret) {
printf("%s: function %s, line %d, command \"busy after erasen 32K\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ret;
}
return 0;
}
uint32_t qspi_flash_erase_64kbytes(uint32_t addr)
{
uint32_t ret;
QSPI_CommandTypeDef s_command;
ret = QSPI_WriteEnable(&QSPIHandle);
if (ret) {
return ret;
}
/* Initialize the read volatile configuration register command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = BLOCK_ERASE_CMD;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = addr;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_NONE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("%s: function %s, line %d, command \"SUBBLOCK_ERASE_CMD\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ((1 << 28) | s_command.Instruction);
}
ret = QSPI_WaitforBusyRelease(&QSPIHandle);
if (ret) {
printf("%s: function %s, line %d, command \"busy after erasen 64K\" failed.\r\n", __FILE__, __FUNCTION__, __LINE__);
return ret;
}
return 0;
}

105
driver/board/qspi_flash.h Normal file
View File

@ -0,0 +1,105 @@
#ifndef __QSPI_FLASH_H__
#define __QSPI_FLASH_H__
#include "stm32h7xx_hal.h"
/* Definition for QSPI clock resources */
#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE()
#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE()
#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define QSPI_BK1_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define QSPI_BK1_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define QSPI_BK1_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define QSPI_BK1_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
#define QSPI_BK1_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define QSPI_MDMA_CLK_ENABLE() __HAL_RCC_MDMA_CLK_ENABLE()
#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET()
#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET()
/* Definition for QSPI Pins */
#define QSPI_CLK_PIN GPIO_PIN_2
#define QSPI_CLK_GPIO_PORT GPIOB
/* Bank 1 */
#define QSPI_BK1_CS_PIN GPIO_PIN_6
#define QSPI_BK1_CS_GPIO_PORT GPIOB
#define QSPI_BK1_D0_PIN GPIO_PIN_11
#define QSPI_BK1_D0_GPIO_PORT GPIOD
#define QSPI_BK1_D1_PIN GPIO_PIN_12
#define QSPI_BK1_D1_GPIO_PORT GPIOD
#define QSPI_BK1_D2_PIN GPIO_PIN_2
#define QSPI_BK1_D2_GPIO_PORT GPIOE
#define QSPI_BK1_D3_PIN GPIO_PIN_13
#define QSPI_BK1_D3_GPIO_PORT GPIOD
/* W25Q64JV memory */
/* Size of the flash */
#define QSPI_FLASH_SIZE 22
#define QSPI_PAGE_SIZE 256
/* Reset Operations */
#define RESET_ENABLE_CMD 0x66
#define RESET_MEMORY_CMD 0x99
/* Identification Operations */
#define READ_ID_CMD 0x9F
#define READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5A
/* Read Operations */
#define READ_CMD 0x03
#define FAST_READ_CMD 0x0B
#define DUAL_OUT_FAST_READ_CMD 0x3B
#define DUAL_INOUT_FAST_READ_CMD 0xBB
#define QUAD_OUT_FAST_READ_CMD 0x6B
#define QUAD_INOUT_FAST_READ_CMD 0xEB
/* Write Operations */
#define WRITE_ENABLE_CMD 0x06
#define WRITE_DISABLE_CMD 0x04
/* Register Operations */
#define READ_STATUS_REG_CMD 0x05
#define WRITE_STATUS_REG_CMD 0x01
/* Program Operations */
#define PAGE_PROG_CMD 0x02
#define QUAD_IN_FAST_PROG_CMD 0x32
/* Erase Operations */
#define SECTOR_ERASE_CMD 0x20 /* 4K-bytes */
#define SUBBLOCK_ERASE_CMD 0x52 /* 32K-bytes */
#define BLOCK_ERASE_CMD 0xD8 /* 64K-bytes */
#define CHIP_ERASE_CMD 0xC7
#define PROG_ERASE_RESUME_CMD 0x7A
#define PROG_ERASE_SUSPEND_CMD 0x75
/* Quad Operations */
#define ENTER_QUAD_CMD 0x38
#define EXIT_QUAD_CMD 0xFF
/* Default dummy clocks cycles */
#define DUMMY_CLOCK_CYCLES_READ 8
#define DUMMY_CLOCK_CYCLES_READ_QUAD 8
/* End address of the QSPI memory */
#define QSPI_END_ADDR (1 << (QSPI_FLASH_SIZE + 1))
#ifdef __cplusplus
extern "C" {
#endif
void qspi_flash_init(uint32_t div);
void qspi_flash_deinit(void);
uint32_t qspi_flash_write(uint32_t addr, uint8_t *data, uint32_t length);
uint32_t qspi_flash_read(uint32_t addr, uint8_t *data, uint32_t length);
uint32_t qspi_flash_erase_4kbytes(uint32_t addr);
uint32_t qspi_flash_erase_32kbytes(uint32_t addr);
uint32_t qspi_flash_erase_64kbytes(uint32_t addr);
#ifdef __cplusplus
}
#endif
#endif /* __QSPI_FLASH_H__ */

View File

@ -1,8 +1,6 @@
#include "uart_log.h"
UART_HandleTypeDef UartHandle;
extern void uart_log_set_console(void);
UART_HandleTypeDef console;
static void UART_LOG_Msp_Init(void)
{
@ -46,28 +44,26 @@ static void UART_LOG_Msp_Init(void)
void uart_log_init(void)
{
UartHandle.Instance = USART_LOG;
UartHandle.Init.BaudRate = UART_LOG_BAUDRATE;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1;
UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
console.Instance = USART_LOG;
console.Init.BaudRate = UART_LOG_BAUDRATE;
console.Init.WordLength = UART_WORDLENGTH_8B;
console.Init.StopBits = UART_STOPBITS_1;
console.Init.Parity = UART_PARITY_NONE;
console.Init.HwFlowCtl = UART_HWCONTROL_NONE;
console.Init.Mode = UART_MODE_TX_RX;
console.Init.ClockPrescaler = UART_PRESCALER_DIV1;
console.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
console.Init.OverSampling = UART_OVERSAMPLING_16;
UART_LOG_Msp_Init();
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
if(HAL_UART_Init(&console) != HAL_OK) {
while (1) {
}
}
/* Set the RXFIFO threshold */
HAL_UARTEx_SetRxFifoThreshold(&UartHandle, UART_RXFIFO_THRESHOLD_1_2);
HAL_UARTEx_SetRxFifoThreshold(&console, UART_RXFIFO_THRESHOLD_1_2);
/* Enable the FIFO mode */
HAL_UARTEx_EnableFifoMode(&UartHandle);
uart_log_set_console();
HAL_UARTEx_EnableFifoMode(&console);
}