[BACKPORT] imxrt and rt117x platform & hardfault_log

This commit is contained in:
David Sidrane
2024-04-29 08:38:57 -07:00
parent de363bf7db
commit 22b6a78bfc
24 changed files with 1770 additions and 33 deletions
@@ -67,6 +67,10 @@
# define PX4_I2C_BUS_CLOCK_INIT {100000, 100000, 100000}
# elif (PX4_NUMBER_I2C_BUSES) == 4
# define PX4_I2C_BUS_CLOCK_INIT {100000, 100000, 100000, 100000}
# elif (PX4_NUMBER_I2C_BUSES) == 5
# define PX4_I2C_BUS_CLOCK_INIT {100000, 100000, 100000, 100000, 100000}
# elif (PX4_NUMBER_I2C_BUSES) == 6
# define PX4_I2C_BUS_CLOCK_INIT {100000, 100000, 100000, 100000, 100000, 100000}
# else
# error PX4_NUMBER_I2C_BUSES not supported
# endif
@@ -353,6 +357,7 @@ typedef enum PX4_SOC_ARCH_ID_t {
PX4_SOC_ARCH_ID_NXPS32K146 = 0x0007,
PX4_SOC_ARCH_ID_NXPS32K344 = 0x0008,
PX4_SOC_ARCH_ID_NXPIMXRT1176 = 0x0009,
PX4_SOC_ARCH_ID_EAGLE = 0x1001,
PX4_SOC_ARCH_ID_QURT = 0x1002,
+3
View File
@@ -139,6 +139,9 @@ function(px4_os_determine_build_chip)
elseif(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "rt106x")
elseif(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "rt117x")
elseif(CONFIG_ARCH_CHIP_S32K146)
set(CHIP_MANUFACTURER "nxp")
set(CHIP "s32k14x")
@@ -60,10 +60,15 @@
#include <px4_platform/progmem_dump.h>
#endif
#ifdef HAS_BBSRAM
# define REBOOTS_COUNT 32000
#elif defined(HAS_PROGMEM)
#ifdef HAS_SSARC
#include <ssarc_dump.h>
#endif
#if defined(HAS_PROGMEM)
# define REBOOTS_COUNT 32
#else
# define REBOOTS_COUNT 32000
#endif
int board_hardfault_init(int display_to_console, bool allow_prompt)
@@ -94,9 +99,21 @@ int board_hardfault_init(int display_to_console, bool allow_prompt)
progmem_dump_initialize(PROGMEM_PATH, filesizes);
#elif defined(HAS_SSARC)
/* NB. the use of the console requires the hrt running
* to poll the DMA
*/
/* Using progmem */
int filesizes[SSARC_DUMP_FILE_COUNT + 1] = SSARC_DUMP_FILE_SIZES;
ssarc_dump_initialize(SSARC_DUMP_PATH, filesizes);
#endif // HAS_PROGMEM
#if defined(SAVE_CRASHDUMP) && (defined(HAS_BBSRAM) || defined(HAS_PROGMEM))
#if defined(SAVE_CRASHDUMP) && (defined(HAS_BBSRAM) || defined(HAS_PROGMEM) || defined(HAS_SSARC))
/* Panic Logging in Battery Backed Up Files */
@@ -34,3 +34,4 @@
px4_add_library(arch_board_hw_info
board_hw_rev_ver.c
)
target_link_libraries(arch_board_hw_info PRIVATE arch_adc crc)
@@ -40,11 +40,15 @@
#include <px4_arch/adc.h>
#include <px4_platform_common/micro_hal.h>
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/px4_manifest.h>
#include <px4_platform/board_determine_hw_info.h>
#include <px4_platform/board_hw_eeprom_rev_ver.h>
#include <stdio.h>
#include <fcntl.h>
#include <board_config.h>
#include <systemlib/px4_macros.h>
#include <lib/crc/crc.h>
#include <lib/systemlib/px4_macros.h>
#if defined(BOARD_HAS_HW_VERSIONING) || defined(BOARD_HAS_HW_SPLIT_VERSIONING)
@@ -138,6 +142,7 @@ static int dn_to_ordinal(uint16_t dn)
static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc_channel)
{
int rv = -EIO;
const unsigned int samples = 16;
/*
* Step one is there resistors?
@@ -232,12 +237,14 @@ static int read_id_dn(int *id, uint32_t gpio_drive, uint32_t gpio_sense, int adc
/* Turn the drive lines to digital outputs High */
imxrt_config_gpio(gpio_drive);
return rv;
}
static int determine_hw_info(int *revision, int *version)
{
int dn;
int rv = read_id_dn(&dn, GPIO_HW_REV_DRIVE, GPIO_HW_REV_SENSE, ADC_HW_REV_SENSE_CHANNEL);
@@ -362,14 +369,24 @@ __EXPORT int board_get_hw_revision()
int board_determine_hw_info()
{
// Read ADC jumpering hw_info
int rv = determine_hw_info(&hw_revision, &hw_version);
if (rv == OK) {
if (rv == OK) {
// MFT supported?
const char *path;
int rvmft = px4_mtd_query("MTD_MFT_VER", NULL, &path);
snprintf(hw_info, sizeof(hw_info), HW_INFO_INIT_PREFIX HW_INFO_SUFFIX, hw_version, hw_revision);
if (rvmft == OK && path != NULL && hw_version == HW_ID_EEPROM) {
mtd_mft_v0_t mtd_mft = {MTD_MFT_v0};
rv = board_get_eeprom_hw_info(path, (mtd_mft_t *)&mtd_mft);
if (rv == OK) {
hw_version = mtd_mft.hw_extended_id;
}
}
path = NULL;
@@ -397,4 +414,144 @@ int board_determine_hw_info()
return rv;
}
/************************************************************************************
* Name: board_set_eeprom_hw_info
*
* Description:
* Function for writing hardware info to EEPROM
*
* Input Parameters:
* *mtd_mft_unk - pointer to mtd_mft to write hw_info
*
* Returned Value:
* 0 - Successful storing to EEPROM
* -1 - Error while storing to EEPROM
*
************************************************************************************/
int board_set_eeprom_hw_info(const char *path, mtd_mft_t *mtd_mft_unk)
{
if (mtd_mft_unk == NULL || path == NULL) {
return -EINVAL;
}
// Later this will be a demux on type
if (mtd_mft_unk->id != MTD_MFT_v0) {
printf("Version is: %d, Only mft version %d is supported\n", mtd_mft_unk->id, MTD_MFT_v0);
return -EINVAL;
}
mtd_mft_v0_t *mtd_mft = (mtd_mft_v0_t *)mtd_mft_unk;
if (mtd_mft->hw_extended_id < HW_EEPROM_ID_MIN) {
printf("hardware version for EEPROM must be greater than %x\n", HW_EEPROM_ID_MIN);
return -EINVAL;
}
int fd = open(path, O_WRONLY);
if (fd < 0) {
return -errno;
}
int ret_val = OK;
mtd_mft->crc = crc16_signature(CRC16_INITIAL, sizeof(*mtd_mft) - sizeof(mtd_mft->crc), (uint8_t *) mtd_mft);
if (
(MTD_MFT_OFFSET != lseek(fd, MTD_MFT_OFFSET, SEEK_SET)) ||
(sizeof(*mtd_mft) != write(fd, mtd_mft, sizeof(*mtd_mft)))
) {
ret_val = -errno;
}
close(fd);
return ret_val;
}
/************************************************************************************
* Name: board_get_eeprom_hw_info
*
* Description:
* Function for reading hardware info from EEPROM
*
* Output Parameters:
* *mtd_mft - pointer to mtd_mft to read hw_info
*
* Returned Value:
* 0 - Successful reading from EEPROM
* -1 - Error while reading from EEPROM
*
************************************************************************************/
__EXPORT int board_get_eeprom_hw_info(const char *path, mtd_mft_t *mtd_mft)
{
if (mtd_mft == NULL || path == NULL) {
return -EINVAL;
}
int fd = open(path, O_RDONLY);
if (fd < 0) {
return -errno;
}
int ret_val = OK;
mtd_mft_t format_version = {-1};
if (
(MTD_MFT_OFFSET != lseek(fd, MTD_MFT_OFFSET, SEEK_SET)) ||
(sizeof(format_version) != read(fd, &format_version, sizeof(format_version)))
) {
ret_val = -errno;
} else if (format_version.id != mtd_mft->id) {
ret_val = -EPROTO;
} else {
uint16_t mft_size = 0;
switch (format_version.id) {
case MTD_MFT_v0: mft_size = sizeof(mtd_mft_v0_t); break;
case MTD_MFT_v1: mft_size = sizeof(mtd_mft_v1_t); break;
default:
printf("[boot] Error, unknown version %d of mtd_mft in EEPROM\n", format_version.id);
ret_val = -1;
break;
}
if (ret_val == OK) {
if (
(MTD_MFT_OFFSET != lseek(fd, MTD_MFT_OFFSET, SEEK_SET)) ||
(mft_size != read(fd, mtd_mft, mft_size))
) {
ret_val = -errno;
} else {
union {
uint16_t w;
uint8_t b[2];
} crc;
uint8_t *bytes = (uint8_t *) mtd_mft;
crc.w = crc16_signature(CRC16_INITIAL, mft_size - sizeof(crc), bytes);
uint8_t *eeprom_crc = &bytes[mft_size - sizeof(crc)];
if (!(crc.b[0] == eeprom_crc[0] && crc.b[1] == eeprom_crc[1])) {
ret_val = -1;
}
}
}
}
close(fd);
return ret_val;
}
#endif
+17 -1
View File
@@ -94,12 +94,28 @@
# define HRT_CLOCK_ALL() imxrt_clockall_gpt_bus() /* The Clock Gating macro for this GPT */
#elif HRT_TIMER == 2
# define HRT_CLOCK_ALL() imxrt_clockall_gpt2_bus() /* The Clock Gating macro for this GPT */
#elif HRT_TIMER == 3
# define HRT_CLOCK_ALL() imxrt_clockall_gpt3_bus() /* The Clock Gating macro for this GPT */
#elif HRT_TIMER == 4
# define HRT_CLOCK_ALL() imxrt_clockall_gpt4_bus() /* The Clock Gating macro for this GPT */
#elif HRT_TIMER == 5
# define HRT_CLOCK_ALL() imxrt_clockall_gpt5_bus() /* The Clock Gating macro for this GPT */
#elif HRT_TIMER == 6
# define HRT_CLOCK_ALL() imxrt_clockall_gpt6_bus() /* The Clock Gating macro for this GPT */
#endif
#if HRT_TIMER == 1 && defined(CONFIG_IMXRT_GPT1)
# error must not set CONFIG_IMXRT_GPT1=y and HRT_TIMER=1
#elif HRT_TIMER == 2 && defined(CONFIG_IMXRT_GPT2)
# error must not set CONFIG_IMXRT_GPT2=y and HRT_TIMER=2
#elif HRT_TIMER == 3 && defined(CONFIG_IMXRT_GPT3)
# error must not set CONFIG_IMXRT_GPT3=y and HRT_TIMER=3
#elif HRT_TIMER == 4 && defined(CONFIG_IMXRT_GPT4)
# error must not set CONFIG_IMXRT_GPT4=y and HRT_TIMER=4
#elif HRT_TIMER == 5 && defined(CONFIG_IMXRT_GPT5)
# error must not set CONFIG_IMXRT_GPT5=y and HRT_TIMER=5
#elif HRT_TIMER == 6 && defined(CONFIG_IMXRT_GPT6)
# error must not set CONFIG_IMXRT_GPT6=y and HRT_TIMER=6
#endif
/*
@@ -165,7 +181,7 @@
# define STATUS_HRT CAT(GPT_SR_OF, HRT_TIMER_CHANNEL) /* OF Output Compare Flag */
# define OFIE_HRT CAT3(GPT_IR_OF, HRT_TIMER_CHANNEL,IE) /* Output Compare Interrupt Enable */
#if (HRT_TIMER_CHANNEL > 1) || (HRT_TIMER_CHANNEL > 3)
#if (HRT_TIMER_CHANNEL < 1) || (HRT_TIMER_CHANNEL > 3)
# error HRT_TIMER_CHANNEL must be a value between 1 and 3
#endif
@@ -121,6 +121,7 @@ typedef struct timer_io_channels_t {
#define PWMA_VAL IMXRT_FLEXPWM_SM0VAL3_OFFSET
#define PWMB_VAL IMXRT_FLEXPWM_SM0VAL5_OFFSET
#define PWMX_VAL IMXRT_FLEXPWM_SM0VAL0_OFFSET //FIXME
typedef void (*channel_handler_t)(void *context, const io_timers_t *timer, uint32_t chan_index,
@@ -0,0 +1,169 @@
/****************************************************************************
*
* Copyright (c) 2022 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 px4io_serial.h
*
* Serial Interface definition for PX4IO
*/
#pragma once
#include <board_config.h>
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/micro_hal.h>
#include <perf/perf_counter.h>
#include <drivers/device/device.h>
#include <modules/px4iofirmware/protocol.h>
class PX4IO_serial : public device::Device
{
public:
PX4IO_serial();
virtual ~PX4IO_serial();
virtual int init() = 0;
virtual int read(unsigned offset, void *data, unsigned count = 1);
virtual int write(unsigned address, void *data, unsigned count = 1);
protected:
/**
* Does the PX4IO_serial instance initialization.
* @param io_buffer The IO buffer that should be used for transfers.
* @return 0 on success.
*/
int init(IOPacket *io_buffer);
/**
* Start the transaction with IO and wait for it to complete.
*/
virtual int _bus_exchange(IOPacket *_packet) = 0;
/**
* Performance counters.
*/
perf_counter_t _pc_txns;
perf_counter_t _pc_retries;
perf_counter_t _pc_timeouts;
perf_counter_t _pc_crcerrs;
perf_counter_t _pc_protoerrs;
perf_counter_t _pc_uerrs;
perf_counter_t _pc_idle;
perf_counter_t _pc_badidle;
private:
/*
* XXX tune this value
*
* At 1.5Mbps each register takes 13.3µs, and we always transfer a full packet.
* Packet overhead is 26µs for the four-byte header.
*
* 32 registers = 451µs
*
* Maybe we can just send smaller packets (e.g. 8 regs) and loop for larger (less common)
* transfers? Could cause issues with any regs expecting to be written atomically...
*/
IOPacket *_io_buffer_ptr;
/** bus-ownership lock */
px4_sem_t _bus_semaphore;
/* do not allow top copying this class */
PX4IO_serial(PX4IO_serial &);
PX4IO_serial &operator = (const PX4IO_serial &);
};
#include <imxrt_edma.h>
class ArchPX4IOSerial : public PX4IO_serial
{
public:
ArchPX4IOSerial();
ArchPX4IOSerial(ArchPX4IOSerial &) = delete;
ArchPX4IOSerial &operator = (const ArchPX4IOSerial &) = delete;
virtual ~ArchPX4IOSerial();
virtual int init();
virtual int ioctl(unsigned operation, unsigned &arg);
protected:
/**
* Start the transaction with IO and wait for it to complete.
*/
int _bus_exchange(IOPacket *_packet);
private:
DMACH_HANDLE _tx_dma;
DMACH_HANDLE _rx_dma;
IOPacket *_current_packet;
/** saved DMA status */
static const unsigned _dma_status_done = 0x00000000;
static const unsigned _dma_status_inactive = 0x00000001;
static const unsigned _dma_status_waiting = 0x00000002;
volatile int _rx_dma_result;
/** client-waiting lock/signal */
px4_sem_t _completion_semaphore;
/**
* DMA completion handler.
*/
static void _dma_callback(DMACH_HANDLE handle, void *arg, bool done, int result);
void _do_rx_dma_callback(bool done, int result);
/**
* Serial interrupt handler.
*/
static int _interrupt(int vector, void *context, void *arg);
void _do_interrupt();
/**
* Cancel any DMA in progress with an error.
*/
void _abort_dma();
/**
* Performance counters.
*/
perf_counter_t _pc_dmaerrs;
/**
* IO Buffer storage
*/
static uint8_t _io_buffer_storage[] px4_cache_aligned_data();
};
@@ -50,14 +50,10 @@ typedef struct {
#if defined(CONFIG_ARCH_FAMILY_IMXRT106x)
const lh_t port_to_irq[9] = {
{_IMXRT_GPIO1_0_15_BASE, _IMXRT_GPIO1_16_31_BASE},
{_IMXRT_GPIO2_0_15_BASE, _IMXRT_GPIO2_16_31_BASE},
{_IMXRT_GPIO3_0_15_BASE, _IMXRT_GPIO3_16_31_BASE},
{_IMXRT_GPIO4_0_15_BASE, _IMXRT_GPIO4_16_31_BASE},
{_IMXRT_GPIO5_0_15_BASE, _IMXRT_GPIO5_16_31_BASE},
{_IMXRT_GPIO6_0_15_BASE, _IMXRT_GPIO6_16_31_BASE},
{_IMXRT_GPIO7_0_15_BASE, _IMXRT_GPIO7_16_31_BASE},
{_IMXRT_GPIO8_0_15_BASE, _IMXRT_GPIO8_16_31_BASE},
{_IMXRT_GPIO1_0_15_BASE, _IMXRT_GPIO1_16_31_BASE}, {_IMXRT_GPIO2_0_15_BASE, _IMXRT_GPIO2_16_31_BASE},
{_IMXRT_GPIO3_0_15_BASE, _IMXRT_GPIO3_16_31_BASE}, {_IMXRT_GPIO4_0_15_BASE, _IMXRT_GPIO4_16_31_BASE},
{_IMXRT_GPIO5_0_15_BASE, _IMXRT_GPIO5_16_31_BASE}, {_IMXRT_GPIO6_0_15_BASE, _IMXRT_GPIO6_16_31_BASE},
{_IMXRT_GPIO7_0_15_BASE, _IMXRT_GPIO7_16_31_BASE}, {_IMXRT_GPIO8_0_15_BASE, _IMXRT_GPIO8_16_31_BASE},
{_IMXRT_GPIO9_0_15_BASE, _IMXRT_GPIO9_16_31_BASE},
};
#endif
@@ -283,7 +283,7 @@ uint32_t io_timer_channel_get_gpio_output(unsigned channel)
}
return timer_io_channels[channel].gpio_portpin | (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_CMOS_OUTPUT | IOMUX_PULL_KEEP
| IOMUX_DRIVE_33OHM | IOMUX_SPEED_MEDIUM | IOMUX_SLEW_FAST);
| IOMUX_SLEW_FAST);
return 0;
}
@@ -42,7 +42,11 @@
#include <stdio.h>
#include <string.h>
#include <arm_internal.h>
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
#include <hardware/rt117x/imxrt117x_ocotp.h>
#else
#include <hardware/imxrt_ocotp.h>
#endif
#define CPU_UUID_BYTE_FORMAT_ORDER {3, 2, 1, 0, 7, 6, 5, 4}
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00ff0000) >> 8) | (((x) & 0x0000ff00) << 8) | ((x) << 24))
@@ -39,10 +39,46 @@
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/defines.h>
#include <chip.h>
#include <hardware/imxrt_usb_analog.h>
#include "arm_internal.h"
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
# include <hardware/rt117x/imxrt117x_ocotp.h>
# include <hardware/rt117x/imxrt117x_anadig.h>
#else
# include <chip.h>
# include <hardware/imxrt_usb_analog.h>
#endif
#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
#define CHIP_TAG "i.MX RT11?0 r??"
#define CHIP_TAG_LEN sizeof(CHIP_TAG)-1
#define SI_REV(n) ((n & 0x7000000) >> 24)
#define DIFPROG_TYPE(n) ((n & 0xF000) >> 12)
#define DIFPROG_REV_MAJOR(n) ((n & 0xF0) >> 4)
#define DIFPROG_REV_MINOR(n) ((n & 0xF))
int board_mcu_version(char *rev, const char **revstr, const char **errata)
{
uint32_t info = getreg32(IMXRT_ANADIG_MISC_MISC_DIFPROG);
static char chip[sizeof(CHIP_TAG)] = CHIP_TAG;
*revstr = chip;
chip[CHIP_TAG_LEN - 6] = '0' + DIFPROG_TYPE(info);
chip[CHIP_TAG_LEN - 2] = 'A' + (DIFPROG_REV_MAJOR(info) - 10);
chip[CHIP_TAG_LEN - 1] = '0' + DIFPROG_REV_MINOR(info);
*rev = '0' + SI_REV(getreg32(IMXRT_OCOTP_FUSE(18)));
if (errata) {
*errata = NULL;
}
return 0;
}
#else
#define DIGPROG_MINOR_SHIFT 0
#define DIGPROG_MINOR_MASK (0xff << DIGPROG_MINOR_SHIFT)
@@ -74,3 +110,5 @@ int board_mcu_version(char *rev, const char **revstr, const char **errata)
return 0;
}
#endif
@@ -0,0 +1,49 @@
############################################################################
#
# 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(adc)
add_subdirectory(../imxrt/board_critmon board_critmon)
add_subdirectory(../imxrt/board_hw_info board_hw_info)
add_subdirectory(../imxrt/board_reset board_reset)
add_subdirectory(../imxrt/romapi romapi)
add_subdirectory(../imxrt/hrt hrt)
add_subdirectory(../imxrt/led_pwm led_pwm)
add_subdirectory(../imxrt/io_pins io_pins)
add_subdirectory(../imxrt/tone_alarm tone_alarm)
add_subdirectory(../imxrt/version version)
add_subdirectory(../imxrt/spi spi)
add_subdirectory(../imxrt/dshot dshot)
add_subdirectory(px4io_serial)
add_subdirectory(ssarc)
@@ -0,0 +1,36 @@
############################################################################
#
# Copyright (c) 2023 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_adc
adc.cpp
)
@@ -0,0 +1,248 @@
/****************************************************************************
*
* Copyright (C) 2023 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 adc.cpp
*
* Driver for the imxrt ADC.
*
* This is a low-rate driver, designed for sampling things like voltages
* and so forth. It avoids the gross complexity of the NuttX ADC driver.
*/
#include <board_config.h>
#include <stdint.h>
#include <drivers/drv_hrt.h>
#include <drivers/drv_adc.h>
#include <px4_arch/adc.h>
#include <hardware/imxrt_adc.h>
#include <imxrt_periphclks.h>
typedef uint32_t adc_chan_t;
#define ADC_TOTAL_CHANNELS 16
#define _REG(_addr) (*(volatile uint32_t *)(_addr))
/* ADC register accessors */
#define REG(base_address, _reg) _REG((base_address) + (_reg))
#define rVERID(base_address) REG(base_address, IMXRT_LPADC_VERID_OFFSET) /* Version ID Register */
#define rPARAM(base_address) REG(base_address, IMXRT_LPADC_PARAM_OFFSET) /* Parameter Register */
#define rCTRL(base_address) REG(base_address, IMXRT_LPADC_CTRL_OFFSET) /* LPADC Control Register */
#define rSTAT(base_address) REG(base_address, IMXRT_LPADC_STAT_OFFSET) /* LPADC Status Register */
#define rIE(base_address) REG(base_address, IMXRT_LPADC_IE_OFFSET) /* Interrupt Enable Register */
#define rDE(base_address) REG(base_address, IMXRT_LPADC_DE_OFFSET) /* DMA Enable Register */
#define rCFG(base_address) REG(base_address, IMXRT_LPADC_CFG_OFFSET) /* LPADC Configuration Register */
#define rPAUSE(base_address) REG(base_address, IMXRT_LPADC_PAUSE_OFFSET) /* LPADC Pause Register */
#define rFCTRL(base_address) REG(base_address, IMXRT_LPADC_FCTRL_OFFSET) /* LPADC FIFO Control Register */
#define rSWTRIG(base_address) REG(base_address, IMXRT_LPADC_SWTRIG_OFFSET) /* Software Trigger Register */
#define rCMDL1(base_address) REG(base_address, IMXRT_LPADC_CMDL1_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH1(base_address) REG(base_address, IMXRT_LPADC_CMDH1_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL2(base_address) REG(base_address, IMXRT_LPADC_CMDL2_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH2(base_address) REG(base_address, IMXRT_LPADC_CMDH2_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL3(base_address) REG(base_address, IMXRT_LPADC_CMDL3_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH3(base_address) REG(base_address, IMXRT_LPADC_CMDH3_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL4(base_address) REG(base_address, IMXRT_LPADC_CMDL4_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH4(base_address) REG(base_address, IMXRT_LPADC_CMDH4_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL5(base_address) REG(base_address, IMXRT_LPADC_CMDL5_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH5(base_address) REG(base_address, IMXRT_LPADC_CMDH5_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL6(base_address) REG(base_address, IMXRT_LPADC_CMDL6_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH6(base_address) REG(base_address, IMXRT_LPADC_CMDH6_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL7(base_address) REG(base_address, IMXRT_LPADC_CMDL7_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH7(base_address) REG(base_address, IMXRT_LPADC_CMDH7_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL8(base_address) REG(base_address, IMXRT_LPADC_CMDL8_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH8(base_address) REG(base_address, IMXRT_LPADC_CMDH8_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL9(base_address) REG(base_address, IMXRT_LPADC_CMDL9_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH9(base_address) REG(base_address, IMXRT_LPADC_CMDH9_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL10(base_address) REG(base_address, IMXRT_LPADC_CMDL10_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH10(base_address) REG(base_address, IMXRT_LPADC_CMDH10_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL11(base_address) REG(base_address, IMXRT_LPADC_CMDL11_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH11(base_address) REG(base_address, IMXRT_LPADC_CMDH11_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL12(base_address) REG(base_address, IMXRT_LPADC_CMDL12_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH12(base_address) REG(base_address, IMXRT_LPADC_CMDH12_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL13(base_address) REG(base_address, IMXRT_LPADC_CMDL13_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH13(base_address) REG(base_address, IMXRT_LPADC_CMDH13_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL14(base_address) REG(base_address, IMXRT_LPADC_CMDL14_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH14(base_address) REG(base_address, IMXRT_LPADC_CMDH14_OFFSET) /* LPADC Command High Buffer Register */
#define rCMDL15(base_address) REG(base_address, IMXRT_LPADC_CMDL15_OFFSET) /* LPADC Command Low Buffer Register */
#define rCMDH15(base_address) REG(base_address, IMXRT_LPADC_CMDH15_OFFSET) /* LPADC Command High Buffer Register */
#define rRESFIFO(base_address) REG(base_address, IMXRT_LPADC_RESFIFO_OFFSET) /* LPADC Data Result FIFO Register */
#define rTCTRL0(base_address) REG(base_address, IMXRT_LPADC_TCTRL0_OFFSET) /* Trigger Control Register */
#define rTCTRL1(base_address) REG(base_address, IMXRT_LPADC_TCTRL1_OFFSET) /* Trigger Control Register */
#define rTCTRL2(base_address) REG(base_address, IMXRT_LPADC_TCTRL2_OFFSET) /* Trigger Control Register */
#define rTCTRL3(base_address) REG(base_address, IMXRT_LPADC_TCTRL3_OFFSET) /* Trigger Control Register */
#define rTCTRL4(base_address) REG(base_address, IMXRT_LPADC_TCTRL4_OFFSET) /* Trigger Control Register */
#define rTCTRL5(base_address) REG(base_address, IMXRT_LPADC_TCTRL5_OFFSET) /* Trigger Control Register */
#define rTCTRL6(base_address) REG(base_address, IMXRT_LPADC_TCTRL6_OFFSET) /* Trigger Control Register */
#define rTCTRL7(base_address) REG(base_address, IMXRT_LPADC_TCTRL7_OFFSET) /* Trigger Control Register */
#define rCV1(base_address) REG(base_address, IMXRT_LPADC_CV1_OFFSET) /* Compare Value Register */
#define rCV2(base_address) REG(base_address, IMXRT_LPADC_CV2_OFFSET) /* Compare Value Register */
#define rCV3(base_address) REG(base_address, IMXRT_LPADC_CV3_OFFSET) /* Compare Value Register */
#define rCV4(base_address) REG(base_address, IMXRT_LPADC_CV4_OFFSET) /* Compare Value Register */
int px4_arch_adc_init(uint32_t base_address)
{
static bool once = false;
if (!once) {
once = true;
/* Input is ADCx_CLK_ROOT_SYS_PLL2_CLK with devide by 6.
* 528 Mhz / 6 = 88 Mhz.
*/
if (base_address == IMXRT_LPADC1_BASE) {
imxrt_clockall_adc1();
} else if (base_address == IMXRT_LPADC2_BASE) {
imxrt_clockall_adc2();
}
irqstate_t flags = px4_enter_critical_section();
rCTRL(base_address) |= IMXRT_LPADC_CTRL_RST;
rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_RST;
rCTRL(base_address) |= IMXRT_LPADC_CTRL_RSTFIFO;
rCFG(base_address) = IMXRT_LPADC_CFG_REFSEL_REFSEL_0 | IMXRT_LPADC_CFG_PWREN | IMXRT_LPADC_CFG_PWRSEL_PWRSEL_3 |
IMXRT_LPADC_CFG_PUDLY(128);
rCTRL(base_address) = IMXRT_LPADC_CTRL_ADCEN;
px4_leave_critical_section(flags);
/* Read ADC1 vtemp_sensor_plus */
rCMDL1(base_address) = IMXRT_LPADC_CMDL1_ADCH_ADCH_7;
rCMDH1(base_address) = IMXRT_LPADC_CMDH1_STS_STS_7 | IMXRT_LPADC_CMDH1_AVGS_AVGS_0;
rTCTRL0(base_address) = IMXRT_LPADC_TCTRL0_TCMD_TCMD_1;
rSTAT(base_address) = IMXRT_LPADC_STAT_FOF;
/* kick off a sample and wait for it to complete */
hrt_abstime now = hrt_absolute_time();
rSWTRIG(base_address) = IMXRT_LPADC_SWTRIG_SWT0;
while (!(rSTAT(base_address) & IMXRT_LPADC_STAT_RDY)) {
/* don't wait for more than 100us, since that means something broke -
* should reset here if we see this
*/
if ((hrt_absolute_time() - now) > 100) {
rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN;
return -4;
}
}
int32_t r = (rRESFIFO(base_address) & IMXRT_LPADC_RESFIFO_D_MASK) >> 3;
UNUSED(r);
rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN;
} // once
return 0;
}
void px4_arch_adc_uninit(uint32_t base_address)
{
rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN;
if (base_address == IMXRT_LPADC1_BASE) {
imxrt_clockoff_adc1();
} else if (base_address == IMXRT_LPADC2_BASE) {
imxrt_clockoff_adc2();
}
}
uint32_t px4_arch_adc_sample(uint32_t base_address, unsigned channel)
{
uint32_t absel = (channel & 1) ? IMXRT_LPADC_CMDL1_ABSEL : 0;
channel >>= 1;
irqstate_t flags = px4_enter_critical_section();
/* clear any previous results */
rCTRL(base_address) |= IMXRT_LPADC_CTRL_RSTFIFO;
rCMDL1(base_address) = absel | (channel & IMXRT_LPADC_CMDL1_ADCH_MASK);
rCMDH1(base_address) = IMXRT_LPADC_CMDH1_STS_STS_7 | IMXRT_LPADC_CMDH1_AVGS_AVGS_0;
rTCTRL0(base_address) = IMXRT_LPADC_TCTRL0_TCMD_TCMD_1;
rSTAT(base_address) = IMXRT_LPADC_STAT_FOF;
rCTRL(base_address) = IMXRT_LPADC_CTRL_ADCEN;
up_udelay(1);
rSWTRIG(base_address) = IMXRT_LPADC_SWTRIG_SWT0;
/* wait for the conversion to complete */
hrt_abstime now = hrt_absolute_time();
while (!(rSTAT(base_address) & IMXRT_LPADC_STAT_RDY)) {
/* don't wait for more than 30us, since that means something broke
* should reset here if we see this
*/
if ((hrt_absolute_time() - now) > 30) {
rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN;
px4_leave_critical_section(flags);
return UINT32_MAX;
}
}
/* read the result and clear COCO0 */
uint32_t result = (rRESFIFO(base_address) & IMXRT_LPADC_RESFIFO_D_MASK) >> 3;
rCTRL(base_address) &= ~IMXRT_LPADC_CTRL_ADCEN;
px4_leave_critical_section(flags);
return result;
}
float px4_arch_adc_reference_v()
{
return BOARD_ADC_POS_REF_V;
}
uint32_t px4_arch_adc_temp_sensor_mask()
{
return 0;
}
uint32_t px4_arch_adc_dn_fullcount(void)
{
return 1 << 12; // 12 bit ADC
}
@@ -0,0 +1,45 @@
/****************************************************************************
*
* 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 <board_config.h>
#if !defined(HW_REV_VER_ADC_BASE)
# define HW_REV_VER_ADC_BASE IMXRT_LPADC1_BASE
#endif
#if !defined(SYSTEM_ADC_BASE)
# define SYSTEM_ADC_BASE IMXRT_LPADC1_BASE
#endif
#include <px4_platform/adc.h>
@@ -0,0 +1,475 @@
/****************************************************************************
*
* Copyright (C) 2023 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 <stdint.h>
#include "hardware/imxrt_flexpwm.h"
#include <px4_platform_common/constexpr_util.h>
#include <board_config.h>
#if !defined(CONFIG_ARCH_CHIP_MIMXRT1176DVMAA)
# error "This code has only been validated with IMXRT1176. Make sure it is correct before using it on another board."
#endif
/*
* PWM
*/
namespace PWM
{
enum FlexPWM {
FlexPWM1 = 0,
FlexPWM2,
FlexPWM3,
FlexPWM4,
};
enum FlexPWMModule {
PWM1_PWM_A = 0,
PWM1_PWM_B,
PWM1_PWM_X,
PWM2_PWM_A,
PWM2_PWM_B,
PWM2_PWM_X,
PWM3_PWM_A,
PWM3_PWM_B,
PWM3_PWM_X,
PWM4_PWM_A,
PWM4_PWM_B,
PWM4_PWM_X,
};
enum FlexPWMSubmodule {
Submodule0 = 0,
Submodule1,
Submodule2,
Submodule3,
};
struct FlexPWMConfig {
FlexPWMModule module;
FlexPWMSubmodule submodule;
};
}
static inline constexpr uint32_t getFlexPWMBaseRegister(PWM::FlexPWM pwm)
{
switch (pwm) {
case PWM::FlexPWM1: return IMXRT_FLEXPWM1_BASE;
case PWM::FlexPWM2: return IMXRT_FLEXPWM2_BASE;
case PWM::FlexPWM3: return IMXRT_FLEXPWM3_BASE;
case PWM::FlexPWM4: return IMXRT_FLEXPWM4_BASE;
}
return 0;
}
namespace IOMUX
{
enum class Pad {
GPIO_EMC_B1_00 = 0,
GPIO_EMC_B1_01 = 1,
GPIO_EMC_B1_02 = 2,
GPIO_EMC_B1_03 = 3,
GPIO_EMC_B1_04 = 4,
GPIO_EMC_B1_05 = 5,
GPIO_EMC_B1_06 = 6,
GPIO_EMC_B1_07 = 7,
GPIO_EMC_B1_08 = 8,
GPIO_EMC_B1_09 = 9,
GPIO_EMC_B1_10 = 10,
GPIO_EMC_B1_11 = 11,
GPIO_EMC_B1_12 = 12,
GPIO_EMC_B1_13 = 13,
GPIO_EMC_B1_14 = 14,
GPIO_EMC_B1_15 = 15,
GPIO_EMC_B1_16 = 16,
GPIO_EMC_B1_17 = 17,
GPIO_EMC_B1_18 = 18,
GPIO_EMC_B1_19 = 19,
GPIO_EMC_B1_20 = 20,
GPIO_EMC_B1_21 = 21,
GPIO_EMC_B1_22 = 22,
GPIO_EMC_B1_23 = 23,
GPIO_EMC_B1_24 = 24,
GPIO_EMC_B1_25 = 25,
GPIO_EMC_B1_26 = 26,
GPIO_EMC_B1_27 = 27,
GPIO_EMC_B1_28 = 28,
GPIO_EMC_B1_29 = 29,
GPIO_EMC_B1_30 = 30,
GPIO_EMC_B1_31 = 31,
GPIO_EMC_B1_32 = 32,
GPIO_EMC_B1_33 = 33,
GPIO_EMC_B1_34 = 34,
GPIO_EMC_B1_35 = 35,
GPIO_EMC_B1_36 = 36,
GPIO_EMC_B1_37 = 37,
GPIO_EMC_B1_38 = 38,
GPIO_EMC_B1_39 = 39,
GPIO_EMC_B1_40 = 40,
GPIO_EMC_B1_41 = 41,
GPIO_EMC_B2_00 = 42,
GPIO_EMC_B2_01 = 43,
GPIO_EMC_B2_02 = 44,
GPIO_EMC_B2_03 = 45,
GPIO_EMC_B2_04 = 46,
GPIO_EMC_B2_05 = 47,
GPIO_EMC_B2_06 = 48,
GPIO_EMC_B2_07 = 49,
GPIO_EMC_B2_08 = 50,
GPIO_EMC_B2_09 = 51,
GPIO_EMC_B2_10 = 52,
GPIO_EMC_B2_11 = 53,
GPIO_EMC_B2_12 = 54,
GPIO_EMC_B2_13 = 55,
GPIO_EMC_B2_14 = 56,
GPIO_EMC_B2_15 = 57,
GPIO_EMC_B2_16 = 58,
GPIO_EMC_B2_17 = 59,
GPIO_EMC_B2_18 = 60,
GPIO_EMC_B2_19 = 61,
GPIO_EMC_B2_20 = 62,
GPIO_AD_00 = 63,
GPIO_AD_01 = 64,
GPIO_AD_02 = 65,
GPIO_AD_03 = 66,
GPIO_AD_04 = 67,
GPIO_AD_05 = 68,
GPIO_AD_06 = 69,
GPIO_AD_07 = 70,
GPIO_AD_08 = 71,
GPIO_AD_09 = 72,
GPIO_AD_10 = 73,
GPIO_AD_11 = 74,
GPIO_AD_12 = 75,
GPIO_AD_13 = 76,
GPIO_AD_14 = 77,
GPIO_AD_15 = 78,
GPIO_AD_16 = 79,
GPIO_AD_17 = 80,
GPIO_AD_18 = 81,
GPIO_AD_19 = 82,
GPIO_AD_20 = 83,
GPIO_AD_21 = 84,
GPIO_AD_22 = 85,
GPIO_AD_23 = 86,
GPIO_AD_24 = 87,
GPIO_AD_25 = 88,
GPIO_AD_26 = 89,
GPIO_AD_27 = 90,
GPIO_AD_28 = 91,
GPIO_AD_29 = 92,
GPIO_AD_30 = 93,
GPIO_AD_31 = 94,
GPIO_AD_32 = 95,
GPIO_AD_33 = 96,
GPIO_AD_34 = 97,
GPIO_AD_35 = 98,
GPIO_SD_B1_00 = 99,
GPIO_SD_B1_01 = 100,
GPIO_SD_B1_02 = 101,
GPIO_SD_B1_03 = 102,
GPIO_SD_B1_04 = 103,
GPIO_SD_B1_05 = 104,
GPIO_SD_B2_00 = 105,
GPIO_SD_B2_01 = 106,
GPIO_SD_B2_02 = 107,
GPIO_SD_B2_03 = 108,
GPIO_SD_B2_04 = 109,
GPIO_SD_B2_05 = 110,
GPIO_SD_B2_06 = 111,
GPIO_SD_B2_07 = 112,
GPIO_SD_B2_08 = 113,
GPIO_SD_B2_09 = 114,
GPIO_SD_B2_10 = 115,
GPIO_SD_B2_11 = 116,
GPIO_DISP_B1_00 = 117,
GPIO_DISP_B1_01 = 118,
GPIO_DISP_B1_02 = 119,
GPIO_DISP_B1_03 = 120,
GPIO_DISP_B1_04 = 121,
GPIO_DISP_B1_05 = 122,
GPIO_DISP_B1_06 = 123,
GPIO_DISP_B1_07 = 124,
GPIO_DISP_B1_08 = 125,
GPIO_DISP_B1_09 = 126,
GPIO_DISP_B1_10 = 127,
GPIO_DISP_B1_11 = 128,
GPIO_DISP_B2_00 = 129,
GPIO_DISP_B2_01 = 130,
GPIO_DISP_B2_02 = 131,
GPIO_DISP_B2_03 = 132,
GPIO_DISP_B2_04 = 133,
GPIO_DISP_B2_05 = 134,
GPIO_DISP_B2_06 = 135,
GPIO_DISP_B2_07 = 136,
GPIO_DISP_B2_08 = 137,
GPIO_DISP_B2_09 = 138,
GPIO_DISP_B2_10 = 139,
GPIO_DISP_B2_11 = 140,
GPIO_DISP_B2_12 = 141,
GPIO_DISP_B2_13 = 142,
GPIO_DISP_B2_14 = 143,
GPIO_DISP_B2_15 = 144,
WAKEUP = 145,
PMIC_ON_REQ = 146,
PMIC_STBY_REQ = 147,
GPIO_SNVS_00 = 148,
GPIO_SNVS_01 = 149,
GPIO_SNVS_02 = 150,
GPIO_SNVS_03 = 151,
GPIO_SNVS_04 = 152,
GPIO_SNVS_05 = 153,
GPIO_SNVS_06 = 154,
GPIO_SNVS_07 = 155,
GPIO_SNVS_08 = 156,
GPIO_SNVS_09 = 157,
GPIO_LPSR_00 = 158,
GPIO_LPSR_01 = 159,
GPIO_LPSR_02 = 160,
GPIO_LPSR_03 = 161,
GPIO_LPSR_04 = 162,
GPIO_LPSR_05 = 163,
GPIO_LPSR_06 = 164,
GPIO_LPSR_07 = 165,
GPIO_LPSR_08 = 166,
GPIO_LPSR_09 = 167,
GPIO_LPSR_10 = 168,
GPIO_LPSR_11 = 169,
GPIO_LPSR_12 = 170,
GPIO_LPSR_13 = 171,
GPIO_LPSR_14 = 172,
GPIO_LPSR_15 = 173
};
}
/*
* GPIO
*/
namespace GPIO
{
enum Port {
PortInvalid = 0,
Port1,
Port2,
Port3,
Port4,
Port5,
Port6,
Port7,
Port8,
Port9,
Port10,
Port11,
Port12,
Port13,
};
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,
};
struct GPIOPin {
Port port;
Pin pin;
};
}
static inline constexpr uint32_t getGPIOPort(GPIO::Port port)
{
switch (port) {
case GPIO::Port1: return GPIO_PORT1;
case GPIO::Port2: return GPIO_PORT2;
case GPIO::Port3: return GPIO_PORT3;
case GPIO::Port4: return GPIO_PORT4;
case GPIO::Port5: return GPIO_PORT5;
case GPIO::Port6: return GPIO_PORT6;
case GPIO::Port7: return GPIO_PORT7;
case GPIO::Port8: return GPIO_PORT8;
case GPIO::Port9: return GPIO_PORT9;
case GPIO::Port10: return GPIO_PORT10;
case GPIO::Port11: return GPIO_PORT11;
case GPIO::Port12: return GPIO_PORT12;
case GPIO::Port13: return GPIO_PORT13;
default: break;
}
return 0;
}
static inline constexpr uint32_t getGPIOPin(GPIO::Pin pin)
{
switch (pin) {
case GPIO::Pin0: return GPIO_PIN0;
case GPIO::Pin1: return GPIO_PIN1;
case GPIO::Pin2: return GPIO_PIN2;
case GPIO::Pin3: return GPIO_PIN3;
case GPIO::Pin4: return GPIO_PIN4;
case GPIO::Pin5: return GPIO_PIN5;
case GPIO::Pin6: return GPIO_PIN6;
case GPIO::Pin7: return GPIO_PIN7;
case GPIO::Pin8: return GPIO_PIN8;
case GPIO::Pin9: return GPIO_PIN9;
case GPIO::Pin10: return GPIO_PIN10;
case GPIO::Pin11: return GPIO_PIN11;
case GPIO::Pin12: return GPIO_PIN12;
case GPIO::Pin13: return GPIO_PIN13;
case GPIO::Pin14: return GPIO_PIN14;
case GPIO::Pin15: return GPIO_PIN15;
case GPIO::Pin16: return GPIO_PIN16;
case GPIO::Pin17: return GPIO_PIN17;
case GPIO::Pin18: return GPIO_PIN18;
case GPIO::Pin19: return GPIO_PIN19;
case GPIO::Pin20: return GPIO_PIN20;
case GPIO::Pin21: return GPIO_PIN21;
case GPIO::Pin22: return GPIO_PIN22;
case GPIO::Pin23: return GPIO_PIN23;
case GPIO::Pin24: return GPIO_PIN24;
case GPIO::Pin25: return GPIO_PIN25;
case GPIO::Pin26: return GPIO_PIN26;
case GPIO::Pin27: return GPIO_PIN27;
case GPIO::Pin28: return GPIO_PIN28;
case GPIO::Pin29: return GPIO_PIN29;
case GPIO::Pin30: return GPIO_PIN30;
case GPIO::Pin31: return GPIO_PIN31;
}
return 0;
}
namespace SPI
{
enum class Bus {
LPSPI1 = 1,
LPSPI2,
LPSPI3,
LPSPI4,
LPSPI5,
LPSPI6,
};
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
@@ -0,0 +1,35 @@
/****************************************************************************
*
* 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 "../../../imxrt/include/px4_arch/i2c_hw_description.h"
@@ -0,0 +1,36 @@
/****************************************************************************
*
* 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 "../../../imxrt/include/px4_arch/io_timer.h"
@@ -0,0 +1,238 @@
/****************************************************************************
*
* 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 <px4_arch/hw_description.h>
#include <px4_platform_common/spi.h>
#if defined(CONFIG_SPI)
#include <imxrt_gpio.h>
constexpr bool validateSPIConfig(const px4_spi_bus_t spi_busses_conf[SPI_BUS_MAX_BUS_ITEMS])
{
const bool nuttx_enabled_spi_buses[] = {
#ifdef CONFIG_IMXRT_LPSPI1
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI2
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI3
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI4
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI5
true,
#else
false,
#endif
#ifdef CONFIG_IMXRT_LPSPI6
true,
#else
false,
#endif
};
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_STM32H7_SPIx)");
}
return false;
}
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{};
ret.cs_gpio = getGPIOPort(cs_gpio.port) | getGPIOPin(cs_gpio.pin) | (GPIO_OUTPUT | GPIO_OUTPUT_ONE | CS_IOMUX);
if (drdy_gpio.port != GPIO::PortInvalid) {
ret.drdy_gpio = getGPIOPort(drdy_gpio.port) | getGPIOPin(drdy_gpio.pin) | (GPIO_INPUT | DRDY_IOMUX);
}
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.port != GPIO::PortInvalid) {
ret.power_enable_gpio = getGPIOPort(power_enable.port) | getGPIOPin(power_enable.pin) |
(GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GENERAL_OUTPUT_IOMUX);
}
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.port == GPIO::PortInvalid) {
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];
};
#if defined(BOARD_HAS_HW_SPLIT_VERSIONING)
static inline constexpr px4_spi_bus_all_hw_t initSPIFmumID(hw_fmun_id_t hw_fmun_id,
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_fmun_id = hw_fmun_id;
return ret;
}
#else
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;
}
#endif
constexpr bool validateSPIConfig(const px4_spi_bus_t spi_buses_conf[SPI_BUS_MAX_BUS_ITEMS]);
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;
}
#endif // CONFIG_SPI
@@ -0,0 +1,125 @@
/****************************************************************************
*
* Copyright (C) 2022 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/fs/ioctl.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#pragma once
#define SSARC_DUMP_GETDESC_IOCTL _DIOC(0x0000) /* Returns a progmem_s */
#define SSARC_DUMP_CLEAR_IOCTL _DIOC(0x0010) /* Erases flash sector */
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
struct ssarc_s {
struct timespec lastwrite;
int fileno;
int len;
int flags;
};
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
# define EXTERN extern "C"
extern "C"
{
#else
# define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Function: ssarc_dump_initialize
*
* Description:
* Initialize the Progmem dump driver
*
* Input Parameters:
* devpath - the path to instantiate the files.
* sizes - Pointer to a any array of file sizes to create
* the last entry should be 0
* A size of -1 will use all the remaining spaces
*
* Returned Value:
* Number of files created on success; Negated errno on failure.
*
* Assumptions:
*
****************************************************************************/
int ssarc_dump_initialize(char *devpath, int *sizes);
/****************************************************************************
* Function: ssarc_dump_savepanic
*
* Description:
* Saves the panic context in a previously allocated BBSRAM file
*
* Parameters:
* fileno - the value returned by the ioctl SSARC_DUMP_GETDESC_IOCTL
* context - Pointer to a any array of bytes to save
* length - The length of the data pointed to byt context
*
* Returned Value:
* Length saved or negated errno.
*
* Assumptions:
*
****************************************************************************/
int ssarc_dump_savepanic(int fileno, uint8_t *context, int length);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
@@ -1,6 +1,6 @@
############################################################################
#
# Copyright (c) 2015 PX4 Development Team. All rights reserved.
# 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
@@ -31,17 +31,6 @@
#
############################################################################
<<<<<<<< HEAD:boards/modalai/voxl2-io/src/CMakeLists.txt
add_library(drivers_board
init.c
timer_config.cpp
)
target_link_libraries(drivers_board
PRIVATE
nuttx_arch
========
px4_add_library(arch_px4io_serial
px4io_serial.cpp
>>>>>>>> e90e8ae0ea (Intial Commit PX4 FMUV6RT):platforms/nuttx/src/px4/nxp/rt117x/px4io_serial/CMakeLists.txt
)
+51 -1
View File
@@ -147,7 +147,57 @@ typedef struct progmem_s dump_s;
PROGMEM_SIZE_FN3, /* For the Panic Log use rest of space */ \
0 /* End of table marker */ \
}
#else /* HAS_PROGMEM */
#elif defined(HAS_SSARC)
typedef struct ssarc_s dump_s;
#define HARDFAULT_REBOOT_FILENO 0
#define HARDFAULT_REBOOT_PATH SSARC_DUMP_PATH "" STRINGIFY(HARDFAULT_REBOOT_FILENO)
#define HARDFAULT_ULOG_FILENO 3
#define HARDFAULT_ULOG_PATH SSARC_DUMP_PATH "" STRINGIFY(HARDFAULT_ULOG_FILENO)
#define HARDFAULT_FILENO 4
#define HARDFAULT_PATH SSARC_DUMP_PATH "" STRINGIFY(HARDFAULT_FILENO)
#define HARDFAULT_MAX_ULOG_FILE_LEN 64 /* must be large enough to store the full path to the log file */
#define SSARC_DUMP_SIZE_FN0 ((((sizeof(int)) / PX4_SSARC_BLOCK_DATA) + 1) * PX4_SSARC_BLOCK_DATA)
#define SSARC_DUMP_SIZE_FN1 (((384 / PX4_SSARC_BLOCK_DATA) + 1) * PX4_SSARC_BLOCK_DATA) /* greater then 2.5 times the size of vehicle_status_s */
#define SSARC_DUMP_SIZE_FN2 (((384 / PX4_SSARC_BLOCK_DATA) + 1) * PX4_SSARC_BLOCK_DATA) /* greater then 2.5 times the size of vehicle_status_s */
#define SSARC_DUMP_SIZE_FN3 (((HARDFAULT_MAX_ULOG_FILE_LEN / PX4_SSARC_BLOCK_DATA) + 1) * PX4_SSARC_BLOCK_DATA)
#define SSARC_DUMP_SIZE_FN4 -1
/* The following guides in the amount of the user and interrupt stack
* data we can save. The amount of storage left will dictate the actual
* number of entries of the user stack data saved. If it is too big
* It will be truncated by the call to savepanic
*/
#define SSARC_DUMP_HEADER_SIZE PX4_SSARC_HEADER_SIZE + 32 /* This is an assumption */
#define SSARC_DUMP_USED ((5*SSARC_DUMP_HEADER_SIZE)+(SSARC_DUMP_SIZE_FN0+SSARC_DUMP_SIZE_FN1+SSARC_DUMP_SIZE_FN2+SSARC_DUMP_SIZE_FN3))
#define SSARC_DUMP_REMAINING (PX4_SSARC_DUMP_SIZE-SSARC_DUMP_USED)
#if CONFIG_ARCH_INTERRUPTSTACK <= 3
# define SSARC_DUMP_NUMBER_STACKS 1
#else
# define SSARC_DUMP_NUMBER_STACKS 2
#endif
#define SSARC_DUMP_FIXED_ELEMENTS_SIZE (sizeof(info_s))
#define SSARC_DUMP_LEFTOVER (SSARC_DUMP_REMAINING-SSARC_DUMP_FIXED_ELEMENTS_SIZE)
#define CONFIG_ISTACK_SIZE (SSARC_DUMP_LEFTOVER/SSARC_DUMP_NUMBER_STACKS/sizeof(stack_word_t))
#define CONFIG_USTACK_SIZE (SSARC_DUMP_LEFTOVER/SSARC_DUMP_NUMBER_STACKS/sizeof(stack_word_t))
#define SSARC_DUMP_FILE_COUNT 5
/* The path to the Battery Backed up SRAM */
#define SSARC_DUMP_PATH "/fs/ssarc"
/* The sizes of the files to create (-1) use rest of BBSRAM memory */
#define SSARC_DUMP_FILE_SIZES { \
SSARC_DUMP_SIZE_FN0, /* For Time stamp only */ \
SSARC_DUMP_SIZE_FN1, /* For Current Flight Parameters Copy A */ \
SSARC_DUMP_SIZE_FN2, /* For Current Flight Parameters Copy B */ \
SSARC_DUMP_SIZE_FN3, /* For the latest ULog file path */ \
SSARC_DUMP_SIZE_FN4, /* For the Panic Log use rest of space */ \
0 /* End of table marker */ \
}
#else /* HAS_SSARC */
#define CONFIG_ISTACK_SIZE 0
#define CONFIG_USTACK_SIZE 0
@@ -66,6 +66,10 @@
#include <px4_platform/progmem_dump.h>
#endif
#ifdef HAS_SSARC
#include <ssarc_dump.h>
#endif
#include "chip.h"
#if defined(CONSTRAINED_FLASH_NO_HELP)