diff --git a/boards/Kconfig b/boards/Kconfig index 63b5baf3814..12d27a8853c 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -1620,6 +1620,16 @@ config ARCH_BOARD_S32K344EVB This options selects support for NuttX on the NXP S32K344EVB board featuring the S32K344 Cortex-M7. +config ARCH_BOARD_MR_CANHUBK3 + bool "NXP MR-CANHUBK3" + depends on ARCH_CHIP_S32K344 + select ARCH_HAVE_LEDS + select ARCH_HAVE_BUTTONS + select ARCH_HAVE_IRQBUTTONS + ---help--- + This options selects support for NuttX on the NXP MR-CANHUBK3 board + featuring the S32K344 Cortex-M7. + config ARCH_BOARD_SABRE_6QUAD bool "NXP/Freescale i.MX6 Sabre-6Quad board" depends on ARCH_CHIP_IMX6_6QUAD @@ -2680,6 +2690,7 @@ config ARCH_BOARD default "ucans32k146" if ARCH_BOARD_UCANS32K146 default "s32k148evb" if ARCH_BOARD_S32K148EVB default "s32k344evb" if ARCH_BOARD_S32K344EVB + default "mr-canhubk3" if ARCH_BOARD_MR_CANHUBK3 default "rv32m1-vega" if ARCH_BOARD_RV32M1_VEGA default "rv-virt" if ARCH_BOARD_QEMU_RV_VIRT default "sabre-6quad" if ARCH_BOARD_SABRE_6QUAD @@ -2856,6 +2867,9 @@ endif if ARCH_BOARD_S32K344EVB source "boards/arm/s32k3xx/s32k344evb/Kconfig" endif +if ARCH_BOARD_MR_CANHUBK3 +source "boards/arm/s32k3xx/mr-canhubk3/Kconfig" +endif if ARCH_BOARD_SABRE_6QUAD source "boards/arm/imx6/sabre-6quad/Kconfig" endif diff --git a/boards/arm/s32k3xx/mr-canhubk3/Kconfig b/boards/arm/s32k3xx/mr-canhubk3/Kconfig new file mode 100644 index 00000000000..a4355bffbca --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/Kconfig @@ -0,0 +1,24 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_BOARD_MR_CANHUBK3 + +config S32K3XX_TJA1153 + bool "TJA1153 Initialization Sequence" + default n + depends on S32K3XX_FLEXCAN + ---help--- + Enables a basic NXP TJA1153 initialization routine to + configure the CAN PHY to allow all incoming and outgoing traffic. + +config S32K3XX_SELFTEST + bool "MR-CANHUBK3 Board Self-Test" + default n + ---help--- + Run basic routines to verify that all board components are up and + running. Results are send to the syslog, it is recommended to + enable all output levels (error, warning and info). + +endif # ARCH_BOARD_MR_CANHUBK3 diff --git a/boards/arm/s32k3xx/mr-canhubk3/README.txt b/boards/arm/s32k3xx/mr-canhubk3/README.txt new file mode 100644 index 00000000000..3fe2805aaba --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/README.txt @@ -0,0 +1,116 @@ +README +====== + +This directory holds the port to the NXP MR-CANHUBK3 board. + +Contents +======== + + o Status + o Serial Console + o LEDs and Buttons + o Configurations + +Status +====== + + 2021-09-28: Configuration created (copy-paste from S32K344EVB). + Remains untested, because hardware is not available yet. + + TODO: Need to calibrate the delay loop. The current value of + CONFIG_BOARD_LOOPSPERMSEC is a bogus value retained from a copy-paste + (see apps/examples/calib_udelay). + +Serial Console +============== + + By default, the serial console will be provided on the DCD-LZ UART + (available on the 7-pin DCD-LZ debug connector P6): + + DCD-LZ UART RX PTA8 (LPUART2_RX) + DCD-LZ UART TX PTA9 (LPUART2_TX) + +LEDs and Buttons +================ + + LEDs + ---- + The MR-CANHUBK3 has one RGB LED: + + RedLED PTE14 (FXIO D7 / EMIOS0 CH19) + GreenLED PTA27 (FXIO D5 / EMIOS1 CH10 / EMIOS2 CH10) + BlueLED PTE12 (FXIO D8 / EMIOS1 CH5) + + An output of '0' illuminates the LED. + + If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in + any way. The following definitions are used to access individual RGB + components (see mr-canhubk3.h): + + GPIO_LED_R + GPIO_LED_G + GPIO_LED_B + + The RGB components could, alternatively, be controlled through PWM using + the common RGB LED driver. + + If CONFIG_ARCH_LEDs is defined, then NuttX will control the LEDs on board + the MR-CANHUBK3. The following definitions describe how NuttX controls the + LEDs: + + ==========================================+========+========+========= + RED GREEN BLUE + ==========================================+========+========+========= + + LED_STARTED NuttX has been started OFF OFF OFF + LED_HEAPALLOCATE Heap has been allocated OFF OFF ON + LED_IRQSENABLED Interrupts enabled OFF OFF ON + LED_STACKCREATED Idle stack created OFF ON OFF + LED_INIRQ In an interrupt (no change) + LED_SIGNAL In a signal handler (no change) + LED_ASSERTION An assertion failed (no change) + LED_PANIC The system has crashed FLASH OFF OFF + LED_IDLE S32K344 in sleep mode (no change) + ==========================================+========+========+========= + + Buttons + ------- + The MR-CANHUBK3 supports two buttons: + + SW1 PTD15 (EIRQ31) + SW2 PTA25 (EIRQ5 / WKPU34) + +Configurations +============== + + Common Information + ------------------ + Each MR-CANHUBK3 configuration is maintained in a sub-directory and can be + selected as follows: + + tools/configure.sh mr-canhubk3: + + Where is one of the sub-directories listed in the next paragraph. + + NOTES (common for all configurations): + + 1. This configuration uses the mconf-based configuration tool. To change + this configuration using that tool, you should: + + a. Build and install the kconfig-mconf tool. See nuttx/README.txt. + Also see additional README.txt files in the NuttX tools repository. + + b. Execute 'make menuconfig' in nuttx/ in order to start the + reconfiguration process. + + 2. Unless otherwise stated, the serial console used is LPUART1 at + 115,200 8N1. This corresponds to the OpenSDA VCOM port. + + Configuration Sub-directories + ----------------------------- + + nsh: + --- + Configures the NuttShell (nsh) located at apps/examples/nsh. Support + for builtin applications is enabled, but in the base configuration the + only application selected is the "Hello, World!" example. diff --git a/boards/arm/s32k3xx/mr-canhubk3/configs/net/defconfig b/boards/arm/s32k3xx/mr-canhubk3/configs/net/defconfig new file mode 100644 index 00000000000..e5a33c4690b --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/configs/net/defconfig @@ -0,0 +1,113 @@ +# +# 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_ARCH_FPU is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +# CONFIG_NSH_DISABLE_DATE is not set +CONFIG_ALLOW_GPL_COMPONENTS=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="mr-canhubk3" +CONFIG_ARCH_BOARD_MR_CANHUBK3=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP="s32k3xx" +CONFIG_ARCH_CHIP_S32K344=y +CONFIG_ARCH_CHIP_S32K3XX=y +CONFIG_ARCH_IRQBUTTONS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_BOARD_LOOPSPERMSEC=14539 +CONFIG_BUILTIN=y +CONFIG_CANUTILS_CANDUMP=y +CONFIG_CANUTILS_CANSEND=y +CONFIG_EXAMPLES_BUTTONS=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_TELNETD=y +CONFIG_FLEXCAN0_ARBI_BITRATE=500000 +CONFIG_FLEXCAN0_DATA_BITRATE=2000000 +CONFIG_FLEXCAN1_ARBI_BITRATE=500000 +CONFIG_FLEXCAN1_DATA_BITRATE=2000000 +CONFIG_FLEXCAN2_ARBI_BITRATE=500000 +CONFIG_FLEXCAN2_DATA_BITRATE=2000000 +CONFIG_FLEXCAN3_ARBI_BITRATE=500000 +CONFIG_FLEXCAN3_DATA_BITRATE=2000000 +CONFIG_FLEXCAN4_ARBI_BITRATE=500000 +CONFIG_FLEXCAN4_DATA_BITRATE=2000000 +CONFIG_FLEXCAN5_ARBI_BITRATE=500000 +CONFIG_FLEXCAN5_DATA_BITRATE=2000000 +CONFIG_FS_LITTLEFS=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INPUT=y +CONFIG_INPUT_BUTTONS=y +CONFIG_INPUT_BUTTONS_LOWER=y +CONFIG_LPUART2_SERIAL_CONSOLE=y +CONFIG_MM_REGIONS=2 +CONFIG_MTD=y +CONFIG_MTD_MX25RXX=y +CONFIG_MX25RXX_LXX=y +CONFIG_NET=y +CONFIG_NETDEV_IFINDEX=y +CONFIG_NETDEV_LATEINIT=y +CONFIG_NETUTILS_PING=y +CONFIG_NETUTILS_TELNETD=y +CONFIG_NET_CAN=y +CONFIG_NET_CAN_EXTID=y +CONFIG_NET_CAN_NOTIFIER=y +CONFIG_NET_CAN_SOCK_OPTS=y +CONFIG_NET_ICMP=y +CONFIG_NET_TCP=y +CONFIG_NET_TIMESTAMP=y +CONFIG_NET_UDP=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=272000 +CONFIG_RAM_START=0x20400000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_S32K3XX_DTCM_HEAP=y +CONFIG_S32K3XX_EIRQINTS=y +CONFIG_S32K3XX_ENET=y +CONFIG_S32K3XX_FLEXCAN0=y +CONFIG_S32K3XX_FLEXCAN1=y +CONFIG_S32K3XX_FLEXCAN2=y +CONFIG_S32K3XX_FLEXCAN3=y +CONFIG_S32K3XX_FLEXCAN4=y +CONFIG_S32K3XX_FLEXCAN5=y +CONFIG_S32K3XX_FS26=y +CONFIG_S32K3XX_GPIOIRQ=y +CONFIG_S32K3XX_LPI2C0=y +CONFIG_S32K3XX_LPI2C1=y +CONFIG_S32K3XX_LPSPI3=y +CONFIG_S32K3XX_LPSPI3_PINCFG=3 +CONFIG_S32K3XX_LPUART0=y +CONFIG_S32K3XX_LPUART10=y +CONFIG_S32K3XX_LPUART13=y +CONFIG_S32K3XX_LPUART14=y +CONFIG_S32K3XX_LPUART1=y +CONFIG_S32K3XX_LPUART2=y +CONFIG_S32K3XX_LPUART9=y +CONFIG_S32K3XX_QSPI=y +CONFIG_S32K3XX_TJA1153=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SPI_DRIVER=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=5 +CONFIG_START_YEAR=2022 +CONFIG_SYMTAB_ORDEREDBYNAME=y +CONFIG_SYSTEM_NSH=y +CONFIG_TIMER=y diff --git a/boards/arm/s32k3xx/mr-canhubk3/configs/nsh/defconfig b/boards/arm/s32k3xx/mr-canhubk3/configs/nsh/defconfig new file mode 100644 index 00000000000..1a4263f7110 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/configs/nsh/defconfig @@ -0,0 +1,52 @@ +# +# 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_ARCH_FPU is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="mr-canhubk3" +CONFIG_ARCH_BOARD_MR_CANHUBK3=y +CONFIG_ARCH_CHIP="s32k3xx" +CONFIG_ARCH_CHIP_S32K344=y +CONFIG_ARCH_CHIP_S32K3XX=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_BOARD_LOOPSPERMSEC=14539 +CONFIG_BUILTIN=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_LPUART2_SERIAL_CONSOLE=y +CONFIG_MM_REGIONS=2 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=272000 +CONFIG_RAM_START=0x20400000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_S32K3XX_DTCM_HEAP=y +CONFIG_S32K3XX_FS26=y +CONFIG_S32K3XX_LPSPI3=y +CONFIG_S32K3XX_LPSPI3_PINCFG=3 +CONFIG_S32K3XX_LPUART2=y +CONFIG_SCHED_WAITPID=y +CONFIG_SPI_DRIVER=y +CONFIG_START_DAY=30 +CONFIG_START_MONTH=5 +CONFIG_START_YEAR=2022 +CONFIG_SYMTAB_ORDEREDBYNAME=y +CONFIG_SYSTEM_NSH=y diff --git a/boards/arm/s32k3xx/mr-canhubk3/include/board.h b/boards/arm/s32k3xx/mr-canhubk3/include/board.h new file mode 100644 index 00000000000..0c59590fdae --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/include/board.h @@ -0,0 +1,324 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +#ifndef __BOARDS_ARM_S32K3XX_MR_CANHUBK3_INCLUDE_BOARD_H +#define __BOARDS_ARM_S32K3XX_MR_CANHUBK3_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking *****************************************************************/ + +/* The MR-CANHUBK3 is fitted with a 16 MHz crystal */ + +#define BOARD_XTAL_FREQUENCY 16000000 + +/* The S32K344 will run at 160 MHz */ + +#define MR_CANHUBK3_SYSCLK_FREQUENCY 160000000 + +/* MX25L QuadSPI Flash ******************************************************/ + +#ifdef CONFIG_S32K3XX_QSPI +# ifdef CONFIG_MTD_MX25RXX +# define HAVE_MX25L +# ifdef CONFIG_FS_LITTLEFS +# define HAVE_MX25L_LITTLEFS +# else +# ifdef CONFIG_FS_NXFFS +# define HAVE_MX25L_NXFFS +# else +# define HAVE_MX25L_CHARDEV +# endif +# endif +# endif +#endif + +#define MX25L_MTD_MINOR 0 +#define MX25L_SMART_MINOR 0 + +/* LED definitions **********************************************************/ + +/* The MR-CANHUBK3 has one RGB LED: + * + * RedLED PTE14 (FXIO D7 / EMIOS0 CH19) + * GreenLED PTA27 (FXIO D5 / EMIOS1 CH10 / EMIOS2 CH10) + * BlueLED PTE12 (FXIO D8 / EMIOS1 CH5) + * + * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in + * any way. The following definitions are used to access individual RGB + * components. + * + * The RGB components could, alternatively be controlled through PWM using + * the common RGB LED driver. + */ + +/* LED index values for use with board_userled() */ + +#define BOARD_LED_R 0 +#define BOARD_LED_G 1 +#define BOARD_LED_B 2 +#define BOARD_NLEDS 3 + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED_R_BIT (1 << BOARD_LED_R) +#define BOARD_LED_G_BIT (1 << BOARD_LED_G) +#define BOARD_LED_B_BIT (1 << BOARD_LED_B) + +/* If CONFIG_ARCH_LEDs is defined, then NuttX will control the LEDs on board + * the MR-CANHUBK3. The following definitions describe how NuttX controls + * the LEDs: + * + * SYMBOL Meaning LED state + * RED GREEN BLUE + * ---------------- ----------------------------- ------------------- + */ + +#define LED_STARTED 1 /* NuttX has been started OFF OFF OFF */ +#define LED_HEAPALLOCATE 2 /* Heap has been allocated OFF OFF ON */ +#define LED_IRQSENABLED 0 /* Interrupts enabled OFF OFF ON */ +#define LED_STACKCREATED 3 /* Idle stack created OFF ON OFF */ +#define LED_INIRQ 0 /* In an interrupt (No change) */ +#define LED_SIGNAL 0 /* In a signal handler (No change) */ +#define LED_ASSERTION 0 /* An assertion failed (No change) */ +#define LED_PANIC 4 /* The system has crashed FLASH OFF OFF */ +#undef LED_IDLE /* S32K344 is in sleep mode (Not used) */ + +/* Button definitions *******************************************************/ + +/* The MR-CANHUBK3 supports two buttons: + * + * SW1 PTD15 (EIRQ31) + * SW2 PTA25 (EIRQ5 / WKPU34) + */ + +#define BUTTON_SW1 0 +#define BUTTON_SW2 1 +#define NUM_BUTTONS 2 + +#define BUTTON_SW1_BIT (1 << BUTTON_SW1) +#define BUTTON_SW2_BIT (1 << BUTTON_SW2) + +/* UART selections **********************************************************/ + +/* By default, the serial console will be provided on the DCD-LZ UART + * (available on the 7-pin DCD-LZ debug connector P6): + * + * DCD-LZ UART RX PTA8 (LPUART2_RX) + * DCD-LZ UART TX PTA9 (LPUART2_TX) + */ + +#define PIN_LPUART2_RX PIN_LPUART2_RX_1 /* PTA8 */ +#define PIN_LPUART2_TX PIN_LPUART2_TX_1 /* PTA9 */ + +/* LPUART0 P2 UART (with flow control) connector */ + +#define PIN_LPUART0_CTS PIN_LPUART0_CTS_1 /* PTA0 */ +#define PIN_LPUART0_RTS PIN_LPUART0_RTS_1 /* PTA1 */ +#define PIN_LPUART0_RX PIN_LPUART0_RX_1 /* PTA2 */ +#define PIN_LPUART0_TX PIN_LPUART0_TX_1 /* PTA3 */ + +/* LPUART1 P5 UART (with flow control) connector */ + +#define PIN_LPUART1_CTS PIN_LPUART1_CTS_2 /* PTE2 */ +#define PIN_LPUART1_RTS PIN_LPUART1_RTS_2 /* PTE6 */ +#define PIN_LPUART1_RX PIN_LPUART1_RX_3 /* PTC6 */ +#define PIN_LPUART1_TX PIN_LPUART1_TX_3 /* PTC7 */ + +/* LPUART9 P24 UART connector */ + +#define PIN_LPUART9_RX PIN_LPUART9_RX_1 /* PTB2 */ +#define PIN_LPUART9_TX PIN_LPUART9_TX_1 /* PTB3 */ + +/* LPUART10 P24 UART connector */ + +#define PIN_LPUART10_RX PIN_LPUART10_RX_1 /* PTC12 */ +#define PIN_LPUART10_TX PIN_LPUART10_TX_1 /* PTC13 */ + +/* LPUART13 P25 UART connector */ + +#define PIN_LPUART13_RX PIN_LPUART13_RX_1 /* PTB19 */ +#define PIN_LPUART13_TX PIN_LPUART13_TX_1 /* PTB18 */ + +/* LPUART14 P25 UART connector */ + +#define PIN_LPUART14_RX PIN_LPUART14_RX_1 /* PTB21 */ +#define PIN_LPUART14_TX PIN_LPUART14_TX_1 /* PTB20 */ + +/* SPI selections ***********************************************************/ + +/* LPSPI1 P1A external SPI connector */ + +#define PIN_LPSPI1_SCK PIN_LPSPI1_SCK_3 /* PTA28 */ +#define PIN_LPSPI1_MISO PIN_LPSPI1_SOUT_2 /* PTA30 */ +#define PIN_LPSPI1_MOSI PIN_LPSPI1_SIN_3 /* PTA29 */ +#define PIN_LPSPI1_PCS0 PIN_LPSPI1_PCS0_2 /* PTA21 */ +#define PIN_LPSPI1_PCS1 PIN_LPSPI1_PCS1_6 /* PTE4 */ + +#define PIN_LPSPI1_PCS (PIN_PTA21 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) /* PTA21 */ + +/* LPSPI2 P1B external SPI connector */ + +#define PIN_LPSPI2_SCK PIN_LPSPI2_SCK_1 /* PTB29 */ +#define PIN_LPSPI2_MISO PIN_LPSPI2_SOUT_3 /* PTB27 */ +#define PIN_LPSPI2_MOSI PIN_LPSPI2_SIN_2 /* PTB28 */ +#define PIN_LPSPI2_PCS0 PIN_LPSPI2_PCS0_2 /* PTB25 */ +#define PIN_LPSPI2_PCS1 PIN_LPSPI2_PCS1_3 /* PTC19 */ + +#define PIN_LPSPI2_PCS (PIN_PTB25 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) /* PTB25 */ + +/* LPSPI3 FS26 Safety SBC */ + +#define PIN_LPSPI3_SCK PIN_LPSPI3_SCK_2 /* PTD1 */ +#define PIN_LPSPI3_MISO PIN_LPSPI3_SOUT_2 /* PTD0 */ +#define PIN_LPSPI3_MOSI PIN_LPSPI3_SIN_3 /* PTE10 */ +#define PIN_LPSPI3_PCS PIN_PTD17 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE + +/* LPSPI4 P8B I/O connector / P26 external IMU connector */ + +#define PIN_LPSPI4_SCK PIN_LPSPI4_SCK_1 /* PTB10 */ +#define PIN_LPSPI4_MISO PIN_LPSPI4_SOUT_1 /* PTB9 */ +#define PIN_LPSPI4_MOSI PIN_LPSPI4_SIN_1 /* PTB11 */ +#define PIN_LPSPI4_PCS0 PIN_LPSPI4_PCS0_1 /* PTB8 */ +#define PIN_LPSPI4_PCS3 PIN_LPSPI4_PCS3_1 /* PTA16 */ + +#define PIN_LPSPI4_PCS (PIN_PTA16 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) /* PTA16 */ + +/* LPSPI5 P26 external IMU connector */ + +#define PIN_LPSPI5_SCK PIN_LPSPI5_SCK_3 /* PTD26 */ +#define PIN_LPSPI5_MISO PIN_LPSPI5_SOUT_2 /* PTD27 */ +#define PIN_LPSPI5_MOSI PIN_LPSPI5_SIN_3 /* PTD28 */ +#define PIN_LPSPI5_PCS1 PIN_LPSPI5_PCS1_1 /* PTA14 */ + +#define PIN_LPSPI5_PCS (PIN_PTA14 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) /* PTA14 */ + +/* PIN_LPSPI5_PCS2 PTD29 */ + +/* I2C selections ***********************************************************/ + +/* LPI2C0 P4 LCD header / P26 external IMU connector */ + +#define PIN_LPI2C0_SCL PIN_LPI2C0_SCL_2 /* PTD14 */ +#define PIN_LPI2C0_SDA PIN_LPI2C0_SDA_2 /* PTD13 */ + +/* LPI2C1 P3 external I2C connector / SE050 EdgeLock Secure Element */ + +#define PIN_LPI2C1_SCL PIN_LPI2C1_SCL_4 /* PTD9 */ +#define PIN_LPI2C1_SDA PIN_LPI2C1_SDA_4 /* PTD8 */ + +/* CAN selections ***********************************************************/ + +/* CAN0 TJA1443 CAN transceiver */ + +#define PIN_CAN0_RX PIN_CAN0_RX_1 /* PTA6 */ +#define PIN_CAN0_TX PIN_CAN0_TX_1 /* PTA7 */ +#define PIN_CAN0_STB (PIN_PTC21 | GPIO_OUTPUT) +#define CAN0_STB_OUT 1 +#define PIN_CAN0_ENABLE (PIN_PTC24 | GPIO_OUTPUT) +#define CAN0_ENABLE_OUT 1 +#define PIN_CAN0_LED (PIN_PTC18 | GPIO_OUTPUT) +#define CAN0_LED_OUT 0 +#define PIN_CAN0_ERRN (PIN_PTC20 | GPIO_INPUT) + +/* CAN1 TJA1443 CAN transceiver */ + +#define PIN_CAN1_RX PIN_CAN1_RX_4 /* PTC9 */ +#define PIN_CAN1_TX PIN_CAN1_TX_4 /* PTC8 */ +#define PIN_CAN1_STB (PIN_PTD2 | GPIO_OUTPUT) +#define CAN1_STB_OUT 1 +#define PIN_CAN1_ENABLE (PIN_PTD23 | GPIO_OUTPUT) +#define CAN1_ENABLE_OUT 1 +#define PIN_CAN1_LED (PIN_PTE5 | GPIO_OUTPUT) +#define CAN1_LED_OUT 0 +#define PIN_CAN1_ERRN (PIN_PTD3 | GPIO_INPUT) + +/* CAN2 TJA1463 CAN transceiver */ + +#define PIN_CAN2_RX PIN_CAN2_RX_5 /* PTE25 */ +#define PIN_CAN2_TX PIN_CAN2_TX_5 /* PTE24 */ +#define PIN_CAN2_STB (PIN_PTD22 | GPIO_OUTPUT) +#define CAN2_STB_OUT 1 +#define PIN_CAN2_ENABLE (PIN_PTD4 | GPIO_OUTPUT) +#define CAN2_ENABLE_OUT 1 +#define PIN_CAN2_LED (PIN_PTD20 | GPIO_OUTPUT) +#define CAN2_LED_OUT 0 +#define PIN_CAN2_ERRN (PIN_PTD21 | GPIO_INPUT) + +/* CAN3 TJA1463 CAN transceiver */ + +#define PIN_CAN3_RX PIN_CAN3_RX_2 /* PTC29 */ +#define PIN_CAN3_TX PIN_CAN3_TX_2 /* PTC28 */ +#define PIN_CAN3_STB (PIN_PTB1 | GPIO_OUTPUT) +#define CAN3_STB_OUT 1 +#define PIN_CAN3_ENABLE (PIN_PTB0 | GPIO_OUTPUT) +#define CAN3_ENABLE_OUT 1 +#define PIN_CAN3_LED (PIN_PTB24 | GPIO_OUTPUT) +#define CAN3_LED_OUT 0 +#define PIN_CAN3_ERRN (PIN_PTC27 | GPIO_INPUT) + +/* CAN4 TJA1153 CAN transceiver */ + +#define PIN_CAN4_RX PIN_CAN4_RX_2 /* PTC31 */ +#define PIN_CAN4_TX PIN_CAN4_TX_2 /* PTC30 */ +#define PIN_CAN4_STB (PIN_PTC25 | GPIO_OUTPUT) +#define CAN4_STB_OUT 0 +#define PIN_CAN4_ENABLE (PIN_PTC26 | GPIO_OUTPUT) +#define CAN4_ENABLE_OUT 1 +#define PIN_CAN4_LED (PIN_PTB26 | GPIO_OUTPUT) +#define CAN4_LED_OUT 0 +#define PIN_CAN4_ERRN (PIN_PTC23 | GPIO_INPUT) + +/* CAN5 TJA1153 CAN transceiver */ + +#define PIN_CAN5_RX PIN_CAN5_RX_1 /* PTC11 */ +#define PIN_CAN5_TX PIN_CAN5_TX_1 /* PTC10 */ +#define PIN_CAN5_STB (PIN_PTE17 | GPIO_OUTPUT) +#define CAN5_STB_OUT 0 +#define PIN_CAN5_ENABLE (PIN_PTD30 | GPIO_OUTPUT) +#define CAN5_ENABLE_OUT 1 +#define PIN_CAN5_LED (PIN_PTD31 | GPIO_OUTPUT) +#define CAN5_LED_OUT 0 +#define PIN_CAN5_ERRN (PIN_PTD24 | GPIO_INPUT) + +/* ENET selections **********************************************************/ + +#define PIN_EMAC_MII_RMII_TXD0 PIN_EMAC_MII_RMII_TXD0_1 /* PTB5 */ +#define PIN_EMAC_MII_RMII_TXD1 PIN_EMAC_MII_RMII_TXD1_1 /* PTB4 */ +#define PIN_EMAC_MII_RMII_TX_EN PIN_EMAC_MII_RMII_TX_EN_3 /* PTE9 */ +#define PIN_EMAC_MII_RMII_RXD0 PIN_EMAC_MII_RMII_RXD0_1 /* PTC0 */ +#define PIN_EMAC_MII_RMII_RXD1 PIN_EMAC_MII_RMII_RXD1_2 /* PTC1 */ +#define PIN_EMAC_MII_RMII_RX_DV PIN_EMAC_MII_RMII_RX_DV_1 /* PTC15 */ +#define PIN_EMAC_MII_RMII_RX_ER PIN_EMAC_MII_RMII_RX_ER_1 /* PTC14 */ +#define PIN_EMAC_MII_RMII_MDC PIN_EMAC_MII_RMII_MDC_3 /* PTC8 */ +#define PIN_EMAC_MII_RMII_MDIO PIN_EMAC_MII_RMII_MDIO_2 /* PTD16 */ +#define PIN_EMAC_MII_RMII_TX_CLK PIN_EMAC_MII_RMII_TX_CLK_2 /* PTD6 */ + +#endif /* __BOARDS_ARM_S32K3XX_MR_CANHUBK3_INCLUDE_BOARD_H */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/scripts/Make.defs b/boards/arm/s32k3xx/mr-canhubk3/scripts/Make.defs new file mode 100644 index 00000000000..4b0b2daaf9a --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/scripts/Make.defs @@ -0,0 +1,49 @@ +############################################################################ +# boards/arm/s32k3xx/mr-canhubk3/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. +# +############################################################################ + +# Copyright 2022 NXP + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs + +ifeq ($(CONFIG_BOOT_RUNFROMFLASH),y) + LDSCRIPT = flash.ld +else ifeq ($(CONFIG_BOOT_RUNFROMISRAM),y) + LDSCRIPT = sram.ld +endif + +$(warning, LDSCRIPT is $(LDSCRIPT)) +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) +$(warning, LDSCRIPT is $(LDSCRIPT)) +$(warning, ARCHSCRIPT is $(ARCHSCRIPT)) + +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 + +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__ + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 diff --git a/boards/arm/s32k3xx/mr-canhubk3/scripts/flash.ld b/boards/arm/s32k3xx/mr-canhubk3/scripts/flash.ld new file mode 100644 index 00000000000..3f8c78238c5 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/scripts/flash.ld @@ -0,0 +1,159 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/scripts/flash.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/* TO DO: ADD DESCRIPTION + * + * 0x00400000 - 0x007fffff 4194304 Program Flash (last 64K sBAF) + * 0x10000000 - 0x1003ffff 262144 Data Flash (last 32K HSE_NVM) + * 0x20400000 - 0x20408000 32768 Standby RAM_0 (32K) + * 0x20400000 - 0x20427fff 163840 SRAM_0 + * 0x20428000 - 0x2044ffff 163840 SRAM_1 + * + * Last 48 KB of SRAM_1 reserved by HSE Firmware + * Last 128 KB of CODE_FLASH_3 reserved by HSE Firmware + * Last 128 KB of DATA_FLASH reserved by HSE Firmware (not supported in this linker file) + * + * Note Standby RAM and SRAM overlaps in NuttX since we dont use the Standby functionality + * + */ + +MEMORY +{ + BOOT_HEADER (R) : ORIGIN = 0x00400000, LENGTH = 0x00001000 /* 0x00400000 - 0x00400fff */ + flash (rx) : ORIGIN = 0x00401000, LENGTH = 0x003cffff /* 0x00401000 - (0x007fffff - 0x20000 (128 KB) = 0x007dffff) */ + sram0_stdby (rwx) : ORIGIN = 0x20400000, LENGTH = 32K + sram (rwx) : ORIGIN = 0x20400000, LENGTH = 272K + itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K + dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +EXTERN(boot_header) +ENTRY(_stext) + +SECTIONS +{ + + .boot_header : + { + KEEP(*(.boot_header)) + } > BOOT_HEADER + + .text : + { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text.__start) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + .init_section : + { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : + { + *(.ARM.extab*) + } >flash + + .ARM.exidx : + { + __exidx_start = ABSOLUTE(.); + *(.ARM.exidx*) + __exidx_end = ABSOLUTE(.); + } >flash + + /* Due ECC initialization sequence __data_start__ and __data_end__ should be aligned on 8 bytes */ + .data : + { + . = ALIGN(8); + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(8); + _edata = ABSOLUTE(.); + } > sram AT > flash + + _eronly = LOADADDR(.data); + + .ramfunc ALIGN(8): + { + _sramfuncs = ABSOLUTE(.); + *(.ramfunc .ramfunc.*) + _eramfuncs = ABSOLUTE(.); + } > sram AT > flash + + _framfuncs = LOADADDR(.ramfunc); + + /* Due ECC initialization sequence __bss_start__ and __bss_end__ should be aligned on 8 bytes */ + .bss : + { + . = ALIGN(8); + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(8); + _ebss = ABSOLUTE(.); + } > sram + + CM7_0_START_ADDRESS = ORIGIN(flash); + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + SRAM_BASE_ADDR = ORIGIN(sram); + SRAM_END_ADDR = ORIGIN(sram) + LENGTH(sram); + SRAM_STDBY_BASE_ADDR = ORIGIN(sram0_stdby); + SRAM_STDBY_END_ADDR = ORIGIN(sram0_stdby) + LENGTH(sram0_stdby); + ITCM_BASE_ADDR = ORIGIN(itcm); + ITCM_END_ADDR = ORIGIN(itcm) + LENGTH(itcm); + DTCM_BASE_ADDR = ORIGIN(dtcm); + DTCM_END_ADDR = ORIGIN(dtcm) + LENGTH(dtcm); +} diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/Makefile b/boards/arm/s32k3xx/mr-canhubk3/src/Makefile new file mode 100644 index 00000000000..78a95dd706c --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/Makefile @@ -0,0 +1,62 @@ +############################################################################ +# boards/arm/s32k3xx/mr-canhubk3/src/Makefile +# +# 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. +# +############################################################################ + +# Copyright 2022 NXP + +include $(TOPDIR)/Make.defs + +CSRCS = s32k3xx_boot.c s32k3xx_bringup.c s32k3xx_clockconfig.c +CSRCS += s32k3xx_periphclocks.c + +ifeq ($(CONFIG_ARCH_BUTTONS),y) +CSRCS += s32k3xx_buttons.c +endif + +ifeq ($(CONFIG_ARCH_LEDS),y) +CSRCS += s32k3xx_autoleds.c +else +CSRCS += s32k3xx_userleds.c +endif + +ifeq ($(CONFIG_BOARDCTL),y) +CSRCS += s32k3xx_appinit.c +endif + +ifeq ($(CONFIG_FAT_DMAMEMORY),y) +CSRCS += s32k3xx_dma_alloc.c +endif + +ifeq ($(CONFIG_S32K3XX_FLEXCAN),y) +CSRCS += s32k3xx_tja1153.c +endif + +ifeq ($(CONFIG_S32K3XX_LPI2C),y) +CSRCS += s32k3xx_i2c.c +endif + +ifeq ($(CONFIG_S32K3XX_LPSPI),y) +CSRCS += s32k3xx_spi.c +endif + +ifeq ($(CONFIG_S32K3XX_SELFTEST),y) +CSRCS += s32k3xx_selftest.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/mr-canhubk3.h b/boards/arm/s32k3xx/mr-canhubk3/src/mr-canhubk3.h new file mode 100644 index 00000000000..bc686ebe39e --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/mr-canhubk3.h @@ -0,0 +1,147 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/mr-canhubk3.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +#ifndef __BOARDS_ARM_S32K3XX_MR_CANHUBK3_SRC_MR_CANHUBK3_H +#define __BOARDS_ARM_S32K3XX_MR_CANHUBK3_SRC_MR_CANHUBK3_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include "hardware/s32k344_pinmux.h" +#include "s32k3xx_periphclocks.h" +#include "s32k3xx_pin.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* MR-CANHUBK3 GPIOs ********************************************************/ + +/* LEDs. The MR-CANHUBK3 has one RGB LED: + * + * RedLED PTE14 (FXIO D7 / EMIOS0 CH19) + * GreenLED PTA27 (FXIO D5 / EMIOS1 CH10 / EMIOS2 CH10) + * BlueLED PTE12 (FXIO D8 / EMIOS1 CH5) + * + * An output of '0' illuminates the LED. + */ + +#define GPIO_LED_R (PIN_PTE14 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) +#define GPIO_LED_G (PIN_PTA27 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) +#define GPIO_LED_B (PIN_PTE12 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) + +/* Buttons. The MR-CANHUBK3 supports two buttons: + * + * SW1 PTD15 (EIRQ31) + * SW2 PTA25 (EIRQ5 / WKPU34) + */ + +#define GPIO_SW1 (PIN_EIRQ31_2 | PIN_INT_BOTH) /* PTD15 */ +#define GPIO_SW2 (PIN_EIRQ5_2 | PIN_INT_BOTH) /* PTA25 */ + +/* Count of peripheral clock user configurations */ + +#define NUM_OF_PERIPHERAL_CLOCKS_0 26 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* User peripheral configuration structure 0 */ + +extern const struct peripheral_clock_config_s g_peripheral_clockconfig0[]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k3xx_bringup + * + * Description: + * Perform architecture-specific initialization + * + * CONFIG_BOARD_LATE_INITIALIZE=y : + * Called from board_late_initialize(). + * + * CONFIG_BOARD_LATE_INITIALIZE=y && CONFIG_BOARDCTL=y : + * Called from the NSH library + * + ****************************************************************************/ + +int s32k3xx_bringup(void); + +/**************************************************************************** + * Name: s32k3xx_i2cdev_initialize + * + * Description: + * Initialize I2C driver and register /dev/i2cN devices. + * + ****************************************************************************/ + +int s32k3xx_i2cdev_initialize(void); + +/**************************************************************************** + * Name: s32k3xx_spidev_initialize + * + * Description: + * Configure chip select pins, initialize the SPI driver and register + * /dev/spiN devices. + * + ****************************************************************************/ + +int s32k3xx_spidev_initialize(void); + +/**************************************************************************** + * Name: s32k3xx_tja1153_initialize + * + * Description: + * Initialize a TJA1153 CAN PHY connected to a FlexCAN peripheral (0-5) + * + ****************************************************************************/ + +int s32k3xx_tja1153_initialize(int bus); + +/**************************************************************************** + * Name: s32k3xx_selftest + * + * Description: + * Runs basic routines to verify that all board components are up and + * running. Results are send to the syslog, it is recommended to + * enable all output levels (error, warning and info). + * + ****************************************************************************/ + +void s32k3xx_selftest(void); + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_S32K3XX_MR_CANHUBK3_SRC_MR_CANHUBK3_H */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_appinit.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_appinit.c new file mode 100644 index 00000000000..4ac3536c4f9 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_appinit.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_appinit.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include "mr-canhubk3.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef OK +# define OK 0 +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 initialization logic and the matching application + * logic. The value could be such things as a mode enumeration + * value, a set of DIP 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. + * + ****************************************************************************/ + +int board_app_initialize(uintptr_t arg) +{ +#ifdef CONFIG_BOARD_LATE_INITIALIZE + /* Board initialization already performed by board_late_initialize() */ + + return OK; +#else + /* Perform board-specific initialization */ + + return s32k3xx_bringup(); +#endif +} diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_autoleds.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_autoleds.c new file mode 100644 index 00000000000..101c85b5f1c --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_autoleds.c @@ -0,0 +1,150 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_autoleds.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/* The MR-CANHUBK3 has one RGB LED: + * + * RedLED PTE14 (FXIO D7 / EMIOS0 CH19) + * GreenLED PTA27 (FXIO D5 / EMIOS1 CH10 / EMIOS2 CH10) + * BlueLED PTE12 (FXIO D8 / EMIOS1 CH5) + * + * An output of '0' illuminates the LED. + * + * If CONFIG_ARCH_LEDs is defined, then NuttX will control the LED on board + * the MR-CANHUBK3. The following definitions describe how NuttX controls + * the LEDs: + * + * SYMBOL Meaning LED state + * RED GREEN BLUE + * ---------------- ------------------------ -------------------- + * LED_STARTED NuttX has been started OFF OFF OFF + * LED_HEAPALLOCATE Heap has been allocated OFF OFF ON + * LED_IRQSENABLED Interrupts enabled OFF OFF ON + * LED_STACKCREATED Idle stack created OFF ON OFF + * LED_INIRQ In an interrupt (No change) + * LED_SIGNAL In a signal handler (No change) + * LED_ASSERTION An assertion failed (No change) + * LED_PANIC The system has crashed FLASH OFF OFF + * LED_IDLE S32K344 is in sleep mode (Optional, not used) + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "s32k3xx_pin.h" + +#include "mr-canhubk3.h" + +#ifdef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Summary of all possible settings */ + +#define LED_NOCHANGE 0 /* LED_IRQSENABLED, LED_INIRQ, LED_SIGNAL, LED_ASSERTION */ +#define LED_OFF_OFF_OFF 1 /* LED_STARTED */ +#define LED_OFF_OFF_ON 2 /* LED_HEAPALLOCATE */ +#define LED_OFF_ON_OFF 3 /* LED_STACKCREATED */ +#define LED_ON_OFF_OFF 4 /* LED_PANIC */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + /* Configure LED GPIOs for output */ + + s32k3xx_pinconfig(GPIO_LED_R); + s32k3xx_pinconfig(GPIO_LED_G); + s32k3xx_pinconfig(GPIO_LED_B); +} + +/**************************************************************************** + * Name: board_autoled_on + ****************************************************************************/ + +void board_autoled_on(int led) +{ + if (led != LED_NOCHANGE) + { + bool redon = false; + bool greenon = false; + bool blueon = false; + + switch (led) + { + default: + case LED_OFF_OFF_OFF: + break; + + case LED_OFF_OFF_ON: + blueon = true; + break; + + case LED_OFF_ON_OFF: + greenon = true; + break; + + case LED_ON_OFF_OFF: + redon = true; + break; + } + + /* Invert output, an output of '0' illuminates the LED */ + + s32k3xx_gpiowrite(GPIO_LED_R, !redon); + s32k3xx_gpiowrite(GPIO_LED_G, !greenon); + s32k3xx_gpiowrite(GPIO_LED_B, !blueon); + } +} + +/**************************************************************************** + * Name: board_autoled_off + ****************************************************************************/ + +void board_autoled_off(int led) +{ + if (led == LED_ON_OFF_OFF) + { + /* Invert outputs, an output of '0' illuminates the LED */ + + s32k3xx_gpiowrite(GPIO_LED_R, !true); + s32k3xx_gpiowrite(GPIO_LED_G, !false); + s32k3xx_gpiowrite(GPIO_LED_B, !false); + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_boot.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_boot.c new file mode 100644 index 00000000000..b4e71a85527 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_boot.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_boot.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include "mr-canhubk3.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k3xx_board_initialize + * + * Description: + * All S32K3XX 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. + * + ****************************************************************************/ + +void s32k3xx_board_initialize(void) +{ +#ifdef CONFIG_SEGGER_SYSVIEW + up_perf_init((void *)MR_CANHUBK3_SYSCLK_FREQUENCY); +#endif + +#ifdef CONFIG_ARCH_LEDS + /* Configure on-board LEDs if LED support has been selected */ + + board_autoled_initialize(); +#endif +} + +/**************************************************************************** + * Name: board_late_initialize + * + * Description: + * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional + * initialization call will be performed in the boot-up sequence to a + * function called board_late_initialize(). board_late_initialize() will + * be called immediately after up_initialize() is called and just before + * the initial application is started. This additional initialization + * phase may be used, for example, to initialize board-specific device + * drivers. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ + /* Perform board-specific initialization */ + + s32k3xx_bringup(); +} +#endif diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_bringup.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_bringup.c new file mode 100644 index 00000000000..b56ea9e84ea --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_bringup.c @@ -0,0 +1,320 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_bringup.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifdef CONFIG_INPUT_BUTTONS +# include +#endif + +#ifdef CONFIG_USERLED +# include +#endif + +#ifdef CONFIG_S32K3XX_FLEXCAN +# include "s32k3xx_flexcan.h" +#endif + +#ifdef CONFIG_S32K3XX_ENET +# include "s32k3xx_emac.h" +#endif + +#ifdef CONFIG_S32K3XX_QSPI +# include +# include +# include +# include "s32k3xx_qspi.h" +#endif + +#include +#include "mr-canhubk3.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef HAVE_MX25L +struct qspi_dev_s *g_qspi; +struct mtd_dev_s *g_mtd_fs; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k3xx_bringup + * + * Description: + * Perform architecture-specific initialization + * + * CONFIG_BOARD_LATE_INITIALIZE=y : + * Called from board_late_initialize(). + * + * CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_BOARDCTL=y : + * Called from the NSH library + * + ****************************************************************************/ + +int s32k3xx_bringup(void) +{ + int ret = OK; +#if defined(CONFIG_BCH) || defined(HAVE_MX25L_LITTLEFS) + char blockdev[32]; +# if !defined(HAVE_MX25L_LITTLEFS) && !defined(HAVE_MX25L_NXFFS) + char chardev[32]; +# endif /* !HAVE_MX25L_LITTLEFS && !HAVE_MX25L_NXFFS */ +#endif /* CONFIG_BCH || HAVE_MX25L_LITTLEFS */ + +#ifdef CONFIG_S32K3XX_LPSPI + /* Initialize SPI driver */ + + ret = s32k3xx_spidev_initialize(); + if (ret < 0) + { + _err("s32k3xx_spidev_initialize() failed: %d\n", ret); + } + else + { + _info("s32k3xx_spidev_initialize() succesful\n"); + } +#endif + +#ifdef CONFIG_INPUT_BUTTONS + /* Register the BUTTON driver */ + + ret = btn_lower_initialize("/dev/buttons"); + if (ret < 0) + { + _err("btn_lower_initialize() failed: %d\n", ret); + } + else + { + _info("btn_lower_initialize() succesful\n"); + } +#endif + +#ifdef CONFIG_USERLED + /* Register the LED driver */ + + ret = userled_lower_initialize("/dev/userleds"); + if (ret < 0) + { + _err("userled_lower_initialize() failed: %d\n", ret); + } + else + { + _info("userled_lower_initialize() succesful\n"); + } +#endif + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + _err("Mounting procfs at /proc failed: %d\n", ret); + } + else + { + _info("Mounting procfs at /proc succesful\n"); + } +#endif + +#ifdef CONFIG_S32K3XX_LPI2C + /* Initialize I2C driver */ + + ret = s32k3xx_i2cdev_initialize(); + if (ret < 0) + { + _err("s32k3xx_i2cdev_initialize() failed: %d\n", ret); + } + else + { + _info("s32k3xx_i2cdev_initialize() succesful\n"); + } +#endif + +#ifdef HAVE_MX25L + /* Create an instance of the S32K3XX QSPI device driver */ + + g_qspi = s32k3xx_qspi_initialize(0); + if (!g_qspi) + { + _err("s32k3xx_qspi_initialize() failed\n"); + } + else + { + _info("s32k3xx_qspi_initialize() succesful\n"); + + /* Use the QSPI device instance to initialize the MX25 device */ + + g_mtd_fs = mx25rxx_initialize(g_qspi, true); + if (!g_mtd_fs) + { + _err("mx25rxx_initialize() failed\n"); + } + else + { + _info("mx25rxx_initialize() succesful\n"); + +# ifdef HAVE_MX25L_LITTLEFS + /* Configure the device with no partition support */ + + snprintf(blockdev, sizeof(blockdev), "/dev/mtdqspi%d", + MX25L_MTD_MINOR); + + ret = register_mtddriver(blockdev, g_mtd_fs, 0755, NULL); + if (ret != OK) + { + _err("register_mtddriver() failed: %d\n", ret); + } + else + { + _info("register_mtddriver() succesful\n"); + + ret = nx_mount(blockdev, "/mnt/qspi", "littlefs", 0, NULL); + if (ret < 0) + { + ret = nx_mount(blockdev, "/mnt/qspi", "littlefs", 0, + "forceformat"); + if (ret < 0) + { + _err("nx_mount() failed: %d\n", ret); + } + else + { + _info("nx_mount() succesful\n"); + } + } + } + +# elif defined(HAVE_MX25L_NXFFS) + /* Initialize to provide NXFFS on the N25QXXX MTD interface */ + + ret = nxffs_initialize(g_mtd_fs); + if (ret < 0) + { + _err("nxffs_initialize() failed: %d\n", ret); + } + else + { + _info("nxffs_initialize() succesful\n"); + + /* Mount the file system at /mnt/qspi */ + + ret = nx_mount(NULL, "/mnt/qspi", "nxffs", 0, NULL); + if (ret < 0) + { + _err("nx_mount() failed: %d\n", ret); + } + else + { + _info("nx_mount() succesful\n"); + } + } + +# else /* if defined(HAVE_MX25L_CHARDEV) */ + /* Use the FTL layer to wrap the MTD driver as a block driver */ + + ret = ftl_initialize(MX25L_MTD_MINOR, g_mtd_fs); + if (ret < 0) + { + _err("ftl_initialize() failed: %d\n", ret); + } +# ifdef CONFIG_BCH + else + { + _info("ftl_initialize() succesful\n"); + + /* Use the minor number to create device paths */ + + snprintf(blockdev, sizeof(blockdev), "/dev/mtdblock%d", + MX25L_MTD_MINOR); + snprintf(chardev, sizeof(chardev), "/dev/mtd%d", + MX25L_MTD_MINOR); + + /* Now create a character device on the block device */ + + ret = bchdev_register(blockdev, chardev, false); + if (ret < 0) + { + _err("bchdev_register %s failed: %d\n", chardev, ret); + } + else + { + _info("bchdev_register %s succesful\n", chardev); + } + } +# endif /* CONFIG_BCH */ +# endif + } + } +#endif + +#ifdef CONFIG_S32K3XX_SELFTEST + s32k3xx_selftest(); +#endif /* CONFIG_S32K3XX_SELFTEST */ + +#ifdef CONFIG_NETDEV_LATEINIT +# ifdef CONFIG_S32K3XX_ENET + s32k3xx_netinitialize(0); +# endif /* CONFIG_S32K3XX_ENET */ +# ifdef CONFIG_S32K3XX_FLEXCAN0 + s32k3xx_caninitialize(0); +# endif /* CONFIG_S32K3XX_FLEXCAN0 */ +# ifdef CONFIG_S32K3XX_FLEXCAN1 + s32k3xx_caninitialize(1); +# endif /* CONFIG_S32K3XX_FLEXCAN1 */ +# ifdef CONFIG_S32K3XX_FLEXCAN2 + s32k3xx_caninitialize(2); +# endif /* CONFIG_S32K3XX_FLEXCAN2 */ +# ifdef CONFIG_S32K3XX_FLEXCAN3 + s32k3xx_caninitialize(3); +# endif /* CONFIG_S32K3XX_FLEXCAN3 */ +# ifdef CONFIG_S32K3XX_FLEXCAN4 + s32k3xx_caninitialize(4); +# ifdef CONFIG_S32K3XX_TJA1153 + s32k3xx_tja1153_initialize(4); +# endif /* CONFIG_S32K3XX_TJA1153 */ +# endif /* CONFIG_S32K3XX_FLEXCAN4 */ +# ifdef CONFIG_S32K3XX_FLEXCAN5 + s32k3xx_caninitialize(5); +# ifdef CONFIG_S32K3XX_TJA1153 + s32k3xx_tja1153_initialize(5); +# endif /* CONFIG_S32K3XX_TJA1153 */ +# endif /* CONFIG_S32K3XX_FLEXCAN5 */ +#endif /* CONFIG_NETDEV_LATEINIT */ + + _info("MR-CANHUBK3 board bringup complete\n"); + + return ret; +} diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_buttons.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_buttons.c new file mode 100644 index 00000000000..78b06601506 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_buttons.c @@ -0,0 +1,154 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_buttons.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/* The MR-CANHUBK3 supports two buttons: + * + * SW1 PTD15 (EIRQ31) + * SW2 PTA25 (EIRQ5 / WKPU34) + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "s32k3xx_pin.h" + +#include + +#include "mr-canhubk3.h" + +#ifdef CONFIG_ARCH_BUTTONS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_button_initialize + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + ****************************************************************************/ + +uint32_t board_button_initialize(void) +{ + /* Configure the GPIO pins as interrupting inputs */ + + s32k3xx_pinconfig(GPIO_SW1); + s32k3xx_pinconfig(GPIO_SW2); + + return NUM_BUTTONS; +} + +/**************************************************************************** + * Name: board_buttons + ****************************************************************************/ + +uint32_t board_buttons(void) +{ + uint32_t ret = 0; + + if (s32k3xx_gpioread(GPIO_SW1)) + { + ret |= BUTTON_SW1_BIT; + } + + if (s32k3xx_gpioread(GPIO_SW2)) + { + ret |= BUTTON_SW2_BIT; + } + + return ret; +} + +#ifdef CONFIG_ARCH_IRQBUTTONS +/**************************************************************************** + * Button support. + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + * After board_button_initialize() has been called, board_buttons() may be + * called to collect the state of all buttons. board_buttons() returns a + * 32-bit bit set with each bit associated with a button. See the + * BUTTON_*_BIT definitions in board.h for the meaning of each bit. + * + * board_button_irq() may be called to register an interrupt handler that + * will be called when a button is pressed or released. The ID value is a + * button enumeration value that uniquely identifies a button resource. + * See the BUTTON_* definitions in board.h for the meaning of enumeration + * value. + * + ****************************************************************************/ + +int board_button_irq(int id, xcpt_t irqhandler, void *arg) +{ + uint32_t pinset; + int ret; + + /* Map the button id to the GPIO bit set */ + + if (id == BUTTON_SW1) + { + pinset = GPIO_SW1; + } + else if (id == BUTTON_SW2) + { + pinset = GPIO_SW2; + } + else + { + return -EINVAL; + } + + /* The button has already been configured as an interrupting input (by + * board_button_initialize() above). + * + * Attach the new button handler. + */ + + ret = s32k3xx_pinirqattach(pinset, irqhandler, NULL); + if (ret >= 0) + { + /* Then make sure that interrupts are enabled on the pin */ + + s32k3xx_pinirqenable(pinset); + } + + return ret; +} +#endif /* CONFIG_ARCH_IRQBUTTONS */ +#endif /* CONFIG_ARCH_BUTTONS */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_clockconfig.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_clockconfig.c new file mode 100644 index 00000000000..64649d30c73 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_clockconfig.c @@ -0,0 +1,162 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_clockconfig.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "s32k3xx_clockconfig.h" +#include "s32k3xx_start.h" + +#include "mr-canhubk3.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Each S32K3XX board must provide the following initialized structure. + * This is needed to establish the initial board clocking. + */ + +const struct clock_configuration_s g_initial_clkconfig = +{ + .cgm = + { + .sirc = + { + .range = CGM_FIRC_RANGE_32K, /* Slow IRC is trimmed to 32 kHz */ + }, + .firc = + { + .range = CGM_FIRC_RANGE_HIGH, /* RANGE */ + .div = CGM_CLOCK_DIV_BY_1, /* FIRCDIV1 */ + }, + .scs = + { + .scs_source = CGM_SCS_SOURCE_PLL_PHI0, + .core_clk = + { + .div = CGM_MUX_DIV_BY_1, + .trigger = false, + }, + .aips_plat_clk = + { + .div = CGM_MUX_DIV_BY_2, + .trigger = false, + }, + .aips_slow_clk = + { + .div = CGM_MUX_DIV_SLOW_BY_4, + .trigger = false, + }, + .hse_clk = + { + .div = CGM_MUX_DIV_BY_1, + .trigger = false, + }, + .dcm_clk = + { + .div = CGM_MUX_DIV_BY_1, + .trigger = false, + }, + .lbist_clk = + { + .div = CGM_MUX_DIV_BY_1, + .trigger = false, + }, +#ifdef CONFIG_S32K3XX_QSPI + .qspi_mem_clk = + { + .div = CGM_MUX_DIV_BY_1, + .trigger = false, + }, +#endif + .mux_3 = + { + .source = CGM_CLK_SRC_AIPS_PLAT_CLK, + .div = CGM_MUX_DIV_BY_1, + }, + .mux_4 = + { + .source = CGM_CLK_SRC_AIPS_PLAT_CLK, + .div = CGM_MUX_DIV_BY_1, + }, +#ifdef CONFIG_S32K3XX_ENET + .mux_7_emac_rx = + { + .source = CGM_CLK_SRC_EMAC_RMII_TX_CLK, + .div = CGM_MUX_DIV_BY_2, + }, + .mux_8_emac_tx = + { + .source = CGM_CLK_SRC_EMAC_RMII_TX_CLK, + .div = CGM_MUX_DIV_BY_2, + }, + .mux_9_emac_ts = + { + .source = CGM_CLK_SRC_EMAC_RMII_TX_CLK, + .div = CGM_MUX_DIV_BY_2, /* FIXME check div value */ + }, +#endif +#ifdef CONFIG_S32K3XX_QSPI + .mux_10_qspi_sfck = + { + .source = CGM_CLK_SRC_PLL_PHI1_CLK, + .div = CGM_MUX_DIV_BY_4, + }, +#endif + }, + .pll = + { + .modul_freq = 0, + .modul_depth = 0, + .core_pll_power = true, + .modulation_type = false, + .sigma_delta = CGM_PLL_SIGMA_DELTA, + .enable_dither = false, + .mode = CGM_PLL_INTEGER_MODE, + .prediv = 2, + .mult = 120, + .postdiv = 2, + .phi0 = CGM_PLL_PHI_DIV_BY_3, + .phi1 = CGM_PLL_PHI_DIV_BY_3, + }, + .clkout = + { + .source = CGM_CLK_SRC_AIPS_SLOW_CLK, + .div = CGM_CLKOUT_DIV_BY_1, + } + }, + .pcc = + { + .count = NUM_OF_PERIPHERAL_CLOCKS_0, /* Number of peripheral clock configurations */ + .pclks = g_peripheral_clockconfig0, /* Peripheral clock configurations */ + }, +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_dma_alloc.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_dma_alloc.c new file mode 100644 index 00000000000..857a8e6628c --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_dma_alloc.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_dma_alloc.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#if defined(CONFIG_FAT_DMAMEMORY) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if !defined(CONFIG_GRAN) +# error microSD DMA support requires CONFIG_GRAN +#endif + +#define BOARD_DMA_ALLOC_POOL_SIZE (8*512) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static GRAN_HANDLE dma_allocator; + +/* The DMA heap size constrains the total number of things that can be + * ready to do DMA at a time. + * + * For example, FAT DMA depends on one sector-sized buffer per filesystem + * plus one sector-sized buffer per file. + * + * We use a fundamental alignment / granule size of 64B; this is sufficient + * to guarantee alignment for the largest STM32 DMA burst + * (16 beats x 32bits). + */ + +static +uint8_t g_dma_heap[BOARD_DMA_ALLOC_POOL_SIZE] aligned_data(64); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_dma_alloc_init + * + * Description: + * All boards may optionally provide this API to instantiate a pool of + * memory for uses with FAST FS DMA operations. + * + ****************************************************************************/ + +int s32k3xx_dma_alloc_init(void) +{ + dma_allocator = gran_initialize(g_dma_heap, + sizeof(g_dma_heap), + 7, /* 128B granule - must be > alignment (XXX bug?) */ + 6); /* 64B alignment */ + + if (dma_allocator == NULL) + { + return -ENOMEM; + } + + return OK; +} + +/* DMA-aware allocator stubs for the FAT filesystem. */ + +void *fat_dma_alloc(size_t size) +{ + return gran_alloc(dma_allocator, size); +} + +void fat_dma_free(FAR void *memory, size_t size) +{ + gran_free(dma_allocator, memory, size); +} + +#endif /* CONFIG_FAT_DMAMEMORY */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_i2c.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_i2c.c new file mode 100644 index 00000000000..9d08fedcaec --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_i2c.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_i2c.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include + +#include "s32k3xx_lpi2c.h" + +#include "mr-canhubk3.h" + +#ifdef CONFIG_S32K3XX_LPI2C + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k3xx_i2cdev_initialize + * + * Description: + * Initialize I2C driver and register /dev/i2cN devices. + * + ****************************************************************************/ + +int weak_function s32k3xx_i2cdev_initialize(void) +{ + int ret = OK; + +#if defined(CONFIG_S32K3XX_LPI2C0) && defined(CONFIG_I2C_DRIVER) + /* LPI2C0 *****************************************************************/ + + /* Initialize the I2C driver for LPI2C0 */ + + struct i2c_master_s *lpi2c0 = s32k3xx_i2cbus_initialize(0); + if (lpi2c0 == NULL) + { + i2cerr("ERROR: FAILED to initialize LPI2C0\n"); + return -ENODEV; + } + + ret = i2c_register(lpi2c0, 0); + if (ret < 0) + { + i2cerr("ERROR: FAILED to register LPI2C0 driver\n"); + s32k3xx_i2cbus_uninitialize(lpi2c0); + return ret; + } + +#endif /* CONFIG_S32K3XX_LPI2C0 && CONFIG_I2C_DRIVER */ + +#if defined(CONFIG_S32K3XX_LPI2C1) && defined(CONFIG_I2C_DRIVER) + /* LPI2C1 *****************************************************************/ + + /* Initialize the I2C driver for LPI2C1 */ + + struct i2c_master_s *lpi2c1 = s32k3xx_i2cbus_initialize(1); + if (lpi2c1 == NULL) + { + i2cerr("ERROR: FAILED to initialize LPI2C1\n"); + return -ENODEV; + } + + ret = i2c_register(lpi2c1, 1); + if (ret < 0) + { + i2cerr("ERROR: FAILED to register LPI2C1 driver\n"); + s32k3xx_i2cbus_uninitialize(lpi2c1); + return ret; + } +#endif /* CONFIG_S32K3XX_LPI2C1 && CONFIG_I2C_DRIVER */ + + return ret; +} + +#endif /* CONFIG_S32K3XX_LPI2C */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_periphclocks.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_periphclocks.c new file mode 100644 index 00000000000..0db0859f020 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_periphclocks.c @@ -0,0 +1,258 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_periphclocks.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "s32k3xx_clocknames.h" +#include "s32k3xx_periphclocks.h" + +#include "mr-canhubk3.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Each S32K3XX board must provide the following initialized structure. + * This is needed to establish the initial peripheral clocking. + */ + +const struct peripheral_clock_config_s g_peripheral_clockconfig0[] = +{ + { + .clkname = FLEXCAN0_CLK, +#ifdef CONFIG_S32K3XX_FLEXCAN0 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = FLEXCAN1_CLK, +#ifdef CONFIG_S32K3XX_FLEXCAN1 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = FLEXCAN2_CLK, +#ifdef CONFIG_S32K3XX_FLEXCAN2 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = FLEXCAN3_CLK, +#ifdef CONFIG_S32K3XX_FLEXCAN3 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = FLEXCAN4_CLK, +#ifdef CONFIG_S32K3XX_FLEXCAN4 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = FLEXCAN5_CLK, +#ifdef CONFIG_S32K3XX_FLEXCAN5 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPI2C0_CLK, +#ifdef CONFIG_S32K3XX_LPI2C0 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPI2C1_CLK, +#ifdef CONFIG_S32K3XX_LPI2C1 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPSPI1_CLK, +#ifdef CONFIG_S32K3XX_LPSPI1 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPSPI2_CLK, +#ifdef CONFIG_S32K3XX_LPSPI2 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPSPI3_CLK, +#ifdef CONFIG_S32K3XX_LPSPI3 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPSPI4_CLK, +#ifdef CONFIG_S32K3XX_LPSPI4 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPSPI5_CLK, +#ifdef CONFIG_S32K3XX_LPSPI5 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPUART0_CLK, +#ifdef CONFIG_S32K3XX_LPUART0 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPUART1_CLK, +#ifdef CONFIG_S32K3XX_LPUART1 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPUART2_CLK, +#ifdef CONFIG_S32K3XX_LPUART2 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPUART9_CLK, +#ifdef CONFIG_S32K3XX_LPUART9 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPUART10_CLK, +#ifdef CONFIG_S32K3XX_LPUART10 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPUART13_CLK, +#ifdef CONFIG_S32K3XX_LPUART13 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = LPUART14_CLK, +#ifdef CONFIG_S32K3XX_LPUART14 + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = WKPU_CLK, +#ifdef CONFIG_S32K3XX_WKPUINTS + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = EMAC_CLK, +#ifdef CONFIG_S32K3XX_ENET + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = QSPI_CLK, +#ifdef CONFIG_S32K3XX_QSPI + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = EDMA_CLK, +#ifdef CONFIG_S32K3XX_EDMA + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = DMAMUX0_CLK, +#ifdef CONFIG_S32K3XX_EDMA + .clkgate = true, +#else + .clkgate = false, +#endif + }, + { + .clkname = DMAMUX1_CLK, +#ifdef CONFIG_S32K3XX_EDMA + .clkgate = true, +#else + .clkgate = false, +#endif + } +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_selftest.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_selftest.c new file mode 100644 index 00000000000..85df009d5b4 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_selftest.c @@ -0,0 +1,464 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_selftest.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "s32k3xx_lpi2c.h" +#include "s32k3xx_pin.h" + +#include +#include "mr-canhubk3.h" + +#ifdef CONFIG_S32K3XX_SELFTEST + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_S32K3XX_LPI2C +static int s32k3xx_selftest_se050(void); +#endif /* CONFIG_S32K3XX_LPI2C */ +#ifdef CONFIG_S32K3XX_FLEXCAN +static int s32k3xx_selftest_can(void); +# if !defined(CONFIG_S32K3XX_TJA1153) +static int s32k3xx_selftest_sct(void); +# endif /* !CONFIG_S32K3XX_TJA1153 */ +#endif /* CONFIG_S32K3XX_FLEXCAN */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_S32K3XX_LPI2C +/**************************************************************************** + * Name: s32k3xx_selftest_se050 + * + * Description: + * Basic check to see if the SE050 is alive by having it ACK a I2C write. + * + ****************************************************************************/ + +static int s32k3xx_selftest_se050(void) +{ + struct i2c_master_s *lpi2c1; + struct i2c_msg_s se050_msg; + uint8_t buf = 0; + int ret = 0; + bool error = false; + +#if !defined(CONFIG_S32K3XX_LPI2C1) +# error CONFIG_S32K3XX_LPI2C1 needs to be enabled to perform SE050 self-test +#endif + + /* Initialize LPI2C1 to which the SE050 is connected */ + + lpi2c1 = s32k3xx_i2cbus_initialize(1); + + if (lpi2c1 != NULL) + { + _info("s32k3xx_i2cbus_initialize() succesful\n"); + } + else + { + error = true; + _err("s32k3xx_i2cbus_initialize() failed\n"); + + return -1; /* Return immediately, no cleanup needed */ + } + + /* Verify SE050 by checking for ACK on I2C write */ + + se050_msg.frequency = I2C_SPEED_STANDARD; + se050_msg.addr = 0x48; + se050_msg.flags = 0; + se050_msg.buffer = &buf; + se050_msg.length = 1; + + ret = I2C_TRANSFER(lpi2c1, &se050_msg, 1); + if (ret == 0) + { + _info("SE050 ACK succesful\n"); + } + else + { + error = true; + _err("SE050 ACK failed: %d\n", ret); + + /* Don't return yet, we still need to cleanup */ + } + + /* Let the LPI2C driver know we won't be using it anymore */ + + ret = s32k3xx_i2cbus_uninitialize(lpi2c1); + + if (ret == 0) + { + _info("s32k3xx_i2cbus_uninitialize() succesful\n"); + + /* Return error if we had any earlier, otherwise return result of + * s32k3xx_i2cbus_uninitialize() + */ + + return (error ? -1 : ret); + } + else + { + error = true; + _err("s32k3xx_i2cbus_uninitialize() failed: %d\n", ret); + + return -1; + } +} +#endif /* CONFIG_S32K3XX_LPI2C */ + +#ifdef CONFIG_S32K3XX_FLEXCAN +/**************************************************************************** + * Name: s32k3xx_selftest_can + * + * Description: + * Basic check of the local failure flags of the CAN transceivers (0-3). + * + ****************************************************************************/ + +static int s32k3xx_selftest_can(void) +{ + uint32_t errn_pins[4] = + { + PIN_CAN0_ERRN, + PIN_CAN1_ERRN, + PIN_CAN2_ERRN, + PIN_CAN3_ERRN + }; + + uint32_t stbn_pins[4] = + { + PIN_CAN0_STB, + PIN_CAN1_STB, + PIN_CAN2_STB, + PIN_CAN3_STB + }; + + uint32_t en_pins[4] = + { + PIN_CAN0_ENABLE, + PIN_CAN1_ENABLE, + PIN_CAN2_ENABLE, + PIN_CAN3_ENABLE + }; + + int i; + int ret = 0; + bool error = false; + +#if !defined(CONFIG_S32K3XX_FLEXCAN0) || !defined(CONFIG_S32K3XX_FLEXCAN1) || \ + !defined(CONFIG_S32K3XX_FLEXCAN2) || !defined(CONFIG_S32K3XX_FLEXCAN3) +# error CONFIG_S32K3XX_FLEXCAN0-3 need to be enabled to perform CAN self-test +#endif + + /* Initialize pins, go into normal mode (EN high, STB_N high) to clear Pwon + * and Wake flags. + */ + + for (i = 0; i < 4; i++) + { + ret = s32k3xx_pinconfig(errn_pins[i]); + if (ret != 0) + { + error = true; + _err("CAN%d ERR_N pin configuration failed\n", i); + + return -1; /* Return immediately, no cleanup needed */ + } + + ret = s32k3xx_pinconfig(stbn_pins[i] | GPIO_OUTPUT_ONE); + if (ret != 0) + { + error = true; + _err("CAN%d STB_N pin configuration failed\n", i); + + return -1; /* Return immediately, no cleanup needed */ + } + + ret = s32k3xx_pinconfig(en_pins[i] | GPIO_OUTPUT_ONE); + if (ret != 0) + { + error = true; + _err("CAN%d EN pin configuration failed\n", i); + + return -1; /* Return immediately, no cleanup needed */ + } + } + + /* Wait for the transition to normal mode to finish and previous status + * flags to be cleared before switching modes again. This is longer + */ + + up_udelay(3000); + + /* Go into listen-only mode (EN low, STB_N still high) to read local + * failure flags. + */ + + for (i = 0; i < 4; i++) + { + s32k3xx_gpiowrite(en_pins[i], 0); + } + + /* Wait for transition to listen-only mode to finish */ + + up_udelay(200); + + /* Check for local failure flags and then go back to normal mode */ + + for (i = 0; i < 4; i++) + { + if (s32k3xx_gpioread(errn_pins[i])) + { + _info("CAN%d flag check succesful\n", i); + } + else + { + error = true; + _err("CAN%d flag check failed\n", i); + + /* Don't return yet, we still need to cleanup */ + } + + s32k3xx_gpiowrite(en_pins[i], 1); + } + + return (error ? -1 : 0); +} + +# if !defined(CONFIG_S32K3XX_TJA1153) +/**************************************************************************** + * Name: s32k3xx_selftest_sct + * + * Description: + * Basic check of the SCTs (4-5). + * + ****************************************************************************/ + +static int s32k3xx_selftest_sct(void) +{ + uint32_t stbn_pins[2] = + { + PIN_CAN4_STB, + PIN_CAN5_STB + }; + + uint32_t en_pins[2] = + { + PIN_CAN4_ENABLE, + PIN_CAN5_ENABLE + }; + + uint32_t txd_pins[2] = + { + PIN_CAN4_TX, + PIN_CAN5_TX + }; + + uint32_t rxd_pins[2] = + { + PIN_CAN4_RX, + PIN_CAN5_RX + }; + + int i; + int ret = 0; + bool error = false; + + /* Configure pins and enable CAN PHY. CAN_TXD will be temporarily changed + * to a GPIO output to be able to control its logic level. + */ + + for (i = 4; i < 6; i++) + { + ret = s32k3xx_pinconfig(stbn_pins[i - 4] | GPIO_OUTPUT_ZERO); + if (ret != 0) + { + error = true; + _err("CAN%d STB_N pin configuration failed\n", i); + + return -1; /* Return immediately, no cleanup needed */ + } + + ret = s32k3xx_pinconfig(en_pins[i - 4] | GPIO_OUTPUT_ONE); + if (ret != 0) + { + error = true; + _err("CAN%d EN pin configuration failed\n", i); + + return -1; /* Return immediately, no cleanup needed */ + } + + ret = s32k3xx_pinconfig((txd_pins[i - 4] & (_PIN_PORT_MASK | + _PIN_MASK)) | GPIO_OUTPUT | GPIO_OUTPUT_ONE); + if (ret != 0) + { + error = true; + _err("CAN%d TXD pin configuration failed\n", i); + + return -1; /* Return immediately, no cleanup needed */ + } + + ret = s32k3xx_pinconfig(rxd_pins[i - 4]); + if (ret != 0) + { + error = true; + _err("CAN%d RXD pin configuration failed\n", i); + + return -1; /* Return immediately, no cleanup needed */ + } + } + + /* Wait for CAN PHY to detect change at TXD pin */ + + up_udelay(5000); + + /* Check if CAN_RXD follows the high level of CAN_TXD */ + + for (i = 4; i < 6; i++) + { + if (s32k3xx_gpioread(rxd_pins[i - 4])) + { + _info("CAN%d RXD high check succesful\n", i); + } + else + { + error = true; + _err("CAN%d RXD high check failed\n", i); + + /* Don't return yet, we still need to cleanup */ + } + } + + for (i = 4; i < 6; i++) + { + s32k3xx_gpiowrite(txd_pins[i - 4], 0); + } + + /* Wait for CAN PHY to detect change at TXD pin */ + + up_udelay(5000); + + /* Check if CAN_RXD follows the low level of CAN_TXD */ + + for (i = 4; i < 6; i++) + { + if (!s32k3xx_gpioread(rxd_pins[i - 4])) + { + _info("CAN%d RXD low check succesful\n", i); + } + else + { + error = true; + _err("CAN%d RXD low check failed\n", i); + + /* Don't return yet, we still need to cleanup */ + } + } + + /* Restore CAN_TXD pinconfig */ + + for (i = 4; i < 6; i++) + { + s32k3xx_pinconfig(txd_pins[i - 4]); + if (ret != 0) + { + error = true; + _err("CAN%d TXD restoring pin configuration failed\n", i); + + /* Don't return yet, we still need to cleanup */ + } + } + + return (error ? -1 : 0); +} +# endif /* !CONFIG_S32K3XX_TJA1153 */ +#endif /* CONFIG_S32K3XX_FLEXCAN */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k3xx_selftest + * + * Description: + * Runs basic routines to verify that all board components are up and + * running. Results are send to the syslog, it is recommended to + * enable all output levels (error, warning and info). + * + ****************************************************************************/ + +void s32k3xx_selftest(void) +{ + int ret = 0; + bool error = false; + +#ifdef CONFIG_S32K3XX_LPI2C + ret = s32k3xx_selftest_se050(); + if (ret != 0) + { + error = true; + _err("s32k3xx_selftest_se050() failed\n"); + } +#endif + +#ifdef CONFIG_S32K3XX_FLEXCAN + ret = s32k3xx_selftest_can(); + if (ret != 0) + { + error = true; + _err("s32k3xx_selftest_can() failed\n"); + } + +# if !defined(CONFIG_S32K3XX_TJA1153) + ret = s32k3xx_selftest_sct(); + if (ret != 0) + { + error = true; + _err("s32k3xx_selftest_sct() failed\n"); + } +# endif /* !CONFIG_S32K3XX_TJA1153 */ +#endif + + if (!error) + { + _info("s32k3xx_selftest() succesful\n"); + } +} + +#endif /* CONFIG_S32K3XX_SELFTEST */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_spi.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_spi.c new file mode 100644 index 00000000000..207c944ac4f --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_spi.c @@ -0,0 +1,376 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_spi.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "s32k3xx_pin.h" +#include "s32k3xx_lpspi.h" + +#include + +#include "mr-canhubk3.h" + +#ifdef CONFIG_S32K3XX_FS26 +#include "s32k3xx_fs26.h" +#endif + +#if defined(CONFIG_S32K3XX_LPSPI2) && defined(CONFIG_MMCSD) +#include +#endif + +#ifdef CONFIG_S32K3XX_LPSPI + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k3xx_spidev_initialize + * + * Description: + * Configure chip select pins, initialize the SPI driver and register + * /dev/spiN devices. + * + ****************************************************************************/ + +int weak_function s32k3xx_spidev_initialize(void) +{ + int ret = OK; + +#ifdef CONFIG_S32K3XX_LPSPI3 + /* LPSPI3 *****************************************************************/ + + /* Configure LPSPI3 peripheral chip select */ + + s32k3xx_pinconfig(PIN_LPSPI3_PCS); + +# ifdef CONFIG_SPI_DRIVER + /* Initialize the SPI driver for LPSPI3 */ + + struct spi_dev_s *g_lpspi3 = s32k3xx_lpspibus_initialize(3); + if (g_lpspi3 == NULL) + { + spierr("ERROR: FAILED to initialize LPSPI3\n"); + return -ENODEV; + } + + ret = spi_register(g_lpspi3, 3); + if (ret < 0) + { + spierr("ERROR: FAILED to register LPSPI3 driver\n"); + return ret; + } +# endif /* CONFIG_SPI_DRIVER */ + +# ifdef CONFIG_S32K3XX_FS26 + fs26_initialize(g_lpspi3); +# endif + +#endif /* CONFIG_S32K3XX_LPSPI3 */ + +#ifdef CONFIG_S32K3XX_LPSPI0 + /* LPSPI0 *****************************************************************/ + + /* Configure LPSPI0 peripheral chip select */ + + s32k3xx_pinconfig(PIN_LPSPI0_PCS); + +# ifdef CONFIG_SPI_DRIVER + /* Initialize the SPI driver for LPSPI0 */ + + struct spi_dev_s *g_lpspi0 = s32k3xx_lpspibus_initialize(0); + if (g_lpspi0 == NULL) + { + spierr("ERROR: FAILED to initialize LPSPI0\n"); + return -ENODEV; + } + + ret = spi_register(g_lpspi0, 0); + if (ret < 0) + { + spierr("ERROR: FAILED to register LPSPI0 driver\n"); + return ret; + } +# endif /* CONFIG_SPI_DRIVER */ +#endif /* CONFIG_S32K3XX_LPSPI0 */ + +#ifdef CONFIG_S32K3XX_LPSPI1 + /* LPSPI1 *****************************************************************/ + + /* Configure LPSPI1 peripheral chip select */ + + s32k3xx_pinconfig(PIN_LPSPI1_PCS); + +# ifdef CONFIG_SPI_DRIVER + /* Initialize the SPI driver for LPSPI1 */ + + struct spi_dev_s *g_lpspi1 = s32k3xx_lpspibus_initialize(1); + if (g_lpspi1 == NULL) + { + spierr("ERROR: FAILED to initialize LPSPI1\n"); + return -ENODEV; + } + + ret = spi_register(g_lpspi1, 1); + if (ret < 0) + { + spierr("ERROR: FAILED to register LPSPI1 driver\n"); + return ret; + } +# endif /* CONFIG_SPI_DRIVER */ +#endif /* CONFIG_S32K3XX_LPSPI1 */ + +#ifdef CONFIG_S32K3XX_LPSPI2 + /* LPSPI2 *****************************************************************/ + + /* Configure LPSPI2 peripheral chip select */ + + s32k3xx_pinconfig(PIN_LPSPI2_PCS); + + /* Initialize the SPI driver for LPSPI2 */ + + struct spi_dev_s *g_lpspi2 = s32k3xx_lpspibus_initialize(2); + if (g_lpspi2 == NULL) + { + spierr("ERROR: FAILED to initialize LPSPI2\n"); + return -ENODEV; + } + +#if defined(CONFIG_S32K3XX_LPSPI2) && defined(CONFIG_MMCSD) + +#if defined(CONFIG_FAT_DMAMEMORY) + if (s32k3xx_dma_alloc_init() < 0) + { + spierr("ERROR: DMA alloc FAILED"); + } +#endif + + if (g_lpspi2 == NULL) + { + spierr("ERROR: FAILED to initialize LPSPI2\n"); + } + + ret = mmcsd_spislotinitialize(0, 0, g_lpspi2); + + if (ret < 0) + { + spierr("ERROR: Failed to bind SPI port %d to SD slot %d\n", + 2, 0); + } +# endif + +# ifdef CONFIG_SPI_DRIVER + ret = spi_register(g_lpspi2, 2); + if (ret < 0) + { + spierr("ERROR: FAILED to register LPSPI2 driver\n"); + return ret; + } +# endif /* CONFIG_SPI_DRIVER */ + +#endif /* CONFIG_S32K3XX_LPSPI2 */ + +#ifdef CONFIG_S32K3XX_LPSPI4 + /* LPSPI4 *****************************************************************/ + + /* Configure LPSPI4 peripheral chip select */ + + s32k3xx_pinconfig(PIN_LPSPI4_PCS); + +# ifdef CONFIG_SPI_DRIVER + /* Initialize the SPI driver for LPSPI4 */ + + struct spi_dev_s *g_lpspi4 = s32k3xx_lpspibus_initialize(4); + if (g_lpspi4 == NULL) + { + spierr("ERROR: FAILED to initialize LPSPI4\n"); + return -ENODEV; + } + + ret = spi_register(g_lpspi4, 4); + if (ret < 0) + { + spierr("ERROR: FAILED to register LPSPI4 driver\n"); + return ret; + } +# endif /* CONFIG_SPI_DRIVER */ +#endif /* CONFIG_S32K3XX_LPSPI4 */ + +#ifdef CONFIG_S32K3XX_LPSPI5 + /* LPSPI5 *****************************************************************/ + + /* Configure LPSPI5 peripheral chip select */ + + s32k3xx_pinconfig(PIN_LPSPI5_PCS); + +# ifdef CONFIG_SPI_DRIVER + /* Initialize the SPI driver for LPSPI5 */ + + struct spi_dev_s *g_lpspi5 = s32k3xx_lpspibus_initialize(5); + if (g_lpspi5 == NULL) + { + spierr("ERROR: FAILED to initialize LPSPI5\n"); + return -ENODEV; + } + + ret = spi_register(g_lpspi5, 5); + if (ret < 0) + { + spierr("ERROR: FAILED to register LPSPI5 driver\n"); + return ret; + } +# endif /* CONFIG_SPI_DRIVER */ +#endif /* CONFIG_S32K3XX_LPSPI5 */ + + return ret; +} + +/**************************************************************************** + * Name: s32k3xx_lpspiNselect and s32k3xx_lpspiNstatus + * + * Description: + * The external functions, s32k3xx_lpspiNselect and s32k3xx_lpspiNstatus + * must be provided by board-specific logic. They are implementations of + * the select and status methods of the SPI interface defined by struct + * spi_ops_s (see include/nuttx/spi/spi.h). All other methods (including + * s32k3xx_lpspibus_initialize()) are provided by common logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in s32k3xx_boardinitialize() to configure SPI chip + * select pins. + * 2. Provide s32k3xx_lpspiNselect() and s32k3xx_lpspiNstatus() functions + * in your board-specific logic. These functions will perform chip + * selection and status operations using GPIOs in the way your board is + * configured. + * 3. Add a calls to s32k3xx_lpspibus_initialize() in your low level + * application initialization logic. + * 4. The handle returned by s32k3xx_lpspibus_initialize() may then be used + * to bind the SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +#ifdef CONFIG_S32K3XX_LPSPI1 +/* LPSPI1 *******************************************************************/ + +void s32k3xx_lpspi1select(struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %" PRId32 ", CS: %s\n", devid, + selected ? "assert" : "de-assert"); + + s32k3xx_gpiowrite(PIN_LPSPI1_PCS, !selected); +} + +uint8_t s32k3xx_lpspi1status(struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif /* CONFIG_S32K3XX_LPSPI1 */ + +#ifdef CONFIG_S32K3XX_LPSPI2 +/* LPSPI2 *******************************************************************/ + +void s32k3xx_lpspi2select(struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %" PRId32 ", CS: %s\n", devid, + selected ? "assert" : "de-assert"); + + s32k3xx_gpiowrite(PIN_LPSPI2_PCS, !selected); +} + +uint8_t s32k3xx_lpspi2status(struct spi_dev_s *dev, uint32_t devid) +{ + return 1; +} +#endif /* CONFIG_S32K3XX_LPSPI2 */ + +#ifdef CONFIG_S32K3XX_LPSPI3 +/* LPSPI3 *******************************************************************/ + +void s32k3xx_lpspi3select(struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %" PRId32 ", CS: %s\n", devid, + selected ? "assert" : "de-assert"); + + s32k3xx_gpiowrite(PIN_LPSPI3_PCS, !selected); +} + +uint8_t s32k3xx_lpspi3status(struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif /* CONFIG_S32K3XX_LPSPI3 */ + +#ifdef CONFIG_S32K3XX_LPSPI4 +/* LPSPI4 *******************************************************************/ + +void s32k3xx_lpspi4select(struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %" PRId32 ", CS: %s\n", devid, + selected ? "assert" : "de-assert"); + + s32k3xx_gpiowrite(PIN_LPSPI4_PCS, !selected); +} + +uint8_t s32k3xx_lpspi4status(struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif /* CONFIG_S32K3XX_LPSPI4 */ + +#ifdef CONFIG_S32K3XX_LPSPI5 +/* LPSPI5 *******************************************************************/ + +void s32k3xx_lpspi5select(struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %" PRId32 ", CS: %s\n", devid, + selected ? "assert" : "de-assert"); + + s32k3xx_gpiowrite(PIN_LPSPI5_PCS, !selected); +} + +uint8_t s32k3xx_lpspi5status(struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif /* CONFIG_S32K3XX_LPSPI5 */ +#endif /* CONFIG_S32K3XX_LPSPI */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_tja1153.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_tja1153.c new file mode 100644 index 00000000000..738fdb8bfef --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_tja1153.c @@ -0,0 +1,334 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_tja1153.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP + * + * This TJA1153 initialization routine is intended for ENGINEERING + * DEVELOPMENT OR EVALUATION PURPOSES ONLY. It is provided as an example to + * use the TJA1153. Please refer to the datasheets and application hints + * provided on NXP.com to implement full functionality. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "s32k3xx_pin.h" +#include +#include "mr-canhubk3.h" + +#ifdef CONFIG_S32K3XX_TJA1153 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bitrate must be set to 125, 250 or 500 kbit/s for CAN 2.0 and CAN FD + * arbitration phase + */ + +#ifdef CONFIG_S32K3XX_FLEXCAN4 +# if CONFIG_NET_CAN_CANFD +# if CONFIG_FLEXCAN4_ARBI_BITRATE > 500000 +# error "FLEXCAN4_ARBI_BITRATE > 500000" +# endif +# else +# if CONFIG_FLEXCAN4_BITRATE > 500000 +# error "FLEXCAN4_BITRATE > 500000" +# endif +# endif +#endif + +#ifdef CONFIG_S32K3XX_FLEXCAN5 +# if CONFIG_NET_CAN_CANFD +# if CONFIG_FLEXCAN5_ARBI_BITRATE > 500000 +# error "FLEXCAN5_ARBI_BITRATE > 500000" +# endif +# else +# if CONFIG_FLEXCAN5_BITRATE > 500000 +# error "FLEXCAN5_BITRATE > 500000" +# endif +# endif +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k3xx_tja1153_initialize + * + * Description: + * Initialize a TJA1153 CAN PHY connected to a FlexCAN peripheral (0-5) + * + ****************************************************************************/ + +int s32k3xx_tja1153_initialize(int bus) +{ + int sock; + struct sockaddr_can addr; + struct can_frame frame_config1; + struct can_frame frame_config2; + struct can_frame frame_config3; + struct can_frame frame_config4; + struct can_frame frame_config5; + struct ifreq ifr; + uint32_t pin_can_txd; + uint32_t pin_can_rxd; + uint32_t pin_can_enable; + uint32_t pin_can_stb_n; + int ret = 0; + + /* Select interface and pins */ + + switch (bus) + { +#ifdef CONFIG_S32K3XX_FLEXCAN4 + case 4: + { + strlcpy(ifr.ifr_name, "can4", IFNAMSIZ); + + pin_can_txd = PIN_CAN4_TX; + pin_can_rxd = PIN_CAN4_RX; + pin_can_enable = PIN_CAN4_ENABLE; + pin_can_stb_n = PIN_CAN4_STB; + } + break; +#endif +#ifdef CONFIG_S32K3XX_FLEXCAN5 + case 5: + { + strlcpy(ifr.ifr_name, "can5", IFNAMSIZ); + + pin_can_txd = PIN_CAN5_TX; + pin_can_rxd = PIN_CAN5_RX; + pin_can_enable = PIN_CAN5_ENABLE; + pin_can_stb_n = PIN_CAN5_STB; + } + break; +#endif + default: + { + /* This FlexCAN is not supported (yet) */ + + return -1; + } + } + + /* First check if configuration is actually needed */ + + s32k3xx_pinconfig((pin_can_txd & (_PIN_PORT_MASK | _PIN_MASK)) | + GPIO_OUTPUT | GPIO_OUTPUT_ZERO); + + if (s32k3xx_gpioread(pin_can_rxd)) + { + _info("CAN%d TJA1153 already configured\n", bus); + + s32k3xx_pinconfig(pin_can_txd); /* Restore CAN_TXD pinconfig */ + return 0; + } + + s32k3xx_pinconfig(pin_can_txd); /* Restore CAN_TXD pinconfig */ + + /* Find network interface */ + + ifr.ifr_ifindex = if_nametoindex(ifr.ifr_name); + if (!ifr.ifr_ifindex) + { + _err("CAN%d TJA1153: if_nametoindex failed\n", bus); + return -1; + } + + /* Configure pins */ + + s32k3xx_pinconfig(pin_can_enable); + s32k3xx_pinconfig(pin_can_stb_n); + + s32k3xx_gpiowrite(pin_can_enable, true); /* Enable TJA1153 */ + s32k3xx_gpiowrite(pin_can_stb_n, false); /* Inverted, so TJA1153 is put in STANDBY */ + + /* Init CAN frames, e.g. LEN = 0 */ + + memset(&frame_config1, 0, sizeof(frame_config1)); + memset(&frame_config2, 0, sizeof(frame_config2)); + memset(&frame_config3, 0, sizeof(frame_config3)); + memset(&frame_config4, 0, sizeof(frame_config4)); + memset(&frame_config5, 0, sizeof(frame_config5)); + + /* Prepare CAN frames. Refer to the TJA1153 datasheets and application + * hints available on NXP.com for details. + */ + + frame_config1.can_id = 0x555; + frame_config1.can_dlc = 0; + + frame_config2.can_id = 0x18da00f1 | CAN_EFF_FLAG; + frame_config2.can_dlc = 6; + frame_config2.data[0] = 0x10; + frame_config2.data[1] = 0x00; + frame_config2.data[2] = 0x50; + frame_config2.data[3] = 0x00; + frame_config2.data[4] = 0x07; + frame_config2.data[5] = 0xff; + + frame_config3.can_id = 0x18da00f1 | CAN_EFF_FLAG; + frame_config3.can_dlc = 6; + frame_config3.data[0] = 0x10; + frame_config3.data[1] = 0x01; + frame_config3.data[2] = 0x9f; + frame_config3.data[3] = 0xff; + frame_config3.data[4] = 0xff; + frame_config3.data[5] = 0xff; + + frame_config4.can_id = 0x18da00f1 | CAN_EFF_FLAG; + frame_config4.can_dlc = 6; + frame_config4.data[0] = 0x10; + frame_config4.data[1] = 0x02; + frame_config4.data[2] = 0xc0; + frame_config4.data[3] = 0x00; + frame_config4.data[4] = 0x00; + frame_config4.data[5] = 0x00; + + frame_config5.can_id = 0x18da00f1 | CAN_EFF_FLAG; + frame_config5.can_dlc = 8; + frame_config5.data[0] = 0x71; + frame_config5.data[1] = 0x02; + frame_config5.data[2] = 0x03; + frame_config5.data[3] = 0x04; + frame_config5.data[4] = 0x05; + frame_config5.data[5] = 0x06; + frame_config5.data[6] = 0x07; + frame_config5.data[7] = 0x08; + + /* Open socket */ + + if ((sock = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) + { + _err("CAN%d TJA1153: Failed to open socket\n", bus); + return -1; + } + + /* Bring up the interface */ + + ifr.ifr_flags = IFF_UP; + ret = ioctl(sock, SIOCSIFFLAGS, (unsigned long)&ifr); + if (ret < 0) + { + _err("CAN%d TJA1153: ioctl failed (can't set interface flags)\n", bus); + close(sock); + return -1; + } + + /* Initialize sockaddr struct */ + + memset(&addr, 0, sizeof(addr)); + addr.can_family = AF_CAN; + addr.can_ifindex = ifr.ifr_ifindex; + + /* Disable default receive filter on this RAW socket + * + * This is obsolete as we do not read from the socket at all, but for this + * reason we can remove the receive list in the kernel to save a little + * (really very little!) CPU usage. + */ + + setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); + + /* Bind socket and send the CAN frames */ + + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + _err("CAN%d TJA1153: Failed to bind socket\n", bus); + close(sock); + return -1; + } + + if (write(sock, &frame_config1, CAN_MTU) != CAN_MTU) + { + _err("CAN%d TJA1153: Failed to write frame_config1\n", bus); + close(sock); + return -1; + } + + if (write(sock, &frame_config2, CAN_MTU) != CAN_MTU) + { + _err("CAN%d TJA1153: Failed to write frame_config2\n", bus); + close(sock); + return -1; + } + + if (write(sock, &frame_config3, CAN_MTU) != CAN_MTU) + { + _err("CAN%d TJA1153: Failed to write frame_config3\n", bus); + close(sock); + return -1; + } + + if (write(sock, &frame_config4, CAN_MTU) != CAN_MTU) + { + _err("CAN%d TJA1153: Failed to write frame_config4\n", bus); + close(sock); + return -1; + } + + if (write(sock, &frame_config5, CAN_MTU) != CAN_MTU) + { + _err("CAN%d TJA1153: Failed to write frame_config5\n", bus); + close(sock); + return -1; + } + + /* Sleep for 100 ms to ensure that CAN frames have been transmitted */ + + nxsig_usleep(100 * 1000); + + /* TJA1153 must be taken out of STB mode */ + + s32k3xx_gpiowrite(pin_can_stb_n, true); /* Inverted, so TJA1153 comes out of STANDBY */ + + /* Bring down the interface */ + + ifr.ifr_flags = IFF_DOWN; + ret = ioctl(sock, SIOCSIFFLAGS, (unsigned long)&ifr); + if (ret < 0) + { + _err("CAN%d TJA1153: ioctl failed (can't set interface flags)\n", bus); + close(sock); + return -1; + } + + close(sock); + _info("CAN%d TJA1153 configuration succesful\n", bus); + return 0; +} + +#endif /* CONFIG_S32K3XX_TJA1153 */ diff --git a/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_userleds.c b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_userleds.c new file mode 100644 index 00000000000..e3dffda6726 --- /dev/null +++ b/boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_userleds.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * boards/arm/s32k3xx/mr-canhubk3/src/s32k3xx_userleds.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. + * + ****************************************************************************/ + +/* Copyright 2022 NXP */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "s32k3xx_pin.h" + +#include + +#include "mr-canhubk3.h" + +#ifndef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_userled_initialize + ****************************************************************************/ + +uint32_t board_userled_initialize(void) +{ + /* Configure LED GPIOs for output */ + + s32k3xx_pinconfig(GPIO_LED_R); + s32k3xx_pinconfig(GPIO_LED_G); + s32k3xx_pinconfig(GPIO_LED_B); + return BOARD_NLEDS; +} + +/**************************************************************************** + * Name: board_userled + ****************************************************************************/ + +void board_userled(int led, bool ledon) +{ + uint32_t ledcfg; + + if (led == BOARD_LED_R) + { + ledcfg = GPIO_LED_R; + } + else if (led == BOARD_LED_G) + { + ledcfg = GPIO_LED_G; + } + else if (led == BOARD_LED_B) + { + ledcfg = GPIO_LED_B; + } + else + { + return; + } + + /* Invert output, an output of '0' illuminates the LED */ + + s32k3xx_gpiowrite(ledcfg, !ledon); +} + +/**************************************************************************** + * Name: board_userled_all + ****************************************************************************/ + +void board_userled_all(uint32_t ledset) +{ + /* Invert output, an output of '0' illuminates the LED */ + + s32k3xx_gpiowrite(GPIO_LED_R, !((ledset & BOARD_LED_R_BIT) != 0)); + s32k3xx_gpiowrite(GPIO_LED_G, !((ledset & BOARD_LED_G_BIT) != 0)); + s32k3xx_gpiowrite(GPIO_LED_B, !((ledset & BOARD_LED_B_BIT) != 0)); +} + +#endif /* !CONFIG_ARCH_LEDS */