Compare commits
10 Commits
01f4e20346
...
e1aff431c0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1aff431c0 | ||
|
|
0d6c458f31 | ||
| 2e86c7816c | |||
| 3de75b2326 | |||
| adef945b30 | |||
| cb66bdd381 | |||
| d59a96bd51 | |||
|
|
0e83ba9240 | ||
| ac17c1662f | |||
| 15dcf53e76 |
@ -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
18
bootloader/Makefile
Normal 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
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
file(GLOB FILELIST
|
||||
led.c
|
||||
uart_download.c
|
||||
)
|
||||
|
||||
add_library(src STATIC ${FILELIST})
|
||||
|
||||
80
bootloader/src/uart_download.c
Normal file
80
bootloader/src/uart_download.c
Normal 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);
|
||||
}
|
||||
}
|
||||
45
bootloader/src/uart_download.h
Normal file
45
bootloader/src/uart_download.h
Normal 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__ */
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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
79
driver/board/ltimer.c
Normal 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
20
driver/board/ltimer.h
Normal 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
387
driver/board/qspi_flash.c
Normal 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
105
driver/board/qspi_flash.h
Normal 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__ */
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user