Compare commits
33 commits
add-max32-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11e07c5a1b | ||
|
|
6c0c556436 | ||
|
|
5c0e9b8f9b | ||
|
|
55fede625d | ||
|
|
f4e9172f2f | ||
|
|
047e58f524 | ||
|
|
8542b474ff | ||
|
|
9c9a3328bd | ||
|
|
b250cb1408 | ||
|
|
c41356e5d8 | ||
|
|
0e5f9f7be4 | ||
|
|
aabf153172 | ||
|
|
9987ec807d | ||
|
|
11e33c0a7d | ||
|
|
cb628c3411 | ||
|
|
d8185b8d2f | ||
|
|
dd240b35b8 | ||
|
|
bb49fbb469 | ||
|
|
07a6d75710 | ||
|
|
2e1dc7fb69 | ||
|
|
00b57aa631 | ||
|
|
2419f6512a | ||
|
|
0805c2e70b | ||
|
|
822ec2aa30 | ||
|
|
81ec22f747 | ||
|
|
ef9729979c | ||
|
|
924b7d86f0 | ||
|
|
998bedb57c | ||
|
|
2ef7ccd2c4 | ||
|
|
a9dbffdfef | ||
|
|
977e99e8a5 | ||
|
|
0081b5ed06 | ||
|
|
3ea0f24242 |
46 changed files with 1603 additions and 617 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
|
@ -65,6 +65,7 @@ jobs:
|
|||
- 'lpc55'
|
||||
- 'mimxrt10xx'
|
||||
- 'stm32f3'
|
||||
- 'stm32h7'
|
||||
- 'stm32l4'
|
||||
with:
|
||||
port: ${{ matrix.port }}
|
||||
|
|
|
|||
20
.github/workflows/build_util.yml
vendored
20
.github/workflows/build_util.yml
vendored
|
|
@ -73,20 +73,22 @@ jobs:
|
|||
- name: Prepare Release Asset
|
||||
if: github.event_name == 'release'
|
||||
run: |
|
||||
if [ ${{ inputs.toolchain }} == 'esp-idf' ]; then
|
||||
if [ ${{ inputs.toolchain }} == esp-idf ]; then
|
||||
zip -jr tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.zip ${{ env.BIN_PATH }}
|
||||
cp ${{ env.BIN_PATH }}/combined.bin combined.bin
|
||||
[ -f ${{ env.BIN_PATH }}/combined-ota.bin ] && cp ${{ env.BIN_PATH }}/combined-ota.bin combined-ota.bin
|
||||
cp ${{ env.BIN_PATH }}/apps/update-tinyuf2.uf2 update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2
|
||||
else
|
||||
if [[ ${{ inputs.build-system }} == cmake ]]; then
|
||||
cp ${{ env.BIN_PATH }}/apps/update-tinyuf2.uf2 update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2
|
||||
[ -f ${{ env.BIN_PATH }}/apps/update-tinyuf2.uf2 ] && cp ${{ env.BIN_PATH }}/apps/update-tinyuf2.uf2 update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2
|
||||
else
|
||||
cp ${{ env.BIN_PATH }}/apps/update-tinyuf2-${{ matrix.board }}.uf2 update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2
|
||||
[ -f ${{ env.BIN_PATH }}/apps/update-tinyuf2-${{ matrix.board }}.uf2] && cp ${{ env.BIN_PATH }}/apps/update-tinyuf2-${{ matrix.board }}.uf2 update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2
|
||||
fi
|
||||
zip -jr tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.zip ${{ env.BIN_PATH }}
|
||||
fi
|
||||
|
||||
- name: Upload Release Asset
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: github.event_name == 'release'
|
||||
with:
|
||||
files: |
|
||||
|
|
@ -99,5 +101,11 @@ jobs:
|
|||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
if: github.event_name == 'release' && inputs.port == 'espressif'
|
||||
run: |
|
||||
[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.zip s3://adafruit-circuit-python/bootloaders/esp32/tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.zip --no-progress --region us-east-1
|
||||
[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2 s3://adafruit-circuit-python/bootloaders/esp32/update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2 --no-progress --region us-east-1
|
||||
if [ -n \"$AWS_ACCESS_KEY_ID\" ]; then
|
||||
aws s3 cp tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.zip s3://adafruit-circuit-python/bootloaders/esp32/${{ matrix.board }}/tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.zip --no-progress --region us-east-1
|
||||
aws s3 cp update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2 s3://adafruit-circuit-python/bootloaders/esp32/${{ matrix.board }}/update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2 --no-progress --region us-east-1
|
||||
aws s3 cp combined.bin s3://adafruit-circuit-python/bootloaders/esp32/${{ matrix.board }}/tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}-combined.bin --no-progress --region us-east-1
|
||||
if [ -f combined-ota.bin ]; then
|
||||
aws s3 cp combined-ota.bin s3://adafruit-circuit-python/bootloaders/esp32/${{ matrix.board }}/tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}-combined-ota.bin --no-progress --region us-east-1
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
4
.github/workflows/ci_set_matrix.py
vendored
4
.github/workflows/ci_set_matrix.py
vendored
|
|
@ -18,8 +18,8 @@ def set_matrix_json():
|
|||
if b.is_dir():
|
||||
matrix[p.name]['board'].append(b.name)
|
||||
# For quick testing by only build 1 espressif board
|
||||
if p.name == 'espressif':
|
||||
break
|
||||
# if p.name == 'espressif':
|
||||
# break
|
||||
print(json.dumps(matrix))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#define BOARD_UF2_FAMILY_ID 0xbfdd4eee
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define BOARD_UF2_FAMILY_ID 0xc47e5767
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define BOARD_UF2_FAMILY_ID 0x3d308e94
|
||||
#else
|
||||
#error unsupported MCUs
|
||||
#endif
|
||||
|
|
|
|||
2
ports/espressif/boards/sensebox_eye_esp32s3/board.cmake
Normal file
2
ports/espressif/boards/sensebox_eye_esp32s3/board.cmake
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Apply board specific content here
|
||||
set(IDF_TARGET "esp32s3")
|
||||
69
ports/espressif/boards/sensebox_eye_esp32s3/board.h
Normal file
69
ports/espressif/boards/sensebox_eye_esp32s3/board.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Ha Thach (tinyusb.org) for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SENSEBOX_EYE_ESP32S3_H_
|
||||
#define SENSEBOX_EYE_ESP32S3_H_
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Button
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Enter UF2 mode if GPIO is pressed while 2nd stage bootloader indicator
|
||||
// is on e.g RGB = Purple. If it is GPIO0, user should not hold this while
|
||||
// reset since that will instead run the 1st stage ROM bootloader
|
||||
#define PIN_BUTTON_UF2 0
|
||||
|
||||
// GPIO that implement 1-bit memory with RC components which hold the
|
||||
// pin value long enough for double reset detection.
|
||||
// #define PIN_DOUBLE_RESET_RC
|
||||
|
||||
// GPIO connected to Neopixel data
|
||||
#define NEOPIXEL_PIN 45
|
||||
|
||||
#define NEOPIXEL_POWER_STATE 1
|
||||
|
||||
// Brightness percentage from 1 to 255
|
||||
#define NEOPIXEL_BRIGHTNESS 0x10
|
||||
|
||||
// Number of neopixels
|
||||
#define NEOPIXEL_NUMBER 1
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB UF2
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define USB_VID 0x303A
|
||||
#define USB_PID 0x82D3
|
||||
#define USB_MANUFACTURER "senseBox"
|
||||
#define USB_PRODUCT "eye ESP32S3"
|
||||
|
||||
#define UF2_PRODUCT_NAME USB_MANUFACTURER " " USB_PRODUCT
|
||||
#define UF2_BOARD_ID "ESP32S3-senseBox-eye"
|
||||
#define UF2_VOLUME_LABEL "senseBox"
|
||||
#define UF2_INDEX_URL "https://sensebox.de"
|
||||
|
||||
// Use favicon
|
||||
#define TINYUF2_FAVICON_HEADER "favicon_sensebox_256.h"
|
||||
|
||||
#endif
|
||||
7
ports/espressif/boards/sensebox_eye_esp32s3/sdkconfig
Normal file
7
ports/espressif/boards/sensebox_eye_esp32s3/sdkconfig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Board Specific Config
|
||||
|
||||
# Partition Table
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-8MB.csv"
|
||||
|
||||
# Serial flasher config
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# Apply board specific content here
|
||||
set(IDF_TARGET "esp32s3")
|
||||
71
ports/espressif/boards/unexpectedmaker_edges3d/board.h
Normal file
71
ports/espressif/boards/unexpectedmaker_edges3d/board.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Ha Thach (tinyusb.org) for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UNEXPECTEDMAKER_EDGE3SD_H_
|
||||
#define UNEXPECTEDMAKER_EDGE3SD_H_
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Button
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Enter UF2 mode if GPIO is pressed while 2nd stage bootloader indicator
|
||||
// is on e.g RGB = Purple. If it is GPIO0, user should not hold this while
|
||||
// reset since that will instead run the 1st stage ROM bootloader
|
||||
#define PIN_BUTTON_UF2 0
|
||||
|
||||
// GPIO that implement 1-bit memory with RC components which hold the
|
||||
// pin value long enough for double reset detection.
|
||||
// #define PIN_DOUBLE_RESET_RC 47
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// LED
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// GPIO connected to Neopixel data
|
||||
// #define NEOPIXEL_PIN 35
|
||||
|
||||
// #define NEOPIXEL_POWER_PIN 34
|
||||
// #define NEOPIXEL_POWER_STATE 1
|
||||
|
||||
// Brightness percentage from 1 to 255
|
||||
// #define NEOPIXEL_BRIGHTNESS 0x64
|
||||
|
||||
// Number of neopixels
|
||||
#define NEOPIXEL_NUMBER 0
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB UF2
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define USB_VID 0x303A
|
||||
#define USB_PID 0x82DE
|
||||
#define USB_MANUFACTURER "Unexpected Maker"
|
||||
#define USB_PRODUCT "EDGES3D"
|
||||
|
||||
#define UF2_PRODUCT_NAME USB_MANUFACTURER " " USB_PRODUCT
|
||||
#define UF2_BOARD_ID "ESP32S3-EDGES3-01"
|
||||
#define UF2_VOLUME_LABEL "EDGES3BOOT"
|
||||
#define UF2_INDEX_URL "https://circuitpython.org/board/unexpectedmaker_edges3d/"
|
||||
|
||||
#endif
|
||||
7
ports/espressif/boards/unexpectedmaker_edges3d/sdkconfig
Normal file
7
ports/espressif/boards/unexpectedmaker_edges3d/sdkconfig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Board Specific Config
|
||||
|
||||
# Partition Table
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-8MB.csv"
|
||||
|
||||
# Serial flasher config
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
|
|
@ -40,6 +40,8 @@
|
|||
#define CFG_TUSB_MCU OPT_MCU_ESP32S2
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define CFG_TUSB_MCU OPT_MCU_ESP32S3
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define CFG_TUSB_MCU OPT_MCU_ESP32P4
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_OS OPT_OS_FREERTOS
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
|||
|
||||
set(UF2_FAMILY_ID_esp32s2 0xbfdd4eee)
|
||||
set(UF2_FAMILY_ID_esp32s3 0xc47e5767)
|
||||
set(UF2_FAMILY_ID_esp32p4 0x3d308e94)
|
||||
set(UF2_FAMILY_ID ${UF2_FAMILY_ID_${IDF_TARGET}})
|
||||
|
||||
# override default family_gen_uf2
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ if (NOT DEFINED TOOLCHAIN)
|
|||
set(TOOLCHAIN gcc)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Build type" FORCE)
|
||||
endif ()
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# FAMILY and BOARD
|
||||
#-------------------------------------------------------------
|
||||
|
|
@ -330,10 +334,17 @@ endfunction()
|
|||
# Add flash openocd adi (Analog Devices) target
|
||||
# included with msdk or compiled from release branch of https://github.com/analogdevicesinc/openocd
|
||||
function(family_flash_openocd_adi TARGET)
|
||||
if (DEFINED $ENV{MAXIM_PATH})
|
||||
# use openocd from msdk
|
||||
set(OPENOCD ENV{MAXIM_PATH}/Tools/OpenOCD/openocd)
|
||||
set(OPENOCD_OPTION2 "-s $ENV{MAXIM_PATH}/Tools/OpenOCD/scripts")
|
||||
if (DEFINED MAXIM_PATH)
|
||||
# use openocd from msdk with MAXIM_PATH cmake variable first if the user
|
||||
# specified it
|
||||
set(OPENOCD ${MAXIM_PATH}/Tools/OpenOCD/openocd)
|
||||
set(OPENOCD_OPTION2 "-s ${MAXIM_PATH}/Tools/OpenOCD/scripts")
|
||||
elseif (DEFINED ENV{MAXIM_PATH})
|
||||
# use openocd from msdk with MAXIM_PATH environment variable. Normalize
|
||||
# since msdk can be Windows (MinGW) or Linux
|
||||
file(TO_CMAKE_PATH "$ENV{MAXIM_PATH}" MAXIM_PATH_NORM)
|
||||
set(OPENOCD ${MAXIM_PATH_NORM}/Tools/OpenOCD/openocd)
|
||||
set(OPENOCD_OPTION2 "-s ${MAXIM_PATH_NORM}/Tools/OpenOCD/scripts")
|
||||
else()
|
||||
# compiled from source
|
||||
if (NOT DEFINED OPENOCD_ADI_PATH)
|
||||
|
|
|
|||
3
ports/maxim/.gitignore
vendored
3
ports/maxim/.gitignore
vendored
|
|
@ -1,3 +0,0 @@
|
|||
# Ignore build logs
|
||||
logs/
|
||||
*.log
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
# List of git submodules that is included as part of the UF2 version
|
||||
GIT_SUBMODULES = tinyusb
|
||||
|
||||
include ../make.mk
|
||||
include port.mk
|
||||
include ../rules.mk
|
||||
|
||||
################################################################################
|
||||
# Optional Save Log Support
|
||||
################################################################################
|
||||
ifeq ($(SAVELOG),1)
|
||||
TIMESTAMP := $(shell date +%Y%m%d_%H%M%S)
|
||||
LOG_SUFFIX = _$(TIMESTAMP).log
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Self-update
|
||||
################################################################################
|
||||
self-update:
|
||||
@mkdir -p $(TOP)/$(PORT_DIR)/apps/self_update/logs/self-update
|
||||
@echo "Building self-update application..."
|
||||
ifeq ($(SAVELOG),1)
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update uf2 2>&1 | tee $(TOP)/$(PORT_DIR)/apps/self_update/logs/self-update/self-update$(LOG_SUFFIX)
|
||||
else
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update uf2
|
||||
endif
|
||||
|
||||
self-update-clean:
|
||||
@mkdir -p $(TOP)/$(PORT_DIR)/apps/self_update/logs/self-update-clean
|
||||
@echo "Cleaning self-update application..."
|
||||
ifeq ($(SAVELOG),1)
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update clean 2>&1 | tee $(TOP)/$(PORT_DIR)/apps/self_update/logs/self-update-clean/self-update-clean$(LOG_SUFFIX)
|
||||
else
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update clean
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Erase Firmware
|
||||
################################################################################
|
||||
erase-firmware:
|
||||
@mkdir -p $(TOP)/$(PORT_DIR)/apps/erase_firmware/logs/erase-firmware
|
||||
@echo "Building erase-firmware application..."
|
||||
ifeq ($(SAVELOG),1)
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/erase_firmware uf2 2>&1 | tee $(TOP)/$(PORT_DIR)/apps/erase_firmware/logs/erase-firmware/erase-firmware$(LOG_SUFFIX)
|
||||
else
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/erase_firmware uf2
|
||||
endif
|
||||
|
||||
erase-firmware-clean:
|
||||
@mkdir -p $(TOP)/$(PORT_DIR)/apps/erase_firmware/logs/erase-firmware-clean
|
||||
@echo "Cleaning erase-firmware application..."
|
||||
ifeq ($(SAVELOG),1)
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/erase_firmware clean 2>&1 | tee $(TOP)/$(PORT_DIR)/apps/erase_firmware/logs/erase-firmware-clean/erase-firmware-clean$(LOG_SUFFIX)
|
||||
else
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/erase_firmware clean
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Blinky
|
||||
################################################################################
|
||||
blinky:
|
||||
@mkdir -p $(TOP)/$(PORT_DIR)/apps/blinky/logs/blinky
|
||||
@echo "Building blinky application..."
|
||||
ifeq ($(SAVELOG),1)
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/blinky uf2 2>&1 | tee $(TOP)/$(PORT_DIR)/apps/blinky/logs/blinky/blinky$(LOG_SUFFIX)
|
||||
else
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/blinky uf2
|
||||
endif
|
||||
|
||||
blinky-clean:
|
||||
@mkdir -p $(TOP)/$(PORT_DIR)/apps/blinky/logs/blinky-clean
|
||||
@echo "Cleaning blinky application..."
|
||||
ifeq ($(SAVELOG),1)
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/blinky clean 2>&1 | tee $(TOP)/$(PORT_DIR)/apps/blinky/logs/blinky-clean/blinky-clean$(LOG_SUFFIX)
|
||||
else
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/blinky clean
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Clean Logs
|
||||
################################################################################
|
||||
clean-logs:
|
||||
@echo "Cleaning all log files..."
|
||||
@rm -rf $(TOP)/$(PORT_DIR)/apps/self_update/logs
|
||||
@rm -rf $(TOP)/$(PORT_DIR)/apps/erase_firmware/logs
|
||||
@rm -rf $(TOP)/$(PORT_DIR)/apps/blinky/logs
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# TinyUF2 - MAX32690 Port
|
||||
|
||||
This folder contains the port of TinyUF2 for Analog Devices' MAX32690 MCU.
|
||||
This folder contains the port of TinyUF2 for Analog Devices' MAX32xxx/MAX78000 MCUs.
|
||||
|
||||
## Navigation
|
||||
|
||||
|
|
@ -17,16 +17,12 @@ This folder contains the port of TinyUF2 for Analog Devices' MAX32690 MCU.
|
|||
- [J-Link vs OpenOCD](#j-link-vs-openocd)
|
||||
- [Flashing with J-Link](#1-j-link-default)
|
||||
- [Flashing with OpenOCD (MSDK)](#2-openocd-from-msdk-optional)
|
||||
- [Notes on SAVELOG=1](#notes-on-savelog1)
|
||||
- [Cleaning Logs](#cleaning-logs)
|
||||
- [Flashing Example Applications](#flashing-example-applications)
|
||||
- [Flashing via Drag-and-Drop](#flashing-via-drag-and-drop)
|
||||
- [Re-Entering Bootloader Mode](#re-entering-bootloader-mode)
|
||||
- [Port Directory Structure](#port-directory-structure)
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## Requirements
|
||||
|
||||
This guide focuses on building TinyUF2 for Analog Devices' MAX32 parts.
|
||||
|
|
@ -40,13 +36,13 @@ All you need is a basic toolchain:
|
|||
|
||||
- **GNU ARM Toolchain** (`arm-none-eabi-gcc`) available in your `PATH`
|
||||
- **make**
|
||||
- **CMake**
|
||||
- **git** (required for submodules)
|
||||
- **SDK Dependencies**
|
||||
|
||||
|
||||
### Installing SDK Dependencies
|
||||
```bash
|
||||
python tools/get_deps.py max32
|
||||
python tools/get_deps.py maxim
|
||||
```
|
||||
or
|
||||
```bash
|
||||
|
|
@ -56,21 +52,13 @@ python tools/get_deps.py --board apard32690
|
|||
|
||||
#### macOS Dependency Install
|
||||
```bash
|
||||
brew install arm-none-eabi-gcc make git
|
||||
brew install arm-none-eabi-gcc make cmake git
|
||||
```
|
||||
|
||||
#### Ubuntu Dependency Install
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install gcc-arm-none-eabi make git
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
```bash
|
||||
# Example usage:
|
||||
cd ports/max32690/
|
||||
make BOARD=apard32690 all
|
||||
sudo apt install gcc-arm-none-eabi make cmake git
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -103,9 +91,6 @@ If needed, set `MAXIM_PATH` to point to your MSDK installation:
|
|||
export MAXIM_PATH=/c/MaximSDK
|
||||
```
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## MSDK (Windows) Environment Setup
|
||||
|
||||
### 1. Using MSDK's MSYS2
|
||||
|
|
@ -126,128 +111,122 @@ If you are using your own MSYS2 or mingw installation (not MSDK’s MSYS2), you
|
|||
export PATH="/c/MaximSDK/Tools/GNUTools/10.3/bin/:$PATH"
|
||||
```
|
||||
|
||||
Or in one-line command for building:
|
||||
|
||||
```bash
|
||||
PATH="/c/MaximSDK/Tools/GNUTools/10.3/bin/:$PATH" make BOARD=apard32690 blinky erase-firmware self-update
|
||||
```
|
||||
|
||||
(Adjust the path if your MSDK installation is in a different location.)
|
||||
|
||||
<br>
|
||||
|
||||
## Available Boards
|
||||
|
||||
Each port supports multiple hardware platforms.
|
||||
The specific boards available for each device can be found inside:
|
||||
|
||||
```
|
||||
ports/maxxxxxx/boards/
|
||||
ports/maxim/boards/
|
||||
```
|
||||
|
||||
For example, for MAX32690:
|
||||
For example:
|
||||
|
||||
```
|
||||
tinyuf2/ports/max32690/boards/
|
||||
tinyuf2/ports/maxim/boards/
|
||||
apard32690
|
||||
max32650evkit
|
||||
max32650fthr
|
||||
max32666evkit
|
||||
max32666fthr
|
||||
max32690evkit
|
||||
max78002evkit
|
||||
```
|
||||
|
||||
When building or flashing, make sure to specify a valid `BOARD` name from the available list:
|
||||
When initially configuring cmake, make sure to specify a valid `BOARD` name from the available list. Otherwise, the build will fail if an invalid board name is provided.
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 all
|
||||
make BOARD=apard32690 flash
|
||||
cmake -DBOARD=apard32690 ..
|
||||
```
|
||||
|
||||
Otherwise, the build will fail if an invalid board name is provided.
|
||||
Afterward, all the cmake/cmake commands can be run within the `build` directory without needing to specify the board again, as it will be cached.
|
||||
|
||||
<br>
|
||||
|
||||
## Building the Bootloader
|
||||
## Building the Bootloader and Applications
|
||||
|
||||
1. Open your MSYS2 terminal (preferably MSDK’s).
|
||||
2. Navigate to the port folder for MAX32690:
|
||||
2. Navigate to the maxim folder, create a build directory, and change into it:
|
||||
|
||||
```bash
|
||||
cd ports/max32690
|
||||
cd ports/maxim
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
|
||||
3. Build the TinyUF2 bootloader:
|
||||
3. Configure cmake with correct BOARD and run make to build:
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 all
|
||||
cmake -DBOARD=apard32690 ..
|
||||
make
|
||||
```
|
||||
|
||||
It will build the TinyUF2 bootloader along with all supported application e.g blinky, update-tinyuf2, erase-firmware. Tinyuf2 binaries will appear in `build/` folder while application are created in `build/apps/$(APP)/`.
|
||||
|
||||
Output files will appear in `_build/` and build logs under `apps/$(APP)/logs/`.
|
||||
- **Blinky** (`apps/blinky`) is useful to quickly test the bootloader
|
||||
- **Erase Firmware** (`apps/erase_firmware`) put the board into a clean state
|
||||
- **Self-Update** (`apps/self_update`) allows updating the bootloader itself
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
## Building Demo Applications
|
||||
|
||||
TinyUF2 for MAX32690 includes three demo applications:
|
||||
- **Blinky** (`apps/blinky`)
|
||||
- **Erase Firmware** (`apps/erase_firmware`)
|
||||
- **Self-Update** (`apps/self_update`)
|
||||
|
||||
### To Build Individual Applications:
|
||||
To list all supported targets, run:
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 blinky
|
||||
make BOARD=apard32690 erase-firmware
|
||||
make BOARD=apard32690 self-update
|
||||
cmake --build . --target help
|
||||
|
||||
The following are some of the valid targets for this Makefile:
|
||||
... all (the default if no target is provided)
|
||||
... clean
|
||||
... depend
|
||||
... edit_cache
|
||||
... rebuild_cache
|
||||
... blinky-uf2
|
||||
... erase_firmware-uf2
|
||||
... tinyuf2-erase-jlink
|
||||
... tinyuf2-jlink
|
||||
... tinyuf2-openocd
|
||||
... update-tinyuf2-uf2
|
||||
... blinky
|
||||
... board_max32666fthr
|
||||
... erase_firmware
|
||||
... tinyuf2
|
||||
... update-tinyuf2
|
||||
```
|
||||
|
||||
### To Clean Individual Applications:
|
||||
### To Build Individual Targets
|
||||
|
||||
To build a specific target, you can specify it directly with `make` or using `cmake --build`:
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 blinky-clean
|
||||
make BOARD=apard32690 erase-firmware-clean
|
||||
make BOARD=apard32690 self-update-clean
|
||||
```
|
||||
|
||||
You can add `SAVELOG=1` to any of these commands to generate a saved build log.
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 SAVELOG=1 blinky erase-firmware self-update
|
||||
make blinky
|
||||
cmake --build . --target blinky
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Flashing the Bootloader
|
||||
|
||||
|
||||
### J-Link vs OpenOCD
|
||||
### J-Link and OpenOCD
|
||||
|
||||
TinyUF2 supports two main ways to flash firmware:
|
||||
|
||||
- **J-Link** (default): Uses SEGGER's proprietary debug probe. Supports fast, reliable flashing and debugging over SWD or JTAG. Requires a J-Link device and SEGGER drivers.
|
||||
- **J-Link**: Uses SEGGER's proprietary debug probe. Supports fast, reliable flashing and debugging over SWD or JTAG. Requires a J-Link device and SEGGER drivers.
|
||||
|
||||
- **OpenOCD (MSDK)**: Open-source tool for programming/debugging via CMSIS-DAP or other adapters.
|
||||
The MSDK includes a custom version of OpenOCD that supports MAX32 devices, since official OpenOCD does not yet have MAX32 flash algorithm support.
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
`make flash` will use **J-Link** by default.
|
||||
`make flash-msdk` to use the **OpenOCD** path with CMSIS-DAP.
|
||||
|
||||
|
||||
|
||||
### 1. J-Link (default)
|
||||
### 1. J-Link
|
||||
|
||||
To flash using a J-Link debugger:
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 flash
|
||||
make tinyuf2-jlink
|
||||
```
|
||||
|
||||
To erase before flashing:
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 erase flash
|
||||
make tinyuf2-erase-jlink tinyuf2-jlink
|
||||
```
|
||||
|
||||
### 2. OpenOCD from MSDK (optional)
|
||||
|
|
@ -255,77 +234,56 @@ make BOARD=apard32690 erase flash
|
|||
If you prefer OpenOCD and you have it installed through MSDK:
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 flash-msdk
|
||||
make tinyuf2-openocd
|
||||
```
|
||||
|
||||
Make sure `MAXIM_PATH` is correctly set to the MSDK base folder. If your default installation of the MSDK is not `C:/MaximSDK` you can pass the MaximSDK directory's location...
|
||||
CMake will automatically leverage the MAXIM_PATH system environment variable if
|
||||
a MAXIM_PATH is not manually specified. To manually specify a MSDK path,
|
||||
you can pass the MaximSDK directory's location to cmake when configuring the
|
||||
build:
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 MAXIM_PATH=C:/MaximSDK flash-msdk
|
||||
cmake -DBOARD=apard32690 -DMAXIM_PATH=/path/to/MaximSDK ..
|
||||
```
|
||||
|
||||
> ⚠️ **Note:**
|
||||
> Optional flash option when running within an installed MSDK to use OpenOCD. Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. If the MSDK is installed, flash-msdk can be run to utilize the the modified openocd with the algorithms.
|
||||
|
||||
<br>
|
||||
|
||||
## Notes on SAVELOG=1
|
||||
|
||||
Log export options are available for demo apps.
|
||||
|
||||
If `SAVELOG=1` is set during a build:
|
||||
|
||||
- Output logs are automatically saved into a `logs/` folder inside each application.
|
||||
- Each application target (e.g., `blinky`, `blinky-clean`) has its own separate subfolder and timestamped `.log` files.
|
||||
- Log files are ignored from Git version control.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
apps/blinky/logs/blinky/blinky_20250425_134500.log
|
||||
apps/blinky/logs/blinky-clean/blinky-clean_20250425_134512.log
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Cleaning Logs
|
||||
|
||||
You can remove all saved build logs across all apps by running:
|
||||
or after initial configuration (in the build directory):
|
||||
|
||||
```bash
|
||||
make BOARD=apard32690 clean-logs
|
||||
cmake -DMAXIM_PATH=C:/MaximSDK .
|
||||
```
|
||||
|
||||
This deletes all `logs/` directories under `apps/blinky`, `apps/erase_firmware`, and `apps/self_update`.
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
## Flashing Example Applications
|
||||
|
||||
After building any of the demo applications (Blinky, Erase Firmware, or Self-Update), a UF2 file will be generated in:
|
||||
|
||||
```
|
||||
apps/<application>/_build/<board>/<application>-<board>.uf2
|
||||
build/apps/<application>/<application>.uf2
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
apps/blinky/_build/<board>/blinky-<board>.uf2
|
||||
apps/blinky/blinky.uf2
|
||||
```
|
||||
|
||||
### Flashing via Drag-and-Drop
|
||||
|
||||
1. **Enter bootloader mode** on your board:
|
||||
- Typically, perform a **double-tap on the reset button** within **500 milliseconds**.
|
||||
- The board will appear as a **USB mass storage device** (for example, named `TINYUF2`) in your operating system's **File Explorer** (Windows) or **Finder** (macOS) or **File Manager** (Linux).
|
||||
- The board will appear as a **USB mass storage device** (for example, named `3269BOOT`) in your operating system's **File Explorer** (Windows) or **Finder** (macOS) or **File Manager** (Linux).
|
||||
|
||||
2. **Using your file explorer**, locate the `.uf2` file you built, and **drag and drop** it onto the mounted TinyUF2 USB drive.
|
||||
|
||||
3. The board will automatically reboot and begin running the new application.
|
||||
|
||||
### Flashing using make/cmake
|
||||
|
||||
To flash an application using the command line, you can use the `make` or `cmake` command:
|
||||
|
||||
```bash
|
||||
make blinky-uf2
|
||||
cmake --build . --target blinky-uf2
|
||||
```
|
||||
|
||||
### Re-Entering Bootloader Mode
|
||||
|
||||
To flash a different application or return to bootloader mode:
|
||||
|
|
@ -333,47 +291,32 @@ To flash a different application or return to bootloader mode:
|
|||
- Perform another **double-tap** of the reset button within 500 milliseconds.
|
||||
- The board will reappear as a USB mass storage device for new UF2 flashing.
|
||||
|
||||
<br>
|
||||
|
||||
> ⚠️ **Note:**
|
||||
> If double-tap reset does not work (for example, if the running application has corrupted necessary flash metadata), you may need to manually reflash the TinyUF2 bootloader using a SWD debug tool such as J-Link or OpenOCD.
|
||||
> Refer to your board's documentation for additional recovery options if needed.
|
||||
|
||||
<br>
|
||||
|
||||
## Port Directory Structure
|
||||
|
||||
Example directory tree for the MAX32690 port:
|
||||
|
||||
```
|
||||
max32690
|
||||
├── Makefile
|
||||
├── README.md
|
||||
├── _build
|
||||
├── apps
|
||||
│ ├── blinky
|
||||
│ │ ├── Makefile
|
||||
│ │ └── _build
|
||||
│ ├── erase_firmware
|
||||
│ │ ├── Makefile
|
||||
│ │ └── _build
|
||||
│ └── self_update
|
||||
│ ├── Makefile
|
||||
│ └── _build
|
||||
├── app.cmake
|
||||
├── board_flash.c
|
||||
├── boards
|
||||
│ ├── apard32690
|
||||
│ │ ├── board.h
|
||||
│ │ └── board.mk
|
||||
│ └── max32690evkit
|
||||
│ ├── board.h
|
||||
│ └── board.mk
|
||||
│ ├── max32650evkit
|
||||
│ ├── max32650fthr
|
||||
│ ├── max32666evkit
|
||||
│ ├── max32666fthr
|
||||
│ ├── max32690evkit
|
||||
│ └── max78002evkit
|
||||
├── boards.c
|
||||
├── boards.h
|
||||
├── CMakeLists.txt
|
||||
├── family.cmake
|
||||
├── linker
|
||||
│ ├── max32690_app.ld
|
||||
│ ├── max32690_boot.ld
|
||||
│ └── max32690_common.ld
|
||||
├── port.mk
|
||||
│ ├── max32650
|
||||
│ ├── max32665
|
||||
│ ├── max32690
|
||||
│ └── max78002
|
||||
├── README.md
|
||||
└── tusb_config.h
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
PORT = max32690
|
||||
OUTNAME = blinky-$(BOARD)
|
||||
|
||||
BUILD_APPLICATION = 1
|
||||
BUILD_NO_TINYUSB = 1
|
||||
|
||||
include ../../../make.mk
|
||||
include ../../port.mk
|
||||
|
||||
SRC_C += \
|
||||
apps/blinky/blinky.c \
|
||||
|
||||
include ../../../rules.mk
|
||||
|
||||
uf2: $(BUILD)/$(OUTNAME).uf2
|
||||
|
||||
$(BUILD)/$(OUTNAME).uf2: $(BUILD)/$(OUTNAME).hex
|
||||
@echo CREATE $@
|
||||
$(PYTHON3) $(TOP)/lib/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID) -c -o $@ $^
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
PORT = max32690
|
||||
OUTNAME = erase_firmware-$(BOARD)
|
||||
|
||||
BUILD_APPLICATION = 1
|
||||
BUILD_NO_TINYUSB = 1
|
||||
|
||||
include ../../../make.mk
|
||||
include ../../port.mk
|
||||
|
||||
SRC_C += \
|
||||
apps/erase_firmware/erase_firmware.c \
|
||||
|
||||
include ../../../rules.mk
|
||||
|
||||
uf2: $(BUILD)/$(OUTNAME).uf2
|
||||
|
||||
$(BUILD)/$(OUTNAME).uf2: $(BUILD)/$(OUTNAME).hex
|
||||
@echo CREATE $@
|
||||
$(PYTHON3) $(TOP)/lib/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID) -c -o $@ $^
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
PORT = max32690
|
||||
OUTNAME = self-update-$(BOARD)
|
||||
|
||||
BUILD_APPLICATION = 1
|
||||
BUILD_NO_TINYUSB = 1
|
||||
|
||||
CFLAGS += -DTINYUF2_SELF_UPDATE
|
||||
|
||||
include ../../../make.mk
|
||||
include ../../port.mk
|
||||
|
||||
SRC_C += \
|
||||
apps/self_update/self_update.c \
|
||||
$(TOP)/$(PORT_DIR)/apps/self_update/_build/bootloader_bin.c \
|
||||
|
||||
include ../../../rules.mk
|
||||
|
||||
|
||||
uf2: $(BUILD)/$(OUTNAME).uf2
|
||||
|
||||
$(BUILD)/$(OUTNAME).uf2: $(BUILD)/$(OUTNAME).hex
|
||||
@echo CREATE $@
|
||||
$(PYTHON3) $(TOP)/lib/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID) -c -o $@ $^
|
||||
|
|
@ -1 +0,0 @@
|
|||
# No specific build requirements for the board.
|
||||
|
|
@ -1 +0,0 @@
|
|||
# No specific build requirements for the board.
|
||||
|
|
@ -1 +0,0 @@
|
|||
# No specific build requirements for the board.
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
set(MAX_DEVICE max32665)
|
||||
set(JLINK_DEVICE max32666)
|
||||
#set(JLINK_OPTION "-USB 801011822")
|
||||
|
||||
function(update_board TARGET)
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
# No specific build requirements for the board.
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
set(MAX_DEVICE max32665)
|
||||
set(JLINK_DEVICE max32666)
|
||||
#set(JLINK_OPTION "-USB 801011822")
|
||||
|
||||
function(update_board TARGET)
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
# No specific build requirements for the board.
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
set(MAX_DEVICE max32690)
|
||||
set(JLINK_DEVICE ${MAX_DEVICE})
|
||||
#set(JLINK_OPTION "-USB jtrace")
|
||||
|
||||
function(update_board TARGET)
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
# No specific build requirements for the board.
|
||||
|
|
@ -1 +0,0 @@
|
|||
# No specific build requirements for the board.
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
UF2_FAMILY_ID = 0x7410520a
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
JLINK_DEVICE = MAX32690
|
||||
|
||||
# Important locations in the hw support for MCU
|
||||
MAX32_CMSIS = lib/mcu/analog/msdk/Libraries/CMSIS
|
||||
MAX32_PERIPH = lib/mcu/analog/msdk/Libraries/PeriphDrivers
|
||||
PERIPH_SRC = $(MAX32_PERIPH)/Source
|
||||
|
||||
FLASH_BOOT_SIZE := 0x8000 #32K
|
||||
|
||||
# Port Compiler Flags
|
||||
CFLAGS += \
|
||||
-mthumb \
|
||||
-mabi=aapcs \
|
||||
-mcpu=cortex-m4 \
|
||||
|
||||
# Flags for TUSB features
|
||||
CFLAGS += \
|
||||
-DCFG_TUSB_MCU=OPT_MCU_MAX32690 \
|
||||
-DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
|
||||
|
||||
# Flags for the MAX32690 SDK
|
||||
CFLAGS += \
|
||||
-DTARGET=MAX32690 \
|
||||
-DTARGET_REV=0x4131 \
|
||||
-DMXC_ASSERT_ENABLE \
|
||||
-DMAX32690 \
|
||||
-DIAR_PRAGMAS=0 \
|
||||
-DFLASH_BOOT_SIZE=$(FLASH_BOOT_SIZE) \
|
||||
-DMAX_PERIPH_ID=18 \
|
||||
|
||||
|
||||
# mcu driver cause following warnings
|
||||
CFLAGS += \
|
||||
-Wno-error=unused-parameter \
|
||||
-Wno-error=strict-prototypes \
|
||||
-Wno-error=old-style-declaration \
|
||||
-Wno-error=sign-compare \
|
||||
-Wno-error=cast-qual \
|
||||
-Wno-lto-type-mismatch \
|
||||
|
||||
# default linker file
|
||||
ifdef BUILD_APPLICATION
|
||||
LD_FILES ?= \
|
||||
$(PORT_DIR)/linker/max32690/max32690_app.ld \
|
||||
$(PORT_DIR)/linker/max32690/max32690_common.ld
|
||||
else
|
||||
LD_FILES ?= \
|
||||
$(PORT_DIR)/linker/max32690/max32690_boot.ld \
|
||||
$(PORT_DIR)/linker/max32690/max32690_common.ld
|
||||
endif
|
||||
|
||||
LDFLAGS += -nostartfiles -Wl,--defsym=__FLASH_BOOT_SIZE=${FLASH_BOOT_SIZE} \
|
||||
|
||||
# Port source
|
||||
SRC_C += \
|
||||
$(PORT_DIR)/boards.c \
|
||||
$(PORT_DIR)/board_flash.c \
|
||||
$(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/heap.c \
|
||||
$(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/system_max32690.c \
|
||||
$(PERIPH_SRC)/SYS/mxc_assert.c \
|
||||
$(PERIPH_SRC)/SYS/mxc_delay.c \
|
||||
$(PERIPH_SRC)/SYS/mxc_lock.c \
|
||||
$(PERIPH_SRC)/SYS/nvic_table.c \
|
||||
$(PERIPH_SRC)/SYS/pins_me18.c \
|
||||
$(PERIPH_SRC)/SYS/sys_me18.c \
|
||||
$(PERIPH_SRC)/CTB/ctb_me18.c \
|
||||
$(PERIPH_SRC)/CTB/ctb_reva.c \
|
||||
$(PERIPH_SRC)/CTB/ctb_common.c \
|
||||
$(PERIPH_SRC)/FLC/flc_common.c \
|
||||
$(PERIPH_SRC)/FLC/flc_me18.c \
|
||||
$(PERIPH_SRC)/FLC/flc_reva.c \
|
||||
$(PERIPH_SRC)/GPIO/gpio_common.c \
|
||||
$(PERIPH_SRC)/GPIO/gpio_me18.c \
|
||||
$(PERIPH_SRC)/GPIO/gpio_reva.c \
|
||||
$(PERIPH_SRC)/ICC/icc_me18.c \
|
||||
$(PERIPH_SRC)/ICC/icc_reva.c \
|
||||
$(PERIPH_SRC)/UART/uart_common.c \
|
||||
$(PERIPH_SRC)/UART/uart_me18.c \
|
||||
$(PERIPH_SRC)/UART/uart_revb.c \
|
||||
|
||||
ifndef BUILD_NO_TINYUSB
|
||||
SRC_C += lib/tinyusb/src/portable/mentor/musb/dcd_musb.c
|
||||
endif
|
||||
|
||||
SRC_S += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/GCC/startup_max32690.S
|
||||
|
||||
# Port include
|
||||
INC += \
|
||||
$(TOP)/lib/CMSIS_5/CMSIS/Core/Include \
|
||||
$(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32690/Include \
|
||||
$(TOP)/$(MAX32_PERIPH)/Include/MAX32690 \
|
||||
$(TOP)/$(PERIPH_SRC)/SYS \
|
||||
$(TOP)/$(PERIPH_SRC)/GPIO \
|
||||
$(TOP)/$(PERIPH_SRC)/CTB \
|
||||
$(TOP)/$(PERIPH_SRC)/ICC \
|
||||
$(TOP)/$(PERIPH_SRC)/FLC \
|
||||
$(TOP)/$(PERIPH_SRC)/UART
|
||||
|
||||
# By default use JLink to the flash the devices since OpenOCD requires ADI's
|
||||
# OpenOCD fork until the part support can get mainlined. See flash-msdk below
|
||||
# to use OpenOCD from ADI
|
||||
flash: flash-jlink
|
||||
erase: erase-jlink
|
||||
|
||||
# Optional flash option when running within an installed MSDK to use OpenOCD
|
||||
# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated.
|
||||
# If the MSDK is installed, flash-msdk can be run to utilize the the modified
|
||||
# openocd with the algorithms
|
||||
|
||||
|
||||
# Convert Windows-style \ to /
|
||||
MAXIM_PATH := $(subst \,/,$(MAXIM_PATH))
|
||||
flash-msdk: $(BUILD)/$(OUTNAME).elf
|
||||
$(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \
|
||||
-f interface/cmsis-dap.cfg -f target/max32690.cfg \
|
||||
-c "program $(BUILD)/$(OUTNAME).elf verify; init; reset; exit"
|
||||
|
|
@ -22,11 +22,13 @@ include ../rules.mk
|
|||
# This uf2 will be loaded into RAM
|
||||
# TODO: this needs to build the actual uf2 binary first
|
||||
self-update: $(BUILD)/$(OUTNAME).bin
|
||||
$(PYTHON3) $(TOP)/lib/uf2/utils/uf2conv.py --carray $^ -o apps/self_update/_build/bootloader_bin.c
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update uf2
|
||||
@echo "not implemented yet"
|
||||
# $(PYTHON3) $(TOP)/lib/uf2/utils/uf2conv.py --carray $^ -o apps/self_update/_build/bootloader_bin.c
|
||||
# $(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update uf2
|
||||
|
||||
self-update-clean:
|
||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update clean
|
||||
@echo "not implemented yet"
|
||||
# $(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update clean
|
||||
|
||||
#---------- Erase app ----------
|
||||
# Compile apps/erase_firmware/erase_firmware.c
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@ OUTNAME = erase_firmware-$(BOARD)
|
|||
BUILD_NO_TINYUSB = 1
|
||||
|
||||
SRC_C += \
|
||||
apps/erase_firmware/erase_firmware.c \
|
||||
$(TOP)/$(PORT_DIR)/boards.c \
|
||||
$(TOP)/$(PORT_DIR)/board_flash.c \
|
||||
$(TOP)/$(PORT_DIR)/board_irq.c \
|
||||
$(TOP)/$(PORT_DIR)/components/w25qxx/w25qxx.c \
|
||||
$(TOP)/$(PORT_DIR)/components/w25qxx/w25qxx_qspi.c \
|
||||
apps/erase_firmware/src/erase_firmware.c \
|
||||
$(PORT_DIR)/boards.c \
|
||||
$(PORT_DIR)/board_flash.c \
|
||||
$(PORT_DIR)/board_irq.c \
|
||||
|
||||
INC += \
|
||||
$(TOP)/src \
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
OUTNAME = self_update-$(BOARD)
|
||||
# OUTNAME = self_update-$(BOARD)
|
||||
|
||||
# skip tinyusb
|
||||
BUILD_NO_TINYUSB = 1
|
||||
# # skip tinyusb
|
||||
# BUILD_NO_TINYUSB = 1
|
||||
|
||||
CFLAGS += -DTINYUF2_SELF_UPDATE
|
||||
# CFLAGS += -DTINYUF2_SELF_UPDATE
|
||||
|
||||
SRC_C += \
|
||||
apps/self_update/self_update.c \
|
||||
$(TOP)/$(PORT_DIR)/apps/self_update/_build/bootloader_bin.c \
|
||||
$(TOP)/$(PORT_DIR)/boards.c \
|
||||
$(TOP)/$(PORT_DIR)/board_hmi.c \
|
||||
$(TOP)/$(PORT_DIR)/board_irq.c \
|
||||
# SRC_C += \
|
||||
# apps/self_update/self_update.c \
|
||||
# $(TOP)/$(PORT_DIR)/apps/self_update/_build/bootloader_bin.c \
|
||||
# $(TOP)/$(PORT_DIR)/boards.c \
|
||||
# $(TOP)/$(PORT_DIR)/board_hmi.c \
|
||||
# $(TOP)/$(PORT_DIR)/board_irq.c \
|
||||
|
||||
INC += \
|
||||
$(TOP)/src \
|
||||
# INC += \
|
||||
# $(TOP)/src \
|
||||
|
||||
include ../app.mk
|
||||
# include ../app.mk
|
||||
|
||||
all:
|
||||
@echo "not implemented yet"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "board_api.h"
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include "qspi_status.h"
|
||||
|
||||
#ifdef W25Qx_SPI
|
||||
#include "components/w25qxx/w25qxx.h"
|
||||
|
|
@ -9,11 +10,16 @@
|
|||
#include "components/w25qxx/w25qxx_qspi.h"
|
||||
#endif // W25Qx_QSPI
|
||||
|
||||
#if BOARD_QSPI_FLASH_EN
|
||||
#ifdef IS25LP064A
|
||||
#include "components/is25lp064a/is25lp064a_qspi.h"
|
||||
#include "components/is25lp064a/is25lp064a.h"
|
||||
#endif
|
||||
|
||||
#if defined (BOARD_QSPI_FLASH_EN) && (BOARD_QSPI_FLASH_EN == 1)
|
||||
QSPI_HandleTypeDef _qspi_flash;
|
||||
#endif // BOARD_QSPI_FLASH_EN
|
||||
|
||||
#if BOARD_SPI_FLASH_EN
|
||||
#if defined (BOARD_SPI_FLASH_EN) && (BOARD_SPI_FLASH_EN == 1)
|
||||
SPI_HandleTypeDef _spi_flash;
|
||||
#endif // BOARD_SPI_FLASH_EN
|
||||
|
||||
|
|
@ -53,6 +59,67 @@ extern volatile uint32_t _board_tmp_boot_magic[];
|
|||
#define TMP_BOOT_ADDR _board_tmp_boot_addr[0]
|
||||
#define TMP_BOOT_MAGIC _board_tmp_boot_magic[0]
|
||||
|
||||
static void qspi_Init(void) {
|
||||
#ifdef W25Qx_QSPI
|
||||
w25qxx_Init();
|
||||
#endif
|
||||
#ifdef IS25LP064A
|
||||
CSP_QSPI_DisableMemoryMappedMode();
|
||||
CSP_QSPI_ExitQPIMODE();
|
||||
if (CSP_QUADSPI_Init() != qspi_OK) {
|
||||
TUF2_LOG1("Error initializing QSPI Flash\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void qspi_EnterQPI(void) {
|
||||
#ifdef W25Qx_QSPI
|
||||
w25qxx_EnterQPI();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void qspi_Startup(void) {
|
||||
#ifdef W25Qx_QSPI
|
||||
w25qxx_Startup(qspi_DTRMode);
|
||||
#endif
|
||||
#ifdef IS25LP064A
|
||||
if (CSP_QSPI_EnableMemoryMappedMode() != qspi_OK) {
|
||||
TUF2_LOG1("Error enabling memory map for QSPI Flash\r\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t qspi_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size) {
|
||||
#ifdef W25Qx_QSPI
|
||||
return w25qxx_Read(pData,ReadAddr,Size);
|
||||
#endif
|
||||
#ifdef IS25LP064A
|
||||
return CSP_QSPI_Read(pData, ReadAddr, Size);
|
||||
#endif
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
static uint8_t qspi_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) {
|
||||
#ifdef W25Qx_QSPI
|
||||
return w25qxx_Write(pData,WriteAddr,Size);
|
||||
#endif
|
||||
#ifdef IS25LP064A
|
||||
return CSP_QSPI_Write(pData,WriteAddr,Size);
|
||||
#endif
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
|
||||
static void qspi_EraseChip(void) {
|
||||
#ifdef W25Qx_QSPI
|
||||
w25qxx_EraseChip();
|
||||
#endif
|
||||
#ifdef IS25LP064A
|
||||
CSP_QSPI_Erase_Chip();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t board_get_app_start_address(void)
|
||||
{
|
||||
if (TMP_BOOT_MAGIC == 0xDEADBEEFU)
|
||||
|
|
@ -79,19 +146,19 @@ void board_clear_temp_boot_addr(void)
|
|||
|
||||
void board_flash_early_init(void)
|
||||
{
|
||||
#if BOARD_QSPI_FLASH_EN
|
||||
#if defined (BOARD_QSPI_FLASH_EN) && (BOARD_QSPI_FLASH_EN == 1)
|
||||
// QSPI is initialized early to check for executable code
|
||||
qspi_flash_init(&_qspi_flash);
|
||||
// Initialize QSPI driver
|
||||
w25qxx_Init();
|
||||
qspi_Init();
|
||||
// SPI -> QPI
|
||||
w25qxx_EnterQPI();
|
||||
qspi_EnterQPI();
|
||||
#endif // BOARD_QSPI_FLASH_EN
|
||||
}
|
||||
|
||||
void board_flash_init(void)
|
||||
{
|
||||
#if BOARD_SPI_FLASH_EN
|
||||
#if defined (BOARD_SPI_FLASH_EN) && (BOARD_SPI_FLASH_EN == 1)
|
||||
// Initialize SPI peripheral
|
||||
spi_flash_init(&_spi_flash);
|
||||
// Initialize SPI drivers
|
||||
|
|
@ -101,10 +168,10 @@ void board_flash_init(void)
|
|||
|
||||
void board_flash_deinit(void)
|
||||
{
|
||||
#if BOARD_QSPI_FLASH_EN
|
||||
#if defined (BOARD_QSPI_FLASH_EN) && (BOARD_QSPI_FLASH_EN == 1)
|
||||
// Enable Memory Mapped Mode
|
||||
// QSPI flash will be available at 0x90000000U (readonly)
|
||||
w25qxx_Startup(w25qxx_DTRMode);
|
||||
qspi_Startup();
|
||||
#endif // BOARD_QSPI_FLASH_EN
|
||||
}
|
||||
|
||||
|
|
@ -123,16 +190,16 @@ void board_flash_flush(void)
|
|||
void board_flash_read(uint32_t addr, void * data, uint32_t len)
|
||||
{
|
||||
TUF2_LOG1("Reading %lu byte(s) from 0x%08lx\r\n", len, addr);
|
||||
#if BOARD_QSPI_FLASH_EN
|
||||
#if defined (BOARD_QSPI_FLASH_EN) && (BOARD_QSPI_FLASH_EN == 1)
|
||||
// addr += QSPI_BASE_ADDR;
|
||||
if (IS_QSPI_ADDR(addr))
|
||||
{
|
||||
(void) W25qxx_Read(data, addr - QSPI_BASE_ADDR, len);
|
||||
(void) qspi_Read(data, addr - QSPI_BASE_ADDR, len);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BOARD_AXISRAM_EN
|
||||
#if defined (BOARD_AXISRAM_EN) && (BOARD_AXISRAM_EN == 1)
|
||||
if (IS_AXISRAM_ADDR(addr) && IS_AXISRAM_ADDR(addr + len - 1))
|
||||
{
|
||||
memcpy(data, (void *) addr, len);
|
||||
|
|
@ -156,11 +223,11 @@ bool board_flash_write(uint32_t addr, void const * data, uint32_t len)
|
|||
{
|
||||
TUF2_LOG1("Programming %lu byte(s) at 0x%08lx\r\n", len, addr);
|
||||
|
||||
// For external flash, W25Qx
|
||||
// For external flash
|
||||
// TODO: these should be configurable parameters
|
||||
// Page size = 256 bytes
|
||||
// Sector size = 4K bytes
|
||||
#if (BOARD_SPI_FLASH_EN == 1U)
|
||||
#if defined (BOARD_SPI_FLASH_EN) && (BOARD_SPI_FLASH_EN == 1U)
|
||||
if (IS_SPI_ADDR(addr) && IS_SPI_ADDR(addr + len - 1))
|
||||
{
|
||||
W25Qx_Write((uint8_t *) data, (addr - SPI_BASE_ADDR), len);
|
||||
|
|
@ -168,20 +235,30 @@ bool board_flash_write(uint32_t addr, void const * data, uint32_t len)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (BOARD_QSPI_FLASH_EN == 1)
|
||||
#if defined (BOARD_QSPI_FLASH_EN) && (BOARD_QSPI_FLASH_EN == 1)
|
||||
if (IS_QSPI_ADDR(addr) && IS_QSPI_ADDR(addr + len - 1))
|
||||
{
|
||||
// SET_BOOT_ADDR(BOARD_AXISRAM_APP_ADDR);
|
||||
// handles erasing internally
|
||||
if (W25qxx_Write((uint8_t *)data, (addr - QSPI_BASE_ADDR), len) != w25qxx_OK)
|
||||
#ifdef IS25LP064A
|
||||
// flash needs to be erased before writing
|
||||
if (addr % IS25LP064A_SECTOR_SIZE == 0) {
|
||||
// erase 4k sector ahead of next page writes
|
||||
if (CSP_QSPI_EraseSector(addr, addr+IS25LP064A_SECTOR_SIZE) != qspi_OK) {
|
||||
TUF2_LOG1("Error erasing sector at address: %lx \r\n",addr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (qspi_Write((uint8_t *)data, (addr - QSPI_BASE_ADDR), len) != qspi_OK)
|
||||
{
|
||||
TUF2_LOG1("Error QSPI Flash write\r\n");
|
||||
__asm("bkpt #9");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BOARD_AXISRAM_EN
|
||||
#if defined (BOARD_AXISRAM_EN) && (BOARD_AXISRAM_EN == 1)
|
||||
if (IS_AXISRAM_ADDR(addr) && IS_AXISRAM_ADDR(addr + len - 1))
|
||||
{
|
||||
// This memory is cached, DCache is cleaned in dfu_complete
|
||||
|
|
@ -211,13 +288,13 @@ void board_flash_erase_app(void)
|
|||
{
|
||||
board_flash_init();
|
||||
|
||||
#if BOARD_QSPI_FLASH_EN
|
||||
#if defined (BOARD_QSPI_FLASH_EN) && (BOARD_QSPI_FLASH_EN == 1)
|
||||
TUF2_LOG1("Erasing QSPI Flash\r\n");
|
||||
// Erase QSPI Flash
|
||||
(void) W25qxx_EraseChip();
|
||||
(void) qspi_EraseChip();
|
||||
#endif
|
||||
|
||||
#if BOARD_SPI_FLASH_EN
|
||||
#if defined(BOARD_SPI_FLASH_EN) && (BOARD_SPI_FLASH_EN == 1)
|
||||
TUF2_LOG1("Erasing SPI Flash\r\n");
|
||||
// Erase QSPI Flash
|
||||
(void) W25Qx_Erase_Chip();
|
||||
|
|
|
|||
|
|
@ -19,49 +19,44 @@ void ST7735_Delay(uint32_t ms)
|
|||
{
|
||||
HAL_Delay(ms);
|
||||
}
|
||||
#endif
|
||||
|
||||
void board_display_init(void)
|
||||
{
|
||||
#if (TINYUF2_DISPLAY == 1U)
|
||||
display_init(&_display_spi);
|
||||
ST7735_Init();
|
||||
// Clear previous screen
|
||||
ST7735_FillScreen(ST7735_BLACK);
|
||||
#endif // TINYUF2_DISPLAY == 1U
|
||||
}
|
||||
|
||||
// The application draws a complete frame in memory and sends it
|
||||
// line-by-line to the display
|
||||
void board_display_draw_line(int y, uint16_t* pixel_color, uint32_t pixel_num)
|
||||
{
|
||||
#if (TINYUF2_DISPLAY == 1U)
|
||||
for (uint32_t x = 0; x < pixel_num; x += 1) {
|
||||
ST7735_DrawPixel(y, x, pixel_color[x]);
|
||||
}
|
||||
#endif // TINYUF2_DISPLAY == 1U
|
||||
}
|
||||
|
||||
#endif // TINYUF2_DISPLAY == 1U
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// LED pattern
|
||||
//--------------------------------------------------------------------+
|
||||
#if defined(TINYUF2_LED)
|
||||
void board_led_write(uint32_t state)
|
||||
{
|
||||
#if defined(TINYUF2_LED)
|
||||
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
#endif // defined(LED_PIN)
|
||||
}
|
||||
#endif // defined(LED_PIN)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Button
|
||||
//--------------------------------------------------------------------+
|
||||
#if defined(BUTTON_PIN)
|
||||
uint32_t board_button_read(void)
|
||||
{
|
||||
#if defined(BUTTON_PIN)
|
||||
return (BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) ? 1: 0;
|
||||
#endif // defined(BUTTON_PIN)
|
||||
}
|
||||
#endif // defined(BUTTON_PIN)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Neopixel color for status
|
||||
|
|
|
|||
|
|
@ -1,8 +1,27 @@
|
|||
#include "stm32h7xx_hal.h"
|
||||
#include "board_api.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define STM32_UUID ((uint32_t *)0x1FF1E800)
|
||||
|
||||
#ifdef UART_DEV
|
||||
static UART_HandleTypeDef UartHandle;
|
||||
#endif
|
||||
|
||||
// fixes for linker warnings: _syscall is not implemented and will always fail
|
||||
void __weak _close(void) {
|
||||
}
|
||||
void __weak _lseek(void) {
|
||||
}
|
||||
void __weak _read(void) {
|
||||
}
|
||||
void __weak _write(void) {
|
||||
}
|
||||
void __weak _fstat(void) {
|
||||
}
|
||||
void __weak _isatty(void) {
|
||||
}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
SCB_EnableICache();
|
||||
|
|
@ -26,9 +45,31 @@ void board_init(void)
|
|||
__HAL_RCC_GPIOI_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOJ_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOK_CLK_ENABLE();
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
// UART
|
||||
#ifdef UART_DEV
|
||||
UART_CLOCK_ENABLE();
|
||||
GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = UART_GPIO_AF;
|
||||
HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
UartHandle.Instance = UART_DEV;
|
||||
UartHandle.Init.BaudRate = 115200;
|
||||
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
UartHandle.Init.StopBits = UART_STOPBITS_1;
|
||||
UartHandle.Init.Parity = UART_PARITY_NONE;
|
||||
UartHandle.Init.Mode = UART_MODE_TX_RX;
|
||||
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
||||
UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1;
|
||||
UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
HAL_UART_Init(&UartHandle);
|
||||
#endif
|
||||
memset(&GPIO_InitStruct,0,sizeof(GPIO_InitStruct));
|
||||
#ifdef BUTTON_PIN
|
||||
GPIO_InitStruct.Pin = BUTTON_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
|
|
@ -53,8 +94,8 @@ void board_init(void)
|
|||
void board_dfu_init(void)
|
||||
{
|
||||
// Not quite sure what an RHPORT is :/
|
||||
#if BOARD_TUD_RHPORT == 0
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
#if defined (BOARD_TUD_RHPORT) && (BOARD_TUD_RHPORT == 0)
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
// Init USB Pins
|
||||
// Configure DM DP pins
|
||||
|
|
@ -81,7 +122,7 @@ void board_dfu_init(void)
|
|||
USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
|
||||
USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
|
||||
|
||||
#elif BOARD_TUD_RHPORT == 1
|
||||
#elif defined (BOARD_TUD_RHPORT) && (BOARD_TUD_RHPORT == 1)
|
||||
// TODO: implement whatever this is
|
||||
#error "Sorry, not implemented yet"
|
||||
#endif
|
||||
|
|
@ -112,8 +153,8 @@ bool board_app_valid(void)
|
|||
switch ((app_vector[0] & 0xFFFF0003u))
|
||||
{
|
||||
case 0x00000000u: // ITCM 64K [0x0000_0000u--0x0000_FFFFu]
|
||||
case 0x20000000u: // DTCM 64K [0x2000_0000u--0x2000_FFFFu]
|
||||
case 0x20010000u: // DTCM 64K [0x2001_0000u--0x2001_FFFFu]
|
||||
case 0x20010000u: // DTCM 64K [0x2000_0000u--0x2000_FFFFu]
|
||||
case 0x20020000u: // DTCM 64K [0x2001_0000u--0x2001_FFFFu]
|
||||
case 0x24000000u: // AXI SRAM 512K [0x2400_0000u--0x2407_FFFFu]
|
||||
case 0x30010000u: // SRAM1 64K [0x3001_0000u--0x3001_FFFFu]
|
||||
case 0x30020000u: // SRAM2 64K [0x3002_0000u--0x3002_FFFFu]
|
||||
|
|
@ -170,16 +211,32 @@ void board_app_jump(void)
|
|||
__HAL_RCC_GPIOJ_CLK_DISABLE();
|
||||
__HAL_RCC_GPIOK_CLK_DISABLE();
|
||||
// Lotsa GPIOs
|
||||
uint8_t allow_rcc_deinit = 1;
|
||||
|
||||
// rcc clock needs to be enabled when executing code from external flash
|
||||
#if defined(BOARD_QSPI_FLASH_EN) && (BOARD_QSPI_FLASH_EN == 1)
|
||||
allow_rcc_deinit = 0;
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_SPI_FLASH_EN) && (BOARD_SPI_FLASH_EN == 1)
|
||||
allow_rcc_deinit = 0;
|
||||
#endif
|
||||
|
||||
if (allow_rcc_deinit) {
|
||||
HAL_RCC_DeInit();
|
||||
}
|
||||
|
||||
HAL_RCC_DeInit();
|
||||
SCB_DisableICache();
|
||||
SCB_DisableDCache();
|
||||
|
||||
// Clear temporary boot address
|
||||
board_clear_temp_boot_addr();
|
||||
|
||||
// Setup VTOR to point to application vectors
|
||||
SCB->VTOR = (uint32_t) app_addr;
|
||||
#ifdef UART_DEV
|
||||
HAL_UART_DeInit(&UartHandle);
|
||||
HAL_GPIO_DeInit(UART_GPIO_PORT, UART_TX_PIN | UART_RX_PIN);
|
||||
UART_CLOCK_DISABLE();
|
||||
#endif
|
||||
|
||||
// Set stack pointer
|
||||
__set_MSP(app_vector[0]);
|
||||
|
|
@ -187,6 +244,11 @@ void board_app_jump(void)
|
|||
|
||||
TUF2_LOG1("App address: %08lx\r\n", app_vector[1]);
|
||||
|
||||
// Setup VTOR to point to application vectors
|
||||
__DMB(); //ARM says to use a DMB instruction before relocating VTOR */
|
||||
SCB->VTOR = (uint32_t) app_addr;
|
||||
__DSB(); //ARM says to use a DSB instruction just after relocating VTOR */
|
||||
|
||||
// Jump to application reset vector
|
||||
asm("bx %0" :: "r"(app_vector[1]));
|
||||
|
||||
|
|
@ -217,9 +279,14 @@ void board_timer_stop(void)
|
|||
|
||||
int board_uart_write(void const * buf, int len)
|
||||
{
|
||||
#ifdef UART_DEV
|
||||
HAL_UART_Transmit(&UartHandle, (uint8_t*) buf, len, 0xFFFFFFFFU);
|
||||
return len;
|
||||
#else
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TINYUF2_SELF_UPDATE
|
||||
|
|
|
|||
240
ports/stm32h7/boards/daisy_seed/board.h
Normal file
240
ports/stm32h7/boards/daisy_seed/board.h
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2025 @snkYmkrct
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H_
|
||||
#define BOARD_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// LED
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define LED_PORT GPIOC
|
||||
#define LED_PIN GPIO_PIN_7
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BUTTON
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define BUTTON_PORT GPIOG
|
||||
#define BUTTON_PIN GPIO_PIN_3
|
||||
#define BUTTON_STATE_ACTIVE 0
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Flash
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Flash size of the board
|
||||
#define BOARD_FLASH_SIZE (128 * 1024)
|
||||
#define BOARD_FLASH_SECTORS 1
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// External QSPI Flash
|
||||
//--------------------------------------------------------------------+
|
||||
#define BOARD_QSPI_FLASH_SIZE (8 * 1024 * 1024) // 8MB
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB UF2
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define USB_VID 0x0483
|
||||
#define USB_PID 0x5740
|
||||
#define USB_MANUFACTURER "STM32"
|
||||
#define USB_PRODUCT "STM32FH750IB"
|
||||
|
||||
#define UF2_PRODUCT_NAME USB_MANUFACTURER " " USB_PRODUCT
|
||||
#define UF2_BOARD_ID "STM32FH750IB-DaisySeed"
|
||||
#define UF2_VOLUME_LABEL "DaisyBOOT"
|
||||
#define UF2_INDEX_URL "https://electro-smith.com/products/daisy-seed"
|
||||
|
||||
#define USB_NO_VBUS_PIN 1
|
||||
#define BOARD_TUD_RHPORT 0
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// UART
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#define UART_DEV UART4
|
||||
#define UART_CLOCK_ENABLE __HAL_RCC_UART4_CLK_ENABLE
|
||||
#define UART_CLOCK_DISABLE __HAL_RCC_UART4_CLK_DISABLE
|
||||
#define UART_GPIO_PORT GPIOB
|
||||
#define UART_GPIO_AF GPIO_AF8_UART4
|
||||
#define UART_TX_PIN GPIO_PIN_9
|
||||
#define UART_RX_PIN GPIO_PIN_8
|
||||
|
||||
static void Error_Handler(void) {
|
||||
__disable_irq();
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// RCC Clock
|
||||
//--------------------------------------------------------------------+
|
||||
static inline void clock_init(void) {
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
// Set voltage scaling in accordance with system clock speed
|
||||
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
|
||||
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
|
||||
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {
|
||||
}
|
||||
|
||||
// Configure LSE Drive
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
|
||||
|
||||
// Set up primary PLL and HSE clocks
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.OscillatorType |= RCC_OSCILLATORTYPE_LSI;
|
||||
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
|
||||
RCC_OscInitStruct.OscillatorType |= RCC_OSCILLATORTYPE_HSI48;
|
||||
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
|
||||
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLM = 1;
|
||||
RCC_OscInitStruct.PLL.PLLN = 50;
|
||||
RCC_OscInitStruct.PLL.PLLP = 2;
|
||||
RCC_OscInitStruct.PLL.PLLQ = 4;
|
||||
RCC_OscInitStruct.PLL.PLLR = 2;
|
||||
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
|
||||
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
|
||||
RCC_OscInitStruct.PLL.PLLFRACN = 0;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
// Configure bus clock sources and divisors
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK |
|
||||
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 |
|
||||
RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
|
||||
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
|
||||
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
|
||||
|
||||
// Set up non-bus peripherals
|
||||
PeriphClkInitStruct.PeriphClockSelection =
|
||||
RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_USB;
|
||||
// UART4
|
||||
PeriphClkInitStruct.Usart234578ClockSelection =
|
||||
RCC_USART234578CLKSOURCE_D2PCLK1;
|
||||
// USB
|
||||
PeriphClkInitStruct.PLL3.PLL3M = 1;
|
||||
PeriphClkInitStruct.PLL3.PLL3N = 12;
|
||||
PeriphClkInitStruct.PLL3.PLL3P = 2;
|
||||
PeriphClkInitStruct.PLL3.PLL3Q = 4;
|
||||
PeriphClkInitStruct.PLL3.PLL3R = 2;
|
||||
PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_3;
|
||||
PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
|
||||
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3;
|
||||
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
// Enable USB Voltage detector
|
||||
HAL_PWREx_EnableUSBVoltageDetector();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// QSPI and SPI FLash
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static inline void qspi_flash_init(QSPI_HandleTypeDef *qspiHandle) {
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_QSPI;
|
||||
PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_PLL;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* QUADSPI clock enable */
|
||||
__HAL_RCC_QSPI_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
/**QUADSPI GPIO Configuration
|
||||
PG6 ------> QUADSPI_BK1_NCS
|
||||
PF7 ------> QUADSPI_BK1_IO2
|
||||
PF6 ------> QUADSPI_BK1_IO3
|
||||
PF10 ------> QUADSPI_CLK
|
||||
PF9 ------> QUADSPI_BK1_IO1
|
||||
PF8 ------> QUADSPI_BK1_IO0
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
|
||||
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_8;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
|
||||
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
|
||||
qspiHandle->Instance = QUADSPI;
|
||||
qspiHandle->Init.ClockPrescaler = 1;
|
||||
qspiHandle->Init.FifoThreshold = 1;
|
||||
qspiHandle->Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
|
||||
qspiHandle->Init.FlashSize = 22;
|
||||
qspiHandle->Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
|
||||
qspiHandle->Init.ClockMode = QSPI_CLOCK_MODE_0;
|
||||
qspiHandle->Init.FlashID = QSPI_FLASH_ID_1;
|
||||
qspiHandle->Init.DualFlash = QSPI_DUALFLASH_DISABLE;
|
||||
if (HAL_QSPI_Init(qspiHandle) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
18
ports/stm32h7/boards/daisy_seed/board.mk
Normal file
18
ports/stm32h7/boards/daisy_seed/board.mk
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
QSPI_FLASH = IS25LP064A
|
||||
|
||||
CFLAGS += \
|
||||
-DSTM32H750xx \
|
||||
-DHSE_VALUE=16000000U \
|
||||
-DTINYUF2_LED=1 \
|
||||
-DBOARD_QSPI_FLASH_EN=1 \
|
||||
-DBOARD_AXISRAM_EN=1 \
|
||||
-D$(QSPI_FLASH)\
|
||||
-DBOARD_FLASH_APP_START=0x90000000 \
|
||||
-DTRAP_EXC \
|
||||
|
||||
MCU = h750xx
|
||||
|
||||
LOG = 0
|
||||
|
||||
SRC_S += \
|
||||
$(ST_CMSIS)/Source/Templates/gcc/startup_stm32h750xx.s
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
SPI_FLASH = W25Qx_SPI
|
||||
QSPI_FLASH = W25Qx_QSPI
|
||||
DISPLAY_DRV = ST7735
|
||||
JLINK_DEVICE = stm32h750vb
|
||||
|
||||
CFLAGS += \
|
||||
-DSTM32H750xx \
|
||||
|
|
|
|||
130
ports/stm32h7/components/is25lp064a/is25lp064a.h
Normal file
130
ports/stm32h7/components/is25lp064a/is25lp064a.h
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* IS25LP064A.h
|
||||
*
|
||||
* Adapted from https://github.com/electro-smith/libDaisy/blob/master/src/dev/flash_IS25LP064A.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INC_FLASH_IS25LP064A_H_
|
||||
#define INC_FLASH_IS25LP064A_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IS25LP064A_FLASH_SIZE 0x800000 /* 8 MBytes*/
|
||||
#define IS25LP064A_BLOCK_SIZE 0x10000 /* 64 KBytes */
|
||||
#define IS25LP064A_SECTOR_SIZE 0x1000 /* 4 KBytes */
|
||||
#define IS25LP064A_PAGE_SIZE 0x100 /* 256 bytes */
|
||||
|
||||
#define IS25LP064A_SECTOR_COUNT 2048
|
||||
|
||||
|
||||
#define IS25LP064A_DUMMY_CYCLES_READ_QUAD 6 /* & */
|
||||
#define IS25LP064A_DUMMY_CYCLES_READ 6 /* & */
|
||||
//#define IS25LP064A_DUMMY_CYCLES_READ_DTR 6 /* & */
|
||||
//#define IS25LP064A_DUMMY_CYCLES_READ_QUAD_DTR 6 /* & */
|
||||
|
||||
|
||||
#define IS25LP064A_DIE_ERASE_MAX_TIME 46000 /* 45 max seconds in datasheet */
|
||||
#define IS25LP064A_BLOCK_ERASE_MAX_TIME 1100 /* 1000 ms max in datasheet */
|
||||
#define IS25LP064A_SECTOR_ERASE_MAX_TIME 350 /* 300 ms max in datasheet */
|
||||
|
||||
|
||||
/* Low Power Modes */
|
||||
#define ENTER_DEEP_POWER_DOWN 0XB9 /* & */
|
||||
#define EXIT_DEEP_POWER_DOWN 0XAB /* Release from Power-down/Read Device ID instruction */
|
||||
|
||||
/* Software Reset Operation commands */
|
||||
#define RESET_ENABLE_CMD 0x66
|
||||
#define RESET_MEMORY_CMD 0x99 /* & */
|
||||
|
||||
/* Identification Operations */
|
||||
#define READ_ID_CMD 0xAB /* Release from Power-down/Read Device ID instruction */
|
||||
#define READ_ID_CMD2 0x9F /* JEDEC ID READ command in SPI mode */
|
||||
#define MULTIPLE_IO_READ_ID_CMD 0xAF /* JEDEC ID READ command in QPI mode */
|
||||
#define READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5A /* Serial Flash Discoverable Parameters (SFDP) */
|
||||
#define READ_MANUFACT_AND_ID 0x90 /* Read Product Identification (RDID) instruction */
|
||||
#define READ_UNIQUE_ID 0x4B /* Read Unique ID Number (RDUID) */
|
||||
|
||||
#define NO_OP 0x00 /* Cancels Reset Enable */
|
||||
|
||||
/* Sector LOCK/UNLOCK Operations */
|
||||
#define SECTOR_UNLOCK 0x26 /**< & */
|
||||
#define SECTOR_LOCK 0x24 /**< & */
|
||||
|
||||
/* Security Information Row */
|
||||
#define INFO_ROW_ERASE_CMD 0x64 /* Information Row Erase (IRER) instruction */
|
||||
#define INFO_ROW_PROGRAM_CMD 0x62 /* Information Row Program (IRP) instruction */
|
||||
#define INFO_ROW_READ_CMD 0x68 /* Information Row Read (IRRD) instruction */
|
||||
|
||||
/* Read Operations */
|
||||
#define READ_CMD 0x03 /* NORMAL READ (NORD) instruction */
|
||||
|
||||
#define FAST_READ_CMD 0x0B /* FAST READ (FRD) instruction for both 1 line and QPI modes */
|
||||
#define FAST_READ_DTR_CMD 0x0D /* FRDTR instruction */
|
||||
|
||||
#define DUAL_OUT_FAST_READ_CMD 0x3B /* FAST READ DUAL OUTPUT OPERATION (FRDO) */
|
||||
|
||||
#define DUAL_INOUT_FAST_READ_CMD 0xBB /* FAST READ DUAL I/O OPERATION (FRDIO) */
|
||||
#define DUAL_INOUT_FAST_READ_DTR_CMD 0xBD /* FAST READ DUAL IO DTR MODE OPERATION (FRDDTR) */
|
||||
|
||||
#define QUAD_OUT_FAST_READ_CMD 0x6B /* FAST READ QUAD OUTPUT OPERATION (FRQO) */
|
||||
|
||||
#define QUAD_INOUT_FAST_READ_CMD 0xEB /* FAST READ QUAD I/O OPERATION (FRQIO) - can be used to enable memory mapped mode */
|
||||
#define QUAD_INOUT_FAST_READ_DTR_CMD 0xED /* FAST READ QUAD IO DTR MODE OPERATION (FRQDTR) */
|
||||
|
||||
/* Write Operations */
|
||||
#define WRITE_ENABLE_CMD 0x06 /* WRITE ENABLE OPERATION (WREN) */
|
||||
#define WRITE_DISABLE_CMD 0x04 /* WRITE DISABLE OPERATION (WRDI) */
|
||||
|
||||
/* Register Operations */
|
||||
#define READ_STATUS_REG_CMD 0x05 /* READ STATUS REGISTER OPERATION (RDSR) */
|
||||
#define WRITE_STATUS_REG_CMD 0x01 /* WRITE STATUS REGISTER OPERATION (WRSR) */
|
||||
|
||||
#define READ_FUNCTION_REGISTER 0X48 /* READ FUNCTION REGISTER OPERATION (RDFR) */
|
||||
#define WRITE_FUNCTION_REGISTER 0x42 /* WRITE FUNCTION REGISTER OPERATION (WRFR) */
|
||||
|
||||
#define WRITE_READ_PARAM_REG_CMD 0xC0 /* SET READ PARAMETERS OPERATION (SRP) */
|
||||
|
||||
/* Page Program Operations */
|
||||
#define PAGE_PROG_CMD 0x02 /* PAGE PROGRAM OPERATION (PP) */
|
||||
|
||||
/* QUAD INPUT PAGE PROGRAM OPERATION (PPQ) */
|
||||
#define QUAD_IN_PAGE_PROG_CMD 0x32
|
||||
#define EXT_QUAD_IN_PAGE_PROG_CMD 0x38
|
||||
|
||||
/* Erase Operations */
|
||||
#define SECTOR_ERASE_CMD 0xd7 /* SECTOR ERASE OPERATION (S E R) on SPI */
|
||||
#define SECTOR_ERASE_QPI_CMD 0x20 /* SECTOR ERASE OPERATION (S E R) QPI */
|
||||
|
||||
#define BLOCK_ERASE_CMD 0xD8 /* BLOCK ERASE OPERATION (BER64K) */
|
||||
#define BLOCK_ERASE_32K_CMD 0x52 /* BLOCK ERASE OPERATION (BER32K) */
|
||||
|
||||
#define CHIP_ERASE_CMD 0xC7 /* CHIP ERASE OPERATION (CER) on SPI */
|
||||
#define EXT_CHIP_ERASE_CMD 0x60 /* CHIP ERASE OPERATION (CER) on QPI*/
|
||||
|
||||
#define PROG_ERASE_RESUME_CMD 0x7A /* Resume program/erase (PERRSM) on SPI */
|
||||
#define EXT_PROG_ERASE_RESUME_CMD 0x30 /* Resume program/erase (PERRSM) on QPI */
|
||||
|
||||
#define PROG_ERASE_SUSPEND_CMD 0x75 /* Suspend during program/erase (PERSUS) on SPI */
|
||||
#define EXT_PROG_ERASE_SUSPEND_CMD 0xB0 /* Suspend during program/erase (PERSUS) on QPI */
|
||||
|
||||
/** Quad Operations */
|
||||
#define ENTER_QUAD_CMD 0x35 /* ENTER QUAD PERIPHERAL INTERFACE (QPI) MODE OPERATION (QIOEN) */
|
||||
#define EXIT_QUAD_CMD 0xF5 /* EXIT QUAD PERIPHERAL INTERFACE (QPI) MODE OPERATION (QIODI) */
|
||||
|
||||
|
||||
/* Status Register */
|
||||
#define IS25LP064A_SR_WIP ((uint8_t)0x01) /* WIP Write in progress */
|
||||
#define IS25LP064A_SR_WREN ((uint8_t)0x02) /* W E L Write enable latch */
|
||||
//#define IS25LP064A_SR_BLOCKPR ((uint8_t)0x5C) /*!< Block protected against program and erase operations */
|
||||
//#define IS25LP064A_SR_PRBOTTOM ((uint8_t)0x20) /*!< Protected memory area defined by BLOCKPR starts from top or bottom */
|
||||
#define IS25LP064A_SR_QE ((uint8_t)0x40) /* QE Quad Enable */
|
||||
#define IS25LP064A_SR_SRWREN ((uint8_t)0x80) /* SRWD Status Register Write Disable*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INC_FLASH_IS25LP064A_H_ */
|
||||
567
ports/stm32h7/components/is25lp064a/is25lp064a_qspi.c
Normal file
567
ports/stm32h7/components/is25lp064a/is25lp064a_qspi.c
Normal file
|
|
@ -0,0 +1,567 @@
|
|||
#include "is25lp064a_qspi.h"
|
||||
#include "is25lp064a.h"
|
||||
#include "qspi_status.h"
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define MEMORY_FLASH_SIZE 0x800000 /* 8 MBytes*/
|
||||
#define MEMORY_SECTOR_SIZE 0x1000 /* 4 KBytes */
|
||||
#define MEMORY_PAGE_SIZE 0x100 /* 256 bytes */
|
||||
|
||||
extern QSPI_HandleTypeDef _qspi_flash;
|
||||
|
||||
static uint8_t qspi_enabled = 0;
|
||||
|
||||
static uint8_t QSPI_Wait(QSPI_AutoPollingTypeDef *config, uint32_t timeout) {
|
||||
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
|
||||
if (qspi_enabled) {
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.DataMode = QSPI_DATA_4_LINES;
|
||||
// Based on Reference manual RM0433 for the STM32H750 Value line,
|
||||
// dummy cycles needed on all read operations in QUAD mode
|
||||
sCommand.DummyCycles = IS25LP064A_DUMMY_CYCLES_READ_QUAD;
|
||||
} else {
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
sCommand.DataMode = QSPI_DATA_1_LINE;
|
||||
sCommand.DummyCycles = 0;
|
||||
}
|
||||
sCommand.Instruction = READ_STATUS_REG_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
|
||||
if (HAL_QSPI_AutoPolling(&_qspi_flash, &sCommand, config, timeout) !=
|
||||
HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t QSPI_ReadStatusRegister(uint8_t *status) {
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
|
||||
if (qspi_enabled) {
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.DataMode = QSPI_DATA_4_LINES;
|
||||
// Based on Reference manual RM0433 for the STM32H750 Value line,
|
||||
// dummy cycles needed on all read operations in QUAD mode
|
||||
sCommand.DummyCycles = IS25LP064A_DUMMY_CYCLES_READ_QUAD;
|
||||
|
||||
} else {
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
sCommand.DataMode = QSPI_DATA_1_LINE;
|
||||
sCommand.DummyCycles = 0;
|
||||
}
|
||||
sCommand.Instruction = READ_STATUS_REG_CMD;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
sCommand.Address = 0;
|
||||
sCommand.NbData = 1;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
if (HAL_QSPI_Receive(&_qspi_flash, status, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) !=
|
||||
HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
static uint8_t QSPI_ResetChip(void) {
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
QSPI_AutoPollingTypeDef sConfig = {0};
|
||||
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.Instruction = RESET_ENABLE_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
sCommand.Address = 0;
|
||||
sCommand.DataMode = QSPI_DATA_NONE;
|
||||
sCommand.DummyCycles = 0;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
sCommand.Instruction = RESET_MEMORY_CMD;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
sConfig.Match = 0;
|
||||
sConfig.Mask = IS25LP064A_SR_WIP;
|
||||
sConfig.MatchMode = QSPI_MATCH_MODE_AND;
|
||||
sConfig.StatusBytesSize = 1;
|
||||
sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
|
||||
sConfig.Interval = 0x10;
|
||||
|
||||
if (QSPI_Wait(&sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
static uint8_t QSPI_WriteEnable(void) {
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
QSPI_AutoPollingTypeDef sConfig = {0};
|
||||
|
||||
/* Enable write / erase operations */
|
||||
if (qspi_enabled) {
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
} else {
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
}
|
||||
sCommand.Instruction = WRITE_ENABLE_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.DataMode = QSPI_DATA_NONE;
|
||||
sCommand.DummyCycles = 0;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Configure automatic polling mode to wait for write enabling */
|
||||
sConfig.Match = IS25LP064A_SR_WREN;
|
||||
sConfig.Mask = IS25LP064A_SR_WREN;
|
||||
sConfig.MatchMode = QSPI_MATCH_MODE_AND;
|
||||
sConfig.StatusBytesSize = 1;
|
||||
sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
|
||||
sConfig.Interval = 0x10;
|
||||
|
||||
if (QSPI_Wait(&sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/*Enable quad mode and set dummy cycles count*/
|
||||
static uint8_t QSPI_Configuration(void) {
|
||||
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
QSPI_AutoPollingTypeDef sConfig = {0};
|
||||
uint8_t reg = 0;
|
||||
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.Instruction = WRITE_READ_PARAM_REG_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
sCommand.DataMode = QSPI_DATA_1_LINE;
|
||||
sCommand.DummyCycles = 0;
|
||||
sCommand.NbData = 1;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Minimum necessary dummy cycles for memory mapped mode at 100 MHz = 6
|
||||
* Setting in Read Register P4 P3 bits as 0 0, so full reg = 11100000 0xE0
|
||||
* see IS25LP064A data sheet section 6.3 READ REGISTER */
|
||||
reg = 0xE0;
|
||||
if (HAL_QSPI_Transmit(&_qspi_flash, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) !=
|
||||
HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
sConfig.Match = 0;
|
||||
sConfig.Mask = IS25LP064A_SR_WIP;
|
||||
sConfig.MatchMode = QSPI_MATCH_MODE_AND;
|
||||
sConfig.StatusBytesSize = 1;
|
||||
sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
|
||||
sConfig.Interval = 0x10;
|
||||
|
||||
if (QSPI_Wait(&sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/*----- Setting the QSPI mode ----*/
|
||||
|
||||
/* Set the non-volatile Quad Enable bit in status register */
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
sCommand.Instruction = WRITE_STATUS_REG_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.DataMode = QSPI_DATA_1_LINE;
|
||||
sCommand.DummyCycles = 0;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.NbData = 1;
|
||||
|
||||
if (QSPI_WriteEnable() != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
reg = 0;
|
||||
if (QSPI_ReadStatusRegister(®) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
reg = reg | IS25LP064A_SR_QE;
|
||||
if (HAL_QSPI_Transmit(&_qspi_flash, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) !=
|
||||
HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
/* Configure automatic polling mode to wait for quad enable complete */
|
||||
sConfig.Match = IS25LP064A_SR_QE;
|
||||
sConfig.Mask = IS25LP064A_SR_QE;
|
||||
|
||||
if (QSPI_Wait(&sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Wait to make sure controller is done with writing */
|
||||
sConfig.Match = 0;
|
||||
sConfig.Mask = IS25LP064A_SR_WIP;
|
||||
|
||||
if (QSPI_Wait(&sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Enter QPI mode */
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
sCommand.Instruction = ENTER_QUAD_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.DataMode = QSPI_DATA_NONE;
|
||||
sCommand.DummyCycles = 0;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.NbData = 0;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
qspi_enabled = 1; /* qpi mode ON */
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
uint8_t CSP_QSPI_Erase_Chip(void) {
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
QSPI_AutoPollingTypeDef sConfig = {0};
|
||||
|
||||
if (QSPI_WriteEnable() != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
sCommand.Instruction = EXT_CHIP_ERASE_CMD;
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
sCommand.Address = 0;
|
||||
sCommand.DataMode = QSPI_DATA_NONE;
|
||||
sCommand.DummyCycles = 0;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
// Poll until the max chip erase time
|
||||
sConfig.Match = 0;
|
||||
sConfig.Mask = IS25LP064A_SR_WIP;
|
||||
sConfig.MatchMode = QSPI_MATCH_MODE_AND;
|
||||
sConfig.StatusBytesSize = 1;
|
||||
sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
|
||||
sConfig.Interval = 0x10;
|
||||
|
||||
if (QSPI_Wait(&sConfig, IS25LP064A_DIE_ERASE_MAX_TIME) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
uint8_t CSP_QSPI_EraseSector(uint32_t EraseStartAddress,
|
||||
uint32_t EraseEndAddress) {
|
||||
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
QSPI_AutoPollingTypeDef sConfig = {0};
|
||||
|
||||
/* Erasing Sequence -------------------------------------------------- */
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.Instruction = SECTOR_ERASE_QPI_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
|
||||
sCommand.DataMode = QSPI_DATA_NONE;
|
||||
sCommand.DummyCycles = 0;
|
||||
|
||||
sConfig.Match = 0;
|
||||
sConfig.Mask = IS25LP064A_SR_WIP;
|
||||
sConfig.MatchMode = QSPI_MATCH_MODE_AND;
|
||||
sConfig.StatusBytesSize = 1;
|
||||
sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
|
||||
sConfig.Interval = 0x10;
|
||||
|
||||
EraseStartAddress =
|
||||
EraseStartAddress - EraseStartAddress % IS25LP064A_SECTOR_SIZE;
|
||||
|
||||
while (EraseEndAddress >= EraseStartAddress) {
|
||||
sCommand.Address = (EraseStartAddress & 0x7FFFFF);
|
||||
|
||||
if (QSPI_WriteEnable() != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
EraseStartAddress += IS25LP064A_SECTOR_SIZE;
|
||||
|
||||
if (QSPI_Wait(&sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
}
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
uint8_t CSP_QSPI_EnableMemoryMappedMode(void) {
|
||||
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
QSPI_MemoryMappedTypeDef sMemMappedCfg = {0};
|
||||
|
||||
/* Enable Memory-Mapped mode
|
||||
The FRQIO instruction allows the address bits to be input four bits at a time.
|
||||
This may allow for code to be executed directly from the SPI in some
|
||||
applications. Sending the mode bits as AX (X = doesn't matter) will set the
|
||||
flash controller in memory mapped mode.
|
||||
*/
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
|
||||
sCommand.DataMode = QSPI_DATA_4_LINES;
|
||||
sCommand.NbData = 0;
|
||||
sCommand.Address = 0;
|
||||
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES;
|
||||
sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
|
||||
sCommand.AlternateBytes = 0x000000A0;
|
||||
sCommand.DummyCycles = IS25LP064A_DUMMY_CYCLES_READ_QUAD - 2;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_ONLY_FIRST_CMD;
|
||||
|
||||
sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
|
||||
|
||||
if (HAL_QSPI_MemoryMapped(&_qspi_flash, &sCommand, &sMemMappedCfg) !=
|
||||
HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
uint8_t CSP_QSPI_DisableMemoryMappedMode(void) {
|
||||
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
uint8_t data;
|
||||
|
||||
// Need to first stop the host controller's access to flash
|
||||
if (HAL_QSPI_Abort(&_qspi_flash) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
|
||||
sCommand.DataMode = QSPI_DATA_4_LINES;
|
||||
sCommand.NbData = 1;
|
||||
sCommand.Address = 0;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES;
|
||||
sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
|
||||
sCommand.AlternateBytes = 0x00000000;
|
||||
sCommand.DummyCycles = IS25LP064A_DUMMY_CYCLES_READ_QUAD;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_ONLY_FIRST_CMD;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
if (HAL_QSPI_Receive(&_qspi_flash, &data, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) !=
|
||||
HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
uint8_t CSP_QSPI_Write(uint8_t *buffer, uint32_t address,
|
||||
uint32_t buffer_size) {
|
||||
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
QSPI_AutoPollingTypeDef sConfig = {0};
|
||||
uint32_t end_addr = 0, current_size = 0, current_addr = 0;
|
||||
|
||||
/* Calculation of the size between the write address and the end of the page
|
||||
*/
|
||||
current_addr = 0;
|
||||
|
||||
while (current_addr <= address) {
|
||||
current_addr += IS25LP064A_PAGE_SIZE;
|
||||
}
|
||||
current_size = current_addr - address;
|
||||
|
||||
/* Check if the size of the data is less than the remaining place in the page
|
||||
*/
|
||||
if (current_size > buffer_size) {
|
||||
current_size = buffer_size;
|
||||
}
|
||||
|
||||
/* Initialize the address variables */
|
||||
current_addr = address;
|
||||
end_addr = address + buffer_size;
|
||||
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.Instruction = PAGE_PROG_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
|
||||
sCommand.DataMode = QSPI_DATA_4_LINES;
|
||||
sCommand.NbData = buffer_size;
|
||||
sCommand.Address = address;
|
||||
sCommand.DummyCycles = 0;
|
||||
|
||||
sConfig.Match = 0;
|
||||
sConfig.Mask = IS25LP064A_SR_WIP;
|
||||
sConfig.MatchMode = QSPI_MATCH_MODE_AND;
|
||||
sConfig.StatusBytesSize = 1;
|
||||
sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
|
||||
sConfig.Interval = 0x10;
|
||||
|
||||
/* Perform the write page by page */
|
||||
do {
|
||||
sCommand.Address = current_addr;
|
||||
sCommand.NbData = current_size;
|
||||
|
||||
if (current_size == 0) {
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Enable write operations */
|
||||
if (QSPI_WriteEnable() != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Configure the command */
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Transmission of the data */
|
||||
if (HAL_QSPI_Transmit(&_qspi_flash, buffer,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Configure automatic polling mode to wait for end of program */
|
||||
if (QSPI_Wait(&sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Update the address and size variables for next page programming */
|
||||
current_addr += current_size;
|
||||
buffer += current_size;
|
||||
current_size = ((current_addr + IS25LP064A_PAGE_SIZE) > end_addr)
|
||||
? (end_addr - current_addr)
|
||||
: IS25LP064A_PAGE_SIZE;
|
||||
} while (current_addr <= end_addr);
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
uint8_t CSP_QSPI_Read(uint8_t *buffer, uint32_t address, uint32_t buffer_size) {
|
||||
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
|
||||
sCommand.DataMode = QSPI_DATA_4_LINES;
|
||||
sCommand.NbData = buffer_size;
|
||||
sCommand.Address = address;
|
||||
sCommand.DummyCycles = IS25LP064A_DUMMY_CYCLES_READ_QUAD;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
if (HAL_QSPI_Receive(&_qspi_flash, buffer, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) !=
|
||||
HAL_OK) {
|
||||
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
uint8_t CSP_QSPI_ExitQPIMODE(void) {
|
||||
QSPI_CommandTypeDef sCommand = {0};
|
||||
|
||||
sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
|
||||
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
sCommand.Instruction = EXIT_QUAD_CMD;
|
||||
sCommand.AddressMode = QSPI_ADDRESS_NONE;
|
||||
|
||||
if (HAL_QSPI_Command(&_qspi_flash, &sCommand,
|
||||
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
qspi_enabled = 0;
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/* QUADSPI init function */
|
||||
uint8_t CSP_QUADSPI_Init(void) {
|
||||
|
||||
if (QSPI_ResetChip() != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
if (QSPI_Configuration() != HAL_OK) {
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/* USER CODE END 1 */
|
||||
30
ports/stm32h7/components/is25lp064a/is25lp064a_qspi.h
Normal file
30
ports/stm32h7/components/is25lp064a/is25lp064a_qspi.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef __IS25LP064A_QSPI_H
|
||||
#define __IS25LP064A_QSPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t CSP_QUADSPI_Init(void);
|
||||
uint8_t CSP_QSPI_Erase_Chip(void);
|
||||
uint8_t CSP_QSPI_EraseSector(uint32_t EraseStartAddress,
|
||||
uint32_t EraseEndAddress);
|
||||
uint8_t CSP_QSPI_EnableMemoryMappedMode(void);
|
||||
uint8_t CSP_QSPI_DisableMemoryMappedMode(void);
|
||||
uint8_t CSP_QSPI_Write(uint8_t *buffer, uint32_t address, uint32_t buffer_size);
|
||||
uint8_t CSP_QSPI_Read(uint8_t *buffer, uint32_t address, uint32_t buffer_size);
|
||||
//---------------------------------------------
|
||||
uint8_t CSP_QSPI_ExitQPIMODE(void);
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#include "board_api.h"
|
||||
#include "w25qxx_qspi.h"
|
||||
#include "qspi_status.h"
|
||||
#include "stm32h7xx_hal.h"
|
||||
|
||||
|
||||
extern QSPI_HandleTypeDef _qspi_flash;
|
||||
|
||||
|
|
@ -13,7 +15,7 @@ static uint32_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi);
|
|||
static uint8_t QSPI_Send_CMD(QSPI_HandleTypeDef *hqspi,uint32_t instruction, uint32_t address,uint32_t addressSize,uint32_t dummyCycles,
|
||||
uint32_t instructionMode,uint32_t addressMode, uint32_t dataMode, uint32_t dataSize);
|
||||
|
||||
w25qxx_StatusTypeDef w25qxx_Mode = w25qxx_SPIMode;
|
||||
qspi_StatusTypeDef w25qxx_Mode = qspi_SPIMode;
|
||||
uint8_t w25qxx_StatusReg[3];
|
||||
uint16_t w25qxx_ID;
|
||||
|
||||
|
|
@ -30,7 +32,7 @@ uint16_t w25qxx_GetID(void)
|
|||
uint8_t ID[6];
|
||||
uint16_t deviceID;
|
||||
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
QSPI_Send_CMD(&_qspi_flash,W25X_QUAD_ManufactDeviceID,0x00,QSPI_ADDRESS_24_BITS,6,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_4_LINES, QSPI_DATA_4_LINES, sizeof(ID));
|
||||
else
|
||||
QSPI_Send_CMD(&_qspi_flash,W25X_ManufactDeviceID,0x00,QSPI_ADDRESS_24_BITS,0,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_4_LINES, QSPI_DATA_4_LINES, sizeof(ID));
|
||||
|
|
@ -38,7 +40,7 @@ uint16_t w25qxx_GetID(void)
|
|||
/* Reception of the data */
|
||||
if (HAL_QSPI_Receive(&_qspi_flash, ID, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
deviceID = (ID[0] << 8) | ID[1];
|
||||
|
||||
|
|
@ -48,7 +50,7 @@ uint16_t w25qxx_GetID(void)
|
|||
uint8_t w25qxx_ReadSR(uint8_t SR)
|
||||
{
|
||||
uint8_t byte=0;
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
QSPI_Send_CMD(&_qspi_flash,SR,0x00,QSPI_ADDRESS_8_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_NONE, QSPI_DATA_1_LINE, 1);
|
||||
else
|
||||
QSPI_Send_CMD(&_qspi_flash,SR,0x00,QSPI_ADDRESS_8_BITS,0,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_NONE, QSPI_DATA_4_LINES, 1);
|
||||
|
|
@ -62,7 +64,7 @@ uint8_t w25qxx_ReadSR(uint8_t SR)
|
|||
|
||||
uint8_t w25qxx_WriteSR(uint8_t SR,uint8_t data)
|
||||
{
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
QSPI_Send_CMD(&_qspi_flash,SR,0x00,QSPI_ADDRESS_8_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_NONE, QSPI_DATA_1_LINE, 1);
|
||||
else
|
||||
QSPI_Send_CMD(&_qspi_flash,SR,0x00,QSPI_ADDRESS_8_BITS,0,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_NONE, QSPI_DATA_4_LINES, 1);
|
||||
|
|
@ -75,7 +77,7 @@ uint8_t w25qxx_ReadAllStatusReg(void)
|
|||
w25qxx_StatusReg[0] = w25qxx_ReadSR(W25X_ReadStatusReg1);
|
||||
w25qxx_StatusReg[1] = w25qxx_ReadSR(W25X_ReadStatusReg2);
|
||||
w25qxx_StatusReg[2] = w25qxx_ReadSR(W25X_ReadStatusReg3);
|
||||
return w25qxx_OK;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
//等待空闲
|
||||
|
|
@ -90,7 +92,7 @@ uint8_t w25qxx_SetReadParameters(uint8_t DummyClock,uint8_t WrapLenth)
|
|||
uint8_t send;
|
||||
send = (DummyClock/2 -1)<<4 | ((WrapLenth/8 - 1)&0x03);
|
||||
|
||||
W25qxx_WriteEnable();
|
||||
w25qxx_WriteEnable();
|
||||
|
||||
QSPI_Send_CMD(&_qspi_flash,W25X_SetReadParam,0x00,QSPI_ADDRESS_8_BITS,0,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_NONE, QSPI_DATA_4_LINES, 1);
|
||||
|
||||
|
|
@ -100,9 +102,9 @@ uint8_t w25qxx_SetReadParameters(uint8_t DummyClock,uint8_t WrapLenth)
|
|||
uint8_t w25qxx_EnterQPI(void)
|
||||
{
|
||||
/* Enter QSPI memory in QSPI mode */
|
||||
if(QSPI_EnterQPI(&_qspi_flash) != w25qxx_OK)
|
||||
if(QSPI_EnterQPI(&_qspi_flash) != qspi_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return w25qxx_SetReadParameters(8,8);
|
||||
|
|
@ -116,14 +118,14 @@ uint8_t w25qxx_EnterQPI(void)
|
|||
uint8_t w25qxx_Startup(uint8_t DTRMode)
|
||||
{
|
||||
/* Enable MemoryMapped mode */
|
||||
if( QSPI_EnableMemoryMappedMode(&_qspi_flash,DTRMode) != w25qxx_OK )
|
||||
if( QSPI_EnableMemoryMappedMode(&_qspi_flash,DTRMode) != qspi_OK )
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
return w25qxx_OK;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
uint8_t W25qxx_WriteEnable(void)
|
||||
uint8_t w25qxx_WriteEnable(void)
|
||||
{
|
||||
return QSPI_WriteEnable(&_qspi_flash);
|
||||
}
|
||||
|
|
@ -132,20 +134,20 @@ uint8_t W25qxx_WriteEnable(void)
|
|||
* @param SectorAddress: Sector address to erase
|
||||
* @retval QSPI memory status
|
||||
*/
|
||||
uint8_t W25qxx_EraseSector(uint32_t SectorAddress)
|
||||
uint8_t w25qxx_EraseSector(uint32_t SectorAddress)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
W25qxx_WriteEnable();
|
||||
w25qxx_WriteEnable();
|
||||
W25QXX_Wait_Busy();
|
||||
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
result = QSPI_Send_CMD(&_qspi_flash,W25X_SectorErase,SectorAddress,QSPI_ADDRESS_24_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_1_LINE,QSPI_DATA_NONE,0);
|
||||
else
|
||||
result = QSPI_Send_CMD(&_qspi_flash,W25X_SectorErase,SectorAddress,QSPI_ADDRESS_24_BITS,0,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_4_LINES,QSPI_DATA_NONE,0);
|
||||
|
||||
/* 等待擦除完成 */
|
||||
if(result == w25qxx_OK)
|
||||
if(result == qspi_OK)
|
||||
W25QXX_Wait_Busy();
|
||||
|
||||
return result;
|
||||
|
|
@ -156,20 +158,20 @@ uint8_t W25qxx_EraseSector(uint32_t SectorAddress)
|
|||
* @param SectorAddress: Sector address to erase
|
||||
* @retval QSPI memory status
|
||||
*/
|
||||
uint8_t W25qxx_EraseBlock(uint32_t BlockAddress)
|
||||
uint8_t w25qxx_EraseBlock(uint32_t BlockAddress)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
W25qxx_WriteEnable();
|
||||
w25qxx_WriteEnable();
|
||||
W25QXX_Wait_Busy();
|
||||
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
result = QSPI_Send_CMD(&_qspi_flash,W25X_BlockErase,BlockAddress,QSPI_ADDRESS_24_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_1_LINE,QSPI_DATA_NONE,0);
|
||||
else
|
||||
result = QSPI_Send_CMD(&_qspi_flash,W25X_BlockErase,BlockAddress,QSPI_ADDRESS_24_BITS,0,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_4_LINES,QSPI_DATA_NONE,0);
|
||||
|
||||
/* 等待擦除完成 */
|
||||
if(result == w25qxx_OK)
|
||||
if(result == qspi_OK)
|
||||
W25QXX_Wait_Busy();
|
||||
|
||||
return result;
|
||||
|
|
@ -180,20 +182,20 @@ uint8_t W25qxx_EraseBlock(uint32_t BlockAddress)
|
|||
* @param SectorAddress: Sector address to erase
|
||||
* @retval QSPI memory status
|
||||
*/
|
||||
uint8_t W25qxx_EraseChip(void)
|
||||
uint8_t w25qxx_EraseChip(void)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
W25qxx_WriteEnable();
|
||||
w25qxx_WriteEnable();
|
||||
W25QXX_Wait_Busy();
|
||||
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
result = QSPI_Send_CMD(&_qspi_flash,W25X_ChipErase,0x00,QSPI_ADDRESS_8_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_NONE,QSPI_DATA_NONE,0);
|
||||
else
|
||||
result = QSPI_Send_CMD(&_qspi_flash,W25X_ChipErase,0x00,QSPI_ADDRESS_8_BITS,0,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_NONE,QSPI_DATA_NONE,0);
|
||||
|
||||
/* 等待擦除完成 */
|
||||
if(result == w25qxx_OK)
|
||||
if(result == qspi_OK)
|
||||
W25QXX_Wait_Busy();
|
||||
|
||||
return result;
|
||||
|
|
@ -206,22 +208,22 @@ uint8_t W25qxx_EraseChip(void)
|
|||
* @param Size Size of data to write. Range 1 ~ W25qxx page size
|
||||
* @retval QSPI memory status
|
||||
*/
|
||||
uint8_t W25qxx_PageProgram(uint8_t *pData, uint32_t WriteAddr, uint32_t Size)
|
||||
uint8_t w25qxx_PageProgram(uint8_t *pData, uint32_t WriteAddr, uint32_t Size)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
W25qxx_WriteEnable();
|
||||
w25qxx_WriteEnable();
|
||||
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
result = QSPI_Send_CMD(&_qspi_flash,W25X_QUAD_INPUT_PAGE_PROG_CMD,WriteAddr,QSPI_ADDRESS_24_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_1_LINE,QSPI_DATA_4_LINES,Size);
|
||||
else
|
||||
result = QSPI_Send_CMD(&_qspi_flash,W25X_PageProgram,WriteAddr,QSPI_ADDRESS_24_BITS,0,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_4_LINES,QSPI_DATA_4_LINES,Size);
|
||||
|
||||
if(result == w25qxx_OK)
|
||||
if(result == qspi_OK)
|
||||
result = HAL_QSPI_Transmit(&_qspi_flash,pData,HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
|
||||
|
||||
/* 等待写入完成 */
|
||||
if(result == w25qxx_OK)
|
||||
if(result == qspi_OK)
|
||||
W25QXX_Wait_Busy();
|
||||
|
||||
return result;
|
||||
|
|
@ -232,7 +234,7 @@ uint8_t W25qxx_PageProgram(uint8_t *pData, uint32_t WriteAddr, uint32_t Size)
|
|||
//pBuffer:数据存储区
|
||||
//ReadAddr:开始读取的地址(最大32bit)
|
||||
//NumByteToRead:要读取的字节数(最大65535)
|
||||
uint8_t W25qxx_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
|
||||
uint8_t w25qxx_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
|
|
@ -240,7 +242,7 @@ uint8_t W25qxx_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
|
|||
|
||||
/* Configure the command for the read instruction */
|
||||
|
||||
if(w25qxx_Mode == w25qxx_QPIMode)
|
||||
if(w25qxx_Mode == qspi_QPIMode)
|
||||
{
|
||||
s_command.Instruction = W25X_QUAD_INOUT_FAST_READ_CMD;
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
|
|
@ -271,7 +273,7 @@ uint8_t W25qxx_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
|
|||
|
||||
result = HAL_QSPI_Command(&_qspi_flash, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
|
||||
|
||||
if(result == w25qxx_OK)
|
||||
if(result == qspi_OK)
|
||||
result = HAL_QSPI_Receive(&_qspi_flash,pData,HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
|
||||
|
||||
return result;
|
||||
|
|
@ -285,7 +287,7 @@ uint8_t W25qxx_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
|
|||
//WriteAddr:开始写入的地址(最大32bit)
|
||||
//NumByteToWrite:要写入的字节数(最大65535)
|
||||
//CHECK OK
|
||||
void W25qxx_WriteNoCheck(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t NumByteToWrite)
|
||||
void w25qxx_WriteNoCheck(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t NumByteToWrite)
|
||||
{
|
||||
uint16_t pageremain;
|
||||
pageremain = 256 - WriteAddr % 256; //单页剩余的字节数
|
||||
|
|
@ -295,7 +297,7 @@ void W25qxx_WriteNoCheck(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t NumByteToW
|
|||
}
|
||||
while(1)
|
||||
{
|
||||
W25qxx_PageProgram(pBuffer, WriteAddr, pageremain);
|
||||
w25qxx_PageProgram(pBuffer, WriteAddr, pageremain);
|
||||
if (NumByteToWrite == pageremain)
|
||||
{
|
||||
break; //写入结束了
|
||||
|
|
@ -320,7 +322,7 @@ void W25qxx_WriteNoCheck(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t NumByteToW
|
|||
//pBuffer:数据存储区
|
||||
//WriteAddr:开始写入的地址(最大32bit)
|
||||
//NumByteToWrite:要写入的字节数(最大65535)
|
||||
uint8_t W25qxx_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
|
||||
uint8_t w25qxx_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
|
||||
{
|
||||
uint32_t secpos;
|
||||
uint16_t secoff;
|
||||
|
|
@ -335,8 +337,8 @@ uint8_t W25qxx_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWri
|
|||
if (NumByteToWrite <= secremain) secremain = NumByteToWrite; //不大于4096个字节
|
||||
while(1)
|
||||
{
|
||||
if (W25qxx_Read(W25QXX_BUF, secpos * 4096, 4096) != w25qxx_OK) {
|
||||
return w25qxx_ERROR;
|
||||
if (w25qxx_Read(W25QXX_BUF, secpos * 4096, 4096) != qspi_OK) {
|
||||
return qspi_ERROR;
|
||||
} //读出整个扇区的内容
|
||||
for (i = 0;i < secremain; i++) //校验数据
|
||||
{
|
||||
|
|
@ -344,18 +346,18 @@ uint8_t W25qxx_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWri
|
|||
}
|
||||
if (i < secremain) //需要擦除
|
||||
{
|
||||
if (W25qxx_EraseSector(secpos) != w25qxx_OK) {
|
||||
return w25qxx_ERROR;
|
||||
if (w25qxx_EraseSector(secpos) != qspi_OK) {
|
||||
return qspi_ERROR;
|
||||
} //擦除这个扇区
|
||||
for (i = 0; i < secremain; i++) //复制
|
||||
{
|
||||
W25QXX_BUF[i + secoff] = pBuffer[i];
|
||||
}
|
||||
W25qxx_WriteNoCheck(W25QXX_BUF, secpos * 4096, 4096); //写入整个扇区
|
||||
w25qxx_WriteNoCheck(W25QXX_BUF, secpos * 4096, 4096); //写入整个扇区
|
||||
}
|
||||
else
|
||||
{
|
||||
W25qxx_WriteNoCheck(pBuffer, WriteAddr, secremain); //写已经擦除了的,直接写入扇区剩余区间.
|
||||
w25qxx_WriteNoCheck(pBuffer, WriteAddr, secremain); //写已经擦除了的,直接写入扇区剩余区间.
|
||||
}
|
||||
if (NumByteToWrite == secremain)
|
||||
{
|
||||
|
|
@ -375,13 +377,13 @@ uint8_t W25qxx_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWri
|
|||
secremain = NumByteToWrite; //下一个扇区可以写完了
|
||||
}
|
||||
}
|
||||
return w25qxx_OK;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the QSPI in memory-mapped mode QPI/SPI && DTR(DDR)/Normal Mode
|
||||
* @param hqspi: QSPI handle
|
||||
* @param DTRMode: w25qxx_DTRMode DTR mode ,w25qxx_NormalMode Normal mode
|
||||
* @param DTRMode: qspi_DTRMode DTR mode ,qspi_NormalMode Normal mode
|
||||
* @retval QSPI memory status
|
||||
*/
|
||||
static uint32_t QSPI_EnableMemoryMappedMode(QSPI_HandleTypeDef *hqspi,uint8_t DTRMode)
|
||||
|
|
@ -390,7 +392,7 @@ static uint32_t QSPI_EnableMemoryMappedMode(QSPI_HandleTypeDef *hqspi,uint8_t DT
|
|||
QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
|
||||
|
||||
/* Configure the command for the read instruction */
|
||||
if(w25qxx_Mode == w25qxx_QPIMode)
|
||||
if(w25qxx_Mode == qspi_QPIMode)
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
else
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
|
|
@ -405,7 +407,7 @@ static uint32_t QSPI_EnableMemoryMappedMode(QSPI_HandleTypeDef *hqspi,uint8_t DT
|
|||
|
||||
s_command.DataMode = QSPI_DATA_4_LINES;
|
||||
|
||||
if(DTRMode == w25qxx_DTRMode)
|
||||
if(DTRMode == qspi_DTRMode)
|
||||
{
|
||||
s_command.Instruction = W25X_QUAD_INOUT_FAST_READ_DTR_CMD;
|
||||
s_command.DummyCycles = W25X_DUMMY_CYCLES_READ_QUAD_DTR;
|
||||
|
|
@ -415,7 +417,7 @@ static uint32_t QSPI_EnableMemoryMappedMode(QSPI_HandleTypeDef *hqspi,uint8_t DT
|
|||
{
|
||||
s_command.Instruction = W25X_QUAD_INOUT_FAST_READ_CMD;
|
||||
|
||||
if(w25qxx_Mode == w25qxx_QPIMode)
|
||||
if(w25qxx_Mode == qspi_QPIMode)
|
||||
s_command.DummyCycles = W25X_DUMMY_CYCLES_READ_QUAD;
|
||||
else
|
||||
s_command.DummyCycles = W25X_DUMMY_CYCLES_READ_QUAD-2;
|
||||
|
|
@ -432,10 +434,10 @@ static uint32_t QSPI_EnableMemoryMappedMode(QSPI_HandleTypeDef *hqspi,uint8_t DT
|
|||
|
||||
if (HAL_QSPI_MemoryMapped(hqspi, &s_command, &s_mem_mapped_cfg) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return w25qxx_OK;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -461,14 +463,14 @@ static uint32_t QSPI_ResetDevice(QSPI_HandleTypeDef *hqspi)
|
|||
/* Send the command */
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Send the reset device command */
|
||||
s_command.Instruction = W25X_ResetDevice;
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
|
|
@ -476,18 +478,18 @@ static uint32_t QSPI_ResetDevice(QSPI_HandleTypeDef *hqspi)
|
|||
/* Send the command */
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Send the reset memory command */
|
||||
s_command.Instruction = W25X_ResetDevice;
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
w25qxx_Mode = w25qxx_SPIMode;
|
||||
return w25qxx_OK;
|
||||
w25qxx_Mode = qspi_SPIMode;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -502,8 +504,8 @@ static uint32_t QSPI_ResetDevice(QSPI_HandleTypeDef *hqspi)
|
|||
* @param dataMode 数据模式; QSPI_DATA_NONE,QSPI_DATA_1_LINE,QSPI_DATA_2_LINES,QSPI_DATA_4_LINES
|
||||
* @param dataSize 待传输的数据长度
|
||||
*
|
||||
* @return uint8_t w25qxx_OK:正常
|
||||
* w25qxx_ERROR:错误
|
||||
* @return uint8_t qspi_OK:正常
|
||||
* qspi_ERROR:错误
|
||||
*/
|
||||
static uint8_t QSPI_Send_CMD(QSPI_HandleTypeDef *hqspi,uint32_t instruction, uint32_t address,uint32_t addressSize,uint32_t dummyCycles,
|
||||
uint32_t instructionMode,uint32_t addressMode, uint32_t dataMode, uint32_t dataSize)
|
||||
|
|
@ -530,9 +532,9 @@ static uint8_t QSPI_Send_CMD(QSPI_HandleTypeDef *hqspi,uint32_t instruction, uin
|
|||
Cmdhandler.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
|
||||
if(HAL_QSPI_Command(hqspi, &Cmdhandler, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
|
||||
return w25qxx_OK;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -556,24 +558,24 @@ static uint32_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
|
|||
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||
|
||||
/* Enable write operations */
|
||||
if (QSPI_WriteEnable(hqspi) != w25qxx_OK)
|
||||
if (QSPI_WriteEnable(hqspi) != qspi_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Send the command */
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Configure automatic polling mode to wait the memory is ready */
|
||||
if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != w25qxx_OK)
|
||||
if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != qspi_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return w25qxx_OK;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -587,7 +589,7 @@ static uint32_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
|
|||
QSPI_AutoPollingTypeDef s_config;
|
||||
|
||||
/* Enable write operations */
|
||||
if(w25qxx_Mode == w25qxx_QPIMode)
|
||||
if(w25qxx_Mode == qspi_QPIMode)
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
else
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
|
|
@ -603,7 +605,7 @@ static uint32_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
|
|||
|
||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
/* Configure automatic polling mode to wait for write enabling */
|
||||
|
|
@ -616,17 +618,17 @@ static uint32_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
|
|||
|
||||
s_command.Instruction = W25X_ReadStatusReg1;
|
||||
|
||||
if(w25qxx_Mode == w25qxx_QPIMode)
|
||||
if(w25qxx_Mode == qspi_QPIMode)
|
||||
s_command.DataMode = QSPI_DATA_4_LINES;
|
||||
else
|
||||
s_command.DataMode = QSPI_DATA_1_LINE;
|
||||
|
||||
if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
return w25qxx_OK;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -642,7 +644,7 @@ static uint32_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Tim
|
|||
|
||||
/* Configure automatic polling mode to wait for memory ready */
|
||||
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||
else
|
||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||
|
|
@ -654,7 +656,7 @@ static uint32_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Tim
|
|||
s_command.AddressSize = QSPI_ADDRESS_8_BITS;
|
||||
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||
|
||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
||||
if(w25qxx_Mode == qspi_SPIMode)
|
||||
s_command.DataMode = QSPI_DATA_1_LINE;
|
||||
else
|
||||
s_command.DataMode = QSPI_DATA_4_LINES;
|
||||
|
|
@ -685,19 +687,19 @@ static uint8_t QSPI_EnterQPI(QSPI_HandleTypeDef *hqspi)
|
|||
stareg2 = w25qxx_ReadSR(W25X_ReadStatusReg2);
|
||||
if((stareg2 & 0X02) == 0) //QE位未使能
|
||||
{
|
||||
W25qxx_WriteEnable();
|
||||
w25qxx_WriteEnable();
|
||||
stareg2 |= 1<<1; //使能QE位
|
||||
w25qxx_WriteSR(W25X_WriteStatusReg2,stareg2);
|
||||
}
|
||||
QSPI_Send_CMD(hqspi,W25X_EnterQSPIMode,0x00,QSPI_ADDRESS_8_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_NONE,QSPI_DATA_NONE,0);
|
||||
|
||||
/* Configure automatic polling mode to wait the memory is ready */
|
||||
if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != w25qxx_OK)
|
||||
if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != qspi_OK)
|
||||
{
|
||||
return w25qxx_ERROR;
|
||||
return qspi_ERROR;
|
||||
}
|
||||
|
||||
w25qxx_Mode = w25qxx_QPIMode;
|
||||
w25qxx_Mode = qspi_QPIMode;
|
||||
|
||||
return w25qxx_OK;
|
||||
return qspi_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,21 +7,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
w25qxx_OK = 0x00,
|
||||
w25qxx_ERROR = 0x01,
|
||||
w25qxx_BUSY = 0x02,
|
||||
w25qxx_TIMEOUT = 0x03,
|
||||
|
||||
w25qxx_QPIMode = 0x04,
|
||||
w25qxx_SPIMode = 0x05,
|
||||
|
||||
w25qxx_DTRMode = 0x06,
|
||||
w25qxx_NormalMode = 0x07,
|
||||
|
||||
} w25qxx_StatusTypeDef;
|
||||
|
||||
/* =============== W25Qxx CMD ================ */
|
||||
#define W25X_WriteEnable 0x06
|
||||
#define W25X_WriteDisable 0x04
|
||||
|
|
@ -84,14 +69,14 @@ uint8_t w25qxx_WriteSR(uint8_t SR,uint8_t data);
|
|||
uint8_t w25qxx_SetReadParameters(uint8_t DummyClock,uint8_t WrapLenth);
|
||||
uint8_t w25qxx_EnterQPI(void);
|
||||
uint8_t w25qxx_Startup(uint8_t DTRMode);
|
||||
uint8_t W25qxx_WriteEnable(void);
|
||||
uint8_t W25qxx_EraseSector(uint32_t SectorAddress);
|
||||
uint8_t W25qxx_EraseBlock(uint32_t BlockAddress);
|
||||
uint8_t W25qxx_EraseChip(void);
|
||||
uint8_t W25qxx_PageProgram(uint8_t *pData, uint32_t WriteAddr, uint32_t Size);
|
||||
uint8_t W25qxx_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size);
|
||||
void W25qxx_WriteNoCheck(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t NumByteToWrite);
|
||||
uint8_t W25qxx_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
|
||||
uint8_t w25qxx_WriteEnable(void);
|
||||
uint8_t w25qxx_EraseSector(uint32_t SectorAddress);
|
||||
uint8_t w25qxx_EraseBlock(uint32_t BlockAddress);
|
||||
uint8_t w25qxx_EraseChip(void);
|
||||
uint8_t w25qxx_PageProgram(uint8_t *pData, uint32_t WriteAddr, uint32_t Size);
|
||||
uint8_t w25qxx_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size);
|
||||
void w25qxx_WriteNoCheck(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t NumByteToWrite);
|
||||
uint8_t w25qxx_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,27 +24,29 @@ endif
|
|||
CFLAGS += -Wno-error=cast-align -Wno-error=unused-parameter -Wno-error=unused-but-set-variable -Wno-error=unused-function
|
||||
|
||||
ifeq ($(SPI_FLASH),W25Qx_SPI)
|
||||
INC += \
|
||||
$(CURRENT_PATH)/components/w25qxx/ \
|
||||
|
||||
INC += ${TOP}/$(PORT_DIR)/components/w25qxx
|
||||
SRC_C += \
|
||||
$(TOP)/$(PORT_DIR)/components/w25qxx/w25qxx.c
|
||||
$(PORT_DIR)/components/w25qxx/w25qxx.c
|
||||
endif
|
||||
|
||||
ifeq ($(QSPI_FLASH),W25Qx_QSPI)
|
||||
INC += \
|
||||
$(CURRENT_PATH)/components/w25qxx/ \
|
||||
|
||||
INC += ${TOP}/$(PORT_DIR)/components/w25qxx
|
||||
SRC_C += \
|
||||
$(TOP)/$(PORT_DIR)/components/w25qxx/w25qxx_qspi.c
|
||||
$(PORT_DIR)/components/w25qxx/w25qxx_qspi.c
|
||||
endif
|
||||
|
||||
ifeq ($(QSPI_FLASH),IS25LP064A)
|
||||
INC += ${TOP}/$(PORT_DIR)/components/is25lp064a
|
||||
SRC_C += \
|
||||
$(PORT_DIR)/components/is25lp064a/is25lp064a_qspi.c
|
||||
endif
|
||||
|
||||
ifeq ($(DISPLAY_DRV),ST7735)
|
||||
INC += \
|
||||
$(CURRENT_PATH)/components/w25qxx/ \
|
||||
INC += ${TOP}/$(PORT_DIR)/components/st7735/
|
||||
|
||||
SRC_C += \
|
||||
$(TOP)/$(PORT_DIR)/components/st7735/st7735.c
|
||||
$(PORT_DIR)/components/st7735/st7735.c \
|
||||
$(PORT_DIR)/components/st7735/fonts.c
|
||||
endif
|
||||
|
||||
# Source
|
||||
|
|
@ -63,8 +65,6 @@ SRC_C += \
|
|||
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_qspi.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_mdma.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_pwr_ex.c \
|
||||
$(TOP)/$(PORT_DIR)/components/st7735/fonts.c \
|
||||
|
||||
|
||||
ifndef BUILD_NO_TINYUSB
|
||||
SRC_C += lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c
|
||||
|
|
@ -75,8 +75,6 @@ endif
|
|||
INC += \
|
||||
$(TOP)/$(BOARD_PATH) \
|
||||
$(TOP)/$(CMSIS_5)/CMSIS/Core/Include \
|
||||
$(CURRENT_PATH)/components/st7735/ \
|
||||
$(CURRENT_PATH)/components/w25qxx/ \
|
||||
$(TOP)/$(PORT_DIR)/ \
|
||||
$(TOP)/$(BOARD_DIR) \
|
||||
$(TOP)/$(ST_CMSIS)/Include \
|
||||
|
|
|
|||
26
ports/stm32h7/qspi_status.h
Normal file
26
ports/stm32h7/qspi_status.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef QSPI_STATUS_H_
|
||||
#define QSPI_STATUS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
qspi_OK = 0x00,
|
||||
qspi_ERROR = 0x01,
|
||||
qspi_BUSY = 0x02,
|
||||
qspi_TIMEOUT = 0x03,
|
||||
|
||||
qspi_QPIMode = 0x04,
|
||||
qspi_SPIMode = 0x05,
|
||||
|
||||
qspi_DTRMode = 0x06,
|
||||
qspi_NormalMode = 0x07,
|
||||
|
||||
} qspi_StatusTypeDef;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue