mirror of https://github.com/wolfSSL/wolfBoot.git
634 lines
28 KiB
C
634 lines
28 KiB
C
/* s32k1xx.h
|
|
*
|
|
* Copyright (C) 2026 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfBoot.
|
|
*
|
|
* wolfBoot is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfBoot is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*
|
|
* Hardware register definitions for NXP S32K1xx (S32K142, S32K144, S32K146, S32K148)
|
|
*/
|
|
|
|
#ifndef S32K1XX_H
|
|
#define S32K1XX_H
|
|
|
|
#include <stdint.h>
|
|
|
|
/*
|
|
* Clock configuration
|
|
* S32K142 supports:
|
|
* - FIRC: 48 MHz Fast Internal RC
|
|
* - SIRC: 8 MHz Slow Internal RC
|
|
* - SOSC: 8-40 MHz System Oscillator (external crystal)
|
|
* - SPLL: System PLL (up to 160 MHz VCO, /2 for SPLL_CLK)
|
|
*
|
|
* Run modes:
|
|
* - RUN: Up to 80 MHz core clock (requires SPLL, currently using FIRC at 48 MHz)
|
|
* - HSRUN: Up to 112 MHz core clock (requires SOSC + SPLL, not implemented yet)
|
|
*
|
|
* Default: RUN mode with FIRC at 48 MHz (no external crystal required)
|
|
* To enable HSRUN mode (112 MHz), define S32K1XX_CLOCK_HSRUN (requires SOSC + SPLL)
|
|
*/
|
|
|
|
/* ============== ARM Cortex-M4 System Registers ============== */
|
|
|
|
/* System Control Block (SCB) */
|
|
#define SCB_BASE (0xE000ED00UL)
|
|
#define SCB_CPUID (*(volatile uint32_t *)(SCB_BASE + 0x00UL))
|
|
#define SCB_ICSR (*(volatile uint32_t *)(SCB_BASE + 0x04UL))
|
|
#define SCB_VTOR (*(volatile uint32_t *)(SCB_BASE + 0x08UL))
|
|
#define SCB_AIRCR (*(volatile uint32_t *)(SCB_BASE + 0x0CUL))
|
|
#define SCB_SCR (*(volatile uint32_t *)(SCB_BASE + 0x10UL))
|
|
#define SCB_CCR (*(volatile uint32_t *)(SCB_BASE + 0x14UL))
|
|
|
|
/* AIRCR - Application Interrupt and Reset Control Register */
|
|
#define AIRCR_VECTKEY (0x05FAUL << 16)
|
|
#define AIRCR_SYSRESETREQ (1UL << 2)
|
|
|
|
/* SysTick Timer */
|
|
#define SYST_BASE (0xE000E010UL)
|
|
#define SYST_CSR (*(volatile uint32_t *)(SYST_BASE + 0x00UL))
|
|
#define SYST_RVR (*(volatile uint32_t *)(SYST_BASE + 0x04UL))
|
|
#define SYST_CVR (*(volatile uint32_t *)(SYST_BASE + 0x08UL))
|
|
#define SYST_CALIB (*(volatile uint32_t *)(SYST_BASE + 0x0CUL))
|
|
|
|
#define SYST_CSR_ENABLE (1UL << 0)
|
|
#define SYST_CSR_TICKINT (1UL << 1)
|
|
#define SYST_CSR_CLKSOURCE (1UL << 2)
|
|
#define SYST_CSR_COUNTFLAG (1UL << 16)
|
|
|
|
/* Clock speed (FIRC = 48 MHz) */
|
|
#ifndef CLOCK_SPEED
|
|
#define CLOCK_SPEED 48000000UL
|
|
#endif
|
|
|
|
/* ============== NVIC - Nested Vectored Interrupt Controller ============== */
|
|
#define NVIC_BASE (0xE000E100UL)
|
|
#define NVIC_ISER(n) (*(volatile uint32_t *)(NVIC_BASE + 0x000UL + 4*(n))) /* Interrupt Set Enable */
|
|
#define NVIC_ICER(n) (*(volatile uint32_t *)(NVIC_BASE + 0x080UL + 4*(n))) /* Interrupt Clear Enable */
|
|
#define NVIC_ISPR(n) (*(volatile uint32_t *)(NVIC_BASE + 0x100UL + 4*(n))) /* Interrupt Set Pending */
|
|
#define NVIC_ICPR(n) (*(volatile uint32_t *)(NVIC_BASE + 0x180UL + 4*(n))) /* Interrupt Clear Pending */
|
|
#define NVIC_IPR(n) (*(volatile uint32_t *)(NVIC_BASE + 0x300UL + 4*(n))) /* Interrupt Priority */
|
|
|
|
/* S32K142 LPUART IRQ numbers */
|
|
#define LPUART0_IRQn 31
|
|
#define LPUART1_IRQn 33
|
|
#define LPUART2_IRQn 35
|
|
|
|
/* NVIC helper macros */
|
|
#define NVIC_EnableIRQ(irq) NVIC_ISER((irq) >> 5) = (1UL << ((irq) & 0x1F))
|
|
#define NVIC_DisableIRQ(irq) NVIC_ICER((irq) >> 5) = (1UL << ((irq) & 0x1F))
|
|
#define NVIC_SetPriority(irq, prio) \
|
|
do { \
|
|
uint32_t _idx = (irq) >> 2; \
|
|
uint32_t _shift = (((irq) & 0x3) << 3) + 4; \
|
|
NVIC_IPR(_idx) = (NVIC_IPR(_idx) & ~(0xFUL << _shift)) | (((prio) & 0xF) << _shift); \
|
|
} while(0)
|
|
|
|
/* ============== System Control Registers ============== */
|
|
|
|
/* SCG - System Clock Generator */
|
|
#define SCG_BASE (0x40064000UL)
|
|
#define SCG_CSR (*(volatile uint32_t *)(SCG_BASE + 0x010UL)) /* Clock Status Register */
|
|
#define SCG_RCCR (*(volatile uint32_t *)(SCG_BASE + 0x014UL)) /* Run Clock Control Register */
|
|
#define SCG_VCCR (*(volatile uint32_t *)(SCG_BASE + 0x018UL)) /* VLPR Clock Control Register */
|
|
#define SCG_HCCR (*(volatile uint32_t *)(SCG_BASE + 0x01CUL)) /* HSRUN Clock Control Register */
|
|
#define SCG_CLKOUTCNFG (*(volatile uint32_t *)(SCG_BASE + 0x020UL)) /* Clock Out Configuration */
|
|
|
|
/* SOSC - System OSC */
|
|
#define SCG_SOSCCSR (*(volatile uint32_t *)(SCG_BASE + 0x100UL))
|
|
#define SCG_SOSCDIV (*(volatile uint32_t *)(SCG_BASE + 0x104UL))
|
|
#define SCG_SOSCCFG (*(volatile uint32_t *)(SCG_BASE + 0x108UL))
|
|
|
|
/* SIRC - Slow IRC */
|
|
#define SCG_SIRCCSR (*(volatile uint32_t *)(SCG_BASE + 0x200UL))
|
|
#define SCG_SIRCDIV (*(volatile uint32_t *)(SCG_BASE + 0x204UL))
|
|
#define SCG_SIRCCFG (*(volatile uint32_t *)(SCG_BASE + 0x208UL))
|
|
|
|
/* FIRC - Fast IRC */
|
|
#define SCG_FIRCCSR (*(volatile uint32_t *)(SCG_BASE + 0x300UL))
|
|
#define SCG_FIRCDIV (*(volatile uint32_t *)(SCG_BASE + 0x304UL))
|
|
#define SCG_FIRCCFG (*(volatile uint32_t *)(SCG_BASE + 0x308UL))
|
|
|
|
/* SPLL - System PLL */
|
|
#define SCG_SPLLCSR (*(volatile uint32_t *)(SCG_BASE + 0x600UL))
|
|
#define SCG_SPLLDIV (*(volatile uint32_t *)(SCG_BASE + 0x604UL))
|
|
#define SCG_SPLLCFG (*(volatile uint32_t *)(SCG_BASE + 0x608UL))
|
|
|
|
/* SCG CSR fields */
|
|
#define SCG_CSR_SCS_SHIFT 24
|
|
#define SCG_CSR_SCS_MASK (0xFUL << SCG_CSR_SCS_SHIFT)
|
|
#define SCG_CSR_SCS_FIRC (3UL << SCG_CSR_SCS_SHIFT)
|
|
#define SCG_CSR_SCS_SPLL (6UL << SCG_CSR_SCS_SHIFT)
|
|
|
|
/* SCG xCCR fields */
|
|
#define SCG_xCCR_SCS_SHIFT 24
|
|
#define SCG_xCCR_SCS_FIRC (3UL << SCG_xCCR_SCS_SHIFT)
|
|
#define SCG_xCCR_SCS_SPLL (6UL << SCG_xCCR_SCS_SHIFT)
|
|
#define SCG_xCCR_DIVCORE_SHIFT 16
|
|
#define SCG_xCCR_DIVBUS_SHIFT 4
|
|
#define SCG_xCCR_DIVSLOW_SHIFT 0
|
|
|
|
/* FIRC CSR fields */
|
|
#define SCG_FIRCCSR_FIRCEN (1UL << 0)
|
|
#define SCG_FIRCCSR_FIRCVLD (1UL << 24)
|
|
|
|
/* SPLL CSR fields */
|
|
#define SCG_SPLLCSR_SPLLEN (1UL << 0)
|
|
#define SCG_SPLLCSR_SPLLVLD (1UL << 24)
|
|
|
|
/* SPLL CFG fields */
|
|
#define SCG_SPLLCFG_MULT_SHIFT 16
|
|
#define SCG_SPLLCFG_PREDIV_SHIFT 8
|
|
|
|
/* SMC - System Mode Controller */
|
|
#define SMC_BASE (0x4007E000UL)
|
|
#define SMC_PMPROT (*(volatile uint32_t *)(SMC_BASE + 0x000UL))
|
|
#define SMC_PMCTRL (*(volatile uint32_t *)(SMC_BASE + 0x004UL))
|
|
#define SMC_PMSTAT (*(volatile uint32_t *)(SMC_BASE + 0x008UL))
|
|
|
|
#define SMC_PMPROT_AHSRUN (1UL << 7) /* Allow HSRUN */
|
|
#define SMC_PMCTRL_RUNM_SHIFT 5
|
|
#define SMC_PMCTRL_RUNM_RUN (0UL << SMC_PMCTRL_RUNM_SHIFT)
|
|
#define SMC_PMCTRL_RUNM_HSRUN (3UL << SMC_PMCTRL_RUNM_SHIFT)
|
|
#define SMC_PMSTAT_HSRUN (0x80UL)
|
|
#define SMC_PMSTAT_RUN (0x01UL)
|
|
|
|
/* PCC - Peripheral Clock Controller */
|
|
#define PCC_BASE (0x40065000UL)
|
|
#define PCC_PORTA (*(volatile uint32_t *)(PCC_BASE + 0x124UL))
|
|
#define PCC_PORTB (*(volatile uint32_t *)(PCC_BASE + 0x128UL))
|
|
#define PCC_PORTC (*(volatile uint32_t *)(PCC_BASE + 0x12CUL))
|
|
#define PCC_LPUART0 (*(volatile uint32_t *)(PCC_BASE + 0x1A8UL))
|
|
#define PCC_LPUART1 (*(volatile uint32_t *)(PCC_BASE + 0x1ACUL))
|
|
#define PCC_LPUART2 (*(volatile uint32_t *)(PCC_BASE + 0x1B0UL))
|
|
#define PCC_FTFC (*(volatile uint32_t *)(PCC_BASE + 0x0B0UL))
|
|
|
|
#define PCC_CGC (1UL << 30) /* Clock Gate Control */
|
|
#define PCC_PCS_SHIFT 24
|
|
#define PCC_PCS_FIRC (3UL << PCC_PCS_SHIFT) /* FIRC 48MHz */
|
|
#define PCC_PCS_SPLLDIV2 (6UL << PCC_PCS_SHIFT) /* SPLL DIV2 */
|
|
|
|
/* ============== GPIO / Port Registers ============== */
|
|
|
|
/* PCC for GPIO ports */
|
|
#define PCC_PORTD (*(volatile uint32_t *)(PCC_BASE + 0x130UL))
|
|
#define PCC_PORTE (*(volatile uint32_t *)(PCC_BASE + 0x134UL))
|
|
|
|
/* Port A - LPUART0/LPUART2 alternate pins */
|
|
#define PORTA_BASE (0x40049000UL)
|
|
#define PORTA_PCR(n) (*(volatile uint32_t *)(PORTA_BASE + ((n) * 4)))
|
|
#define PORTA_PCR2 (*(volatile uint32_t *)(PORTA_BASE + 0x008UL)) /* LPUART0_RX (ALT6) */
|
|
#define PORTA_PCR3 (*(volatile uint32_t *)(PORTA_BASE + 0x00CUL)) /* LPUART0_TX (ALT6) */
|
|
#define PORTA_PCR8 (*(volatile uint32_t *)(PORTA_BASE + 0x020UL)) /* LPUART2_RX (ALT6) */
|
|
#define PORTA_PCR9 (*(volatile uint32_t *)(PORTA_BASE + 0x024UL)) /* LPUART2_TX (ALT6) */
|
|
|
|
/* Port B - LPUART0/LPUART1 alternate pins */
|
|
#define PORTB_BASE (0x4004A000UL)
|
|
#define PORTB_PCR(n) (*(volatile uint32_t *)(PORTB_BASE + ((n) * 4)))
|
|
#define PORTB_PCR0 (*(volatile uint32_t *)(PORTB_BASE + 0x000UL)) /* LPUART0_RX (ALT2) */
|
|
#define PORTB_PCR1 (*(volatile uint32_t *)(PORTB_BASE + 0x004UL)) /* LPUART0_TX (ALT2) */
|
|
|
|
/* Port C - LPUART1/LPUART2 pins */
|
|
#define PORTC_BASE (0x4004B000UL)
|
|
#define PORTC_PCR(n) (*(volatile uint32_t *)(PORTC_BASE + ((n) * 4)))
|
|
#define PORTC_PCR6 (*(volatile uint32_t *)(PORTC_BASE + 0x018UL)) /* LPUART1_RX (ALT2) */
|
|
#define PORTC_PCR7 (*(volatile uint32_t *)(PORTC_BASE + 0x01CUL)) /* LPUART1_TX (ALT2) */
|
|
#define PORTC_PCR8 (*(volatile uint32_t *)(PORTC_BASE + 0x020UL)) /* LPUART1_RX (ALT2) alt */
|
|
#define PORTC_PCR9 (*(volatile uint32_t *)(PORTC_BASE + 0x024UL)) /* LPUART1_TX (ALT2) alt */
|
|
|
|
/* Port D - LED pins on S32K142EVB, LPUART2 alternate pins */
|
|
#define PORTD_BASE (0x4004C000UL)
|
|
#define PORTD_PCR(n) (*(volatile uint32_t *)(PORTD_BASE + ((n) * 4)))
|
|
#define PORTD_PCR0 (*(volatile uint32_t *)(PORTD_BASE + 0x000UL)) /* Blue LED */
|
|
#define PORTD_PCR6 (*(volatile uint32_t *)(PORTD_BASE + 0x018UL)) /* LPUART2_RX (ALT2) */
|
|
#define PORTD_PCR7 (*(volatile uint32_t *)(PORTD_BASE + 0x01CUL)) /* LPUART2_TX (ALT2) */
|
|
#define PORTD_PCR15 (*(volatile uint32_t *)(PORTD_BASE + 0x03CUL)) /* Red LED */
|
|
#define PORTD_PCR16 (*(volatile uint32_t *)(PORTD_BASE + 0x040UL)) /* Green LED */
|
|
|
|
/* Port E - additional peripheral pins */
|
|
#define PORTE_BASE (0x4004D000UL)
|
|
#define PORTE_PCR(n) (*(volatile uint32_t *)(PORTE_BASE + ((n) * 4)))
|
|
|
|
/* GPIO D registers */
|
|
#define GPIOD_BASE (0x400FF0C0UL)
|
|
#define GPIOD_PDOR (*(volatile uint32_t *)(GPIOD_BASE + 0x00UL)) /* Data Output */
|
|
#define GPIOD_PSOR (*(volatile uint32_t *)(GPIOD_BASE + 0x04UL)) /* Set Output */
|
|
#define GPIOD_PCOR (*(volatile uint32_t *)(GPIOD_BASE + 0x08UL)) /* Clear Output */
|
|
#define GPIOD_PTOR (*(volatile uint32_t *)(GPIOD_BASE + 0x0CUL)) /* Toggle Output */
|
|
#define GPIOD_PDIR (*(volatile uint32_t *)(GPIOD_BASE + 0x10UL)) /* Data Input */
|
|
#define GPIOD_PDDR (*(volatile uint32_t *)(GPIOD_BASE + 0x14UL)) /* Data Direction */
|
|
|
|
/* Port Control Register fields */
|
|
#define PORT_PCR_MUX_SHIFT 8
|
|
#define PORT_PCR_MUX_MASK (7UL << PORT_PCR_MUX_SHIFT)
|
|
#define PORT_PCR_MUX_GPIO (1UL << PORT_PCR_MUX_SHIFT) /* GPIO mode */
|
|
#define PORT_PCR_MUX_ALT2 (2UL << PORT_PCR_MUX_SHIFT) /* Alternate function 2 */
|
|
#define PORT_PCR_MUX_ALT3 (3UL << PORT_PCR_MUX_SHIFT) /* Alternate function 3 */
|
|
#define PORT_PCR_MUX_ALT4 (4UL << PORT_PCR_MUX_SHIFT) /* Alternate function 4 */
|
|
#define PORT_PCR_MUX_ALT5 (5UL << PORT_PCR_MUX_SHIFT) /* Alternate function 5 */
|
|
#define PORT_PCR_MUX_ALT6 (6UL << PORT_PCR_MUX_SHIFT) /* Alternate function 6 */
|
|
#define PORT_PCR_MUX_ALT7 (7UL << PORT_PCR_MUX_SHIFT) /* Alternate function 7 */
|
|
|
|
/* S32K142EVB LED pins (accent RGB LED accent accent accent accent LED accent accent accent-low accent LED) */
|
|
#define LED_PIN_BLUE 0 /* PTD0 - Blue LED (active low) */
|
|
#define LED_PIN_RED 15 /* PTD15 - Red LED (active low) */
|
|
#define LED_PIN_GREEN 16 /* PTD16 - Green LED (active low) */
|
|
|
|
/* ============== LPUART Registers ============== */
|
|
|
|
/* LPUART base addresses */
|
|
#define LPUART0_BASE (0x4006A000UL)
|
|
#define LPUART1_BASE (0x4006B000UL)
|
|
#define LPUART2_BASE (0x4006C000UL)
|
|
|
|
/* LPUART register offsets */
|
|
#define LPUART_VERID_OFF 0x000UL
|
|
#define LPUART_PARAM_OFF 0x004UL
|
|
#define LPUART_GLOBAL_OFF 0x008UL
|
|
#define LPUART_BAUD_OFF 0x010UL
|
|
#define LPUART_STAT_OFF 0x014UL
|
|
#define LPUART_CTRL_OFF 0x018UL
|
|
#define LPUART_DATA_OFF 0x01CUL
|
|
|
|
/* LPUART0 registers */
|
|
#define LPUART0_VERID (*(volatile uint32_t *)(LPUART0_BASE + LPUART_VERID_OFF))
|
|
#define LPUART0_PARAM (*(volatile uint32_t *)(LPUART0_BASE + LPUART_PARAM_OFF))
|
|
#define LPUART0_GLOBAL (*(volatile uint32_t *)(LPUART0_BASE + LPUART_GLOBAL_OFF))
|
|
#define LPUART0_BAUD (*(volatile uint32_t *)(LPUART0_BASE + LPUART_BAUD_OFF))
|
|
#define LPUART0_STAT (*(volatile uint32_t *)(LPUART0_BASE + LPUART_STAT_OFF))
|
|
#define LPUART0_CTRL (*(volatile uint32_t *)(LPUART0_BASE + LPUART_CTRL_OFF))
|
|
#define LPUART0_DATA (*(volatile uint32_t *)(LPUART0_BASE + LPUART_DATA_OFF))
|
|
|
|
/* LPUART1 registers */
|
|
#define LPUART1_VERID (*(volatile uint32_t *)(LPUART1_BASE + LPUART_VERID_OFF))
|
|
#define LPUART1_PARAM (*(volatile uint32_t *)(LPUART1_BASE + LPUART_PARAM_OFF))
|
|
#define LPUART1_GLOBAL (*(volatile uint32_t *)(LPUART1_BASE + LPUART_GLOBAL_OFF))
|
|
#define LPUART1_BAUD (*(volatile uint32_t *)(LPUART1_BASE + LPUART_BAUD_OFF))
|
|
#define LPUART1_STAT (*(volatile uint32_t *)(LPUART1_BASE + LPUART_STAT_OFF))
|
|
#define LPUART1_CTRL (*(volatile uint32_t *)(LPUART1_BASE + LPUART_CTRL_OFF))
|
|
#define LPUART1_DATA (*(volatile uint32_t *)(LPUART1_BASE + LPUART_DATA_OFF))
|
|
|
|
/* LPUART2 registers */
|
|
#define LPUART2_VERID (*(volatile uint32_t *)(LPUART2_BASE + LPUART_VERID_OFF))
|
|
#define LPUART2_PARAM (*(volatile uint32_t *)(LPUART2_BASE + LPUART_PARAM_OFF))
|
|
#define LPUART2_GLOBAL (*(volatile uint32_t *)(LPUART2_BASE + LPUART_GLOBAL_OFF))
|
|
#define LPUART2_BAUD (*(volatile uint32_t *)(LPUART2_BASE + LPUART_BAUD_OFF))
|
|
#define LPUART2_STAT (*(volatile uint32_t *)(LPUART2_BASE + LPUART_STAT_OFF))
|
|
#define LPUART2_CTRL (*(volatile uint32_t *)(LPUART2_BASE + LPUART_CTRL_OFF))
|
|
#define LPUART2_DATA (*(volatile uint32_t *)(LPUART2_BASE + LPUART_DATA_OFF))
|
|
|
|
/* LPUART register field definitions */
|
|
#define LPUART_BAUD_OSR_SHIFT 24
|
|
#define LPUART_BAUD_SBR_SHIFT 0
|
|
#define LPUART_CTRL_TE (1UL << 19) /* Transmitter Enable */
|
|
#define LPUART_CTRL_RE (1UL << 18) /* Receiver Enable */
|
|
#define LPUART_CTRL_RIE (1UL << 21) /* Receiver Interrupt Enable */
|
|
#define LPUART_STAT_TDRE (1UL << 23) /* Transmit Data Register Empty */
|
|
#define LPUART_STAT_TC (1UL << 22) /* Transmission Complete */
|
|
#define LPUART_STAT_RDRF (1UL << 21) /* Receive Data Register Full */
|
|
#define LPUART_STAT_OR (1UL << 19) /* Overrun Flag */
|
|
#define LPUART_STAT_NF (1UL << 18) /* Noise Flag */
|
|
#define LPUART_STAT_FE (1UL << 17) /* Framing Error */
|
|
#define LPUART_STAT_PF (1UL << 16) /* Parity Error */
|
|
|
|
/* ============== LPUART Build-Time Configuration ============== */
|
|
/*
|
|
* Select LPUART instance and pins at build time using these defines:
|
|
*
|
|
* DEBUG_UART_NUM: LPUART instance (0, 1, or 2). Default: 1
|
|
*
|
|
* DEBUG_UART_TX_PORT: Port for TX pin (S32K_PORT_A/B/C/D/E). Default depends on LPUART
|
|
* DEBUG_UART_TX_PIN: Pin number for TX. Default depends on LPUART
|
|
* DEBUG_UART_TX_MUX: Pin mux function. Default: PORT_PCR_MUX_ALT2
|
|
*
|
|
* DEBUG_UART_RX_PORT: Port for RX pin (S32K_PORT_A/B/C/D/E). Default depends on LPUART
|
|
* DEBUG_UART_RX_PIN: Pin number for RX. Default depends on LPUART
|
|
* DEBUG_UART_RX_MUX: Pin mux function. Default: PORT_PCR_MUX_ALT2
|
|
*
|
|
* Example pin mappings for S32K1xx:
|
|
*
|
|
* LPUART0:
|
|
* - PTB0 (RX, ALT2), PTB1 (TX, ALT2) - Default
|
|
* - PTA2 (RX, ALT6), PTA3 (TX, ALT6)
|
|
*
|
|
* LPUART1:
|
|
* - PTC6 (RX, ALT2), PTC7 (TX, ALT2) - Default (S32K142EVB OpenSDA)
|
|
* - PTC8 (RX, ALT2), PTC9 (TX, ALT2)
|
|
*
|
|
* LPUART2:
|
|
* - PTA8 (RX, ALT6), PTA9 (TX, ALT6)
|
|
* - PTD6 (RX, ALT2), PTD7 (TX, ALT2) - Default
|
|
*
|
|
* Usage in .config file:
|
|
* CFLAGS_EXTRA+=-DDEBUG_UART_NUM=0
|
|
* CFLAGS_EXTRA+=-DDEBUG_UART_TX_PORT=S32K_PORT_B -DDEBUG_UART_TX_PIN=1
|
|
* CFLAGS_EXTRA+=-DDEBUG_UART_RX_PORT=S32K_PORT_B -DDEBUG_UART_RX_PIN=0
|
|
*/
|
|
|
|
/* Default LPUART instance */
|
|
#ifndef DEBUG_UART_NUM
|
|
#define DEBUG_UART_NUM 1
|
|
#endif
|
|
|
|
/* Map to selected LPUART registers based on DEBUG_UART_NUM */
|
|
#if DEBUG_UART_NUM == 0
|
|
#define LPUART_BAUD LPUART0_BAUD
|
|
#define LPUART_STAT LPUART0_STAT
|
|
#define LPUART_CTRL LPUART0_CTRL
|
|
#define LPUART_DATA LPUART0_DATA
|
|
#define PCC_LPUART PCC_LPUART0
|
|
#elif DEBUG_UART_NUM == 2
|
|
#define LPUART_BAUD LPUART2_BAUD
|
|
#define LPUART_STAT LPUART2_STAT
|
|
#define LPUART_CTRL LPUART2_CTRL
|
|
#define LPUART_DATA LPUART2_DATA
|
|
#define PCC_LPUART PCC_LPUART2
|
|
#else /* DEBUG_UART_NUM == 1 (default) */
|
|
#define LPUART_BAUD LPUART1_BAUD
|
|
#define LPUART_STAT LPUART1_STAT
|
|
#define LPUART_CTRL LPUART1_CTRL
|
|
#define LPUART_DATA LPUART1_DATA
|
|
#define PCC_LPUART PCC_LPUART1
|
|
#endif
|
|
|
|
/* Port identifier values for preprocessor comparisons */
|
|
#define S32K_PORT_A 0
|
|
#define S32K_PORT_B 1
|
|
#define S32K_PORT_C 2
|
|
#define S32K_PORT_D 3
|
|
#define S32K_PORT_E 4
|
|
|
|
/* Default pin configuration based on selected LPUART */
|
|
#if DEBUG_UART_NUM == 0
|
|
/* LPUART0 defaults: PTB0 (RX), PTB1 (TX) */
|
|
#ifndef DEBUG_UART_TX_PORT
|
|
#define DEBUG_UART_TX_PORT S32K_PORT_B
|
|
#endif
|
|
#ifndef DEBUG_UART_TX_PIN
|
|
#define DEBUG_UART_TX_PIN 1
|
|
#endif
|
|
#ifndef DEBUG_UART_RX_PORT
|
|
#define DEBUG_UART_RX_PORT S32K_PORT_B
|
|
#endif
|
|
#ifndef DEBUG_UART_RX_PIN
|
|
#define DEBUG_UART_RX_PIN 0
|
|
#endif
|
|
#elif DEBUG_UART_NUM == 2
|
|
/* LPUART2 defaults: PTD6 (RX), PTD7 (TX) */
|
|
#ifndef DEBUG_UART_TX_PORT
|
|
#define DEBUG_UART_TX_PORT S32K_PORT_D
|
|
#endif
|
|
#ifndef DEBUG_UART_TX_PIN
|
|
#define DEBUG_UART_TX_PIN 7
|
|
#endif
|
|
#ifndef DEBUG_UART_RX_PORT
|
|
#define DEBUG_UART_RX_PORT S32K_PORT_D
|
|
#endif
|
|
#ifndef DEBUG_UART_RX_PIN
|
|
#define DEBUG_UART_RX_PIN 6
|
|
#endif
|
|
#else /* DEBUG_UART_NUM == 1 (default) */
|
|
/* LPUART1 defaults: PTC6 (RX), PTC7 (TX) - S32K142EVB OpenSDA */
|
|
#ifndef DEBUG_UART_TX_PORT
|
|
#define DEBUG_UART_TX_PORT S32K_PORT_C
|
|
#endif
|
|
#ifndef DEBUG_UART_TX_PIN
|
|
#define DEBUG_UART_TX_PIN 7
|
|
#endif
|
|
#ifndef DEBUG_UART_RX_PORT
|
|
#define DEBUG_UART_RX_PORT S32K_PORT_C
|
|
#endif
|
|
#ifndef DEBUG_UART_RX_PIN
|
|
#define DEBUG_UART_RX_PIN 6
|
|
#endif
|
|
#endif
|
|
|
|
/* Default pin mux - ALT2 for most LPUART pins */
|
|
#ifndef DEBUG_UART_TX_MUX
|
|
#define DEBUG_UART_TX_MUX PORT_PCR_MUX_ALT2
|
|
#endif
|
|
#ifndef DEBUG_UART_RX_MUX
|
|
#define DEBUG_UART_RX_MUX PORT_PCR_MUX_ALT2
|
|
#endif
|
|
|
|
/* Map TX port/pin to PCR register and PCC */
|
|
#if DEBUG_UART_TX_PORT == S32K_PORT_A
|
|
#define DEBUG_UART_TX_PCC_PORT PCC_PORTA
|
|
#define DEBUG_UART_TX_PCR PORTA_PCR(DEBUG_UART_TX_PIN)
|
|
#elif DEBUG_UART_TX_PORT == S32K_PORT_B
|
|
#define DEBUG_UART_TX_PCC_PORT PCC_PORTB
|
|
#define DEBUG_UART_TX_PCR PORTB_PCR(DEBUG_UART_TX_PIN)
|
|
#elif DEBUG_UART_TX_PORT == S32K_PORT_D
|
|
#define DEBUG_UART_TX_PCC_PORT PCC_PORTD
|
|
#define DEBUG_UART_TX_PCR PORTD_PCR(DEBUG_UART_TX_PIN)
|
|
#elif DEBUG_UART_TX_PORT == S32K_PORT_E
|
|
#define DEBUG_UART_TX_PCC_PORT PCC_PORTE
|
|
#define DEBUG_UART_TX_PCR PORTE_PCR(DEBUG_UART_TX_PIN)
|
|
#else /* S32K_PORT_C (default) */
|
|
#define DEBUG_UART_TX_PCC_PORT PCC_PORTC
|
|
#define DEBUG_UART_TX_PCR PORTC_PCR(DEBUG_UART_TX_PIN)
|
|
#endif
|
|
|
|
/* Map RX port/pin to PCR register and PCC */
|
|
#if DEBUG_UART_RX_PORT == S32K_PORT_A
|
|
#define DEBUG_UART_RX_PCC_PORT PCC_PORTA
|
|
#define DEBUG_UART_RX_PCR PORTA_PCR(DEBUG_UART_RX_PIN)
|
|
#elif DEBUG_UART_RX_PORT == S32K_PORT_B
|
|
#define DEBUG_UART_RX_PCC_PORT PCC_PORTB
|
|
#define DEBUG_UART_RX_PCR PORTB_PCR(DEBUG_UART_RX_PIN)
|
|
#elif DEBUG_UART_RX_PORT == S32K_PORT_D
|
|
#define DEBUG_UART_RX_PCC_PORT PCC_PORTD
|
|
#define DEBUG_UART_RX_PCR PORTD_PCR(DEBUG_UART_RX_PIN)
|
|
#elif DEBUG_UART_RX_PORT == S32K_PORT_E
|
|
#define DEBUG_UART_RX_PCC_PORT PCC_PORTE
|
|
#define DEBUG_UART_RX_PCR PORTE_PCR(DEBUG_UART_RX_PIN)
|
|
#else /* S32K_PORT_C (default) */
|
|
#define DEBUG_UART_RX_PCC_PORT PCC_PORTC
|
|
#define DEBUG_UART_RX_PCR PORTC_PCR(DEBUG_UART_RX_PIN)
|
|
#endif
|
|
|
|
/* Check if TX and RX use the same port (for clock enable optimization) */
|
|
#if DEBUG_UART_TX_PORT == DEBUG_UART_RX_PORT
|
|
#define DEBUG_UART_SAME_PORT 1
|
|
#else
|
|
#define DEBUG_UART_SAME_PORT 0
|
|
#endif
|
|
|
|
/* ============== Flash (FTFC) Registers ============== */
|
|
|
|
#define FTFC_BASE (0x40020000UL)
|
|
#define FTFC_FSTAT (*(volatile uint8_t *)(FTFC_BASE + 0x000UL))
|
|
#define FTFC_FCNFG (*(volatile uint8_t *)(FTFC_BASE + 0x001UL))
|
|
#define FTFC_FSEC (*(volatile uint8_t *)(FTFC_BASE + 0x002UL))
|
|
#define FTFC_FOPT (*(volatile uint8_t *)(FTFC_BASE + 0x003UL))
|
|
#define FTFC_FCCOB3 (*(volatile uint8_t *)(FTFC_BASE + 0x004UL))
|
|
#define FTFC_FCCOB2 (*(volatile uint8_t *)(FTFC_BASE + 0x005UL))
|
|
#define FTFC_FCCOB1 (*(volatile uint8_t *)(FTFC_BASE + 0x006UL))
|
|
#define FTFC_FCCOB0 (*(volatile uint8_t *)(FTFC_BASE + 0x007UL))
|
|
#define FTFC_FCCOB7 (*(volatile uint8_t *)(FTFC_BASE + 0x008UL))
|
|
#define FTFC_FCCOB6 (*(volatile uint8_t *)(FTFC_BASE + 0x009UL))
|
|
#define FTFC_FCCOB5 (*(volatile uint8_t *)(FTFC_BASE + 0x00AUL))
|
|
#define FTFC_FCCOB4 (*(volatile uint8_t *)(FTFC_BASE + 0x00BUL))
|
|
#define FTFC_FCCOBB (*(volatile uint8_t *)(FTFC_BASE + 0x00CUL))
|
|
#define FTFC_FCCOBA (*(volatile uint8_t *)(FTFC_BASE + 0x00DUL))
|
|
#define FTFC_FCCOB9 (*(volatile uint8_t *)(FTFC_BASE + 0x00EUL))
|
|
#define FTFC_FCCOB8 (*(volatile uint8_t *)(FTFC_BASE + 0x00FUL))
|
|
|
|
/* FTFC Commands */
|
|
#define FTFC_CMD_PROGRAM_PHRASE 0x07 /* Program 8 bytes (phrase) */
|
|
#define FTFC_CMD_ERASE_SECTOR 0x09 /* Erase flash sector (2KB) */
|
|
#define FTFC_CMD_READ_RESOURCE 0x03 /* Read resource */
|
|
|
|
/* FTFC_FSTAT bits */
|
|
#define FTFC_FSTAT_CCIF (1U << 7) /* Command Complete */
|
|
#define FTFC_FSTAT_RDCOLERR (1U << 6) /* Read Collision Error */
|
|
#define FTFC_FSTAT_ACCERR (1U << 5) /* Access Error */
|
|
#define FTFC_FSTAT_FPVIOL (1U << 4) /* Protection Violation */
|
|
#define FTFC_FSTAT_MGSTAT0 (1U << 0) /* Command Failure */
|
|
|
|
/* Flash programming unit: 8 bytes (double-word / phrase) */
|
|
#define FLASH_PHRASE_SIZE 8
|
|
|
|
/* ============== S32K1xx Variant Flash Sizes ============== */
|
|
/* Define the appropriate variant or use automatic detection based on WOLFBOOT config
|
|
*
|
|
* S32K142: 256KB Flash (0x00000 - 0x3FFFF), 32KB SRAM, 2KB sectors
|
|
* S32K144: 512KB Flash (0x00000 - 0x7FFFF), 64KB SRAM, 4KB sectors
|
|
* S32K146: 1MB Flash (0x00000 - 0xFFFFF), 128KB SRAM, 4KB sectors
|
|
* S32K148: 2MB Flash (0x00000 - 0x1FFFFF), 256KB SRAM, 4KB sectors
|
|
*
|
|
* IMPORTANT: Flash sector size depends on total flash size:
|
|
* - 256KB Flash (S32K142): 2KB sectors
|
|
* - 512KB+ Flash (S32K144/146/148): 4KB sectors
|
|
*
|
|
* All variants use 8-byte phrase programming.
|
|
*/
|
|
#if defined(S32K148)
|
|
#define FLASH_SIZE (2048 * 1024) /* 2MB */
|
|
#define SRAM_SIZE (256 * 1024) /* 256KB */
|
|
#define FLASH_SECTOR_SIZE 4096 /* 4KB sectors */
|
|
#elif defined(S32K146)
|
|
#define FLASH_SIZE (1024 * 1024) /* 1MB */
|
|
#define SRAM_SIZE (128 * 1024) /* 128KB */
|
|
#define FLASH_SECTOR_SIZE 4096 /* 4KB sectors */
|
|
#elif defined(S32K144)
|
|
#define FLASH_SIZE (512 * 1024) /* 512KB */
|
|
#define SRAM_SIZE (64 * 1024) /* 64KB */
|
|
#define FLASH_SECTOR_SIZE 4096 /* 4KB sectors */
|
|
#else /* S32K142 (default) */
|
|
#define FLASH_SIZE (256 * 1024) /* 256KB */
|
|
#define SRAM_SIZE (32 * 1024) /* 32KB */
|
|
#define FLASH_SECTOR_SIZE 2048 /* 2KB sectors */
|
|
#endif
|
|
|
|
/* Flash base address */
|
|
#define FLASH_BASE_ADDR 0x00000000
|
|
|
|
/* Flash Configuration Field (FCF) region - MUST NOT be modified at runtime!
|
|
* Writing incorrect values here can permanently lock the device.
|
|
* Address range: 0x400 - 0x40F (16 bytes)
|
|
*/
|
|
#define FCF_START_ADDR 0x400
|
|
#define FCF_END_ADDR 0x410
|
|
|
|
/* SRAM base address (all S32K1xx variants) */
|
|
#define SRAM_BASE_ADDR 0x1FFF8000 /* Lower SRAM */
|
|
#define SRAM_UPPER_ADDR 0x20000000 /* Upper SRAM */
|
|
|
|
/* ============== Watchdog (WDOG) Registers ============== */
|
|
/* S32K1xx has a software-controlled watchdog timer */
|
|
|
|
#define WDOG_BASE (0x40052000UL)
|
|
#define WDOG_CS (*(volatile uint32_t *)(WDOG_BASE + 0x00UL)) /* Control and Status */
|
|
#define WDOG_CNT (*(volatile uint32_t *)(WDOG_BASE + 0x04UL)) /* Counter */
|
|
#define WDOG_TOVAL (*(volatile uint32_t *)(WDOG_BASE + 0x08UL)) /* Timeout Value */
|
|
#define WDOG_WIN (*(volatile uint32_t *)(WDOG_BASE + 0x0CUL)) /* Window */
|
|
|
|
/* WDOG CS Register Bits */
|
|
#define WDOG_CS_STOP (1UL << 0) /* Stop enable */
|
|
#define WDOG_CS_WAIT (1UL << 1) /* Wait enable */
|
|
#define WDOG_CS_DBG (1UL << 2) /* Debug enable */
|
|
#define WDOG_CS_TST_SHIFT 3
|
|
#define WDOG_CS_TST_MASK (3UL << WDOG_CS_TST_SHIFT) /* Test mode */
|
|
#define WDOG_CS_UPDATE (1UL << 5) /* Allow updates */
|
|
#define WDOG_CS_INT (1UL << 6) /* Interrupt enable */
|
|
#define WDOG_CS_EN (1UL << 7) /* Watchdog enable */
|
|
#define WDOG_CS_CLK_SHIFT 8
|
|
#define WDOG_CS_CLK_MASK (3UL << WDOG_CS_CLK_SHIFT) /* Clock source */
|
|
#define WDOG_CS_CLK_BUS (0UL << WDOG_CS_CLK_SHIFT) /* Bus clock */
|
|
#define WDOG_CS_CLK_LPO (1UL << WDOG_CS_CLK_SHIFT) /* LPO clock (128kHz) */
|
|
#define WDOG_CS_CLK_SOSC (2UL << WDOG_CS_CLK_SHIFT) /* SOSC clock */
|
|
#define WDOG_CS_CLK_SIRC (3UL << WDOG_CS_CLK_SHIFT) /* SIRC clock */
|
|
#define WDOG_CS_RCS (1UL << 10) /* Reconfiguration success */
|
|
#define WDOG_CS_ULK (1UL << 11) /* Unlock status */
|
|
#define WDOG_CS_PRES (1UL << 12) /* Prescaler (256 divider) */
|
|
#define WDOG_CS_CMD32EN (1UL << 13) /* 32-bit command support */
|
|
#define WDOG_CS_FLG (1UL << 14) /* Interrupt flag */
|
|
#define WDOG_CS_WIN (1UL << 15) /* Window mode enable */
|
|
|
|
/* WDOG Unlock Key - write to CNT register to unlock */
|
|
#define WDOG_CNT_UNLOCK (0xD928C520UL)
|
|
|
|
/* WDOG Refresh Keys - write in sequence to CNT register to refresh */
|
|
#define WDOG_CNT_REFRESH_HI (0xB480UL)
|
|
#define WDOG_CNT_REFRESH_LO (0xA602UL)
|
|
#define WDOG_CNT_REFRESH (0xB480A602UL) /* For CMD32EN mode */
|
|
|
|
/* Default WDOG timeout value (max = 0xFFFF) */
|
|
#define WDOG_TOVAL_DEFAULT (0xFFFFUL)
|
|
|
|
/* Watchdog disable configuration:
|
|
* - EN=0 (disabled), UPDATE=1, CMD32EN=1, CLK=LPO
|
|
*/
|
|
#define WDOG_CS_DISABLE_CFG (WDOG_CS_UPDATE | WDOG_CS_CMD32EN | WDOG_CS_CLK_LPO)
|
|
|
|
/* Watchdog enable configuration:
|
|
* - EN=1, UPDATE=1, CMD32EN=1, CLK=LPO
|
|
* LPO is 128kHz, with PRES=0 (no 256 divider)
|
|
* Timeout = TOVAL / 128kHz = TOVAL * 7.8125us
|
|
* For ~1 second timeout: TOVAL = 128000
|
|
*/
|
|
#define WDOG_CS_ENABLE_CFG (WDOG_CS_EN | WDOG_CS_UPDATE | WDOG_CS_CMD32EN | \
|
|
WDOG_CS_CLK_LPO)
|
|
|
|
|
|
/* Default 1 second timeout */
|
|
#ifndef WATCHDOG_TIMEOUT_MS
|
|
#define WATCHDOG_TIMEOUT_MS 1000
|
|
#endif
|
|
|
|
/* ============== UART Function Declarations ============== */
|
|
/* These functions are implemented in hal/s32k1xx.c when DEBUG_UART is defined.
|
|
* They use the LPUART instance and pins configured by the DEBUG_UART_* macros.
|
|
*/
|
|
|
|
#ifdef DEBUG_UART
|
|
/* Initialize the UART with configured LPUART and pins */
|
|
void uart_init(void);
|
|
|
|
/* Write data to UART (blocking, with automatic LF -> CRLF conversion) */
|
|
void uart_write(const char* buf, unsigned int sz);
|
|
|
|
/* Read a single character from UART (non-blocking)
|
|
* Returns: 1 if character read, 0 if no data available, -1 on error
|
|
*/
|
|
int uart_read(char* c);
|
|
|
|
#endif /* DEBUG_UART */
|
|
|
|
#endif /* S32K1XX_H */
|
|
|