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'
|
- 'lpc55'
|
||||||
- 'mimxrt10xx'
|
- 'mimxrt10xx'
|
||||||
- 'stm32f3'
|
- 'stm32f3'
|
||||||
|
- 'stm32h7'
|
||||||
- 'stm32l4'
|
- 'stm32l4'
|
||||||
with:
|
with:
|
||||||
port: ${{ matrix.port }}
|
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
|
- name: Prepare Release Asset
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
run: |
|
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 }}
|
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
|
cp ${{ env.BIN_PATH }}/apps/update-tinyuf2.uf2 update-tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.uf2
|
||||||
else
|
else
|
||||||
if [[ ${{ inputs.build-system }} == cmake ]]; then
|
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
|
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
|
fi
|
||||||
zip -jr tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.zip ${{ env.BIN_PATH }}
|
zip -jr tinyuf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.zip ${{ env.BIN_PATH }}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Upload Release Asset
|
- name: Upload Release Asset
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v2
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
|
|
@ -99,5 +101,11 @@ jobs:
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
if: github.event_name == 'release' && inputs.port == 'espressif'
|
if: github.event_name == 'release' && inputs.port == 'espressif'
|
||||||
run: |
|
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
|
if [ -n \"$AWS_ACCESS_KEY_ID\" ]; then
|
||||||
[ -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
|
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():
|
if b.is_dir():
|
||||||
matrix[p.name]['board'].append(b.name)
|
matrix[p.name]['board'].append(b.name)
|
||||||
# For quick testing by only build 1 espressif board
|
# For quick testing by only build 1 espressif board
|
||||||
if p.name == 'espressif':
|
# if p.name == 'espressif':
|
||||||
break
|
# break
|
||||||
print(json.dumps(matrix))
|
print(json.dumps(matrix))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@
|
||||||
#define BOARD_UF2_FAMILY_ID 0xbfdd4eee
|
#define BOARD_UF2_FAMILY_ID 0xbfdd4eee
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
#define BOARD_UF2_FAMILY_ID 0xc47e5767
|
#define BOARD_UF2_FAMILY_ID 0xc47e5767
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||||
|
#define BOARD_UF2_FAMILY_ID 0x3d308e94
|
||||||
#else
|
#else
|
||||||
#error unsupported MCUs
|
#error unsupported MCUs
|
||||||
#endif
|
#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
|
#define CFG_TUSB_MCU OPT_MCU_ESP32S2
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
#define CFG_TUSB_MCU OPT_MCU_ESP32S3
|
#define CFG_TUSB_MCU OPT_MCU_ESP32S3
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||||
|
#define CFG_TUSB_MCU OPT_MCU_ESP32P4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CFG_TUSB_OS OPT_OS_FREERTOS
|
#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_esp32s2 0xbfdd4eee)
|
||||||
set(UF2_FAMILY_ID_esp32s3 0xc47e5767)
|
set(UF2_FAMILY_ID_esp32s3 0xc47e5767)
|
||||||
|
set(UF2_FAMILY_ID_esp32p4 0x3d308e94)
|
||||||
set(UF2_FAMILY_ID ${UF2_FAMILY_ID_${IDF_TARGET}})
|
set(UF2_FAMILY_ID ${UF2_FAMILY_ID_${IDF_TARGET}})
|
||||||
|
|
||||||
# override default family_gen_uf2
|
# override default family_gen_uf2
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,10 @@ if (NOT DEFINED TOOLCHAIN)
|
||||||
set(TOOLCHAIN gcc)
|
set(TOOLCHAIN gcc)
|
||||||
endif ()
|
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
|
# FAMILY and BOARD
|
||||||
#-------------------------------------------------------------
|
#-------------------------------------------------------------
|
||||||
|
|
@ -330,10 +334,17 @@ endfunction()
|
||||||
# Add flash openocd adi (Analog Devices) target
|
# Add flash openocd adi (Analog Devices) target
|
||||||
# included with msdk or compiled from release branch of https://github.com/analogdevicesinc/openocd
|
# included with msdk or compiled from release branch of https://github.com/analogdevicesinc/openocd
|
||||||
function(family_flash_openocd_adi TARGET)
|
function(family_flash_openocd_adi TARGET)
|
||||||
if (DEFINED $ENV{MAXIM_PATH})
|
if (DEFINED MAXIM_PATH)
|
||||||
# use openocd from msdk
|
# use openocd from msdk with MAXIM_PATH cmake variable first if the user
|
||||||
set(OPENOCD ENV{MAXIM_PATH}/Tools/OpenOCD/openocd)
|
# specified it
|
||||||
set(OPENOCD_OPTION2 "-s $ENV{MAXIM_PATH}/Tools/OpenOCD/scripts")
|
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()
|
else()
|
||||||
# compiled from source
|
# compiled from source
|
||||||
if (NOT DEFINED OPENOCD_ADI_PATH)
|
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
|
# 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
|
## 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)
|
- [J-Link vs OpenOCD](#j-link-vs-openocd)
|
||||||
- [Flashing with J-Link](#1-j-link-default)
|
- [Flashing with J-Link](#1-j-link-default)
|
||||||
- [Flashing with OpenOCD (MSDK)](#2-openocd-from-msdk-optional)
|
- [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 Example Applications](#flashing-example-applications)
|
||||||
- [Flashing via Drag-and-Drop](#flashing-via-drag-and-drop)
|
- [Flashing via Drag-and-Drop](#flashing-via-drag-and-drop)
|
||||||
- [Re-Entering Bootloader Mode](#re-entering-bootloader-mode)
|
- [Re-Entering Bootloader Mode](#re-entering-bootloader-mode)
|
||||||
- [Port Directory Structure](#port-directory-structure)
|
- [Port Directory Structure](#port-directory-structure)
|
||||||
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
This guide focuses on building TinyUF2 for Analog Devices' MAX32 parts.
|
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`
|
- **GNU ARM Toolchain** (`arm-none-eabi-gcc`) available in your `PATH`
|
||||||
- **make**
|
- **make**
|
||||||
|
- **CMake**
|
||||||
- **git** (required for submodules)
|
- **git** (required for submodules)
|
||||||
- **SDK Dependencies**
|
- **SDK Dependencies**
|
||||||
|
|
||||||
|
|
||||||
### Installing SDK Dependencies
|
### Installing SDK Dependencies
|
||||||
```bash
|
```bash
|
||||||
python tools/get_deps.py max32
|
python tools/get_deps.py maxim
|
||||||
```
|
```
|
||||||
or
|
or
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -56,21 +52,13 @@ python tools/get_deps.py --board apard32690
|
||||||
|
|
||||||
#### macOS Dependency Install
|
#### macOS Dependency Install
|
||||||
```bash
|
```bash
|
||||||
brew install arm-none-eabi-gcc make git
|
brew install arm-none-eabi-gcc make cmake git
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Ubuntu Dependency Install
|
#### Ubuntu Dependency Install
|
||||||
```bash
|
```bash
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install gcc-arm-none-eabi make git
|
sudo apt install gcc-arm-none-eabi make cmake git
|
||||||
```
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Example usage:
|
|
||||||
cd ports/max32690/
|
|
||||||
make BOARD=apard32690 all
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -103,9 +91,6 @@ If needed, set `MAXIM_PATH` to point to your MSDK installation:
|
||||||
export MAXIM_PATH=/c/MaximSDK
|
export MAXIM_PATH=/c/MaximSDK
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## MSDK (Windows) Environment Setup
|
## MSDK (Windows) Environment Setup
|
||||||
|
|
||||||
### 1. Using MSDK's MSYS2
|
### 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"
|
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.)
|
(Adjust the path if your MSDK installation is in a different location.)
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Available Boards
|
## Available Boards
|
||||||
|
|
||||||
Each port supports multiple hardware platforms.
|
Each port supports multiple hardware platforms.
|
||||||
The specific boards available for each device can be found inside:
|
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
|
apard32690
|
||||||
|
max32650evkit
|
||||||
|
max32650fthr
|
||||||
|
max32666evkit
|
||||||
|
max32666fthr
|
||||||
max32690evkit
|
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
|
```bash
|
||||||
make BOARD=apard32690 all
|
cmake -DBOARD=apard32690 ..
|
||||||
make BOARD=apard32690 flash
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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>
|
<br>
|
||||||
|
|
||||||
## Building the Bootloader
|
## Building the Bootloader and Applications
|
||||||
|
|
||||||
1. Open your MSYS2 terminal (preferably MSDK’s).
|
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
|
```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
|
```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
|
||||||
|
|
||||||
|
To list all supported targets, run:
|
||||||
<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:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make BOARD=apard32690 blinky
|
cmake --build . --target help
|
||||||
make BOARD=apard32690 erase-firmware
|
|
||||||
make BOARD=apard32690 self-update
|
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
|
```bash
|
||||||
make BOARD=apard32690 blinky-clean
|
make blinky
|
||||||
make BOARD=apard32690 erase-firmware-clean
|
cmake --build . --target blinky
|
||||||
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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Flashing the Bootloader
|
## Flashing the Bootloader
|
||||||
|
|
||||||
|
### J-Link and OpenOCD
|
||||||
### J-Link vs OpenOCD
|
|
||||||
|
|
||||||
TinyUF2 supports two main ways to flash firmware:
|
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.
|
- **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.
|
The MSDK includes a custom version of OpenOCD that supports MAX32 devices, since official OpenOCD does not yet have MAX32 flash algorithm support.
|
||||||
|
|
||||||
|
### 1. J-Link
|
||||||
<br>
|
|
||||||
|
|
||||||
`make flash` will use **J-Link** by default.
|
|
||||||
`make flash-msdk` to use the **OpenOCD** path with CMSIS-DAP.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 1. J-Link (default)
|
|
||||||
|
|
||||||
To flash using a J-Link debugger:
|
To flash using a J-Link debugger:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make BOARD=apard32690 flash
|
make tinyuf2-jlink
|
||||||
```
|
```
|
||||||
|
|
||||||
To erase before flashing:
|
To erase before flashing:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make BOARD=apard32690 erase flash
|
make tinyuf2-erase-jlink tinyuf2-jlink
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. OpenOCD from MSDK (optional)
|
### 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:
|
If you prefer OpenOCD and you have it installed through MSDK:
|
||||||
|
|
||||||
```bash
|
```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
|
```bash
|
||||||
make BOARD=apard32690 MAXIM_PATH=C:/MaximSDK flash-msdk
|
cmake -DBOARD=apard32690 -DMAXIM_PATH=/path/to/MaximSDK ..
|
||||||
```
|
```
|
||||||
|
or after initial configuration (in the build directory):
|
||||||
> ⚠️ **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:
|
|
||||||
|
|
||||||
```bash
|
```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
|
## Flashing Example Applications
|
||||||
|
|
||||||
After building any of the demo applications (Blinky, Erase Firmware, or Self-Update), a UF2 file will be generated in:
|
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:
|
For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
apps/blinky/_build/<board>/blinky-<board>.uf2
|
apps/blinky/blinky.uf2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Flashing via Drag-and-Drop
|
### Flashing via Drag-and-Drop
|
||||||
|
|
||||||
1. **Enter bootloader mode** on your board:
|
1. **Enter bootloader mode** on your board:
|
||||||
- Typically, perform a **double-tap on the reset button** within **500 milliseconds**.
|
- 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.
|
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.
|
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
|
### Re-Entering Bootloader Mode
|
||||||
|
|
||||||
To flash a different application or return to 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.
|
- 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.
|
- The board will reappear as a USB mass storage device for new UF2 flashing.
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
> ⚠️ **Note:**
|
> ⚠️ **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.
|
> 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.
|
> Refer to your board's documentation for additional recovery options if needed.
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Port Directory Structure
|
## Port Directory Structure
|
||||||
|
|
||||||
Example directory tree for the MAX32690 port:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
max32690
|
├── app.cmake
|
||||||
├── Makefile
|
|
||||||
├── README.md
|
|
||||||
├── _build
|
|
||||||
├── apps
|
|
||||||
│ ├── blinky
|
|
||||||
│ │ ├── Makefile
|
|
||||||
│ │ └── _build
|
|
||||||
│ ├── erase_firmware
|
|
||||||
│ │ ├── Makefile
|
|
||||||
│ │ └── _build
|
|
||||||
│ └── self_update
|
|
||||||
│ ├── Makefile
|
|
||||||
│ └── _build
|
|
||||||
├── board_flash.c
|
├── board_flash.c
|
||||||
├── boards
|
├── boards
|
||||||
│ ├── apard32690
|
│ ├── apard32690
|
||||||
│ │ ├── board.h
|
│ ├── max32650evkit
|
||||||
│ │ └── board.mk
|
│ ├── max32650fthr
|
||||||
│ └── max32690evkit
|
│ ├── max32666evkit
|
||||||
│ ├── board.h
|
│ ├── max32666fthr
|
||||||
│ └── board.mk
|
│ ├── max32690evkit
|
||||||
|
│ └── max78002evkit
|
||||||
├── boards.c
|
├── boards.c
|
||||||
├── boards.h
|
├── boards.h
|
||||||
|
├── CMakeLists.txt
|
||||||
|
├── family.cmake
|
||||||
├── linker
|
├── linker
|
||||||
│ ├── max32690_app.ld
|
│ ├── max32650
|
||||||
│ ├── max32690_boot.ld
|
│ ├── max32665
|
||||||
│ └── max32690_common.ld
|
│ ├── max32690
|
||||||
├── port.mk
|
│ └── max78002
|
||||||
|
├── README.md
|
||||||
└── tusb_config.h
|
└── 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(MAX_DEVICE max32665)
|
||||||
set(JLINK_DEVICE max32666)
|
set(JLINK_DEVICE max32666)
|
||||||
#set(JLINK_OPTION "-USB 801011822")
|
|
||||||
|
|
||||||
function(update_board TARGET)
|
function(update_board TARGET)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
# No specific build requirements for the board.
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
set(MAX_DEVICE max32665)
|
set(MAX_DEVICE max32665)
|
||||||
set(JLINK_DEVICE max32666)
|
set(JLINK_DEVICE max32666)
|
||||||
#set(JLINK_OPTION "-USB 801011822")
|
|
||||||
|
|
||||||
function(update_board TARGET)
|
function(update_board TARGET)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
# No specific build requirements for the board.
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
set(MAX_DEVICE max32690)
|
set(MAX_DEVICE max32690)
|
||||||
set(JLINK_DEVICE ${MAX_DEVICE})
|
set(JLINK_DEVICE ${MAX_DEVICE})
|
||||||
#set(JLINK_OPTION "-USB jtrace")
|
|
||||||
|
|
||||||
function(update_board TARGET)
|
function(update_board TARGET)
|
||||||
endfunction()
|
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
|
# This uf2 will be loaded into RAM
|
||||||
# TODO: this needs to build the actual uf2 binary first
|
# TODO: this needs to build the actual uf2 binary first
|
||||||
self-update: $(BUILD)/$(OUTNAME).bin
|
self-update: $(BUILD)/$(OUTNAME).bin
|
||||||
$(PYTHON3) $(TOP)/lib/uf2/utils/uf2conv.py --carray $^ -o apps/self_update/_build/bootloader_bin.c
|
@echo "not implemented yet"
|
||||||
$(MAKE) -C $(TOP)/$(PORT_DIR)/apps/self_update uf2
|
# $(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:
|
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 ----------
|
#---------- Erase app ----------
|
||||||
# Compile apps/erase_firmware/erase_firmware.c
|
# Compile apps/erase_firmware/erase_firmware.c
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,10 @@ OUTNAME = erase_firmware-$(BOARD)
|
||||||
BUILD_NO_TINYUSB = 1
|
BUILD_NO_TINYUSB = 1
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
apps/erase_firmware/erase_firmware.c \
|
apps/erase_firmware/src/erase_firmware.c \
|
||||||
$(TOP)/$(PORT_DIR)/boards.c \
|
$(PORT_DIR)/boards.c \
|
||||||
$(TOP)/$(PORT_DIR)/board_flash.c \
|
$(PORT_DIR)/board_flash.c \
|
||||||
$(TOP)/$(PORT_DIR)/board_irq.c \
|
$(PORT_DIR)/board_irq.c \
|
||||||
$(TOP)/$(PORT_DIR)/components/w25qxx/w25qxx.c \
|
|
||||||
$(TOP)/$(PORT_DIR)/components/w25qxx/w25qxx_qspi.c \
|
|
||||||
|
|
||||||
INC += \
|
INC += \
|
||||||
$(TOP)/src \
|
$(TOP)/src \
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,21 @@
|
||||||
OUTNAME = self_update-$(BOARD)
|
# OUTNAME = self_update-$(BOARD)
|
||||||
|
|
||||||
# skip tinyusb
|
# # skip tinyusb
|
||||||
BUILD_NO_TINYUSB = 1
|
# BUILD_NO_TINYUSB = 1
|
||||||
|
|
||||||
CFLAGS += -DTINYUF2_SELF_UPDATE
|
# CFLAGS += -DTINYUF2_SELF_UPDATE
|
||||||
|
|
||||||
SRC_C += \
|
# SRC_C += \
|
||||||
apps/self_update/self_update.c \
|
# apps/self_update/self_update.c \
|
||||||
$(TOP)/$(PORT_DIR)/apps/self_update/_build/bootloader_bin.c \
|
# $(TOP)/$(PORT_DIR)/apps/self_update/_build/bootloader_bin.c \
|
||||||
$(TOP)/$(PORT_DIR)/boards.c \
|
# $(TOP)/$(PORT_DIR)/boards.c \
|
||||||
$(TOP)/$(PORT_DIR)/board_hmi.c \
|
# $(TOP)/$(PORT_DIR)/board_hmi.c \
|
||||||
$(TOP)/$(PORT_DIR)/board_irq.c \
|
# $(TOP)/$(PORT_DIR)/board_irq.c \
|
||||||
|
|
||||||
INC += \
|
# INC += \
|
||||||
$(TOP)/src \
|
# $(TOP)/src \
|
||||||
|
|
||||||
include ../app.mk
|
# include ../app.mk
|
||||||
|
|
||||||
|
all:
|
||||||
|
@echo "not implemented yet"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "board_api.h"
|
#include "board_api.h"
|
||||||
#include "stm32h7xx_hal.h"
|
#include "stm32h7xx_hal.h"
|
||||||
|
#include "qspi_status.h"
|
||||||
|
|
||||||
#ifdef W25Qx_SPI
|
#ifdef W25Qx_SPI
|
||||||
#include "components/w25qxx/w25qxx.h"
|
#include "components/w25qxx/w25qxx.h"
|
||||||
|
|
@ -9,11 +10,16 @@
|
||||||
#include "components/w25qxx/w25qxx_qspi.h"
|
#include "components/w25qxx/w25qxx_qspi.h"
|
||||||
#endif // W25Qx_QSPI
|
#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;
|
QSPI_HandleTypeDef _qspi_flash;
|
||||||
#endif // BOARD_QSPI_FLASH_EN
|
#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;
|
SPI_HandleTypeDef _spi_flash;
|
||||||
#endif // BOARD_SPI_FLASH_EN
|
#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_ADDR _board_tmp_boot_addr[0]
|
||||||
#define TMP_BOOT_MAGIC _board_tmp_boot_magic[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)
|
uint32_t board_get_app_start_address(void)
|
||||||
{
|
{
|
||||||
if (TMP_BOOT_MAGIC == 0xDEADBEEFU)
|
if (TMP_BOOT_MAGIC == 0xDEADBEEFU)
|
||||||
|
|
@ -79,19 +146,19 @@ void board_clear_temp_boot_addr(void)
|
||||||
|
|
||||||
void board_flash_early_init(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 is initialized early to check for executable code
|
||||||
qspi_flash_init(&_qspi_flash);
|
qspi_flash_init(&_qspi_flash);
|
||||||
// Initialize QSPI driver
|
// Initialize QSPI driver
|
||||||
w25qxx_Init();
|
qspi_Init();
|
||||||
// SPI -> QPI
|
// SPI -> QPI
|
||||||
w25qxx_EnterQPI();
|
qspi_EnterQPI();
|
||||||
#endif // BOARD_QSPI_FLASH_EN
|
#endif // BOARD_QSPI_FLASH_EN
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_flash_init(void)
|
void board_flash_init(void)
|
||||||
{
|
{
|
||||||
#if BOARD_SPI_FLASH_EN
|
#if defined (BOARD_SPI_FLASH_EN) && (BOARD_SPI_FLASH_EN == 1)
|
||||||
// Initialize SPI peripheral
|
// Initialize SPI peripheral
|
||||||
spi_flash_init(&_spi_flash);
|
spi_flash_init(&_spi_flash);
|
||||||
// Initialize SPI drivers
|
// Initialize SPI drivers
|
||||||
|
|
@ -101,10 +168,10 @@ void board_flash_init(void)
|
||||||
|
|
||||||
void board_flash_deinit(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
|
// Enable Memory Mapped Mode
|
||||||
// QSPI flash will be available at 0x90000000U (readonly)
|
// QSPI flash will be available at 0x90000000U (readonly)
|
||||||
w25qxx_Startup(w25qxx_DTRMode);
|
qspi_Startup();
|
||||||
#endif // BOARD_QSPI_FLASH_EN
|
#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)
|
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);
|
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;
|
// addr += QSPI_BASE_ADDR;
|
||||||
if (IS_QSPI_ADDR(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;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#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))
|
if (IS_AXISRAM_ADDR(addr) && IS_AXISRAM_ADDR(addr + len - 1))
|
||||||
{
|
{
|
||||||
memcpy(data, (void *) addr, len);
|
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);
|
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
|
// TODO: these should be configurable parameters
|
||||||
// Page size = 256 bytes
|
// Page size = 256 bytes
|
||||||
// Sector size = 4K 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))
|
if (IS_SPI_ADDR(addr) && IS_SPI_ADDR(addr + len - 1))
|
||||||
{
|
{
|
||||||
W25Qx_Write((uint8_t *) data, (addr - SPI_BASE_ADDR), len);
|
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
|
#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))
|
if (IS_QSPI_ADDR(addr) && IS_QSPI_ADDR(addr + len - 1))
|
||||||
{
|
{
|
||||||
// SET_BOOT_ADDR(BOARD_AXISRAM_APP_ADDR);
|
// SET_BOOT_ADDR(BOARD_AXISRAM_APP_ADDR);
|
||||||
// handles erasing internally
|
// 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");
|
__asm("bkpt #9");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#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))
|
if (IS_AXISRAM_ADDR(addr) && IS_AXISRAM_ADDR(addr + len - 1))
|
||||||
{
|
{
|
||||||
// This memory is cached, DCache is cleaned in dfu_complete
|
// This memory is cached, DCache is cleaned in dfu_complete
|
||||||
|
|
@ -211,13 +288,13 @@ void board_flash_erase_app(void)
|
||||||
{
|
{
|
||||||
board_flash_init();
|
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");
|
TUF2_LOG1("Erasing QSPI Flash\r\n");
|
||||||
// Erase QSPI Flash
|
// Erase QSPI Flash
|
||||||
(void) W25qxx_EraseChip();
|
(void) qspi_EraseChip();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOARD_SPI_FLASH_EN
|
#if defined(BOARD_SPI_FLASH_EN) && (BOARD_SPI_FLASH_EN == 1)
|
||||||
TUF2_LOG1("Erasing SPI Flash\r\n");
|
TUF2_LOG1("Erasing SPI Flash\r\n");
|
||||||
// Erase QSPI Flash
|
// Erase QSPI Flash
|
||||||
(void) W25Qx_Erase_Chip();
|
(void) W25Qx_Erase_Chip();
|
||||||
|
|
|
||||||
|
|
@ -19,49 +19,44 @@ void ST7735_Delay(uint32_t ms)
|
||||||
{
|
{
|
||||||
HAL_Delay(ms);
|
HAL_Delay(ms);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void board_display_init(void)
|
void board_display_init(void)
|
||||||
{
|
{
|
||||||
#if (TINYUF2_DISPLAY == 1U)
|
|
||||||
display_init(&_display_spi);
|
display_init(&_display_spi);
|
||||||
ST7735_Init();
|
ST7735_Init();
|
||||||
// Clear previous screen
|
// Clear previous screen
|
||||||
ST7735_FillScreen(ST7735_BLACK);
|
ST7735_FillScreen(ST7735_BLACK);
|
||||||
#endif // TINYUF2_DISPLAY == 1U
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The application draws a complete frame in memory and sends it
|
// The application draws a complete frame in memory and sends it
|
||||||
// line-by-line to the display
|
// line-by-line to the display
|
||||||
void board_display_draw_line(int y, uint16_t* pixel_color, uint32_t pixel_num)
|
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) {
|
for (uint32_t x = 0; x < pixel_num; x += 1) {
|
||||||
ST7735_DrawPixel(y, x, pixel_color[x]);
|
ST7735_DrawPixel(y, x, pixel_color[x]);
|
||||||
}
|
}
|
||||||
#endif // TINYUF2_DISPLAY == 1U
|
|
||||||
}
|
}
|
||||||
|
#endif // TINYUF2_DISPLAY == 1U
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// LED pattern
|
// LED pattern
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
#if defined(TINYUF2_LED)
|
||||||
void board_led_write(uint32_t state)
|
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);
|
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||||
#endif // defined(LED_PIN)
|
|
||||||
}
|
}
|
||||||
|
#endif // defined(LED_PIN)
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Button
|
// Button
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
#if defined(BUTTON_PIN)
|
||||||
uint32_t board_button_read(void)
|
uint32_t board_button_read(void)
|
||||||
{
|
{
|
||||||
#if defined(BUTTON_PIN)
|
|
||||||
return (BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)) ? 1: 0;
|
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
|
// Neopixel color for status
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,27 @@
|
||||||
#include "stm32h7xx_hal.h"
|
#include "stm32h7xx_hal.h"
|
||||||
#include "board_api.h"
|
#include "board_api.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define STM32_UUID ((uint32_t *)0x1FF1E800)
|
#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)
|
void board_init(void)
|
||||||
{
|
{
|
||||||
SCB_EnableICache();
|
SCB_EnableICache();
|
||||||
|
|
@ -26,9 +45,31 @@ void board_init(void)
|
||||||
__HAL_RCC_GPIOI_CLK_ENABLE();
|
__HAL_RCC_GPIOI_CLK_ENABLE();
|
||||||
__HAL_RCC_GPIOJ_CLK_ENABLE();
|
__HAL_RCC_GPIOJ_CLK_ENABLE();
|
||||||
__HAL_RCC_GPIOK_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
|
#ifdef BUTTON_PIN
|
||||||
GPIO_InitStruct.Pin = BUTTON_PIN;
|
GPIO_InitStruct.Pin = BUTTON_PIN;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
|
|
@ -53,8 +94,8 @@ void board_init(void)
|
||||||
void board_dfu_init(void)
|
void board_dfu_init(void)
|
||||||
{
|
{
|
||||||
// Not quite sure what an RHPORT is :/
|
// Not quite sure what an RHPORT is :/
|
||||||
#if BOARD_TUD_RHPORT == 0
|
#if defined (BOARD_TUD_RHPORT) && (BOARD_TUD_RHPORT == 0)
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||||
|
|
||||||
// Init USB Pins
|
// Init USB Pins
|
||||||
// Configure DM DP 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_BVALOEN;
|
||||||
USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
|
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
|
// TODO: implement whatever this is
|
||||||
#error "Sorry, not implemented yet"
|
#error "Sorry, not implemented yet"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -112,8 +153,8 @@ bool board_app_valid(void)
|
||||||
switch ((app_vector[0] & 0xFFFF0003u))
|
switch ((app_vector[0] & 0xFFFF0003u))
|
||||||
{
|
{
|
||||||
case 0x00000000u: // ITCM 64K [0x0000_0000u--0x0000_FFFFu]
|
case 0x00000000u: // ITCM 64K [0x0000_0000u--0x0000_FFFFu]
|
||||||
case 0x20000000u: // DTCM 64K [0x2000_0000u--0x2000_FFFFu]
|
case 0x20010000u: // DTCM 64K [0x2000_0000u--0x2000_FFFFu]
|
||||||
case 0x20010000u: // DTCM 64K [0x2001_0000u--0x2001_FFFFu]
|
case 0x20020000u: // DTCM 64K [0x2001_0000u--0x2001_FFFFu]
|
||||||
case 0x24000000u: // AXI SRAM 512K [0x2400_0000u--0x2407_FFFFu]
|
case 0x24000000u: // AXI SRAM 512K [0x2400_0000u--0x2407_FFFFu]
|
||||||
case 0x30010000u: // SRAM1 64K [0x3001_0000u--0x3001_FFFFu]
|
case 0x30010000u: // SRAM1 64K [0x3001_0000u--0x3001_FFFFu]
|
||||||
case 0x30020000u: // SRAM2 64K [0x3002_0000u--0x3002_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_GPIOJ_CLK_DISABLE();
|
||||||
__HAL_RCC_GPIOK_CLK_DISABLE();
|
__HAL_RCC_GPIOK_CLK_DISABLE();
|
||||||
// Lotsa GPIOs
|
// 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_DisableICache();
|
||||||
SCB_DisableDCache();
|
SCB_DisableDCache();
|
||||||
|
|
||||||
// Clear temporary boot address
|
// Clear temporary boot address
|
||||||
board_clear_temp_boot_addr();
|
board_clear_temp_boot_addr();
|
||||||
|
|
||||||
// Setup VTOR to point to application vectors
|
#ifdef UART_DEV
|
||||||
SCB->VTOR = (uint32_t) app_addr;
|
HAL_UART_DeInit(&UartHandle);
|
||||||
|
HAL_GPIO_DeInit(UART_GPIO_PORT, UART_TX_PIN | UART_RX_PIN);
|
||||||
|
UART_CLOCK_DISABLE();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set stack pointer
|
// Set stack pointer
|
||||||
__set_MSP(app_vector[0]);
|
__set_MSP(app_vector[0]);
|
||||||
|
|
@ -187,6 +244,11 @@ void board_app_jump(void)
|
||||||
|
|
||||||
TUF2_LOG1("App address: %08lx\r\n", app_vector[1]);
|
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
|
// Jump to application reset vector
|
||||||
asm("bx %0" :: "r"(app_vector[1]));
|
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)
|
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) buf;
|
||||||
(void) len;
|
(void) len;
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TINYUF2_SELF_UPDATE
|
#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
|
SPI_FLASH = W25Qx_SPI
|
||||||
QSPI_FLASH = W25Qx_QSPI
|
QSPI_FLASH = W25Qx_QSPI
|
||||||
DISPLAY_DRV = ST7735
|
DISPLAY_DRV = ST7735
|
||||||
|
JLINK_DEVICE = stm32h750vb
|
||||||
|
|
||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
-DSTM32H750xx \
|
-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 "w25qxx_qspi.h"
|
||||||
|
#include "qspi_status.h"
|
||||||
|
#include "stm32h7xx_hal.h"
|
||||||
|
|
||||||
|
|
||||||
extern QSPI_HandleTypeDef _qspi_flash;
|
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,
|
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);
|
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];
|
uint8_t w25qxx_StatusReg[3];
|
||||||
uint16_t w25qxx_ID;
|
uint16_t w25qxx_ID;
|
||||||
|
|
||||||
|
|
@ -30,7 +32,7 @@ uint16_t w25qxx_GetID(void)
|
||||||
uint8_t ID[6];
|
uint8_t ID[6];
|
||||||
uint16_t deviceID;
|
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));
|
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
|
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));
|
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 */
|
/* Reception of the data */
|
||||||
if (HAL_QSPI_Receive(&_qspi_flash, ID, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
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];
|
deviceID = (ID[0] << 8) | ID[1];
|
||||||
|
|
||||||
|
|
@ -48,7 +50,7 @@ uint16_t w25qxx_GetID(void)
|
||||||
uint8_t w25qxx_ReadSR(uint8_t SR)
|
uint8_t w25qxx_ReadSR(uint8_t SR)
|
||||||
{
|
{
|
||||||
uint8_t byte=0;
|
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);
|
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
|
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);
|
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)
|
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);
|
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
|
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);
|
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[0] = w25qxx_ReadSR(W25X_ReadStatusReg1);
|
||||||
w25qxx_StatusReg[1] = w25qxx_ReadSR(W25X_ReadStatusReg2);
|
w25qxx_StatusReg[1] = w25qxx_ReadSR(W25X_ReadStatusReg2);
|
||||||
w25qxx_StatusReg[2] = w25qxx_ReadSR(W25X_ReadStatusReg3);
|
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;
|
uint8_t send;
|
||||||
send = (DummyClock/2 -1)<<4 | ((WrapLenth/8 - 1)&0x03);
|
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);
|
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)
|
uint8_t w25qxx_EnterQPI(void)
|
||||||
{
|
{
|
||||||
/* Enter QSPI memory in QSPI mode */
|
/* 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);
|
return w25qxx_SetReadParameters(8,8);
|
||||||
|
|
@ -116,14 +118,14 @@ uint8_t w25qxx_EnterQPI(void)
|
||||||
uint8_t w25qxx_Startup(uint8_t DTRMode)
|
uint8_t w25qxx_Startup(uint8_t DTRMode)
|
||||||
{
|
{
|
||||||
/* Enable MemoryMapped mode */
|
/* 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);
|
return QSPI_WriteEnable(&_qspi_flash);
|
||||||
}
|
}
|
||||||
|
|
@ -132,20 +134,20 @@ uint8_t W25qxx_WriteEnable(void)
|
||||||
* @param SectorAddress: Sector address to erase
|
* @param SectorAddress: Sector address to erase
|
||||||
* @retval QSPI memory status
|
* @retval QSPI memory status
|
||||||
*/
|
*/
|
||||||
uint8_t W25qxx_EraseSector(uint32_t SectorAddress)
|
uint8_t w25qxx_EraseSector(uint32_t SectorAddress)
|
||||||
{
|
{
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
|
|
||||||
W25qxx_WriteEnable();
|
w25qxx_WriteEnable();
|
||||||
W25QXX_Wait_Busy();
|
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);
|
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
|
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);
|
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();
|
W25QXX_Wait_Busy();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -156,20 +158,20 @@ uint8_t W25qxx_EraseSector(uint32_t SectorAddress)
|
||||||
* @param SectorAddress: Sector address to erase
|
* @param SectorAddress: Sector address to erase
|
||||||
* @retval QSPI memory status
|
* @retval QSPI memory status
|
||||||
*/
|
*/
|
||||||
uint8_t W25qxx_EraseBlock(uint32_t BlockAddress)
|
uint8_t w25qxx_EraseBlock(uint32_t BlockAddress)
|
||||||
{
|
{
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
|
|
||||||
W25qxx_WriteEnable();
|
w25qxx_WriteEnable();
|
||||||
W25QXX_Wait_Busy();
|
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);
|
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
|
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);
|
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();
|
W25QXX_Wait_Busy();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -180,20 +182,20 @@ uint8_t W25qxx_EraseBlock(uint32_t BlockAddress)
|
||||||
* @param SectorAddress: Sector address to erase
|
* @param SectorAddress: Sector address to erase
|
||||||
* @retval QSPI memory status
|
* @retval QSPI memory status
|
||||||
*/
|
*/
|
||||||
uint8_t W25qxx_EraseChip(void)
|
uint8_t w25qxx_EraseChip(void)
|
||||||
{
|
{
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
|
|
||||||
W25qxx_WriteEnable();
|
w25qxx_WriteEnable();
|
||||||
W25QXX_Wait_Busy();
|
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);
|
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
|
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);
|
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();
|
W25QXX_Wait_Busy();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -206,22 +208,22 @@ uint8_t W25qxx_EraseChip(void)
|
||||||
* @param Size Size of data to write. Range 1 ~ W25qxx page size
|
* @param Size Size of data to write. Range 1 ~ W25qxx page size
|
||||||
* @retval QSPI memory status
|
* @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;
|
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);
|
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
|
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);
|
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);
|
result = HAL_QSPI_Transmit(&_qspi_flash,pData,HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
|
||||||
|
|
||||||
/* 等待写入完成 */
|
/* 等待写入完成 */
|
||||||
if(result == w25qxx_OK)
|
if(result == qspi_OK)
|
||||||
W25QXX_Wait_Busy();
|
W25QXX_Wait_Busy();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -232,7 +234,7 @@ uint8_t W25qxx_PageProgram(uint8_t *pData, uint32_t WriteAddr, uint32_t Size)
|
||||||
//pBuffer:数据存储区
|
//pBuffer:数据存储区
|
||||||
//ReadAddr:开始读取的地址(最大32bit)
|
//ReadAddr:开始读取的地址(最大32bit)
|
||||||
//NumByteToRead:要读取的字节数(最大65535)
|
//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;
|
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 */
|
/* 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.Instruction = W25X_QUAD_INOUT_FAST_READ_CMD;
|
||||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
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);
|
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);
|
result = HAL_QSPI_Receive(&_qspi_flash,pData,HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -285,7 +287,7 @@ uint8_t W25qxx_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
|
||||||
//WriteAddr:开始写入的地址(最大32bit)
|
//WriteAddr:开始写入的地址(最大32bit)
|
||||||
//NumByteToWrite:要写入的字节数(最大65535)
|
//NumByteToWrite:要写入的字节数(最大65535)
|
||||||
//CHECK OK
|
//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;
|
uint16_t pageremain;
|
||||||
pageremain = 256 - WriteAddr % 256; //单页剩余的字节数
|
pageremain = 256 - WriteAddr % 256; //单页剩余的字节数
|
||||||
|
|
@ -295,7 +297,7 @@ void W25qxx_WriteNoCheck(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t NumByteToW
|
||||||
}
|
}
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
W25qxx_PageProgram(pBuffer, WriteAddr, pageremain);
|
w25qxx_PageProgram(pBuffer, WriteAddr, pageremain);
|
||||||
if (NumByteToWrite == pageremain)
|
if (NumByteToWrite == pageremain)
|
||||||
{
|
{
|
||||||
break; //写入结束了
|
break; //写入结束了
|
||||||
|
|
@ -320,7 +322,7 @@ void W25qxx_WriteNoCheck(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t NumByteToW
|
||||||
//pBuffer:数据存储区
|
//pBuffer:数据存储区
|
||||||
//WriteAddr:开始写入的地址(最大32bit)
|
//WriteAddr:开始写入的地址(最大32bit)
|
||||||
//NumByteToWrite:要写入的字节数(最大65535)
|
//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;
|
uint32_t secpos;
|
||||||
uint16_t secoff;
|
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个字节
|
if (NumByteToWrite <= secremain) secremain = NumByteToWrite; //不大于4096个字节
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
if (W25qxx_Read(W25QXX_BUF, secpos * 4096, 4096) != w25qxx_OK) {
|
if (w25qxx_Read(W25QXX_BUF, secpos * 4096, 4096) != qspi_OK) {
|
||||||
return w25qxx_ERROR;
|
return qspi_ERROR;
|
||||||
} //读出整个扇区的内容
|
} //读出整个扇区的内容
|
||||||
for (i = 0;i < secremain; i++) //校验数据
|
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 (i < secremain) //需要擦除
|
||||||
{
|
{
|
||||||
if (W25qxx_EraseSector(secpos) != w25qxx_OK) {
|
if (w25qxx_EraseSector(secpos) != qspi_OK) {
|
||||||
return w25qxx_ERROR;
|
return qspi_ERROR;
|
||||||
} //擦除这个扇区
|
} //擦除这个扇区
|
||||||
for (i = 0; i < secremain; i++) //复制
|
for (i = 0; i < secremain; i++) //复制
|
||||||
{
|
{
|
||||||
W25QXX_BUF[i + secoff] = pBuffer[i];
|
W25QXX_BUF[i + secoff] = pBuffer[i];
|
||||||
}
|
}
|
||||||
W25qxx_WriteNoCheck(W25QXX_BUF, secpos * 4096, 4096); //写入整个扇区
|
w25qxx_WriteNoCheck(W25QXX_BUF, secpos * 4096, 4096); //写入整个扇区
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
W25qxx_WriteNoCheck(pBuffer, WriteAddr, secremain); //写已经擦除了的,直接写入扇区剩余区间.
|
w25qxx_WriteNoCheck(pBuffer, WriteAddr, secremain); //写已经擦除了的,直接写入扇区剩余区间.
|
||||||
}
|
}
|
||||||
if (NumByteToWrite == secremain)
|
if (NumByteToWrite == secremain)
|
||||||
{
|
{
|
||||||
|
|
@ -375,13 +377,13 @@ uint8_t W25qxx_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWri
|
||||||
secremain = NumByteToWrite; //下一个扇区可以写完了
|
secremain = NumByteToWrite; //下一个扇区可以写完了
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return w25qxx_OK;
|
return qspi_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configure the QSPI in memory-mapped mode QPI/SPI && DTR(DDR)/Normal Mode
|
* @brief Configure the QSPI in memory-mapped mode QPI/SPI && DTR(DDR)/Normal Mode
|
||||||
* @param hqspi: QSPI handle
|
* @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
|
* @retval QSPI memory status
|
||||||
*/
|
*/
|
||||||
static uint32_t QSPI_EnableMemoryMappedMode(QSPI_HandleTypeDef *hqspi,uint8_t DTRMode)
|
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;
|
QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
|
||||||
|
|
||||||
/* Configure the command for the read instruction */
|
/* Configure the command for the read instruction */
|
||||||
if(w25qxx_Mode == w25qxx_QPIMode)
|
if(w25qxx_Mode == qspi_QPIMode)
|
||||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||||
else
|
else
|
||||||
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
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;
|
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.Instruction = W25X_QUAD_INOUT_FAST_READ_DTR_CMD;
|
||||||
s_command.DummyCycles = W25X_DUMMY_CYCLES_READ_QUAD_DTR;
|
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;
|
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;
|
s_command.DummyCycles = W25X_DUMMY_CYCLES_READ_QUAD;
|
||||||
else
|
else
|
||||||
s_command.DummyCycles = W25X_DUMMY_CYCLES_READ_QUAD-2;
|
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)
|
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 */
|
/* Send the command */
|
||||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
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 */
|
/* Send the reset device command */
|
||||||
s_command.Instruction = W25X_ResetDevice;
|
s_command.Instruction = W25X_ResetDevice;
|
||||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
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;
|
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||||
|
|
@ -476,18 +478,18 @@ static uint32_t QSPI_ResetDevice(QSPI_HandleTypeDef *hqspi)
|
||||||
/* Send the command */
|
/* Send the command */
|
||||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
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 */
|
/* Send the reset memory command */
|
||||||
s_command.Instruction = W25X_ResetDevice;
|
s_command.Instruction = W25X_ResetDevice;
|
||||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
||||||
{
|
{
|
||||||
return w25qxx_ERROR;
|
return qspi_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
w25qxx_Mode = w25qxx_SPIMode;
|
w25qxx_Mode = qspi_SPIMode;
|
||||||
return w25qxx_OK;
|
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 dataMode 数据模式; QSPI_DATA_NONE,QSPI_DATA_1_LINE,QSPI_DATA_2_LINES,QSPI_DATA_4_LINES
|
||||||
* @param dataSize 待传输的数据长度
|
* @param dataSize 待传输的数据长度
|
||||||
*
|
*
|
||||||
* @return uint8_t w25qxx_OK:正常
|
* @return uint8_t qspi_OK:正常
|
||||||
* w25qxx_ERROR:错误
|
* qspi_ERROR:错误
|
||||||
*/
|
*/
|
||||||
static uint8_t QSPI_Send_CMD(QSPI_HandleTypeDef *hqspi,uint32_t instruction, uint32_t address,uint32_t addressSize,uint32_t dummyCycles,
|
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)
|
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;
|
Cmdhandler.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||||
|
|
||||||
if(HAL_QSPI_Command(hqspi, &Cmdhandler, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
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;
|
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
|
||||||
|
|
||||||
/* Enable write operations */
|
/* Enable write operations */
|
||||||
if (QSPI_WriteEnable(hqspi) != w25qxx_OK)
|
if (QSPI_WriteEnable(hqspi) != qspi_OK)
|
||||||
{
|
{
|
||||||
return w25qxx_ERROR;
|
return qspi_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the command */
|
/* Send the command */
|
||||||
if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
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 */
|
/* 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;
|
QSPI_AutoPollingTypeDef s_config;
|
||||||
|
|
||||||
/* Enable write operations */
|
/* Enable write operations */
|
||||||
if(w25qxx_Mode == w25qxx_QPIMode)
|
if(w25qxx_Mode == qspi_QPIMode)
|
||||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
||||||
else
|
else
|
||||||
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
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)
|
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 */
|
/* 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;
|
s_command.Instruction = W25X_ReadStatusReg1;
|
||||||
|
|
||||||
if(w25qxx_Mode == w25qxx_QPIMode)
|
if(w25qxx_Mode == qspi_QPIMode)
|
||||||
s_command.DataMode = QSPI_DATA_4_LINES;
|
s_command.DataMode = QSPI_DATA_4_LINES;
|
||||||
else
|
else
|
||||||
s_command.DataMode = QSPI_DATA_1_LINE;
|
s_command.DataMode = QSPI_DATA_1_LINE;
|
||||||
|
|
||||||
if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
|
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 */
|
/* 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;
|
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
|
||||||
else
|
else
|
||||||
s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
|
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.AddressSize = QSPI_ADDRESS_8_BITS;
|
||||||
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
|
||||||
|
|
||||||
if(w25qxx_Mode == w25qxx_SPIMode)
|
if(w25qxx_Mode == qspi_SPIMode)
|
||||||
s_command.DataMode = QSPI_DATA_1_LINE;
|
s_command.DataMode = QSPI_DATA_1_LINE;
|
||||||
else
|
else
|
||||||
s_command.DataMode = QSPI_DATA_4_LINES;
|
s_command.DataMode = QSPI_DATA_4_LINES;
|
||||||
|
|
@ -685,19 +687,19 @@ static uint8_t QSPI_EnterQPI(QSPI_HandleTypeDef *hqspi)
|
||||||
stareg2 = w25qxx_ReadSR(W25X_ReadStatusReg2);
|
stareg2 = w25qxx_ReadSR(W25X_ReadStatusReg2);
|
||||||
if((stareg2 & 0X02) == 0) //QE位未使能
|
if((stareg2 & 0X02) == 0) //QE位未使能
|
||||||
{
|
{
|
||||||
W25qxx_WriteEnable();
|
w25qxx_WriteEnable();
|
||||||
stareg2 |= 1<<1; //使能QE位
|
stareg2 |= 1<<1; //使能QE位
|
||||||
w25qxx_WriteSR(W25X_WriteStatusReg2,stareg2);
|
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);
|
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 */
|
/* 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>
|
#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 ================ */
|
/* =============== W25Qxx CMD ================ */
|
||||||
#define W25X_WriteEnable 0x06
|
#define W25X_WriteEnable 0x06
|
||||||
#define W25X_WriteDisable 0x04
|
#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_SetReadParameters(uint8_t DummyClock,uint8_t WrapLenth);
|
||||||
uint8_t w25qxx_EnterQPI(void);
|
uint8_t w25qxx_EnterQPI(void);
|
||||||
uint8_t w25qxx_Startup(uint8_t DTRMode);
|
uint8_t w25qxx_Startup(uint8_t DTRMode);
|
||||||
uint8_t W25qxx_WriteEnable(void);
|
uint8_t w25qxx_WriteEnable(void);
|
||||||
uint8_t W25qxx_EraseSector(uint32_t SectorAddress);
|
uint8_t w25qxx_EraseSector(uint32_t SectorAddress);
|
||||||
uint8_t W25qxx_EraseBlock(uint32_t BlockAddress);
|
uint8_t w25qxx_EraseBlock(uint32_t BlockAddress);
|
||||||
uint8_t W25qxx_EraseChip(void);
|
uint8_t w25qxx_EraseChip(void);
|
||||||
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 W25qxx_Read(uint8_t *pData, uint32_t ReadAddr, 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);
|
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_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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
|
CFLAGS += -Wno-error=cast-align -Wno-error=unused-parameter -Wno-error=unused-but-set-variable -Wno-error=unused-function
|
||||||
|
|
||||||
ifeq ($(SPI_FLASH),W25Qx_SPI)
|
ifeq ($(SPI_FLASH),W25Qx_SPI)
|
||||||
INC += \
|
INC += ${TOP}/$(PORT_DIR)/components/w25qxx
|
||||||
$(CURRENT_PATH)/components/w25qxx/ \
|
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
$(TOP)/$(PORT_DIR)/components/w25qxx/w25qxx.c
|
$(PORT_DIR)/components/w25qxx/w25qxx.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(QSPI_FLASH),W25Qx_QSPI)
|
ifeq ($(QSPI_FLASH),W25Qx_QSPI)
|
||||||
INC += \
|
INC += ${TOP}/$(PORT_DIR)/components/w25qxx
|
||||||
$(CURRENT_PATH)/components/w25qxx/ \
|
|
||||||
|
|
||||||
SRC_C += \
|
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
|
endif
|
||||||
|
|
||||||
ifeq ($(DISPLAY_DRV),ST7735)
|
ifeq ($(DISPLAY_DRV),ST7735)
|
||||||
INC += \
|
INC += ${TOP}/$(PORT_DIR)/components/st7735/
|
||||||
$(CURRENT_PATH)/components/w25qxx/ \
|
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
$(TOP)/$(PORT_DIR)/components/st7735/st7735.c
|
$(PORT_DIR)/components/st7735/st7735.c \
|
||||||
|
$(PORT_DIR)/components/st7735/fonts.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Source
|
# Source
|
||||||
|
|
@ -63,8 +65,6 @@ SRC_C += \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_qspi.c \
|
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_qspi.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_mdma.c \
|
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_mdma.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_pwr_ex.c \
|
$(ST_HAL_DRIVER)/Src/stm32h7xx_hal_pwr_ex.c \
|
||||||
$(TOP)/$(PORT_DIR)/components/st7735/fonts.c \
|
|
||||||
|
|
||||||
|
|
||||||
ifndef BUILD_NO_TINYUSB
|
ifndef BUILD_NO_TINYUSB
|
||||||
SRC_C += lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c
|
SRC_C += lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c
|
||||||
|
|
@ -75,8 +75,6 @@ endif
|
||||||
INC += \
|
INC += \
|
||||||
$(TOP)/$(BOARD_PATH) \
|
$(TOP)/$(BOARD_PATH) \
|
||||||
$(TOP)/$(CMSIS_5)/CMSIS/Core/Include \
|
$(TOP)/$(CMSIS_5)/CMSIS/Core/Include \
|
||||||
$(CURRENT_PATH)/components/st7735/ \
|
|
||||||
$(CURRENT_PATH)/components/w25qxx/ \
|
|
||||||
$(TOP)/$(PORT_DIR)/ \
|
$(TOP)/$(PORT_DIR)/ \
|
||||||
$(TOP)/$(BOARD_DIR) \
|
$(TOP)/$(BOARD_DIR) \
|
||||||
$(TOP)/$(ST_CMSIS)/Include \
|
$(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