From 8b58c01cd77bbf9f2e8390a8536c0219f9f77672 Mon Sep 17 00:00:00 2001 From: henrykotze Date: Wed, 25 Sep 2024 14:29:39 +0200 Subject: [PATCH] ESP32 Support Sponsored by AutonoSky nsh console running on USB param module running working with i2c and common drivers provided implementation for drv_pwm_output.h i2cdetect working as expected with no device mavlink started succesfully mounts sd card and logger runs logger to file succesfully pwm_servo implemented without using Nuttx lib pwm_out outputs expected waveforms - however currently if the frequency is higher than what the pwm_out driver runs, there will be aliasing, based on how the registers gets resets wifi softap working - Seeing wifi hotspot - cant connect due to wrong password - problems with adjusting ssid and password wifi ssid and password being set accordinglu connected to wifi hotspot with dhpcd - made some changes to nuttx to only build for SoftAP mode, however this was effectivelyy removing the ifdef for STATION mode. Should investigate the coexist option again added ifdef to not use timer 0 when wifi enabled - reverted esp32 rt_timer to make use of timer 0 by default fix setting incorrect bit in hrt timer register - hrt running as expected, but on startup the pwm_out driver starts up at about 200Hz and then rises over a minute or so 250Hz. Not sure if this was present previously, and could be due to Wifi running at time priority on timer 0 pull xtensa compilers in setup.ubuntu.sh revert logger stacksize and cmake argument esp32 chip revision and PX4 UUID implemented spi board reset implemented, formatting checked devkit acts on startup as a wifi bridge for comms - the most usefull setting for the general developer when buying a esp32 devkit - testing Mavlink shell using ./Tools/mavlink_shell.py - todo: Test mavlink messages being forward improve wifi telemetry by increasing prio - Remove power save mode on wifi - increased daemon thread schedule priority to 50 compiles without Nuttx changes - updated compiler settings to match those of nuttx on px4 side add espressif_esp32 to excluded boards ci: allow docker to find xtensa compilers --- Tools/ci/generate_board_targets_json.py | 2 +- Tools/setup/Dockerfile | 2 + Tools/setup/ubuntu.sh | 7 + .../espressif/esp32/boot/bootloader-esp32.bin | Bin 0 -> 26288 bytes boards/espressif/esp32/boot/bootloader.bin | Bin 0 -> 27888 bytes .../espressif/esp32/boot/partition-table.bin | Bin 0 -> 3072 bytes boards/espressif/esp32/default.px4board | 39 + boards/espressif/esp32/firmware.prototype | 13 + boards/espressif/esp32/init/rc.board_defaults | 8 + boards/espressif/esp32/init/rc.board_mavlink | 6 + boards/espressif/esp32/init/rc.board_sensors | 4 + .../esp32/nuttx-config/include/board.h | 61 + .../esp32/nuttx-config/include/esp32_board.h | 85 + .../esp32/nuttx-config/nsh/defconfig | 219 ++ .../esp32/nuttx-config/scripts/esp32.ld | 296 +++ .../esp32/nuttx-config/scripts/esp32_out.ld | 121 + .../esp32/nuttx-config/scripts/esp32_rom.ld | 2049 +++++++++++++++++ .../esp32/nuttx-config/scripts/script.ld | 78 + .../esp32/nuttx-config/src/Make.defs | 72 + boards/espressif/esp32/src/CMakeLists.txt | 54 + boards/espressif/esp32/src/board_config.h | 120 + .../esp32/src/esp32_board_spiflash.c | 574 +++++ .../esp32/src/esp32_board_spiflash_setup.c | 353 +++ .../esp32/src/esp32_board_spiflash_setup.h | 68 + .../esp32/src/esp32_board_wlan_setup.c | 91 + .../esp32/src/esp32_board_wlan_setup.h | 73 + boards/espressif/esp32/src/i2c.cpp | 38 + boards/espressif/esp32/src/init.c | 300 +++ boards/espressif/esp32/src/led.c | 102 + boards/espressif/esp32/src/mtd.cpp | 76 + boards/espressif/esp32/src/spi.cpp | 52 + boards/espressif/esp32/src/timer_config.cpp | 48 + boards/espressif/esp32/src/usb.c | 84 + platforms/nuttx/CMakeLists.txt | 100 + .../Generic-xtensa-esp32-elf-gcc-esp32.cmake | 4 + .../cmake/Toolchain-xtensa-esp32-elf.cmake | 44 + platforms/nuttx/cmake/px4_impl_os.cmake | 3 + platforms/nuttx/src/px4/common/SerialImpl.cpp | 4 + .../nuttx/src/px4/espressif/CMakeLists.txt | 34 + .../src/px4/espressif/esp32/CMakeLists.txt | 6 + .../esp32/board_critmon/CMakeLists.txt | 36 + .../esp32/board_critmon/board_critmon.c | 66 + .../esp32/board_reset/CMakeLists.txt | 43 + .../esp32/board_reset/board_reset.cpp | 105 + .../px4/espressif/esp32/hrt/CMakeLists.txt | 41 + .../nuttx/src/px4/espressif/esp32/hrt/hrt.c | 636 +++++ .../espressif/esp32/include/px4_arch/adc.h | 39 + .../esp32/include/px4_arch/hw_description.h | 245 ++ .../include/px4_arch/i2c_hw_description.h | 56 + .../esp32/include/px4_arch/io_timer.h | 176 ++ .../px4_arch/io_timer_hw_description.h | 170 ++ .../esp32/include/px4_arch/micro_hal.h | 130 ++ .../include/px4_arch/spi_hw_description.h | 220 ++ .../espressif/esp32/io_pins/CMakeLists.txt | 44 + .../espressif/esp32/io_pins/esp32_pinset.c | 74 + .../px4/espressif/esp32/io_pins/io_timer.c | 98 + .../px4/espressif/esp32/io_pins/pwm_servo.c | 321 +++ .../px4/espressif/esp32/spi/CMakeLists.txt | 39 + .../nuttx/src/px4/espressif/esp32/spi/spi.cpp | 322 +++ .../espressif/esp32/version/CMakeLists.txt | 37 + .../espressif/esp32/version/board_identity.c | 160 ++ .../esp32/version/board_mcu_version.c | 103 + 62 files changed, 8450 insertions(+), 1 deletion(-) create mode 100644 boards/espressif/esp32/boot/bootloader-esp32.bin create mode 100755 boards/espressif/esp32/boot/bootloader.bin create mode 100644 boards/espressif/esp32/boot/partition-table.bin create mode 100644 boards/espressif/esp32/default.px4board create mode 100644 boards/espressif/esp32/firmware.prototype create mode 100644 boards/espressif/esp32/init/rc.board_defaults create mode 100644 boards/espressif/esp32/init/rc.board_mavlink create mode 100644 boards/espressif/esp32/init/rc.board_sensors create mode 100644 boards/espressif/esp32/nuttx-config/include/board.h create mode 100644 boards/espressif/esp32/nuttx-config/include/esp32_board.h create mode 100644 boards/espressif/esp32/nuttx-config/nsh/defconfig create mode 100644 boards/espressif/esp32/nuttx-config/scripts/esp32.ld create mode 100644 boards/espressif/esp32/nuttx-config/scripts/esp32_out.ld create mode 100644 boards/espressif/esp32/nuttx-config/scripts/esp32_rom.ld create mode 100644 boards/espressif/esp32/nuttx-config/scripts/script.ld create mode 100644 boards/espressif/esp32/nuttx-config/src/Make.defs create mode 100644 boards/espressif/esp32/src/CMakeLists.txt create mode 100644 boards/espressif/esp32/src/board_config.h create mode 100644 boards/espressif/esp32/src/esp32_board_spiflash.c create mode 100644 boards/espressif/esp32/src/esp32_board_spiflash_setup.c create mode 100644 boards/espressif/esp32/src/esp32_board_spiflash_setup.h create mode 100644 boards/espressif/esp32/src/esp32_board_wlan_setup.c create mode 100644 boards/espressif/esp32/src/esp32_board_wlan_setup.h create mode 100644 boards/espressif/esp32/src/i2c.cpp create mode 100644 boards/espressif/esp32/src/init.c create mode 100644 boards/espressif/esp32/src/led.c create mode 100644 boards/espressif/esp32/src/mtd.cpp create mode 100644 boards/espressif/esp32/src/spi.cpp create mode 100644 boards/espressif/esp32/src/timer_config.cpp create mode 100644 boards/espressif/esp32/src/usb.c create mode 100644 platforms/nuttx/cmake/Platform/Generic-xtensa-esp32-elf-gcc-esp32.cmake create mode 100644 platforms/nuttx/cmake/Toolchain-xtensa-esp32-elf.cmake create mode 100644 platforms/nuttx/src/px4/espressif/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/espressif/esp32/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/espressif/esp32/board_critmon/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/espressif/esp32/board_critmon/board_critmon.c create mode 100644 platforms/nuttx/src/px4/espressif/esp32/board_reset/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/espressif/esp32/board_reset/board_reset.cpp create mode 100644 platforms/nuttx/src/px4/espressif/esp32/hrt/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/espressif/esp32/hrt/hrt.c create mode 100644 platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/adc.h create mode 100644 platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/hw_description.h create mode 100644 platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/i2c_hw_description.h create mode 100644 platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/io_timer.h create mode 100644 platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/io_timer_hw_description.h create mode 100644 platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/micro_hal.h create mode 100644 platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/spi_hw_description.h create mode 100644 platforms/nuttx/src/px4/espressif/esp32/io_pins/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/espressif/esp32/io_pins/esp32_pinset.c create mode 100644 platforms/nuttx/src/px4/espressif/esp32/io_pins/io_timer.c create mode 100644 platforms/nuttx/src/px4/espressif/esp32/io_pins/pwm_servo.c create mode 100644 platforms/nuttx/src/px4/espressif/esp32/spi/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/espressif/esp32/spi/spi.cpp create mode 100644 platforms/nuttx/src/px4/espressif/esp32/version/CMakeLists.txt create mode 100644 platforms/nuttx/src/px4/espressif/esp32/version/board_identity.c create mode 100644 platforms/nuttx/src/px4/espressif/esp32/version/board_mcu_version.c diff --git a/Tools/ci/generate_board_targets_json.py b/Tools/ci/generate_board_targets_json.py index 75c894b49d5..ceb412e2ecc 100755 --- a/Tools/ci/generate_board_targets_json.py +++ b/Tools/ci/generate_board_targets_json.py @@ -38,7 +38,7 @@ if args.filter: default_container = 'ghcr.io/px4/px4-dev:v1.16.0-rc1-258-g0369abd556' build_configs = [] grouped_targets = {} -excluded_boards = ['modalai_voxl2', 'px4_ros2'] # TODO: fix and enable +excluded_boards = ['modalai_voxl2', 'px4_ros2', 'espressif_esp32'] # TODO: fix and enable excluded_manufacturers = ['atlflight'] excluded_platforms = ['qurt'] excluded_labels = [ diff --git a/Tools/setup/Dockerfile b/Tools/setup/Dockerfile index be587824886..1b884157cfc 100644 --- a/Tools/setup/Dockerfile +++ b/Tools/setup/Dockerfile @@ -29,6 +29,8 @@ RUN git config --global --add safe.directory '*' # Create user with id 1001 (jenkins docker workflow default) RUN useradd --shell /bin/bash -u 1001 -c "" -m user && usermod -a -G dialout user +ENV PATH="${PATH}:/opt/xtensa-esp-elf/bin" + ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] CMD ["/bin/bash"] diff --git a/Tools/setup/ubuntu.sh b/Tools/setup/ubuntu.sh index f2b09758fa9..b043b133c2b 100755 --- a/Tools/setup/ubuntu.sh +++ b/Tools/setup/ubuntu.sh @@ -155,7 +155,14 @@ if [[ $INSTALL_NUTTX == "true" ]]; then g++-multilib \ gcc-arm-none-eabi \ gcc-multilib \ + esptool \ ; + + echo + echo "Fetching Xtensa compilers" + wget -q -P $DIR https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.xz + sudo tar -xf $DIR/xtensa-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.xz -C /opt + echo 'export PATH=$PATH:/opt/xtensa-esp-elf/bin/' >> /home/$USER/.bashrc fi if [[ "${INSTALL_ARCH}" == "aarch64" ]]; then diff --git a/boards/espressif/esp32/boot/bootloader-esp32.bin b/boards/espressif/esp32/boot/bootloader-esp32.bin new file mode 100644 index 0000000000000000000000000000000000000000..7ab36750cfcfd0a78298302c8ac8df8b8678ea84 GIT binary patch literal 26288 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 literal 0 HcmV?d00001 diff --git a/boards/espressif/esp32/boot/bootloader.bin b/boards/espressif/esp32/boot/bootloader.bin new file mode 100755 index 0000000000000000000000000000000000000000..e98377ffea523674ce4e18ef8875b75fd270bf66 GIT binary patch literal 27888 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 literal 0 HcmV?d00001 diff --git a/boards/espressif/esp32/default.px4board b/boards/espressif/esp32/default.px4board new file mode 100644 index 00000000000..bb7d0cdc60c --- /dev/null +++ b/boards/espressif/esp32/default.px4board @@ -0,0 +1,39 @@ +CONFIG_BOARD_TOOLCHAIN="xtensa-esp32-elf" +CONFIG_BOARD_ARCHITECTURE="esp32" +CONFIG_BOARD_ROMFSROOT="cannode" +CONFIG_BOARD_EXTERNAL_METADATA=y +CONFIG_BOARD_ETHERNET=y +CONFIG_DRIVERS_PWM_OUT=y +CONFIG_MODULES_CONTROL_ALLOCATOR=y +CONFIG_MODULES_DATAMAN=y +# CONFIG_DATAMAN_PERSISTENT_STORAGE is not set +CONFIG_NUM_MISSION_ITMES_SUPPORTED=1 +CONFIG_MODULES_EVENTS=y +CONFIG_MODULES_GIMBAL=y +CONFIG_MODULES_LOAD_MON=y +CONFIG_MODULES_LOGGER=y +CONFIG_LOGGER_STACK_SIZE=4000 +CONFIG_MODULES_MAVLINK=y +CONFIG_MODULES_NAVIGATOR=y +# CONFIG_NAVIGATOR_ADSB is not set +CONFIG_MODULES_PAYLOAD_DELIVERER=y +CONFIG_SYSTEMCMDS_BSONDUMP=y +CONFIG_SYSTEMCMDS_DMESG=y +CONFIG_SYSTEMCMDS_DUMPFILE=y +CONFIG_SYSTEMCMDS_I2CDETECT=y +CONFIG_SYSTEMCMDS_MFT=y +CONFIG_SYSTEMCMDS_MTD=y +CONFIG_SYSTEMCMDS_NETMAN=y +CONFIG_SYSTEMCMDS_NSHTERM=y +CONFIG_SYSTEMCMDS_PARAM=y +CONFIG_SYSTEMCMDS_PERF=y +CONFIG_SYSTEMCMDS_REBOOT=y +CONFIG_SYSTEMCMDS_SD_BENCH=y +CONFIG_SYSTEMCMDS_SD_STRESS=y +CONFIG_SYSTEMCMDS_SYSTEM_TIME=y +CONFIG_SYSTEMCMDS_TOP=y +CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y +CONFIG_SYSTEMCMDS_UORB=y +CONFIG_SYSTEMCMDS_VER=y +CONFIG_SYSTEMCMDS_WORK_QUEUE=y +CONFIG_BOARD_PWM_FREQ=250 diff --git a/boards/espressif/esp32/firmware.prototype b/boards/espressif/esp32/firmware.prototype new file mode 100644 index 00000000000..3d2fe77d408 --- /dev/null +++ b/boards/espressif/esp32/firmware.prototype @@ -0,0 +1,13 @@ +{ + "board_id": 42, + "magic": "ESP32", + "description": "Firmware for the ESP32", + "image": "", + "build_time": 0, + "summary": "ESP32", + "version": "0.1", + "image_size": 0, + "image_maxsize": 1032192, + "git_identity": "", + "board_revision": 0 +} diff --git a/boards/espressif/esp32/init/rc.board_defaults b/boards/espressif/esp32/init/rc.board_defaults new file mode 100644 index 00000000000..021b5b82c19 --- /dev/null +++ b/boards/espressif/esp32/init/rc.board_defaults @@ -0,0 +1,8 @@ +#!/bin/sh +# +# board specific defaults +#------------------------------------------------------------------------------ + +dhcpd_start wlan0 +mavlink start -u 14550 -o 14550 -m 0 -r 1000 -x -p -s +mavlink start -d /dev/ttyS1 -b 115200 -f -w -Z diff --git a/boards/espressif/esp32/init/rc.board_mavlink b/boards/espressif/esp32/init/rc.board_mavlink new file mode 100644 index 00000000000..6e2bfb3340c --- /dev/null +++ b/boards/espressif/esp32/init/rc.board_mavlink @@ -0,0 +1,6 @@ +#!/bin/sh +# +# board specific MAVLink startup script. +#------------------------------------------------------------------------------ + +# Start MAVLink on the USB port diff --git a/boards/espressif/esp32/init/rc.board_sensors b/boards/espressif/esp32/init/rc.board_sensors new file mode 100644 index 00000000000..0c5ac912bb2 --- /dev/null +++ b/boards/espressif/esp32/init/rc.board_sensors @@ -0,0 +1,4 @@ +#!/bin/sh +# +# board specific sensors init +#------------------------------------------------------------------------------ diff --git a/boards/espressif/esp32/nuttx-config/include/board.h b/boards/espressif/esp32/nuttx-config/include/board.h new file mode 100644 index 00000000000..0968948da71 --- /dev/null +++ b/boards/espressif/esp32/nuttx-config/include/board.h @@ -0,0 +1,61 @@ +/************************************************************************************ + * configs/px4fmu/include/board.h + * include/arch/board/board.h + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_BOARD_BOARD_H +#define __ARCH_BOARD_BOARD_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#ifndef __ASSEMBLY__ +# include +#endif + +#include + +#define LED_STARTED 0 /* LED2 */ +#define LED_HEAPALLOCATE 1 /* LED3 */ +#define LED_IRQSENABLED 2 /* LED3 + LED2 */ +#define LED_STACKCREATED 3 /* LED3 */ +#define LED_INIRQ 4 /* LED1 + LED3 */ +#define LED_SIGNAL 5 /* LED2 + LED3 */ +#define LED_ASSERTION 6 /* LED1 + LED2 + LED3 */ +#define LED_PANIC 7 /* LED1 + N/C + N/C */ + + +#endif /* __ARCH_BOARD_BOARD_H */ diff --git a/boards/espressif/esp32/nuttx-config/include/esp32_board.h b/boards/espressif/esp32/nuttx-config/include/esp32_board.h new file mode 100644 index 00000000000..2afaef90fde --- /dev/null +++ b/boards/espressif/esp32/nuttx-config/include/esp32_board.h @@ -0,0 +1,85 @@ +/**************************************************************************** + * boards/xtensa/esp32/esp32-devkitc/include/board.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_XTENSA_ESP32_ESP32_CORE_INCLUDE_BOARD_H +#define __BOARDS_XTENSA_ESP32_ESP32_CORE_INCLUDE_BOARD_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking *****************************************************************/ + +/* The ESP32 Core board V2 is fitted with either a 26 a 40MHz crystal */ + +#ifdef CONFIG_ESP32_XTAL_26MHz +# define BOARD_XTAL_FREQUENCY 26000000 +#else +# define BOARD_XTAL_FREQUENCY 40000000 +#endif + +/* Clock reconfiguration is currently disabled, so the CPU will be running + * at the XTAL frequency or at two times the XTAL frequency, depending upon + * how we load the code: + * + * - If we load the code into FLASH at address 0x1000 where it is started by + * the second level bootloader, then the frequency is the crystal + * frequency. + * - If we load the code into IRAM after the second level bootloader has run + * this frequency will be twice the crystal frequency. + * + * Don't ask me for an explanation. + */ + +/* Note: The bootloader (esp-idf bootloader.bin) configures: + * + * - CPU frequency to 80MHz + * - The XTAL frequency according to the SDK config CONFIG_ESP32_XTAL_FREQ, + * which is 40MHz by default. + * + * Reference: + * https://github.com/espressif/esp-idf/blob + * /6fd855ab8d00d23bad4660216bc2122c2285d5be/components + * /bootloader_support/src/bootloader_clock.c#L38-L62 + */ + +#ifdef CONFIG_ESP32_RUN_IRAM +# define BOARD_CLOCK_FREQUENCY (2 * BOARD_XTAL_FREQUENCY) +#else +#ifdef CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ +# define BOARD_CLOCK_FREQUENCY (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000) +#else +# define BOARD_CLOCK_FREQUENCY 80000000 +#endif +#endif + +/* LED definitions **********************************************************/ + +/* Define how many LEDs this board has (needed by userleds) */ + +#define BOARD_NLEDS 1 + +/* GPIO pins used by the GPIO Subsystem */ + +#define BOARD_NGPIOOUT 1 /* Amount of GPIO Output pins */ +#define BOARD_NGPIOIN 1 /* Amount of GPIO Input without Interruption */ +#define BOARD_NGPIOINT 1 /* Amount of GPIO Input w/ Interruption pins */ + +#endif /* __BOARDS_XTENSA_ESP32_ESP32_CORE_INCLUDE_BOARD_H */ diff --git a/boards/espressif/esp32/nuttx-config/nsh/defconfig b/boards/espressif/esp32/nuttx-config/nsh/defconfig new file mode 100644 index 00000000000..b66cf9b9e25 --- /dev/null +++ b/boards/espressif/esp32/nuttx-config/nsh/defconfig @@ -0,0 +1,219 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ESP32_SPI3_DMA is not set +# CONFIG_ESP32_SPI_SWCS is not set +# CONFIG_ESP32_WIFI_RX_AMPDU is not set +# CONFIG_ESP32_WIFI_TX_AMPDU is not set +# CONFIG_MMCSD_HAVE_CARDDETECT is not set +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_NSH_DISABLE_DATE is not set +# CONFIG_SPI_CALLBACK is not set +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_CUSTOM=y +CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/espressif/esp32/nuttx-config" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +CONFIG_ARCH_BOARD_CUSTOM_NAME="" +CONFIG_ARCH_CHIP="esp32" +CONFIG_ARCH_CHIP_ESP32=y +CONFIG_ARCH_CHIP_ESP32WROOM32=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARDCTL_MKRD=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_TCBINFO=y +CONFIG_DEV_FIFO_SIZE=0 +CONFIG_DEV_PIPE_MAXSIZE=1024 +CONFIG_DEV_PIPE_SIZE=70 +CONFIG_DEV_URANDOM=y +CONFIG_DRIVERS_IEEE80211=y +CONFIG_DRIVERS_WIRELESS=y +CONFIG_ELF=y +CONFIG_ESP32_FLASH_FREQ_80M=y +CONFIG_ESP32_FLASH_MODE_QIO=y +CONFIG_ESP32_I2C0=y +CONFIG_ESP32_I2CTIMEOMS=10 +CONFIG_ESP32_LEDC=y +CONFIG_ESP32_LEDC_CHANNEL1_PIN=13 +CONFIG_ESP32_LEDC_CHANNEL2_PIN=16 +CONFIG_ESP32_LEDC_CHANNEL3_PIN=17 +CONFIG_ESP32_LEDC_TIM0=y +CONFIG_ESP32_LEDC_TIM0_CHANNELS=4 +CONFIG_ESP32_SPI3=y +CONFIG_ESP32_SPIFLASH=y +CONFIG_ESP32_SPIFLASH_SPIFFS=y +CONFIG_ESP32_UART0=y +CONFIG_ESP32_UART1=y +CONFIG_ESP32_UART1_RXPIN=14 +CONFIG_ESP32_UART1_TXPIN=12 +CONFIG_ESP32_WIFI=y +CONFIG_ESP32_WIFI_DYNAMIC_RXBUF_NUM=16 +CONFIG_ESP32_WIFI_DYNAMIC_TXBUF_NUM=16 +CONFIG_ESP32_WIFI_SAVE_PARAM=y +CONFIG_ESP32_WIFI_STATION_SOFTAP_COEXISTENCE=y +CONFIG_EXAMPLES_CALIB_UDELAY=y +CONFIG_EXAMPLES_DHCPD=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_LFN_ALIAS_HASH=y +CONFIG_FAT_LFN_UTF8=y +CONFIG_FSUTILS_IPCFG=y +CONFIG_FS_BINFS=y +CONFIG_FS_CROMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FATTIME=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_ROMFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IEEE80211_BROADCOM_DEFAULT_COUNTRY="27" +CONFIG_IEEE80211_BROADCOM_SCHED_PRIORITY=50 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=6000 +CONFIG_INTELHEX_BINARY=y +CONFIG_IOB_THROTTLE=0 +CONFIG_IPCFG_BINARY=y +CONFIG_IPCFG_CHARDEV=y +CONFIG_IPCFG_PATH="/fs/mtd_net" +CONFIG_LIBC_MAX_EXITFUNS=1 +CONFIG_MMCSD=y +CONFIG_MM_REGIONS=3 +CONFIG_MTD_RAMTRON=y +CONFIG_NAME_MAX=48 +CONFIG_NETDB_DNSCLIENT=y +CONFIG_NETDEVICES=y +CONFIG_NETDEV_LATEINIT=y +CONFIG_NETDEV_PHY_IOCTL=y +CONFIG_NETDEV_WIRELESS_IOCTL=y +CONFIG_NETDOWN_NOTIFIER=y +CONFIG_NETINIT_DNS=y +CONFIG_NETINIT_DNSIPADDR=0xA290AFE +CONFIG_NETINIT_DRIPADDR=0XA290AFE +CONFIG_NETINIT_IPADDR=0xC0A80001 +CONFIG_NETINIT_MONITOR=y +CONFIG_NETINIT_THREAD=y +CONFIG_NETINIT_THREAD_PRIORITY=49 +CONFIG_NETINIT_WAPI_ALG=0 +CONFIG_NETINIT_WAPI_AUTHWPA=0x00000001 +CONFIG_NETINIT_WAPI_CIPHERMODE=0x00000001 +CONFIG_NETINIT_WAPI_PASSPHRASE="px4-esp32" +CONFIG_NETINIT_WAPI_SSID="px4-esp32" +CONFIG_NETINIT_WAPI_STAMODE=3 +CONFIG_NETUTILS_DHCPC_BOOTP_FLAGS=0x0000 +CONFIG_NETUTILS_DHCPD=y +CONFIG_NETUTILS_DHCPD_DNSIP=0xc0a80001 +CONFIG_NETUTILS_DHCPD_MAXLEASES=2 +CONFIG_NETUTILS_DHCPD_ROUTERIP=0xc0a80001 +CONFIG_NETUTILS_DHCPD_STACKSIZE=3048 +CONFIG_NETUTILS_DHCPD_STARTIP=0xc0a80002 +CONFIG_NETUTILS_TELNETC=y +CONFIG_NETUTILS_TELNETD=y +CONFIG_NET_ARP_IPIN=y +CONFIG_NET_ARP_SEND=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ETH_PKTSIZE=1518 +CONFIG_NET_ICMP=y +CONFIG_NET_ICMP_SOCKET=y +CONFIG_NET_NETLINK=y +CONFIG_NET_SOLINGER=y +CONFIG_NET_TCP=y +CONFIG_NET_TCPBACKLOG=y +CONFIG_NET_TCP_DELAYED_ACK=y +CONFIG_NET_TCP_WRITE_BUFFERS=y +CONFIG_NET_UDP=y +CONFIG_NET_UDP_WRITE_BUFFERS=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_CROMFSETC=y +CONFIG_NSH_DISABLE_BASENAME=y +CONFIG_NSH_DISABLE_CMP=y +CONFIG_NSH_DISABLE_DD=y +CONFIG_NSH_DISABLE_DIRNAME=y +CONFIG_NSH_DISABLE_HEXDUMP=y +CONFIG_NSH_DISABLE_LOSETUP=y +CONFIG_NSH_DISABLE_MKFIFO=y +CONFIG_NSH_DISABLE_MKRD=y +CONFIG_NSH_DISABLE_PRINTF=y +CONFIG_NSH_DISABLE_PUT=y +CONFIG_NSH_DISABLE_TRUNCATE=y +CONFIG_NSH_DISABLE_UNAME=y +CONFIG_NSH_DISABLE_WGET=y +CONFIG_NSH_DISABLE_XD=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=128 +CONFIG_NSH_MAXARGUMENTS=15 +CONFIG_NSH_NESTDEPTH=8 +CONFIG_NSH_READLINE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ROMFSSECTSIZE=128 +CONFIG_NSH_VARS=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=50 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_PWM_MULTICHAN=y +CONFIG_PWM_NCHANNELS=4 +CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=10 +CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=10 +CONFIG_RAMTRON_SETSPEED=y +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=4 +CONFIG_READLINE_CMD_HISTORY_LINELEN=64 +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=249 +CONFIG_SCHED_HPWORKSTACKSIZE=1280 +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y +CONFIG_SCHED_INSTRUMENTATION_SWITCH=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKPRIOMAX=178 +CONFIG_SCHED_WAITPID=y +CONFIG_SEM_PREALLOCHOLDERS=32 +CONFIG_SERIAL_TERMIOS=y +CONFIG_SIG_DEFAULT=y +CONFIG_SIG_SIGALRM_ACTION=y +CONFIG_SIG_SIGCONDTIMEDOUT=19 +CONFIG_SIG_SIGUSR1_ACTION=y +CONFIG_SIG_SIGUSR2_ACTION=y +CONFIG_SIG_SIGWORK=20 +CONFIG_SPIFFS_NAME_MAX=48 +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=11 +CONFIG_STDIO_BUFFER_SIZE=32 +CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_MDIO=y +CONFIG_SYSTEM_NETDB=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_STACKSIZE=1000 +CONFIG_SYSTEM_PING=y +CONFIG_TASK_NAME_SIZE=24 +CONFIG_TLS_TASK_NELEM=4 +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USEC_PER_TICK=1000 +CONFIG_WIRELESS=y +CONFIG_WIRELESS_WAPI=y +CONFIG_WIRELESS_WAPI_CMDTOOL=y +CONFIG_WIRELESS_WAPI_STACKSIZE=4096 diff --git a/boards/espressif/esp32/nuttx-config/scripts/esp32.ld b/boards/espressif/esp32/nuttx-config/scripts/esp32.ld new file mode 100644 index 00000000000..0996b0955f9 --- /dev/null +++ b/boards/espressif/esp32/nuttx-config/scripts/esp32.ld @@ -0,0 +1,296 @@ +/**************************************************************************** + * boards/xtensa/esp32/common/scripts/esp32.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Default entry point: */ + +ENTRY(__start); + +SECTIONS +{ + /* Send .iram0 code to iram */ + + .iram0.vectors : + { + /* Vectors go to IRAM */ + + _init_start = ABSOLUTE(.); + + /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ + + . = 0x0; + KEEP (*(.window_vectors.text)); + . = 0x180; + KEEP (*(.xtensa_level2_vector.text)); + . = 0x1c0; + KEEP (*(.xtensa_level3_vector.text)); + . = 0x200; + KEEP (*(.xtensa_level4_vector.text)); + . = 0x240; + KEEP (*(.xtensa_level5_vector.text)); + . = 0x280; + KEEP (*(.debug_exception_vector.text)); + . = 0x2c0; + KEEP (*(.nmi_vector.text)); + . = 0x300; + KEEP (*(.kernel_exception_vector.text)); + . = 0x340; + KEEP (*(.user_exception_vector.text)); + . = 0x3c0; + KEEP (*(.double_exception_vector.text)); + . = 0x400; + *(.*_vector.literal) + + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + _init_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.text : + { + /* Code marked as running out of IRAM */ + + _iram_text_start = ABSOLUTE(.); + *(.iram1 .iram1.*) + *librtc.a:(.literal .text .literal.* .text.*) + *libarch.a:esp32_spiflash.*(.literal .text .literal.* .text.*) + *libarch.a:xtensa_cpupause.*(.literal .text .literal.* .text.*) + *libarch.a:xtensa_copystate.*(.literal .text .literal.* .text.*) + *libarch.a:xtensa_interruptcontext.*(.literal .text .literal.* .text.*) + *libarch.a:xtensa_testset.*(.literal .text .literal.* .text.*) + + *libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*) + *libsched.a:sched_note.*(.literal .text .literal.* .text.*) + *libsched.a:sched_thistask.*(.literal .text .literal.* .text.*) + *libsched.a:spinlock.*(.literal .text .literal.* .text.*) + *libsched.a:irq_csection.*(.literal .text .literal.* .text.*) + *libsched.a:irq_dispatch.*(.literal .text .literal.* .text.*) + + *(.wifirxiram .wifirxiram.*) + *(.wifi0iram .wifi0iram.*) + *(.wifislpiram .wifislpiram.*) + *(.wifislprxiram .wifislprxiram.*) + *(.phyiram .phyiram.*) + _iram_text_end = ABSOLUTE(.); + + /* IRAM heap starts at the end of iram0_0_seg */ + + . = ALIGN (4); + _siramheap = ABSOLUTE(.); + } > iram0_0_seg + + /* Shared RAM */ + + .dram0.bss (NOLOAD) : + { + /* .bss initialized on power-up */ + + . = ALIGN (8); + _sbss = ABSOLUTE(.); + _bss_start = ABSOLUTE(.); + *(.ext_ram.bss*) + _bt_bss_start = ABSOLUTE(.); + *libbt.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _bt_bss_end = ABSOLUTE(.); + _btdm_bss_start = ABSOLUTE(.); + *libbtdm_app.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _btdm_bss_end = ABSOLUTE(.); + . = ALIGN (8); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + KEEP (*(.bss)) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + *libarch.a:esp32_spiflash.*(.bss .bss.* COMMON) + *libarch.a:xtensa_cpupause.*(.bss .bss.* COMMON) + *libarch.a:xtensa_copystate.*(.bss .bss.* COMMON) + *libarch.a:xtensa_interruptcontext.*(.bss .bss.* COMMON) + *libarch.a:xtensa_testset.*(.bss .bss.* COMMON) + + *libsched.a:sched_suspendscheduler.*(.bss .bss.* COMMON) + *libsched.a:sched_thistask.*(.bss .bss.* COMMON) + *libsched.a:sched_note.*(.bss .bss.* COMMON) + *libsched.a:spinlock.*(.bss .bss.* COMMON) + *libsched.a:irq_csection.*(.bss .bss.* COMMON) + *libsched.a:irq_dispatch.*(.bss .bss.* COMMON) + + . = ALIGN(8); + _bss_end = ABSOLUTE(.); + _ebss = ABSOLUTE(.); + } >dram0_0_seg + + .noinit (NOLOAD): + { + /* This section contains data that is not initialized during load, + * or during the application's initialization sequence. + */ + + *(.noinit) + } >dram0_0_seg + + .dram0.data : + { + /* .data initialized on power-up in ROMed configurations. */ + + _sdata = ABSOLUTE(.); + _bt_data_start = ABSOLUTE(.); + *libbt.a:(.data .data.*) + . = ALIGN (4); + _bt_data_end = ABSOLUTE(.); + _btdm_data_start = ABSOLUTE(.); + *libbtdm_app.a:(.data .data.*) + . = ALIGN (4); + _btdm_data_end = ABSOLUTE(.); + KEEP (*(.data)) + KEEP (*(.data.*)) + KEEP (*(.gnu.linkonce.d.*)) + KEEP (*(.data1)) + KEEP (*(.sdata)) + KEEP (*(.sdata.*)) + KEEP (*(.gnu.linkonce.s.*)) + KEEP (*(.sdata2)) + KEEP (*(.sdata2.*)) + KEEP (*(.gnu.linkonce.s2.*)) + KEEP (*(.jcr)) + *(.dram1 .dram1.*) + *libphy.a:(.rodata .rodata.*) + *libarch.a:esp32_spiflash.*(.rodata .rodata.*) + *libarch.a:xtensa_cpupause.*(.rodata .rodata.*) + *libarch.a:xtensa_copystate.*(.rodata .rodata.*) + *libarch.a:xtensa_interruptcontext.*(.rodata .rodata.*) + *libarch.a:xtensa_testset.*(.rodata .rodata.*) + + *libsched.a:sched_suspendscheduler.*(.rodata .rodata.*) + *libsched.a:sched_thistask.*(.rodata .rodata.*) + *libsched.a:sched_note.*(.rodata .rodata.*) + *libsched.a:spinlock.*(.rodata .rodata.*) + *libsched.a:irq_csection.*(.rodata .rodata.*) + *libsched.a:irq_dispatch.*(.rodata .rodata.*) + + . = ALIGN(4); + _edata = ABSOLUTE(.); + + /* Heap starts at the end of .data */ + + _sheap = ABSOLUTE(.); + } >dram0_0_seg + + /* External memory bss, from any global variable with EXT_RAM_ATTR attribute */ + + .extmem.bss (NOLOAD) : + { + _sbss_extmem = ABSOLUTE(.); + *(.extmem.bss .extmem.bss.*) + . = ALIGN(4); + _ebss_extmem = ABSOLUTE(.); + } > extmem_seg + + .flash.rodata : + { + _srodata = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + *(.eh_frame) + + . = (. + 3) & ~ 3; + + /* C++ constructor and destructor tables, properly ordered: */ + + _sinit = ABSOLUTE(.); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + _einit = ABSOLUTE(.); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + + /* C++ exception handlers table: */ + + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + _erodata = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + } >default_rodata_seg + + .flash.text : + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } >default_code_seg + + .rtc.text : + { + . = ALIGN(4); + *(.rtc.literal .rtc.text) + } >rtc_iram_seg + + .rtc.data : + { + *(.rtc.data) + *(.rtc.rodata) + + /* Whatever is left from the RTC memory is used as a special heap. */ + + . = ALIGN (4); + _srtcheap = ABSOLUTE(.); + } > rtc_slow_seg +} diff --git a/boards/espressif/esp32/nuttx-config/scripts/esp32_out.ld b/boards/espressif/esp32/nuttx-config/scripts/esp32_out.ld new file mode 100644 index 00000000000..ace0fcd5945 --- /dev/null +++ b/boards/espressif/esp32/nuttx-config/scripts/esp32_out.ld @@ -0,0 +1,121 @@ +/**************************************************************************** + * boards/xtensa/esp32/common/scripts/esp32.template.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ +/**************************************************************************** + * ESP32 Linker Script Memory Layout + * + * This file describes the memory layout (memory blocks) as virtual + * memory addresses. + * + * esp32.ld contains output sections to link compiler output into these + * memory blocks. + * + * NOTE: That this is not the actual linker script but rather a "template" + * for the esp32_out.ld script. This template script is passed through + * the C preprocessor to include selected configuration options. + * + ****************************************************************************/ +/* config.h -- Autogenerated! Do not edit. */ +/* Used to represent the values of tristate options */ +/* General Definitions ***********************************/ +/* Sanity Checks *****************************************/ +/* If the end of RAM is not specified then it is assumed to be + * the beginning of RAM plus the RAM size. + */ +/* If the end of FLASH is not specified then it is assumed to be + * the beginning of FLASH plus the FLASH size. + */ +/**************************************************************************** + * boards/xtensa/esp32/common/scripts/esp32_aliases.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ +/* config.h -- Autogenerated! Do not edit. */ +/* Lower-case aliases for symbols not compliant to nxstyle */ +/* Bluetooth needs symbol alias, to be removed after IDF rename it */ +MEMORY +{ + /* Below values assume the flash cache is on, and have the blocks this + * uses subtracted from the length of the various regions. The 'data access + * port' dram/drom regions map to the same iram/irom regions but are + * connected to the data port of the CPU and e.g. allow bytewise access. + */ + /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */ + iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 + /* Flash mapped instruction data. */ + /* The 0x20 offset is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB). + */ + irom0_0_seg (RX) : org = 0x400d0020, len = 0x330000 - 0x20 + /* Shared data RAM, excluding memory reserved for ROM bss/data/stack. + * Enabling Bluetooth & Trace Memory features in menuconfig will decrease + * the amount of RAM available. + * + * Note: The length of this section should be 0x50000, and this extra + * DRAM is available in heap at runtime. However due to static ROM memory + * usage at this 176KB mark, the additional static memory temporarily cannot + * be used. + */ + dram0_0_seg (RW) : org = 0x3ffb0000 + 0, + len = 0x2c200 - 0 - 0 + /* Flash mapped constant data */ + /* The 0x20 offset is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB). + */ + drom0_0_seg (R) : org = 0x3f400020, len = 0x400000 - 0x20 + /* RTC fast memory (executable). Persists over deep sleep. */ + rtc_iram_seg (RWX) : org = 0x400c0000, len = 0x2000 + /* RTC slow memory (data accessible). Persists over deep sleep. + * Start of RTC slow memory is reserved for ULP co-processor code + data, + * if enabled. + */ + rtc_slow_seg (RW) : org = 0x50000000 + 0, + len = 0x1000 - 0 + /* External memory, including data and text */ + extmem_seg (RWX) : org = 0x3f800000, len = 0x400000 +} + REGION_ALIAS("default_rodata_seg", drom0_0_seg); + REGION_ALIAS("default_code_seg", irom0_0_seg); +/* Heap ends at top of dram0_0_seg */ +_eheap = 0x40000000 - 0; +/* IRAM heap ends at top of dram0_0_seg */ +_eiramheap = 0x400a0000; +/* Mark the end of the RTC heap (top of the RTC region) */ +_ertcheap = 0x50001fff; +EXTERN(board_get_manifest) diff --git a/boards/espressif/esp32/nuttx-config/scripts/esp32_rom.ld b/boards/espressif/esp32/nuttx-config/scripts/esp32_rom.ld new file mode 100644 index 00000000000..8430192b2fc --- /dev/null +++ b/boards/espressif/esp32/nuttx-config/scripts/esp32_rom.ld @@ -0,0 +1,2049 @@ +/* +ESP32 ROM address table +Generated for ROM with MD5sum: +ab8282ae908fe9e7a63fb2a4ac2df013 ../../rom_image/prorom.elf +*/ + +/* Unlike other ROM functions which are exported using PROVIDE, which declares + * weak symbols, these libgcc functions are exported using assignment, + * which declares strong symbols. This is done so that ROM functions are always + * used instead of the ones provided by libgcc.a. + */ + +__absvdi2 = 0x4006387c; +__absvsi2 = 0x40063868; +__adddf3 = 0x40002590; +__addsf3 = 0x400020e8; +__addvdi3 = 0x40002cbc; +__addvsi3 = 0x40002c98; +__ashldi3 = 0x4000c818; +__ashrdi3 = 0x4000c830; +__bswapdi2 = 0x40064b08; +__bswapsi2 = 0x40064ae0; +__clrsbdi2 = 0x40064b7c; +__clrsbsi2 = 0x40064b64; +__clzdi2 = 0x4000ca50; +__clzsi2 = 0x4000c7e8; +__cmpdi2 = 0x40063820; +__ctzdi2 = 0x4000ca64; +__ctzsi2 = 0x4000c7f0; +__divdc3 = 0x400645a4; +__divdf3 = 0x40002954; +__divdi3 = 0x4000ca84; +__divsi3 = 0x4000c7b8; +__eqdf2 = 0x400636a8; +__eqsf2 = 0x40063374; +__extendsfdf2 = 0x40002c34; +__fixdfdi = 0x40002ac4; +__fixdfsi = 0x40002a78; +__fixsfdi = 0x4000244c; +__fixsfsi = 0x4000240c; +__fixunsdfsi = 0x40002b30; +__fixunssfdi = 0x40002504; +__fixunssfsi = 0x400024ac; +__floatdidf = 0x4000c988; +__floatdisf = 0x4000c8c0; +__floatsidf = 0x4000c944; +__floatsisf = 0x4000c870; +__floatundidf = 0x4000c978; +__floatundisf = 0x4000c8b0; +__floatunsidf = 0x4000c938; +__floatunsisf = 0x4000c864; +__gcc_bcmp = 0x40064a70; +__gedf2 = 0x40063768; +__gesf2 = 0x4006340c; +__gtdf2 = 0x400636dc; +__gtsf2 = 0x400633a0; +__ledf2 = 0x40063704; +__lesf2 = 0x400633c0; +__lshrdi3 = 0x4000c84c; +__ltdf2 = 0x40063790; +__ltsf2 = 0x4006342c; +__moddi3 = 0x4000cd4c; +__modsi3 = 0x4000c7c0; +__muldc3 = 0x40063c90; +__muldf3 = 0x4006358c; +__muldi3 = 0x4000c9fc; +__mulsf3 = 0x400632c8; +__mulsi3 = 0x4000c7b0; +__mulvdi3 = 0x40002d78; +__mulvsi3 = 0x40002d60; +__nedf2 = 0x400636a8; +__negdf2 = 0x400634a0; +__negdi2 = 0x4000ca14; +__negsf2 = 0x400020c0; +__negvdi2 = 0x40002e98; +__negvsi2 = 0x40002e78; +__nesf2 = 0x40063374; +__nsau_data = 0x3ff96544; +__paritysi2 = 0x40002f3c; +__popcount_tab = 0x3ff96544; +__popcountdi2 = 0x40002ef8; +__popcountsi2 = 0x40002ed0; +__powidf2 = 0x400638e4; +__subdf3 = 0x400026e4; +__subsf3 = 0x400021d0; +__subvdi3 = 0x40002d20; +__subvsi3 = 0x40002cf8; +__truncdfsf2 = 0x40002b90; +__ucmpdi2 = 0x40063840; +__udiv_w_sdiv = 0x40064bec; +__udivdi3 = 0x4000cff8; +__udivmoddi4 = 0x40064bf4; +__udivsi3 = 0x4000c7c8; +__umoddi3 = 0x4000d280; +__umodsi3 = 0x4000c7d0; +__umulsidi3 = 0x4000c7d8; +__unorddf2 = 0x400637f4; +__unordsf2 = 0x40063478; + +PROVIDE ( abort = 0x4000bba4 ); +PROVIDE ( abs = 0x40056340 ); +PROVIDE ( Add2SelfBigHex256 = 0x40015b7c ); +PROVIDE ( AddBigHex256 = 0x40015b28 ); +PROVIDE ( AddBigHexModP256 = 0x40015c98 ); +PROVIDE ( AddP256 = 0x40015c74 ); +PROVIDE ( AddPdiv2_256 = 0x40015ce0 ); +PROVIDE ( aes_128_cbc_decrypt = 0x4005cc7c ); +PROVIDE ( aes_128_cbc_encrypt = 0x4005cc18 ); +PROVIDE ( aes_unwrap = 0x4005ccf0 ); +PROVIDE ( app_gpio_arg = 0x3ffe003c ); +PROVIDE ( app_gpio_handler = 0x3ffe0040 ); +PROVIDE ( __ascii_wctomb = 0x40058ef0 ); +PROVIDE ( asctime = 0x40059588 ); +PROVIDE ( asctime_r = 0x40000ec8 ); +PROVIDE ( asiprintf = 0x40056d9c ); +PROVIDE ( _asiprintf_r = 0x40056d4c ); +PROVIDE ( asniprintf = 0x40056cd8 ); +PROVIDE ( _asniprintf_r = 0x40056c64 ); +PROVIDE ( asnprintf = 0x40056cd8 ); +PROVIDE ( _asnprintf_r = 0x40056c64 ); +PROVIDE ( asprintf = 0x40056d9c ); +PROVIDE ( _asprintf_r = 0x40056d4c ); +PROVIDE ( atoi = 0x400566c4 ); +PROVIDE ( _atoi_r = 0x400566d4 ); +PROVIDE ( atol = 0x400566ec ); +PROVIDE ( _atol_r = 0x400566fc ); +PROVIDE ( base64_decode = 0x4005ced8 ); +PROVIDE ( base64_encode = 0x4005cdbc ); +PROVIDE ( BasePoint_x_256 = 0x3ff97488 ); +PROVIDE ( BasePoint_y_256 = 0x3ff97468 ); +PROVIDE ( bigHexInversion256 = 0x400168f0 ); +PROVIDE ( bigHexP256 = 0x3ff973bc ); +PROVIDE ( btdm_r_ble_bt_handler_tab_p_get = 0x40019b0c ); +PROVIDE ( btdm_r_btdm_option_data_p_get = 0x40010004 ); +PROVIDE ( btdm_r_btdm_rom_version_get = 0x40010078 ); +PROVIDE ( btdm_r_data_init = 0x4001002c ); +PROVIDE ( btdm_r_import_rf_phy_func_p_get = 0x40054298 ); +PROVIDE ( btdm_r_ip_func_p_get = 0x40019af0 ); +PROVIDE ( btdm_r_ip_func_p_set = 0x40019afc ); +PROVIDE ( btdm_r_modules_func_p_get = 0x4005427c ); +PROVIDE ( btdm_r_modules_func_p_set = 0x40054270 ); +PROVIDE ( btdm_r_plf_func_p_set = 0x40054288 ); +PROVIDE ( bt_util_buf_env = 0x3ffb8bd4 ); +PROVIDE ( bzero = 0x4000c1f4 ); +PROVIDE ( cache_flash_mmu_set = 0x400095e0 ); +PROVIDE ( cache_flush = 0x40009a14 ); +PROVIDE ( cache_read_disable = 0x40009ab8 ); +PROVIDE ( cache_read_enable = 0x40009a84 ); +PROVIDE ( cache_read_init = 0x40009950 ); +/* This is static function, but can be used, not generated by script*/ +PROVIDE ( calc_rtc_memory_crc = 0x40008170 ); +PROVIDE ( calloc = 0x4000bee4 ); +PROVIDE ( _calloc_r = 0x4000bbf8 ); +PROVIDE ( check_pos = 0x400068b8 ); +PROVIDE ( _cleanup = 0x40001df8 ); +PROVIDE ( _cleanup_r = 0x40001d48 ); +PROVIDE ( __clear_cache = 0x40063860 ); +PROVIDE ( close = 0x40001778 ); +PROVIDE ( _close_r = 0x4000bd3c ); +PROVIDE ( co_default_bdaddr = 0x3ffae704 ); +PROVIDE ( co_null_bdaddr = 0x3ffb80e0 ); +PROVIDE ( co_sca2ppm = 0x3ff971e8 ); +PROVIDE ( crc16_be = 0x4005d09c ); +PROVIDE ( crc16_le = 0x4005d05c ); +PROVIDE ( crc32_be = 0x4005d024 ); +PROVIDE ( crc32_le = 0x4005cfec ); +PROVIDE ( crc8_be = 0x4005d114 ); +PROVIDE ( crc8_le = 0x4005d0e0 ); +PROVIDE ( creat = 0x40000e8c ); +PROVIDE ( ctime = 0x400595b0 ); +PROVIDE ( ctime_r = 0x400595c4 ); +PROVIDE ( _ctype_ = 0x3ff96354 ); +PROVIDE ( __ctype_ptr__ = 0x3ff96350 ); +PROVIDE ( _data_end = 0x4000d5c8 ); +PROVIDE ( _data_end_btdm_rom = 0x4000d4f8 ); +PROVIDE ( _data_start = 0x4000d4f8 ); +PROVIDE ( _data_start_btdm_rom = 0x4000d4f4 ); +PROVIDE ( _data_start_btdm = 0x3ffae6e0); +PROVIDE ( _data_end_btdm = 0x3ffaff10); +PROVIDE ( _sbss_btdm = 0x3ffb8000); +PROVIDE ( _ebss_btdm = 0x3ffbff70); +PROVIDE ( _daylight = 0x3ffae0a4 ); +PROVIDE ( dbg_default_handler = 0x3ff97218 ); +PROVIDE ( dbg_default_state = 0x3ff97220 ); +PROVIDE ( dbg_state = 0x3ffb8d5d ); +PROVIDE ( DebugE256PublicKey_x = 0x3ff97428 ); +PROVIDE ( DebugE256PublicKey_y = 0x3ff97408 ); +PROVIDE ( DebugE256SecretKey = 0x3ff973e8 ); +PROVIDE ( debug_timer = 0x3ffe042c ); +PROVIDE ( debug_timerfn = 0x3ffe0430 ); +PROVIDE ( dh_group14_generator = 0x3ff9ac60 ); +PROVIDE ( dh_group14_prime = 0x3ff9ab60 ); +PROVIDE ( dh_group15_generator = 0x3ff9ab5f ); +PROVIDE ( dh_group15_prime = 0x3ff9a9df ); +PROVIDE ( dh_group16_generator = 0x3ff9a9de ); +PROVIDE ( dh_group16_prime = 0x3ff9a7de ); +PROVIDE ( dh_group17_generator = 0x3ff9a7dd ); +PROVIDE ( dh_group17_prime = 0x3ff9a4dd ); +PROVIDE ( dh_group18_generator = 0x3ff9a4dc ); +PROVIDE ( dh_group18_prime = 0x3ff9a0dc ); +PROVIDE ( dh_group1_generator = 0x3ff9ae03 ); +PROVIDE ( dh_group1_prime = 0x3ff9ada3 ); +PROVIDE ( dh_group2_generator = 0x3ff9ada2 ); +PROVIDE ( dh_group2_prime = 0x3ff9ad22 ); +PROVIDE ( dh_group5_generator = 0x3ff9ad21 ); +PROVIDE ( dh_group5_prime = 0x3ff9ac61 ); +PROVIDE ( div = 0x40056348 ); +PROVIDE ( _DoubleExceptionVector = 0x400003c0 ); +PROVIDE ( dummy_len_plus = 0x3ffae290 ); +PROVIDE ( __dummy_lock = 0x4000c728 ); +PROVIDE ( __dummy_lock_try = 0x4000c730 ); +PROVIDE ( ecc_env = 0x3ffb8d60 ); +PROVIDE ( ecc_Jacobian_InfinityPoint256 = 0x3ff972e8 ); +PROVIDE ( em_buf_env = 0x3ffb8d74 ); +PROVIDE ( environ = 0x3ffae0b4 ); +PROVIDE ( __env_lock = 0x40001fd4 ); +PROVIDE ( __env_unlock = 0x40001fe0 ); +PROVIDE ( esp_crc8 = 0x4005d144 ); +PROVIDE ( _etext = 0x4000d66c ); +PROVIDE ( ets_aes_crypt = 0x4005c9b8 ); +PROVIDE ( ets_aes_disable = 0x4005c8f8 ); +PROVIDE ( ets_aes_enable = 0x4005c8cc ); +PROVIDE ( ets_aes_set_endian = 0x4005c928 ); +PROVIDE ( ets_aes_setkey_dec = 0x4005c994 ); +PROVIDE ( ets_aes_setkey_enc = 0x4005c97c ); +PROVIDE ( ets_bigint_disable = 0x4005c4e0 ); +PROVIDE ( ets_bigint_enable = 0x4005c498 ); +PROVIDE ( ets_bigint_mod_mult_getz = 0x4005c818 ); +PROVIDE ( ets_bigint_mod_mult_prepare = 0x4005c7b4 ); +PROVIDE ( ets_bigint_mod_power_getz = 0x4005c614 ); +PROVIDE ( ets_bigint_mod_power_prepare = 0x4005c54c ); +PROVIDE ( ets_bigint_montgomery_mult_getz = 0x4005c7a4 ); +PROVIDE ( ets_bigint_montgomery_mult_prepare = 0x4005c6fc ); +PROVIDE ( ets_bigint_mult_getz = 0x4005c6e8 ); +PROVIDE ( ets_bigint_mult_prepare = 0x4005c630 ); +PROVIDE ( ets_bigint_wait_finish = 0x4005c520 ); +PROVIDE ( ets_delay_us = 0x40008534 ); +PROVIDE ( ets_efuse_get_8M_clock = 0x40008710 ); +PROVIDE ( ets_efuse_get_spiconfig = 0x40008658 ); +PROVIDE ( ets_efuse_program_op = 0x40008628 ); +PROVIDE ( ets_efuse_read_op = 0x40008600 ); +PROVIDE ( ets_get_cpu_frequency = 0x4000855c ); +PROVIDE ( ets_get_detected_xtal_freq = 0x40008588 ); +PROVIDE ( ets_get_xtal_scale = 0x4000856c ); +PROVIDE ( ets_update_cpu_frequency_rom = 0x40008550 ); +PROVIDE ( ets_install_putc1 = 0x40007d18 ); +PROVIDE ( ets_install_putc2 = 0x40007d38 ); +PROVIDE ( ets_install_uart_printf = 0x40007d28 ); +PROVIDE ( ets_intr_count = 0x3ffe03fc ); +PROVIDE ( ets_intr_lock = 0x400067b0 ); +PROVIDE ( ets_intr_unlock = 0x400067c4 ); +PROVIDE ( ets_isr_attach = 0x400067ec ); +PROVIDE ( ets_isr_mask = 0x400067fc ); +PROVIDE ( ets_isr_unmask = 0x40006808 ); +PROVIDE ( ets_post = 0x4000673c ); +PROVIDE ( ets_printf = 0x40007d54 ); +PROVIDE ( g_ticks_per_us_pro = 0x3ffe01e0 ); +PROVIDE ( g_ticks_per_us_app = 0x3ffe40f0 ); +PROVIDE ( ets_readySet_ = 0x3ffe01f0 ); +PROVIDE ( ets_run = 0x400066bc ); +PROVIDE ( ets_secure_boot_check = 0x4005cb40 ); +PROVIDE ( ets_secure_boot_check_finish = 0x4005cc04 ); +PROVIDE ( ets_secure_boot_check_start = 0x4005cbcc ); +PROVIDE ( ets_secure_boot_finish = 0x4005ca84 ); +PROVIDE ( ets_secure_boot_hash = 0x4005cad4 ); +PROVIDE ( ets_secure_boot_obtain = 0x4005cb14 ); +PROVIDE ( ets_secure_boot_rd_abstract = 0x4005cba8 ); +PROVIDE ( ets_secure_boot_rd_iv = 0x4005cb84 ); +PROVIDE ( ets_secure_boot_start = 0x4005ca34 ); +PROVIDE ( ets_set_appcpu_boot_addr = 0x4000689c ); +PROVIDE ( ets_set_idle_cb = 0x40006674 ); +PROVIDE ( ets_set_startup_callback = 0x4000688c ); +PROVIDE ( ets_set_user_start = 0x4000687c ); +PROVIDE ( ets_sha_disable = 0x4005c0a8 ); +PROVIDE ( ets_sha_enable = 0x4005c07c ); +PROVIDE ( ets_sha_finish = 0x4005c104 ); +PROVIDE ( ets_sha_init = 0x4005c0d4 ); +PROVIDE ( ets_sha_update = 0x4005c2a0 ); +PROVIDE ( ets_startup_callback = 0x3ffe0404 ); +PROVIDE ( ets_task = 0x40006688 ); +PROVIDE ( ets_timer_arm = 0x40008368 ); +PROVIDE ( ets_timer_arm_us = 0x400083ac ); +PROVIDE ( ets_timer_disarm = 0x400083ec ); +PROVIDE ( ets_timer_done = 0x40008428 ); +PROVIDE ( ets_timer_handler_isr = 0x40008454 ); +PROVIDE ( ets_timer_init = 0x400084e8 ); +PROVIDE ( ets_timer_setfn = 0x40008350 ); +PROVIDE ( ets_unpack_flash_code = 0x40007018 ); +PROVIDE ( ets_unpack_flash_code_legacy = 0x4000694c ); +PROVIDE ( ets_update_cpu_frequency = 0x40008550 ); +PROVIDE ( ets_waiti0 = 0x400067d8 ); +PROVIDE ( exc_cause_table = 0x3ff991d0 ); +PROVIDE ( _exit_r = 0x4000bd28 ); +PROVIDE ( fclose = 0x400020ac ); +PROVIDE ( _fclose_r = 0x40001fec ); +PROVIDE ( fflush = 0x40059394 ); +PROVIDE ( _fflush_r = 0x40059320 ); +PROVIDE ( FilePacketSendDeflatedReqMsgProc = 0x40008b24 ); +PROVIDE ( FilePacketSendReqMsgProc = 0x40008860 ); +PROVIDE ( _findenv_r = 0x40001f44 ); +PROVIDE ( fiprintf = 0x40056efc ); +PROVIDE ( _fiprintf_r = 0x40056ed8 ); +PROVIDE ( fiscanf = 0x40058884 ); +PROVIDE ( _fiscanf_r = 0x400588b4 ); +PROVIDE ( FlashDwnLdDeflatedStartMsgProc = 0x40008ad8 ); +PROVIDE ( FlashDwnLdParamCfgMsgProc = 0x4000891c ); +PROVIDE ( FlashDwnLdStartMsgProc = 0x40008820 ); +PROVIDE ( FlashDwnLdStopDeflatedReqMsgProc = 0x40008c18 ); +PROVIDE ( FlashDwnLdStopReqMsgProc = 0x400088ec ); +PROVIDE ( __fp_lock_all = 0x40001f1c ); +PROVIDE ( fprintf = 0x40056efc ); +PROVIDE ( _fprintf_r = 0x40056ed8 ); +PROVIDE ( __fp_unlock_all = 0x40001f30 ); +PROVIDE ( fputwc = 0x40058ea8 ); +PROVIDE ( __fputwc = 0x40058da0 ); +PROVIDE ( _fputwc_r = 0x40058e4c ); +PROVIDE ( free = 0x4000beb8 ); +PROVIDE ( _free_r = 0x4000bbcc ); +PROVIDE ( fscanf = 0x40058884 ); +PROVIDE ( _fscanf_r = 0x400588b4 ); +PROVIDE ( _fstat_r = 0x4000bccc ); +PROVIDE ( _fwalk = 0x4000c738 ); +PROVIDE ( _fwalk_reent = 0x4000c770 ); +PROVIDE ( _GeneralException = 0x40000e14 ); +PROVIDE ( __get_current_time_locale = 0x40001834 ); +PROVIDE ( _getenv_r = 0x40001fbc ); +PROVIDE ( _getpid_r = 0x4000bcfc ); +PROVIDE ( __getreent = 0x4000be8c ); +PROVIDE ( _gettimeofday_r = 0x4000bc58 ); +PROVIDE ( __gettzinfo = 0x40001fcc ); +PROVIDE ( GetUartDevice = 0x40009598 ); +PROVIDE ( GF_Jacobian_Point_Addition256 = 0x400163a4 ); +PROVIDE ( GF_Jacobian_Point_Double256 = 0x40016260 ); +PROVIDE ( GF_Point_Jacobian_To_Affine256 = 0x40016b0c ); +PROVIDE ( _global_impure_ptr = 0x3ffae0b0 ); +PROVIDE ( gmtime = 0x40059848 ); +PROVIDE ( gmtime_r = 0x40059868 ); +PROVIDE ( g_phyFuns_instance = 0x3ffae0c4 ); +PROVIDE ( gpio_init = 0x40009c20 ); +PROVIDE ( gpio_input_get = 0x40009b88 ); +PROVIDE ( gpio_input_get_high = 0x40009b9c ); +PROVIDE ( gpio_intr_ack = 0x40009dd4 ); +PROVIDE ( gpio_intr_ack_high = 0x40009e1c ); +PROVIDE ( gpio_intr_handler_register = 0x40009e6c ); +PROVIDE ( gpio_intr_pending = 0x40009cec ); +PROVIDE ( gpio_intr_pending_high = 0x40009cf8 ); +PROVIDE ( gpio_matrix_in = 0x40009edc ); +PROVIDE ( gpio_matrix_out = 0x40009f0c ); +PROVIDE ( gpio_output_set = 0x40009b24 ); +PROVIDE ( gpio_output_set_high = 0x40009b5c ); +PROVIDE ( gpio_pad_hold = 0x4000a734 ); +PROVIDE ( gpio_pad_pulldown = 0x4000a348 ); +PROVIDE ( gpio_pad_pullup = 0x4000a22c ); +PROVIDE ( gpio_pad_select_gpio = 0x40009fdc ); +PROVIDE ( gpio_pad_set_drv = 0x4000a11c ); +PROVIDE ( gpio_pad_unhold = 0x4000a484 ); +PROVIDE ( gpio_pending_mask = 0x3ffe0038 ); +PROVIDE ( gpio_pending_mask_high = 0x3ffe0044 ); +PROVIDE ( gpio_pin_intr_state_set = 0x40009d04 ); +PROVIDE ( gpio_pin_wakeup_disable = 0x40009eb0 ); +PROVIDE ( gpio_pin_wakeup_enable = 0x40009e7c ); +PROVIDE ( gpio_register_get = 0x40009cbc ); +PROVIDE ( gpio_register_set = 0x40009bbc ); +PROVIDE ( gTxMsg = 0x3ffe0050 ); +PROVIDE ( hci_cmd_desc_root_tab = 0x3ff976d4 ); +PROVIDE ( hci_cmd_desc_tab_ctrl_bb = 0x3ff97b70 ); +PROVIDE ( hci_cmd_desc_tab_info_par = 0x3ff97b1c ); +PROVIDE ( hci_cmd_desc_tab_le = 0x3ff97870 ); +PROVIDE ( hci_cmd_desc_tab_lk_ctrl = 0x3ff97fc0 ); +PROVIDE ( hci_cmd_desc_tab_lk_pol = 0x3ff97f3c ); +PROVIDE ( hci_cmd_desc_tab_stat_par = 0x3ff97ac8 ); +PROVIDE ( hci_cmd_desc_tab_testing = 0x3ff97a98 ); +PROVIDE ( hci_cmd_desc_tab_vs = 0x3ff97714 ); +PROVIDE ( hci_command_handler = 0x4004c928 ); +PROVIDE ( hci_env = 0x3ffb9350 ); +PROVIDE ( rwip_env = 0x3ffb8bcc ); +PROVIDE ( hci_evt_dbg_desc_tab = 0x3ff9750c ); +PROVIDE ( hci_evt_desc_tab = 0x3ff9751c ); +PROVIDE ( hci_evt_le_desc_tab = 0x3ff974b4 ); +PROVIDE ( hci_fc_env = 0x3ffb9340 ); +PROVIDE ( hmac_md5 = 0x4005d264 ); +PROVIDE ( hmac_md5_vector = 0x4005d17c ); +PROVIDE ( hmac_sha1 = 0x40060acc ); +PROVIDE ( hmac_sha1_vector = 0x400609e4 ); +PROVIDE ( hmac_sha256 = 0x40060d58 ); +PROVIDE ( hmac_sha256_vector = 0x40060c84 ); +PROVIDE ( intr_matrix_set = 0x4000681c ); +PROVIDE ( iprintf = 0x40056978 ); +PROVIDE ( _iprintf_r = 0x40056944 ); +PROVIDE ( isalnum = 0x40000f04 ); +PROVIDE ( isalpha = 0x40000f18 ); +PROVIDE ( isascii = 0x4000c20c ); +PROVIDE ( _isatty_r = 0x40000ea0 ); +PROVIDE ( isblank = 0x40000f2c ); +PROVIDE ( iscanf = 0x40058760 ); +PROVIDE ( _iscanf_r = 0x4005879c ); +PROVIDE ( iscntrl = 0x40000f50 ); +PROVIDE ( isdigit = 0x40000f64 ); +PROVIDE ( isgraph = 0x40000f94 ); +PROVIDE ( islower = 0x40000f78 ); +PROVIDE ( isprint = 0x40000fa8 ); +PROVIDE ( ispunct = 0x40000fc0 ); +PROVIDE ( isspace = 0x40000fd4 ); +PROVIDE ( isupper = 0x40000fe8 ); +PROVIDE ( itoa = 0x400566b4 ); +PROVIDE ( __itoa = 0x40056678 ); +PROVIDE ( jd_decomp = 0x400613e8 ); +PROVIDE ( jd_prepare = 0x40060fa8 ); +PROVIDE ( ke_env = 0x3ffb93cc ); +PROVIDE ( ke_handler_search = 0x4001a430 ); +PROVIDE ( ke_task_env = 0x3ffb81d4 ); +PROVIDE ( _KernelExceptionVector = 0x40000300 ); +PROVIDE ( _kill_r = 0x4000bd10 ); +PROVIDE ( labs = 0x40056370 ); +PROVIDE ( lb_default_handler = 0x3ff982b8 ); +PROVIDE ( lb_default_state_tab_p_get = 0x4001c198 ); +PROVIDE ( lb_env = 0x3ffb9424 ); +PROVIDE ( lb_hci_cmd_handler_tab_p_get = 0x4001c18c ); +PROVIDE ( lb_state = 0x3ffb94e8 ); +PROVIDE ( lc_default_handler = 0x3ff98648 ); +PROVIDE ( lc_default_state_tab_p_get = 0x4002f494 ); +PROVIDE ( lc_env = 0x3ffb94ec ); +PROVIDE ( lc_hci_cmd_handler_tab_p_get = 0x4002f488 ); +PROVIDE ( lc_state = 0x3ffb9508 ); +PROVIDE ( ld_acl_br_sizes = 0x3ff98a2a ); +PROVIDE ( ld_acl_br_types = 0x3ff98a36 ); +PROVIDE ( ld_acl_edr_sizes = 0x3ff98a14 ); +PROVIDE ( ld_acl_edr_types = 0x3ff98a22 ); +PROVIDE ( ld_env = 0x3ffb9510 ); +PROVIDE ( ldiv = 0x40056378 ); +PROVIDE ( ld_pcm_settings_dft = 0x3ff98a0c ); +PROVIDE ( ld_sched_params = 0x3ffb96c0 ); +PROVIDE ( ld_sync_train_channels = 0x3ff98a3c ); +PROVIDE ( _xtensa_level2_from = 0x40000954 ); +PROVIDE ( _xtensa_level2_vector = 0x40000180 ); +PROVIDE ( _xtensa_level3_from = 0x40000a28 ); +PROVIDE ( _xtensa_level3_vector = 0x400001c0 ); +PROVIDE ( _xtensa_level4_from = 0x40000af8 ); +PROVIDE ( _xtensa_level4_vector = 0x40000200 ); +PROVIDE ( _xtensa_level5_from = 0x40000c68 ); +PROVIDE ( _xtensa_level5_vector = 0x40000240 ); +PROVIDE ( _LevelOneInterrupt = 0x40000835 ); +PROVIDE ( _link_r = 0x4000bc9c ); +PROVIDE ( llc_default_handler = 0x3ff98b3c ); +PROVIDE ( llc_default_state_tab_p_get = 0x40046058 ); +PROVIDE ( llc_env = 0x3ffb96d0 ); +PROVIDE ( llc_hci_acl_data_tx_handler = 0x40042398 ); +PROVIDE ( llc_hci_cmd_handler_tab_p_get = 0x40042358 ); +PROVIDE ( llc_hci_command_handler = 0x40042360 ); +PROVIDE ( llcp_pdu_handler_tab_p_get = 0x40043f64 ); +PROVIDE ( llc_state = 0x3ffb96f8 ); +PROVIDE ( lldesc_build_chain = 0x4000a850 ); +PROVIDE ( lldesc_num2link = 0x4000a948 ); +PROVIDE ( lldesc_set_owner = 0x4000a974 ); +PROVIDE ( lld_evt_deferred_elt_push = 0x400466b4 ); +PROVIDE ( lld_evt_deferred_elt_pop = 0x400466dc ); +PROVIDE ( lld_evt_winsize_change = 0x40046730 ); +PROVIDE ( lld_evt_rxwin_compute = 0x400467c8 ); +PROVIDE ( lld_evt_slave_time_compute = 0x40046818 ); +PROVIDE ( lld_evt_env = 0x3ffb9704 ); +PROVIDE ( lld_evt_elt_wait_get = 0x400468e4 ); +PROVIDE ( lld_evt_get_next_free_slot = 0x4004692c ); +PROVIDE ( lld_pdu_adv_pk_desc_tab = 0x3ff98c70 ); +PROVIDE ( lld_pdu_llcp_pk_desc_tab = 0x3ff98b68 ); +PROVIDE ( lld_pdu_tx_flush_list = 0x4004a760 ); +PROVIDE ( lld_pdu_pack = 0x4004ab14 ); +PROVIDE ( LLM_AA_CT1 = 0x3ff98d8a ); +PROVIDE ( LLM_AA_CT2 = 0x3ff98d88 ); +PROVIDE ( llm_default_handler = 0x3ff98d80 ); +PROVIDE ( llm_default_state_tab_p_get = 0x4004e718 ); +PROVIDE ( llm_hci_cmd_handler_tab_p_get = 0x4004c920 ); +PROVIDE ( llm_le_env = 0x3ffb976c ); +PROVIDE ( llm_local_cmds = 0x3ff98d38 ); +PROVIDE ( llm_local_data_len_values = 0x3ff98d1c ); +PROVIDE ( llm_local_le_feats = 0x3ff98d30 ); +PROVIDE ( llm_local_le_states = 0x3ff98d28 ); +PROVIDE ( llm_state = 0x3ffb985c ); +PROVIDE ( lm_default_handler = 0x3ff990e0 ); +PROVIDE ( lm_default_state_tab_p_get = 0x40054268 ); +PROVIDE ( lm_env = 0x3ffb9860 ); +PROVIDE ( lm_hci_cmd_handler_tab_p_get = 0x4005425c ); +PROVIDE ( lm_local_supp_feats = 0x3ff990ee ); +PROVIDE ( lm_n_page_tab = 0x3ff990e8 ); +PROVIDE ( lmp_desc_tab = 0x3ff96e6c ); +PROVIDE ( lmp_ext_desc_tab = 0x3ff96d9c ); +PROVIDE ( lm_state = 0x3ffb9a1c ); +PROVIDE ( __locale_charset = 0x40059540 ); +PROVIDE ( __locale_cjk_lang = 0x40059558 ); +PROVIDE ( localeconv = 0x4005957c ); +PROVIDE ( _localeconv_r = 0x40059560 ); +PROVIDE ( __locale_mb_cur_max = 0x40059548 ); +PROVIDE ( __locale_msgcharset = 0x40059550 ); +PROVIDE ( localtime = 0x400595dc ); +PROVIDE ( localtime_r = 0x400595fc ); +PROVIDE ( _lock_acquire = 0x4000be14 ); +PROVIDE ( _lock_acquire_recursive = 0x4000be28 ); +PROVIDE ( _lock_close = 0x4000bdec ); +PROVIDE ( _lock_close_recursive = 0x4000be00 ); +PROVIDE ( _lock_init = 0x4000bdc4 ); +PROVIDE ( _lock_init_recursive = 0x4000bdd8 ); +PROVIDE ( _lock_release = 0x4000be64 ); +PROVIDE ( _lock_release_recursive = 0x4000be78 ); +PROVIDE ( _lock_try_acquire = 0x4000be3c ); +PROVIDE ( _lock_try_acquire_recursive = 0x4000be50 ); +PROVIDE ( longjmp = 0x400562cc ); +PROVIDE ( _lseek_r = 0x4000bd8c ); +PROVIDE ( malloc = 0x4000bea0 ); +PROVIDE ( _malloc_r = 0x4000bbb4 ); +PROVIDE ( maxSecretKey_256 = 0x3ff97448 ); +PROVIDE ( __mb_cur_max = 0x3ff96530 ); +PROVIDE ( MD5Final = 0x4005db1c ); +PROVIDE ( MD5Init = 0x4005da7c ); +PROVIDE ( MD5Update = 0x4005da9c ); +PROVIDE ( md5_vector = 0x4005db80 ); +PROVIDE ( memccpy = 0x4000c220 ); +PROVIDE ( memchr = 0x4000c244 ); +PROVIDE ( memcmp = 0x4000c260 ); +PROVIDE ( memcpy = 0x4000c2c8 ); +PROVIDE ( MemDwnLdStartMsgProc = 0x40008948 ); +PROVIDE ( MemDwnLdStopReqMsgProc = 0x400089dc ); +PROVIDE ( memmove = 0x4000c3c0 ); +PROVIDE ( MemPacketSendReqMsgProc = 0x40008978 ); +PROVIDE ( memrchr = 0x4000c400 ); +PROVIDE ( memset = 0x4000c44c ); +PROVIDE ( mktime = 0x4005a5e8 ); +PROVIDE ( mmu_init = 0x400095a4 ); +PROVIDE ( __month_lengths = 0x3ff9609c ); +PROVIDE ( MultiplyBigHexByUint32_256 = 0x40016214 ); +PROVIDE ( MultiplyBigHexModP256 = 0x400160b8 ); +PROVIDE ( MultiplyByU32ModP256 = 0x40015fdc ); +PROVIDE ( multofup = 0x4000ab8c ); +PROVIDE ( mz_adler32 = 0x4005edbc ); +PROVIDE ( mz_crc32 = 0x4005ee88 ); +PROVIDE ( mz_free = 0x4005eed4 ); +PROVIDE ( _NMIExceptionVector = 0x400002c0 ); +PROVIDE ( notEqual256 = 0x40015b04 ); +PROVIDE ( one_bits = 0x3ff971f8 ); +PROVIDE ( open = 0x4000178c ); +PROVIDE ( _open_r = 0x4000bd54 ); +PROVIDE ( pbkdf2_sha1 = 0x40060ba4 ); +PROVIDE ( phy_get_romfuncs = 0x40004100 ); +PROVIDE ( __powisf2 = 0x4006389c ); +PROVIDE ( _Pri_4_HandlerAddress = 0x3ffe0648 ); +PROVIDE ( _Pri_5_HandlerAddress = 0x3ffe064c ); +PROVIDE ( printf = 0x40056978 ); +PROVIDE ( _printf_common = 0x40057338 ); +PROVIDE ( _printf_float = 0x4000befc ); +PROVIDE ( _printf_i = 0x40057404 ); +PROVIDE ( _printf_r = 0x40056944 ); +PROVIDE ( qsort = 0x40056424 ); +PROVIDE ( _raise_r = 0x4000bc70 ); +PROVIDE ( rand = 0x40001058 ); +PROVIDE ( rand_r = 0x400010d4 ); +PROVIDE ( r_btdm_option_data = 0x3ffae6e0 ); +PROVIDE ( r_bt_util_buf_acl_rx_alloc = 0x40010218 ); +PROVIDE ( r_bt_util_buf_acl_rx_free = 0x40010234 ); +PROVIDE ( r_bt_util_buf_acl_tx_alloc = 0x40010268 ); +PROVIDE ( r_bt_util_buf_acl_tx_free = 0x40010280 ); +PROVIDE ( r_bt_util_buf_init = 0x400100e4 ); +PROVIDE ( r_bt_util_buf_lmp_tx_alloc = 0x400101d0 ); +PROVIDE ( r_bt_util_buf_lmp_tx_free = 0x400101ec ); +PROVIDE ( r_bt_util_buf_sync_clear = 0x400103c8 ); +PROVIDE ( r_bt_util_buf_sync_init = 0x400102c4 ); +PROVIDE ( r_bt_util_buf_sync_rx_alloc = 0x40010468 ); +PROVIDE ( r_bt_util_buf_sync_rx_free = 0x4001049c ); +PROVIDE ( r_bt_util_buf_sync_tx_alloc = 0x400103ec ); +PROVIDE ( r_bt_util_buf_sync_tx_free = 0x40010428 ); +PROVIDE ( rc4_skip = 0x40060928 ); +PROVIDE ( r_co_bdaddr_compare = 0x40014324 ); +PROVIDE ( r_co_bytes_to_string = 0x400142e4 ); +PROVIDE ( r_co_list_check_size_available = 0x400142c4 ); +PROVIDE ( r_co_list_extract = 0x4001404c ); +PROVIDE ( r_co_list_extract_after = 0x40014118 ); +PROVIDE ( r_co_list_find = 0x4001419c ); +PROVIDE ( r_co_list_init = 0x40013f14 ); +PROVIDE ( r_co_list_insert_after = 0x40014254 ); +PROVIDE ( r_co_list_insert_before = 0x40014200 ); +PROVIDE ( r_co_list_merge = 0x400141bc ); +PROVIDE ( r_co_list_pool_init = 0x40013f30 ); +PROVIDE ( r_co_list_pop_front = 0x40014028 ); +PROVIDE ( r_co_list_push_back = 0x40013fb8 ); +PROVIDE ( r_co_list_push_front = 0x40013ff4 ); +PROVIDE ( r_co_list_size = 0x400142ac ); +PROVIDE ( r_co_nb_good_channels = 0x40014360 ); +PROVIDE ( r_co_slot_to_duration = 0x40014348 ); +PROVIDE ( RcvMsg = 0x4000954c ); +PROVIDE ( r_dbg_init = 0x40014394 ); +PROVIDE ( r_dbg_platform_reset_complete = 0x400143d0 ); +PROVIDE ( r_dbg_swdiag_init = 0x40014470 ); +PROVIDE ( r_dbg_swdiag_read = 0x400144a4 ); +PROVIDE ( r_dbg_swdiag_write = 0x400144d0 ); +PROVIDE ( r_E1 = 0x400108e8 ); +PROVIDE ( r_E21 = 0x40010968 ); +PROVIDE ( r_E22 = 0x400109b4 ); +PROVIDE ( r_E3 = 0x40010a58 ); +PROVIDE ( lm_n192_mod_mul = 0x40011dc0 ); +PROVIDE ( lm_n192_mod_add = 0x40011e9c ); +PROVIDE ( lm_n192_mod_sub = 0x40011eec ); +PROVIDE ( r_ea_alarm_clear = 0x40015ab4 ); +PROVIDE ( r_ea_alarm_set = 0x40015a10 ); +PROVIDE ( read = 0x400017dc ); +PROVIDE ( _read_r = 0x4000bda8 ); +PROVIDE ( r_ea_elt_cancel = 0x400150d0 ); +PROVIDE ( r_ea_elt_create = 0x40015264 ); +PROVIDE ( r_ea_elt_insert = 0x400152a8 ); +PROVIDE ( r_ea_elt_remove = 0x400154f0 ); +PROVIDE ( r_ea_finetimer_isr = 0x400155d4 ); +PROVIDE ( r_ea_init = 0x40015228 ); +PROVIDE ( r_ea_interval_create = 0x4001555c ); +PROVIDE ( r_ea_interval_delete = 0x400155a8 ); +PROVIDE ( r_ea_interval_duration_req = 0x4001597c ); +PROVIDE ( r_ea_interval_insert = 0x4001557c ); +PROVIDE ( r_ea_interval_remove = 0x40015590 ); +PROVIDE ( realloc = 0x4000becc ); +PROVIDE ( _realloc_r = 0x4000bbe0 ); +PROVIDE ( ea_conflict_check = 0x40014e9c ); +PROVIDE ( ea_prog_timer = 0x40014f88 ); +PROVIDE ( r_ea_offset_req = 0x40015748 ); +PROVIDE ( r_ea_sleep_check = 0x40015928 ); +PROVIDE ( r_ea_sw_isr = 0x40015724 ); +PROVIDE ( r_ea_time_get_halfslot_rounded = 0x40015894 ); +PROVIDE ( r_ea_time_get_slot_rounded = 0x400158d4 ); +PROVIDE ( r_ecc_abort_key256_generation = 0x40017070 ); +PROVIDE ( r_ecc_generate_key256 = 0x40016e00 ); +PROVIDE ( r_ecc_gen_new_public_key = 0x400170c0 ); +PROVIDE ( r_ecc_gen_new_secret_key = 0x400170e4 ); +PROVIDE ( r_ecc_get_debug_Keys = 0x40017224 ); +PROVIDE ( r_ecc_init = 0x40016dbc ); +PROVIDE ( ecc_point_multiplication_uint8_256 = 0x40016804 ); +PROVIDE ( RecvBuff = 0x3ffe009c ); +PROVIDE ( recv_packet = 0x40009424 ); +PROVIDE ( r_em_buf_init = 0x4001729c ); +PROVIDE ( r_em_buf_rx_buff_addr_get = 0x400173e8 ); +PROVIDE ( r_em_buf_rx_free = 0x400173c4 ); +PROVIDE ( r_em_buf_tx_buff_addr_get = 0x40017404 ); +PROVIDE ( r_em_buf_tx_free = 0x4001741c ); +PROVIDE ( _rename_r = 0x4000bc28 ); +PROVIDE ( _ResetHandler = 0x40000450 ); +PROVIDE ( _ResetVector = 0x40000400 ); +PROVIDE ( r_F1_256 = 0x400133e4 ); +PROVIDE ( r_F2_256 = 0x40013568 ); +PROVIDE ( r_F3_256 = 0x40013664 ); +PROVIDE ( RFPLL_ICP_TABLE = 0x3ffb8b7c ); +PROVIDE ( r_G_256 = 0x40013470 ); +PROVIDE ( r_H3 = 0x40013760 ); +PROVIDE ( r_H4 = 0x40013830 ); +PROVIDE ( r_h4tl_init = 0x40017878 ); +PROVIDE ( r_h4tl_start = 0x40017924 ); +PROVIDE ( r_h4tl_stop = 0x40017934 ); +PROVIDE ( r_h4tl_write = 0x400178d0 ); +PROVIDE ( r_H5 = 0x400138dc ); +PROVIDE ( r_hashConcat = 0x40013a38 ); +PROVIDE ( r_hci_acl_tx_data_alloc = 0x4001951c ); +PROVIDE ( r_hci_acl_tx_data_received = 0x40019654 ); +PROVIDE ( r_hci_bt_acl_bdaddr_register = 0x40018900 ); +PROVIDE ( r_hci_bt_acl_bdaddr_unregister = 0x400189ac ); +PROVIDE ( r_hci_bt_acl_conhdl_register = 0x4001895c ); +PROVIDE ( r_hci_cmd_get_max_param_size = 0x400192d0 ); +PROVIDE ( r_hci_cmd_received = 0x400192f8 ); +PROVIDE ( r_hci_evt_filter_add = 0x40018a64 ); +PROVIDE ( r_hci_evt_mask_set = 0x400189e4 ); +PROVIDE ( r_hci_fc_acl_buf_size_set = 0x40017988 ); +PROVIDE ( r_hci_fc_acl_en = 0x400179d8 ); +PROVIDE ( r_hci_fc_acl_packet_sent = 0x40017a3c ); +PROVIDE ( r_hci_fc_check_host_available_nb_acl_packets = 0x40017aa4 ); +PROVIDE ( r_hci_fc_check_host_available_nb_sync_packets = 0x40017ac8 ); +PROVIDE ( r_hci_fc_host_nb_acl_pkts_complete = 0x40017a6c ); +PROVIDE ( r_hci_fc_host_nb_sync_pkts_complete = 0x40017a88 ); +PROVIDE ( r_hci_fc_init = 0x40017974 ); +PROVIDE ( r_hci_fc_sync_buf_size_set = 0x400179b0 ); +PROVIDE ( r_hci_fc_sync_en = 0x40017a30 ); +PROVIDE ( r_hci_fc_sync_packet_sent = 0x40017a54 ); +PROVIDE ( r_hci_init = 0x40018538 ); +PROVIDE ( r_hci_look_for_cmd_desc = 0x40018454 ); +PROVIDE ( r_hci_look_for_dbg_evt_desc = 0x400184c4 ); +PROVIDE ( r_hci_look_for_evt_desc = 0x400184a0 ); +PROVIDE ( r_hci_look_for_le_evt_desc = 0x400184e0 ); +PROVIDE ( r_hci_reset = 0x4001856c ); +PROVIDE ( r_hci_send_2_host = 0x400185bc ); +PROVIDE ( r_hci_sync_tx_data_alloc = 0x40019754 ); +PROVIDE ( r_hci_sync_tx_data_received = 0x400197c0 ); +PROVIDE ( r_hci_tl_init = 0x40019290 ); +PROVIDE ( r_hci_tl_send = 0x40019228 ); +PROVIDE ( r_hci_util_pack = 0x40019874 ); +PROVIDE ( r_hci_util_unpack = 0x40019998 ); +PROVIDE ( r_hci_voice_settings_get = 0x40018bdc ); +PROVIDE ( r_hci_voice_settings_set = 0x40018be8 ); +PROVIDE ( r_HMAC = 0x40013968 ); +PROVIDE ( r_import_rf_phy_func = 0x3ffb8354 ); +PROVIDE ( r_import_rf_phy_func_p = 0x3ffafd64 ); +PROVIDE ( r_ip_funcs = 0x3ffae710 ); +PROVIDE ( r_ip_funcs_p = 0x3ffae70c ); +PROVIDE ( r_ke_check_malloc = 0x40019de0 ); +PROVIDE ( r_ke_event_callback_set = 0x40019ba8 ); +PROVIDE ( r_ke_event_clear = 0x40019c2c ); +PROVIDE ( r_ke_event_flush = 0x40019ccc ); +PROVIDE ( r_ke_event_get = 0x40019c78 ); +PROVIDE ( r_ke_event_get_all = 0x40019cc0 ); +PROVIDE ( r_ke_event_init = 0x40019b90 ); +PROVIDE ( r_ke_event_schedule = 0x40019cdc ); +PROVIDE ( r_ke_event_set = 0x40019be0 ); +PROVIDE ( r_ke_flush = 0x4001a374 ); +PROVIDE ( r_ke_free = 0x4001a014 ); +PROVIDE ( r_ke_get_max_mem_usage = 0x4001a1c8 ); +PROVIDE ( r_ke_get_mem_usage = 0x4001a1a0 ); +PROVIDE ( r_ke_init = 0x4001a318 ); +PROVIDE ( r_ke_is_free = 0x4001a184 ); +PROVIDE ( r_ke_malloc = 0x40019eb4 ); +PROVIDE ( r_ke_mem_init = 0x40019d3c ); +PROVIDE ( r_ke_mem_is_empty = 0x40019d8c ); +PROVIDE ( r_ke_msg_alloc = 0x4001a1e0 ); +PROVIDE ( r_ke_msg_dest_id_get = 0x4001a2e0 ); +PROVIDE ( r_ke_msg_discard = 0x4001a850 ); +PROVIDE ( r_ke_msg_forward = 0x4001a290 ); +PROVIDE ( r_ke_msg_forward_new_id = 0x4001a2ac ); +PROVIDE ( r_ke_msg_free = 0x4001a2cc ); +PROVIDE ( r_ke_msg_in_queue = 0x4001a2f8 ); +PROVIDE ( r_ke_msg_save = 0x4001a858 ); +PROVIDE ( r_ke_msg_send = 0x4001a234 ); +PROVIDE ( r_ke_msg_send_basic = 0x4001a26c ); +PROVIDE ( r_ke_msg_src_id_get = 0x4001a2ec ); +PROVIDE ( r_ke_queue_extract = 0x40055fd0 ); +PROVIDE ( r_ke_queue_insert = 0x40056020 ); +PROVIDE ( r_ke_sleep_check = 0x4001a3d8 ); +PROVIDE ( r_ke_state_get = 0x4001a7d8 ); +PROVIDE ( r_ke_state_set = 0x4001a6fc ); +PROVIDE ( r_ke_stats_get = 0x4001a3f0 ); +PROVIDE ( r_ke_task_check = 0x4001a8a4 ); +PROVIDE ( r_ke_task_create = 0x4001a674 ); +PROVIDE ( r_ke_task_delete = 0x4001a6c0 ); +PROVIDE ( r_ke_task_init = 0x4001a650 ); +PROVIDE ( r_ke_task_msg_flush = 0x4001a860 ); +PROVIDE ( r_ke_timer_active = 0x4001ac08 ); +PROVIDE ( r_ke_timer_adjust_all = 0x4001ac30 ); +PROVIDE ( r_ke_timer_clear = 0x4001ab90 ); +PROVIDE ( r_ke_timer_init = 0x4001aa9c ); +PROVIDE ( r_ke_timer_set = 0x4001aac0 ); +PROVIDE ( r_ke_timer_sleep_check = 0x4001ac50 ); +PROVIDE ( r_KPrimC = 0x40010ad4 ); +PROVIDE ( r_lb_clk_adj_activate = 0x4001ae70 ); +PROVIDE ( r_lb_clk_adj_id_get = 0x4001af14 ); +PROVIDE ( r_lb_clk_adj_period_update = 0x4001af20 ); +PROVIDE ( r_lb_init = 0x4001acd4 ); +PROVIDE ( r_lb_mst_key = 0x4001afc0 ); +PROVIDE ( r_lb_mst_key_cmp = 0x4001af74 ); +PROVIDE ( r_lb_mst_key_restart_enc = 0x4001b0d4 ); +PROVIDE ( r_lb_mst_start_act_bcst_enc = 0x4001b198 ); +PROVIDE ( r_lb_mst_stop_act_bcst_enc = 0x4001b24c ); +PROVIDE ( r_lb_reset = 0x4001ad38 ); +PROVIDE ( r_lb_send_lmp = 0x4001adbc ); +PROVIDE ( r_lb_send_pdu_clk_adj = 0x4001af3c ); +PROVIDE ( r_lb_util_get_csb_mode = 0x4001ada4 ); +PROVIDE ( r_lb_util_get_nb_broadcast = 0x4001ad80 ); +PROVIDE ( r_lb_util_get_res_lt_addr = 0x4001ad98 ); +PROVIDE ( r_lb_util_set_nb_broadcast = 0x4001ad8c ); +PROVIDE ( r_lc_afh_set = 0x4001cc74 ); +PROVIDE ( r_lc_afh_start = 0x4001d240 ); +PROVIDE ( r_lc_auth_cmp = 0x4001cd54 ); +PROVIDE ( r_lc_calc_link_key = 0x4001ce7c ); +PROVIDE ( r_lc_chg_pkt_type_cmp = 0x4001d038 ); +PROVIDE ( r_lc_chg_pkt_type_cont = 0x4001cfbc ); +PROVIDE ( r_lc_chg_pkt_type_retry = 0x4001d0ac ); +PROVIDE ( r_lc_chk_to = 0x4001d2a8 ); +PROVIDE ( r_lc_cmd_stat_send = 0x4001c914 ); +PROVIDE ( r_lc_comb_key_svr = 0x4001d30c ); +PROVIDE ( r_lc_con_cmp = 0x4001d44c ); +PROVIDE ( r_lc_con_cmp_evt_send = 0x4001d4fc ); +PROVIDE ( r_lc_conn_seq_done = 0x40021334 ); +PROVIDE ( r_lc_detach = 0x4002037c ); +PROVIDE ( r_lc_dhkey = 0x4001d564 ); +PROVIDE ( r_lc_enc_cmp = 0x4001d8bc ); +PROVIDE ( r_lc_enc_key_refresh = 0x4001d720 ); +PROVIDE ( r_lc_end_chk_colli = 0x4001d858 ); +PROVIDE ( r_lc_end_of_sniff_nego = 0x4001d9a4 ); +PROVIDE ( r_lc_enter_sniff_mode = 0x4001ddb8 ); +PROVIDE ( r_lc_epr_change_lk = 0x4001db38 ); +PROVIDE ( r_lc_epr_cmp = 0x4001da88 ); +PROVIDE ( r_lc_epr_resp = 0x4001e0b4 ); +PROVIDE ( r_lc_epr_rsw_cmp = 0x4001dd40 ); +PROVIDE ( r_lc_ext_feat = 0x40020d6c ); +PROVIDE ( r_lc_feat = 0x40020984 ); +PROVIDE ( r_lc_hl_connect = 0x400209e8 ); +PROVIDE ( r_lc_init = 0x4001c948 ); +PROVIDE ( r_lc_init_calc_f3 = 0x4001deb0 ); +PROVIDE ( r_lc_initiator_epr = 0x4001e064 ); +PROVIDE ( r_lc_init_passkey_loop = 0x4001dfc0 ); +PROVIDE ( r_lc_init_start_mutual_auth = 0x4001df60 ); +PROVIDE ( r_lc_key_exch_end = 0x4001e140 ); +PROVIDE ( r_lc_legacy_pair = 0x4001e1c0 ); +PROVIDE ( r_lc_local_switch = 0x4001e22c ); +PROVIDE ( r_lc_local_trans_mode = 0x4001e2e4 ); +PROVIDE ( r_lc_local_untrans_mode = 0x4001e3a0 ); +PROVIDE ( r_lc_loc_auth = 0x40020ecc ); +PROVIDE ( r_lc_locepr_lkref = 0x4001d648 ); +PROVIDE ( r_lc_locepr_rsw = 0x4001d5d0 ); +PROVIDE ( r_lc_loc_sniff = 0x40020a6c ); +PROVIDE ( r_lc_max_slot_mgt = 0x4001e410 ); +PROVIDE ( r_lc_mst_key = 0x4001e7c0 ); +PROVIDE ( r_lc_mst_qos_done = 0x4001ea80 ); +PROVIDE ( r_lc_mst_send_mst_key = 0x4001e8f4 ); +PROVIDE ( r_lc_mutual_auth_end = 0x4001e670 ); +PROVIDE ( r_lc_mutual_auth_end2 = 0x4001e4f4 ); +PROVIDE ( r_lc_packet_type = 0x40021038 ); +PROVIDE ( r_lc_pair = 0x40020ddc ); +PROVIDE ( r_lc_pairing_cont = 0x4001eafc ); +PROVIDE ( r_lc_passkey_comm = 0x4001ed20 ); +PROVIDE ( r_lc_prepare_all_links_for_clk_adj = 0x40021430 ); +PROVIDE ( r_lc_proc_rcv_dhkey = 0x4001edec ); +PROVIDE ( r_lc_ptt = 0x4001ee2c ); +PROVIDE ( r_lc_ptt_cmp = 0x4001eeec ); +PROVIDE ( r_lc_qos_setup = 0x4001ef50 ); +PROVIDE ( r_lc_rd_rem_name = 0x4001efd0 ); +PROVIDE ( r_lc_release = 0x4001f8a8 ); +PROVIDE ( r_lc_rem_enc = 0x4001f124 ); +PROVIDE ( r_lc_rem_name_cont = 0x4001f290 ); +PROVIDE ( r_lc_rem_nego_trans_mode = 0x4001f1b4 ); +PROVIDE ( r_lc_rem_sniff = 0x40020ca4 ); +PROVIDE ( r_lc_rem_sniff_sub_rate = 0x40020b10 ); +PROVIDE ( r_lc_rem_switch = 0x4001f070 ); +PROVIDE ( r_lc_rem_trans_mode = 0x4001f314 ); +PROVIDE ( r_lc_rem_unsniff = 0x400207a0 ); +PROVIDE ( r_lc_rem_untrans_mode = 0x4001f36c ); +PROVIDE ( r_lc_reset = 0x4001c99c ); +PROVIDE ( r_lc_resp_auth = 0x4001f518 ); +PROVIDE ( r_lc_resp_calc_f3 = 0x4001f710 ); +PROVIDE ( r_lc_resp_num_comp = 0x40020074 ); +PROVIDE ( r_lc_resp_oob_nonce = 0x4001f694 ); +PROVIDE ( r_lc_resp_oob_wait_nonce = 0x4001f66c ); +PROVIDE ( r_lc_resp_pair = 0x400208a4 ); +PROVIDE ( r_lc_resp_sec_auth = 0x4001f4a0 ); +PROVIDE ( r_lc_resp_wait_dhkey_cont = 0x4001f86c ); +PROVIDE ( r_lc_restart_enc = 0x4001f8ec ); +PROVIDE ( r_lc_restart_enc_cont = 0x4001f940 ); +PROVIDE ( r_lc_restore_afh_reporting = 0x4001f028 ); +PROVIDE ( r_lc_restore_to = 0x4001f9e0 ); +PROVIDE ( r_lc_ret_sniff_max_slot_chg = 0x4001fa30 ); +PROVIDE ( r_lc_rsw_clean_up = 0x4001dc70 ); +PROVIDE ( r_lc_rsw_done = 0x4001db94 ); +PROVIDE ( r_lc_sco_baseband_ack = 0x40022b00 ); +PROVIDE ( r_lc_sco_detach = 0x40021e40 ); +PROVIDE ( r_lc_sco_host_accept = 0x40022118 ); +PROVIDE ( r_lc_sco_host_reject = 0x400222b8 ); +PROVIDE ( r_lc_sco_host_request = 0x40021f4c ); +PROVIDE ( r_lc_sco_host_request_disc = 0x4002235c ); +PROVIDE ( r_lc_sco_init = 0x40021dc8 ); +PROVIDE ( r_lc_sco_peer_accept = 0x40022780 ); +PROVIDE ( r_lc_sco_peer_accept_disc = 0x40022a08 ); +PROVIDE ( r_lc_sco_peer_reject = 0x40022824 ); +PROVIDE ( r_lc_sco_peer_reject_disc = 0x40022a8c ); +PROVIDE ( r_lc_sco_peer_request = 0x4002240c ); +PROVIDE ( r_lc_sco_peer_request_disc = 0x400228ec ); +PROVIDE ( r_lc_sco_release = 0x40021eec ); +PROVIDE ( r_lc_sco_reset = 0x40021dfc ); +PROVIDE ( r_lc_sco_timeout = 0x40022bd4 ); +PROVIDE ( r_lc_sec_auth_compute_sres = 0x4001f3ec ); +PROVIDE ( r_lc_semi_key_cmp = 0x40020294 ); +PROVIDE ( r_lc_send_enc_chg_evt = 0x4002134c ); +PROVIDE ( r_lc_send_enc_mode = 0x40020220 ); +PROVIDE ( r_lc_send_lmp = 0x4001c1a8 ); +PROVIDE ( r_lc_send_pdu_acc = 0x4001c21c ); +PROVIDE ( r_lc_send_pdu_acc_ext4 = 0x4001c240 ); +PROVIDE ( r_lc_send_pdu_au_rand = 0x4001c308 ); +PROVIDE ( r_lc_send_pdu_auto_rate = 0x4001c5d0 ); +PROVIDE ( r_lc_send_pdu_clk_adj_ack = 0x4001c46c ); +PROVIDE ( r_lc_send_pdu_clk_adj_req = 0x4001c494 ); +PROVIDE ( r_lc_send_pdu_comb_key = 0x4001c368 ); +PROVIDE ( r_lc_send_pdu_dhkey_chk = 0x4001c8e8 ); +PROVIDE ( r_lc_send_pdu_encaps_head = 0x4001c440 ); +PROVIDE ( r_lc_send_pdu_encaps_payl = 0x4001c410 ); +PROVIDE ( r_lc_send_pdu_enc_key_sz_req = 0x4001c670 ); +PROVIDE ( r_lc_send_pdu_esco_lk_rem_req = 0x4001c5a8 ); +PROVIDE ( r_lc_send_pdu_feats_ext_req = 0x4001c6ec ); +PROVIDE ( r_lc_send_pdu_feats_res = 0x4001c694 ); +PROVIDE ( r_lc_send_pdu_in_rand = 0x4001c338 ); +PROVIDE ( r_lc_send_pdu_io_cap_res = 0x4001c72c ); +PROVIDE ( r_lc_send_pdu_lsto = 0x4001c64c ); +PROVIDE ( r_lc_send_pdu_max_slot = 0x4001c3c8 ); +PROVIDE ( r_lc_send_pdu_max_slot_req = 0x4001c3ec ); +PROVIDE ( r_lc_send_pdu_not_acc = 0x4001c26c ); +PROVIDE ( r_lc_send_pdu_not_acc_ext4 = 0x4001c294 ); +PROVIDE ( r_lc_send_pdu_num_comp_fail = 0x4001c770 ); +PROVIDE ( r_lc_send_pdu_pause_enc_aes_req = 0x4001c794 ); +PROVIDE ( r_lc_send_pdu_paus_enc_req = 0x4001c7c0 ); +PROVIDE ( r_lc_send_pdu_ptt_req = 0x4001c4c0 ); +PROVIDE ( r_lc_send_pdu_qos_req = 0x4001c82c ); +PROVIDE ( r_lc_send_pdu_resu_enc_req = 0x4001c7e4 ); +PROVIDE ( r_lc_send_pdu_sco_lk_rem_req = 0x4001c580 ); +PROVIDE ( r_lc_send_pdu_set_afh = 0x4001c2c8 ); +PROVIDE ( r_lc_send_pdu_setup_cmp = 0x4001c808 ); +PROVIDE ( r_lc_send_pdu_slot_off = 0x4001c854 ); +PROVIDE ( r_lc_send_pdu_sniff_req = 0x4001c5f0 ); +PROVIDE ( r_lc_send_pdu_sp_cfm = 0x4001c518 ); +PROVIDE ( r_lc_send_pdu_sp_nb = 0x4001c4e8 ); +PROVIDE ( r_lc_send_pdu_sres = 0x4001c548 ); +PROVIDE ( r_lc_send_pdu_tim_acc = 0x4001c6cc ); +PROVIDE ( r_lc_send_pdu_unit_key = 0x4001c398 ); +PROVIDE ( r_lc_send_pdu_unsniff_req = 0x4001c894 ); +PROVIDE ( r_lc_send_pdu_vers_req = 0x4001c8b4 ); +PROVIDE ( r_lc_skip_hl_oob_req = 0x400201bc ); +PROVIDE ( r_lc_sniff_init = 0x40022cac ); +PROVIDE ( r_lc_sniff_max_slot_chg = 0x40020590 ); +PROVIDE ( r_lc_sniff_reset = 0x40022cc8 ); +PROVIDE ( r_lc_sniff_slot_unchange = 0x40021100 ); +PROVIDE ( r_lc_sniff_sub_mode = 0x400204fc ); +PROVIDE ( r_lc_sp_end = 0x400213a8 ); +PROVIDE ( r_lc_sp_fail = 0x40020470 ); +PROVIDE ( r_lc_sp_oob_tid_fail = 0x400204cc ); +PROVIDE ( r_lc_ssr_nego = 0x4002125c ); +PROVIDE ( r_lc_start = 0x4001ca28 ); +PROVIDE ( r_lc_start_enc = 0x4001fb28 ); +PROVIDE ( r_lc_start_enc_key_size = 0x4001fd9c ); +PROVIDE ( r_lc_start_key_exch = 0x4001fe10 ); +PROVIDE ( r_lc_start_lmp_to = 0x4001fae8 ); +PROVIDE ( r_lc_start_oob = 0x4001fffc ); +PROVIDE ( r_lc_start_passkey = 0x4001feac ); +PROVIDE ( r_lc_start_passkey_loop = 0x4001ff88 ); +PROVIDE ( r_lc_stop_afh_report = 0x40020184 ); +PROVIDE ( r_lc_stop_enc = 0x40020110 ); +PROVIDE ( r_lc_switch_cmp = 0x40020448 ); +PROVIDE ( r_lc_unit_key_svr = 0x400206d8 ); +PROVIDE ( r_lc_unsniff = 0x40020c50 ); +PROVIDE ( r_lc_unsniff_cmp = 0x40020810 ); +PROVIDE ( r_lc_unsniff_cont = 0x40020750 ); +PROVIDE ( r_lc_upd_to = 0x4002065c ); +PROVIDE ( r_lc_util_convert_pref_rate_to_packet_type = 0x4002f9b0 ); +PROVIDE ( r_lc_util_get_max_packet_size = 0x4002f4ac ); +PROVIDE ( r_lc_util_get_offset_clke = 0x4002f538 ); +PROVIDE ( r_lc_util_get_offset_clkn = 0x4002f51c ); +PROVIDE ( r_lc_util_set_loc_trans_coll = 0x4002f500 ); +PROVIDE ( r_lc_version = 0x40020a30 ); +PROVIDE ( lc_set_encap_pdu_data_p192 = 0x4002e4c8 ); +PROVIDE ( lc_set_encap_pdu_data_p256 = 0x4002e454 ); +PROVIDE ( lm_get_auth_method = 0x40023420 ); +PROVIDE ( lmp_accepted_ext_handler = 0x40027290 ); +PROVIDE ( lmp_not_accepted_ext_handler = 0x40029c54 ); +PROVIDE ( lmp_clk_adj_handler = 0x40027468 ); +PROVIDE ( lmp_clk_adj_ack_handler = 0x400274f4 ); +PROVIDE ( lm_get_auth_method = 0x40023420 ); +PROVIDE ( lmp_accepted_ext_handler = 0x40027290 ); +PROVIDE ( lmp_not_accepted_ext_handler = 0x40029c54 ); +PROVIDE ( lmp_clk_adj_handler = 0x40027468 ); +PROVIDE ( lmp_clk_adj_ack_handler = 0x400274f4 ); +PROVIDE ( lmp_clk_adj_req_handler = 0x4002751c ); +PROVIDE ( lmp_feats_res_ext_handler = 0x4002cac4 ); +PROVIDE ( lmp_feats_req_ext_handler = 0x4002ccb0 ); +PROVIDE ( lmp_pkt_type_tbl_req_handler = 0x40027574 ); +PROVIDE ( lmp_esco_link_req_handler = 0x40027610 ); +PROVIDE ( lmp_rmv_esco_link_req_handler = 0x400276e8 ); +PROVIDE ( lmp_ch_class_req_handler = 0x40027730 ); +PROVIDE ( lmp_ch_class_handler = 0x4002ca18 ); +PROVIDE ( lmp_ssr_req_handler = 0x4002780c ); +PROVIDE ( lmp_ssr_res_handler = 0x40027900 ); +PROVIDE ( lmp_pause_enc_aes_req_handler = 0x400279a4 ); +PROVIDE ( lmp_pause_enc_req_handler = 0x4002df90 ); +PROVIDE ( lmp_resume_enc_req_handler = 0x4002e084 ); +PROVIDE ( lmp_num_comparison_fail_handler = 0x40027a74 ); +PROVIDE ( lmp_passkey_fail_handler = 0x40027aec ); +PROVIDE ( lmp_keypress_notif_handler = 0x4002c5c8 ); +PROVIDE ( lmp_pwr_ctrl_req_handler = 0x400263bc ); +PROVIDE ( lmp_pwr_ctrl_res_handler = 0x40026480 ); +PROVIDE ( lmp_auto_rate_handler = 0x40026548 ); +PROVIDE ( lmp_pref_rate_handler = 0x4002657c ); +PROVIDE ( lmp_name_req_handler = 0x40025050 ); +PROVIDE ( lmp_name_res_handler = 0x400250bc ); +PROVIDE ( lmp_not_accepted_handler = 0x400251d0 ); +PROVIDE ( lmp_accepted_handler = 0x4002e894 ); +PROVIDE ( lmp_clk_off_req_handler = 0x40025a44 ); +PROVIDE ( lmp_clk_off_res_handler = 0x40025ab8 ); +PROVIDE ( lmp_detach_handler = 0x40025b74 ); +PROVIDE ( lmp_tempkey_handler = 0x4002b6b0 ); +PROVIDE ( lmp_temprand_handler = 0x4002b74c ); +PROVIDE ( lmp_sres_handler = 0x4002b840 ); +PROVIDE ( lmp_aurand_handler = 0x4002bda0 ); +PROVIDE ( lmp_unitkey_handler = 0x4002c13c ); +PROVIDE ( lmp_combkey_handler = 0x4002c234 ); +PROVIDE ( lmp_inrand_handler = 0x4002c414 ); +PROVIDE ( lmp_oob_fail_handler = 0x40027b84 ); +PROVIDE ( lmp_ping_req_handler = 0x40027c08 ); +PROVIDE ( lmp_ping_res_handler = 0x40027c5c ); +PROVIDE ( lmp_enc_mode_req_handler = 0x40025c60 ); +PROVIDE ( lmp_enc_key_size_req_handler = 0x40025e54 ); +PROVIDE ( lmp_switch_req_handler = 0x40025f84 ); +PROVIDE ( lmp_start_enc_req_handler = 0x4002e124 ); +PROVIDE ( lmp_stop_enc_req_handler = 0x4002de30 ); +PROVIDE ( lmp_sniff_req_handler = 0x400260c8 ); +PROVIDE ( lmp_unsniff_req_handler = 0x400261e0 ); +PROVIDE ( lmp_incr_pwr_req_handler = 0x4002629c ); +PROVIDE ( lmp_decr_pwr_req_handler = 0x400262f8 ); +PROVIDE ( lmp_max_pwr_handler = 0x40026354 ); +PROVIDE ( lmp_min_pwr_handler = 0x40026388 ); +PROVIDE ( lmp_ver_req_handler = 0x400265f0 ); +PROVIDE ( lmp_ver_res_handler = 0x40026670 ); +PROVIDE ( lmp_qos_handler = 0x40026790 ); +PROVIDE ( lmp_qos_req_handler = 0x40026844 ); +PROVIDE ( lmp_sco_link_req_handler = 0x40026930 ); +PROVIDE ( lmp_rmv_sco_link_req_handler = 0x40026a10 ); +PROVIDE ( lmp_max_slot_handler = 0x40026a54 ); +PROVIDE ( lmp_max_slot_req_handler = 0x40026aac ); +PROVIDE ( lmp_timing_accu_req_handler = 0x40026b54 ); +PROVIDE ( lmp_timing_accu_res_handler = 0x40026bcc ); +PROVIDE ( lmp_setup_cmp_handler = 0x40026c84 ); +PROVIDE ( lmp_feats_res_handler = 0x4002b548 ); +PROVIDE ( lmp_feats_req_handler = 0x4002b620 ); +PROVIDE ( lmp_host_con_req_handler = 0x4002b3d8 ); +PROVIDE ( lmp_use_semi_perm_key_handler = 0x4002b4c4 ); +PROVIDE ( lmp_slot_off_handler = 0x40026cc8 ); +PROVIDE ( lmp_page_mode_req_handler = 0x40026d0c ); +PROVIDE ( lmp_page_scan_mode_req_handler = 0x40026d4c ); +PROVIDE ( lmp_supv_to_handler = 0x40026d94 ); +PROVIDE ( lmp_test_activate_handler = 0x40026e7c ); +PROVIDE ( lmp_test_ctrl_handler = 0x40026ee4 ); +PROVIDE ( lmp_enc_key_size_mask_req_handler = 0x40027038 ); +PROVIDE ( lmp_enc_key_size_mask_res_handler = 0x400270a4 ); +PROVIDE ( lmp_set_afh_handler = 0x4002b2e4 ); +PROVIDE ( lmp_encaps_hdr_handler = 0x40027120 ); +PROVIDE ( lmp_encaps_payl_handler = 0x4002e590 ); +PROVIDE ( lmp_sp_nb_handler = 0x4002acf0 ); +PROVIDE ( lmp_sp_cfm_handler = 0x4002b170 ); +PROVIDE ( lmp_dhkey_chk_handler = 0x4002ab48 ); +PROVIDE ( lmp_pause_enc_aes_req_handler = 0x400279a4 ); +PROVIDE ( lmp_io_cap_res_handler = 0x4002c670 ); +PROVIDE ( lmp_io_cap_req_handler = 0x4002c7a4 ); +PROVIDE ( lc_cmd_cmp_bd_addr_send = 0x4002cec4 ); +PROVIDE ( ld_acl_tx_packet_type_select = 0x4002fb40 ); +PROVIDE ( ld_acl_sched = 0x40033268 ); +PROVIDE ( ld_acl_sniff_sched = 0x4003340c ); +PROVIDE ( ld_acl_rx = 0x4003274c ); +PROVIDE ( ld_acl_tx = 0x4002ffdc ); +PROVIDE ( ld_acl_rx_sync = 0x4002fbec ); +PROVIDE ( ld_acl_rx_sync2 = 0x4002fd8c ); +PROVIDE ( ld_acl_rx_no_sync = 0x4002fe78 ); +PROVIDE ( ld_acl_clk_isr = 0x40030cf8 ); +PROVIDE ( ld_acl_rsw_frm_cbk = 0x40033bb0 ); +PROVIDE ( ld_sco_modify = 0x40031778 ); +PROVIDE ( lm_cmd_cmp_send = 0x40051838 ); +PROVIDE ( ld_sco_frm_cbk = 0x400349dc ); +PROVIDE ( ld_acl_sco_rsvd_check = 0x4002fa94 ); +PROVIDE ( ld_acl_sniff_frm_cbk = 0x4003482c ); +PROVIDE ( ld_inq_end = 0x4003ab48 ); +PROVIDE ( ld_inq_sched = 0x4003aba4 ); +PROVIDE ( ld_inq_frm_cbk = 0x4003ae4c ); +PROVIDE ( ld_pscan_frm_cbk = 0x4003ebe4 ); +PROVIDE ( r_ld_acl_active_hop_types_get = 0x40036e10 ); +PROVIDE ( r_ld_acl_afh_confirm = 0x40036d40 ); +PROVIDE ( r_ld_acl_afh_prepare = 0x40036c84 ); +PROVIDE ( r_ld_acl_afh_set = 0x40036b60 ); +PROVIDE ( r_ld_acl_allowed_tx_packet_types_set = 0x40036810 ); +PROVIDE ( r_ld_acl_bcst_rx_dec = 0x40036394 ); +PROVIDE ( r_ld_acl_bit_off_get = 0x40036b18 ); +PROVIDE ( r_ld_acl_clk_adj_set = 0x40036a00 ); +PROVIDE ( r_ld_acl_clk_off_get = 0x40036b00 ); +PROVIDE ( r_ld_acl_clk_set = 0x40036950 ); +PROVIDE ( r_ld_acl_clock_offset_get = 0x400364c0 ); +PROVIDE ( r_ld_acl_current_tx_power_get = 0x400368f0 ); +PROVIDE ( r_ld_acl_data_flush = 0x400357bc ); +PROVIDE ( r_ld_acl_data_tx = 0x4003544c ); +PROVIDE ( r_ld_acl_edr_set = 0x4003678c ); +PROVIDE ( r_ld_acl_enc_key_load = 0x40036404 ); +PROVIDE ( r_ld_acl_flow_off = 0x40035400 ); +PROVIDE ( r_ld_acl_flow_on = 0x4003541c ); +PROVIDE ( r_ld_acl_flush_timeout_get = 0x40035f9c ); +PROVIDE ( r_ld_acl_flush_timeout_set = 0x40035fe0 ); +PROVIDE ( r_ld_acl_init = 0x40034d08 ); +PROVIDE ( r_ld_acl_lmp_flush = 0x40035d80 ); +PROVIDE ( r_ld_acl_lmp_tx = 0x40035b34 ); +PROVIDE ( r_ld_acl_lsto_get = 0x400366b4 ); +PROVIDE ( r_ld_acl_lsto_set = 0x400366f8 ); +PROVIDE ( r_ld_acl_reset = 0x40034d24 ); +PROVIDE ( r_ld_acl_role_get = 0x40036b30 ); +PROVIDE ( r_ld_acl_rssi_delta_get = 0x40037028 ); +PROVIDE ( r_ld_acl_rsw_req = 0x40035e74 ); +PROVIDE ( r_ld_acl_rx_enc = 0x40036344 ); +PROVIDE ( r_ld_acl_rx_max_slot_get = 0x40036e58 ); +PROVIDE ( r_ld_acl_rx_max_slot_set = 0x40036ea0 ); +PROVIDE ( r_ld_acl_slot_offset_get = 0x4003653c ); +PROVIDE ( r_ld_acl_slot_offset_set = 0x40036658 ); +PROVIDE ( r_ld_acl_sniff = 0x4003617c ); +PROVIDE ( r_ld_acl_sniff_trans = 0x400360a8 ); +PROVIDE ( r_ld_acl_ssr_set = 0x40036274 ); +PROVIDE ( r_ld_acl_start = 0x40034ddc ); +PROVIDE ( r_ld_acl_stop = 0x4003532c ); +PROVIDE ( r_ld_acl_test_mode_set = 0x40036f24 ); +PROVIDE ( r_ld_acl_timing_accuracy_set = 0x4003673c ); +PROVIDE ( r_ld_acl_t_poll_get = 0x40036024 ); +PROVIDE ( r_ld_acl_t_poll_set = 0x40036068 ); +PROVIDE ( r_ld_acl_tx_enc = 0x400362f8 ); +PROVIDE ( ld_acl_frm_cbk = 0x40034414 ); +PROVIDE ( ld_acl_rsw_end = 0x40032bc0 ); +PROVIDE ( ld_acl_end = 0x40033140 ); +PROVIDE ( ld_acl_resched = 0x40033814 ); +PROVIDE ( ld_acl_test_mode_update = 0x40032050 ); +PROVIDE ( r_ld_acl_unsniff = 0x400361e0 ); +PROVIDE ( r_ld_active_check = 0x4003cac4 ); +PROVIDE ( r_ld_afh_ch_assess_data_get = 0x4003caec ); +PROVIDE ( r_ld_bcst_acl_data_tx = 0x40038d3c ); +PROVIDE ( r_ld_bcst_acl_init = 0x40038bd0 ); +PROVIDE ( r_ld_bcst_acl_reset = 0x40038bdc ); +PROVIDE ( r_ld_bcst_acl_start = 0x4003882c ); +PROVIDE ( r_ld_bcst_afh_update = 0x40038f3c ); +PROVIDE ( r_ld_bcst_enc_key_load = 0x4003906c ); +PROVIDE ( r_ld_bcst_lmp_tx = 0x40038bf8 ); +PROVIDE ( r_ld_bcst_tx_enc = 0x40038ff8 ); +PROVIDE ( r_ld_bd_addr_get = 0x4003ca20 ); +PROVIDE ( r_ld_channel_assess = 0x4003c184 ); +PROVIDE ( r_ld_class_of_dev_get = 0x4003ca34 ); +PROVIDE ( r_ld_class_of_dev_set = 0x4003ca50 ); +PROVIDE ( r_ld_csb_rx_afh_update = 0x40039af4 ); +PROVIDE ( r_ld_csb_rx_init = 0x40039690 ); +PROVIDE ( r_ld_csb_rx_reset = 0x4003969c ); +PROVIDE ( r_ld_csb_rx_start = 0x4003972c ); +PROVIDE ( r_ld_csb_rx_stop = 0x40039bb8 ); +PROVIDE ( r_ld_csb_tx_afh_update = 0x4003a5fc ); +PROVIDE ( r_ld_csb_tx_clr_data = 0x4003a71c ); +PROVIDE ( r_ld_csb_tx_dis = 0x4003a5e8 ); +PROVIDE ( r_ld_csb_tx_en = 0x4003a1c0 ); +PROVIDE ( r_ld_csb_tx_init = 0x4003a0e8 ); +PROVIDE ( r_ld_csb_tx_reset = 0x4003a0f8 ); +PROVIDE ( r_ld_csb_tx_set_data = 0x4003a6c0 ); +PROVIDE ( r_ld_fm_clk_isr = 0x4003a7a8 ); +PROVIDE ( r_ld_fm_frame_isr = 0x4003a82c ); +PROVIDE ( r_ld_fm_init = 0x4003a760 ); +PROVIDE ( r_ld_fm_prog_check = 0x4003ab28 ); +PROVIDE ( r_ld_fm_prog_disable = 0x4003a984 ); +PROVIDE ( r_ld_fm_prog_enable = 0x4003a944 ); +PROVIDE ( r_ld_fm_prog_push = 0x4003a9d4 ); +PROVIDE ( r_ld_fm_reset = 0x4003a794 ); +PROVIDE ( r_ld_fm_rx_isr = 0x4003a7f4 ); +PROVIDE ( r_ld_fm_sket_isr = 0x4003a8a4 ); +PROVIDE ( r_ld_init = 0x4003c294 ); +PROVIDE ( r_ld_inq_init = 0x4003b15c ); +PROVIDE ( r_ld_inq_reset = 0x4003b168 ); +PROVIDE ( r_ld_inq_start = 0x4003b1f0 ); +PROVIDE ( r_ld_inq_stop = 0x4003b4f0 ); +PROVIDE ( r_ld_iscan_eir_get = 0x4003c118 ); +PROVIDE ( r_ld_iscan_eir_set = 0x4003bfa0 ); +PROVIDE ( r_ld_iscan_init = 0x4003b9f0 ); +PROVIDE ( r_ld_iscan_reset = 0x4003ba14 ); +PROVIDE ( r_ld_iscan_restart = 0x4003ba44 ); +PROVIDE ( r_ld_iscan_start = 0x4003bb28 ); +PROVIDE ( r_ld_iscan_stop = 0x4003bf1c ); +PROVIDE ( r_ld_iscan_tx_pwr_get = 0x4003c138 ); +PROVIDE ( r_ld_page_init = 0x4003d808 ); +PROVIDE ( r_ld_page_reset = 0x4003d814 ); +PROVIDE ( r_ld_page_start = 0x4003d848 ); +PROVIDE ( r_ld_page_stop = 0x4003da54 ); +PROVIDE ( r_ld_pca_coarse_clock_adjust = 0x4003e324 ); +PROVIDE ( r_ld_pca_init = 0x4003deb4 ); +PROVIDE ( r_ld_pca_initiate_clock_dragging = 0x4003e4ac ); +PROVIDE ( r_ld_pca_local_config = 0x4003df6c ); +PROVIDE ( r_ld_pca_mws_frame_sync = 0x4003e104 ); +PROVIDE ( r_ld_pca_mws_moment_offset_gt = 0x4003e278 ); +PROVIDE ( r_ld_pca_mws_moment_offset_lt = 0x4003e280 ); +PROVIDE ( r_ld_pca_reporting_enable = 0x4003e018 ); +PROVIDE ( r_ld_pca_reset = 0x4003df0c ); +PROVIDE ( r_ld_pca_update_target_offset = 0x4003e050 ); +PROVIDE ( r_ld_pscan_evt_handler = 0x4003f238 ); +PROVIDE ( r_ld_pscan_init = 0x4003f474 ); +PROVIDE ( r_ld_pscan_reset = 0x4003f498 ); +PROVIDE ( r_ld_pscan_restart = 0x4003f4b8 ); +PROVIDE ( r_ld_pscan_start = 0x4003f514 ); +PROVIDE ( r_ld_pscan_stop = 0x4003f618 ); +PROVIDE ( r_ld_read_clock = 0x4003c9e4 ); +PROVIDE ( r_ld_reset = 0x4003c714 ); +PROVIDE ( r_ld_sched_acl_add = 0x4003f978 ); +PROVIDE ( r_ld_sched_acl_remove = 0x4003f99c ); +PROVIDE ( r_ld_sched_compute = 0x4003f6f8 ); +PROVIDE ( r_ld_sched_init = 0x4003f7ac ); +PROVIDE ( r_ld_sched_inq_add = 0x4003f8a8 ); +PROVIDE ( r_ld_sched_inq_remove = 0x4003f8d0 ); +PROVIDE ( r_ld_sched_iscan_add = 0x4003f7e8 ); +PROVIDE ( r_ld_sched_iscan_remove = 0x4003f808 ); +PROVIDE ( r_ld_sched_page_add = 0x4003f910 ); +PROVIDE ( r_ld_sched_page_remove = 0x4003f938 ); +PROVIDE ( r_ld_sched_pscan_add = 0x4003f828 ); +PROVIDE ( r_ld_sched_pscan_remove = 0x4003f848 ); +PROVIDE ( r_ld_sched_reset = 0x4003f7d4 ); +PROVIDE ( r_ld_sched_sco_add = 0x4003fa4c ); +PROVIDE ( r_ld_sched_sco_remove = 0x4003fa9c ); +PROVIDE ( r_ld_sched_sniff_add = 0x4003f9c4 ); +PROVIDE ( r_ld_sched_sniff_remove = 0x4003fa0c ); +PROVIDE ( r_ld_sched_sscan_add = 0x4003f868 ); +PROVIDE ( r_ld_sched_sscan_remove = 0x4003f888 ); +PROVIDE ( r_ld_sco_audio_isr = 0x40037cc8 ); +PROVIDE ( r_ld_sco_data_tx = 0x40037ee8 ); +PROVIDE ( r_ld_sco_start = 0x40037110 ); +PROVIDE ( r_ld_sco_stop = 0x40037c40 ); +PROVIDE ( r_ld_sco_update = 0x40037a74 ); +PROVIDE ( r_ld_sscan_activated = 0x4004031c ); +PROVIDE ( r_ld_sscan_init = 0x400402f0 ); +PROVIDE ( r_ld_sscan_reset = 0x400402fc ); +PROVIDE ( r_ld_sscan_start = 0x40040384 ); +PROVIDE ( r_ld_strain_init = 0x400409f4 ); +PROVIDE ( r_ld_strain_reset = 0x40040a00 ); +PROVIDE ( r_ld_strain_start = 0x40040a8c ); +PROVIDE ( r_ld_strain_stop = 0x40040df0 ); +PROVIDE ( r_ld_timing_accuracy_get = 0x4003caac ); +PROVIDE ( r_ld_util_active_master_afh_map_get = 0x4004131c ); +PROVIDE ( r_ld_util_active_master_afh_map_set = 0x40041308 ); +PROVIDE ( r_ld_util_bch_create = 0x40040fcc ); +PROVIDE ( r_ld_util_fhs_pk = 0x400411c8 ); +PROVIDE ( r_ld_util_fhs_unpk = 0x40040e54 ); +PROVIDE ( r_ld_util_stp_pk = 0x400413f4 ); +PROVIDE ( r_ld_util_stp_unpk = 0x40041324 ); +PROVIDE ( r_ld_version_get = 0x4003ca6c ); +PROVIDE ( r_ld_wlcoex_set = 0x4003caf8 ); +PROVIDE ( r_llc_ch_assess_get_current_ch_map = 0x40041574 ); +PROVIDE ( r_llc_ch_assess_get_local_ch_map = 0x4004150c ); +PROVIDE ( r_llc_ch_assess_local = 0x40041494 ); +PROVIDE ( r_llc_ch_assess_merge_ch = 0x40041588 ); +PROVIDE ( r_llc_ch_assess_reass_ch = 0x400415c0 ); +PROVIDE ( r_llc_common_cmd_complete_send = 0x40044eac ); +PROVIDE ( r_llc_common_cmd_status_send = 0x40044ee0 ); +PROVIDE ( r_llc_common_enc_change_evt_send = 0x40044f6c ); +PROVIDE ( r_llc_common_enc_key_ref_comp_evt_send = 0x40044f38 ); +PROVIDE ( r_llc_common_flush_occurred_send = 0x40044f0c ); +PROVIDE ( r_llc_common_nb_of_pkt_comp_evt_send = 0x40045000 ); +PROVIDE ( r_llc_con_update_complete_send = 0x40044d68 ); +PROVIDE ( r_llc_con_update_finished = 0x4004518c ); +PROVIDE ( r_llc_con_update_ind = 0x40045038 ); +PROVIDE ( r_llc_discon_event_complete_send = 0x40044a30 ); +PROVIDE ( r_llc_end_evt_defer = 0x40046330 ); +PROVIDE ( r_llc_feats_rd_event_send = 0x40044e0c ); +PROVIDE ( r_llc_init = 0x40044778 ); +PROVIDE ( r_llc_le_con_cmp_evt_send = 0x40044a78 ); +PROVIDE ( r_llc_llcp_ch_map_update_pdu_send = 0x40043f94 ); +PROVIDE ( r_llc_llcp_con_param_req_pdu_send = 0x400442fc ); +PROVIDE ( r_llc_llcp_con_param_rsp_pdu_send = 0x40044358 ); +PROVIDE ( r_llc_llcp_con_update_pdu_send = 0x400442c4 ); +PROVIDE ( r_llc_llcp_enc_req_pdu_send = 0x40044064 ); +PROVIDE ( r_llc_llcp_enc_rsp_pdu_send = 0x40044160 ); +PROVIDE ( r_llc_llcp_feats_req_pdu_send = 0x400443b4 ); +PROVIDE ( r_llc_llcp_feats_rsp_pdu_send = 0x400443f0 ); +PROVIDE ( r_llc_llcp_get_autorize = 0x4004475c ); +PROVIDE ( r_llc_llcp_length_req_pdu_send = 0x40044574 ); +PROVIDE ( r_llc_llcp_length_rsp_pdu_send = 0x400445ac ); +PROVIDE ( r_llc_llcp_pause_enc_req_pdu_send = 0x40043fd8 ); +PROVIDE ( r_llc_llcp_pause_enc_rsp_pdu_send = 0x40044010 ); +PROVIDE ( r_llc_llcp_ping_req_pdu_send = 0x4004454c ); +PROVIDE ( r_llc_llcp_ping_rsp_pdu_send = 0x40044560 ); +PROVIDE ( r_llc_llcp_recv_handler = 0x40044678 ); +PROVIDE ( r_llc_llcp_reject_ind_pdu_send = 0x4004425c ); +PROVIDE ( r_llc_llcp_start_enc_req_pdu_send = 0x4004441c ); +PROVIDE ( r_llc_llcp_start_enc_rsp_pdu_send = 0x400441f8 ); +PROVIDE ( r_llc_llcp_terminate_ind_pdu_send = 0x400444b0 ); +PROVIDE ( r_llc_llcp_tester_send = 0x400445e4 ); +PROVIDE ( r_llc_llcp_unknown_rsp_send_pdu = 0x40044534 ); +PROVIDE ( r_llc_llcp_version_ind_pdu_send = 0x40043f6c ); +PROVIDE ( r_llc_lsto_con_update = 0x40045098 ); +PROVIDE ( r_llc_ltk_req_send = 0x40044dc0 ); +PROVIDE ( r_llc_map_update_finished = 0x40045260 ); +PROVIDE ( r_llc_map_update_ind = 0x400450f0 ); +PROVIDE ( r_llc_pdu_acl_tx_ack_defer = 0x400464dc ); +PROVIDE ( r_llc_pdu_defer = 0x40046528 ); +PROVIDE ( r_llc_pdu_llcp_tx_ack_defer = 0x400463ac ); +PROVIDE ( r_llc_reset = 0x400447b8 ); +PROVIDE ( r_llc_start = 0x400447f4 ); +PROVIDE ( r_llc_stop = 0x400449ac ); +PROVIDE ( r_llc_util_bw_mgt = 0x4004629c ); +PROVIDE ( r_llc_util_clear_operation_ptr = 0x40046234 ); +PROVIDE ( r_llc_util_dicon_procedure = 0x40046130 ); +PROVIDE ( r_llc_util_get_free_conhdl = 0x400460c8 ); +PROVIDE ( r_llc_util_get_nb_active_link = 0x40046100 ); +PROVIDE ( r_llc_util_set_auth_payl_to_margin = 0x400461f4 ); +PROVIDE ( r_llc_util_set_llcp_discard_enable = 0x400461c8 ); +PROVIDE ( r_llc_util_update_channel_map = 0x400461ac ); +PROVIDE ( r_llc_version_rd_event_send = 0x40044e60 ); +PROVIDE ( r_lld_adv_start = 0x40048b38 ); +PROVIDE ( r_lld_adv_stop = 0x40048ea0 ); +PROVIDE ( r_lld_ch_map_ind = 0x4004a2f4 ); +PROVIDE ( r_lld_con_param_req = 0x40049f0c ); +PROVIDE ( r_lld_con_param_rsp = 0x40049e00 ); +PROVIDE ( r_lld_con_start = 0x400491f8 ); +PROVIDE ( r_lld_con_stop = 0x40049fdc ); +PROVIDE ( r_lld_con_update_after_param_req = 0x40049bcc ); +PROVIDE ( r_lld_con_update_ind = 0x4004a30c ); +PROVIDE ( r_lld_con_update_req = 0x40049b60 ); +PROVIDE ( r_lld_core_reset = 0x40048a9c ); +PROVIDE ( r_lld_crypt_isr = 0x4004a324 ); +PROVIDE ( r_lld_evt_adv_create = 0x400481f4 ); +PROVIDE ( r_lld_evt_canceled = 0x400485c8 ); +PROVIDE ( r_lld_evt_channel_next = 0x40046aac ); +PROVIDE ( r_lld_evt_deffered_elt_handler = 0x400482bc ); +PROVIDE ( r_lld_evt_delete_elt_handler = 0x40046974 ); +PROVIDE ( r_lld_evt_delete_elt_push = 0x40046a3c ); +PROVIDE ( r_lld_evt_drift_compute = 0x40047670 ); +PROVIDE ( r_lld_evt_elt_delete = 0x40047538 ); +PROVIDE ( r_lld_evt_elt_insert = 0x400474c8 ); +PROVIDE ( r_lld_evt_end = 0x400483e8 ); +PROVIDE ( r_lld_evt_end_isr = 0x4004862c ); +PROVIDE ( r_lld_evt_init = 0x40046b3c ); +PROVIDE ( r_lld_evt_init_evt = 0x40046cd0 ); +PROVIDE ( r_lld_evt_move_to_master = 0x40047ba0 ); +PROVIDE ( r_lld_evt_move_to_slave = 0x40047e18 ); +PROVIDE ( r_lld_evt_prevent_stop = 0x40047adc ); +PROVIDE ( r_lld_evt_restart = 0x40046d50 ); +PROVIDE ( r_lld_evt_rx = 0x40048578 ); +PROVIDE ( r_lld_evt_rx_isr = 0x40048678 ); +PROVIDE ( r_lld_evt_scan_create = 0x40047ae8 ); +PROVIDE ( r_lld_evt_schedule = 0x40047908 ); +PROVIDE ( r_lld_evt_schedule_next = 0x400477dc ); +PROVIDE ( r_lld_evt_schedule_next_instant = 0x400476a8 ); +PROVIDE ( r_lld_evt_slave_update = 0x40048138 ); +PROVIDE ( r_lld_evt_update_create = 0x40047cd8 ); +PROVIDE ( r_lld_get_mode = 0x40049ff8 ); +PROVIDE ( r_lld_init = 0x4004873c ); +PROVIDE ( r_lld_move_to_master = 0x400499e0 ); +PROVIDE ( r_lld_move_to_slave = 0x4004a024 ); +PROVIDE ( r_lld_pdu_adv_pack = 0x4004b488 ); +PROVIDE ( r_lld_pdu_check = 0x4004ac34 ); +PROVIDE ( r_lld_pdu_data_send = 0x4004b018 ); +PROVIDE ( r_lld_pdu_data_tx_push = 0x4004aecc ); +PROVIDE ( r_lld_pdu_rx_handler = 0x4004b4d4 ); +PROVIDE ( r_lld_pdu_send_packet = 0x4004b774 ); +PROVIDE ( r_lld_pdu_tx_flush = 0x4004b414 ); +PROVIDE ( r_lld_pdu_tx_loop = 0x4004ae40 ); +PROVIDE ( r_lld_pdu_tx_prog = 0x4004b120 ); +PROVIDE ( r_lld_pdu_tx_push = 0x4004b080 ); +PROVIDE ( r_lld_ral_renew_req = 0x4004a73c ); +/**************************************************************************** + * boards/xtensa/elf32-core/scripts/esp32_rom.ld + ****************************************************************************/ + +PROVIDE ( r_lld_scan_start = 0x40048ee0 ); +PROVIDE ( r_lld_scan_stop = 0x40049190 ); +PROVIDE ( r_lld_test_mode_rx = 0x4004a540 ); +PROVIDE ( r_lld_test_mode_tx = 0x4004a350 ); +PROVIDE ( r_lld_test_stop = 0x4004a710 ); +PROVIDE ( r_lld_util_anchor_point_move = 0x4004bacc ); +PROVIDE ( r_lld_util_compute_ce_max = 0x4004bc0c ); +PROVIDE ( r_lld_util_connection_param_set = 0x4004ba40 ); +PROVIDE ( r_lld_util_dle_set_cs_fields = 0x4004ba90 ); +PROVIDE ( r_lld_util_eff_tx_time_set = 0x4004bd88 ); +PROVIDE ( r_lld_util_elt_programmed = 0x4004bce0 ); +PROVIDE ( r_lld_util_flush_list = 0x4004bbd8 ); +PROVIDE ( r_lld_util_freq2chnl = 0x4004b9e4 ); +PROVIDE ( r_lld_util_get_bd_address = 0x4004b8ac ); +PROVIDE ( r_lld_util_get_local_offset = 0x4004ba10 ); +PROVIDE ( r_lld_util_get_peer_offset = 0x4004ba24 ); +PROVIDE ( r_lld_util_get_tx_pkt_cnt = 0x4004bd80 ); +PROVIDE ( r_lld_util_instant_get = 0x4004b890 ); +PROVIDE ( r_lld_util_instant_ongoing = 0x4004bbfc ); +PROVIDE ( r_lld_util_priority_set = 0x4004bd10 ); +PROVIDE ( r_lld_util_priority_update = 0x4004bd78 ); +PROVIDE ( r_lld_util_ral_force_rpa_renew = 0x4004b980 ); +PROVIDE ( r_lld_util_set_bd_address = 0x4004b8f8 ); +PROVIDE ( r_lld_wlcoex_set = 0x4004bd98 ); +PROVIDE ( r_llm_ble_ready = 0x4004cc34 ); +PROVIDE ( r_llm_common_cmd_complete_send = 0x4004d288 ); +PROVIDE ( r_llm_common_cmd_status_send = 0x4004d2b4 ); +PROVIDE ( r_llm_con_req_ind = 0x4004cc54 ); +PROVIDE ( r_llm_con_req_tx_cfm = 0x4004d158 ); +PROVIDE ( r_llm_create_con = 0x4004de78 ); +PROVIDE ( r_llm_encryption_done = 0x4004dff8 ); +PROVIDE ( r_llm_encryption_start = 0x4004e128 ); +PROVIDE ( r_llm_end_evt_defer = 0x4004eb6c ); +PROVIDE ( r_llm_init = 0x4004c9f8 ); +PROVIDE ( r_llm_le_adv_report_ind = 0x4004cdf4 ); +PROVIDE ( r_llm_pdu_defer = 0x4004ec48 ); +PROVIDE ( r_llm_ral_clear = 0x4004e1fc ); +PROVIDE ( r_llm_ral_dev_add = 0x4004e23c ); +PROVIDE ( r_llm_ral_dev_rm = 0x4004e3bc ); +PROVIDE ( r_llm_ral_get_rpa = 0x4004e400 ); +PROVIDE ( r_llm_ral_set_timeout = 0x4004e4a0 ); +PROVIDE ( r_llm_ral_update = 0x4004e4f8 ); +PROVIDE ( r_llm_set_adv_data = 0x4004d960 ); +PROVIDE ( r_llm_set_adv_en = 0x4004d7ec ); +PROVIDE ( r_llm_set_adv_param = 0x4004d5f4 ); +PROVIDE ( r_llm_set_scan_en = 0x4004db64 ); +PROVIDE ( r_llm_set_scan_param = 0x4004dac8 ); +PROVIDE ( r_llm_set_scan_rsp_data = 0x4004da14 ); +PROVIDE ( r_llm_test_mode_start_rx = 0x4004d534 ); +PROVIDE ( r_llm_test_mode_start_tx = 0x4004d2fc ); +PROVIDE ( r_llm_util_adv_data_update = 0x4004e8fc ); +PROVIDE ( r_llm_util_apply_bd_addr = 0x4004e868 ); +PROVIDE ( r_llm_util_bd_addr_in_ral = 0x4004eb08 ); +PROVIDE ( r_llm_util_bd_addr_in_wl = 0x4004e788 ); +PROVIDE ( r_llm_util_bd_addr_wl_position = 0x4004e720 ); +PROVIDE ( r_llm_util_bl_add = 0x4004e9ac ); +PROVIDE ( r_llm_util_bl_check = 0x4004e930 ); +PROVIDE ( r_llm_util_bl_rem = 0x4004ea70 ); +PROVIDE ( r_llm_util_check_address_validity = 0x4004e7e4 ); +PROVIDE ( r_llm_util_check_evt_mask = 0x4004e8b0 ); +PROVIDE ( r_llm_util_check_map_validity = 0x4004e800 ); +PROVIDE ( r_llm_util_get_channel_map = 0x4004e8d4 ); +PROVIDE ( r_llm_util_get_supp_features = 0x4004e8e8 ); +PROVIDE ( r_llm_util_set_public_addr = 0x4004e89c ); +PROVIDE ( r_llm_wl_clr = 0x4004dc54 ); +PROVIDE ( r_llm_wl_dev_add = 0x4004dcc0 ); +PROVIDE ( r_llm_wl_dev_add_hdl = 0x4004dd38 ); +PROVIDE ( r_llm_wl_dev_rem = 0x4004dcfc ); +PROVIDE ( r_llm_wl_dev_rem_hdl = 0x4004dde0 ); +PROVIDE ( r_lm_acl_disc = 0x4004f148 ); +PROVIDE ( r_LM_AddSniff = 0x40022d20 ); +PROVIDE ( r_lm_add_sync = 0x40051358 ); +PROVIDE ( r_lm_afh_activate_timer = 0x4004f444 ); +PROVIDE ( r_lm_afh_ch_ass_en_get = 0x4004f3f8 ); +PROVIDE ( r_lm_afh_host_ch_class_get = 0x4004f410 ); +PROVIDE ( r_lm_afh_master_ch_map_get = 0x4004f43c ); +PROVIDE ( r_lm_afh_peer_ch_class_set = 0x4004f418 ); +PROVIDE ( r_lm_check_active_sync = 0x40051334 ); +PROVIDE ( r_LM_CheckEdrFeatureRequest = 0x4002f90c ); +PROVIDE ( r_LM_CheckSwitchInstant = 0x4002f8c0 ); +PROVIDE ( r_lm_check_sync_hl_rsp = 0x4005169c ); +PROVIDE ( r_lm_clk_adj_ack_pending_clear = 0x4004f514 ); +PROVIDE ( r_lm_clk_adj_instant_pending_set = 0x4004f4d8 ); +PROVIDE ( r_LM_ComputePacketType = 0x4002f554 ); +PROVIDE ( r_LM_ComputeSniffSubRate = 0x400233ac ); +PROVIDE ( r_lm_debug_key_compare_192 = 0x4004f3a8 ); +PROVIDE ( r_lm_debug_key_compare_256 = 0x4004f3d0 ); +PROVIDE ( r_lm_dhkey_calc_init = 0x40013234 ); +PROVIDE ( r_lm_dhkey_compare = 0x400132d8 ); +PROVIDE ( r_lm_dut_mode_en_get = 0x4004f3ec ); +PROVIDE ( r_LM_ExtractMaxEncKeySize = 0x4001aca4 ); +PROVIDE ( r_lm_f1 = 0x40012bb8 ); +PROVIDE ( r_lm_f2 = 0x40012cfc ); +PROVIDE ( r_lm_f3 = 0x40013050 ); +PROVIDE ( r_lm_g = 0x40012f90 ); +PROVIDE ( r_LM_GetAFHSwitchInstant = 0x4002f86c ); +PROVIDE ( r_lm_get_auth_en = 0x4004f1ac ); +PROVIDE ( r_lm_get_common_pkt_types = 0x4002fa1c ); +PROVIDE ( r_LM_GetConnectionAcceptTimeout = 0x4004f1f4 ); +PROVIDE ( r_LM_GetFeature = 0x4002f924 ); +PROVIDE ( r_LM_GetLinkTimeout = 0x400233ec ); +PROVIDE ( r_LM_GetLocalNameSeg = 0x4004f200 ); +PROVIDE ( r_lm_get_loopback_mode = 0x4004f248 ); +PROVIDE ( r_LM_GetMasterEncKeySize = 0x4001b29c ); +PROVIDE ( r_LM_GetMasterEncRand = 0x4001b288 ); +PROVIDE ( r_LM_GetMasterKey = 0x4001b260 ); +PROVIDE ( r_LM_GetMasterKeyRand = 0x4001b274 ); +PROVIDE ( r_lm_get_min_sync_intv = 0x400517a8 ); +PROVIDE ( r_lm_get_nb_acl = 0x4004ef9c ); +PROVIDE ( r_lm_get_nb_sync_link = 0x4005179c ); +PROVIDE ( r_lm_get_nonce = 0x400131c4 ); +PROVIDE ( r_lm_get_oob_local_commit = 0x4004f374 ); +PROVIDE ( r_lm_get_oob_local_data_192 = 0x4004f2d4 ); +PROVIDE ( r_lm_get_oob_local_data_256 = 0x4004f318 ); +PROVIDE ( r_LM_GetPINType = 0x4004f1e8 ); +PROVIDE ( r_lm_get_priv_key_192 = 0x4004f278 ); +PROVIDE ( r_lm_get_priv_key_256 = 0x4004f2b8 ); +PROVIDE ( r_lm_get_pub_key_192 = 0x4004f258 ); +PROVIDE ( r_lm_get_pub_key_256 = 0x4004f298 ); +PROVIDE ( r_LM_GetQoSParam = 0x4002f6e0 ); +PROVIDE ( r_lm_get_sec_con_host_supp = 0x4004f1d4 ); +PROVIDE ( r_LM_GetSniffSubratingParam = 0x4002325c ); +PROVIDE ( r_lm_get_sp_en = 0x4004f1c0 ); +PROVIDE ( r_LM_GetSwitchInstant = 0x4002f7f8 ); +PROVIDE ( r_lm_get_synchdl = 0x4005175c ); +PROVIDE ( r_lm_get_sync_param = 0x400503b4 ); +PROVIDE ( r_lm_init = 0x4004ed34 ); +PROVIDE ( r_lm_init_sync = 0x400512d8 ); +PROVIDE ( r_lm_is_acl_con = 0x4004f47c ); +PROVIDE ( r_lm_is_acl_con_role = 0x4004f49c ); +PROVIDE ( r_lm_is_clk_adj_ack_pending = 0x4004f4e8 ); +PROVIDE ( r_lm_is_clk_adj_instant_pending = 0x4004f4c8 ); +PROVIDE ( r_lm_local_ext_fr_configured = 0x4004f540 ); +PROVIDE ( r_lm_look_for_stored_link_key = 0x4002f948 ); +PROVIDE ( r_lm_look_for_sync = 0x40051774 ); +PROVIDE ( r_lm_lt_addr_alloc = 0x4004ef1c ); +PROVIDE ( r_lm_lt_addr_free = 0x4004ef74 ); +PROVIDE ( r_lm_lt_addr_reserve = 0x4004ef48 ); +PROVIDE ( r_LM_MakeCof = 0x4002f84c ); +PROVIDE ( r_LM_MakeRandVec = 0x400112d8 ); +PROVIDE ( r_lm_master_clk_adj_req_handler = 0x40054180 ); +PROVIDE ( r_LM_MaxSlot = 0x4002f694 ); +PROVIDE ( r_lm_modif_sync = 0x40051578 ); +PROVIDE ( r_lm_n_is_zero = 0x40012170 ); +PROVIDE ( r_lm_num_clk_adj_ack_pending_set = 0x4004f500 ); +PROVIDE ( r_lm_oob_f1 = 0x40012e54 ); +PROVIDE ( r_lm_pca_sscan_link_get = 0x4004f560 ); +PROVIDE ( r_lm_pca_sscan_link_set = 0x4004f550 ); +PROVIDE ( nvds_null_read = 0x400542a0 ); +PROVIDE ( nvds_null_write = 0x400542a8 ); +PROVIDE ( nvds_null_erase = 0x400542b0 ); +PROVIDE ( nvds_read = 0x400542c4 ); +PROVIDE ( nvds_write = 0x400542fc ); +PROVIDE ( nvds_erase = 0x40054334 ); +PROVIDE ( nvds_init_memory = 0x40054358 ); +PROVIDE ( r_lmp_pack = 0x4001135c ); +PROVIDE ( r_lmp_unpack = 0x4001149c ); +PROVIDE ( r_lm_read_features = 0x4004f0d8 ); +PROVIDE ( r_LM_RemoveSniff = 0x40023124 ); +PROVIDE ( r_LM_RemoveSniffSubrating = 0x400233c4 ); +PROVIDE ( r_lm_remove_sync = 0x400517c8 ); +PROVIDE ( r_lm_reset_sync = 0x40051304 ); +PROVIDE ( r_lm_role_switch_finished = 0x4004f028 ); +PROVIDE ( r_lm_role_switch_start = 0x4004efe0 ); +PROVIDE ( r_lm_sco_nego_end = 0x40051828 ); +PROVIDE ( r_LM_SniffSubrateNegoRequired = 0x40023334 ); +PROVIDE ( r_LM_SniffSubratingHlReq = 0x40023154 ); +PROVIDE ( r_LM_SniffSubratingPeerReq = 0x400231dc ); +PROVIDE ( r_lm_sp_debug_mode_get = 0x4004f398 ); +PROVIDE ( r_lm_sp_n192_convert_wnaf = 0x400123c0 ); +PROVIDE ( r_lm_sp_n_one = 0x400123a4 ); +PROVIDE ( r_lm_sp_p192_add = 0x40012828 ); +PROVIDE ( r_lm_sp_p192_dbl = 0x4001268c ); +PROVIDE ( r_lm_sp_p192_invert = 0x40012b6c ); +PROVIDE ( r_lm_sp_p192_point_jacobian_to_affine = 0x40012468 ); +PROVIDE ( r_lm_sp_p192_points_jacobian_to_affine = 0x400124e4 ); +PROVIDE ( r_lm_sp_p192_point_to_inf = 0x40012458 ); +PROVIDE ( r_lm_sp_pre_compute_points = 0x40012640 ); +PROVIDE ( r_lm_sp_sha256_calculate = 0x400121a0 ); +PROVIDE ( r_LM_SuppressAclPacket = 0x4002f658 ); +PROVIDE ( r_lm_sync_flow_ctrl_en_get = 0x4004f404 ); +PROVIDE ( r_LM_UpdateAclEdrPacketType = 0x4002f5d8 ); +PROVIDE ( r_LM_UpdateAclPacketType = 0x4002f584 ); +PROVIDE ( r_modules_funcs = 0x3ffafd6c ); +PROVIDE ( r_modules_funcs_p = 0x3ffafd68 ); +PROVIDE ( r_nvds_del = 0x400544c4 ); +PROVIDE ( r_nvds_get = 0x40054488 ); +PROVIDE ( r_nvds_init = 0x40054410 ); +PROVIDE ( r_nvds_lock = 0x400544fc ); +PROVIDE ( r_nvds_put = 0x40054534 ); +PROVIDE ( rom_abs_temp = 0x400054f0 ); +PROVIDE ( rom_bb_bss_bw_40_en = 0x4000401c ); +PROVIDE ( rom_bb_bss_cbw40_dig = 0x40003bac ); +PROVIDE ( rom_bb_rx_ht20_cen_bcov_en = 0x40003734 ); +PROVIDE ( rom_bb_tx_ht20_cen = 0x40003760 ); +PROVIDE ( rom_bb_wdg_test_en = 0x40003b70 ); +PROVIDE ( rom_cbw2040_cfg = 0x400040b0 ); +PROVIDE ( rom_check_noise_floor = 0x40003c78 ); +PROVIDE ( rom_chip_i2c_readReg = 0x40004110 ); +PROVIDE ( rom_chip_i2c_writeReg = 0x40004168 ); +PROVIDE ( rom_chip_v7_bt_init = 0x40004d8c ); +PROVIDE ( rom_chip_v7_rx_init = 0x40004cec ); +PROVIDE ( rom_chip_v7_rx_rifs_en = 0x40003d90 ); +PROVIDE ( rom_chip_v7_tx_init = 0x40004d18 ); +PROVIDE ( rom_clk_force_on_vit = 0x40003710 ); +PROVIDE ( rom_correct_rf_ana_gain = 0x400062a8 ); +PROVIDE ( rom_dc_iq_est = 0x400055c8 ); +PROVIDE ( rom_disable_agc = 0x40002fa4 ); +PROVIDE ( rom_enable_agc = 0x40002fcc ); +PROVIDE ( rom_en_pwdet = 0x4000506c ); +PROVIDE ( rom_gen_rx_gain_table = 0x40003e3c ); +PROVIDE ( rom_get_data_sat = 0x4000312c ); +PROVIDE ( rom_get_fm_sar_dout = 0x40005204 ); +PROVIDE ( rom_get_power_db = 0x40005fc8 ); +PROVIDE ( rom_get_pwctrl_correct = 0x400065d4 ); +PROVIDE ( rom_get_rfcal_rxiq_data = 0x40005bbc ); +PROVIDE ( rom_get_rf_gain_qdb = 0x40006290 ); +PROVIDE ( rom_get_sar_dout = 0x40006564 ); +PROVIDE ( rom_i2c_readreg = 0x40004148 ); +PROVIDE ( rom_i2c_readreg_Mask = 0x400041c0 ); +PROVIDE ( rom_i2c_writereg = 0x400041a4 ); +PROVIDE ( rom_i2c_writereg_Mask = 0x400041fc ); +PROVIDE ( rom_index_to_txbbgain = 0x40004df8 ); +PROVIDE ( rom_iq_est_disable = 0x40005590 ); +PROVIDE ( rom_iq_est_enable = 0x40005514 ); +PROVIDE ( rom_linear_to_db = 0x40005f64 ); +PROVIDE ( rom_loopback_mode_en = 0x400030f8 ); +PROVIDE ( rom_main = 0x400076c4 ); +PROVIDE ( rom_meas_tone_pwr_db = 0x40006004 ); +PROVIDE ( rom_mhz2ieee = 0x4000404c ); +PROVIDE ( rom_noise_floor_auto_set = 0x40003bdc ); +PROVIDE ( rom_pbus_debugmode = 0x40004458 ); +PROVIDE ( rom_pbus_force_mode = 0x40004270 ); +PROVIDE ( rom_pbus_force_test = 0x400043c0 ); +PROVIDE ( rom_pbus_rd = 0x40004414 ); +PROVIDE ( rom_pbus_rd_addr = 0x40004334 ); +PROVIDE ( rom_pbus_rd_shift = 0x40004374 ); +PROVIDE ( rom_pbus_rx_dco_cal = 0x40005620 ); +PROVIDE ( rom_pbus_set_dco = 0x40004638 ); +PROVIDE ( rom_pbus_set_rxgain = 0x40004480 ); +PROVIDE ( rom_pbus_workmode = 0x4000446c ); +PROVIDE ( rom_pbus_xpd_rx_off = 0x40004508 ); +PROVIDE ( rom_pbus_xpd_rx_on = 0x4000453c ); +PROVIDE ( rom_pbus_xpd_tx_off = 0x40004590 ); +PROVIDE ( rom_pbus_xpd_tx_on = 0x400045e0 ); +PROVIDE ( rom_phy_disable_agc = 0x40002f6c ); +PROVIDE ( rom_phy_disable_cca = 0x40003000 ); +PROVIDE ( rom_phy_enable_agc = 0x40002f88 ); +PROVIDE ( rom_phy_enable_cca = 0x4000302c ); +PROVIDE ( rom_phy_freq_correct = 0x40004b44 ); +PROVIDE ( rom_phyFuns = 0x3ffae0c0 ); +PROVIDE ( rom_phy_get_noisefloor = 0x40003c2c ); +PROVIDE ( rom_phy_get_vdd33 = 0x4000642c ); +PROVIDE ( rom_pow_usr = 0x40003044 ); +PROVIDE ( rom_read_sar_dout = 0x400051c0 ); +PROVIDE ( rom_restart_cal = 0x400046e0 ); +PROVIDE ( rom_rfcal_pwrctrl = 0x40006058 ); +PROVIDE ( rom_rfcal_rxiq = 0x40005b4c ); +PROVIDE ( rom_rfcal_txcap = 0x40005dec ); +PROVIDE ( rom_rfpll_reset = 0x40004680 ); +PROVIDE ( rom_rfpll_set_freq = 0x400047f8 ); +PROVIDE ( rom_rtc_mem_backup = 0x40003db4 ); +PROVIDE ( rom_rtc_mem_recovery = 0x40003df4 ); +PROVIDE ( rom_rx_gain_force = 0x4000351c ); +PROVIDE ( rom_rxiq_cover_mg_mp = 0x40005a68 ); +PROVIDE ( rom_rxiq_get_mis = 0x400058e4 ); +PROVIDE ( rom_rxiq_set_reg = 0x40005a00 ); +PROVIDE ( rom_set_cal_rxdc = 0x400030b8 ); +PROVIDE ( rom_set_chan_cal_interp = 0x40005ce0 ); +PROVIDE ( rom_set_channel_freq = 0x40004880 ); +PROVIDE ( rom_set_loopback_gain = 0x40003060 ); +PROVIDE ( rom_set_noise_floor = 0x40003d48 ); +PROVIDE ( rom_set_pbus_mem = 0x400031a4 ); +PROVIDE ( rom_set_rf_freq_offset = 0x40004ca8 ); +PROVIDE ( rom_set_rxclk_en = 0x40003594 ); +PROVIDE ( rom_set_txcap_reg = 0x40005d50 ); +PROVIDE ( rom_set_txclk_en = 0x40003564 ); +PROVIDE ( rom_spur_coef_cfg = 0x40003ac8 ); +PROVIDE ( rom_spur_reg_write_one_tone = 0x400037f0 ); +PROVIDE ( rom_start_tx_tone = 0x400036b4 ); +PROVIDE ( rom_start_tx_tone_step = 0x400035d0 ); +PROVIDE ( rom_stop_tx_tone = 0x40003f98 ); +PROVIDE ( _rom_store = 0x4000d66c ); +PROVIDE ( _rom_store_table = 0x4000d4f8 ); +PROVIDE ( rom_target_power_add_backoff = 0x40006268 ); +PROVIDE ( rom_tx_atten_set_interp = 0x400061cc ); +PROVIDE ( rom_txbbgain_to_index = 0x40004dc0 ); +PROVIDE ( rom_txcal_work_mode = 0x4000510c ); +PROVIDE ( rom_txdc_cal_init = 0x40004e10 ); +PROVIDE ( rom_txdc_cal_v70 = 0x40004ea4 ); +PROVIDE ( rom_txiq_cover = 0x4000538c ); +PROVIDE ( rom_txiq_get_mis_pwr = 0x400052dc ); +PROVIDE ( rom_txiq_set_reg = 0x40005154 ); +PROVIDE ( rom_tx_pwctrl_bg_init = 0x4000662c ); +PROVIDE ( rom_txtone_linear_pwr = 0x40005290 ); +PROVIDE ( rom_wait_rfpll_cal_end = 0x400047a8 ); +PROVIDE ( rom_write_gain_mem = 0x4000348c ); +PROVIDE ( rom_write_rfpll_sdm = 0x40004740 ); +PROVIDE ( roundup2 = 0x4000ab7c ); +PROVIDE ( r_plf_funcs_p = 0x3ffb8360 ); +PROVIDE ( r_rf_rw_bt_init = 0x40054868 ); +PROVIDE ( r_rf_rw_init = 0x40054b0c ); +PROVIDE ( r_rf_rw_le_init = 0x400549d0 ); +PROVIDE ( r_rwble_activity_ongoing_check = 0x40054d8c ); +PROVIDE ( r_rwble_init = 0x40054bf4 ); +PROVIDE ( r_rwble_isr = 0x40054e08 ); +PROVIDE ( r_rwble_reset = 0x40054ce8 ); +PROVIDE ( r_rwble_sleep_check = 0x40054d78 ); +PROVIDE ( r_rwble_version = 0x40054dac ); +PROVIDE ( r_rwbt_init = 0x40055160 ); +PROVIDE ( r_rwbt_isr = 0x40055248 ); +PROVIDE ( r_rwbt_reset = 0x400551bc ); +PROVIDE ( r_rwbt_sleep_check = 0x4005577c ); +PROVIDE ( r_rwbt_sleep_enter = 0x400557a4 ); +PROVIDE ( r_rwbt_sleep_wakeup = 0x400557fc ); +PROVIDE ( r_rwbt_sleep_wakeup_end = 0x400558cc ); +PROVIDE ( r_rwbt_version = 0x4005520c ); +PROVIDE ( r_rwip_assert_err = 0x40055f88 ); +PROVIDE ( r_rwip_check_wakeup_boundary = 0x400558fc ); +PROVIDE ( r_rwip_ext_wakeup_enable = 0x40055f3c ); +PROVIDE ( r_rwip_init = 0x4005595c ); +PROVIDE ( r_rwip_pca_clock_dragging_only = 0x40055f48 ); +PROVIDE ( r_rwip_prevent_sleep_clear = 0x40055ec8 ); +PROVIDE ( r_rwip_prevent_sleep_set = 0x40055e64 ); +PROVIDE ( r_rwip_reset = 0x40055ab8 ); +PROVIDE ( r_rwip_schedule = 0x40055b38 ); +PROVIDE ( r_rwip_sleep = 0x40055b5c ); +PROVIDE ( r_rwip_sleep_enable = 0x40055f30 ); +PROVIDE ( r_rwip_version = 0x40055b20 ); +PROVIDE ( r_rwip_wakeup = 0x40055dc4 ); +PROVIDE ( r_rwip_wakeup_delay_set = 0x40055e4c ); +PROVIDE ( r_rwip_wakeup_end = 0x40055e18 ); +PROVIDE ( r_rwip_wlcoex_set = 0x40055f60 ); +PROVIDE ( r_SHA_256 = 0x40013a90 ); +PROVIDE ( rtc_boot_control = 0x4000821c ); +PROVIDE ( rtc_get_reset_reason = 0x400081d4 ); +PROVIDE ( rtc_get_wakeup_cause = 0x400081f4 ); +PROVIDE ( rtc_select_apb_bridge = 0x40008288 ); +PROVIDE ( rwip_coex_cfg = 0x3ff9914c ); +PROVIDE ( rwip_priority = 0x3ff99159 ); +PROVIDE ( rwip_rf = 0x3ffbdb28 ); +PROVIDE ( rwip_rf_p_get = 0x400558f4 ); +PROVIDE ( r_XorKey = 0x400112c0 ); +PROVIDE ( sbrk = 0x400017f4 ); +PROVIDE ( _sbrk_r = 0x4000bce4 ); +PROVIDE ( scanf = 0x40058760 ); +PROVIDE ( _scanf_chars = 0x40058384 ); +PROVIDE ( _scanf_float = 0x4000bf18 ); +PROVIDE ( _scanf_i = 0x4005845c ); +PROVIDE ( _scanf_r = 0x4005879c ); +PROVIDE ( __sccl = 0x4000c498 ); +PROVIDE ( __sclose = 0x400011b8 ); +PROVIDE ( SelectSpiFunction = 0x40061f84 ); +PROVIDE ( SelectSpiQIO = 0x40061ddc ); +PROVIDE ( SendMsg = 0x40009384 ); +PROVIDE ( send_packet = 0x40009340 ); +PROVIDE ( __seofread = 0x40001148 ); +PROVIDE ( setjmp = 0x40056268 ); +PROVIDE ( setlocale = 0x40059568 ); +PROVIDE ( _setlocale_r = 0x4005950c ); +PROVIDE ( set_rtc_memory_crc = 0x40008208 ); +PROVIDE ( SetSpiDrvs = 0x40061e78 ); +PROVIDE ( __sf_fake_stderr = 0x3ff96458 ); +PROVIDE ( __sf_fake_stdin = 0x3ff96498 ); +PROVIDE ( __sf_fake_stdout = 0x3ff96478 ); +PROVIDE ( __sflush_r = 0x400591e0 ); +PROVIDE ( __sfmoreglue = 0x40001dc8 ); +PROVIDE ( __sfp = 0x40001e90 ); +PROVIDE ( __sfp_lock_acquire = 0x40001e08 ); +PROVIDE ( __sfp_lock_release = 0x40001e14 ); +PROVIDE ( __sfputs_r = 0x40057790 ); +PROVIDE ( __sfvwrite_r = 0x4005893c ); +PROVIDE ( sha1_prf = 0x40060ae8 ); +PROVIDE ( sha1_vector = 0x40060b64 ); +PROVIDE ( sha256_prf = 0x40060d70 ); +PROVIDE ( sha256_vector = 0x40060e08 ); +PROVIDE ( sha_blk_bits = 0x3ff99290 ); +PROVIDE ( sha_blk_bits_bytes = 0x3ff99288 ); +PROVIDE ( sha_blk_hash_bytes = 0x3ff9928c ); +PROVIDE ( sig_matrix = 0x3ffae293 ); +PROVIDE ( __sinit = 0x40001e38 ); +PROVIDE ( __sinit_lock_acquire = 0x40001e20 ); +PROVIDE ( __sinit_lock_release = 0x40001e2c ); +PROVIDE ( sip_after_tx_complete = 0x4000b358 ); +PROVIDE ( sip_alloc_to_host_evt = 0x4000ab9c ); +PROVIDE ( sip_get_ptr = 0x4000b34c ); +PROVIDE ( sip_get_state = 0x4000ae2c ); +PROVIDE ( sip_init_attach = 0x4000ae58 ); +PROVIDE ( sip_install_rx_ctrl_cb = 0x4000ae10 ); +PROVIDE ( sip_install_rx_data_cb = 0x4000ae20 ); +PROVIDE ( sip_is_active = 0x4000b3c0 ); +PROVIDE ( sip_post_init = 0x4000aed8 ); +PROVIDE ( sip_reclaim_from_host_cmd = 0x4000adbc ); +PROVIDE ( sip_reclaim_tx_data_pkt = 0x4000ad5c ); +PROVIDE ( siprintf = 0x40056c08 ); +PROVIDE ( _siprintf_r = 0x40056bbc ); +PROVIDE ( sip_send = 0x4000af54 ); +PROVIDE ( sip_to_host_chain_append = 0x4000aef8 ); +PROVIDE ( sip_to_host_evt_send_done = 0x4000ac04 ); +PROVIDE ( siscanf = 0x400587d0 ); +PROVIDE ( _siscanf_r = 0x40058830 ); +PROVIDE ( slc_add_credits = 0x4000baf4 ); +PROVIDE ( slc_enable = 0x4000b64c ); +PROVIDE ( slc_from_host_chain_fetch = 0x4000b7e8 ); +PROVIDE ( slc_from_host_chain_recycle = 0x4000bb10 ); +PROVIDE ( slc_has_pkt_to_host = 0x4000b5fc ); +PROVIDE ( slc_init_attach = 0x4000b918 ); +PROVIDE ( slc_init_credit = 0x4000badc ); +PROVIDE ( slc_reattach = 0x4000b62c ); +PROVIDE ( slc_send_to_host_chain = 0x4000b6a0 ); +PROVIDE ( slc_set_host_io_max_window = 0x4000b89c ); +PROVIDE ( slc_to_host_chain_recycle = 0x4000b758 ); +PROVIDE ( __smakebuf_r = 0x40059108 ); +PROVIDE ( sniprintf = 0x40056b4c ); +PROVIDE ( _sniprintf_r = 0x40056ae4 ); +PROVIDE ( snprintf = 0x40056b4c ); +PROVIDE ( _snprintf_r = 0x40056ae4 ); +PROVIDE ( software_reset = 0x4000824c ); +PROVIDE ( software_reset_cpu = 0x40008264 ); +PROVIDE ( specialModP256 = 0x4001600c ); +PROVIDE ( spi_cache_sram_init = 0x400626e4 ); +PROVIDE ( SPIClkConfig = 0x40062bc8 ); +PROVIDE ( SPI_Common_Command = 0x4006246c ); +PROVIDE ( spi_dummy_len_fix = 0x40061d90 ); +PROVIDE ( SPI_Encrypt_Write = 0x40062e78 ); +PROVIDE ( SPIEraseArea = 0x400631ac ); +PROVIDE ( SPIEraseBlock = 0x40062c4c ); +PROVIDE ( SPIEraseChip = 0x40062c14 ); +PROVIDE ( SPIEraseSector = 0x40062ccc ); +PROVIDE ( spi_flash_attach = 0x40062a6c ); +PROVIDE ( SPILock = 0x400628f0 ); +PROVIDE ( SPIMasterReadModeCnfig = 0x40062b64 ); +PROVIDE ( spi_modes = 0x3ff99270 ); +PROVIDE ( SPIParamCfg = 0x40063238 ); +PROVIDE ( SPI_Prepare_Encrypt_Data = 0x40062e1c ); +PROVIDE ( SPIRead = 0x40062ed8 ); +PROVIDE ( SPIReadModeCnfig = 0x40062944 ); +/* This is static function, but can be used, not generated by script*/ +PROVIDE ( SPI_read_status = 0x4006226c ); +/* This is static function, but can be used, not generated by script*/ +PROVIDE ( SPI_read_status_high = 0x40062448 ); +PROVIDE ( SPIUnlock = 0x400628b0 ); +PROVIDE ( SPI_user_command_read = 0x400621b0 ); +PROVIDE ( spi_w25q16 = 0x3ffae270 ); +PROVIDE ( SPIWrite = 0x40062d50 ); +/* This is static function, but can be used, not generated by script*/ +PROVIDE ( SPI_write_enable = 0x40062320 ); +PROVIDE ( SPI_Write_Encrypt_Disable = 0x40062e60 ); +PROVIDE ( SPI_Write_Encrypt_Enable = 0x40062df4 ); +/* This is static function, but can be used, not generated by script*/ +PROVIDE ( SPI_write_status = 0x400622f0 ); +PROVIDE ( sprintf = 0x40056c08 ); +PROVIDE ( _sprintf_r = 0x40056bbc ); +PROVIDE ( __sprint_r = 0x400577e4 ); +PROVIDE ( srand = 0x40001004 ); +PROVIDE ( __sread = 0x40001118 ); +PROVIDE ( __srefill_r = 0x400593d4 ); +PROVIDE ( sscanf = 0x400587d0 ); +PROVIDE ( _sscanf_r = 0x40058830 ); +PROVIDE ( __sseek = 0x40001184 ); +PROVIDE ( __ssprint_r = 0x40056ff8 ); +PROVIDE ( __ssputs_r = 0x40056f2c ); +PROVIDE ( __ssrefill_r = 0x40057fec ); +PROVIDE ( __ssvfiscanf_r = 0x4005802c ); +PROVIDE ( __ssvfscanf_r = 0x4005802c ); +PROVIDE ( __stack = 0x3ffe3f20 ); +PROVIDE ( __stack_app = 0x3ffe7e30 ); +PROVIDE ( _stack_sentry = 0x3ffe1320 ); +PROVIDE ( _stack_sentry_app = 0x3ffe5230 ); +PROVIDE ( _start = 0x40000704 ); +PROVIDE ( start_tb_console = 0x4005a980 ); +PROVIDE ( _stat_r = 0x4000bcb4 ); +PROVIDE ( _stext = 0x40000560 ); +PROVIDE ( strcasecmp = 0x400011cc ); +PROVIDE ( strcasestr = 0x40001210 ); +PROVIDE ( strcat = 0x4000c518 ); +PROVIDE ( strchr = 0x4000c53c ); +PROVIDE ( strcmp = 0x40001274 ); +PROVIDE ( strcoll = 0x40001398 ); +PROVIDE ( strcpy = 0x400013ac ); +PROVIDE ( strcspn = 0x4000c558 ); +PROVIDE ( strdup = 0x4000143c ); +PROVIDE ( _strdup_r = 0x40001450 ); +PROVIDE ( strftime = 0x40059ab4 ); +PROVIDE ( strlcat = 0x40001470 ); +PROVIDE ( strlcpy = 0x4000c584 ); +PROVIDE ( strlen = 0x400014c0 ); +PROVIDE ( strlwr = 0x40001524 ); +PROVIDE ( strncasecmp = 0x40001550 ); +PROVIDE ( strncat = 0x4000c5c4 ); +PROVIDE ( strncmp = 0x4000c5f4 ); +PROVIDE ( strncpy = 0x400015d4 ); +PROVIDE ( strndup = 0x400016b0 ); +PROVIDE ( _strndup_r = 0x400016c4 ); +PROVIDE ( strnlen = 0x4000c628 ); +PROVIDE ( strrchr = 0x40001708 ); +PROVIDE ( strsep = 0x40001734 ); +PROVIDE ( strspn = 0x4000c648 ); +PROVIDE ( strstr = 0x4000c674 ); +PROVIDE ( __strtok_r = 0x4000c6a8 ); +PROVIDE ( strtok_r = 0x4000c70c ); +PROVIDE ( strtol = 0x4005681c ); +PROVIDE ( _strtol_r = 0x40056714 ); +PROVIDE ( strtoul = 0x4005692c ); +PROVIDE ( _strtoul_r = 0x40056834 ); +PROVIDE ( strupr = 0x4000174c ); +PROVIDE ( __submore = 0x40058f3c ); +PROVIDE ( SubtractBigHex256 = 0x40015bcc ); +PROVIDE ( SubtractBigHexMod256 = 0x40015e8c ); +PROVIDE ( SubtractBigHexUint32_256 = 0x40015f8c ); +PROVIDE ( SubtractFromSelfBigHex256 = 0x40015c20 ); +PROVIDE ( SubtractFromSelfBigHexSign256 = 0x40015dc8 ); +PROVIDE ( _sungetc_r = 0x40057f6c ); +PROVIDE ( _svfiprintf_r = 0x40057100 ); +PROVIDE ( __svfiscanf_r = 0x40057b08 ); +PROVIDE ( _svfprintf_r = 0x40057100 ); +PROVIDE ( __svfscanf = 0x40057f04 ); +PROVIDE ( __svfscanf_r = 0x40057b08 ); +PROVIDE ( __swbuf = 0x40058cb4 ); +PROVIDE ( __swbuf_r = 0x40058bec ); +PROVIDE ( __swrite = 0x40001150 ); +PROVIDE ( __swsetup_r = 0x40058cc8 ); +PROVIDE ( sw_to_hw = 0x3ffb8d40 ); +PROVIDE ( _SyscallException = 0x400007cf ); +PROVIDE ( syscall_table_ptr_app = 0x3ffae020 ); +PROVIDE ( syscall_table_ptr_pro = 0x3ffae024 ); +PROVIDE ( _system_r = 0x4000bc10 ); +PROVIDE ( tdefl_compress = 0x400600bc ); +PROVIDE ( tdefl_compress_buffer = 0x400607f4 ); +PROVIDE ( tdefl_compress_mem_to_mem = 0x40060900 ); +PROVIDE ( tdefl_compress_mem_to_output = 0x400608e0 ); +PROVIDE ( tdefl_get_adler32 = 0x400608d8 ); +PROVIDE ( tdefl_get_prev_return_status = 0x400608d0 ); +PROVIDE ( tdefl_init = 0x40060810 ); +PROVIDE ( tdefl_write_image_to_png_file_in_memory = 0x4006091c ); +PROVIDE ( tdefl_write_image_to_png_file_in_memory_ex = 0x40060910 ); +PROVIDE ( time = 0x40001844 ); +PROVIDE ( __time_load_locale = 0x4000183c ); +PROVIDE ( times = 0x40001808 ); +PROVIDE ( _times_r = 0x4000bc40 ); +PROVIDE ( _timezone = 0x3ffae0a0 ); +PROVIDE ( tinfl_decompress = 0x4005ef30 ); +PROVIDE ( tinfl_decompress_mem_to_callback = 0x40060090 ); +PROVIDE ( tinfl_decompress_mem_to_mem = 0x40060050 ); +PROVIDE ( toascii = 0x4000c720 ); +PROVIDE ( tolower = 0x40001868 ); +PROVIDE ( toupper = 0x40001884 ); +PROVIDE ( __tzcalc_limits = 0x400018a0 ); +PROVIDE ( __tz_lock = 0x40001a04 ); +PROVIDE ( _tzname = 0x3ffae030 ); +PROVIDE ( tzset = 0x40001a1c ); +PROVIDE ( _tzset_r = 0x40001a28 ); +PROVIDE ( __tz_unlock = 0x40001a10 ); +PROVIDE ( uartAttach = 0x40008fd0 ); +PROVIDE ( uart_baudrate_detect = 0x40009034 ); +PROVIDE ( uart_buff_switch = 0x400093c0 ); +PROVIDE ( UartConnCheck = 0x40008738 ); +PROVIDE ( UartConnectProc = 0x40008a04 ); +PROVIDE ( UartDev = 0x3ffe019c ); +PROVIDE ( uart_div_modify = 0x400090cc ); +PROVIDE ( UartDwnLdProc = 0x40008ce8 ); +PROVIDE ( UartGetCmdLn = 0x40009564 ); +PROVIDE ( Uart_Init = 0x40009120 ); +PROVIDE ( UartRegReadProc = 0x40008a58 ); +PROVIDE ( UartRegWriteProc = 0x40008a14 ); +PROVIDE ( uart_rx_intr_handler = 0x40008f4c ); +PROVIDE ( uart_rx_one_char = 0x400092d0 ); +PROVIDE ( uart_rx_one_char_block = 0x400092a4 ); +PROVIDE ( uart_rx_readbuff = 0x40009394 ); +PROVIDE ( UartRxString = 0x400092fc ); +PROVIDE ( UartSetBaudProc = 0x40008aac ); +PROVIDE ( UartSpiAttachProc = 0x40008a6c ); +PROVIDE ( UartSpiReadProc = 0x40008a80 ); +PROVIDE ( uart_tx_flush = 0x40009258 ); +PROVIDE ( uart_tx_one_char = 0x40009200 ); +PROVIDE ( uart_tx_one_char2 = 0x4000922c ); +PROVIDE ( uart_tx_switch = 0x40009028 ); +PROVIDE ( uart_tx_wait_idle = 0x40009278 ); +PROVIDE ( ungetc = 0x400590f4 ); +PROVIDE ( _ungetc_r = 0x40058fa0 ); +PROVIDE ( _unlink_r = 0x4000bc84 ); +PROVIDE ( user_code_start = 0x3ffe0400 ); +PROVIDE ( _UserExceptionVector = 0x40000340 ); +PROVIDE ( utoa = 0x40056258 ); +PROVIDE ( __utoa = 0x400561f0 ); +PROVIDE ( vasiprintf = 0x40056eb8 ); +PROVIDE ( _vasiprintf_r = 0x40056e80 ); +PROVIDE ( vasniprintf = 0x40056e58 ); +PROVIDE ( _vasniprintf_r = 0x40056df8 ); +PROVIDE ( vasnprintf = 0x40056e58 ); +PROVIDE ( _vasnprintf_r = 0x40056df8 ); +PROVIDE ( vasprintf = 0x40056eb8 ); +PROVIDE ( _vasprintf_r = 0x40056e80 ); +PROVIDE ( VerifyFlashMd5Proc = 0x40008c44 ); +PROVIDE ( veryBigHexP256 = 0x3ff9736c ); +PROVIDE ( vfiprintf = 0x40057ae8 ); +PROVIDE ( _vfiprintf_r = 0x40057850 ); +PROVIDE ( vfiscanf = 0x40057eb8 ); +PROVIDE ( _vfiscanf_r = 0x40057f24 ); +PROVIDE ( vfprintf = 0x40057ae8 ); +PROVIDE ( _vfprintf_r = 0x40057850 ); +PROVIDE ( vfscanf = 0x40057eb8 ); +PROVIDE ( _vfscanf_r = 0x40057f24 ); +PROVIDE ( viprintf = 0x400569b4 ); +PROVIDE ( _viprintf_r = 0x400569e4 ); +PROVIDE ( viscanf = 0x40058698 ); +PROVIDE ( _viscanf_r = 0x400586c8 ); +PROVIDE ( vprintf = 0x400569b4 ); +PROVIDE ( _vprintf_r = 0x400569e4 ); +PROVIDE ( vscanf = 0x40058698 ); +PROVIDE ( _vscanf_r = 0x400586c8 ); +PROVIDE ( vsiprintf = 0x40056ac4 ); +PROVIDE ( _vsiprintf_r = 0x40056a90 ); +PROVIDE ( vsiscanf = 0x40058740 ); +PROVIDE ( _vsiscanf_r = 0x400586f8 ); +PROVIDE ( vsniprintf = 0x40056a68 ); +PROVIDE ( _vsniprintf_r = 0x40056a14 ); +PROVIDE ( vsnprintf = 0x40056a68 ); +PROVIDE ( _vsnprintf_r = 0x40056a14 ); +PROVIDE ( vsprintf = 0x40056ac4 ); +PROVIDE ( _vsprintf_r = 0x40056a90 ); +PROVIDE ( vsscanf = 0x40058740 ); +PROVIDE ( _vsscanf_r = 0x400586f8 ); +PROVIDE ( wcrtomb = 0x40058920 ); +PROVIDE ( _wcrtomb_r = 0x400588d8 ); +PROVIDE ( __wctomb = 0x3ff96540 ); +PROVIDE ( _wctomb_r = 0x40058f14 ); +PROVIDE ( _WindowOverflow12 = 0x40000100 ); +PROVIDE ( _WindowOverflow4 = 0x40000000 ); +PROVIDE ( _WindowOverflow8 = 0x40000080 ); +PROVIDE ( _WindowUnderflow12 = 0x40000140 ); +PROVIDE ( _WindowUnderflow4 = 0x40000040 ); +PROVIDE ( _WindowUnderflow8 = 0x400000c0 ); +PROVIDE ( write = 0x4000181c ); +PROVIDE ( _write_r = 0x4000bd70 ); +PROVIDE ( xthal_bcopy = 0x4000c098 ); +PROVIDE ( xthal_copy123 = 0x4000c124 ); +PROVIDE ( xthal_get_ccompare = 0x4000c078 ); +PROVIDE ( xthal_get_ccount = 0x4000c050 ); +PROVIDE ( xthal_get_interrupt = 0x4000c1e4 ); +PROVIDE ( xthal_get_intread = 0x4000c1e4 ); +PROVIDE ( Xthal_intlevel = 0x3ff9c2b4 ); +PROVIDE ( xthal_memcpy = 0x4000c0bc ); +PROVIDE ( xthal_set_ccompare = 0x4000c058 ); +PROVIDE ( xthal_set_intclear = 0x4000c1ec ); +PROVIDE ( _xtos_set_intlevel = 0x4000bfdc ); +PROVIDE ( g_ticks_per_us_pro = 0x3ffe01e0 ); +PROVIDE ( g_ticks_per_us_app = 0x3ffe40f0 ); +PROVIDE ( esp_rom_spiflash_config_param = 0x40063238 ); +PROVIDE ( esp_rom_spiflash_read_user_cmd = 0x400621b0 ); +PROVIDE ( esp_rom_spiflash_write_encrypted_disable = 0x40062e60 ); +PROVIDE ( esp_rom_spiflash_write_encrypted_enable = 0x40062df4 ); +PROVIDE ( esp_rom_spiflash_prepare_encrypted_data = 0x40062e1c ); +PROVIDE ( esp_rom_spiflash_select_qio_pins = 0x40061ddc ); +PROVIDE ( esp_rom_spiflash_attach = 0x40062a6c ); +PROVIDE ( esp_rom_spiflash_config_clk = 0x40062bc8 ); +PROVIDE ( g_rom_spiflash_chip = 0x3ffae270 ); +PROVIDE ( hci_le_rd_rem_used_feats_cmd_handler = 0x400417b4 ); +PROVIDE ( llcp_length_req_handler = 0x40043808 ); +PROVIDE ( llcp_unknown_rsp_handler = 0x40043ba8 ); +PROVIDE ( llcp_channel_map_req_handler = 0x4004291c ); +PROVIDE ( llcp_con_up_req_handler = 0x400426f0 ); +PROVIDE ( _xtos_alloca_handler = 0x40000010 ); +PROVIDE ( _xtos_cause3_handler = 0x40000dd8 ); +PROVIDE ( _xtos_c_handler_table = 0x3ffe0548 ); +PROVIDE ( _xtos_c_wrapper_handler = 0x40000de8 ); +PROVIDE ( _xtos_enabled = 0x3ffe0650 ); +PROVIDE ( _xtos_exc_handler_table = 0x3ffe0448 ); +PROVIDE ( _xtos_interrupt_mask_table = 0x3ffe0758 ); +PROVIDE ( _xtos_interrupt_table = 0x3ffe0658 ); +PROVIDE ( _xtos_ints_off = 0x4000bfac ); +PROVIDE ( _xtos_ints_on = 0x4000bf88 ); +PROVIDE ( _xtos_intstruct = 0x3ffe0650 ); +PROVIDE ( _xtos_l1int_handler = 0x40000814 ); +PROVIDE ( _xtos_p_none = 0x4000bfd4 ); +PROVIDE ( _xtos_restore_intlevel = 0x40000928 ); +PROVIDE ( _xtos_return_from_exc = 0x4000c034 ); +PROVIDE ( _xtos_set_exception_handler = 0x4000074c ); +PROVIDE ( _xtos_set_interrupt_handler = 0x4000bf78 ); +PROVIDE ( _xtos_set_interrupt_handler_arg = 0x4000bf34 ); +PROVIDE ( _xtos_set_intlevel = 0x4000bfdc ); +PROVIDE ( _xtos_set_min_intlevel = 0x4000bff8 ); +PROVIDE ( _xtos_set_vpri = 0x40000934 ); +PROVIDE ( _xtos_syscall_handler = 0x40000790 ); +PROVIDE ( _xtos_unhandled_exception = 0x4000c024 ); +PROVIDE ( _xtos_unhandled_interrupt = 0x4000c01c ); +PROVIDE ( _xtos_vpri_enabled = 0x3ffe0654 ); +PROVIDE ( g_rom_flashchip = 0x3ffae270 ); +PROVIDE ( g_rom_spiflash_dummy_len_plus = 0x3ffae290 ); +PROVIDE ( esp_rom_spiflash_read_user_cmd = 0x400621b0 ); +PROVIDE ( esp_rom_spiflash_write_encrypted_enable = 0x40062df4 ); +PROVIDE ( esp_rom_spiflash_write_encrypted_disable = 0x40062e60 ); +PROVIDE ( esp_rom_spiflash_prepare_encrypted_data = 0x40062e1c ); + +PROVIDE ( esp_rom_printf = ets_printf ); +PROVIDE ( esp_rom_delay_us = ets_delay_us ); + +/* Following are static data, but can be used, not generated by script <<<<< btdm data */ + +PROVIDE ( hci_tl_env = 0x3ffb8154 ); +PROVIDE ( ld_acl_env = 0x3ffb8258 ); +PROVIDE ( ea_env = 0x3ffb80ec ); +PROVIDE ( lc_sco_data_path_config = 0x3ffb81f8 ); +PROVIDE ( lc_sco_env = 0x3ffb81fc ); +PROVIDE ( ld_active_ch_map = 0x3ffb8334 ); +PROVIDE ( ld_bcst_acl_env = 0x3ffb8274 ); +PROVIDE ( ld_csb_rx_env = 0x3ffb8278 ); +PROVIDE ( ld_csb_tx_env = 0x3ffb827c ); +PROVIDE ( ld_env = 0x3ffb9510 ); +PROVIDE ( ld_fm_env = 0x3ffb8284 ); +PROVIDE ( ld_inq_env = 0x3ffb82e4 ); +PROVIDE ( ld_iscan_env = 0x3ffb82e8 ); +PROVIDE ( ld_page_env = 0x3ffb82f0 ); +PROVIDE ( ld_pca_env = 0x3ffb82f4 ); +PROVIDE ( ld_pscan_env = 0x3ffb8308 ); +PROVIDE ( ld_sched_env = 0x3ffb830c ); +PROVIDE ( ld_sched_params = 0x3ffb96c0 ); +PROVIDE ( ld_sco_env = 0x3ffb824c ); +PROVIDE ( ld_sscan_env = 0x3ffb832c ); +PROVIDE ( ld_strain_env = 0x3ffb8330 ); +PROVIDE ( LM_Sniff = 0x3ffb8230 ); +PROVIDE ( LM_SniffSubRate = 0x3ffb8214 ); +PROVIDE ( prbs_64bytes = 0x3ff98992 ); +PROVIDE ( nvds_env = 0x3ffb8364 ); +PROVIDE ( nvds_magic_number = 0x3ff9912a ); +PROVIDE ( TASK_DESC_LLD = 0x3ff98b58 ); +/* Above are static data, but can be used, not generated by script >>>>> btdm data */ diff --git a/boards/espressif/esp32/nuttx-config/scripts/script.ld b/boards/espressif/esp32/nuttx-config/scripts/script.ld new file mode 100644 index 00000000000..d0d5e8c498f --- /dev/null +++ b/boards/espressif/esp32/nuttx-config/scripts/script.ld @@ -0,0 +1,78 @@ +/**************************************************************************** + * boards/xtensa/esp32/common/scripts/esp32.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Default entry point: */ + + +MEMORY +{ + /* Below values assume the flash cache is on, and have the blocks this + * uses subtracted from the length of the various regions. The 'data access + * port' dram/drom regions map to the same iram/irom regions but are + * connected to the data port of the CPU and e.g. allow bytewise access. + */ + /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */ + iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 + /* Flash mapped instruction data. */ + /* The 0x20 offset is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB). + */ + irom0_0_seg (RX) : org = 0x400d0020, len = 0x330000 - 0x20 + /* Shared data RAM, excluding memory reserved for ROM bss/data/stack. + * Enabling Bluetooth & Trace Memory features in menuconfig will decrease + * the amount of RAM available. + * + * Note: The length of this section should be 0x50000, and this extra + * DRAM is available in heap at runtime. However due to static ROM memory + * usage at this 176KB mark, the additional static memory temporarily cannot + * be used. + */ + dram0_0_seg (RW) : org = 0x3ffb0000 + 0, + len = 0x2c200 - 0 - 0 + /* Flash mapped constant data */ + /* The 0x20 offset is a convenience for the app binary image generation. + * Flash cache has 64KB pages. The .bin file which is flashed to the chip + * has a 0x18 byte file header, and each segment has a 0x08 byte segment + * header. Setting this offset makes it simple to meet the flash cache MMU's + * constraint that (paddr % 64KB == vaddr % 64KB). + */ + drom0_0_seg (R) : org = 0x3f400020, len = 0x400000 - 0x20 + /* RTC fast memory (executable). Persists over deep sleep. */ + rtc_iram_seg (RWX) : org = 0x400c0000, len = 0x2000 + /* RTC slow memory (data accessible). Persists over deep sleep. + * Start of RTC slow memory is reserved for ULP co-processor code + data, + * if enabled. + */ + rtc_slow_seg (RW) : org = 0x50000000 + 0, + len = 0x1000 - 0 + /* External memory, including data and text */ + extmem_seg (RWX) : org = 0x3f800000, len = 0x400000 +} + REGION_ALIAS("default_rodata_seg", drom0_0_seg); + REGION_ALIAS("default_code_seg", irom0_0_seg); +/* Heap ends at top of dram0_0_seg */ +_eheap = 0x40000000 - 0; +/* IRAM heap ends at top of dram0_0_seg */ +_eiramheap = 0x400a0000; +/* Mark the end of the RTC heap (top of the RTC region) */ +_ertcheap = 0x50001fff; diff --git a/boards/espressif/esp32/nuttx-config/src/Make.defs b/boards/espressif/esp32/nuttx-config/src/Make.defs new file mode 100644 index 00000000000..f4948996cba --- /dev/null +++ b/boards/espressif/esp32/nuttx-config/src/Make.defs @@ -0,0 +1,72 @@ +############################################################################ +# boards/xtensa/esp32/esp32-devkitc/scripts/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/tools/esp32/Config.mk +include $(TOPDIR)/arch/xtensa/src/lx6/Toolchain.defs + +ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32_rom.ld + +# Pick the linker scripts from the board level if they exist, if not +# pick the common linker scripts. + +ifeq ($(CONFIG_BUILD_PROTECTED),y) + ARCHSCRIPT += $(call FINDSCRIPT,protected_memory.ld) + ARCHSCRIPT += $(call FINDSCRIPT,kernel-space.ld) +else + ARCHSCRIPT += $(call FINDSCRIPT,flat_memory.ld) + + ifeq ($(CONFIG_ESP32_APP_FORMAT_MCUBOOT),y) + ARCHSCRIPT += $(call FINDSCRIPT,mcuboot_sections.ld) + else + ARCHSCRIPT += $(call FINDSCRIPT,legacy_sections.ld) + endif +endif + +ARCHPICFLAGS = -fpic + +# if SPIRAM/PSRAM is used then we need to include a workaround + +ifeq ($(CONFIG_ESP32_SPIRAM),y) + ARCHCFLAGS += -mfix-esp32-psram-cache-issue +endif + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ + +# Loadable module definitions + +CMODULEFLAGS = $(CFLAGS) -mtext-section-literals + +LDMODULEFLAGS = -r -e module_initialize +LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) + +# ELF module definitions + +CELFFLAGS = $(CFLAGS) -mtext-section-literals +CXXELFFLAGS = $(CXXFLAGS) -mtext-section-literals + +LDELFFLAGS = -r -e main +LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)libelf$(DELIM)gnu-elf.ld) diff --git a/boards/espressif/esp32/src/CMakeLists.txt b/boards/espressif/esp32/src/CMakeLists.txt new file mode 100644 index 00000000000..7020b0503ce --- /dev/null +++ b/boards/espressif/esp32/src/CMakeLists.txt @@ -0,0 +1,54 @@ +############################################################################ +# +# Copyright (c) 2021 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_library(drivers_board + i2c.cpp + init.c + led.c + spi.cpp + timer_config.cpp + # usb.c + esp32_board_spiflash.c + esp32_board_wlan_setup.c + mtd.cpp +) + +target_link_libraries(drivers_board + PRIVATE + arch_io_pins + arch_spi + drivers__led # drv_led_start + nuttx_arch # sdio + nuttx_drivers # sdio + px4_layer +) diff --git a/boards/espressif/esp32/src/board_config.h b/boards/espressif/esp32/src/board_config.h new file mode 100644 index 00000000000..bac76ef037a --- /dev/null +++ b/boards/espressif/esp32/src/board_config.h @@ -0,0 +1,120 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_config.h + * + * board internal definitions + */ + +#pragma once + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include +#include +#include + +/* LEDs */ +#define GPIO_LED_BLUE 4 | GPIO_OUTPUT + +/* GPIOs available*/ +#define GPIO_1 4 | GPIO_OUTPUT +#define GPIO_2 4 | GPIO_OUTPUT +#define GPIO_3 4 | GPIO_OUTPUT +#define GPIO_4 4 | GPIO_OUTPUT + +#define PX4_NUMBER_I2C_BUSES 2 + +#define BOARD_SPI_BUS_MAX_BUS_ITEMS 2 + +/* + * ADC channels + * + * These are the channel numbers of the ADCs of the microcontroller that can be used by the Px4 Firmware in the adc driver + */ +#define ADC_CHANNELS (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) // Change this later based on the adc channels actually used + +#define ADC_BATTERY_VOLTAGE_CHANNEL 1 // Corresponding GPIO 27. Used in init.c for disabling GPIO_IE +#define ADC_BATTERY_CURRENT_CHANNEL 2 // Corresponding GPIO 28. Used in init.c for disabling GPIO_IE +#define ADC_RC_RSSI_CHANNEL 0 + +/* High-resolution timer */ +/* + * For wifi to work, it needs to use its own timer. + * Make sure you are not using the timer for hrt + * that is being using for the wifi +*/ +#define HRT_TIMER 2 + +/* This board provides a DMA pool and APIs */ // Needs to be figured out +#define BOARD_DMA_ALLOC_POOL_SIZE 2048 + +#define BOARD_ENABLE_CONSOLE_BUFFER +#define BOARD_CONSOLE_BUFFER_SIZE (1024*3) + +/* PWM + */ +#define DIRECT_PWM_OUTPUT_CHANNELS 4 + +// Has pwm outputs +#define BOARD_HAS_PWM DIRECT_PWM_OUTPUT_CHANNELS + +// #define BOARD_ADC_USB_CONNECTED (px4_arch_gpioread(GPIO_USB_VBUS_VALID)); +int esp32_spiflash_init(void); +int esp32_partition_init(void); + +__BEGIN_DECLS + +#ifndef __ASSEMBLY__ + + +/**************************************************************************************************** + * Name: rp2040_usbinitialize + * + * Description: + * Called to configure USB IO. + * + ****************************************************************************************************/ + +extern void esp32_spiinitialize(void); + +extern void board_peripheral_reset(int ms); + +#include + +#endif /* __ASSEMBLY__ */ + +__END_DECLS diff --git a/boards/espressif/esp32/src/esp32_board_spiflash.c b/boards/espressif/esp32/src/esp32_board_spiflash.c new file mode 100644 index 00000000000..06329746598 --- /dev/null +++ b/boards/espressif/esp32/src/esp32_board_spiflash.c @@ -0,0 +1,574 @@ +/**************************************************************************** + * boards/xtensa/esp32/common/src/esp32_board_spiflash.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef CONFIG_ESP32_SPIFLASH_NXFFS +#include +#endif +#ifdef CONFIG_BCH +#include +#endif + +#include "esp32_spiflash.h" +#include "esp32_board_spiflash_setup.h" + +// #define CONFIG_ESP32_SPIFLASH_SPIFFS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0])) + +#ifdef CONFIG_ESP32_OTA_PARTITION_ENCRYPT +# define OTA_ENCRYPT true +#else +# define OTA_ENCRYPT false +#endif + +#ifdef CONFIG_ESP32_WIFI_MTD_ENCRYPT +# define WIFI_ENCRYPT true +#else +# define WIFI_ENCRYPT false +#endif + +#ifdef CONFIG_ESP32_STORAGE_MTD_ENCRYPT +# define STORAGE_ENCRYPT true +#else +# define STORAGE_ENCRYPT false +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef CONFIG_ESP32_HAVE_OTA_PARTITION +struct ota_partition_s { + uint32_t offset; /* Partition offset from the beginning of MTD */ + uint32_t size; /* Partition size in bytes */ + const char *devpath; /* Partition device path */ +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_ESP32_HAVE_OTA_PARTITION +static int init_ota_partitions(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ESP32_HAVE_OTA_PARTITION +static const struct ota_partition_s g_ota_partition_table[] = { + { + .offset = CONFIG_ESP32_OTA_PRIMARY_SLOT_OFFSET, + .size = CONFIG_ESP32_OTA_SLOT_SIZE, + .devpath = CONFIG_ESP32_OTA_PRIMARY_SLOT_DEVPATH + }, + { + .offset = CONFIG_ESP32_OTA_SECONDARY_SLOT_OFFSET, + .size = CONFIG_ESP32_OTA_SLOT_SIZE, + .devpath = CONFIG_ESP32_OTA_SECONDARY_SLOT_DEVPATH + }, + { + .offset = CONFIG_ESP32_OTA_SCRATCH_OFFSET, + .size = CONFIG_ESP32_OTA_SCRATCH_SIZE, + .devpath = CONFIG_ESP32_OTA_SCRATCH_DEVPATH + } +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_ESP32_HAVE_OTA_PARTITION +static int init_ota_partitions(void) +{ + struct mtd_dev_s *mtd; +#ifdef CONFIG_BCH + char blockdev[18]; +#endif + int ret = OK; + + for (int i = 0; i < ARRAYSIZE(g_ota_partition_table); ++i) { + const struct ota_partition_s *part = &g_ota_partition_table[i]; + mtd = esp32_spiflash_alloc_mtdpart(part->offset, part->size, + OTA_ENCRYPT); + + ret = ftl_initialize(i, mtd); + + if (ret < 0) { + ferr("ERROR: Failed to initialize the FTL layer: %d\n", ret); + return ret; + } + +#ifdef CONFIG_BCH + snprintf(blockdev, sizeof(blockdev), "/dev/mtdblock%d", i); + + ret = bchdev_register(blockdev, part->devpath, false); + + if (ret < 0) { + ferr("ERROR: bchdev_register %s failed: %d\n", part->devpath, ret); + return ret; + } + +#endif + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: setup_smartfs + * + * Description: + * Provide a block driver wrapper around MTD partition and mount a + * SMART FS over it. + * + * Parameters: + * smartn - Number used to register the mtd partition: /dev/smartx, where + * x = smartn. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_SPIFLASH_SMARTFS +static int setup_smartfs(int smartn, struct mtd_dev_s *mtd, + const char *mnt_pt) +{ + int ret = OK; + char path[22]; + + ret = smart_initialize(smartn, mtd, NULL); + + if (ret < 0) { + finfo("smart_initialize failed, Trying to erase first...\n"); + ret = mtd->ioctl(mtd, MTDIOC_BULKERASE, 0); + + if (ret < 0) { + ferr("ERROR: ioctl(BULKERASE) failed: %d\n", ret); + return ret; + } + + finfo("Erase successful, initializing it again.\n"); + ret = smart_initialize(smartn, mtd, NULL); + + if (ret < 0) { + ferr("ERROR: smart_initialize failed: %d\n", ret); + return ret; + } + } + + if (mnt_pt != NULL) { + snprintf(path, sizeof(path), "/dev/smart%d", smartn); + + ret = nx_mount(path, mnt_pt, "smartfs", 0, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: setup_littlefs + * + * Description: + * Register a mtd driver and mount a Little FS over it. + * + * Parameters: + * path - Path name used to register the mtd driver. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * priv - Privileges + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_SPIFLASH_LITTLEFS +static int setup_littlefs(const char *path, struct mtd_dev_s *mtd, + const char *mnt_pt, int priv) +{ + int ret = OK; + + ret = register_mtddriver(path, mtd, priv, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to register MTD: %d\n", ret); + return -ENOMEM; + } + + if (mnt_pt != NULL) { + ret = nx_mount(path, mnt_pt, "littlefs", 0, NULL); + + if (ret < 0) { + ret = nx_mount(path, mnt_pt, "littlefs", 0, "forceformat"); + + if (ret < 0) { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: setup_spiffs + * + * Description: + * Register a mtd driver and mount a SPIFFS over it. + * + * Parameters: + * path - Path name used to register the mtd driver. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * priv - Privileges + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_SPIFLASH_SPIFFS +static int setup_spiffs(const char *path, struct mtd_dev_s *mtd, + const char *mnt_pt, int priv) +{ + int ret = OK; + + ret = register_mtddriver(path, mtd, priv, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to register MTD: %d\n", ret); + return -ENOMEM; + } + + if (mnt_pt != NULL) { + ret = nx_mount(path, mnt_pt, "spiffs", 0, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: setup_nxffs + * + * Description: + * Register a mtd driver and mount a SPIFFS over it. + * + * Parameters: + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_SPIFLASH_NXFFS +static int setup_nxffs(struct mtd_dev_s *mtd, const char *mnt_pt) +{ + int ret = OK; + + ret = nxffs_initialize(mtd); + + if (ret < 0) { + ferr("ERROR: NXFFS init failed: %d\n", ret); + return ret; + } + + if (mnt_pt != NULL) { + ret = nx_mount(NULL, mnt_pt, "nxffs", 0, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: init_wifi_partition + * + * Description: + * Initialize partition that is dedicated to Wi-Fi. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM +static int init_wifi_partition(void) +{ + int ret = OK; + struct mtd_dev_s *mtd; + + mtd = esp32_spiflash_alloc_mtdpart(CONFIG_ESP32_WIFI_MTD_OFFSET, + CONFIG_ESP32_WIFI_MTD_SIZE, + WIFI_ENCRYPT); + + if (!mtd) { + ferr("ERROR: Failed to alloc MTD partition of SPI Flash\n"); + return -ENOMEM; + } + +#ifdef CONFIG_ESP32_SPIFLASH_SMARTFS + + ret = setup_smartfs(1, mtd, CONFIG_ESP32_WIFI_FS_MOUNTPT); + + if (ret < 0) { + ferr("ERROR: Failed to setup smartfs\n"); + return ret; + } + +#elif defined(CONFIG_ESP32_SPIFLASH_LITTLEFS) + + const char *path = "/dev/mtdblock1"; + ret = setup_littlefs(path, mtd, CONFIG_ESP32_WIFI_FS_MOUNTPT, 0777); + + if (ret < 0) { + ferr("ERROR: Failed to setup littlefs\n"); + return ret; + } + +#elif defined(CONFIG_ESP32_SPIFLASH_SPIFFS) + + const char *path = "/dev/mtdblock1"; + ret = setup_spiffs(path, mtd, CONFIG_ESP32_WIFI_FS_MOUNTPT, 0777); + + if (ret < 0) { + ferr("ERROR: Failed to setup spiffs\n"); + return ret; + } + +#else + + ferr("ERROR: No supported FS selected. Wi-Fi partition " + "should be mounted before Wi-Fi initialization\n"); + +#endif + + return ret; +} +#endif + +/**************************************************************************** + * Name: init_storage_partition + * + * Description: + * Initialize partition that is dedicated to general use. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int init_storage_partition(void) +{ + int ret = OK; + struct mtd_dev_s *mtd; + + mtd = esp32_spiflash_alloc_mtdpart(CONFIG_ESP32_STORAGE_MTD_OFFSET, + CONFIG_ESP32_STORAGE_MTD_SIZE, + STORAGE_ENCRYPT); + + if (!mtd) { + ferr("ERROR: Failed to alloc MTD partition of SPI Flash\n"); + return -ENOMEM; + } + +#ifdef CONFIG_ESP32_SPIFLASH_SMARTFS + + ret = setup_smartfs(0, mtd, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to setup smartfs\n"); + return ret; + } + +#elif defined(CONFIG_ESP32_SPIFLASH_NXFFS) + + ret = setup_nxffs(mtd, "/mnt"); + + if (ret < 0) { + ferr("ERROR: Failed to setup nxffs\n"); + return ret; + } + +#elif defined(CONFIG_ESP32_SPIFLASH_LITTLEFS) + + const char *path = "/dev/esp32flash"; + ret = setup_littlefs(path, mtd, NULL, 0755); + + if (ret < 0) { + ferr("ERROR: Failed to setup littlefs\n"); + return ret; + } + +#elif defined(CONFIG_ESP32_SPIFLASH_SPIFFS) + const char *path = "/dev/esp32flash"; + ret = setup_spiffs(path, mtd, NULL, 0755); + + if (ret < 0) { + ferr("ERROR: Failed to setup spiffs\n"); + return ret; + } + +#else + + ret = register_mtddriver("/dev/esp32flash", mtd, 0755, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to register MTD: %d\n", ret); + return ret; + } + +#endif + + return ret; +} + +#define CONFIG_ESP32_PARAM_MTD_OFFSET 0x330000 +#define CONFIG_ESP32_PARAM_MTD_SIZE 0x10000 + +static int init_param_partition(void) +{ + int ret = OK; + struct mtd_dev_s *mtd; + + mtd = esp32_spiflash_alloc_mtdpart(CONFIG_ESP32_PARAM_MTD_OFFSET, + CONFIG_ESP32_PARAM_MTD_SIZE, + STORAGE_ENCRYPT); + + if (!mtd) { + ferr("ERROR: Failed to alloc PARAM MTD partition of SPI Flash\n"); + return -ENOMEM; + } + + ret = register_mtddriver("/fs/mtd_params", mtd, 0755, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to register PARAM MTD: %d\n", ret); + return ret; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_spiflash_init + * + * Description: + * Initialize the SPI Flash and register the MTD. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int esp32_spiflash_init(void) +{ + int ret = OK; + +#ifdef CONFIG_ESP32_HAVE_OTA_PARTITION + ret = init_ota_partitions(); + + if (ret < 0) { + return ret; + } + +#endif + +#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM + ret = init_wifi_partition(); + + if (ret < 0) { + return ret; + } + +#endif + + ret = init_storage_partition(); + + if (ret < 0) { + return ret; + } + + ret = init_param_partition(); + + if (ret < 0) { + return ret; + } + + + return ret; +} diff --git a/boards/espressif/esp32/src/esp32_board_spiflash_setup.c b/boards/espressif/esp32/src/esp32_board_spiflash_setup.c new file mode 100644 index 00000000000..cafd462c2e8 --- /dev/null +++ b/boards/espressif/esp32/src/esp32_board_spiflash_setup.c @@ -0,0 +1,353 @@ +/**************************************************************************** + * boards/xtensa/esp32/common/src/esp32_board_spiflash.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef CONFIG_ESP32_SPIFLASH_NXFFS +#include +#endif +#ifdef CONFIG_BCH +#include +#endif + +#include +#define MODULE_NAME "spiflash" + +#include "esp32_spiflash.h" +#include "esp32_partition.h" +// #include "esp32_board_spiflash_setup.h" + +#include "board_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0])) + +#ifdef CONFIG_ESP32_OTA_PARTITION_ENCRYPT +# define OTA_ENCRYPT true +#else +# define OTA_ENCRYPT false +#endif + +#ifdef CONFIG_ESP32_WIFI_MTD_ENCRYPT +# define WIFI_ENCRYPT true +#else +# define WIFI_ENCRYPT false +#endif + +#ifdef CONFIG_ESP32_STORAGE_MTD_ENCRYPT +# define STORAGE_ENCRYPT true +#else +# define STORAGE_ENCRYPT false +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +int esp32_spiflash_init(void); +int esp32_partition_init(void); + +static int init_ota_partitions(void) +{ + struct mtd_dev_s *mtd; + char blockdev[18]; + int ret = OK; + + mtd = esp32_spiflash_alloc_mtdpart(CONFIG_ESP32_STORAGE_MTD_OFFSET, CONFIG_ESP32_STORAGE_MTD_SIZE, false); + + ret = ftl_initialize(0, mtd); + + if (ret < 0) { + PX4_INFO("ERROR: Failed to initialize the FTL layer: %d\n", ret); + return ret; + } + + snprintf(blockdev, sizeof(blockdev), "/dev/mtdblock%d", 0); + + ret = bchdev_register(blockdev, "/fs/mtd_params", false); + + if (ret < 0) { + PX4_INFO("ERROR: bchdev_register %s failed: %d\n", "/fs/mtd_params", ret); + return ret; + } + + return ret; +} + +/**************************************************************************** + * Name: setup_smartfs + * + * Description: + * Provide a block driver wrapper around MTD partition and mount a + * SMART FS over it. + * + * Parameters: + * smartn - Number used to register the mtd partition: /dev/smartx, where + * x = smartn. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +/**************************************************************************** + * Name: setup_littlefs + * + * Description: + * Register a mtd driver and mount a Little FS over it. + * + * Parameters: + * path - Path name used to register the mtd driver. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * priv - Privileges + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int setup_littlefs(const char *path, struct mtd_dev_s *mtd, + const char *mnt_pt, int priv) +{ + int ret = OK; + + ret = register_mtddriver(path, mtd, priv, NULL); + + if (ret < 0) { + PX4_INFO("ERROR: Failed to register MTD: %d\n", ret); + return -ENOMEM; + } + + // if (mnt_pt != NULL) + // { + // ret = nx_mount(path, "/mnt/lfs", "littlefs", 0, ""); + // if (ret < 0) + // { + // ret = nx_mount(path, "/fs/lfs", "littlefs", 0, "forceformat"); + // if (ret < 0) + // { + // PX4_INFO("ERROR: Failed to mount the FS volume: %d\n", ret); + // return ret; + // } + // } + // } + + return OK; +} + +/**************************************************************************** + * Name: setup_spiffs + * + * Description: + * Register a mtd driver and mount a SPIFFS over it. + * + * Parameters: + * path - Path name used to register the mtd driver. + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * priv - Privileges + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int setup_spiffs(const char *path, struct mtd_dev_s *mtd, + const char *mnt_pt, int priv) +{ + int ret = OK; + + ret = register_mtddriver(path, mtd, priv, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to register MTD: %d\n", ret); + return -ENOMEM; + } + + if (mnt_pt != NULL) { + ret = nx_mount(path, mnt_pt, "spiffs", 0, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + + return ret; +} + +/**************************************************************************** + * Name: setup_nxffs + * + * Description: + * Register a mtd driver and mount a SPIFFS over it. + * + * Parameters: + * mtd - Pointer to a pre-allocated mtd partition. + * mnt_pt - Mount point + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_SPIFLASH_NXFFS +static int setup_nxffs(struct mtd_dev_s *mtd, const char *mnt_pt) +{ + int ret = OK; + + ret = nxffs_initialize(mtd); + + if (ret < 0) { + ferr("ERROR: NXFFS init failed: %d\n", ret); + return ret; + } + + if (mnt_pt != NULL) { + ret = nx_mount(NULL, mnt_pt, "nxffs", 0, NULL); + + if (ret < 0) { + ferr("ERROR: Failed to mount the FS volume: %d\n", ret); + return ret; + } + } + + return ret; +} +#endif + + +/**************************************************************************** + * Name: init_storage_partition + * + * Description: + * Initialize partition that is dedicated to general use. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int init_storage_partition(void) +{ + int ret = OK; + struct mtd_dev_s *mtd; + + + mtd = esp32_spiflash_alloc_mtdpart(CONFIG_ESP32_STORAGE_MTD_OFFSET, + CONFIG_ESP32_STORAGE_MTD_SIZE, + STORAGE_ENCRYPT); + + if (!mtd) { + PX4_INFO("ERROR: Failed to alloc MTD partition of SPI Flash\n"); + return -ENOMEM; + } + + const char *path = "/dev/esp32flash"; + ret = setup_littlefs(path, mtd, "/mnt/esp32", 0755); + + if (ret < 0) { + PX4_INFO("ERROR: Failed to setup littlefs\n"); + return ret; + } + + // const char *path = "/dev/esp32flash"; + // ret = setup_spiffs(path, mtd, "/mnt/spiffs/", 0755); + // if (ret < 0) + // { + // ferr("ERROR: Failed to setup spiffs\n"); + // return ret; + // } + + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_spiflash_init + * + * Description: + * Initialize the SPI Flash and register the MTD. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int esp32_spiflash_init(void) +{ + int ret = OK; + + ret = init_ota_partitions(); + PX4_INFO("ret = %d = init_ota_paritions()\n", ret); + + if (ret < 0) { + return ret; + } + + // ret = esp32_partition_init(); + // if (ret < 0) + // { + // syslog(LOG_ERR, "ERROR: Failed to initialize partition error=%d\n", + // ret); + // } +// + // ret = init_storage_partition(); + // PX4_INFO("ret = %d = init_storage_paritions()\n", ret); + + // if (ret < 0) + // { + // return ret; + // } + + return ret; +} diff --git a/boards/espressif/esp32/src/esp32_board_spiflash_setup.h b/boards/espressif/esp32/src/esp32_board_spiflash_setup.h new file mode 100644 index 00000000000..0dd4257572e --- /dev/null +++ b/boards/espressif/esp32/src/esp32_board_spiflash_setup.h @@ -0,0 +1,68 @@ +/**************************************************************************** + * boards/xtensa/esp32/common/include/esp32_board_spiflash.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_XTENSA_ESP32_COMMON_INCLUDE_ESP32_BOARD_SPIFLASH_H +#define __BOARDS_XTENSA_ESP32_COMMON_INCLUDE_ESP32_BOARD_SPIFLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_spiflash_init + * + * Description: + * Initialize the SPI Flash and register the MTD. + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int esp32_spiflash_init(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_XTENSA_ESP32_COMMON_INCLUDE_ESP32_BOARD_SPIFLASH_H */ diff --git a/boards/espressif/esp32/src/esp32_board_wlan_setup.c b/boards/espressif/esp32/src/esp32_board_wlan_setup.c new file mode 100644 index 00000000000..db790c328f5 --- /dev/null +++ b/boards/espressif/esp32/src/esp32_board_wlan_setup.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * boards/xtensa/esp32/common/src/esp32_board_wlan.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "esp32_spiflash.h" +#include "esp32_wlan.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_wlan_init + * + * Description: + * Configure the wireless subsystem. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int board_wlan_init(void) +{ + int ret = OK; + + +#ifdef ESP32_WLAN_HAS_STA + // ret = esp32_wlan_sta_initialize(); + // if (ret) + // { + // printf("ERROR: Failed to initialize Wi-Fi station\n"); + // return ret; + // } +#endif + + +#ifdef ESP32_WLAN_HAS_SOFTAP + ret = esp32_wlan_softap_initialize(); + + if (ret) { + wlerr("ERROR: Failed to initialize Wi-Fi softAP\n"); + return ret; + } + +#endif + + // netlib_ifup("wlan1"); + // dhcpd_start("wlan1"); + + return ret; +} diff --git a/boards/espressif/esp32/src/esp32_board_wlan_setup.h b/boards/espressif/esp32/src/esp32_board_wlan_setup.h new file mode 100644 index 00000000000..7f096193522 --- /dev/null +++ b/boards/espressif/esp32/src/esp32_board_wlan_setup.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * boards/xtensa/esp32/common/include/esp32_board_wlan.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_XTENSA_ESP32_COMMON_INCLUDE_ESP32_BOARD_WLAN_H +#define __BOARDS_XTENSA_ESP32_COMMON_INCLUDE_ESP32_BOARD_WLAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_ESP32_WIRELESS + +/**************************************************************************** + * Name: board_wlan_init + * + * Description: + * Configure the wireless subsystem. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int board_wlan_init(void); + +#endif /* CONFIG_ESP32_WIRELESS */ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_XTENSA_ESP32_COMMON_INCLUDE_ESP32_BOARD_WLAN_H */ diff --git a/boards/espressif/esp32/src/i2c.cpp b/boards/espressif/esp32/src/i2c.cpp new file mode 100644 index 00000000000..34b159bbc31 --- /dev/null +++ b/boards/espressif/esp32/src/i2c.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = { + initI2CBusInternal(1), +}; diff --git a/boards/espressif/esp32/src/init.c b/boards/espressif/esp32/src/init.c new file mode 100644 index 00000000000..13800d4516b --- /dev/null +++ b/boards/espressif/esp32/src/init.c @@ -0,0 +1,300 @@ +/**************************************************************************** + * + * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file init.c + * + * board specific early startup code. This file implements the + * board_app_initialize() function that is called early by nsh during startup. + * + * Code here is run before the rcS script is invoked; it should start required + * subsystems and perform board-specific initialization. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include +#include "board_config.h" + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#define LEDC_LS_SIG_OUT0_IDX 79 + +#include "esp32_board_wlan_setup.h" +#ifdef CONFIG_ESP32_SPIFLASH +#include "esp32_board_spiflash_setup.h" +#endif + +#include "esp32_rt_timer.h" +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/** + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +__END_DECLS + +/**************************************************************************** + * Protected Functions + ****************************************************************************/ +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/************************************************************************************ + * Name: board_peripheral_reset + * + * Description: + * + ************************************************************************************/ +__EXPORT void board_peripheral_reset(int ms) +{ + UNUSED(ms); +} + +/************************************************************************************ + * Name: board_on_reset + * + * Description: + * Optionally provided function called on entry to board_system_reset + * It should perform any house keeping prior to the rest. + * + * status - 1 if resetting to boot loader + * 0 if just resetting + * + ************************************************************************************/ +__EXPORT void board_on_reset(int status) +{ + // Configure the GPIO pins to outputs and keep them low. + for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) { + px4_arch_configgpio(io_timer_channel_get_gpio_output(i)); + esp32_gpio_matrix_out(timer_io_channels[i].gpio_out, LEDC_LS_SIG_OUT0_IDX + timer_io_channels[i].timer_channel, 0, 0); + } + + /* + * On resets invoked from system (not boot) insure we establish a low + * output state (discharge the pins) on PWM pins before they become inputs. + */ + + if (status >= 0) { + up_mdelay(400); + } +} + +/************************************************************************************ + * Name: board_read_VBUS_state + * + * Description: + * All boards must provide a way to read the state of VBUS, this my be simple + * digital input on a GPIO. Or something more complicated like a Analong input + * or reading a bit from a USB controller register. + * + * Returns - 0 if connected. + * + ************************************************************************************/ + +int board_read_VBUS_state(void) +{ + // return BOARD_ADC_USB_CONNECTED ? 0 : 1; + return 0; +} + +/************************************************************************************ + * Name: esp32_board_initialize + * + * Description: + * All architectures must provide the following entry point. This entry point + * is called early in the initialization -- after all memory has been configured + * and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +__EXPORT void +esp32_board_initialize(void) +{ + // /* Reset all PWM to Low outputs */ + board_on_reset(-1); + + // /* configure LEDs */ + board_autoled_initialize(); + up_mdelay(2); + esp32_spiinitialize(); + +} + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initalization logic and the the + * matching application logic. The value cold be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_SPI2 +static struct spi_dev_s *spi2; +#endif + +#ifdef CONFIG_ESP32_SPI3 +static struct spi_dev_s *spi3; +#endif + + +__EXPORT int board_app_initialize(uintptr_t arg) +{ + px4_platform_init(); + + /* configure the DMA allocator */ // Needs to be figured out + + if (board_dma_alloc_init() < 0) { + syslog(LOG_ERR, "DMA alloc FAILED\n"); + } + + + /* initial LED state */ + drv_led_start(); + +#ifdef CONFIG_ESP32_SPI2 + spi2 = esp32_spibus_initialize(2); + + if (!spi2) { + syslog(LOG_ERR, "[boot] FAILED to initialize SPI port 2\n"); + // led_on(LED_RED); + } + + // Default SPI1 to 10MHz + SPI_SETFREQUENCY(spi2, 10000000); + SPI_SETBITS(spi2, 8); + SPI_SETMODE(spi2, SPIDEV_MODE3); + up_udelay(20); + +#endif + +#ifdef CONFIG_ESP32_SPI3 + spi3 = esp32_spibus_initialize(3); + + if (!spi3) { + syslog(LOG_ERR, "[boot] FAILED to initialize SPI port 3\n"); + // led_on(LED_RED); + } + + /* Now bind the SPI interface to the MMCSD driver */ + int result = mmcsd_spislotinitialize(CONFIG_NSH_MMCSDMINOR, CONFIG_NSH_MMCSDSLOTNO, spi3); + + if (result != OK) { + syslog(LOG_ERR, "[boot] FAILED to bind SPI port 3 to the MMCSD driver\n"); + } + +#endif + int ret = esp32_spiflash_init(); + + if (ret) { + syslog(LOG_ERR, "ERROR: Failed to initialize SPI Flash\n"); + } + + esp32_rt_timer_init(); + + led_on(GPIO_LED_BLUE); + up_mdelay(100); + led_off(GPIO_LED_BLUE); + up_mdelay(100); + led_on(GPIO_LED_BLUE); + up_mdelay(100); + led_off(GPIO_LED_BLUE); + + + + /* Configure the HW based on the manifest */ + px4_platform_configure(); + + up_mdelay(1000); + + board_wlan_init(); + + return OK; +} diff --git a/boards/espressif/esp32/src/led.c b/boards/espressif/esp32/src/led.c new file mode 100644 index 00000000000..11ba4ec44c8 --- /dev/null +++ b/boards/espressif/esp32/src/led.c @@ -0,0 +1,102 @@ +/**************************************************************************** + * + * Copyright (c) 2013 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file led.c + * + * PX4FMU LED backend. + */ + +#include + +#include + +#include "board_config.h" + +#include + +/* + * Ideally we'd be able to get these from arm_internal.h, + * but since we want to be able to disable the NuttX use + * of leds for system indication at will and there is no + * separate switch, we need to build independent of the + * CONFIG_ARCH_LEDS configuration switch. + */ +__BEGIN_DECLS +extern void led_init(void); +extern void led_on(int led); +extern void led_off(int led); +extern void led_toggle(int led); +__END_DECLS + + + +static uint32_t g_ledmap[] = { + GPIO_LED_BLUE, // Indexed by LED_BLUE +}; + +__EXPORT void led_init(void) +{ + /* Configure LED GPIOs for output */ + for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) { + px4_arch_configgpio(g_ledmap[l]); + } +} + +static void phy_set_led(int led, bool state) +{ + /* Pull Down to switch on */ + px4_arch_gpiowrite(g_ledmap[led], !state); +} + +static bool phy_get_led(int led) +{ + + return !px4_arch_gpioread(g_ledmap[led]); +} + +__EXPORT void led_on(int led) +{ + phy_set_led(led, true); +} + +__EXPORT void led_off(int led) +{ + phy_set_led(led, false); +} + +__EXPORT void led_toggle(int led) +{ + + phy_set_led(led, !phy_get_led(led)); +} diff --git a/boards/espressif/esp32/src/mtd.cpp b/boards/espressif/esp32/src/mtd.cpp new file mode 100644 index 00000000000..c5cb280b7f1 --- /dev/null +++ b/boards/espressif/esp32/src/mtd.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include +#include + +#include +#include +// KiB BS nB +static const px4_mft_device_t flash = { // 24AA64FT on Base 8K 32 X 256 + .bus_type = px4_mft_device_t::ONCHIP +}; + + +static const px4_mtd_entry_t fmu_flash = { + .device = &flash, + .npart = 1, + .partd = { + { + .type = MTD_PARAMETERS, + .path = "/fs/mtd_params", + .nblocks = 1 + } + }, +}; + +static const px4_mtd_manifest_t board_mtd_config = { + .nconfigs = 1, + .entries = { + &fmu_flash, + } +}; + +static const px4_mft_entry_s mtd_mft = { + .type = MTD, + .pmft = (void *) &board_mtd_config, +}; + +static const px4_mft_s mft = { + .nmft = 1, + .mfts = {&mtd_mft} +}; + +const px4_mft_s *board_get_manifest(void) +{ + return &mft; +} diff --git a/boards/espressif/esp32/src/spi.cpp b/boards/espressif/esp32/src/spi.cpp new file mode 100644 index 00000000000..c6162c81641 --- /dev/null +++ b/boards/espressif/esp32/src/spi.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#include +#include +#include + +const constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { +#ifdef CONFIG_ESP32_SPI2 + initSPIBus(SPI::Bus::SPI2, { + initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::Pin(CONFIG_ESP32_SPI2_CSPIN)}), + + }), +#endif +#ifdef CONFIG_ESP32_SPI3 + initSPIBus(SPI::Bus::SPI3, { + initSPIDevice(SPIDEV_MMCSD(0), SPI::CS{GPIO::Pin(CONFIG_ESP32_SPI3_CSPIN)}) + + }), +#endif +}; + +static constexpr bool unused = validateSPIConfig(px4_spi_buses); diff --git a/boards/espressif/esp32/src/timer_config.cpp b/boards/espressif/esp32/src/timer_config.cpp new file mode 100644 index 00000000000..e9df640c2c7 --- /dev/null +++ b/boards/espressif/esp32/src/timer_config.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include + +constexpr io_timers_t io_timers[MAX_IO_TIMERS] = { + initIOTimer(Timer::Timer0), // this refers to LEDC periherals +}; + +constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = { + initIOTimerChannel(io_timers, {Timer::Timer0, Timer::Channel0}, {GPIO::Pin(CONFIG_ESP32_LEDC_CHANNEL0_PIN)}), + initIOTimerChannel(io_timers, {Timer::Timer0, Timer::Channel1}, {GPIO::Pin(CONFIG_ESP32_LEDC_CHANNEL1_PIN)}), + initIOTimerChannel(io_timers, {Timer::Timer0, Timer::Channel2}, {GPIO::Pin(CONFIG_ESP32_LEDC_CHANNEL2_PIN)}), + initIOTimerChannel(io_timers, {Timer::Timer0, Timer::Channel3}, {GPIO::Pin(CONFIG_ESP32_LEDC_CHANNEL3_PIN)}), +}; + +// constexpr io_timers_channel_mapping_t io_timers_channel_mapping = initIOTimerChannelMapping(io_timers, +// timer_io_channels); diff --git a/boards/espressif/esp32/src/usb.c b/boards/espressif/esp32/src/usb.c new file mode 100644 index 00000000000..784257dc9eb --- /dev/null +++ b/boards/espressif/esp32/src/usb.c @@ -0,0 +1,84 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file usb.c + * + * Board-specific USB functions. + */ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include "board_config.h" + +/************************************************************************************ + * Name: rp2040_usbinitialize + * + * Description: + * Called to setup USB-related GPIO pins for the omnibusf4sd board. + * + ************************************************************************************/ + +__EXPORT void esp32_usbinitialize(void) +{ + // px4_arch_configgpio(GPIO_USB_VBUS_VALID); +} + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +__EXPORT void esp32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + uinfo("resume: %d\n", resume); +} diff --git a/platforms/nuttx/CMakeLists.txt b/platforms/nuttx/CMakeLists.txt index 19fcae552ea..4bee8ed581c 100644 --- a/platforms/nuttx/CMakeLists.txt +++ b/platforms/nuttx/CMakeLists.txt @@ -242,6 +242,105 @@ if (NOT CONFIG_BUILD_FLAT) else() +if(CONFIG_ARCH_CHIP_ESP32) + + set(PX4_STARTUP_DIR ${PX4_SOURCE_DIR}/platforms/nuttx/NuttX/nuttx/arch/xtensa/src) + set(WIRELESS_LIB ${PX4_STARTUP_DIR}/esp32/esp-wireless-drivers-3rdparty/libs/esp32/) + + set(NUTTX_STARTUP_OBJS + ${PX4_STARTUP_DIR}/xtensa_vectors.o + ${PX4_STARTUP_DIR}/xtensa_window_vector.o + ${PX4_STARTUP_DIR}/xtensa_windowspill.o + ${PX4_STARTUP_DIR}/xtensa_int_handlers.o + ${PX4_STARTUP_DIR}/xtensa_user_handler.o + ${PX4_STARTUP_DIR}/xtensa_initialize.o + ${PX4_STARTUP_DIR}/xtensa_initialstate.o + ${PX4_STARTUP_DIR}/esp32_start.o + ${PX4_STARTUP_DIR}/esp32_wdt.o + ) + + set(NUTTX_NETWORK_LIB + libbtdm_app.a + libcoexist.a + libcore.a + libespnow.a + libnet80211.a + libphy.a + libpp.a + librtc.a + libsmartconfig.a + libwapi.a + libwpa_supplicant.a + ) + execute_process(COMMAND touch ${NUTTX_STARTUP_OBJS} + WORKING_DIRECTORY ${PX4_SOURCE_DIR}) + set_source_files_properties( + ${NUTTX_STARTUP_OBJS} + PROPERTIES + EXTERNAL_OBJECT true + GENERATED true) + + target_link_libraries(nuttx_c INTERFACE nuttx_sched) # nxsched_get_streams + + target_link_libraries(nuttx_arch + INTERFACE + drivers_board + arch_hrt + arch_board_reset + -L${WIRELESS_LIB} + -Wl,--start-group + ${NUTTX_NETWORK_LIB} + -Wl,--end-group + ) + + target_link_libraries(nuttx_c INTERFACE nuttx_drivers) + target_link_libraries(nuttx_drivers INTERFACE nuttx_c nuttx_fs) + target_link_libraries(nuttx_xx INTERFACE nuttx_c) + target_link_libraries(nuttx_fs INTERFACE nuttx_c nuttx_net) + target_link_libraries(nuttx_net INTERFACE nuttx_mm) + target_link_libraries(px4 PRIVATE + -nostartfiles + -nodefaultlibs + -nostdlib + -nostdinc++ + -mlongcalls + -fno-exceptions + -fno-rtti + -Wl,--cref + -L${WIRELESS_LIB} + + -Wl,-T${NUTTX_CONFIG_DIR_CYG}/scripts/${SCRIPT_PREFIX}esp32_out.ld + -T${NUTTX_CONFIG_DIR_CYG}/scripts/${SCRIPT_PREFIX}esp32.ld + -T${NUTTX_CONFIG_DIR_CYG}/scripts/${SCRIPT_PREFIX}esp32_rom.ld + -Wl,-Map=${PX4_CONFIG}.map + -Wl,--gc-sections + + -Wl,--start-group + ${nuttx_libs} + ${NUTTX_STARTUP_OBJS} + ${NUTTX_NETWORK_LIB} + -Wl,--end-group + + m + gcc + ) + + if(NOT USE_LD_GOLD) + target_link_libraries(px4 PRIVATE -Wl,--print-memory-usage) + endif() + + target_link_libraries(px4 PRIVATE ${module_libraries}) + if(config_romfs_root) + add_subdirectory(${PX4_SOURCE_DIR}/ROMFS ${PX4_BINARY_DIR}/ROMFS) + target_link_libraries(px4 PRIVATE romfs) + endif() + add_custom_command(OUTPUT ${PX4_BINARY_OUTPUT} + COMMAND esptool --chip esp32 elf2image -o ${PX4_BINARY_OUTPUT} ${PX4_BINARY_DIR_REL}/${FW_NAME} + COMMAND du ${PX4_BINARY_OUTPUT} -h + DEPENDS px4 + ) +else() + target_link_libraries(nuttx_c INTERFACE nuttx_sched) # nxsched_get_streams target_link_libraries(nuttx_arch @@ -294,6 +393,7 @@ else() COMMAND ${CMAKE_OBJCOPY} -O binary ${PX4_BINARY_DIR_REL}/${FW_NAME} ${PX4_BINARY_OUTPUT} DEPENDS px4 ) +endif() endif() diff --git a/platforms/nuttx/cmake/Platform/Generic-xtensa-esp32-elf-gcc-esp32.cmake b/platforms/nuttx/cmake/Platform/Generic-xtensa-esp32-elf-gcc-esp32.cmake new file mode 100644 index 00000000000..0e897d2ebab --- /dev/null +++ b/platforms/nuttx/cmake/Platform/Generic-xtensa-esp32-elf-gcc-esp32.cmake @@ -0,0 +1,4 @@ +set(cpu_flags "-mlongcalls -Wno-format -Wno-unused-function -fdata-sections -Wno-pointer-arith")#-DDEBUG_BUILD +set(CMAKE_C_FLAGS "${cpu_flags} -Wstrict-prototypes -Wshadow" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS "${cpu_flags} -nostdinc++ -Wshadow" CACHE STRING "" FORCE) +set(CMAKE_ASM_FLAGS "${cpu_flags} -D__ASSEMBLY__" CACHE STRING "" FORCE) diff --git a/platforms/nuttx/cmake/Toolchain-xtensa-esp32-elf.cmake b/platforms/nuttx/cmake/Toolchain-xtensa-esp32-elf.cmake new file mode 100644 index 00000000000..43d33142b16 --- /dev/null +++ b/platforms/nuttx/cmake/Toolchain-xtensa-esp32-elf.cmake @@ -0,0 +1,44 @@ +# arm-none-eabi-gcc toolchain + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_VERSION 1) + +set(triple xtensa-esp32-elf) +set(CMAKE_LIBRARY_ARCHITECTURE ${triple}) +set(TOOLCHAIN_PREFIX ${triple}) + +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_C_COMPILER_TARGET ${triple}) + +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_CXX_COMPILER_TARGET ${triple}) + +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}-gcc) + +# needed for test compilation +set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs") + +# compiler tools +find_program(CMAKE_AR ${TOOLCHAIN_PREFIX}-ar) +find_program(CMAKE_GDB ${TOOLCHAIN_PREFIX}-gdb) +find_program(CMAKE_LD ${TOOLCHAIN_PREFIX}-ld) +find_program(CMAKE_LINKER ${TOOLCHAIN_PREFIX}-ld) +find_program(CMAKE_NM ${TOOLCHAIN_PREFIX}-nm) +find_program(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-objcopy) +find_program(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}-objdump) +find_program(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}-gcc-ranlib) +find_program(CMAKE_STRIP ${TOOLCHAIN_PREFIX}-strip) + +set(CMAKE_FIND_ROOT_PATH get_file_component(${CMAKE_C_COMPILER} PATH)) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# os tools +foreach(tool grep make) + string(TOUPPER ${tool} TOOL) + find_program(${TOOL} ${tool}) + if(NOT ${TOOL}) + message(FATAL_ERROR "could not find ${tool}") + endif() +endforeach() diff --git a/platforms/nuttx/cmake/px4_impl_os.cmake b/platforms/nuttx/cmake/px4_impl_os.cmake index ef4e2212080..cefa37a6c28 100644 --- a/platforms/nuttx/cmake/px4_impl_os.cmake +++ b/platforms/nuttx/cmake/px4_impl_os.cmake @@ -170,6 +170,9 @@ function(px4_os_determine_build_chip) elseif(CONFIG_ARCH_CHIP_RP2040) set(CHIP_MANUFACTURER "rpi") set(CHIP "rp2040") + elseif(CONFIG_ARCH_CHIP_ESP32) + set(CHIP_MANUFACTURER "espressif") + set(CHIP "esp32") else() message(FATAL_ERROR "Could not determine chip architecture from NuttX config. You may have to add it.") endif() diff --git a/platforms/nuttx/src/px4/common/SerialImpl.cpp b/platforms/nuttx/src/px4/common/SerialImpl.cpp index a46c1bd548e..cd9caa49823 100644 --- a/platforms/nuttx/src/px4/common/SerialImpl.cpp +++ b/platforms/nuttx/src/px4/common/SerialImpl.cpp @@ -129,7 +129,11 @@ bool SerialImpl::configure() default: speed = _baudrate; +#ifdef CONFIG_ARCH_CHIP_ESP32 + PX4_WARN("Using non-standard baudrate: %u", _baudrate); +#else PX4_WARN("Using non-standard baudrate: %lu", _baudrate); +#endif break; } diff --git a/platforms/nuttx/src/px4/espressif/CMakeLists.txt b/platforms/nuttx/src/px4/espressif/CMakeLists.txt new file mode 100644 index 00000000000..72584f3178e --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/CMakeLists.txt @@ -0,0 +1,34 @@ +############################################################################ +# +# Copyright (c) 2019 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +add_subdirectory(${PX4_CHIP}) diff --git a/platforms/nuttx/src/px4/espressif/esp32/CMakeLists.txt b/platforms/nuttx/src/px4/espressif/esp32/CMakeLists.txt new file mode 100644 index 00000000000..80f70cea9ac --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/CMakeLists.txt @@ -0,0 +1,6 @@ +add_subdirectory(hrt hrt) +add_subdirectory(version version) +add_subdirectory(board_critmon board_critmon) +add_subdirectory(board_reset board_reset) +add_subdirectory(spi spi) +add_subdirectory(io_pins io_pins) diff --git a/platforms/nuttx/src/px4/espressif/esp32/board_critmon/CMakeLists.txt b/platforms/nuttx/src/px4/espressif/esp32/board_critmon/CMakeLists.txt new file mode 100644 index 00000000000..3edcbee0620 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/board_critmon/CMakeLists.txt @@ -0,0 +1,36 @@ +############################################################################ +# +# Copyright (C) 2021 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(arch_board_critmon + board_critmon.c +) diff --git a/platforms/nuttx/src/px4/espressif/esp32/board_critmon/board_critmon.c b/platforms/nuttx/src/px4/espressif/esp32/board_critmon/board_critmon.c new file mode 100644 index 00000000000..14e7a3bb3bb --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/board_critmon/board_critmon.c @@ -0,0 +1,66 @@ +/************************************************************************************ + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#if defined(CONFIG_SCHED_CRITMONITOR) || defined(CONFIG_SCHED_IRQMONITOR) + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#error "missing implementation for up_critmon_gettime() and up_critmon_convert()" + +/************************************************************************************ + * Name: up_critmon_gettime + ************************************************************************************/ + +// uint32_t up_critmon_gettime(void) +// { +// } + +/************************************************************************************ + * Name: up_critmon_convert + ************************************************************************************/ + +// void up_critmon_convert(uint32_t elapsed, FAR struct timespec *ts) +// { +// } + +#endif /* CONFIG_SCHED_CRITMONITOR */ diff --git a/platforms/nuttx/src/px4/espressif/esp32/board_reset/CMakeLists.txt b/platforms/nuttx/src/px4/espressif/esp32/board_reset/CMakeLists.txt new file mode 100644 index 00000000000..d1fb1802c30 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/board_reset/CMakeLists.txt @@ -0,0 +1,43 @@ +############################################################################ +# +# Copyright (C) 2021 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(arch_board_reset + board_reset.cpp +) + +# up_systemreset +if (NOT DEFINED CONFIG_BUILD_FLAT) + target_link_libraries(arch_board_reset PRIVATE nuttx_karch) +else() + target_link_libraries(arch_board_reset PRIVATE nuttx_arch) +endif() diff --git a/platforms/nuttx/src/px4/espressif/esp32/board_reset/board_reset.cpp b/platforms/nuttx/src/px4/espressif/esp32/board_reset/board_reset.cpp new file mode 100644 index 00000000000..8a2f8a517ba --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/board_reset/board_reset.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * Author: @author David Sidrane + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_reset.cpp + * Implementation of RP2040 based Board RESET API + */ + +#include +#include +#include +#include + +#include +#include +#include "esp32_systemreset.h" + + +// Functions in here are modified so that board_reset() function resembles +// the one available in nuttx's boards/raspberrypi-pico folder. + +#ifdef CONFIG_BOARDCTL_RESET + +/**************************************************************************** + * Name: board_reset + * + * Description: + * Reset board. Support for this function is required by board-level + * logic if CONFIG_BOARDCTL_RESET is selected. + * + * Input Parameters: + * status - Status information provided with the reset event. This + * meaning of this status information is board-specific. If not + * used by a board, the value zero may be provided in calls to + * board_reset(). + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ + +int board_reset(int status) +{ + up_systemreset(); + + return 0; +} +#endif /* CONFIG_BOARDCTL_RESET */ + +#if defined(SUPPORT_ALT_CAN_BOOTLOADER) +/**************************************************************************** + * Name: board_booted_by_px4 + * + * Description: + * Determines if the the boot loader was PX4 + * + * Input Parameters: + * none + * + * Returned Value: + * true if booted byt a PX4 bootloader. + * + ****************************************************************************/ +bool board_booted_by_px4(void) +{ + uint32_t *vectors = (uint32_t *) STM32_FLASH_BASE; + + /* Nuttx uses common vector */ + + return (vectors[2] == vectors[3]) && (vectors[4] == vectors[5]); +} +#endif diff --git a/platforms/nuttx/src/px4/espressif/esp32/hrt/CMakeLists.txt b/platforms/nuttx/src/px4/espressif/esp32/hrt/CMakeLists.txt new file mode 100644 index 00000000000..82854e0def2 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/hrt/CMakeLists.txt @@ -0,0 +1,41 @@ +############################################################################ +# +# Copyright (c) 2015-2019 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(arch_hrt + hrt.c +) +target_compile_options(arch_hrt + PRIVATE + ${MAX_CUSTOM_OPT_LEVEL} + -Wno-cast-align # TODO: fix and enable +) diff --git a/platforms/nuttx/src/px4/espressif/esp32/hrt/hrt.c b/platforms/nuttx/src/px4/espressif/esp32/hrt/hrt.c new file mode 100644 index 00000000000..3e714cc1a67 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/hrt/hrt.c @@ -0,0 +1,636 @@ +/**************************************************************************** + * + * Copyright (c) 2012, 2013 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file drv_hrt.c + * + * High-resolution timer callouts and timekeeping. + * + * This can use any general or advanced STM32 timer. + * + * Note that really, this could use systick too, but that's + * monopolised by NuttX and stealing it would just be awkward. + * + * We don't use the NuttX STM32 driver per se; rather, we + * claim the timer and then drive it directly. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "esp32_irq.h" +#include + +#include +#include + +#ifdef CONFIG_DEBUG_HRT +# define hrtinfo _info +#else +# define hrtinfo(x...) +#endif + +#ifdef HRT_TIMER + +/* HRT configuration */ +#if HRT_TIMER == 0 +# define HRT_TIM_BASE 0x3ff5f000 +# define HRT_TIMER_PERIPH 14 +# define HRT_TIMER_PRIO 1 +# define HRT_TIMER_VECTOR 5 + HRT_TIMER_PERIPH +# define HRT_TIMER_CLOCK 80 * 1000000 +# define HRT_TIMER_BASE 0x3ff5f000 +# define HRT_TIMER_CLR_OFFSET 0x00a4 +# define HRT_TIMER_INT_ENA_OFFSET 0x0098 +# define HRT_TIMER_INT_CLR 1 << 0 +# if CONFIG_ESP32_WIFI +# error must not set CONFIG_ESP32_WIFI=y and HRT_TIMER=0. WIFI makes use of TIMER=0 +# endif +#elif HRT_TIMER == 1 +# define HRT_TIM_BASE 0x3ff5f000 + 0x0024 +# define HRT_TIMER_PERIPH 15 +# define HRT_TIMER_PRIO 1 +# define HRT_TIMER_VECTOR 5 + HRT_TIMER_PERIPH +# define HRT_TIMER_CLOCK 80 * 1000000 +# define HRT_TIMER_BASE 0x3ff5f000 + 0x0024 +# define HRT_TIMER_CLR_OFFSET 0x0080 +# define HRT_TIMER_INT_ENA_OFFSET 0x0074 +# define HRT_TIMER_INT_CLR 1 << 1 +# if CONFIG_ESP32_TIMER1 +# error must not set CONFIG_ESP32_TIMER1=y and HRT_TIMER=1 +# endif +#elif HRT_TIMER == 2 +# define HRT_TIM_BASE 0x3ff5f000 + 0x1000 +# define HRT_TIMER_PERIPH 18 +# define HRT_TIMER_PRIO 1 +# define HRT_TIMER_VECTOR 5 + HRT_TIMER_PERIPH +# define HRT_TIMER_CLOCK 80 * 1000000 +# define HRT_TIMER_BASE 0x3ff5f000 + 0x1000 +# define HRT_TIMER_CLR_OFFSET 0x00a4 +# define HRT_TIMER_INT_ENA_OFFSET 0x0098 +# define HRT_TIMER_INT_CLR 1 << 0 +# if CONFIG_ESP32_TIMER2 +# error must not set CONFIG_ESP32_TIMER2=y and HRT_TIMER=2 +# endif +#elif HRT_TIMER == 3 +# define HRT_TIM_BASE 0x3ff5f000 + 0x0024 + 0x1000 +# define HRT_TIMER_PERIPH 19 +# define HRT_TIMER_PRIO 1 +# define HRT_TIMER_VECTOR 5 + HRT_TIMER_PERIPH +# define HRT_TIMER_CLOCK 80 * 1000000 +# define HRT_TIMER_BASE 0x3ff5f000 + 0x0024 + 0x1000 +# define HRT_TIMER_CLR_OFFSET 0x0080 +# define HRT_TIMER_INT_ENA_OFFSET 0x0074 +# define HRT_TIMER_INT_CLR 1 << 1 +# if CONFIG_ESP32_TIMER3 +# error must not set CONFIG_ESP32_TIMER3=y and HRT_TIMER=3 +# endif +#else +# error HRT_TIMER must be a value between 0 and 3 +#endif + +#define REG(_reg) (*(volatile uint32_t *)(HRT_TIMER_BASE + _reg)) + +#define HRT_CONFIG_OFFSET 0x00 +#define HRT_LOAD_LO_OFFSET 0x0018 +#define HRT_LOAD_HI_OFFSET 0x001c +#define HRT_LOAD_OFFSET 0x0020 +#define HRT_ALARM_LO_OFFSET 0x0010 +#define HRT_ALARM_HI_OFFSET 0x0014 +#define HRT_UPDATE_OFFSET 0x000c +#define HRT_LO_OFFSET 0x0004 +#define HRT_HI_OFFSET 0x0008 +#define HRT_DIVIDER_S 13 +#define HRT_DIVIDER_M 0xffff << 13 +#define HRT_ALARM_EN 1 << 10 +#define HRT_AUTORELOAD 1 << 29 +#define HRT_TIMER_LEVEL_INT_EN 1 << 11 +#define HRT_TIMER_INT_ENA 1 << 0 +#define HRT_TIMER_EN 1 << 31 +#define HRT_INCREASE 1 << 30 + +#define rLO REG(HRT_LO_OFFSET) +#define rHI REG(HRT_HI_OFFSET) +#define rUPDATE REG(HRT_UPDATE_OFFSET) +#define rALARMLO REG(HRT_ALARM_LO_OFFSET) +#define rALARMHI REG(HRT_ALARM_HI_OFFSET) + +/* + * HRT clock must be a multiple of 1MHz greater than 1MHz + */ +#if (HRT_TIMER_CLOCK % 1000000) != 0 +# error HRT_TIMER_CLOCK must be a multiple of 1MHz +#endif +#if HRT_TIMER_CLOCK <= 1000000 +# error HRT_TIMER_CLOCK must be greater than 1MHz +#endif + +/** + * Minimum/maximum deadlines. + * + * These are suitable for use with a 16-bit timer/counter clocked + * at 1MHz. The high-resolution timer need only guarantee that it + * not wrap more than once in the 50ms period for absolute time to + * be consistently maintained. + * + * The minimum deadline must be such that the time taken between + * reading a time and writing a deadline to the timer cannot + * result in missing the deadline. + */ +#define HRT_INTERVAL_MIN 50 +#define HRT_INTERVAL_MAX 50000 + +/* + * Period of the free-running counter, in microseconds. + */ +#define HRT_COUNTER_PERIOD 18446744073709551615 + +/* + * Scaling factor(s) for the free-running counter; convert an input + * in counts to a time in microseconds. + */ +#define HRT_COUNTER_SCALE(_c) (_c) + +/* + * Queue of callout entries. + */ +static struct sq_queue_s callout_queue; + +/* latency baseline (last compare value applied) */ +static uint64_t latency_baseline; + +/* timer count at interrupt (for latency purposes) */ +static uint64_t latency_actual; + +/* latency histogram */ +const uint16_t latency_bucket_count = LATENCY_BUCKET_COUNT; +const uint16_t latency_buckets[LATENCY_BUCKET_COUNT] = { 1, 2, 5, 10, 20, 50, 100, 1000 }; +__EXPORT uint32_t latency_counters[LATENCY_BUCKET_COUNT + 1]; + +/* timer-specific functions */ +static void hrt_tim_init(void); +static int hrt_tim_isr(int irq, void *context, void *arg); +static void hrt_latency_update(void); +static void esp32_tim_modifyreg32(uint32_t base, uint32_t offset, uint32_t clearbits, uint32_t setbits); +static void esp32_tim_putreg(uint32_t base, uint32_t offset, uint32_t value); +static uint32_t esp32_tim_getreg(uint32_t base, uint32_t offset); + +/* callout list manipulation */ +static void hrt_call_internal(struct hrt_call *entry, + hrt_abstime deadline, + hrt_abstime interval, + hrt_callout callout, + void *arg); +static void hrt_call_enter(struct hrt_call *entry); +static void hrt_call_reschedule(void); +static void hrt_call_invoke(void); + + +int hrt_ioctl(unsigned int cmd, unsigned long arg); + +static void esp32_tim_modifyreg32(uint32_t base, uint32_t offset, uint32_t clearbits, uint32_t setbits) +{ + modifyreg32(base + offset, clearbits, setbits); +} +static void esp32_tim_putreg(uint32_t base, uint32_t offset, uint32_t value) +{ + putreg32(value, base + offset); +} +static uint32_t esp32_tim_getreg(uint32_t base, uint32_t offset) +{ + + return getreg32(base + offset); +} + +/** + * Initialise the timer we are going to use. + * + * We expect that we'll own one of the reduced-function STM32 general + * timers, and that we can use channel 1 in compare mode. + */ + +static void +hrt_tim_init(void) +{ + + // ESP32_TIM_SETPRE(tim, ESP32_HRT_TIMER_PRESCALER); + uint32_t mask = ((uint32_t)(HRT_TIMER_CLOCK / 1000000) - 1) << HRT_DIVIDER_S; + esp32_tim_modifyreg32(HRT_TIM_BASE, HRT_CONFIG_OFFSET, HRT_DIVIDER_M, mask); + + // ESP32_TIM_SETMODE(tim, ESP32_TIM_MODE_UP); + esp32_tim_modifyreg32(HRT_TIM_BASE, HRT_CONFIG_OFFSET, 0, HRT_INCREASE); + + // ESP32_TIM_CLEAR(tim); + esp32_tim_putreg(HRT_TIM_BASE, HRT_LOAD_LO_OFFSET, 0); + esp32_tim_putreg(HRT_TIM_BASE, HRT_LOAD_HI_OFFSET, 0); + esp32_tim_putreg(HRT_TIM_BASE, HRT_LOAD_OFFSET, 1 << 0); //reload + + // ESP32_TIM_SETCTR(tim, 0); //set counter value + esp32_tim_putreg(HRT_TIM_BASE, HRT_LOAD_LO_OFFSET, 0); + esp32_tim_putreg(HRT_TIM_BASE, HRT_LOAD_HI_OFFSET, 0); + + // ESP32_TIM_RLD_NOW(tim); //reload value now + esp32_tim_putreg(HRT_TIM_BASE, HRT_LOAD_OFFSET, 1 << 0); //reload + + // ESP32_TIM_SETALRVL(tim, 1000); //alarm value + uint64_t val = 1000; + uint64_t low_64 = val & 0xffffffff; + uint64_t high_64 = (val >> 32) & 0xffffffff; + esp32_tim_putreg(HRT_TIM_BASE, HRT_ALARM_LO_OFFSET, (uint32_t)low_64); + esp32_tim_putreg(HRT_TIM_BASE, HRT_ALARM_HI_OFFSET, (uint32_t)high_64); + + // ESP32_TIM_SETALRM(tim, true); //enable alarm + esp32_tim_modifyreg32(HRT_TIM_BASE, HRT_CONFIG_OFFSET, 0, HRT_ALARM_EN); + // ESP32_TIM_SETARLD(tim, false); //auto reload + esp32_tim_modifyreg32(HRT_TIM_BASE, HRT_CONFIG_OFFSET, HRT_AUTORELOAD, 0); + + // ESP32_TIM_SETISR(tim, hrt_tim_isr, NULL); + esp32_setup_irq(0, HRT_TIMER_PERIPH, HRT_TIMER_PRIO, ESP32_CPUINT_LEVEL); + irq_attach(HRT_TIMER_VECTOR, hrt_tim_isr, NULL); + up_enable_irq(HRT_TIMER_VECTOR); + + // ESP32_TIM_ENABLEINT(tim); + esp32_tim_modifyreg32(HRT_TIM_BASE, HRT_CONFIG_OFFSET, 0, HRT_TIMER_LEVEL_INT_EN); + esp32_tim_modifyreg32(HRT_TIM_BASE, HRT_TIMER_INT_ENA_OFFSET, 0, HRT_TIMER_INT_ENA); + + // ESP32_TIM_START(tim); + esp32_tim_modifyreg32(HRT_TIM_BASE, HRT_CONFIG_OFFSET, 0, HRT_TIMER_EN); + +} + +/** + * Handle the compare interrupt by calling the callout dispatcher + * and then re-scheduling the next deadline. + */ +static int IRAM_ATTR +hrt_tim_isr(int irq, void *context, void *arg) +{ + // uint32_t status = REG_READ(DPORT_APP_INTR_STATUS_1_REG); + + /* grab the timer for latency tracking purposes */ + uint32_t value_32; + latency_actual = 0; + /* Dummy value to latch the counter value to read it */ + esp32_tim_putreg(HRT_TIM_BASE, HRT_UPDATE_OFFSET, 1 << 0); + /* Read value */ + value_32 = esp32_tim_getreg(HRT_TIM_BASE, HRT_HI_OFFSET); /* High 32 bits */ + latency_actual |= (uint64_t)value_32; + latency_actual <<= 32; + value_32 = esp32_tim_getreg(HRT_TIM_BASE, HRT_LO_OFFSET); /* Low 32 bits */ + latency_actual |= (uint64_t)value_32; + + /* do latency calculations */ + hrt_latency_update(); + + /* run any callouts that have met their deadline */ + hrt_call_invoke(); + + /* and schedule the next interrupt */ + hrt_call_reschedule(); + + // acknowledge the interrupt + esp32_tim_putreg(HRT_TIM_BASE, HRT_TIMER_CLR_OFFSET, HRT_TIMER_INT_CLR); + esp32_tim_modifyreg32(HRT_TIM_BASE, HRT_CONFIG_OFFSET, 0, HRT_ALARM_EN); + + return OK; +} + +/** + * Fetch a never-wrapping absolute time value in microseconds from + * some arbitrary epoch shortly after system start. + */ +hrt_abstime IRAM_ATTR +hrt_absolute_time(void) +{ + hrt_abstime abstime; + // uint64_t count; + irqstate_t flags; + + /* + * Counter state. Marked volatile as they may change + * inside this routine but outside the irqsave/restore + * pair. Discourage the compiler from moving loads/stores + * to these outside of the protected range. + */ + // static volatile uint64_t last_count; + + /* prevent re-entry */ + flags = px4_enter_critical_section(); + rUPDATE = 1; + abstime = (hrt_abstime)(((uint64_t)rHI << 32) | (uint64_t)rLO); + + px4_leave_critical_section(flags); + + return abstime; +} + +/** + * Store the absolute time in an interrupt-safe fashion + */ +void +hrt_store_absolute_time(volatile hrt_abstime *t) +{ + irqstate_t flags = px4_enter_critical_section(); + *t = hrt_absolute_time(); + px4_leave_critical_section(flags); +} + +/** + * Initialise the high-resolution timing module. + */ +void +hrt_init(void) +{ + sq_init(&callout_queue); + hrt_tim_init(); + +} + +/** + * Call callout(arg) after interval has elapsed. + */ +void __attribute__((section(".iram1"))) +hrt_call_after(struct hrt_call *entry, hrt_abstime delay, hrt_callout callout, void *arg) +{ + hrt_call_internal(entry, + hrt_absolute_time() + delay, + 0, + callout, + arg); +} + +/** + * Call callout(arg) at calltime. + */ +void __attribute__((section(".iram1"))) +hrt_call_at(struct hrt_call *entry, hrt_abstime calltime, hrt_callout callout, void *arg) +{ + hrt_call_internal(entry, calltime, 0, callout, arg); +} + +/** + * Call callout(arg) every period. + */ +void __attribute__((section(".iram1"))) +hrt_call_every(struct hrt_call *entry, hrt_abstime delay, hrt_abstime interval, hrt_callout callout, void *arg) +{ + hrt_call_internal(entry, + hrt_absolute_time() + delay, + interval, + callout, + arg); +} + +static void __attribute__((section(".iram1"))) +hrt_call_internal(struct hrt_call *entry, hrt_abstime deadline, hrt_abstime interval, hrt_callout callout, void *arg) +{ + irqstate_t flags = px4_enter_critical_section(); + + /* if the entry is currently queued, remove it */ + /* note that we are using a potentially uninitialised + entry->link here, but it is safe as sq_rem() doesn't + dereference the passed node unless it is found in the + list. So we potentially waste a bit of time searching the + queue for the uninitialised entry->link but we don't do + anything actually unsafe. + */ + if (entry->deadline != 0) { + sq_rem(&entry->link, &callout_queue); + } + + entry->deadline = deadline; + entry->period = interval; + entry->callout = callout; + entry->arg = arg; + + hrt_call_enter(entry); + + px4_leave_critical_section(flags); +} + +/** + * If this returns true, the call has been invoked and removed from the callout list. + * + * Always returns false for repeating callouts. + */ +bool __attribute__((section(".iram1"))) +hrt_called(struct hrt_call *entry) +{ + return (entry->deadline == 0); +} + +/** + * Remove the entry from the callout list. + */ +void __attribute__((section(".iram1"))) +hrt_cancel(struct hrt_call *entry) +{ + irqstate_t flags = px4_enter_critical_section(); + + sq_rem(&entry->link, &callout_queue); + entry->deadline = 0; + + /* if this is a periodic call being removed by the callout, prevent it from + * being re-entered when the callout returns. + */ + entry->period = 0; + + px4_leave_critical_section(flags); +} + +static void __attribute__((section(".iram1"))) +hrt_call_enter(struct hrt_call *entry) +{ + struct hrt_call *call, *next; + + call = (struct hrt_call *)sq_peek(&callout_queue); + + if ((call == NULL) || (entry->deadline < call->deadline)) { + sq_addfirst(&entry->link, &callout_queue); + hrtinfo("call enter at head, reschedule\n"); + /* we changed the next deadline, reschedule the timer event */ + hrt_call_reschedule(); + + } else { + do { + next = (struct hrt_call *)sq_next(&call->link); + + if ((next == NULL) || (entry->deadline < next->deadline)) { + hrtinfo("call enter after head\n"); + sq_addafter(&call->link, &entry->link, &callout_queue); + break; + } + } while ((call = next) != NULL); + } + + hrtinfo("scheduled\n"); +} + +static void __attribute__((section(".iram1"))) +hrt_call_invoke(void) +{ + struct hrt_call *call; + hrt_abstime deadline; + + while (true) { + /* get the current time */ + hrt_abstime now = hrt_absolute_time(); + + call = (struct hrt_call *)sq_peek(&callout_queue); + + if (call == NULL) { + break; + } + + if (call->deadline > now) { + break; + } + + sq_rem(&call->link, &callout_queue); + hrtinfo("call pop\n"); + + /* save the intended deadline for periodic calls */ + deadline = call->deadline; + + /* zero the deadline, as the call has occurred */ + call->deadline = 0; + + /* invoke the callout (if there is one) */ + if (call->callout) { + hrtinfo("call %p: %p(%p)\n", call, call->callout, call->arg); + call->callout(call->arg); + } + + /* if the callout has a non-zero period, it has to be re-entered */ + if (call->period != 0) { + // re-check call->deadline to allow for + // callouts to re-schedule themselves + // using hrt_call_delay() + if (call->deadline <= now) { + call->deadline = deadline + call->period; + } + + hrt_call_enter(call); + } + } +} + +/** + * Reschedule the next timer interrupt. + * + * This routine must be called with interrupts disabled. + */ +static void __attribute__((section(".iram1"))) +hrt_call_reschedule() +{ + hrt_abstime now = hrt_absolute_time(); + struct hrt_call *next = (struct hrt_call *)sq_peek(&callout_queue); + hrt_abstime deadline = now + HRT_INTERVAL_MAX; + + /* + * Determine what the next deadline will be. + * + * Note that we ensure that this will be within the counter + * period, so that when we truncate all but the low 16 bits + * the next time the compare matches it will be the deadline + * we want. + * + * It is important for accurate timekeeping that the compare + * interrupt fires sufficiently often that the base_time update in + * hrt_absolute_time runs at least once per timer period. + */ + if (next != NULL) { + hrtinfo("entry in queue\n"); + + if (next->deadline <= (now + HRT_INTERVAL_MIN)) { + hrtinfo("pre-expired\n"); + /* set a minimal deadline so that we call ASAP */ + deadline = now + HRT_INTERVAL_MIN; + + } else if (next->deadline < deadline) { + hrtinfo("due soon\n"); + deadline = next->deadline; + } + } + + hrtinfo("schedule for %u at %u\n", (unsigned)(deadline & 0xffffffff), (unsigned)(now & 0xffffffff)); + + /* set the new compare value and remember it for latency tracking */ + latency_baseline = deadline & 0xffff; + + rALARMLO = (uint32_t)(deadline & 0xffffffff); + rALARMHI = (uint32_t)((deadline >> 32) & 0xffffffff); +} + +static void +hrt_latency_update(void) +{ + uint16_t latency = latency_actual - latency_baseline; + unsigned index; + + /* bounded buckets */ + for (index = 0; index < LATENCY_BUCKET_COUNT; index++) { + if (latency <= latency_buckets[index]) { + latency_counters[index]++; + return; + } + } + + /* catch-all at the end */ + latency_counters[index]++; +} + +void __attribute__((section(".iram1"))) +hrt_call_init(struct hrt_call *entry) +{ + memset(entry, 0, sizeof(*entry)); +} + +void __attribute__((section(".iram1"))) +hrt_call_delay(struct hrt_call *entry, hrt_abstime delay) +{ + entry->deadline = hrt_absolute_time() + delay; +} + +#endif /* HRT_TIMER */ diff --git a/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/adc.h b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/adc.h new file mode 100644 index 00000000000..5ae5548411b --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/adc.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * + * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once + +#include + +#define SYSTEM_ADC_BASE 0 // not used on kinetis + +#include diff --git a/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/hw_description.h b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/hw_description.h new file mode 100644 index 00000000000..6137ec69089 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/hw_description.h @@ -0,0 +1,245 @@ +/**************************************************************************** + * + * Copyright (C) 2019 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + + +#include + +#include "hardware/esp32_tim.h" +#include "hardware/esp32_gpio.h" +#include "hardware/esp32_soc.h" + +#include + +/* + * Timers + */ + +namespace Timer +{ +enum Timer { + Timer0 = 0, + Timer1, + Timer2, + Timer3, +}; +// These are actually the Operators +enum Channel { + Channel0 = 0, + Channel1, + Channel2, + Channel3, + Channel4, + Channel5, + Channel6, + Channel7 +}; +struct TimerChannel { + Timer timer; + Channel channel; +}; +} + +static inline constexpr uint32_t timerBaseRegister(Timer::Timer timer) +{ + switch (timer) { + case Timer::Timer0: return DR_REG_PWM_BASE + 0x04; + + case Timer::Timer1: return DR_REG_PWM1_BASE + 0x04; + + case Timer::Timer2: return DR_REG_PWM1_BASE + 0x04; + + case Timer::Timer3: return DR_REG_PWM1_BASE + 0x04; + } + + return 0; +} + +/* + * GPIO + */ + +namespace GPIO +{ + +enum Pin { + Pin0 = 0, + Pin1, + Pin2, + Pin3, + Pin4, + Pin5, + Pin6, + Pin7, + Pin8, + Pin9, + Pin10, + Pin11, + Pin12, + Pin13, + Pin14, + Pin15, + Pin16, + Pin17, + Pin18, + Pin19, + Pin20, + Pin21, + Pin22, + Pin23, + Pin24, + Pin25, + Pin26, + Pin27, + Pin28, + Pin29, + Pin30, + Pin31, + Pin32, + Pin33, + Pin34, + Pin35, + Pin36, + Pin37, + Pin38, +}; +struct GPIOPin { + Pin pin; +}; +} + +static inline constexpr uint32_t getGPIOPin(GPIO::Pin pin) +{ + switch (pin) { + case GPIO::Pin0: return 0; + + case GPIO::Pin1: return 1; + + case GPIO::Pin2: return 2; + + case GPIO::Pin3: return 3; + + case GPIO::Pin4: return 4; + + case GPIO::Pin5: return 5; + + case GPIO::Pin6: return 6; + + case GPIO::Pin7: return 7; + + case GPIO::Pin8: return 8; + + case GPIO::Pin9: return 9; + + case GPIO::Pin10: return 10; + + case GPIO::Pin11: return 11; + + case GPIO::Pin12: return 12; + + case GPIO::Pin13: return 13; + + case GPIO::Pin14: return 14; + + case GPIO::Pin15: return 15; + + case GPIO::Pin16: return 16; + + case GPIO::Pin17: return 17; + + case GPIO::Pin18: return 18; + + case GPIO::Pin19: return 19; + + case GPIO::Pin20: return 20; + + case GPIO::Pin21: return 21; + + case GPIO::Pin22: return 22; + + case GPIO::Pin23: return 23; + + case GPIO::Pin24: return 24; + + case GPIO::Pin25: return 25; + + case GPIO::Pin26: return 26; + + case GPIO::Pin27: return 27; + + case GPIO::Pin28: return 28; + + case GPIO::Pin29: return 29; + + case GPIO::Pin30: return 30; + + case GPIO::Pin31: return 31; + + case GPIO::Pin32: return 32; + + case GPIO::Pin33: return 33; + + case GPIO::Pin34: return 34; + + case GPIO::Pin35: return 35; + + case GPIO::Pin36: return 36; + + case GPIO::Pin37: return 37; + + case GPIO::Pin38: return 38; + + } + + return 0; +} + +namespace SPI +{ + +enum class Bus { + SPI1 = 1, + SPI2, + SPI3, +}; + +using CS = GPIO::GPIOPin; ///< chip-select pin +using DRDY = GPIO::GPIOPin; ///< data ready pin + +struct bus_device_external_cfg_t { + CS cs_gpio; + DRDY drdy_gpio; +}; + +} // namespace SPI diff --git a/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/i2c_hw_description.h b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/i2c_hw_description.h new file mode 100644 index 00000000000..4b7940e1dd1 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/i2c_hw_description.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include + +#if defined(CONFIG_I2C) + +static inline constexpr px4_i2c_bus_t initI2CBusInternal(int bus) +{ + px4_i2c_bus_t ret{}; + ret.bus = bus; + ret.is_external = false; + return ret; +} + +static inline constexpr px4_i2c_bus_t initI2CBusExternal(int bus) +{ + px4_i2c_bus_t ret{}; + ret.bus = bus; + ret.is_external = true; + return ret; +} +#endif // CONFIG_I2C diff --git a/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/io_timer.h b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/io_timer.h new file mode 100644 index 00000000000..9efb7161739 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/io_timer.h @@ -0,0 +1,176 @@ +/**************************************************************************** + * + * Copyright (C) 2012, 2017 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file io_timer.h + */ +#include +#include +#include + +#include + +#pragma once +__BEGIN_DECLS +/* configuration limits */ +#ifdef BOARD_NUM_IO_TIMERS +#define MAX_IO_TIMERS BOARD_NUM_IO_TIMERS +#else +#define MAX_IO_TIMERS 1 +#endif +#if DIRECT_PWM_OUTPUT_CHANNELS > 8 +#define MAX_TIMER_IO_CHANNELS DIRECT_PWM_OUTPUT_CHANNELS +#else +#define MAX_TIMER_IO_CHANNELS 8 +#endif + +#define MAX_LED_TIMERS 2 +#define MAX_TIMER_LED_CHANNELS 6 + +#define MAX_SPIX_SYNC_TIMERS 2 +#define MAX_TIMER_SPIX_SYNC_CHANNELS 2 + +#define IO_TIMER_ALL_MODES_CHANNELS 0 + +typedef enum io_timer_channel_mode_t { + IOTimerChanMode_NotUsed = 0, + IOTimerChanMode_PWMOut = 1, + IOTimerChanMode_PWMIn = 2, + IOTimerChanMode_Capture = 3, + IOTimerChanMode_OneShot = 4, + IOTimerChanMode_Trigger = 5, + IOTimerChanMode_Dshot = 6, + IOTimerChanMode_LED = 7, + IOTimerChanMode_PPS = 8, + IOTimerChanMode_Other = 9, + IOTimerChanModeSize +} io_timer_channel_mode_t; + +typedef uint16_t io_timer_channel_allocation_t; /* big enough to hold MAX_TIMER_IO_CHANNELS */ + +/* array of timers dedicated to PWM in and out and capture use + *** Note that the clock_freq is set to the source in the clock tree that + *** feeds this specific timer. This can differs by Timer! + *** In PWM mode the timer's prescaler is set to achieve a counter frequency of 1MHz + *** In OneShot mode the timer's prescaler is set to achieve a counter frequency of 8MHz + *** Other prescaler rates can be achieved by fore instance by setting the clock_freq = 1Mhz + *** the resulting PSC will be one and the timer will count at it's clock frequency. + */ +typedef struct io_timers_t { + uint32_t base; + uint32_t clock_register; + uint32_t clock_bit; + uint32_t clock_freq; + uint32_t vectorno; +} io_timers_t; + +typedef struct io_timers_channel_mapping_element_t { + uint32_t first_channel_index; + uint32_t channel_count; + uint32_t lowest_timer_channel; + uint32_t channel_count_including_gaps; +} io_timers_channel_mapping_element_t; + +/* mapping for each io_timers to timer_io_channels */ +typedef struct io_timers_channel_mapping_t { + io_timers_channel_mapping_element_t element[MAX_IO_TIMERS]; +} io_timers_channel_mapping_t; + +/* array of channels in logical order */ +typedef struct timer_io_channels_t { + uint32_t gpio_out; + uint32_t gpio_in; + uint8_t timer_index; + uint8_t timer_channel; + uint16_t masks; + uint8_t ccr_offset; +} timer_io_channels_t; + +typedef void (*channel_handler_t)(void *context, const io_timers_t *timer, uint32_t chan_index, + const timer_io_channels_t *chan, + hrt_abstime isrs_time, uint16_t isrs_rcnt); + + +/* supplied by board-specific code */ +__EXPORT extern const io_timers_t io_timers[MAX_IO_TIMERS]; +__EXPORT extern const io_timers_channel_mapping_t io_timers_channel_mapping; +__EXPORT extern const timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS]; + +__EXPORT extern const io_timers_t led_pwm_timers[MAX_LED_TIMERS]; +__EXPORT extern const timer_io_channels_t led_pwm_channels[MAX_TIMER_LED_CHANNELS]; + +__EXPORT extern const io_timers_t spix_sync_timers[MAX_SPIX_SYNC_TIMERS]; +__EXPORT extern const io_timers_channel_mapping_t spix_sync_channel_mapping; +__EXPORT extern const timer_io_channels_t spix_sync_channels[MAX_TIMER_SPIX_SYNC_CHANNELS]; + +__EXPORT int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode, + channel_handler_t channel_handler, void *context); + +__EXPORT int io_timer_init_timer(unsigned timer, io_timer_channel_mode_t mode); + +__EXPORT int io_timer_set_pwm_rate(unsigned timer, unsigned rate); +__EXPORT int io_timer_set_enable(bool state, io_timer_channel_mode_t mode, + io_timer_channel_allocation_t masks); +__EXPORT uint16_t io_channel_get_ccr(unsigned channel); +__EXPORT int io_timer_set_ccr(unsigned channel, uint16_t value); +__EXPORT uint32_t io_timer_get_group(unsigned timer); +__EXPORT int io_timer_validate_channel_index(unsigned channel); +__EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t mode); +__EXPORT int io_timer_unallocate_channel(unsigned channel); +__EXPORT int io_timer_get_channel_mode(unsigned channel); +__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode); +__EXPORT extern void io_timer_trigger(unsigned channels_mask); +__EXPORT void io_timer_update_dma_req(uint8_t timer, bool enable); + +/** + * Reserve a timer + * @return 0 on success (if not used yet, or already set to the mode) + */ +__EXPORT int io_timer_allocate_timer(unsigned timer, io_timer_channel_mode_t mode); + +__EXPORT int io_timer_unallocate_timer(unsigned timer); + +__EXPORT extern int io_timer_set_dshot_mode(uint8_t timer, unsigned dshot_pwm_rate, uint8_t dma_burst_length); + +/** + * Returns the pin configuration for a specific channel, to be used as GPIO output. + * 0 is returned if the channel is not valid. + */ +__EXPORT uint32_t io_timer_channel_get_gpio_output(unsigned channel); +/** + * Returns the pin configuration for a specific channel, to be used as PWM input. + * 0 is returned if the channel is not valid. + */ +__EXPORT uint32_t io_timer_channel_get_as_pwm_input(unsigned channel); + +__END_DECLS diff --git a/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/io_timer_hw_description.h b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/io_timer_hw_description.h new file mode 100644 index 00000000000..c7ba29387e5 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/io_timer_hw_description.h @@ -0,0 +1,170 @@ +/**************************************************************************** + * + * Copyright (C) 2019 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + + +#include +#include +#include +#include +#include +#include +#include + +// static inline constexpr timer_io_channels_t initIOTimerGPIOInOut(Timer::TimerChannel timer, GPIO::GPIOPin pin); + +#define initIOTimerChannelCapture initIOTimerChannel // alias, used for param metadata generation + +static inline constexpr timer_io_channels_t initIOTimerChannel(const io_timers_t io_timers_conf[MAX_IO_TIMERS], + Timer::TimerChannel timer, GPIO::GPIOPin pin) +{ + timer_io_channels_t ret = {}; + ret.gpio_out = getGPIOPin(pin.pin); + ret.timer_channel = timer.channel; + ret.timer_index = timer.timer; + + bool nuttx_incorrect_mapping = false; + + bool multiple_timers_configure = false; + bool timer_configured = false; + +#if defined(CONFIG_ESP32_LEDC_TIM0_CHANNELS) + multiple_timers_configure = timer_configured; + timer_configured = true; +#endif +#if defined(CONFIG_ESP32_LEDC_TIM1_CHANNELS) + multiple_timers_configure = timer_configured; + timer_configured = true; + +#endif +#if defined(CONFIG_ESP32_LEDC_TIM2_CHANNELS) + multiple_timers_configure = timer_configured; + timer_configured = true; +#endif +#if defined(CONFIG_ESP32_LEDC_TIM3_CHANNELS) + multiple_timers_configure = timer_configured; + timer_configured = true; +#endif + + int channel = timer.channel; + + switch (channel) { + case 0: +#if defined(CONFIG_ESP32_LEDC_CHANNEL0_PIN) + nuttx_incorrect_mapping = pin.pin == CONFIG_ESP32_LEDC_CHANNEL0_PIN; +#endif + break; + + case 1: +#if defined(CONFIG_ESP32_LEDC_CHANNEL1_PIN) + nuttx_incorrect_mapping = pin.pin == CONFIG_ESP32_LEDC_CHANNEL1_PIN; +#endif + break; + + case 2: +#if defined(CONFIG_ESP32_LEDC_CHANNEL2_PIN) + nuttx_incorrect_mapping = pin.pin == CONFIG_ESP32_LEDC_CHANNEL2_PIN; +#endif + break; + + case 3: +#if defined(CONFIG_ESP32_LEDC_CHANNEL3_PIN) + nuttx_incorrect_mapping = pin.pin == CONFIG_ESP32_LEDC_CHANNEL3_PIN; +#endif + break; + + default: + break; + } + + + constexpr_assert(nuttx_incorrect_mapping, "PX4 ChannelTimer Mapping different from Nuttx)"); + constexpr_assert(!multiple_timers_configure, "Only a single timer can be configured in Nuttx"); + + + return ret; +} + +static inline constexpr timer_io_channels_t initIOTimerChannelOutputClear(const io_timers_t + io_timers_conf[MAX_IO_TIMERS], Timer::TimerChannel timer, GPIO::GPIOPin pin) +{ + timer_io_channels_t ret = initIOTimerChannel(io_timers_conf, timer, pin); + ret.gpio_out |= 0; + return ret; +} + + +static inline constexpr io_timers_t initIOTimer(Timer::Timer timer) +{ + bool nuttx_config_timer_enabled = false; + io_timers_t ret{}; + + switch (timer) { + case Timer::Timer0: // refers to MCPWM peripheral 1 + ret.base = 0; +#if defined(CONFIG_ESP32_LEDC_TIM0) + nuttx_config_timer_enabled = true; +#endif + break; + + case Timer::Timer1: // refers to MCPWM peripheral 2 + ret.base = 1; +#if defined(CONFIG_ESP32_LEDC_TIM1) + nuttx_config_timer_enabled = true; +#endif + break; + + case Timer::Timer2: // refers to MCPWM peripheral 2 + ret.base = 2; +#if defined(CONFIG_ESP32_LEDC_TIM2) + nuttx_config_timer_enabled = true; +#endif + break; + + case Timer::Timer3: // refers to MCPWM peripheral 2 + ret.base = 4; +#if defined(CONFIG_ESP32_LEDC_TIM3) + nuttx_config_timer_enabled = true; +#endif + break; + + default: break; + } + + constexpr_assert(nuttx_config_timer_enabled, + "IO Timer requires NuttX timer config to be Enabled (CONFIG_ESP32_LEDC_TIMx)"); + + + return ret; +} diff --git a/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/micro_hal.h b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/micro_hal.h new file mode 100644 index 00000000000..5c76a581e9d --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/micro_hal.h @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright (c) 2019 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#pragma once + + +#include + +__BEGIN_DECLS + +#include +#include +#include +#include +#include + +#include + +# define PX4_CPU_UUID_WORD32_UNIQUE_H 1 /* Most significant digits change the least */ +# define PX4_CPU_UUID_WORD32_UNIQUE_M 1 /* Middle significant digits */ +# define PX4_CPU_UUID_WORD32_UNIQUE_L 0 /* Least significant digits change the most */ + +#define PX4_CPU_UUID_BYTE_LENGTH 8 +#define PX4_CPU_UUID_WORD32_LENGTH (PX4_CPU_UUID_BYTE_LENGTH/sizeof(uint32_t)) +#define PX4_CPU_MFGUID_BYTE_LENGTH PX4_CPU_UUID_BYTE_LENGTH + +#define px4_enter_critical_section() enter_critical_section() +#define px4_leave_critical_section(flags) leave_critical_section(flags) + +#define px4_udelay(usec) up_udelay(usec) +#define px4_mdelay(msec) up_mdelay(msec) + +#define px4_cache_aligned_data() +#define px4_cache_aligned_alloc malloc + +// bits Function +// 0-5 GPIO number. 0-40 is valid. +// 6 input +// 7 output +// 8 fun +// 9 pull up +// 10 pull down +// 11 open drain +// 12-14 GPIO function select +// 15-31 Unused + +#define GPIO_SET_SHIFT 6 +#define GPIO_INPUT (1 << 6) +#define GPIO_OUTPUT (1 << 7) +#define GPIO_FUNCTION (1 << 8) + +#define GPIO_PULLUP (1 << 9) +#define GPIO_PULLDOWN (1 << 10) +#define GPIO_OPEN_DRAIN (1 << 11) + +#define FUNCTION_SHIFT 6 +#define FUNCTION_1 (1 << FUNCTION_SHIFT) +#define FUNCTION_2 (2 << FUNCTION_SHIFT) +#define FUNCTION_3 (3 << FUNCTION_SHIFT) +#define FUNCTION_4 (4 << FUNCTION_SHIFT) +#define FUNCTION_5 (5 << FUNCTION_SHIFT) +#define FUNCTION_6 (6 << FUNCTION_SHIFT) + +#define GPIO_FUN(func) (func << 12) // Function select + +#define GPIO_NUM_MASK 0x3f +#define GPIO_INPUT_MASK 0x40 +#define GPIO_OUTPUT_MASK 0x80 +#define GPIO_FUNCTION_MASK 0x100 +#define GPIO_PULLUP_MASK 0x200 +#define GPIO_PULLDOWN_MASK 0x400 +#define GPIO_OPEN_DRAIN_MASK 0x800 +#define GPIO_FUN_SELECT_MASK 0x7000 + +int px4_esp32_configgpio(uint32_t pinset); +int px4_esp32_unconfiggpio(uint32_t pinset); +int esp32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, bool event, xcpt_t func, void *arg); +#define PX4_BUS_OFFSET 1 +#define px4_arch_configgpio(pinset) px4_esp32_configgpio(pinset) +#define px4_arch_unconfiggpio(pinset) px4_esp32_unconfiggpio(pinset) +#define px4_arch_gpioread(pinset) esp32_gpioread(pinset & GPIO_NUM_MASK) +#define px4_arch_gpiowrite(pinset, value) esp32_gpiowrite(pinset & GPIO_NUM_MASK, value) +#define px4_arch_gpiosetevent(pinset,r,f,e,fp,a) esp32_gpiosetevent(pinset,r,f,e,fp,a) + +#define px4_arch_mtd_dev() esp32_spiflash_get_mtd() + +#define px4_spibus_initialize(bus_num_1based) esp32_spibus_initialize(bus_num_1based) + +#define px4_i2cbus_initialize(bus_num_1based) esp32_i2cbus_initialize(PX4_BUS_NUMBER_FROM_PX4(bus_num_1based)) +#define px4_i2cbus_uninitialize(pdev) esp32_i2cbus_uninitialize(pdev) + +#define PX4_SOC_ARCH_ID PX4_SOC_ARCH_ID_UNUSED +#define PX4_FLASH_BASE ESP32_FLASH_BASE +#define PX4_NUMBER_I2C_BUSES 2 +#define PX4_ADC_INTERNAL_TEMP_SENSOR_CHANNEL 0 + + + +#undef DISABLED + +__END_DECLS diff --git a/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/spi_hw_description.h b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/spi_hw_description.h new file mode 100644 index 00000000000..a2e0a847a77 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/include/px4_arch/spi_hw_description.h @@ -0,0 +1,220 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include +#include + +#if defined(CONFIG_ESP32_SPI) + +#include + +static inline constexpr px4_spi_bus_device_t initSPIDevice(uint32_t devid, SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) +{ + px4_spi_bus_device_t ret{}; + + if (cs_gpio.pin == -1) { + ret.cs_gpio = 0; + + } else { + ret.cs_gpio = (cs_gpio.pin | GPIO_PULLUP | GPIO_OUTPUT); + } + + if (drdy_gpio.pin == -1) { + ret.drdy_gpio = 0; + + } else { + ret.drdy_gpio = (drdy_gpio.pin | GPIO_INPUT); + } + + if (PX4_SPIDEVID_TYPE(devid) == 0) { // it's a PX4 device (internal or external) + ret.devid = PX4_SPIDEV_ID(PX4_SPI_DEVICE_ID, devid); + + } else { // it's a NuttX device (e.g. SPIDEV_FLASH(0)) + ret.devid = devid; + } + + ret.devtype_driver = PX4_SPI_DEV_ID(devid); + return ret; +} + +static inline constexpr px4_spi_bus_t initSPIBus(SPI::Bus bus, const px4_spi_bus_devices_t &devices, + GPIO::GPIOPin power_enable = {}) +{ + px4_spi_bus_t ret{}; + ret.requires_locking = false; + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + ret.devices[i] = devices.devices[i]; + + + if (ret.devices[i].cs_gpio != 0) { + if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + int same_devices_count = 0; + + for (int j = 0; j < i; ++j) { + if (ret.devices[j].cs_gpio != 0) { + same_devices_count += (ret.devices[i].devid & 0xff) == (ret.devices[j].devid & 0xff); + } + } + + // increment the 2. LSB byte to allow multiple devices of the same type + ret.devices[i].devid |= same_devices_count << 8; + + } else { + // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) + ret.requires_locking = true; + } + } + } + + ret.bus = (int)bus; + ret.is_external = false; + + if (power_enable.pin == -1) { + ret.power_enable_gpio = 0; + + } else { + ret.power_enable_gpio = (power_enable.pin | GPIO_OUTPUT | GPIO_PULLUP); + } + + + return ret; +} + +// just a wrapper since we cannot pass brace-enclosed initialized arrays directly as arguments +struct bus_device_external_cfg_array_t { + SPI::bus_device_external_cfg_t devices[SPI_BUS_MAX_DEVICES]; +}; + +static inline constexpr px4_spi_bus_t initSPIBusExternal(SPI::Bus bus, const bus_device_external_cfg_array_t &devices) +{ + px4_spi_bus_t ret{}; + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + if (devices.devices[i].cs_gpio.pin == -1) { + break; + } + + ret.devices[i] = initSPIDevice(i, devices.devices[i].cs_gpio, devices.devices[i].drdy_gpio); + } + + ret.bus = (int)bus; + ret.is_external = true; + ret.requires_locking = false; // external buses are never accessed by NuttX drivers + return ret; +} + +static inline constexpr SPI::bus_device_external_cfg_t initSPIConfigExternal(SPI::CS cs_gpio, SPI::DRDY drdy_gpio = {}) +{ + SPI::bus_device_external_cfg_t ret{}; + ret.cs_gpio = cs_gpio; + ret.drdy_gpio = drdy_gpio; + return ret; +} + +struct px4_spi_bus_array_t { + px4_spi_bus_t item[SPI_BUS_MAX_BUS_ITEMS]; +}; +static inline constexpr px4_spi_bus_all_hw_t initSPIHWVersion(int hw_version_revision, + const px4_spi_bus_array_t &bus_items) +{ + px4_spi_bus_all_hw_t ret{}; + + for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) { + ret.buses[i] = bus_items.item[i]; + } + + ret.board_hw_version_revision = hw_version_revision; + return ret; +} +static constexpr bool validateSPIConfig(const px4_spi_bus_t spi_buses_conf[SPI_BUS_MAX_BUS_ITEMS]); + +static constexpr bool validateSPIConfig(const px4_spi_bus_all_hw_t spi_buses_conf[BOARD_NUM_SPI_CFG_HW_VERSIONS]) +{ + for (int ver = 0; ver < BOARD_NUM_SPI_CFG_HW_VERSIONS; ++ver) { + validateSPIConfig(spi_buses_conf[ver].buses); + } + + for (int ver = 1; ver < BOARD_NUM_SPI_CFG_HW_VERSIONS; ++ver) { + for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) { + const bool equal_power_enable_gpio = spi_buses_conf[ver].buses[i].power_enable_gpio == spi_buses_conf[ver - + 1].buses[i].power_enable_gpio; + // currently board_control_spi_sensors_power_configgpio() depends on that - this restriction can be removed + // by ensuring board_control_spi_sensors_power_configgpio() is called after the hw version is determined + // and SPI config is initialized. + constexpr_assert(equal_power_enable_gpio, "All HW versions must define the same power enable GPIO"); + } + } + + return false; +} + +constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS]) +{ + const bool nuttx_enabled_spi_buses[] = { + false, +#ifdef CONFIG_ESP32_SPI2 + true, +#else + false, +#endif +#ifdef CONFIG_ESP32_SPI3 + true, +#else + false, +#endif + false, + false, + false, + }; + + for (unsigned i = 0; i < sizeof(nuttx_enabled_spi_buses) / sizeof(nuttx_enabled_spi_buses[0]); ++i) { + bool found_bus = false; + + for (int j = 0; j < SPI_BUS_MAX_BUS_ITEMS; ++j) { + if (spi_busses_conf[j].bus == (int)i + 1) { + found_bus = true; + } + } + + // Either the bus is enabled in NuttX and configured in spi_busses_conf, or disabled and not configured + constexpr_assert(found_bus == nuttx_enabled_spi_buses[i], "SPI bus config mismatch (CONFIG_ESP32_SPIx)"); + } + + return false; +} + +#endif // CONFIG_SPI diff --git a/platforms/nuttx/src/px4/espressif/esp32/io_pins/CMakeLists.txt b/platforms/nuttx/src/px4/espressif/esp32/io_pins/CMakeLists.txt new file mode 100644 index 00000000000..5a260ab16b7 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/io_pins/CMakeLists.txt @@ -0,0 +1,44 @@ +############################################################################ +# +# Copyright (c) 2021 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(arch_io_pins + io_timer.c + esp32_pinset.c + pwm_servo.c + # pwm_trigger.c + # input_capture.c +) + +target_compile_options(arch_io_pins PRIVATE ${MAX_CUSTOM_OPT_LEVEL}) + +target_link_libraries(arch_io_pins PRIVATE drivers_board) diff --git a/platforms/nuttx/src/px4/espressif/esp32/io_pins/esp32_pinset.c b/platforms/nuttx/src/px4/espressif/esp32/io_pins/esp32_pinset.c new file mode 100644 index 00000000000..b2aa9961b90 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/io_pins/esp32_pinset.c @@ -0,0 +1,74 @@ +#include +#include + +#include + +#include +#include +#include +#include + +int px4_esp32_configgpio(uint32_t pinset) +{ + if ((pinset & GPIO_NUM_MASK) >= ESP32_NGPIOS) { + return -EINVAL; + } + + return esp32_configgpio((int)(pinset & GPIO_NUM_MASK), (uint16_t)(pinset >> GPIO_SET_SHIFT)); +} + +int px4_esp32_unconfiggpio(uint32_t pinset) +{ + return px4_esp32_configgpio((pinset & GPIO_NUM_MASK) | GPIO_INPUT | GPIO_OPEN_DRAIN); +} + +/**************************************************************************** + * Name: esp32_gpiosetevent + * + * Description: + * Sets/clears GPIO based event and interrupt triggers. + * + * Input Parameters: + * - pinset: GPIO pin configuration + * - risingedge: Enables interrupt on rising edges + * - fallingedge: Enables interrupt on falling edges + * - event: Generate event when set + * - func: When non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ +int esp32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, + bool event, xcpt_t func, void *arg) +{ + uint32_t pin = pinset & GPIO_NUM_MASK; + int irq = ESP32_PIN2IRQ(pin); + + if (event == true) { + int ret = irq_attach(irq, func, arg); + + if (ret < 0) { + syslog(LOG_ERR, "ERROR: irq_attach() failed: %d\n", ret); + return ret; + } + + if (risingedge == true && fallingedge == true) { + esp32_gpioirqenable(irq, CHANGE); + + } else if (risingedge == true && fallingedge == false) { + esp32_gpioirqenable(irq, RISING); + + } else if (risingedge == false && fallingedge == true) { + esp32_gpioirqenable(irq, FALLING); + } + + } else { + esp32_gpioirqdisable(irq); + } + + //syslog(LOG_INFO, "esp32_gpiosetevent: %d\n", ret); + return OK; +} diff --git a/platforms/nuttx/src/px4/espressif/esp32/io_pins/io_timer.c b/platforms/nuttx/src/px4/espressif/esp32/io_pins/io_timer.c new file mode 100644 index 00000000000..b9035e9f25a --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/io_pins/io_timer.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file io_timer.c + * + * Servo driver supporting PWM servos connected to RP2040 PWM blocks. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +uint32_t io_timer_get_group(unsigned timer) +{ + if (timer == 0) { + +#if defined(CONFIG_ESP32_LEDC_TIM0_CHANNELS) + return (1 << CONFIG_ESP32_LEDC_TIM0_CHANNELS) - 1; +#endif + return -1; + + } else if (timer == 1) { + +#if defined(CONFIG_ESP32_LEDC_TIM1_CHANNELS) + return (1 << CONFIG_ESP32_LEDC_TIM1_CHANNELS) - 1; +#endif + return -1; + + } else if (timer == 2) { +#if defined(CONFIG_ESP32_LEDC_TIM2_CHANNELS) + return (1 << CONFIG_ESP32_LEDC_TIM2_CHANNELS) - 1; +#endif + return -1; + + } else if (timer == 3) { +#if defined(CONFIG_ESP32_LEDC_TIM3_CHANNELS) + return (1 << CONFIG_ESP32_LEDC_TIM3_CHANNELS) - 1; +#endif + return -1; + } + + return -1; + +} + +uint32_t io_timer_channel_get_gpio_output(unsigned channel) +{ + return timer_io_channels[channel].gpio_out | GPIO_OUTPUT | GPIO_PULLUP; +} diff --git a/platforms/nuttx/src/px4/espressif/esp32/io_pins/pwm_servo.c b/platforms/nuttx/src/px4/espressif/esp32/io_pins/pwm_servo.c new file mode 100644 index 00000000000..da2b7e932a4 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/io_pins/pwm_servo.c @@ -0,0 +1,321 @@ +/**************************************************************************** + * + * Copyright (C) 2012, 2017 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* + * @file drv_pwm_servo.c + * + * Servo driver supporting PWM servos connected to STM32 timer blocks. + * + * Works with any of the 'generic' or 'advanced' STM32 timers that + * have output pins, does not require an interrupt. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +// #include +#include "xtensa.h" + + +#define DR_REG_DPORT_BASE 0x3ff00000 +#define DPORT_PERIP_CLK_EN_REG (DR_REG_DPORT_BASE + 0x0C0) +#define DPORT_PERIP_RST_EN_REG (DR_REG_DPORT_BASE + 0x0C4) + +#define DR_REG_LEDC_BASE 0x3ff59000 +#define LEDC_LSTIMER0_CONF_REG (DR_REG_LEDC_BASE + 0x0160) +#define LEDC_LSTIMER1_CONF_REG (DR_REG_LEDC_BASE + 0x0168) +#define LEDC_LSCH1_CONF0_REG (DR_REG_LEDC_BASE + 0x00B4) +#define LEDC_LSCH0_CONF0_REG (DR_REG_LEDC_BASE + 0x00A0) +#define LEDC_LSCH0_CONF1_REG (DR_REG_LEDC_BASE + 0x00AC) +#define LEDC_LSCH0_HPOINT_REG (DR_REG_LEDC_BASE + 0x00A4) +#define LEDC_LSCH0_DUTY_REG (DR_REG_LEDC_BASE + 0x00A8) +#define LEDC_CONF_REG (DR_REG_LEDC_BASE + 0x0190) + + +#define LEDC_SIG_OUT_EN_LSCH0 1 << 2 +#define LEDC_PARA_UP_LSCH0 1 << 4 +#define DPORT_LEDC_CLK_EN 1 << 11 +#define DPORT_LEDC_RST 1 << 11 +#define LEDC_LSTIMER0_PAUSE 1 << 23 +#define LEDC_LSTIMER0_RST 1 << 24 +#define LEDC_TICK_SEL_LSTIMER0 1 << 25 +#define LEDC_LSTIMER0_PARA_UP 1 << 26 +#define LEDC_DUTY_START_LSCH0 1 << 31 + +#define LEDC_DIV_NUM_LSTIMER0_S 5 +#define LEDC_LSTIMER0_DUTY_RES_S 0 + +#define b16HALF 0x00008000 /* 0.5 */ +#define b16toi(a) ((a) >> 16) /* Conversion to integer */ + +/* LEDC clock resource */ +#define LEDC_CLK_RES (1) /* APB clock */ + +/* LEDC timer max reload */ +#define LEDC_RELOAD_MAX (1048576) /* 2^20 */ + +/* LEDC timer max clock divider parameter */ +#define LEDC_CLKDIV_MAX (1024) /* 2^10 */ + +/* LEDC timer registers mapping */ +#define LEDC_TIMER_REG(r, n) ((r) + (n) * (LEDC_LSTIMER1_CONF_REG - LEDC_LSTIMER0_CONF_REG)) + +/* LEDC timer channel registers mapping */ +#define setbits(bs, a) modifyreg32(a, 0, bs) +#define resetbits(bs, a) modifyreg32(a, bs, 0) + +#define LEDC_CHAN_REG(r, n) ((r) + (n) * (LEDC_LSCH1_CONF0_REG - LEDC_LSCH0_CONF0_REG)) + +#define SET_TIMER_BITS(t, r, b) setbits(b, LEDC_TIMER_REG(r, t)); +#define SET_TIMER_REG(t, r, v) putreg32(v, LEDC_TIMER_REG(r, t)); + +#define SET_CHAN_BITS(c, r, b) setbits(b, LEDC_CHAN_REG(r, c)); +#define SET_CHAN_REG(c, r, v) putreg32(v, LEDC_CHAN_REG(r, c)); + +uint32_t reload = 0; +uint32_t prescaler = 0; +uint32_t shift = 0; +uint32_t timer_rate = 0; + +void get_optimal_timer_setup(uint32_t desired_freq) +{ + + uint32_t shifted = 1; + timer_rate = desired_freq; + reload = (20480000000 / desired_freq + LEDC_CLKDIV_MAX) / LEDC_CLKDIV_MAX; + + if (reload == 0) { + reload = 1; + + } else if (reload > LEDC_RELOAD_MAX) { + reload = LEDC_RELOAD_MAX; + } + + for (uint32_t c = 2; c <= LEDC_RELOAD_MAX; c *= 2) { + if (c * 2 > reload) { + reload = c; + break; + } + + shifted++; + } + + shift = shifted; + prescaler = (20480000000 / reload) / desired_freq; +} + +int up_pwm_servo_set(unsigned channel, uint16_t value) +{ + uint32_t duty = (value * timer_rate) * 0.065535; + uint32_t regval = b16toi(duty * reload + b16HALF); + + irqstate_t flags; + + flags = px4_enter_critical_section(); + SET_CHAN_REG(channel, LEDC_LSCH0_DUTY_REG, regval << 4); + SET_CHAN_BITS(channel, LEDC_LSCH0_CONF0_REG, LEDC_PARA_UP_LSCH0); + px4_leave_critical_section(flags); + + return OK; +} + +uint16_t up_pwm_servo_get(unsigned channel) +{ + return 0; +} + +int up_pwm_servo_init(uint32_t channel_mask) +{ + // pause the timer + SET_TIMER_BITS(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, LEDC_LSTIMER0_PAUSE); + // reset the timer + SET_TIMER_BITS(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, LEDC_LSTIMER0_RST); + + // We are going to use REF_Tick as our source, which is set at 1Mhz. + // our prescaler is thus 0 + irqstate_t flags; + prescaler = 0; + shift = 0; + get_optimal_timer_setup(400); + + flags = px4_enter_critical_section(); + + setbits(DPORT_LEDC_CLK_EN, DPORT_PERIP_CLK_EN_REG); + resetbits(DPORT_LEDC_RST, DPORT_PERIP_RST_EN_REG); + putreg32(LEDC_CLK_RES, LEDC_CONF_REG); + + uint32_t regval = (shift << LEDC_LSTIMER0_DUTY_RES_S) | (prescaler << LEDC_DIV_NUM_LSTIMER0_S); + SET_TIMER_REG(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, regval); + + /* Setup to timer to use APB clock (80MHz) */ + SET_TIMER_BITS(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, LEDC_TICK_SEL_LSTIMER0); + + /* Update clock divide and reload to hardware */ + SET_TIMER_BITS(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, LEDC_LSTIMER0_PARA_UP); + + px4_leave_critical_section(flags); + + return channel_mask; +} + +void up_pwm_servo_deinit(uint32_t channel_mask) +{ + /* disable the timers */ + up_pwm_servo_arm(false, channel_mask); +} + +int up_pwm_servo_set_rate_group_update(unsigned group, unsigned rate) +{ + if (group == 0 || group == 1 || group == 2 || group == 3) { + irqstate_t flags; + shift = 0; + prescaler = 0; + get_optimal_timer_setup(rate); + + flags = px4_enter_critical_section(); + + uint32_t regval = (shift << LEDC_LSTIMER0_DUTY_RES_S) | (prescaler << LEDC_DIV_NUM_LSTIMER0_S); + SET_TIMER_REG(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, regval); + + /* Setup to timer to use APB clock (80MHz) */ + SET_TIMER_BITS(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, LEDC_TICK_SEL_LSTIMER0); + + /* Update clock divide and reload to hardware */ + SET_TIMER_BITS(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, LEDC_LSTIMER0_PARA_UP); + + px4_leave_critical_section(flags); + + return OK; + + } + + return ERROR; +} + +void up_pwm_update(unsigned channels_mask) +{ + //syslog(LOG_INFO, "up_pwm_update channels_mask: %d\n", channels_mask); + // pwm->ops->start(pwm,&pwm_info); +} + +uint32_t up_pwm_servo_get_rate_group(unsigned group) +{ + + if (group == 0) { +#if defined(CONFIG_ESP32_LEDC_TIM0_CHANNELS) + return (1 << CONFIG_ESP32_LEDC_TIM0_CHANNELS) - 1; +#endif + return -1; + + } else if (group == 1) { + +#if defined(CONFIG_ESP32_LEDC_TIM1_CHANNELS) + return (1 << CONFIG_ESP32_LEDC_TIM1_CHANNELS) - 1; +#endif + return -1; + + } else if (group == 2) { +#if defined(CONFIG_ESP32_LEDC_TIM2_CHANNELS) + return (1 << CONFIG_ESP32_LEDC_TIM2_CHANNELS) - -1; +#endif + return -1; + + } else if (group == 3) { +#if defined(CONFIG_ESP32_LEDC_TIM3_CHANNELS) + return (1 << CONFIG_ESP32_LEDC_TIM3_CHANNELS) - 1; +#endif + return -1; + } + + return -1; +} + +void +up_pwm_servo_arm(bool armed, uint32_t channel_mask) +{ + if (armed) { + for (uint8_t chan = 0; chan < 4; chan++) { + + irqstate_t flags; + flags = px4_enter_critical_section(); + + /* Reset config 0 & 1 registers */ + SET_CHAN_REG(chan, LEDC_LSCH0_CONF0_REG, 0); + SET_CHAN_REG(chan, LEDC_LSCH0_CONF1_REG, 0); + + /* Set pulse phase 0 */ + SET_CHAN_REG(chan, LEDC_LSCH0_HPOINT_REG, 0); + + /* Start GPIO output */ + SET_CHAN_BITS(chan, LEDC_LSCH0_CONF0_REG, LEDC_SIG_OUT_EN_LSCH0); + + /* Start Duty counter */ + SET_CHAN_BITS(chan, LEDC_LSCH0_CONF1_REG, LEDC_DUTY_START_LSCH0); + + /* Update duty and phase to hardware */ + SET_CHAN_BITS(chan, LEDC_LSCH0_CONF0_REG, LEDC_PARA_UP_LSCH0); + + px4_leave_critical_section(flags); + } + + } else { + irqstate_t flags; + + flags = px4_enter_critical_section(); + + /* Stop timer */ + SET_TIMER_BITS(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, LEDC_LSTIMER0_PAUSE); + + /* Reset timer */ + SET_TIMER_BITS(io_timers[0].base, LEDC_LSTIMER0_CONF_REG, LEDC_LSTIMER0_RST); + + px4_leave_critical_section(flags); + } +} diff --git a/platforms/nuttx/src/px4/espressif/esp32/spi/CMakeLists.txt b/platforms/nuttx/src/px4/espressif/esp32/spi/CMakeLists.txt new file mode 100644 index 00000000000..e4627c30bbd --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/spi/CMakeLists.txt @@ -0,0 +1,39 @@ +############################################################################ +# +# Copyright (c) 2020 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(arch_spi + spi.cpp +) +target_compile_options(arch_spi PRIVATE ${MAX_CUSTOM_OPT_LEVEL}) + +target_link_libraries (arch_spi PRIVATE drivers_board) # px4_spi_buses diff --git a/platforms/nuttx/src/px4/espressif/esp32/spi/spi.cpp b/platforms/nuttx/src/px4/espressif/esp32/spi/spi.cpp new file mode 100644 index 00000000000..f68789bdd51 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/spi/spi.cpp @@ -0,0 +1,322 @@ +/**************************************************************************** + * + * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +static const px4_spi_bus_t *_spi_bus2; +static const px4_spi_bus_t *_spi_bus3; + +static void spi_bus_configgpio_cs(const px4_spi_bus_t *bus) +{ + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + if (bus->devices[i].cs_gpio != 0) { + px4_arch_configgpio(bus->devices[i].cs_gpio); + } + } +} + +__EXPORT void esp32_spiinitialize() +{ + px4_set_spi_buses_from_hw_version(); + board_control_spi_sensors_power_configgpio(); + board_control_spi_sensors_power(true, 0xffff); + + for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) { + switch (px4_spi_buses[i].bus) { + case 2: _spi_bus2 = &px4_spi_buses[i]; break; + + case 3: _spi_bus3 = &px4_spi_buses[i]; break; + } + } + +#if defined(CONFIG_ESP32_SPI2) + ASSERT(_spi_bus2); + + if (board_has_bus(BOARD_SPI_BUS, 2)) { + //syslog(LOG_DEBUG, "spi bus configgpio cs %i\n", _spi_bus2->bus); + spi_bus_configgpio_cs(_spi_bus2); + } + +#endif // CONFIG_ESP32_SPI2 + +#ifdef CONFIG_ESP32_SPI3 + ASSERT(_spi_bus3); + + if (board_has_bus(BOARD_SPI_BUS, 3)) { + //syslog(LOG_DEBUG, "spi bus configgpio cs %i\n", _spi_bus3->bus); + spi_bus_configgpio_cs(_spi_bus3); + } + +#endif // CONFIG_ESP32_SPI3 + +} + +static inline void esp32_spixselect(const px4_spi_bus_t *bus, struct spi_dev_s *dev, uint32_t devid, bool selected) +{ + //syslog(LOG_DEBUG, "esp32 spixselect %i\n", bus->bus); + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + if (bus->devices[i].cs_gpio == 0) { + break; + } + + if (devid == bus->devices[i].devid) { + // SPI select is active low, so write !selected to select the device + //syslog(LOG_DEBUG, "esp32_gpiowrite %i\n", bus->bus); + px4_arch_gpiowrite(bus->devices[i].cs_gpio, !selected); + } + } +} + +/************************************************************************************ + * Name: ESP32_spi2select and ESP32_spi2status + * + * Description: + * Called by ESP32 spi driver on bus 2. + * + ************************************************************************************/ +#if defined(CONFIG_ESP32_SPI2) +__EXPORT void esp32_spi2_select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) +{ + esp32_spixselect(_spi_bus2, dev, devid, selected); +} + +__EXPORT uint8_t esp32_spi2_status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return SPI_STATUS_PRESENT; +} +#endif // CONFIG_ESP32_SPI2 + +/************************************************************************************ + * Name: esp32_spi3select and esp32_spi3status + * + * Description: + * Called by ESP32 spi driver on bus 3. + * + ************************************************************************************/ +#if defined(CONFIG_ESP32_SPI3) +__EXPORT void esp32_spi3_select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) +{ + esp32_spixselect(_spi_bus3, dev, devid, selected); +} + +__EXPORT uint8_t esp32_spi3_status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return SPI_STATUS_PRESENT; +} +#endif // CONFIG_ESP32_SPI3 + +void board_control_spi_sensors_power(bool enable_power, int bus_mask) +{ + const px4_spi_bus_t *buses = px4_spi_buses; + // this might be called very early on boot where we have not yet determined the hw version + // (we expect all versions to have the same power GPIO) +#if BOARD_NUM_SPI_CFG_HW_VERSIONS > 1 + + if (!buses) { + buses = &px4_spi_buses_all_hw[0].buses[0]; + } + +#endif + + for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) { + if (buses[bus].bus == -1) { + break; + } + + const bool bus_matches = bus_mask & (1 << (buses[bus].bus - 1)); + + if (buses[bus].power_enable_gpio == 0 || + !board_has_bus(BOARD_SPI_BUS, buses[bus].bus) || + !bus_matches) { + continue; + } + + px4_arch_gpiowrite(buses[bus].power_enable_gpio, enable_power ? 1 : 0); + } +} + +void board_control_spi_sensors_power_configgpio() +{ + const px4_spi_bus_t *buses = px4_spi_buses; + // this might be called very early on boot where we have yet not determined the hw version + // (we expect all versions to have the same power GPIO) +#if BOARD_NUM_SPI_CFG_HW_VERSIONS > 1 + + if (!buses) { + buses = &px4_spi_buses_all_hw[0].buses[0]; + } + +#endif + + for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) { + if (buses[bus].bus == -1) { + break; + } + + if (buses[bus].power_enable_gpio == 0 || + !board_has_bus(BOARD_SPI_BUS, buses[bus].bus)) { + continue; + } + + px4_arch_configgpio(buses[bus].power_enable_gpio); + } +} + +#define _PIN_OFF(def) (((def) & GPIO_NUM_MASK) | (GPIO_INPUT | GPIO_PULLDOWN)) + +__EXPORT void board_spi_reset(int ms, int bus_mask) +{ + + bool has_power_enable = false; + + // disable SPI bus + for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) { + if (px4_spi_buses[bus].bus == -1) { + break; + } + + const bool bus_requested = bus_mask & (1 << (px4_spi_buses[bus].bus - 1)); + + if (px4_spi_buses[bus].power_enable_gpio == 0 || + !board_has_bus(BOARD_SPI_BUS, px4_spi_buses[bus].bus) || + !bus_requested) { + continue; + } + + has_power_enable = true; + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + if (px4_spi_buses[bus].devices[i].cs_gpio != 0) { + px4_arch_configgpio(_PIN_OFF(px4_spi_buses[bus].devices[i].cs_gpio)); + } + + if (px4_spi_buses[bus].devices[i].drdy_gpio != 0) { + px4_arch_configgpio(_PIN_OFF(px4_spi_buses[bus].devices[i].drdy_gpio)); + } + } + +#if defined(CONFIG_ESP32_SPI2) + + if (px4_spi_buses[bus].bus == 2) { + px4_arch_configgpio(_PIN_OFF(CONFIG_ESP32_SPI2_CLKPIN)); + px4_arch_configgpio(_PIN_OFF(CONFIG_ESP32_SPI2_MOSIPIN)); + px4_arch_configgpio(_PIN_OFF(CONFIG_ESP32_SPI2_MISOPIN)); + } + +#endif +#if defined(CONFIG_ESP32_SPI3) + + if (px4_spi_buses[bus].bus == 3) { + px4_arch_configgpio(_PIN_OFF(CONFIG_ESP32_SPI3_CLKPIN)); + px4_arch_configgpio(_PIN_OFF(CONFIG_ESP32_SPI3_MOSIPIN)); + px4_arch_configgpio(_PIN_OFF(CONFIG_ESP32_SPI3_MISOPIN)); + } + +#endif + } + + if (!has_power_enable) { + // board does not have power control over any of the sensor buses + return; + } + + // set the sensor rail(s) off + board_control_spi_sensors_power(false, bus_mask); + + // wait for the sensor rail to reach GND + usleep(ms * 1000); + syslog(LOG_DEBUG, "reset done, %d ms\n", ms); + + /* re-enable power */ + + // switch the sensor rail back on + board_control_spi_sensors_power(true, bus_mask); + + /* wait a bit before starting SPI, different times didn't influence results */ + usleep(100); + + /* reconfigure the SPI pins */ + for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) { + if (px4_spi_buses[bus].bus == -1) { + break; + } + + const bool bus_requested = bus_mask & (1 << (px4_spi_buses[bus].bus - 1)); + + if (px4_spi_buses[bus].power_enable_gpio == 0 || + !board_has_bus(BOARD_SPI_BUS, px4_spi_buses[bus].bus) || + !bus_requested) { + continue; + } + + for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + if (px4_spi_buses[bus].devices[i].cs_gpio != 0) { + px4_arch_configgpio(px4_spi_buses[bus].devices[i].cs_gpio | GPIO_OUTPUT); + } + + if (px4_spi_buses[bus].devices[i].drdy_gpio != 0) { + px4_arch_configgpio(px4_spi_buses[bus].devices[i].drdy_gpio | GPIO_INPUT); + } + } + +#if defined(CONFIG_ESP32_SPI2) + + if (px4_spi_buses[bus].bus == 2) { + px4_arch_configgpio(CONFIG_ESP32_SPI2_CLKPIN | (GPIO_OUTPUT | FUNCTION_2)); + px4_arch_configgpio(CONFIG_ESP32_SPI2_MOSIPIN | (GPIO_OUTPUT | FUNCTION_2)); + px4_arch_configgpio(CONFIG_ESP32_SPI2_MISOPIN | (GPIO_INPUT | PULLUP | FUNCTION_2); + } + +#endif +#if defined(CONFIG_ESP32_SPI3) + + if (px4_spi_buses[bus].bus == 3) { + px4_arch_configgpio(CONFIG_ESP32_SPI3_CLKPIN | (GPIO_OUTPUT | FUNCTION_3)); + px4_arch_configgpio(CONFIG_ESP32_SPI3_MOSIPIN | (GPIO_OUTPUT | FUNCTION_3)); + px4_arch_configgpio(CONFIG_ESP32_SPI3_MISOPIN | (GPIO_INPUT | PULLUP | FUNCTION_3)); + } + +#endif + } +} diff --git a/platforms/nuttx/src/px4/espressif/esp32/version/CMakeLists.txt b/platforms/nuttx/src/px4/espressif/esp32/version/CMakeLists.txt new file mode 100644 index 00000000000..b102ab612f1 --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/version/CMakeLists.txt @@ -0,0 +1,37 @@ +############################################################################ +# +# Copyright (c) 2021 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +px4_add_library(arch_version + board_identity.c + board_mcu_version.c +) diff --git a/platforms/nuttx/src/px4/espressif/esp32/version/board_identity.c b/platforms/nuttx/src/px4/espressif/esp32/version/board_identity.c new file mode 100644 index 00000000000..208faa01eee --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/version/board_identity.c @@ -0,0 +1,160 @@ +/** + * @file board_identity.c + * Implementation of RP2040 based Board identity API + */ + +#include +#include +#include + +// ESP32 doesn't really have a cpu register with unique id. +// but we can make use of its unique mac address +#define MAC_ADDR0_LOWER (0x3ff5a004) +#define MAC_ADDR1_HIGHER (0x3ff5a008) +#define REG_READ(_r) (*(volatile uint32_t *)(_r)) + + +#define CPU_UUID_BYTE_FORMAT_ORDER {5,4,3,2,1,0} +#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00ff0000) >> 8) | (((x) & 0x0000ff00) << 8) | ((x) << 24)) + +static const uint16_t soc_arch_id = PX4_SOC_ARCH_ID; + +/* A type suitable for holding the reordering array for the byte format of the UUID + */ + +typedef const uint8_t uuid_uint8_reorder_t[PX4_CPU_UUID_BYTE_LENGTH]; + + +static int emac_read_mac(uint32_t *mac) +{ + /* The MAC address in register is from high byte to low byte */ + mac[0] = REG_READ(MAC_ADDR0_LOWER); + mac[1] = REG_READ(MAC_ADDR1_HIGHER) & 0xffff; + + return 0; +} + + +void board_get_uuid(uuid_byte_t uuid_bytes) +{ + uuid_uint8_reorder_t reorder = CPU_UUID_BYTE_FORMAT_ORDER; + union { + uuid_byte_t b; + uuid_uint32_t w; + } id; + + /* Copy the serial from the chips non-write memory */ + + board_get_uuid32(id.w); + + /* swap endianess */ + + for (int i = 0; i < PX4_CPU_UUID_BYTE_LENGTH; i++) { + uuid_bytes[i] = id.b[reorder[i]]; + } +} + +__EXPORT void board_get_uuid32(uuid_uint32_t uuid_words) +{ + uint32_t mac[2]; + emac_read_mac(mac); + uint32_t *chip_uuid = mac; + // memcpy(&chip_uuid, mac, sizeof(chip_uuid)); + + for (unsigned i = 0; i < PX4_CPU_UUID_WORD32_LENGTH; i++) { + uuid_words[i] = chip_uuid[i]; + } +} + +int board_get_uuid32_formated(char *format_buffer, int size, + const char *format, + const char *seperator) +{ + uuid_uint32_t uuid; + board_get_uuid32(uuid); + int offset = 0; + int sep_size = seperator ? strlen(seperator) : 0; + + for (unsigned i = 0; (offset < size - 1) && (i < PX4_CPU_UUID_WORD32_LENGTH); i++) { + offset += snprintf(&format_buffer[offset], size - offset, format, uuid[i]); + + if (sep_size && (offset < size - sep_size - 1) && (i < PX4_CPU_UUID_WORD32_LENGTH - 1)) { + strncat(&format_buffer[offset], seperator, size - offset); + offset += sep_size; + } + } + + return 0; +} + +int board_get_mfguid(mfguid_t mfgid) +{ + uint32_t mac[2]; + emac_read_mac(mac); + uint32_t *chip_uuid = mac; + uint8_t *rv = &mfgid[0]; + + for (unsigned i = 0; i < PX4_CPU_UUID_WORD32_LENGTH; i++) { + uint32_t uuid_bytes = SWAP_UINT32(chip_uuid[(PX4_CPU_UUID_WORD32_LENGTH - 1) - i]); + memcpy(rv, &uuid_bytes, sizeof(uint32_t)); + rv += sizeof(uint32_t); + } + + return PX4_CPU_MFGUID_BYTE_LENGTH; +} + +int board_get_mfguid_formated(char *format_buffer, int size) +{ + mfguid_t mfguid; + + board_get_mfguid(mfguid); + int offset = 0; + + for (unsigned i = 0; offset < size && i < PX4_CPU_MFGUID_BYTE_LENGTH; i++) { + offset += snprintf(&format_buffer[offset], size - offset, "%02x", mfguid[i]); + } + + return offset; +} + +int board_get_px4_guid(px4_guid_t px4_guid) +{ + uint8_t *pb = (uint8_t *) &px4_guid[0]; + *pb++ = (soc_arch_id >> 8) & 0xff; + *pb++ = (soc_arch_id & 0xff); + + for (unsigned i = 0; i < PX4_GUID_BYTE_LENGTH - (sizeof(soc_arch_id) + PX4_CPU_UUID_BYTE_LENGTH); i++) { + *pb++ = 0; + } + + uint32_t mac[2]; + emac_read_mac(mac); + uint32_t *chip_uuid = mac; + + for (unsigned i = 0; i < PX4_CPU_UUID_WORD32_LENGTH; i++) { + uint32_t uuid_bytes = SWAP_UINT32(chip_uuid[(PX4_CPU_UUID_WORD32_LENGTH - 1) - i]); + memcpy(pb, &uuid_bytes, sizeof(uint32_t)); + pb += sizeof(uint32_t); + } + + return PX4_GUID_BYTE_LENGTH; +} + +int board_get_px4_guid_formated(char *format_buffer, int size) +{ + px4_guid_t px4_guid; + board_get_px4_guid(px4_guid); + int offset = 0; + + /* size should be 2 per byte + 1 for termination + * So it needs to be odd + */ + size = size & 1 ? size : size - 1; + + /* Discard from MSD */ + for (unsigned i = PX4_GUID_BYTE_LENGTH - size / 2; offset < size && i < PX4_GUID_BYTE_LENGTH; i++) { + offset += snprintf(&format_buffer[offset], size - offset, "%02x", px4_guid[i]); + } + + return offset; +} diff --git a/platforms/nuttx/src/px4/espressif/esp32/version/board_mcu_version.c b/platforms/nuttx/src/px4/espressif/esp32/version/board_mcu_version.c new file mode 100644 index 00000000000..d5743077d9c --- /dev/null +++ b/platforms/nuttx/src/px4/espressif/esp32/version/board_mcu_version.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * + * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file board_mcu_version.c + * Implementation of ESP32 based SoC version API + */ + +#include +#include + + +/* Define any issues with the Silicon as lines separated by \n + * omitting the last \n + */ +#define ESP32_ERRATA "No unique CPU ID, using MAC address." +#define DR_REG_EFUSE_BASE 0x3ff5a000 +#define DR_REG_SYSCON_BASE 0x60026000 +#define EFUSE_BLK0_RDATA3_REG (DR_REG_EFUSE_BASE + 0x00c) +#define EFUSE_BLK0_RDATA5_REG (DR_REG_EFUSE_BASE + 0x014) +#define SYSCON_DATE_REG (DR_REG_SYSCON_BASE + 0x3FC) + +#define REG_READ(_r) (*(volatile uint32_t *)(_r)) + + +int board_mcu_version(char *rev, const char **revstr, const char **errata) +{ + /* + comes from esp-idf in efuse_hal_get_major_chip_version + and efuse_hal_get_minor_chip_version + */ + uint8_t eco_bit0 = (REG_READ(EFUSE_BLK0_RDATA3_REG) >> 15) & 0x1; + uint8_t eco_bit1 = (REG_READ(EFUSE_BLK0_RDATA5_REG) >> 20) & 0x1; + uint8_t eco_bit2 = (REG_READ(SYSCON_DATE_REG) & 0x80000000) >> 31; + uint32_t combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0; + uint8_t minor_revision = (REG_READ(EFUSE_BLK0_RDATA5_REG) >> 24) & 0x3; + + int revid; + + switch (combine_value) { + case 0: + *revstr = "ESP32 v0"; + *rev = minor_revision + 48; + revid = minor_revision; + break; + + case 1: + *revstr = "ESP32 v1"; + *rev = minor_revision + 48; + revid = minor_revision; + break; + + case 3: + *revstr = "ESP32 v2"; + *rev = minor_revision + 48; + revid = minor_revision; + break; + + case 7: + *revstr = "ESP32 v3"; + *rev = minor_revision + 48; + revid = minor_revision; + break; + + default: + *revstr = "ESP32 v?"; + *rev = '?'; + revid = 0; + break; + } + + return revid; +}