diff --git a/hal/targets.json b/hal/targets.json index 40fb3a8377..394624e70c 100644 --- a/hal/targets.json +++ b/hal/targets.json @@ -475,17 +475,6 @@ "progen": {"target": "kl26z"}, "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"] }, - "KL43Z": { - "supported_form_factors": ["ARDUINO"], - "core": "Cortex-M0+", - "extra_labels": ["Freescale", "KLXX"], - "is_disk_virtual": true, - "supported_toolchains": ["GCC_ARM", "ARM"], - "inherits": ["Target"], - "progen": {"target": "frdm-kl43z"}, - "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], - "release_versions": ["2"] - }, "KL46Z": { "supported_form_factors": ["ARDUINO"], "core": "Cortex-M0+", @@ -553,6 +542,19 @@ "default_build": "standard", "release_versions": ["2"] }, + "KL43Z": { + "supported_form_factors": ["ARDUINO"], + "core": "Cortex-M0+", + "supported_toolchains": ["GCC_ARM", "ARM", "IAR"], + "extra_labels": ["Freescale", "KSDK2_MCUS", "FRDM"], + "macros": ["CPU_MKL43Z256VLH4", "FSL_RTOS_MBED"], + "is_disk_virtual": true, + "inherits": ["Target"], + "progen": {"target": "frdm-kl43z"}, + "detect_code": ["0262"], + "device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "release_versions": ["2", "5"] + }, "K64F": { "supported_form_factors": ["ARDUINO"], "core": "Cortex-M4F", diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/MKL43Z4.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/MKL43Z4.h new file mode 100644 index 0000000000..f5c2e65172 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/MKL43Z4.h @@ -0,0 +1,8112 @@ +/* +** ################################################################### +** Processors: MKL43Z128VLH4 +** MKL43Z128VMP4 +** MKL43Z256VLH4 +** MKL43Z256VMP4 +** +** Compilers: Keil ARM C/C++ Compiler +** Freescale C/C++ for Embedded ARM +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** +** Reference manual: KL43P64M48SF6RM, Rev.3, Aug 2014 +** Version: rev. 1.6, 2015-07-29 +** Build: b151221 +** +** Abstract: +** CMSIS Peripheral Access Layer for MKL43Z4 +** +** Copyright (c) 1997 - 2015 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** Revisions: +** - rev. 1.0 (2014-03-27) +** Initial version. +** - rev. 1.1 (2014-05-26) +** I2S registers TCR2/RCR2 and others were changed. +** FLEXIO register FLEXIO_VERID has now bitfields: FEATURE, MINOR, MAJOR. +** Names of the bitfields of the FLEXIO_SHIFTBUF have been changed to the appropriate register name e.g.: FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS. +** Peripheral_BASES macros has been changed to Peripheral_BASE_PTRS, e.g.: ADC_BASES to ADC_BASE_PTRS. +** Clock configuration for high range external oscillator has been added. +** RFSYS module access has been added. +** - rev. 1.2 (2014-07-10) +** GPIO - Renamed modules PTA,PTB,PTC,PTD,PTE to GPIOA,GPIOB,GPIOC,GPIOD,GPIOE. +** UART0 - UART0 module renamed to UART2. +** I2S - removed MDR register. +** - rev. 1.3 (2014-08-21) +** UART2 - Removed ED register. +** UART2 - Removed MODEM register. +** UART2 - Removed IR register. +** UART2 - Removed PFIFO register. +** UART2 - Removed CFIFO register. +** UART2 - Removed SFIFO register. +** UART2 - Removed TWFIFO register. +** UART2 - Removed TCFIFO register. +** UART2 - Removed RWFIFO register. +** UART2 - Removed RCFIFO register. +** USB - Removed bitfield REG_EN in CLK_RECOVER_IRC_EN register. +** SIM - Changed bitfield value MCGIRCLK to LIRC_CLK of bitfield CLKOUTSEL in SOPT2 register. +** SIM - Removed bitfield DIEID in SDID register. +** - rev. 1.4 (2014-09-01) +** USB - USB0_CTL0 was renamed to USB0_OTGCTL register. +** USB - USB0_CTL1 was renamed to USB0_CTL register. +** - rev. 1.5 (2014-09-05) +** USB - Renamed USBEN bitfield of USB0_CTL was renamed to USBENSOFEN. +** - rev. 1.6 (2015-07-29) +** Correction of backward compatibility. +** +** ################################################################### +*/ + +/*! + * @file MKL43Z4.h + * @version 1.6 + * @date 2015-07-29 + * @brief CMSIS Peripheral Access Layer for MKL43Z4 + * + * CMSIS Peripheral Access Layer for MKL43Z4 + */ + +#ifndef _MKL43Z4_H_ +#define _MKL43Z4_H_ /**< Symbol preventing repeated inclusion */ + +/** Memory map major version (memory maps with equal major version number are + * compatible) */ +#define MCU_MEM_MAP_VERSION 0x0100U +/** Memory map minor version */ +#define MCU_MEM_MAP_VERSION_MINOR 0x0006U + + +/* ---------------------------------------------------------------------------- + -- Interrupt vector numbers + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Interrupt_vector_numbers Interrupt vector numbers + * @{ + */ + +/** Interrupt Number Definitions */ +#define NUMBER_OF_INT_VECTORS 48 /**< Number of interrupts in the Vector table */ + +typedef enum IRQn { + /* Auxiliary constants */ + NotAvail_IRQn = -128, /**< Not available device specific interrupt */ + + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M0 SV Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M0 SV Call Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M0 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M0 System Tick Interrupt */ + + /* Device specific interrupts */ + DMA0_IRQn = 0, /**< DMA channel 0 transfer complete */ + DMA1_IRQn = 1, /**< DMA channel 1 transfer complete */ + DMA2_IRQn = 2, /**< DMA channel 2 transfer complete */ + DMA3_IRQn = 3, /**< DMA channel 3 transfer complete */ + Reserved20_IRQn = 4, /**< Reserved interrupt */ + FTFA_IRQn = 5, /**< Command complete and read collision */ + PMC_IRQn = 6, /**< Low-voltage detect, low-voltage warning */ + LLWU_IRQn = 7, /**< Low leakage wakeup */ + I2C0_IRQn = 8, /**< I2C0 interrupt */ + I2C1_IRQn = 9, /**< I2C1 interrupt */ + SPI0_IRQn = 10, /**< SPI0 single interrupt vector for all sources */ + SPI1_IRQn = 11, /**< SPI1 single interrupt vector for all sources */ + LPUART0_IRQn = 12, /**< LPUART0 status and error */ + LPUART1_IRQn = 13, /**< LPUART1 status and error */ + UART2_FLEXIO_IRQn = 14, /**< UART2 or FLEXIO */ + ADC0_IRQn = 15, /**< ADC0 interrupt */ + CMP0_IRQn = 16, /**< CMP0 interrupt */ + TPM0_IRQn = 17, /**< TPM0 single interrupt vector for all sources */ + TPM1_IRQn = 18, /**< TPM1 single interrupt vector for all sources */ + TPM2_IRQn = 19, /**< TPM2 single interrupt vector for all sources */ + RTC_IRQn = 20, /**< RTC alarm */ + RTC_Seconds_IRQn = 21, /**< RTC seconds */ + PIT_IRQn = 22, /**< PIT interrupt */ + I2S0_IRQn = 23, /**< I2S0 interrupt */ + USB0_IRQn = 24, /**< USB0 interrupt */ + DAC0_IRQn = 25, /**< DAC0 interrupt */ + Reserved42_IRQn = 26, /**< Reserved interrupt */ + Reserved43_IRQn = 27, /**< Reserved interrupt */ + LPTMR0_IRQn = 28, /**< LPTMR0 interrupt */ + LCD_IRQn = 29, /**< LCD interrupt */ + PORTA_IRQn = 30, /**< PORTA Pin detect */ + PORTC_PORTD_IRQn = 31 /**< Single interrupt vector for PORTC; PORTD Pin detect */ +} IRQn_Type; + +/*! + * @} + */ /* end of group Interrupt_vector_numbers */ + + +/* ---------------------------------------------------------------------------- + -- Cortex M0 Core Configuration + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Cortex_Core_Configuration Cortex M0 Core Configuration + * @{ + */ + +#define __CM0PLUS_REV 0x0000 /**< Core revision r0p0 */ +#define __MPU_PRESENT 0 /**< Defines if an MPU is present or not */ +#define __VTOR_PRESENT 1 /**< Defines if an MPU is present or not */ +#define __NVIC_PRIO_BITS 2 /**< Number of priority bits implemented in the NVIC */ +#define __Vendor_SysTickConfig 0 /**< Vendor specific implementation of SysTickConfig is defined */ + +#include "core_cm0plus.h" /* Core Peripheral Access Layer */ +#include "system_MKL43Z4.h" /* Device specific configuration file */ + +/*! + * @} + */ /* end of group Cortex_Core_Configuration */ + + +/* ---------------------------------------------------------------------------- + -- Mapping Information + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Mapping_Information Mapping Information + * @{ + */ + +/** Mapping Information */ +/*! + * @addtogroup edma_request + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Structure for the DMA hardware request + * + * Defines the structure for the DMA hardware request collections. The user can configure the + * hardware request into DMAMUX to trigger the DMA transfer accordingly. The index + * of the hardware request varies according to the to SoC. + */ +typedef enum _dma_request_source +{ + kDmaRequestMux0Disable = 0|0x100U, /**< Disable */ + kDmaRequestMux0Reserved1 = 1|0x100U, /**< Reserved1 */ + kDmaRequestMux0LPUART0Rx = 2|0x100U, /**< LPUART0 Receive. */ + kDmaRequestMux0LPUART0Tx = 3|0x100U, /**< LPUART0 Transmit. */ + kDmaRequestMux0LPUART1Rx = 4|0x100U, /**< LPUART1 Receive. */ + kDmaRequestMux0LPUART1Tx = 5|0x100U, /**< LPUART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /**< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /**< UART2 Transmit. */ + kDmaRequestMux0Reserved8 = 8|0x100U, /**< Reserved8 */ + kDmaRequestMux0Reserved9 = 9|0x100U, /**< Reserved9 */ + kDmaRequestMux0FlexIOChannel0 = 10|0x100U, /**< FlexIO Channel 0. */ + kDmaRequestMux0FlexIOChannel1 = 11|0x100U, /**< FlexIO Channel 0. */ + kDmaRequestMux0FlexIOChannel2 = 12|0x100U, /**< FlexIO Channel 0. */ + kDmaRequestMux0FlexIOChannel3 = 13|0x100U, /**< FlexIO Channel 0. */ + kDmaRequestMux0I2S0Rx = 14|0x100U, /**< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 15|0x100U, /**< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 16|0x100U, /**< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 17|0x100U, /**< SPI0 Transmit. */ + kDmaRequestMux0SPI1Rx = 18|0x100U, /**< SPI1 Receive. */ + kDmaRequestMux0SPI1Tx = 19|0x100U, /**< SPI1 Transmit. */ + kDmaRequestMux0Reserved20 = 20|0x100U, /**< Reserved20 */ + kDmaRequestMux0Reserved21 = 21|0x100U, /**< Reserved21 */ + kDmaRequestMux0I2C0 = 22|0x100U, /**< I2C0. */ + kDmaRequestMux0I2C1 = 23|0x100U, /**< I2C1. */ + kDmaRequestMux0TPM0Channel0 = 24|0x100U, /**< TPM0 channel 0. */ + kDmaRequestMux0TPM0Channel1 = 25|0x100U, /**< TPM0 channel 1. */ + kDmaRequestMux0TPM0Channel2 = 26|0x100U, /**< TPM0 channel 2. */ + kDmaRequestMux0TPM0Channel3 = 27|0x100U, /**< TPM0 channel 3. */ + kDmaRequestMux0TPM0Channel4 = 28|0x100U, /**< TPM0 channel 4. */ + kDmaRequestMux0TPM0Channel5 = 29|0x100U, /**< TPM0 channel 5. */ + kDmaRequestMux0Reserved30 = 30|0x100U, /**< Reserved30 */ + kDmaRequestMux0Reserved31 = 31|0x100U, /**< Reserved31 */ + kDmaRequestMux0TPM1Channel0 = 32|0x100U, /**< TPM1 channel 0. */ + kDmaRequestMux0TPM1Channel1 = 33|0x100U, /**< TPM1 channel 1. */ + kDmaRequestMux0TPM2Channel0 = 34|0x100U, /**< TPM2 channel 0. */ + kDmaRequestMux0TPM2Channel1 = 35|0x100U, /**< TPM2 channel 1. */ + kDmaRequestMux0Reserved36 = 36|0x100U, /**< Reserved36 */ + kDmaRequestMux0Reserved37 = 37|0x100U, /**< Reserved37 */ + kDmaRequestMux0Reserved38 = 38|0x100U, /**< Reserved38 */ + kDmaRequestMux0Reserved39 = 39|0x100U, /**< Reserved39 */ + kDmaRequestMux0ADC0 = 40|0x100U, /**< ADC0. */ + kDmaRequestMux0Reserved41 = 41|0x100U, /**< Reserved41 */ + kDmaRequestMux0CMP0 = 42|0x100U, /**< CMP0. */ + kDmaRequestMux0Reserved43 = 43|0x100U, /**< Reserved43 */ + kDmaRequestMux0Reserved44 = 44|0x100U, /**< Reserved44 */ + kDmaRequestMux0DAC0 = 45|0x100U, /**< DAC0. */ + kDmaRequestMux0Reserved46 = 46|0x100U, /**< Reserved46 */ + kDmaRequestMux0Reserved47 = 47|0x100U, /**< Reserved47 */ + kDmaRequestMux0Reserved48 = 48|0x100U, /**< Reserved48 */ + kDmaRequestMux0PortA = 49|0x100U, /**< GPIO Port A. */ + kDmaRequestMux0Reserved50 = 50|0x100U, /**< Reserved50 */ + kDmaRequestMux0PortC = 51|0x100U, /**< GPIO Port C. */ + kDmaRequestMux0PortD = 52|0x100U, /**< GPIO Port D. */ + kDmaRequestMux0Reserved53 = 53|0x100U, /**< Reserved53 */ + kDmaRequestMux0TPM0Overflow = 54|0x100U, /**< TPM0 overflow. */ + kDmaRequestMux0TPM1Overflow = 55|0x100U, /**< TPM1 overflow. */ + kDmaRequestMux0TPM2Overflow = 56|0x100U, /**< TPM2 overflow. */ + kDmaRequestMux0Reserved57 = 57|0x100U, /**< Reserved57 */ + kDmaRequestMux0Reserved58 = 58|0x100U, /**< Reserved58 */ + kDmaRequestMux0Reserved59 = 59|0x100U, /**< Reserved59 */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /**< Always enabled. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /**< Always enabled. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /**< Always enabled. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /**< Always enabled. */ +} dma_request_source_t; + +/* @} */ + + +/*! + * @} + */ /* end of group Mapping_Information */ + + +/* ---------------------------------------------------------------------------- + -- Device Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Peripheral_access_layer Device Peripheral Access Layer + * @{ + */ + + +/* +** Start of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #pragma push + #pragma anon_unions +#elif defined(__CWCC__) + #pragma push + #pragma cpp_extensions on +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=extended +#else + #error Not supported compiler type +#endif + +/* ---------------------------------------------------------------------------- + -- ADC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer + * @{ + */ + +/** ADC - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC1[2]; /**< ADC Status and Control Registers 1, array offset: 0x0, array step: 0x4 */ + __IO uint32_t CFG1; /**< ADC Configuration Register 1, offset: 0x8 */ + __IO uint32_t CFG2; /**< ADC Configuration Register 2, offset: 0xC */ + __I uint32_t R[2]; /**< ADC Data Result Register, array offset: 0x10, array step: 0x4 */ + __IO uint32_t CV1; /**< Compare Value Registers, offset: 0x18 */ + __IO uint32_t CV2; /**< Compare Value Registers, offset: 0x1C */ + __IO uint32_t SC2; /**< Status and Control Register 2, offset: 0x20 */ + __IO uint32_t SC3; /**< Status and Control Register 3, offset: 0x24 */ + __IO uint32_t OFS; /**< ADC Offset Correction Register, offset: 0x28 */ + __IO uint32_t PG; /**< ADC Plus-Side Gain Register, offset: 0x2C */ + __IO uint32_t MG; /**< ADC Minus-Side Gain Register, offset: 0x30 */ + __IO uint32_t CLPD; /**< ADC Plus-Side General Calibration Value Register, offset: 0x34 */ + __IO uint32_t CLPS; /**< ADC Plus-Side General Calibration Value Register, offset: 0x38 */ + __IO uint32_t CLP4; /**< ADC Plus-Side General Calibration Value Register, offset: 0x3C */ + __IO uint32_t CLP3; /**< ADC Plus-Side General Calibration Value Register, offset: 0x40 */ + __IO uint32_t CLP2; /**< ADC Plus-Side General Calibration Value Register, offset: 0x44 */ + __IO uint32_t CLP1; /**< ADC Plus-Side General Calibration Value Register, offset: 0x48 */ + __IO uint32_t CLP0; /**< ADC Plus-Side General Calibration Value Register, offset: 0x4C */ + uint8_t RESERVED_0[4]; + __IO uint32_t CLMD; /**< ADC Minus-Side General Calibration Value Register, offset: 0x54 */ + __IO uint32_t CLMS; /**< ADC Minus-Side General Calibration Value Register, offset: 0x58 */ + __IO uint32_t CLM4; /**< ADC Minus-Side General Calibration Value Register, offset: 0x5C */ + __IO uint32_t CLM3; /**< ADC Minus-Side General Calibration Value Register, offset: 0x60 */ + __IO uint32_t CLM2; /**< ADC Minus-Side General Calibration Value Register, offset: 0x64 */ + __IO uint32_t CLM1; /**< ADC Minus-Side General Calibration Value Register, offset: 0x68 */ + __IO uint32_t CLM0; /**< ADC Minus-Side General Calibration Value Register, offset: 0x6C */ +} ADC_Type; + +/* ---------------------------------------------------------------------------- + -- ADC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Register_Masks ADC Register Masks + * @{ + */ + +/*! @name SC1 - ADC Status and Control Registers 1 */ +#define ADC_SC1_ADCH_MASK (0x1FU) +#define ADC_SC1_ADCH_SHIFT (0U) +#define ADC_SC1_ADCH(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_ADCH_SHIFT)) & ADC_SC1_ADCH_MASK) +#define ADC_SC1_DIFF_MASK (0x20U) +#define ADC_SC1_DIFF_SHIFT (5U) +#define ADC_SC1_DIFF(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_DIFF_SHIFT)) & ADC_SC1_DIFF_MASK) +#define ADC_SC1_AIEN_MASK (0x40U) +#define ADC_SC1_AIEN_SHIFT (6U) +#define ADC_SC1_AIEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_AIEN_SHIFT)) & ADC_SC1_AIEN_MASK) +#define ADC_SC1_COCO_MASK (0x80U) +#define ADC_SC1_COCO_SHIFT (7U) +#define ADC_SC1_COCO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_COCO_SHIFT)) & ADC_SC1_COCO_MASK) + +/* The count of ADC_SC1 */ +#define ADC_SC1_COUNT (2U) + +/*! @name CFG1 - ADC Configuration Register 1 */ +#define ADC_CFG1_ADICLK_MASK (0x3U) +#define ADC_CFG1_ADICLK_SHIFT (0U) +#define ADC_CFG1_ADICLK(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADICLK_SHIFT)) & ADC_CFG1_ADICLK_MASK) +#define ADC_CFG1_MODE_MASK (0xCU) +#define ADC_CFG1_MODE_SHIFT (2U) +#define ADC_CFG1_MODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_MODE_SHIFT)) & ADC_CFG1_MODE_MASK) +#define ADC_CFG1_ADLSMP_MASK (0x10U) +#define ADC_CFG1_ADLSMP_SHIFT (4U) +#define ADC_CFG1_ADLSMP(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADLSMP_SHIFT)) & ADC_CFG1_ADLSMP_MASK) +#define ADC_CFG1_ADIV_MASK (0x60U) +#define ADC_CFG1_ADIV_SHIFT (5U) +#define ADC_CFG1_ADIV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADIV_SHIFT)) & ADC_CFG1_ADIV_MASK) +#define ADC_CFG1_ADLPC_MASK (0x80U) +#define ADC_CFG1_ADLPC_SHIFT (7U) +#define ADC_CFG1_ADLPC(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADLPC_SHIFT)) & ADC_CFG1_ADLPC_MASK) + +/*! @name CFG2 - ADC Configuration Register 2 */ +#define ADC_CFG2_ADLSTS_MASK (0x3U) +#define ADC_CFG2_ADLSTS_SHIFT (0U) +#define ADC_CFG2_ADLSTS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADLSTS_SHIFT)) & ADC_CFG2_ADLSTS_MASK) +#define ADC_CFG2_ADHSC_MASK (0x4U) +#define ADC_CFG2_ADHSC_SHIFT (2U) +#define ADC_CFG2_ADHSC(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADHSC_SHIFT)) & ADC_CFG2_ADHSC_MASK) +#define ADC_CFG2_ADACKEN_MASK (0x8U) +#define ADC_CFG2_ADACKEN_SHIFT (3U) +#define ADC_CFG2_ADACKEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADACKEN_SHIFT)) & ADC_CFG2_ADACKEN_MASK) +#define ADC_CFG2_MUXSEL_MASK (0x10U) +#define ADC_CFG2_MUXSEL_SHIFT (4U) +#define ADC_CFG2_MUXSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_MUXSEL_SHIFT)) & ADC_CFG2_MUXSEL_MASK) + +/*! @name R - ADC Data Result Register */ +#define ADC_R_D_MASK (0xFFFFU) +#define ADC_R_D_SHIFT (0U) +#define ADC_R_D(x) (((uint32_t)(((uint32_t)(x)) << ADC_R_D_SHIFT)) & ADC_R_D_MASK) + +/* The count of ADC_R */ +#define ADC_R_COUNT (2U) + +/*! @name CV1 - Compare Value Registers */ +#define ADC_CV1_CV_MASK (0xFFFFU) +#define ADC_CV1_CV_SHIFT (0U) +#define ADC_CV1_CV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CV1_CV_SHIFT)) & ADC_CV1_CV_MASK) + +/*! @name CV2 - Compare Value Registers */ +#define ADC_CV2_CV_MASK (0xFFFFU) +#define ADC_CV2_CV_SHIFT (0U) +#define ADC_CV2_CV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CV2_CV_SHIFT)) & ADC_CV2_CV_MASK) + +/*! @name SC2 - Status and Control Register 2 */ +#define ADC_SC2_REFSEL_MASK (0x3U) +#define ADC_SC2_REFSEL_SHIFT (0U) +#define ADC_SC2_REFSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_REFSEL_SHIFT)) & ADC_SC2_REFSEL_MASK) +#define ADC_SC2_DMAEN_MASK (0x4U) +#define ADC_SC2_DMAEN_SHIFT (2U) +#define ADC_SC2_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_DMAEN_SHIFT)) & ADC_SC2_DMAEN_MASK) +#define ADC_SC2_ACREN_MASK (0x8U) +#define ADC_SC2_ACREN_SHIFT (3U) +#define ADC_SC2_ACREN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACREN_SHIFT)) & ADC_SC2_ACREN_MASK) +#define ADC_SC2_ACFGT_MASK (0x10U) +#define ADC_SC2_ACFGT_SHIFT (4U) +#define ADC_SC2_ACFGT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACFGT_SHIFT)) & ADC_SC2_ACFGT_MASK) +#define ADC_SC2_ACFE_MASK (0x20U) +#define ADC_SC2_ACFE_SHIFT (5U) +#define ADC_SC2_ACFE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACFE_SHIFT)) & ADC_SC2_ACFE_MASK) +#define ADC_SC2_ADTRG_MASK (0x40U) +#define ADC_SC2_ADTRG_SHIFT (6U) +#define ADC_SC2_ADTRG(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ADTRG_SHIFT)) & ADC_SC2_ADTRG_MASK) +#define ADC_SC2_ADACT_MASK (0x80U) +#define ADC_SC2_ADACT_SHIFT (7U) +#define ADC_SC2_ADACT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ADACT_SHIFT)) & ADC_SC2_ADACT_MASK) + +/*! @name SC3 - Status and Control Register 3 */ +#define ADC_SC3_AVGS_MASK (0x3U) +#define ADC_SC3_AVGS_SHIFT (0U) +#define ADC_SC3_AVGS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_AVGS_SHIFT)) & ADC_SC3_AVGS_MASK) +#define ADC_SC3_AVGE_MASK (0x4U) +#define ADC_SC3_AVGE_SHIFT (2U) +#define ADC_SC3_AVGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_AVGE_SHIFT)) & ADC_SC3_AVGE_MASK) +#define ADC_SC3_ADCO_MASK (0x8U) +#define ADC_SC3_ADCO_SHIFT (3U) +#define ADC_SC3_ADCO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_ADCO_SHIFT)) & ADC_SC3_ADCO_MASK) +#define ADC_SC3_CALF_MASK (0x40U) +#define ADC_SC3_CALF_SHIFT (6U) +#define ADC_SC3_CALF(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_CALF_SHIFT)) & ADC_SC3_CALF_MASK) +#define ADC_SC3_CAL_MASK (0x80U) +#define ADC_SC3_CAL_SHIFT (7U) +#define ADC_SC3_CAL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_CAL_SHIFT)) & ADC_SC3_CAL_MASK) + +/*! @name OFS - ADC Offset Correction Register */ +#define ADC_OFS_OFS_MASK (0xFFFFU) +#define ADC_OFS_OFS_SHIFT (0U) +#define ADC_OFS_OFS(x) (((uint32_t)(((uint32_t)(x)) << ADC_OFS_OFS_SHIFT)) & ADC_OFS_OFS_MASK) + +/*! @name PG - ADC Plus-Side Gain Register */ +#define ADC_PG_PG_MASK (0xFFFFU) +#define ADC_PG_PG_SHIFT (0U) +#define ADC_PG_PG(x) (((uint32_t)(((uint32_t)(x)) << ADC_PG_PG_SHIFT)) & ADC_PG_PG_MASK) + +/*! @name MG - ADC Minus-Side Gain Register */ +#define ADC_MG_MG_MASK (0xFFFFU) +#define ADC_MG_MG_SHIFT (0U) +#define ADC_MG_MG(x) (((uint32_t)(((uint32_t)(x)) << ADC_MG_MG_SHIFT)) & ADC_MG_MG_MASK) + +/*! @name CLPD - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLPD_CLPD_MASK (0x3FU) +#define ADC_CLPD_CLPD_SHIFT (0U) +#define ADC_CLPD_CLPD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLPD_CLPD_SHIFT)) & ADC_CLPD_CLPD_MASK) + +/*! @name CLPS - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLPS_CLPS_MASK (0x3FU) +#define ADC_CLPS_CLPS_SHIFT (0U) +#define ADC_CLPS_CLPS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLPS_CLPS_SHIFT)) & ADC_CLPS_CLPS_MASK) + +/*! @name CLP4 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP4_CLP4_MASK (0x3FFU) +#define ADC_CLP4_CLP4_SHIFT (0U) +#define ADC_CLP4_CLP4(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP4_CLP4_SHIFT)) & ADC_CLP4_CLP4_MASK) + +/*! @name CLP3 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP3_CLP3_MASK (0x1FFU) +#define ADC_CLP3_CLP3_SHIFT (0U) +#define ADC_CLP3_CLP3(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP3_CLP3_SHIFT)) & ADC_CLP3_CLP3_MASK) + +/*! @name CLP2 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP2_CLP2_MASK (0xFFU) +#define ADC_CLP2_CLP2_SHIFT (0U) +#define ADC_CLP2_CLP2(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP2_CLP2_SHIFT)) & ADC_CLP2_CLP2_MASK) + +/*! @name CLP1 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP1_CLP1_MASK (0x7FU) +#define ADC_CLP1_CLP1_SHIFT (0U) +#define ADC_CLP1_CLP1(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP1_CLP1_SHIFT)) & ADC_CLP1_CLP1_MASK) + +/*! @name CLP0 - ADC Plus-Side General Calibration Value Register */ +#define ADC_CLP0_CLP0_MASK (0x3FU) +#define ADC_CLP0_CLP0_SHIFT (0U) +#define ADC_CLP0_CLP0(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP0_CLP0_SHIFT)) & ADC_CLP0_CLP0_MASK) + +/*! @name CLMD - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLMD_CLMD_MASK (0x3FU) +#define ADC_CLMD_CLMD_SHIFT (0U) +#define ADC_CLMD_CLMD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLMD_CLMD_SHIFT)) & ADC_CLMD_CLMD_MASK) + +/*! @name CLMS - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLMS_CLMS_MASK (0x3FU) +#define ADC_CLMS_CLMS_SHIFT (0U) +#define ADC_CLMS_CLMS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLMS_CLMS_SHIFT)) & ADC_CLMS_CLMS_MASK) + +/*! @name CLM4 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM4_CLM4_MASK (0x3FFU) +#define ADC_CLM4_CLM4_SHIFT (0U) +#define ADC_CLM4_CLM4(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM4_CLM4_SHIFT)) & ADC_CLM4_CLM4_MASK) + +/*! @name CLM3 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM3_CLM3_MASK (0x1FFU) +#define ADC_CLM3_CLM3_SHIFT (0U) +#define ADC_CLM3_CLM3(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM3_CLM3_SHIFT)) & ADC_CLM3_CLM3_MASK) + +/*! @name CLM2 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM2_CLM2_MASK (0xFFU) +#define ADC_CLM2_CLM2_SHIFT (0U) +#define ADC_CLM2_CLM2(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM2_CLM2_SHIFT)) & ADC_CLM2_CLM2_MASK) + +/*! @name CLM1 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM1_CLM1_MASK (0x7FU) +#define ADC_CLM1_CLM1_SHIFT (0U) +#define ADC_CLM1_CLM1(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM1_CLM1_SHIFT)) & ADC_CLM1_CLM1_MASK) + +/*! @name CLM0 - ADC Minus-Side General Calibration Value Register */ +#define ADC_CLM0_CLM0_MASK (0x3FU) +#define ADC_CLM0_CLM0_SHIFT (0U) +#define ADC_CLM0_CLM0(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM0_CLM0_SHIFT)) & ADC_CLM0_CLM0_MASK) + + +/*! + * @} + */ /* end of group ADC_Register_Masks */ + + +/* ADC - Peripheral instance base addresses */ +/** Peripheral ADC0 base address */ +#define ADC0_BASE (0x4003B000u) +/** Peripheral ADC0 base pointer */ +#define ADC0 ((ADC_Type *)ADC0_BASE) +/** Array initializer of ADC peripheral base addresses */ +#define ADC_BASE_ADDRS { ADC0_BASE } +/** Array initializer of ADC peripheral base pointers */ +#define ADC_BASE_PTRS { ADC0 } +/** Interrupt vectors for the ADC peripheral type */ +#define ADC_IRQS { ADC0_IRQn } + +/*! + * @} + */ /* end of group ADC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CMP Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMP_Peripheral_Access_Layer CMP Peripheral Access Layer + * @{ + */ + +/** CMP - Register Layout Typedef */ +typedef struct { + __IO uint8_t CR0; /**< CMP Control Register 0, offset: 0x0 */ + __IO uint8_t CR1; /**< CMP Control Register 1, offset: 0x1 */ + __IO uint8_t FPR; /**< CMP Filter Period Register, offset: 0x2 */ + __IO uint8_t SCR; /**< CMP Status and Control Register, offset: 0x3 */ + __IO uint8_t DACCR; /**< DAC Control Register, offset: 0x4 */ + __IO uint8_t MUXCR; /**< MUX Control Register, offset: 0x5 */ +} CMP_Type; + +/* ---------------------------------------------------------------------------- + -- CMP Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMP_Register_Masks CMP Register Masks + * @{ + */ + +/*! @name CR0 - CMP Control Register 0 */ +#define CMP_CR0_HYSTCTR_MASK (0x3U) +#define CMP_CR0_HYSTCTR_SHIFT (0U) +#define CMP_CR0_HYSTCTR(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR0_HYSTCTR_SHIFT)) & CMP_CR0_HYSTCTR_MASK) +#define CMP_CR0_FILTER_CNT_MASK (0x70U) +#define CMP_CR0_FILTER_CNT_SHIFT (4U) +#define CMP_CR0_FILTER_CNT(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR0_FILTER_CNT_SHIFT)) & CMP_CR0_FILTER_CNT_MASK) + +/*! @name CR1 - CMP Control Register 1 */ +#define CMP_CR1_EN_MASK (0x1U) +#define CMP_CR1_EN_SHIFT (0U) +#define CMP_CR1_EN(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_EN_SHIFT)) & CMP_CR1_EN_MASK) +#define CMP_CR1_OPE_MASK (0x2U) +#define CMP_CR1_OPE_SHIFT (1U) +#define CMP_CR1_OPE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_OPE_SHIFT)) & CMP_CR1_OPE_MASK) +#define CMP_CR1_COS_MASK (0x4U) +#define CMP_CR1_COS_SHIFT (2U) +#define CMP_CR1_COS(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_COS_SHIFT)) & CMP_CR1_COS_MASK) +#define CMP_CR1_INV_MASK (0x8U) +#define CMP_CR1_INV_SHIFT (3U) +#define CMP_CR1_INV(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_INV_SHIFT)) & CMP_CR1_INV_MASK) +#define CMP_CR1_PMODE_MASK (0x10U) +#define CMP_CR1_PMODE_SHIFT (4U) +#define CMP_CR1_PMODE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_PMODE_SHIFT)) & CMP_CR1_PMODE_MASK) +#define CMP_CR1_TRIGM_MASK (0x20U) +#define CMP_CR1_TRIGM_SHIFT (5U) +#define CMP_CR1_TRIGM(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_TRIGM_SHIFT)) & CMP_CR1_TRIGM_MASK) +#define CMP_CR1_WE_MASK (0x40U) +#define CMP_CR1_WE_SHIFT (6U) +#define CMP_CR1_WE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_WE_SHIFT)) & CMP_CR1_WE_MASK) +#define CMP_CR1_SE_MASK (0x80U) +#define CMP_CR1_SE_SHIFT (7U) +#define CMP_CR1_SE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_SE_SHIFT)) & CMP_CR1_SE_MASK) + +/*! @name FPR - CMP Filter Period Register */ +#define CMP_FPR_FILT_PER_MASK (0xFFU) +#define CMP_FPR_FILT_PER_SHIFT (0U) +#define CMP_FPR_FILT_PER(x) (((uint8_t)(((uint8_t)(x)) << CMP_FPR_FILT_PER_SHIFT)) & CMP_FPR_FILT_PER_MASK) + +/*! @name SCR - CMP Status and Control Register */ +#define CMP_SCR_COUT_MASK (0x1U) +#define CMP_SCR_COUT_SHIFT (0U) +#define CMP_SCR_COUT(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_COUT_SHIFT)) & CMP_SCR_COUT_MASK) +#define CMP_SCR_CFF_MASK (0x2U) +#define CMP_SCR_CFF_SHIFT (1U) +#define CMP_SCR_CFF(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_CFF_SHIFT)) & CMP_SCR_CFF_MASK) +#define CMP_SCR_CFR_MASK (0x4U) +#define CMP_SCR_CFR_SHIFT (2U) +#define CMP_SCR_CFR(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_CFR_SHIFT)) & CMP_SCR_CFR_MASK) +#define CMP_SCR_IEF_MASK (0x8U) +#define CMP_SCR_IEF_SHIFT (3U) +#define CMP_SCR_IEF(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_IEF_SHIFT)) & CMP_SCR_IEF_MASK) +#define CMP_SCR_IER_MASK (0x10U) +#define CMP_SCR_IER_SHIFT (4U) +#define CMP_SCR_IER(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_IER_SHIFT)) & CMP_SCR_IER_MASK) +#define CMP_SCR_DMAEN_MASK (0x40U) +#define CMP_SCR_DMAEN_SHIFT (6U) +#define CMP_SCR_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_DMAEN_SHIFT)) & CMP_SCR_DMAEN_MASK) + +/*! @name DACCR - DAC Control Register */ +#define CMP_DACCR_VOSEL_MASK (0x3FU) +#define CMP_DACCR_VOSEL_SHIFT (0U) +#define CMP_DACCR_VOSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_VOSEL_SHIFT)) & CMP_DACCR_VOSEL_MASK) +#define CMP_DACCR_VRSEL_MASK (0x40U) +#define CMP_DACCR_VRSEL_SHIFT (6U) +#define CMP_DACCR_VRSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_VRSEL_SHIFT)) & CMP_DACCR_VRSEL_MASK) +#define CMP_DACCR_DACEN_MASK (0x80U) +#define CMP_DACCR_DACEN_SHIFT (7U) +#define CMP_DACCR_DACEN(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_DACEN_SHIFT)) & CMP_DACCR_DACEN_MASK) + +/*! @name MUXCR - MUX Control Register */ +#define CMP_MUXCR_MSEL_MASK (0x7U) +#define CMP_MUXCR_MSEL_SHIFT (0U) +#define CMP_MUXCR_MSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_MUXCR_MSEL_SHIFT)) & CMP_MUXCR_MSEL_MASK) +#define CMP_MUXCR_PSEL_MASK (0x38U) +#define CMP_MUXCR_PSEL_SHIFT (3U) +#define CMP_MUXCR_PSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_MUXCR_PSEL_SHIFT)) & CMP_MUXCR_PSEL_MASK) +#define CMP_MUXCR_PSTM_MASK (0x80U) +#define CMP_MUXCR_PSTM_SHIFT (7U) +#define CMP_MUXCR_PSTM(x) (((uint8_t)(((uint8_t)(x)) << CMP_MUXCR_PSTM_SHIFT)) & CMP_MUXCR_PSTM_MASK) + + +/*! + * @} + */ /* end of group CMP_Register_Masks */ + + +/* CMP - Peripheral instance base addresses */ +/** Peripheral CMP0 base address */ +#define CMP0_BASE (0x40073000u) +/** Peripheral CMP0 base pointer */ +#define CMP0 ((CMP_Type *)CMP0_BASE) +/** Array initializer of CMP peripheral base addresses */ +#define CMP_BASE_ADDRS { CMP0_BASE } +/** Array initializer of CMP peripheral base pointers */ +#define CMP_BASE_PTRS { CMP0 } +/** Interrupt vectors for the CMP peripheral type */ +#define CMP_IRQS { CMP0_IRQn } + +/*! + * @} + */ /* end of group CMP_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DAC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DAC_Peripheral_Access_Layer DAC Peripheral Access Layer + * @{ + */ + +/** DAC - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x2 */ + __IO uint8_t DATL; /**< DAC Data Low Register, array offset: 0x0, array step: 0x2 */ + __IO uint8_t DATH; /**< DAC Data High Register, array offset: 0x1, array step: 0x2 */ + } DAT[2]; + uint8_t RESERVED_0[28]; + __IO uint8_t SR; /**< DAC Status Register, offset: 0x20 */ + __IO uint8_t C0; /**< DAC Control Register, offset: 0x21 */ + __IO uint8_t C1; /**< DAC Control Register 1, offset: 0x22 */ + __IO uint8_t C2; /**< DAC Control Register 2, offset: 0x23 */ +} DAC_Type; + +/* ---------------------------------------------------------------------------- + -- DAC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DAC_Register_Masks DAC Register Masks + * @{ + */ + +/*! @name DATL - DAC Data Low Register */ +#define DAC_DATL_DATA0_MASK (0xFFU) +#define DAC_DATL_DATA0_SHIFT (0U) +#define DAC_DATL_DATA0(x) (((uint8_t)(((uint8_t)(x)) << DAC_DATL_DATA0_SHIFT)) & DAC_DATL_DATA0_MASK) + +/* The count of DAC_DATL */ +#define DAC_DATL_COUNT (2U) + +/*! @name DATH - DAC Data High Register */ +#define DAC_DATH_DATA1_MASK (0xFU) +#define DAC_DATH_DATA1_SHIFT (0U) +#define DAC_DATH_DATA1(x) (((uint8_t)(((uint8_t)(x)) << DAC_DATH_DATA1_SHIFT)) & DAC_DATH_DATA1_MASK) + +/* The count of DAC_DATH */ +#define DAC_DATH_COUNT (2U) + +/*! @name SR - DAC Status Register */ +#define DAC_SR_DACBFRPBF_MASK (0x1U) +#define DAC_SR_DACBFRPBF_SHIFT (0U) +#define DAC_SR_DACBFRPBF(x) (((uint8_t)(((uint8_t)(x)) << DAC_SR_DACBFRPBF_SHIFT)) & DAC_SR_DACBFRPBF_MASK) +#define DAC_SR_DACBFRPTF_MASK (0x2U) +#define DAC_SR_DACBFRPTF_SHIFT (1U) +#define DAC_SR_DACBFRPTF(x) (((uint8_t)(((uint8_t)(x)) << DAC_SR_DACBFRPTF_SHIFT)) & DAC_SR_DACBFRPTF_MASK) + +/*! @name C0 - DAC Control Register */ +#define DAC_C0_DACBBIEN_MASK (0x1U) +#define DAC_C0_DACBBIEN_SHIFT (0U) +#define DAC_C0_DACBBIEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACBBIEN_SHIFT)) & DAC_C0_DACBBIEN_MASK) +#define DAC_C0_DACBTIEN_MASK (0x2U) +#define DAC_C0_DACBTIEN_SHIFT (1U) +#define DAC_C0_DACBTIEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACBTIEN_SHIFT)) & DAC_C0_DACBTIEN_MASK) +#define DAC_C0_LPEN_MASK (0x8U) +#define DAC_C0_LPEN_SHIFT (3U) +#define DAC_C0_LPEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_LPEN_SHIFT)) & DAC_C0_LPEN_MASK) +#define DAC_C0_DACSWTRG_MASK (0x10U) +#define DAC_C0_DACSWTRG_SHIFT (4U) +#define DAC_C0_DACSWTRG(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACSWTRG_SHIFT)) & DAC_C0_DACSWTRG_MASK) +#define DAC_C0_DACTRGSEL_MASK (0x20U) +#define DAC_C0_DACTRGSEL_SHIFT (5U) +#define DAC_C0_DACTRGSEL(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACTRGSEL_SHIFT)) & DAC_C0_DACTRGSEL_MASK) +#define DAC_C0_DACRFS_MASK (0x40U) +#define DAC_C0_DACRFS_SHIFT (6U) +#define DAC_C0_DACRFS(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACRFS_SHIFT)) & DAC_C0_DACRFS_MASK) +#define DAC_C0_DACEN_MASK (0x80U) +#define DAC_C0_DACEN_SHIFT (7U) +#define DAC_C0_DACEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACEN_SHIFT)) & DAC_C0_DACEN_MASK) + +/*! @name C1 - DAC Control Register 1 */ +#define DAC_C1_DACBFEN_MASK (0x1U) +#define DAC_C1_DACBFEN_SHIFT (0U) +#define DAC_C1_DACBFEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DACBFEN_SHIFT)) & DAC_C1_DACBFEN_MASK) +#define DAC_C1_DACBFMD_MASK (0x6U) +#define DAC_C1_DACBFMD_SHIFT (1U) +#define DAC_C1_DACBFMD(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DACBFMD_SHIFT)) & DAC_C1_DACBFMD_MASK) +#define DAC_C1_DMAEN_MASK (0x80U) +#define DAC_C1_DMAEN_SHIFT (7U) +#define DAC_C1_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DMAEN_SHIFT)) & DAC_C1_DMAEN_MASK) + +/*! @name C2 - DAC Control Register 2 */ +#define DAC_C2_DACBFUP_MASK (0x1U) +#define DAC_C2_DACBFUP_SHIFT (0U) +#define DAC_C2_DACBFUP(x) (((uint8_t)(((uint8_t)(x)) << DAC_C2_DACBFUP_SHIFT)) & DAC_C2_DACBFUP_MASK) +#define DAC_C2_DACBFRP_MASK (0x10U) +#define DAC_C2_DACBFRP_SHIFT (4U) +#define DAC_C2_DACBFRP(x) (((uint8_t)(((uint8_t)(x)) << DAC_C2_DACBFRP_SHIFT)) & DAC_C2_DACBFRP_MASK) + + +/*! + * @} + */ /* end of group DAC_Register_Masks */ + + +/* DAC - Peripheral instance base addresses */ +/** Peripheral DAC0 base address */ +#define DAC0_BASE (0x4003F000u) +/** Peripheral DAC0 base pointer */ +#define DAC0 ((DAC_Type *)DAC0_BASE) +/** Array initializer of DAC peripheral base addresses */ +#define DAC_BASE_ADDRS { DAC0_BASE } +/** Array initializer of DAC peripheral base pointers */ +#define DAC_BASE_PTRS { DAC0 } +/** Interrupt vectors for the DAC peripheral type */ +#define DAC_IRQS { DAC0_IRQn } + +/*! + * @} + */ /* end of group DAC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMA Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Peripheral_Access_Layer DMA Peripheral Access Layer + * @{ + */ + +/** DMA - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[256]; + struct { /* offset: 0x100, array step: 0x10 */ + __IO uint32_t SAR; /**< Source Address Register, array offset: 0x100, array step: 0x10 */ + __IO uint32_t DAR; /**< Destination Address Register, array offset: 0x104, array step: 0x10 */ + union { /* offset: 0x108, array step: 0x10 */ + __IO uint32_t DSR_BCR; /**< DMA Status Register / Byte Count Register, array offset: 0x108, array step: 0x10 */ + struct { /* offset: 0x108, array step: 0x10 */ + uint8_t RESERVED_0[3]; + __IO uint8_t DSR; /**< DMA_DSR0 register...DMA_DSR3 register., array offset: 0x10B, array step: 0x10 */ + } DMA_DSR_ACCESS8BIT; + }; + __IO uint32_t DCR; /**< DMA Control Register, array offset: 0x10C, array step: 0x10 */ + } DMA[4]; +} DMA_Type; + +/* ---------------------------------------------------------------------------- + -- DMA Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Register_Masks DMA Register Masks + * @{ + */ + +/*! @name SAR - Source Address Register */ +#define DMA_SAR_SAR_MASK (0xFFFFFFFFU) +#define DMA_SAR_SAR_SHIFT (0U) +#define DMA_SAR_SAR(x) (((uint32_t)(((uint32_t)(x)) << DMA_SAR_SAR_SHIFT)) & DMA_SAR_SAR_MASK) + +/* The count of DMA_SAR */ +#define DMA_SAR_COUNT (4U) + +/*! @name DAR - Destination Address Register */ +#define DMA_DAR_DAR_MASK (0xFFFFFFFFU) +#define DMA_DAR_DAR_SHIFT (0U) +#define DMA_DAR_DAR(x) (((uint32_t)(((uint32_t)(x)) << DMA_DAR_DAR_SHIFT)) & DMA_DAR_DAR_MASK) + +/* The count of DMA_DAR */ +#define DMA_DAR_COUNT (4U) + +/*! @name DSR_BCR - DMA Status Register / Byte Count Register */ +#define DMA_DSR_BCR_BCR_MASK (0xFFFFFFU) +#define DMA_DSR_BCR_BCR_SHIFT (0U) +#define DMA_DSR_BCR_BCR(x) (((uint32_t)(((uint32_t)(x)) << DMA_DSR_BCR_BCR_SHIFT)) & DMA_DSR_BCR_BCR_MASK) +#define DMA_DSR_BCR_DONE_MASK (0x1000000U) +#define DMA_DSR_BCR_DONE_SHIFT (24U) +#define DMA_DSR_BCR_DONE(x) (((uint32_t)(((uint32_t)(x)) << DMA_DSR_BCR_DONE_SHIFT)) & DMA_DSR_BCR_DONE_MASK) +#define DMA_DSR_BCR_BSY_MASK (0x2000000U) +#define DMA_DSR_BCR_BSY_SHIFT (25U) +#define DMA_DSR_BCR_BSY(x) (((uint32_t)(((uint32_t)(x)) << DMA_DSR_BCR_BSY_SHIFT)) & DMA_DSR_BCR_BSY_MASK) +#define DMA_DSR_BCR_REQ_MASK (0x4000000U) +#define DMA_DSR_BCR_REQ_SHIFT (26U) +#define DMA_DSR_BCR_REQ(x) (((uint32_t)(((uint32_t)(x)) << DMA_DSR_BCR_REQ_SHIFT)) & DMA_DSR_BCR_REQ_MASK) +#define DMA_DSR_BCR_BED_MASK (0x10000000U) +#define DMA_DSR_BCR_BED_SHIFT (28U) +#define DMA_DSR_BCR_BED(x) (((uint32_t)(((uint32_t)(x)) << DMA_DSR_BCR_BED_SHIFT)) & DMA_DSR_BCR_BED_MASK) +#define DMA_DSR_BCR_BES_MASK (0x20000000U) +#define DMA_DSR_BCR_BES_SHIFT (29U) +#define DMA_DSR_BCR_BES(x) (((uint32_t)(((uint32_t)(x)) << DMA_DSR_BCR_BES_SHIFT)) & DMA_DSR_BCR_BES_MASK) +#define DMA_DSR_BCR_CE_MASK (0x40000000U) +#define DMA_DSR_BCR_CE_SHIFT (30U) +#define DMA_DSR_BCR_CE(x) (((uint32_t)(((uint32_t)(x)) << DMA_DSR_BCR_CE_SHIFT)) & DMA_DSR_BCR_CE_MASK) + +/* The count of DMA_DSR_BCR */ +#define DMA_DSR_BCR_COUNT (4U) + +/* The count of DMA_DSR */ +#define DMA_DSR_COUNT (4U) + +/*! @name DCR - DMA Control Register */ +#define DMA_DCR_LCH2_MASK (0x3U) +#define DMA_DCR_LCH2_SHIFT (0U) +#define DMA_DCR_LCH2(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_LCH2_SHIFT)) & DMA_DCR_LCH2_MASK) +#define DMA_DCR_LCH1_MASK (0xCU) +#define DMA_DCR_LCH1_SHIFT (2U) +#define DMA_DCR_LCH1(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_LCH1_SHIFT)) & DMA_DCR_LCH1_MASK) +#define DMA_DCR_LINKCC_MASK (0x30U) +#define DMA_DCR_LINKCC_SHIFT (4U) +#define DMA_DCR_LINKCC(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_LINKCC_SHIFT)) & DMA_DCR_LINKCC_MASK) +#define DMA_DCR_D_REQ_MASK (0x80U) +#define DMA_DCR_D_REQ_SHIFT (7U) +#define DMA_DCR_D_REQ(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_D_REQ_SHIFT)) & DMA_DCR_D_REQ_MASK) +#define DMA_DCR_DMOD_MASK (0xF00U) +#define DMA_DCR_DMOD_SHIFT (8U) +#define DMA_DCR_DMOD(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_DMOD_SHIFT)) & DMA_DCR_DMOD_MASK) +#define DMA_DCR_SMOD_MASK (0xF000U) +#define DMA_DCR_SMOD_SHIFT (12U) +#define DMA_DCR_SMOD(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_SMOD_SHIFT)) & DMA_DCR_SMOD_MASK) +#define DMA_DCR_START_MASK (0x10000U) +#define DMA_DCR_START_SHIFT (16U) +#define DMA_DCR_START(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_START_SHIFT)) & DMA_DCR_START_MASK) +#define DMA_DCR_DSIZE_MASK (0x60000U) +#define DMA_DCR_DSIZE_SHIFT (17U) +#define DMA_DCR_DSIZE(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_DSIZE_SHIFT)) & DMA_DCR_DSIZE_MASK) +#define DMA_DCR_DINC_MASK (0x80000U) +#define DMA_DCR_DINC_SHIFT (19U) +#define DMA_DCR_DINC(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_DINC_SHIFT)) & DMA_DCR_DINC_MASK) +#define DMA_DCR_SSIZE_MASK (0x300000U) +#define DMA_DCR_SSIZE_SHIFT (20U) +#define DMA_DCR_SSIZE(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_SSIZE_SHIFT)) & DMA_DCR_SSIZE_MASK) +#define DMA_DCR_SINC_MASK (0x400000U) +#define DMA_DCR_SINC_SHIFT (22U) +#define DMA_DCR_SINC(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_SINC_SHIFT)) & DMA_DCR_SINC_MASK) +#define DMA_DCR_EADREQ_MASK (0x800000U) +#define DMA_DCR_EADREQ_SHIFT (23U) +#define DMA_DCR_EADREQ(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_EADREQ_SHIFT)) & DMA_DCR_EADREQ_MASK) +#define DMA_DCR_AA_MASK (0x10000000U) +#define DMA_DCR_AA_SHIFT (28U) +#define DMA_DCR_AA(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_AA_SHIFT)) & DMA_DCR_AA_MASK) +#define DMA_DCR_CS_MASK (0x20000000U) +#define DMA_DCR_CS_SHIFT (29U) +#define DMA_DCR_CS(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_CS_SHIFT)) & DMA_DCR_CS_MASK) +#define DMA_DCR_ERQ_MASK (0x40000000U) +#define DMA_DCR_ERQ_SHIFT (30U) +#define DMA_DCR_ERQ(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_ERQ_SHIFT)) & DMA_DCR_ERQ_MASK) +#define DMA_DCR_EINT_MASK (0x80000000U) +#define DMA_DCR_EINT_SHIFT (31U) +#define DMA_DCR_EINT(x) (((uint32_t)(((uint32_t)(x)) << DMA_DCR_EINT_SHIFT)) & DMA_DCR_EINT_MASK) + +/* The count of DMA_DCR */ +#define DMA_DCR_COUNT (4U) + + +/*! + * @} + */ /* end of group DMA_Register_Masks */ + + +/* DMA - Peripheral instance base addresses */ +/** Peripheral DMA base address */ +#define DMA_BASE (0x40008000u) +/** Peripheral DMA base pointer */ +#define DMA0 ((DMA_Type *)DMA_BASE) +/** Array initializer of DMA peripheral base addresses */ +#define DMA_BASE_ADDRS { DMA_BASE } +/** Array initializer of DMA peripheral base pointers */ +#define DMA_BASE_PTRS { DMA0 } +/** Interrupt vectors for the DMA peripheral type */ +#define DMA_CHN_IRQS { DMA0_IRQn, DMA1_IRQn, DMA2_IRQn, DMA3_IRQn } + +/*! + * @} + */ /* end of group DMA_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMAMUX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMAMUX_Peripheral_Access_Layer DMAMUX Peripheral Access Layer + * @{ + */ + +/** DMAMUX - Register Layout Typedef */ +typedef struct { + __IO uint8_t CHCFG[4]; /**< Channel Configuration register, array offset: 0x0, array step: 0x1 */ +} DMAMUX_Type; + +/* ---------------------------------------------------------------------------- + -- DMAMUX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMAMUX_Register_Masks DMAMUX Register Masks + * @{ + */ + +/*! @name CHCFG - Channel Configuration register */ +#define DMAMUX_CHCFG_SOURCE_MASK (0x3FU) +#define DMAMUX_CHCFG_SOURCE_SHIFT (0U) +#define DMAMUX_CHCFG_SOURCE(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_SOURCE_SHIFT)) & DMAMUX_CHCFG_SOURCE_MASK) +#define DMAMUX_CHCFG_TRIG_MASK (0x40U) +#define DMAMUX_CHCFG_TRIG_SHIFT (6U) +#define DMAMUX_CHCFG_TRIG(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_TRIG_SHIFT)) & DMAMUX_CHCFG_TRIG_MASK) +#define DMAMUX_CHCFG_ENBL_MASK (0x80U) +#define DMAMUX_CHCFG_ENBL_SHIFT (7U) +#define DMAMUX_CHCFG_ENBL(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_ENBL_SHIFT)) & DMAMUX_CHCFG_ENBL_MASK) + +/* The count of DMAMUX_CHCFG */ +#define DMAMUX_CHCFG_COUNT (4U) + + +/*! + * @} + */ /* end of group DMAMUX_Register_Masks */ + + +/* DMAMUX - Peripheral instance base addresses */ +/** Peripheral DMAMUX0 base address */ +#define DMAMUX0_BASE (0x40021000u) +/** Peripheral DMAMUX0 base pointer */ +#define DMAMUX0 ((DMAMUX_Type *)DMAMUX0_BASE) +/** Array initializer of DMAMUX peripheral base addresses */ +#define DMAMUX_BASE_ADDRS { DMAMUX0_BASE } +/** Array initializer of DMAMUX peripheral base pointers */ +#define DMAMUX_BASE_PTRS { DMAMUX0 } + +/*! + * @} + */ /* end of group DMAMUX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FLEXIO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FLEXIO_Peripheral_Access_Layer FLEXIO Peripheral Access Layer + * @{ + */ + +/** FLEXIO - Register Layout Typedef */ +typedef struct { + __I uint32_t VERID; /**< Version ID Register, offset: 0x0 */ + __I uint32_t PARAM; /**< Parameter Register, offset: 0x4 */ + __IO uint32_t CTRL; /**< FlexIO Control Register, offset: 0x8 */ + uint8_t RESERVED_0[4]; + __IO uint32_t SHIFTSTAT; /**< Shifter Status Register, offset: 0x10 */ + __IO uint32_t SHIFTERR; /**< Shifter Error Register, offset: 0x14 */ + __IO uint32_t TIMSTAT; /**< Timer Status Register, offset: 0x18 */ + uint8_t RESERVED_1[4]; + __IO uint32_t SHIFTSIEN; /**< Shifter Status Interrupt Enable, offset: 0x20 */ + __IO uint32_t SHIFTEIEN; /**< Shifter Error Interrupt Enable, offset: 0x24 */ + __IO uint32_t TIMIEN; /**< Timer Interrupt Enable Register, offset: 0x28 */ + uint8_t RESERVED_2[4]; + __IO uint32_t SHIFTSDEN; /**< Shifter Status DMA Enable, offset: 0x30 */ + uint8_t RESERVED_3[76]; + __IO uint32_t SHIFTCTL[4]; /**< Shifter Control N Register, array offset: 0x80, array step: 0x4 */ + uint8_t RESERVED_4[112]; + __IO uint32_t SHIFTCFG[4]; /**< Shifter Configuration N Register, array offset: 0x100, array step: 0x4 */ + uint8_t RESERVED_5[240]; + __IO uint32_t SHIFTBUF[4]; /**< Shifter Buffer N Register, array offset: 0x200, array step: 0x4 */ + uint8_t RESERVED_6[112]; + __IO uint32_t SHIFTBUFBIS[4]; /**< Shifter Buffer N Bit Swapped Register, array offset: 0x280, array step: 0x4 */ + uint8_t RESERVED_7[112]; + __IO uint32_t SHIFTBUFBYS[4]; /**< Shifter Buffer N Byte Swapped Register, array offset: 0x300, array step: 0x4 */ + uint8_t RESERVED_8[112]; + __IO uint32_t SHIFTBUFBBS[4]; /**< Shifter Buffer N Bit Byte Swapped Register, array offset: 0x380, array step: 0x4 */ + uint8_t RESERVED_9[112]; + __IO uint32_t TIMCTL[4]; /**< Timer Control N Register, array offset: 0x400, array step: 0x4 */ + uint8_t RESERVED_10[112]; + __IO uint32_t TIMCFG[4]; /**< Timer Configuration N Register, array offset: 0x480, array step: 0x4 */ + uint8_t RESERVED_11[112]; + __IO uint32_t TIMCMP[4]; /**< Timer Compare N Register, array offset: 0x500, array step: 0x4 */ +} FLEXIO_Type; + +/* ---------------------------------------------------------------------------- + -- FLEXIO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FLEXIO_Register_Masks FLEXIO Register Masks + * @{ + */ + +/*! @name VERID - Version ID Register */ +#define FLEXIO_VERID_FEATURE_MASK (0xFFFFU) +#define FLEXIO_VERID_FEATURE_SHIFT (0U) +#define FLEXIO_VERID_FEATURE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_VERID_FEATURE_SHIFT)) & FLEXIO_VERID_FEATURE_MASK) +#define FLEXIO_VERID_MINOR_MASK (0xFF0000U) +#define FLEXIO_VERID_MINOR_SHIFT (16U) +#define FLEXIO_VERID_MINOR(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_VERID_MINOR_SHIFT)) & FLEXIO_VERID_MINOR_MASK) +#define FLEXIO_VERID_MAJOR_MASK (0xFF000000U) +#define FLEXIO_VERID_MAJOR_SHIFT (24U) +#define FLEXIO_VERID_MAJOR(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_VERID_MAJOR_SHIFT)) & FLEXIO_VERID_MAJOR_MASK) + +/*! @name PARAM - Parameter Register */ +#define FLEXIO_PARAM_SHIFTER_MASK (0xFFU) +#define FLEXIO_PARAM_SHIFTER_SHIFT (0U) +#define FLEXIO_PARAM_SHIFTER(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PARAM_SHIFTER_SHIFT)) & FLEXIO_PARAM_SHIFTER_MASK) +#define FLEXIO_PARAM_TIMER_MASK (0xFF00U) +#define FLEXIO_PARAM_TIMER_SHIFT (8U) +#define FLEXIO_PARAM_TIMER(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PARAM_TIMER_SHIFT)) & FLEXIO_PARAM_TIMER_MASK) +#define FLEXIO_PARAM_PIN_MASK (0xFF0000U) +#define FLEXIO_PARAM_PIN_SHIFT (16U) +#define FLEXIO_PARAM_PIN(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PARAM_PIN_SHIFT)) & FLEXIO_PARAM_PIN_MASK) +#define FLEXIO_PARAM_TRIGGER_MASK (0xFF000000U) +#define FLEXIO_PARAM_TRIGGER_SHIFT (24U) +#define FLEXIO_PARAM_TRIGGER(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_PARAM_TRIGGER_SHIFT)) & FLEXIO_PARAM_TRIGGER_MASK) + +/*! @name CTRL - FlexIO Control Register */ +#define FLEXIO_CTRL_FLEXEN_MASK (0x1U) +#define FLEXIO_CTRL_FLEXEN_SHIFT (0U) +#define FLEXIO_CTRL_FLEXEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_FLEXEN_SHIFT)) & FLEXIO_CTRL_FLEXEN_MASK) +#define FLEXIO_CTRL_SWRST_MASK (0x2U) +#define FLEXIO_CTRL_SWRST_SHIFT (1U) +#define FLEXIO_CTRL_SWRST(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_SWRST_SHIFT)) & FLEXIO_CTRL_SWRST_MASK) +#define FLEXIO_CTRL_FASTACC_MASK (0x4U) +#define FLEXIO_CTRL_FASTACC_SHIFT (2U) +#define FLEXIO_CTRL_FASTACC(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_FASTACC_SHIFT)) & FLEXIO_CTRL_FASTACC_MASK) +#define FLEXIO_CTRL_DBGE_MASK (0x40000000U) +#define FLEXIO_CTRL_DBGE_SHIFT (30U) +#define FLEXIO_CTRL_DBGE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_DBGE_SHIFT)) & FLEXIO_CTRL_DBGE_MASK) +#define FLEXIO_CTRL_DOZEN_MASK (0x80000000U) +#define FLEXIO_CTRL_DOZEN_SHIFT (31U) +#define FLEXIO_CTRL_DOZEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_CTRL_DOZEN_SHIFT)) & FLEXIO_CTRL_DOZEN_MASK) + +/*! @name SHIFTSTAT - Shifter Status Register */ +#define FLEXIO_SHIFTSTAT_SSF_MASK (0xFU) +#define FLEXIO_SHIFTSTAT_SSF_SHIFT (0U) +#define FLEXIO_SHIFTSTAT_SSF(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTSTAT_SSF_SHIFT)) & FLEXIO_SHIFTSTAT_SSF_MASK) + +/*! @name SHIFTERR - Shifter Error Register */ +#define FLEXIO_SHIFTERR_SEF_MASK (0xFU) +#define FLEXIO_SHIFTERR_SEF_SHIFT (0U) +#define FLEXIO_SHIFTERR_SEF(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTERR_SEF_SHIFT)) & FLEXIO_SHIFTERR_SEF_MASK) + +/*! @name TIMSTAT - Timer Status Register */ +#define FLEXIO_TIMSTAT_TSF_MASK (0xFU) +#define FLEXIO_TIMSTAT_TSF_SHIFT (0U) +#define FLEXIO_TIMSTAT_TSF(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMSTAT_TSF_SHIFT)) & FLEXIO_TIMSTAT_TSF_MASK) + +/*! @name SHIFTSIEN - Shifter Status Interrupt Enable */ +#define FLEXIO_SHIFTSIEN_SSIE_MASK (0xFU) +#define FLEXIO_SHIFTSIEN_SSIE_SHIFT (0U) +#define FLEXIO_SHIFTSIEN_SSIE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTSIEN_SSIE_SHIFT)) & FLEXIO_SHIFTSIEN_SSIE_MASK) + +/*! @name SHIFTEIEN - Shifter Error Interrupt Enable */ +#define FLEXIO_SHIFTEIEN_SEIE_MASK (0xFU) +#define FLEXIO_SHIFTEIEN_SEIE_SHIFT (0U) +#define FLEXIO_SHIFTEIEN_SEIE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTEIEN_SEIE_SHIFT)) & FLEXIO_SHIFTEIEN_SEIE_MASK) + +/*! @name TIMIEN - Timer Interrupt Enable Register */ +#define FLEXIO_TIMIEN_TEIE_MASK (0xFU) +#define FLEXIO_TIMIEN_TEIE_SHIFT (0U) +#define FLEXIO_TIMIEN_TEIE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMIEN_TEIE_SHIFT)) & FLEXIO_TIMIEN_TEIE_MASK) + +/*! @name SHIFTSDEN - Shifter Status DMA Enable */ +#define FLEXIO_SHIFTSDEN_SSDE_MASK (0xFU) +#define FLEXIO_SHIFTSDEN_SSDE_SHIFT (0U) +#define FLEXIO_SHIFTSDEN_SSDE(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTSDEN_SSDE_SHIFT)) & FLEXIO_SHIFTSDEN_SSDE_MASK) + +/*! @name SHIFTCTL - Shifter Control N Register */ +#define FLEXIO_SHIFTCTL_SMOD_MASK (0x7U) +#define FLEXIO_SHIFTCTL_SMOD_SHIFT (0U) +#define FLEXIO_SHIFTCTL_SMOD(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_SMOD_SHIFT)) & FLEXIO_SHIFTCTL_SMOD_MASK) +#define FLEXIO_SHIFTCTL_PINPOL_MASK (0x80U) +#define FLEXIO_SHIFTCTL_PINPOL_SHIFT (7U) +#define FLEXIO_SHIFTCTL_PINPOL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINPOL_SHIFT)) & FLEXIO_SHIFTCTL_PINPOL_MASK) +#define FLEXIO_SHIFTCTL_PINSEL_MASK (0x700U) +#define FLEXIO_SHIFTCTL_PINSEL_SHIFT (8U) +#define FLEXIO_SHIFTCTL_PINSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINSEL_SHIFT)) & FLEXIO_SHIFTCTL_PINSEL_MASK) +#define FLEXIO_SHIFTCTL_PINCFG_MASK (0x30000U) +#define FLEXIO_SHIFTCTL_PINCFG_SHIFT (16U) +#define FLEXIO_SHIFTCTL_PINCFG(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINCFG_SHIFT)) & FLEXIO_SHIFTCTL_PINCFG_MASK) +#define FLEXIO_SHIFTCTL_TIMPOL_MASK (0x800000U) +#define FLEXIO_SHIFTCTL_TIMPOL_SHIFT (23U) +#define FLEXIO_SHIFTCTL_TIMPOL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_TIMPOL_SHIFT)) & FLEXIO_SHIFTCTL_TIMPOL_MASK) +#define FLEXIO_SHIFTCTL_TIMSEL_MASK (0x3000000U) +#define FLEXIO_SHIFTCTL_TIMSEL_SHIFT (24U) +#define FLEXIO_SHIFTCTL_TIMSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCTL_TIMSEL_SHIFT)) & FLEXIO_SHIFTCTL_TIMSEL_MASK) + +/* The count of FLEXIO_SHIFTCTL */ +#define FLEXIO_SHIFTCTL_COUNT (4U) + +/*! @name SHIFTCFG - Shifter Configuration N Register */ +#define FLEXIO_SHIFTCFG_SSTART_MASK (0x3U) +#define FLEXIO_SHIFTCFG_SSTART_SHIFT (0U) +#define FLEXIO_SHIFTCFG_SSTART(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCFG_SSTART_SHIFT)) & FLEXIO_SHIFTCFG_SSTART_MASK) +#define FLEXIO_SHIFTCFG_SSTOP_MASK (0x30U) +#define FLEXIO_SHIFTCFG_SSTOP_SHIFT (4U) +#define FLEXIO_SHIFTCFG_SSTOP(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCFG_SSTOP_SHIFT)) & FLEXIO_SHIFTCFG_SSTOP_MASK) +#define FLEXIO_SHIFTCFG_INSRC_MASK (0x100U) +#define FLEXIO_SHIFTCFG_INSRC_SHIFT (8U) +#define FLEXIO_SHIFTCFG_INSRC(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTCFG_INSRC_SHIFT)) & FLEXIO_SHIFTCFG_INSRC_MASK) + +/* The count of FLEXIO_SHIFTCFG */ +#define FLEXIO_SHIFTCFG_COUNT (4U) + +/*! @name SHIFTBUF - Shifter Buffer N Register */ +#define FLEXIO_SHIFTBUF_SHIFTBUF_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUF_SHIFTBUF_SHIFT (0U) +#define FLEXIO_SHIFTBUF_SHIFTBUF(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUF_SHIFTBUF_SHIFT)) & FLEXIO_SHIFTBUF_SHIFTBUF_MASK) + +/* The count of FLEXIO_SHIFTBUF */ +#define FLEXIO_SHIFTBUF_COUNT (4U) + +/*! @name SHIFTBUFBIS - Shifter Buffer N Bit Swapped Register */ +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_SHIFT (0U) +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_SHIFT)) & FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_MASK) + +/* The count of FLEXIO_SHIFTBUFBIS */ +#define FLEXIO_SHIFTBUFBIS_COUNT (4U) + +/*! @name SHIFTBUFBYS - Shifter Buffer N Byte Swapped Register */ +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_SHIFT (0U) +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_SHIFT)) & FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_MASK) + +/* The count of FLEXIO_SHIFTBUFBYS */ +#define FLEXIO_SHIFTBUFBYS_COUNT (4U) + +/*! @name SHIFTBUFBBS - Shifter Buffer N Bit Byte Swapped Register */ +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_MASK (0xFFFFFFFFU) +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_SHIFT (0U) +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_SHIFT)) & FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_MASK) + +/* The count of FLEXIO_SHIFTBUFBBS */ +#define FLEXIO_SHIFTBUFBBS_COUNT (4U) + +/*! @name TIMCTL - Timer Control N Register */ +#define FLEXIO_TIMCTL_TIMOD_MASK (0x3U) +#define FLEXIO_TIMCTL_TIMOD_SHIFT (0U) +#define FLEXIO_TIMCTL_TIMOD(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_TIMOD_SHIFT)) & FLEXIO_TIMCTL_TIMOD_MASK) +#define FLEXIO_TIMCTL_PINPOL_MASK (0x80U) +#define FLEXIO_TIMCTL_PINPOL_SHIFT (7U) +#define FLEXIO_TIMCTL_PINPOL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_PINPOL_SHIFT)) & FLEXIO_TIMCTL_PINPOL_MASK) +#define FLEXIO_TIMCTL_PINSEL_MASK (0x700U) +#define FLEXIO_TIMCTL_PINSEL_SHIFT (8U) +#define FLEXIO_TIMCTL_PINSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_PINSEL_SHIFT)) & FLEXIO_TIMCTL_PINSEL_MASK) +#define FLEXIO_TIMCTL_PINCFG_MASK (0x30000U) +#define FLEXIO_TIMCTL_PINCFG_SHIFT (16U) +#define FLEXIO_TIMCTL_PINCFG(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_PINCFG_SHIFT)) & FLEXIO_TIMCTL_PINCFG_MASK) +#define FLEXIO_TIMCTL_TRGSRC_MASK (0x400000U) +#define FLEXIO_TIMCTL_TRGSRC_SHIFT (22U) +#define FLEXIO_TIMCTL_TRGSRC(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_TRGSRC_SHIFT)) & FLEXIO_TIMCTL_TRGSRC_MASK) +#define FLEXIO_TIMCTL_TRGPOL_MASK (0x800000U) +#define FLEXIO_TIMCTL_TRGPOL_SHIFT (23U) +#define FLEXIO_TIMCTL_TRGPOL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_TRGPOL_SHIFT)) & FLEXIO_TIMCTL_TRGPOL_MASK) +#define FLEXIO_TIMCTL_TRGSEL_MASK (0xF000000U) +#define FLEXIO_TIMCTL_TRGSEL_SHIFT (24U) +#define FLEXIO_TIMCTL_TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCTL_TRGSEL_SHIFT)) & FLEXIO_TIMCTL_TRGSEL_MASK) + +/* The count of FLEXIO_TIMCTL */ +#define FLEXIO_TIMCTL_COUNT (4U) + +/*! @name TIMCFG - Timer Configuration N Register */ +#define FLEXIO_TIMCFG_TSTART_MASK (0x2U) +#define FLEXIO_TIMCFG_TSTART_SHIFT (1U) +#define FLEXIO_TIMCFG_TSTART(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TSTART_SHIFT)) & FLEXIO_TIMCFG_TSTART_MASK) +#define FLEXIO_TIMCFG_TSTOP_MASK (0x30U) +#define FLEXIO_TIMCFG_TSTOP_SHIFT (4U) +#define FLEXIO_TIMCFG_TSTOP(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TSTOP_SHIFT)) & FLEXIO_TIMCFG_TSTOP_MASK) +#define FLEXIO_TIMCFG_TIMENA_MASK (0x700U) +#define FLEXIO_TIMCFG_TIMENA_SHIFT (8U) +#define FLEXIO_TIMCFG_TIMENA(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMENA_SHIFT)) & FLEXIO_TIMCFG_TIMENA_MASK) +#define FLEXIO_TIMCFG_TIMDIS_MASK (0x7000U) +#define FLEXIO_TIMCFG_TIMDIS_SHIFT (12U) +#define FLEXIO_TIMCFG_TIMDIS(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMDIS_SHIFT)) & FLEXIO_TIMCFG_TIMDIS_MASK) +#define FLEXIO_TIMCFG_TIMRST_MASK (0x70000U) +#define FLEXIO_TIMCFG_TIMRST_SHIFT (16U) +#define FLEXIO_TIMCFG_TIMRST(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMRST_SHIFT)) & FLEXIO_TIMCFG_TIMRST_MASK) +#define FLEXIO_TIMCFG_TIMDEC_MASK (0x300000U) +#define FLEXIO_TIMCFG_TIMDEC_SHIFT (20U) +#define FLEXIO_TIMCFG_TIMDEC(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMDEC_SHIFT)) & FLEXIO_TIMCFG_TIMDEC_MASK) +#define FLEXIO_TIMCFG_TIMOUT_MASK (0x3000000U) +#define FLEXIO_TIMCFG_TIMOUT_SHIFT (24U) +#define FLEXIO_TIMCFG_TIMOUT(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCFG_TIMOUT_SHIFT)) & FLEXIO_TIMCFG_TIMOUT_MASK) + +/* The count of FLEXIO_TIMCFG */ +#define FLEXIO_TIMCFG_COUNT (4U) + +/*! @name TIMCMP - Timer Compare N Register */ +#define FLEXIO_TIMCMP_CMP_MASK (0xFFFFU) +#define FLEXIO_TIMCMP_CMP_SHIFT (0U) +#define FLEXIO_TIMCMP_CMP(x) (((uint32_t)(((uint32_t)(x)) << FLEXIO_TIMCMP_CMP_SHIFT)) & FLEXIO_TIMCMP_CMP_MASK) + +/* The count of FLEXIO_TIMCMP */ +#define FLEXIO_TIMCMP_COUNT (4U) + + +/*! + * @} + */ /* end of group FLEXIO_Register_Masks */ + + +/* FLEXIO - Peripheral instance base addresses */ +/** Peripheral FLEXIO base address */ +#define FLEXIO_BASE (0x4005F000u) +/** Peripheral FLEXIO base pointer */ +#define FLEXIO ((FLEXIO_Type *)FLEXIO_BASE) +/** Array initializer of FLEXIO peripheral base addresses */ +#define FLEXIO_BASE_ADDRS { FLEXIO_BASE } +/** Array initializer of FLEXIO peripheral base pointers */ +#define FLEXIO_BASE_PTRS { FLEXIO } +/** Interrupt vectors for the FLEXIO peripheral type */ +#define FLEXIO_IRQS { UART2_FLEXIO_IRQn } + +/*! + * @} + */ /* end of group FLEXIO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FTFA Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTFA_Peripheral_Access_Layer FTFA Peripheral Access Layer + * @{ + */ + +/** FTFA - Register Layout Typedef */ +typedef struct { + __IO uint8_t FSTAT; /**< Flash Status Register, offset: 0x0 */ + __IO uint8_t FCNFG; /**< Flash Configuration Register, offset: 0x1 */ + __I uint8_t FSEC; /**< Flash Security Register, offset: 0x2 */ + __I uint8_t FOPT; /**< Flash Option Register, offset: 0x3 */ + __IO uint8_t FCCOB3; /**< Flash Common Command Object Registers, offset: 0x4 */ + __IO uint8_t FCCOB2; /**< Flash Common Command Object Registers, offset: 0x5 */ + __IO uint8_t FCCOB1; /**< Flash Common Command Object Registers, offset: 0x6 */ + __IO uint8_t FCCOB0; /**< Flash Common Command Object Registers, offset: 0x7 */ + __IO uint8_t FCCOB7; /**< Flash Common Command Object Registers, offset: 0x8 */ + __IO uint8_t FCCOB6; /**< Flash Common Command Object Registers, offset: 0x9 */ + __IO uint8_t FCCOB5; /**< Flash Common Command Object Registers, offset: 0xA */ + __IO uint8_t FCCOB4; /**< Flash Common Command Object Registers, offset: 0xB */ + __IO uint8_t FCCOBB; /**< Flash Common Command Object Registers, offset: 0xC */ + __IO uint8_t FCCOBA; /**< Flash Common Command Object Registers, offset: 0xD */ + __IO uint8_t FCCOB9; /**< Flash Common Command Object Registers, offset: 0xE */ + __IO uint8_t FCCOB8; /**< Flash Common Command Object Registers, offset: 0xF */ + __IO uint8_t FPROT3; /**< Program Flash Protection Registers, offset: 0x10 */ + __IO uint8_t FPROT2; /**< Program Flash Protection Registers, offset: 0x11 */ + __IO uint8_t FPROT1; /**< Program Flash Protection Registers, offset: 0x12 */ + __IO uint8_t FPROT0; /**< Program Flash Protection Registers, offset: 0x13 */ +} FTFA_Type; + +/* ---------------------------------------------------------------------------- + -- FTFA Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTFA_Register_Masks FTFA Register Masks + * @{ + */ + +/*! @name FSTAT - Flash Status Register */ +#define FTFA_FSTAT_MGSTAT0_MASK (0x1U) +#define FTFA_FSTAT_MGSTAT0_SHIFT (0U) +#define FTFA_FSTAT_MGSTAT0(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_MGSTAT0_SHIFT)) & FTFA_FSTAT_MGSTAT0_MASK) +#define FTFA_FSTAT_FPVIOL_MASK (0x10U) +#define FTFA_FSTAT_FPVIOL_SHIFT (4U) +#define FTFA_FSTAT_FPVIOL(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_FPVIOL_SHIFT)) & FTFA_FSTAT_FPVIOL_MASK) +#define FTFA_FSTAT_ACCERR_MASK (0x20U) +#define FTFA_FSTAT_ACCERR_SHIFT (5U) +#define FTFA_FSTAT_ACCERR(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_ACCERR_SHIFT)) & FTFA_FSTAT_ACCERR_MASK) +#define FTFA_FSTAT_RDCOLERR_MASK (0x40U) +#define FTFA_FSTAT_RDCOLERR_SHIFT (6U) +#define FTFA_FSTAT_RDCOLERR(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_RDCOLERR_SHIFT)) & FTFA_FSTAT_RDCOLERR_MASK) +#define FTFA_FSTAT_CCIF_MASK (0x80U) +#define FTFA_FSTAT_CCIF_SHIFT (7U) +#define FTFA_FSTAT_CCIF(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSTAT_CCIF_SHIFT)) & FTFA_FSTAT_CCIF_MASK) + +/*! @name FCNFG - Flash Configuration Register */ +#define FTFA_FCNFG_ERSSUSP_MASK (0x10U) +#define FTFA_FCNFG_ERSSUSP_SHIFT (4U) +#define FTFA_FCNFG_ERSSUSP(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCNFG_ERSSUSP_SHIFT)) & FTFA_FCNFG_ERSSUSP_MASK) +#define FTFA_FCNFG_ERSAREQ_MASK (0x20U) +#define FTFA_FCNFG_ERSAREQ_SHIFT (5U) +#define FTFA_FCNFG_ERSAREQ(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCNFG_ERSAREQ_SHIFT)) & FTFA_FCNFG_ERSAREQ_MASK) +#define FTFA_FCNFG_RDCOLLIE_MASK (0x40U) +#define FTFA_FCNFG_RDCOLLIE_SHIFT (6U) +#define FTFA_FCNFG_RDCOLLIE(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCNFG_RDCOLLIE_SHIFT)) & FTFA_FCNFG_RDCOLLIE_MASK) +#define FTFA_FCNFG_CCIE_MASK (0x80U) +#define FTFA_FCNFG_CCIE_SHIFT (7U) +#define FTFA_FCNFG_CCIE(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCNFG_CCIE_SHIFT)) & FTFA_FCNFG_CCIE_MASK) + +/*! @name FSEC - Flash Security Register */ +#define FTFA_FSEC_SEC_MASK (0x3U) +#define FTFA_FSEC_SEC_SHIFT (0U) +#define FTFA_FSEC_SEC(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSEC_SEC_SHIFT)) & FTFA_FSEC_SEC_MASK) +#define FTFA_FSEC_FSLACC_MASK (0xCU) +#define FTFA_FSEC_FSLACC_SHIFT (2U) +#define FTFA_FSEC_FSLACC(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSEC_FSLACC_SHIFT)) & FTFA_FSEC_FSLACC_MASK) +#define FTFA_FSEC_MEEN_MASK (0x30U) +#define FTFA_FSEC_MEEN_SHIFT (4U) +#define FTFA_FSEC_MEEN(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSEC_MEEN_SHIFT)) & FTFA_FSEC_MEEN_MASK) +#define FTFA_FSEC_KEYEN_MASK (0xC0U) +#define FTFA_FSEC_KEYEN_SHIFT (6U) +#define FTFA_FSEC_KEYEN(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FSEC_KEYEN_SHIFT)) & FTFA_FSEC_KEYEN_MASK) + +/*! @name FOPT - Flash Option Register */ +#define FTFA_FOPT_OPT_MASK (0xFFU) +#define FTFA_FOPT_OPT_SHIFT (0U) +#define FTFA_FOPT_OPT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FOPT_OPT_SHIFT)) & FTFA_FOPT_OPT_MASK) + +/*! @name FCCOB3 - Flash Common Command Object Registers */ +#define FTFA_FCCOB3_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB3_CCOBn_SHIFT (0U) +#define FTFA_FCCOB3_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB3_CCOBn_SHIFT)) & FTFA_FCCOB3_CCOBn_MASK) + +/*! @name FCCOB2 - Flash Common Command Object Registers */ +#define FTFA_FCCOB2_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB2_CCOBn_SHIFT (0U) +#define FTFA_FCCOB2_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB2_CCOBn_SHIFT)) & FTFA_FCCOB2_CCOBn_MASK) + +/*! @name FCCOB1 - Flash Common Command Object Registers */ +#define FTFA_FCCOB1_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB1_CCOBn_SHIFT (0U) +#define FTFA_FCCOB1_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB1_CCOBn_SHIFT)) & FTFA_FCCOB1_CCOBn_MASK) + +/*! @name FCCOB0 - Flash Common Command Object Registers */ +#define FTFA_FCCOB0_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB0_CCOBn_SHIFT (0U) +#define FTFA_FCCOB0_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB0_CCOBn_SHIFT)) & FTFA_FCCOB0_CCOBn_MASK) + +/*! @name FCCOB7 - Flash Common Command Object Registers */ +#define FTFA_FCCOB7_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB7_CCOBn_SHIFT (0U) +#define FTFA_FCCOB7_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB7_CCOBn_SHIFT)) & FTFA_FCCOB7_CCOBn_MASK) + +/*! @name FCCOB6 - Flash Common Command Object Registers */ +#define FTFA_FCCOB6_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB6_CCOBn_SHIFT (0U) +#define FTFA_FCCOB6_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB6_CCOBn_SHIFT)) & FTFA_FCCOB6_CCOBn_MASK) + +/*! @name FCCOB5 - Flash Common Command Object Registers */ +#define FTFA_FCCOB5_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB5_CCOBn_SHIFT (0U) +#define FTFA_FCCOB5_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB5_CCOBn_SHIFT)) & FTFA_FCCOB5_CCOBn_MASK) + +/*! @name FCCOB4 - Flash Common Command Object Registers */ +#define FTFA_FCCOB4_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB4_CCOBn_SHIFT (0U) +#define FTFA_FCCOB4_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB4_CCOBn_SHIFT)) & FTFA_FCCOB4_CCOBn_MASK) + +/*! @name FCCOBB - Flash Common Command Object Registers */ +#define FTFA_FCCOBB_CCOBn_MASK (0xFFU) +#define FTFA_FCCOBB_CCOBn_SHIFT (0U) +#define FTFA_FCCOBB_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOBB_CCOBn_SHIFT)) & FTFA_FCCOBB_CCOBn_MASK) + +/*! @name FCCOBA - Flash Common Command Object Registers */ +#define FTFA_FCCOBA_CCOBn_MASK (0xFFU) +#define FTFA_FCCOBA_CCOBn_SHIFT (0U) +#define FTFA_FCCOBA_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOBA_CCOBn_SHIFT)) & FTFA_FCCOBA_CCOBn_MASK) + +/*! @name FCCOB9 - Flash Common Command Object Registers */ +#define FTFA_FCCOB9_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB9_CCOBn_SHIFT (0U) +#define FTFA_FCCOB9_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB9_CCOBn_SHIFT)) & FTFA_FCCOB9_CCOBn_MASK) + +/*! @name FCCOB8 - Flash Common Command Object Registers */ +#define FTFA_FCCOB8_CCOBn_MASK (0xFFU) +#define FTFA_FCCOB8_CCOBn_SHIFT (0U) +#define FTFA_FCCOB8_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FCCOB8_CCOBn_SHIFT)) & FTFA_FCCOB8_CCOBn_MASK) + +/*! @name FPROT3 - Program Flash Protection Registers */ +#define FTFA_FPROT3_PROT_MASK (0xFFU) +#define FTFA_FPROT3_PROT_SHIFT (0U) +#define FTFA_FPROT3_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FPROT3_PROT_SHIFT)) & FTFA_FPROT3_PROT_MASK) + +/*! @name FPROT2 - Program Flash Protection Registers */ +#define FTFA_FPROT2_PROT_MASK (0xFFU) +#define FTFA_FPROT2_PROT_SHIFT (0U) +#define FTFA_FPROT2_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FPROT2_PROT_SHIFT)) & FTFA_FPROT2_PROT_MASK) + +/*! @name FPROT1 - Program Flash Protection Registers */ +#define FTFA_FPROT1_PROT_MASK (0xFFU) +#define FTFA_FPROT1_PROT_SHIFT (0U) +#define FTFA_FPROT1_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FPROT1_PROT_SHIFT)) & FTFA_FPROT1_PROT_MASK) + +/*! @name FPROT0 - Program Flash Protection Registers */ +#define FTFA_FPROT0_PROT_MASK (0xFFU) +#define FTFA_FPROT0_PROT_SHIFT (0U) +#define FTFA_FPROT0_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFA_FPROT0_PROT_SHIFT)) & FTFA_FPROT0_PROT_MASK) + + +/*! + * @} + */ /* end of group FTFA_Register_Masks */ + + +/* FTFA - Peripheral instance base addresses */ +/** Peripheral FTFA base address */ +#define FTFA_BASE (0x40020000u) +/** Peripheral FTFA base pointer */ +#define FTFA ((FTFA_Type *)FTFA_BASE) +/** Array initializer of FTFA peripheral base addresses */ +#define FTFA_BASE_ADDRS { FTFA_BASE } +/** Array initializer of FTFA peripheral base pointers */ +#define FTFA_BASE_PTRS { FTFA } +/** Interrupt vectors for the FTFA peripheral type */ +#define FTFA_COMMAND_COMPLETE_IRQS { FTFA_IRQn } + +/*! + * @} + */ /* end of group FTFA_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GPIO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Peripheral_Access_Layer GPIO Peripheral Access Layer + * @{ + */ + +/** GPIO - Register Layout Typedef */ +typedef struct { + __IO uint32_t PDOR; /**< Port Data Output Register, offset: 0x0 */ + __O uint32_t PSOR; /**< Port Set Output Register, offset: 0x4 */ + __O uint32_t PCOR; /**< Port Clear Output Register, offset: 0x8 */ + __O uint32_t PTOR; /**< Port Toggle Output Register, offset: 0xC */ + __I uint32_t PDIR; /**< Port Data Input Register, offset: 0x10 */ + __IO uint32_t PDDR; /**< Port Data Direction Register, offset: 0x14 */ +} GPIO_Type; + +/* ---------------------------------------------------------------------------- + -- GPIO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Register_Masks GPIO Register Masks + * @{ + */ + +/*! @name PDOR - Port Data Output Register */ +#define GPIO_PDOR_PDO_MASK (0xFFFFFFFFU) +#define GPIO_PDOR_PDO_SHIFT (0U) +#define GPIO_PDOR_PDO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDOR_PDO_SHIFT)) & GPIO_PDOR_PDO_MASK) + +/*! @name PSOR - Port Set Output Register */ +#define GPIO_PSOR_PTSO_MASK (0xFFFFFFFFU) +#define GPIO_PSOR_PTSO_SHIFT (0U) +#define GPIO_PSOR_PTSO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PSOR_PTSO_SHIFT)) & GPIO_PSOR_PTSO_MASK) + +/*! @name PCOR - Port Clear Output Register */ +#define GPIO_PCOR_PTCO_MASK (0xFFFFFFFFU) +#define GPIO_PCOR_PTCO_SHIFT (0U) +#define GPIO_PCOR_PTCO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PCOR_PTCO_SHIFT)) & GPIO_PCOR_PTCO_MASK) + +/*! @name PTOR - Port Toggle Output Register */ +#define GPIO_PTOR_PTTO_MASK (0xFFFFFFFFU) +#define GPIO_PTOR_PTTO_SHIFT (0U) +#define GPIO_PTOR_PTTO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PTOR_PTTO_SHIFT)) & GPIO_PTOR_PTTO_MASK) + +/*! @name PDIR - Port Data Input Register */ +#define GPIO_PDIR_PDI_MASK (0xFFFFFFFFU) +#define GPIO_PDIR_PDI_SHIFT (0U) +#define GPIO_PDIR_PDI(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDIR_PDI_SHIFT)) & GPIO_PDIR_PDI_MASK) + +/*! @name PDDR - Port Data Direction Register */ +#define GPIO_PDDR_PDD_MASK (0xFFFFFFFFU) +#define GPIO_PDDR_PDD_SHIFT (0U) +#define GPIO_PDDR_PDD(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDDR_PDD_SHIFT)) & GPIO_PDDR_PDD_MASK) + + +/*! + * @} + */ /* end of group GPIO_Register_Masks */ + + +/* GPIO - Peripheral instance base addresses */ +/** Peripheral GPIOA base address */ +#define GPIOA_BASE (0x400FF000u) +/** Peripheral GPIOA base pointer */ +#define GPIOA ((GPIO_Type *)GPIOA_BASE) +/** Peripheral GPIOB base address */ +#define GPIOB_BASE (0x400FF040u) +/** Peripheral GPIOB base pointer */ +#define GPIOB ((GPIO_Type *)GPIOB_BASE) +/** Peripheral GPIOC base address */ +#define GPIOC_BASE (0x400FF080u) +/** Peripheral GPIOC base pointer */ +#define GPIOC ((GPIO_Type *)GPIOC_BASE) +/** Peripheral GPIOD base address */ +#define GPIOD_BASE (0x400FF0C0u) +/** Peripheral GPIOD base pointer */ +#define GPIOD ((GPIO_Type *)GPIOD_BASE) +/** Peripheral GPIOE base address */ +#define GPIOE_BASE (0x400FF100u) +/** Peripheral GPIOE base pointer */ +#define GPIOE ((GPIO_Type *)GPIOE_BASE) +/** Array initializer of GPIO peripheral base addresses */ +#define GPIO_BASE_ADDRS { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE, GPIOE_BASE } +/** Array initializer of GPIO peripheral base pointers */ +#define GPIO_BASE_PTRS { GPIOA, GPIOB, GPIOC, GPIOD, GPIOE } + +/*! + * @} + */ /* end of group GPIO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2C Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Peripheral_Access_Layer I2C Peripheral Access Layer + * @{ + */ + +/** I2C - Register Layout Typedef */ +typedef struct { + __IO uint8_t A1; /**< I2C Address Register 1, offset: 0x0 */ + __IO uint8_t F; /**< I2C Frequency Divider register, offset: 0x1 */ + __IO uint8_t C1; /**< I2C Control Register 1, offset: 0x2 */ + __IO uint8_t S; /**< I2C Status register, offset: 0x3 */ + __IO uint8_t D; /**< I2C Data I/O register, offset: 0x4 */ + __IO uint8_t C2; /**< I2C Control Register 2, offset: 0x5 */ + __IO uint8_t FLT; /**< I2C Programmable Input Glitch Filter Register, offset: 0x6 */ + __IO uint8_t RA; /**< I2C Range Address register, offset: 0x7 */ + __IO uint8_t SMB; /**< I2C SMBus Control and Status register, offset: 0x8 */ + __IO uint8_t A2; /**< I2C Address Register 2, offset: 0x9 */ + __IO uint8_t SLTH; /**< I2C SCL Low Timeout Register High, offset: 0xA */ + __IO uint8_t SLTL; /**< I2C SCL Low Timeout Register Low, offset: 0xB */ + __IO uint8_t S2; /**< I2C Status register 2, offset: 0xC */ +} I2C_Type; + +/* ---------------------------------------------------------------------------- + -- I2C Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Register_Masks I2C Register Masks + * @{ + */ + +/*! @name A1 - I2C Address Register 1 */ +#define I2C_A1_AD_MASK (0xFEU) +#define I2C_A1_AD_SHIFT (1U) +#define I2C_A1_AD(x) (((uint8_t)(((uint8_t)(x)) << I2C_A1_AD_SHIFT)) & I2C_A1_AD_MASK) + +/*! @name F - I2C Frequency Divider register */ +#define I2C_F_ICR_MASK (0x3FU) +#define I2C_F_ICR_SHIFT (0U) +#define I2C_F_ICR(x) (((uint8_t)(((uint8_t)(x)) << I2C_F_ICR_SHIFT)) & I2C_F_ICR_MASK) +#define I2C_F_MULT_MASK (0xC0U) +#define I2C_F_MULT_SHIFT (6U) +#define I2C_F_MULT(x) (((uint8_t)(((uint8_t)(x)) << I2C_F_MULT_SHIFT)) & I2C_F_MULT_MASK) + +/*! @name C1 - I2C Control Register 1 */ +#define I2C_C1_DMAEN_MASK (0x1U) +#define I2C_C1_DMAEN_SHIFT (0U) +#define I2C_C1_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_DMAEN_SHIFT)) & I2C_C1_DMAEN_MASK) +#define I2C_C1_WUEN_MASK (0x2U) +#define I2C_C1_WUEN_SHIFT (1U) +#define I2C_C1_WUEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_WUEN_SHIFT)) & I2C_C1_WUEN_MASK) +#define I2C_C1_RSTA_MASK (0x4U) +#define I2C_C1_RSTA_SHIFT (2U) +#define I2C_C1_RSTA(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_RSTA_SHIFT)) & I2C_C1_RSTA_MASK) +#define I2C_C1_TXAK_MASK (0x8U) +#define I2C_C1_TXAK_SHIFT (3U) +#define I2C_C1_TXAK(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_TXAK_SHIFT)) & I2C_C1_TXAK_MASK) +#define I2C_C1_TX_MASK (0x10U) +#define I2C_C1_TX_SHIFT (4U) +#define I2C_C1_TX(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_TX_SHIFT)) & I2C_C1_TX_MASK) +#define I2C_C1_MST_MASK (0x20U) +#define I2C_C1_MST_SHIFT (5U) +#define I2C_C1_MST(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_MST_SHIFT)) & I2C_C1_MST_MASK) +#define I2C_C1_IICIE_MASK (0x40U) +#define I2C_C1_IICIE_SHIFT (6U) +#define I2C_C1_IICIE(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_IICIE_SHIFT)) & I2C_C1_IICIE_MASK) +#define I2C_C1_IICEN_MASK (0x80U) +#define I2C_C1_IICEN_SHIFT (7U) +#define I2C_C1_IICEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_IICEN_SHIFT)) & I2C_C1_IICEN_MASK) + +/*! @name S - I2C Status register */ +#define I2C_S_RXAK_MASK (0x1U) +#define I2C_S_RXAK_SHIFT (0U) +#define I2C_S_RXAK(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_RXAK_SHIFT)) & I2C_S_RXAK_MASK) +#define I2C_S_IICIF_MASK (0x2U) +#define I2C_S_IICIF_SHIFT (1U) +#define I2C_S_IICIF(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_IICIF_SHIFT)) & I2C_S_IICIF_MASK) +#define I2C_S_SRW_MASK (0x4U) +#define I2C_S_SRW_SHIFT (2U) +#define I2C_S_SRW(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_SRW_SHIFT)) & I2C_S_SRW_MASK) +#define I2C_S_RAM_MASK (0x8U) +#define I2C_S_RAM_SHIFT (3U) +#define I2C_S_RAM(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_RAM_SHIFT)) & I2C_S_RAM_MASK) +#define I2C_S_ARBL_MASK (0x10U) +#define I2C_S_ARBL_SHIFT (4U) +#define I2C_S_ARBL(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_ARBL_SHIFT)) & I2C_S_ARBL_MASK) +#define I2C_S_BUSY_MASK (0x20U) +#define I2C_S_BUSY_SHIFT (5U) +#define I2C_S_BUSY(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_BUSY_SHIFT)) & I2C_S_BUSY_MASK) +#define I2C_S_IAAS_MASK (0x40U) +#define I2C_S_IAAS_SHIFT (6U) +#define I2C_S_IAAS(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_IAAS_SHIFT)) & I2C_S_IAAS_MASK) +#define I2C_S_TCF_MASK (0x80U) +#define I2C_S_TCF_SHIFT (7U) +#define I2C_S_TCF(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_TCF_SHIFT)) & I2C_S_TCF_MASK) + +/*! @name D - I2C Data I/O register */ +#define I2C_D_DATA_MASK (0xFFU) +#define I2C_D_DATA_SHIFT (0U) +#define I2C_D_DATA(x) (((uint8_t)(((uint8_t)(x)) << I2C_D_DATA_SHIFT)) & I2C_D_DATA_MASK) + +/*! @name C2 - I2C Control Register 2 */ +#define I2C_C2_AD_MASK (0x7U) +#define I2C_C2_AD_SHIFT (0U) +#define I2C_C2_AD(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_AD_SHIFT)) & I2C_C2_AD_MASK) +#define I2C_C2_RMEN_MASK (0x8U) +#define I2C_C2_RMEN_SHIFT (3U) +#define I2C_C2_RMEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_RMEN_SHIFT)) & I2C_C2_RMEN_MASK) +#define I2C_C2_SBRC_MASK (0x10U) +#define I2C_C2_SBRC_SHIFT (4U) +#define I2C_C2_SBRC(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_SBRC_SHIFT)) & I2C_C2_SBRC_MASK) +#define I2C_C2_HDRS_MASK (0x20U) +#define I2C_C2_HDRS_SHIFT (5U) +#define I2C_C2_HDRS(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_HDRS_SHIFT)) & I2C_C2_HDRS_MASK) +#define I2C_C2_ADEXT_MASK (0x40U) +#define I2C_C2_ADEXT_SHIFT (6U) +#define I2C_C2_ADEXT(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_ADEXT_SHIFT)) & I2C_C2_ADEXT_MASK) +#define I2C_C2_GCAEN_MASK (0x80U) +#define I2C_C2_GCAEN_SHIFT (7U) +#define I2C_C2_GCAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_GCAEN_SHIFT)) & I2C_C2_GCAEN_MASK) + +/*! @name FLT - I2C Programmable Input Glitch Filter Register */ +#define I2C_FLT_FLT_MASK (0xFU) +#define I2C_FLT_FLT_SHIFT (0U) +#define I2C_FLT_FLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_FLT_SHIFT)) & I2C_FLT_FLT_MASK) +#define I2C_FLT_STARTF_MASK (0x10U) +#define I2C_FLT_STARTF_SHIFT (4U) +#define I2C_FLT_STARTF(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_STARTF_SHIFT)) & I2C_FLT_STARTF_MASK) +#define I2C_FLT_SSIE_MASK (0x20U) +#define I2C_FLT_SSIE_SHIFT (5U) +#define I2C_FLT_SSIE(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_SSIE_SHIFT)) & I2C_FLT_SSIE_MASK) +#define I2C_FLT_STOPF_MASK (0x40U) +#define I2C_FLT_STOPF_SHIFT (6U) +#define I2C_FLT_STOPF(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_STOPF_SHIFT)) & I2C_FLT_STOPF_MASK) +#define I2C_FLT_SHEN_MASK (0x80U) +#define I2C_FLT_SHEN_SHIFT (7U) +#define I2C_FLT_SHEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_SHEN_SHIFT)) & I2C_FLT_SHEN_MASK) + +/*! @name RA - I2C Range Address register */ +#define I2C_RA_RAD_MASK (0xFEU) +#define I2C_RA_RAD_SHIFT (1U) +#define I2C_RA_RAD(x) (((uint8_t)(((uint8_t)(x)) << I2C_RA_RAD_SHIFT)) & I2C_RA_RAD_MASK) + +/*! @name SMB - I2C SMBus Control and Status register */ +#define I2C_SMB_SHTF2IE_MASK (0x1U) +#define I2C_SMB_SHTF2IE_SHIFT (0U) +#define I2C_SMB_SHTF2IE(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF2IE_SHIFT)) & I2C_SMB_SHTF2IE_MASK) +#define I2C_SMB_SHTF2_MASK (0x2U) +#define I2C_SMB_SHTF2_SHIFT (1U) +#define I2C_SMB_SHTF2(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF2_SHIFT)) & I2C_SMB_SHTF2_MASK) +#define I2C_SMB_SHTF1_MASK (0x4U) +#define I2C_SMB_SHTF1_SHIFT (2U) +#define I2C_SMB_SHTF1(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF1_SHIFT)) & I2C_SMB_SHTF1_MASK) +#define I2C_SMB_SLTF_MASK (0x8U) +#define I2C_SMB_SLTF_SHIFT (3U) +#define I2C_SMB_SLTF(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SLTF_SHIFT)) & I2C_SMB_SLTF_MASK) +#define I2C_SMB_TCKSEL_MASK (0x10U) +#define I2C_SMB_TCKSEL_SHIFT (4U) +#define I2C_SMB_TCKSEL(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_TCKSEL_SHIFT)) & I2C_SMB_TCKSEL_MASK) +#define I2C_SMB_SIICAEN_MASK (0x20U) +#define I2C_SMB_SIICAEN_SHIFT (5U) +#define I2C_SMB_SIICAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SIICAEN_SHIFT)) & I2C_SMB_SIICAEN_MASK) +#define I2C_SMB_ALERTEN_MASK (0x40U) +#define I2C_SMB_ALERTEN_SHIFT (6U) +#define I2C_SMB_ALERTEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_ALERTEN_SHIFT)) & I2C_SMB_ALERTEN_MASK) +#define I2C_SMB_FACK_MASK (0x80U) +#define I2C_SMB_FACK_SHIFT (7U) +#define I2C_SMB_FACK(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_FACK_SHIFT)) & I2C_SMB_FACK_MASK) + +/*! @name A2 - I2C Address Register 2 */ +#define I2C_A2_SAD_MASK (0xFEU) +#define I2C_A2_SAD_SHIFT (1U) +#define I2C_A2_SAD(x) (((uint8_t)(((uint8_t)(x)) << I2C_A2_SAD_SHIFT)) & I2C_A2_SAD_MASK) + +/*! @name SLTH - I2C SCL Low Timeout Register High */ +#define I2C_SLTH_SSLT_MASK (0xFFU) +#define I2C_SLTH_SSLT_SHIFT (0U) +#define I2C_SLTH_SSLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_SLTH_SSLT_SHIFT)) & I2C_SLTH_SSLT_MASK) + +/*! @name SLTL - I2C SCL Low Timeout Register Low */ +#define I2C_SLTL_SSLT_MASK (0xFFU) +#define I2C_SLTL_SSLT_SHIFT (0U) +#define I2C_SLTL_SSLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_SLTL_SSLT_SHIFT)) & I2C_SLTL_SSLT_MASK) + +/*! @name S2 - I2C Status register 2 */ +#define I2C_S2_EMPTY_MASK (0x1U) +#define I2C_S2_EMPTY_SHIFT (0U) +#define I2C_S2_EMPTY(x) (((uint8_t)(((uint8_t)(x)) << I2C_S2_EMPTY_SHIFT)) & I2C_S2_EMPTY_MASK) +#define I2C_S2_ERROR_MASK (0x2U) +#define I2C_S2_ERROR_SHIFT (1U) +#define I2C_S2_ERROR(x) (((uint8_t)(((uint8_t)(x)) << I2C_S2_ERROR_SHIFT)) & I2C_S2_ERROR_MASK) + + +/*! + * @} + */ /* end of group I2C_Register_Masks */ + + +/* I2C - Peripheral instance base addresses */ +/** Peripheral I2C0 base address */ +#define I2C0_BASE (0x40066000u) +/** Peripheral I2C0 base pointer */ +#define I2C0 ((I2C_Type *)I2C0_BASE) +/** Peripheral I2C1 base address */ +#define I2C1_BASE (0x40067000u) +/** Peripheral I2C1 base pointer */ +#define I2C1 ((I2C_Type *)I2C1_BASE) +/** Array initializer of I2C peripheral base addresses */ +#define I2C_BASE_ADDRS { I2C0_BASE, I2C1_BASE } +/** Array initializer of I2C peripheral base pointers */ +#define I2C_BASE_PTRS { I2C0, I2C1 } +/** Interrupt vectors for the I2C peripheral type */ +#define I2C_IRQS { I2C0_IRQn, I2C1_IRQn } + +/*! + * @} + */ /* end of group I2C_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2S Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2S_Peripheral_Access_Layer I2S Peripheral Access Layer + * @{ + */ + +/** I2S - Register Layout Typedef */ +typedef struct { + __IO uint32_t TCSR; /**< SAI Transmit Control Register, offset: 0x0 */ + uint8_t RESERVED_0[4]; + __IO uint32_t TCR2; /**< SAI Transmit Configuration 2 Register, offset: 0x8 */ + __IO uint32_t TCR3; /**< SAI Transmit Configuration 3 Register, offset: 0xC */ + __IO uint32_t TCR4; /**< SAI Transmit Configuration 4 Register, offset: 0x10 */ + __IO uint32_t TCR5; /**< SAI Transmit Configuration 5 Register, offset: 0x14 */ + uint8_t RESERVED_1[8]; + __O uint32_t TDR[1]; /**< SAI Transmit Data Register, array offset: 0x20, array step: 0x4 */ + uint8_t RESERVED_2[60]; + __IO uint32_t TMR; /**< SAI Transmit Mask Register, offset: 0x60 */ + uint8_t RESERVED_3[28]; + __IO uint32_t RCSR; /**< SAI Receive Control Register, offset: 0x80 */ + uint8_t RESERVED_4[4]; + __IO uint32_t RCR2; /**< SAI Receive Configuration 2 Register, offset: 0x88 */ + __IO uint32_t RCR3; /**< SAI Receive Configuration 3 Register, offset: 0x8C */ + __IO uint32_t RCR4; /**< SAI Receive Configuration 4 Register, offset: 0x90 */ + __IO uint32_t RCR5; /**< SAI Receive Configuration 5 Register, offset: 0x94 */ + uint8_t RESERVED_5[8]; + __I uint32_t RDR[1]; /**< SAI Receive Data Register, array offset: 0xA0, array step: 0x4 */ + uint8_t RESERVED_6[60]; + __IO uint32_t RMR; /**< SAI Receive Mask Register, offset: 0xE0 */ + uint8_t RESERVED_7[28]; + __IO uint32_t MCR; /**< SAI MCLK Control Register, offset: 0x100 */ +} I2S_Type; + +/* ---------------------------------------------------------------------------- + -- I2S Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2S_Register_Masks I2S Register Masks + * @{ + */ + +/*! @name TCSR - SAI Transmit Control Register */ +#define I2S_TCSR_FWDE_MASK (0x2U) +#define I2S_TCSR_FWDE_SHIFT (1U) +#define I2S_TCSR_FWDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWDE_SHIFT)) & I2S_TCSR_FWDE_MASK) +#define I2S_TCSR_FWIE_MASK (0x200U) +#define I2S_TCSR_FWIE_SHIFT (9U) +#define I2S_TCSR_FWIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWIE_SHIFT)) & I2S_TCSR_FWIE_MASK) +#define I2S_TCSR_FEIE_MASK (0x400U) +#define I2S_TCSR_FEIE_SHIFT (10U) +#define I2S_TCSR_FEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FEIE_SHIFT)) & I2S_TCSR_FEIE_MASK) +#define I2S_TCSR_SEIE_MASK (0x800U) +#define I2S_TCSR_SEIE_SHIFT (11U) +#define I2S_TCSR_SEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SEIE_SHIFT)) & I2S_TCSR_SEIE_MASK) +#define I2S_TCSR_WSIE_MASK (0x1000U) +#define I2S_TCSR_WSIE_SHIFT (12U) +#define I2S_TCSR_WSIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_WSIE_SHIFT)) & I2S_TCSR_WSIE_MASK) +#define I2S_TCSR_FWF_MASK (0x20000U) +#define I2S_TCSR_FWF_SHIFT (17U) +#define I2S_TCSR_FWF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWF_SHIFT)) & I2S_TCSR_FWF_MASK) +#define I2S_TCSR_FEF_MASK (0x40000U) +#define I2S_TCSR_FEF_SHIFT (18U) +#define I2S_TCSR_FEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FEF_SHIFT)) & I2S_TCSR_FEF_MASK) +#define I2S_TCSR_SEF_MASK (0x80000U) +#define I2S_TCSR_SEF_SHIFT (19U) +#define I2S_TCSR_SEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SEF_SHIFT)) & I2S_TCSR_SEF_MASK) +#define I2S_TCSR_WSF_MASK (0x100000U) +#define I2S_TCSR_WSF_SHIFT (20U) +#define I2S_TCSR_WSF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_WSF_SHIFT)) & I2S_TCSR_WSF_MASK) +#define I2S_TCSR_SR_MASK (0x1000000U) +#define I2S_TCSR_SR_SHIFT (24U) +#define I2S_TCSR_SR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SR_SHIFT)) & I2S_TCSR_SR_MASK) +#define I2S_TCSR_FR_MASK (0x2000000U) +#define I2S_TCSR_FR_SHIFT (25U) +#define I2S_TCSR_FR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FR_SHIFT)) & I2S_TCSR_FR_MASK) +#define I2S_TCSR_BCE_MASK (0x10000000U) +#define I2S_TCSR_BCE_SHIFT (28U) +#define I2S_TCSR_BCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_BCE_SHIFT)) & I2S_TCSR_BCE_MASK) +#define I2S_TCSR_DBGE_MASK (0x20000000U) +#define I2S_TCSR_DBGE_SHIFT (29U) +#define I2S_TCSR_DBGE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_DBGE_SHIFT)) & I2S_TCSR_DBGE_MASK) +#define I2S_TCSR_STOPE_MASK (0x40000000U) +#define I2S_TCSR_STOPE_SHIFT (30U) +#define I2S_TCSR_STOPE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_STOPE_SHIFT)) & I2S_TCSR_STOPE_MASK) +#define I2S_TCSR_TE_MASK (0x80000000U) +#define I2S_TCSR_TE_SHIFT (31U) +#define I2S_TCSR_TE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_TE_SHIFT)) & I2S_TCSR_TE_MASK) + +/*! @name TCR2 - SAI Transmit Configuration 2 Register */ +#define I2S_TCR2_DIV_MASK (0xFFU) +#define I2S_TCR2_DIV_SHIFT (0U) +#define I2S_TCR2_DIV(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_DIV_SHIFT)) & I2S_TCR2_DIV_MASK) +#define I2S_TCR2_BCD_MASK (0x1000000U) +#define I2S_TCR2_BCD_SHIFT (24U) +#define I2S_TCR2_BCD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCD_SHIFT)) & I2S_TCR2_BCD_MASK) +#define I2S_TCR2_BCP_MASK (0x2000000U) +#define I2S_TCR2_BCP_SHIFT (25U) +#define I2S_TCR2_BCP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCP_SHIFT)) & I2S_TCR2_BCP_MASK) +#define I2S_TCR2_MSEL_MASK (0xC000000U) +#define I2S_TCR2_MSEL_SHIFT (26U) +#define I2S_TCR2_MSEL(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_MSEL_SHIFT)) & I2S_TCR2_MSEL_MASK) +#define I2S_TCR2_BCI_MASK (0x10000000U) +#define I2S_TCR2_BCI_SHIFT (28U) +#define I2S_TCR2_BCI(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCI_SHIFT)) & I2S_TCR2_BCI_MASK) +#define I2S_TCR2_BCS_MASK (0x20000000U) +#define I2S_TCR2_BCS_SHIFT (29U) +#define I2S_TCR2_BCS(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCS_SHIFT)) & I2S_TCR2_BCS_MASK) +#define I2S_TCR2_SYNC_MASK (0xC0000000U) +#define I2S_TCR2_SYNC_SHIFT (30U) +#define I2S_TCR2_SYNC(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_SYNC_SHIFT)) & I2S_TCR2_SYNC_MASK) + +/*! @name TCR3 - SAI Transmit Configuration 3 Register */ +#define I2S_TCR3_WDFL_MASK (0x1U) +#define I2S_TCR3_WDFL_SHIFT (0U) +#define I2S_TCR3_WDFL(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR3_WDFL_SHIFT)) & I2S_TCR3_WDFL_MASK) +#define I2S_TCR3_TCE_MASK (0x10000U) +#define I2S_TCR3_TCE_SHIFT (16U) +#define I2S_TCR3_TCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR3_TCE_SHIFT)) & I2S_TCR3_TCE_MASK) + +/*! @name TCR4 - SAI Transmit Configuration 4 Register */ +#define I2S_TCR4_FSD_MASK (0x1U) +#define I2S_TCR4_FSD_SHIFT (0U) +#define I2S_TCR4_FSD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSD_SHIFT)) & I2S_TCR4_FSD_MASK) +#define I2S_TCR4_FSP_MASK (0x2U) +#define I2S_TCR4_FSP_SHIFT (1U) +#define I2S_TCR4_FSP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSP_SHIFT)) & I2S_TCR4_FSP_MASK) +#define I2S_TCR4_ONDEM_MASK (0x4U) +#define I2S_TCR4_ONDEM_SHIFT (2U) +#define I2S_TCR4_ONDEM(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_ONDEM_SHIFT)) & I2S_TCR4_ONDEM_MASK) +#define I2S_TCR4_FSE_MASK (0x8U) +#define I2S_TCR4_FSE_SHIFT (3U) +#define I2S_TCR4_FSE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSE_SHIFT)) & I2S_TCR4_FSE_MASK) +#define I2S_TCR4_MF_MASK (0x10U) +#define I2S_TCR4_MF_SHIFT (4U) +#define I2S_TCR4_MF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_MF_SHIFT)) & I2S_TCR4_MF_MASK) +#define I2S_TCR4_SYWD_MASK (0x1F00U) +#define I2S_TCR4_SYWD_SHIFT (8U) +#define I2S_TCR4_SYWD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_SYWD_SHIFT)) & I2S_TCR4_SYWD_MASK) +#define I2S_TCR4_FRSZ_MASK (0x10000U) +#define I2S_TCR4_FRSZ_SHIFT (16U) +#define I2S_TCR4_FRSZ(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FRSZ_SHIFT)) & I2S_TCR4_FRSZ_MASK) +#define I2S_TCR4_FPACK_MASK (0x3000000U) +#define I2S_TCR4_FPACK_SHIFT (24U) +#define I2S_TCR4_FPACK(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FPACK_SHIFT)) & I2S_TCR4_FPACK_MASK) +#define I2S_TCR4_FCONT_MASK (0x10000000U) +#define I2S_TCR4_FCONT_SHIFT (28U) +#define I2S_TCR4_FCONT(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FCONT_SHIFT)) & I2S_TCR4_FCONT_MASK) + +/*! @name TCR5 - SAI Transmit Configuration 5 Register */ +#define I2S_TCR5_FBT_MASK (0x1F00U) +#define I2S_TCR5_FBT_SHIFT (8U) +#define I2S_TCR5_FBT(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_FBT_SHIFT)) & I2S_TCR5_FBT_MASK) +#define I2S_TCR5_W0W_MASK (0x1F0000U) +#define I2S_TCR5_W0W_SHIFT (16U) +#define I2S_TCR5_W0W(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_W0W_SHIFT)) & I2S_TCR5_W0W_MASK) +#define I2S_TCR5_WNW_MASK (0x1F000000U) +#define I2S_TCR5_WNW_SHIFT (24U) +#define I2S_TCR5_WNW(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_WNW_SHIFT)) & I2S_TCR5_WNW_MASK) + +/*! @name TDR - SAI Transmit Data Register */ +#define I2S_TDR_TDR_MASK (0xFFFFFFFFU) +#define I2S_TDR_TDR_SHIFT (0U) +#define I2S_TDR_TDR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TDR_TDR_SHIFT)) & I2S_TDR_TDR_MASK) + +/* The count of I2S_TDR */ +#define I2S_TDR_COUNT (1U) + +/*! @name TMR - SAI Transmit Mask Register */ +#define I2S_TMR_TWM_MASK (0x3U) +#define I2S_TMR_TWM_SHIFT (0U) +#define I2S_TMR_TWM(x) (((uint32_t)(((uint32_t)(x)) << I2S_TMR_TWM_SHIFT)) & I2S_TMR_TWM_MASK) + +/*! @name RCSR - SAI Receive Control Register */ +#define I2S_RCSR_FWDE_MASK (0x2U) +#define I2S_RCSR_FWDE_SHIFT (1U) +#define I2S_RCSR_FWDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWDE_SHIFT)) & I2S_RCSR_FWDE_MASK) +#define I2S_RCSR_FWIE_MASK (0x200U) +#define I2S_RCSR_FWIE_SHIFT (9U) +#define I2S_RCSR_FWIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWIE_SHIFT)) & I2S_RCSR_FWIE_MASK) +#define I2S_RCSR_FEIE_MASK (0x400U) +#define I2S_RCSR_FEIE_SHIFT (10U) +#define I2S_RCSR_FEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FEIE_SHIFT)) & I2S_RCSR_FEIE_MASK) +#define I2S_RCSR_SEIE_MASK (0x800U) +#define I2S_RCSR_SEIE_SHIFT (11U) +#define I2S_RCSR_SEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SEIE_SHIFT)) & I2S_RCSR_SEIE_MASK) +#define I2S_RCSR_WSIE_MASK (0x1000U) +#define I2S_RCSR_WSIE_SHIFT (12U) +#define I2S_RCSR_WSIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_WSIE_SHIFT)) & I2S_RCSR_WSIE_MASK) +#define I2S_RCSR_FWF_MASK (0x20000U) +#define I2S_RCSR_FWF_SHIFT (17U) +#define I2S_RCSR_FWF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWF_SHIFT)) & I2S_RCSR_FWF_MASK) +#define I2S_RCSR_FEF_MASK (0x40000U) +#define I2S_RCSR_FEF_SHIFT (18U) +#define I2S_RCSR_FEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FEF_SHIFT)) & I2S_RCSR_FEF_MASK) +#define I2S_RCSR_SEF_MASK (0x80000U) +#define I2S_RCSR_SEF_SHIFT (19U) +#define I2S_RCSR_SEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SEF_SHIFT)) & I2S_RCSR_SEF_MASK) +#define I2S_RCSR_WSF_MASK (0x100000U) +#define I2S_RCSR_WSF_SHIFT (20U) +#define I2S_RCSR_WSF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_WSF_SHIFT)) & I2S_RCSR_WSF_MASK) +#define I2S_RCSR_SR_MASK (0x1000000U) +#define I2S_RCSR_SR_SHIFT (24U) +#define I2S_RCSR_SR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SR_SHIFT)) & I2S_RCSR_SR_MASK) +#define I2S_RCSR_FR_MASK (0x2000000U) +#define I2S_RCSR_FR_SHIFT (25U) +#define I2S_RCSR_FR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FR_SHIFT)) & I2S_RCSR_FR_MASK) +#define I2S_RCSR_BCE_MASK (0x10000000U) +#define I2S_RCSR_BCE_SHIFT (28U) +#define I2S_RCSR_BCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_BCE_SHIFT)) & I2S_RCSR_BCE_MASK) +#define I2S_RCSR_DBGE_MASK (0x20000000U) +#define I2S_RCSR_DBGE_SHIFT (29U) +#define I2S_RCSR_DBGE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_DBGE_SHIFT)) & I2S_RCSR_DBGE_MASK) +#define I2S_RCSR_STOPE_MASK (0x40000000U) +#define I2S_RCSR_STOPE_SHIFT (30U) +#define I2S_RCSR_STOPE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_STOPE_SHIFT)) & I2S_RCSR_STOPE_MASK) +#define I2S_RCSR_RE_MASK (0x80000000U) +#define I2S_RCSR_RE_SHIFT (31U) +#define I2S_RCSR_RE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_RE_SHIFT)) & I2S_RCSR_RE_MASK) + +/*! @name RCR2 - SAI Receive Configuration 2 Register */ +#define I2S_RCR2_DIV_MASK (0xFFU) +#define I2S_RCR2_DIV_SHIFT (0U) +#define I2S_RCR2_DIV(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_DIV_SHIFT)) & I2S_RCR2_DIV_MASK) +#define I2S_RCR2_BCD_MASK (0x1000000U) +#define I2S_RCR2_BCD_SHIFT (24U) +#define I2S_RCR2_BCD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCD_SHIFT)) & I2S_RCR2_BCD_MASK) +#define I2S_RCR2_BCP_MASK (0x2000000U) +#define I2S_RCR2_BCP_SHIFT (25U) +#define I2S_RCR2_BCP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCP_SHIFT)) & I2S_RCR2_BCP_MASK) +#define I2S_RCR2_MSEL_MASK (0xC000000U) +#define I2S_RCR2_MSEL_SHIFT (26U) +#define I2S_RCR2_MSEL(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_MSEL_SHIFT)) & I2S_RCR2_MSEL_MASK) +#define I2S_RCR2_BCI_MASK (0x10000000U) +#define I2S_RCR2_BCI_SHIFT (28U) +#define I2S_RCR2_BCI(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCI_SHIFT)) & I2S_RCR2_BCI_MASK) +#define I2S_RCR2_BCS_MASK (0x20000000U) +#define I2S_RCR2_BCS_SHIFT (29U) +#define I2S_RCR2_BCS(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCS_SHIFT)) & I2S_RCR2_BCS_MASK) +#define I2S_RCR2_SYNC_MASK (0xC0000000U) +#define I2S_RCR2_SYNC_SHIFT (30U) +#define I2S_RCR2_SYNC(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_SYNC_SHIFT)) & I2S_RCR2_SYNC_MASK) + +/*! @name RCR3 - SAI Receive Configuration 3 Register */ +#define I2S_RCR3_WDFL_MASK (0x1U) +#define I2S_RCR3_WDFL_SHIFT (0U) +#define I2S_RCR3_WDFL(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR3_WDFL_SHIFT)) & I2S_RCR3_WDFL_MASK) +#define I2S_RCR3_RCE_MASK (0x10000U) +#define I2S_RCR3_RCE_SHIFT (16U) +#define I2S_RCR3_RCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR3_RCE_SHIFT)) & I2S_RCR3_RCE_MASK) + +/*! @name RCR4 - SAI Receive Configuration 4 Register */ +#define I2S_RCR4_FSD_MASK (0x1U) +#define I2S_RCR4_FSD_SHIFT (0U) +#define I2S_RCR4_FSD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSD_SHIFT)) & I2S_RCR4_FSD_MASK) +#define I2S_RCR4_FSP_MASK (0x2U) +#define I2S_RCR4_FSP_SHIFT (1U) +#define I2S_RCR4_FSP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSP_SHIFT)) & I2S_RCR4_FSP_MASK) +#define I2S_RCR4_ONDEM_MASK (0x4U) +#define I2S_RCR4_ONDEM_SHIFT (2U) +#define I2S_RCR4_ONDEM(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_ONDEM_SHIFT)) & I2S_RCR4_ONDEM_MASK) +#define I2S_RCR4_FSE_MASK (0x8U) +#define I2S_RCR4_FSE_SHIFT (3U) +#define I2S_RCR4_FSE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSE_SHIFT)) & I2S_RCR4_FSE_MASK) +#define I2S_RCR4_MF_MASK (0x10U) +#define I2S_RCR4_MF_SHIFT (4U) +#define I2S_RCR4_MF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_MF_SHIFT)) & I2S_RCR4_MF_MASK) +#define I2S_RCR4_SYWD_MASK (0x1F00U) +#define I2S_RCR4_SYWD_SHIFT (8U) +#define I2S_RCR4_SYWD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_SYWD_SHIFT)) & I2S_RCR4_SYWD_MASK) +#define I2S_RCR4_FRSZ_MASK (0x10000U) +#define I2S_RCR4_FRSZ_SHIFT (16U) +#define I2S_RCR4_FRSZ(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FRSZ_SHIFT)) & I2S_RCR4_FRSZ_MASK) +#define I2S_RCR4_FPACK_MASK (0x3000000U) +#define I2S_RCR4_FPACK_SHIFT (24U) +#define I2S_RCR4_FPACK(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FPACK_SHIFT)) & I2S_RCR4_FPACK_MASK) +#define I2S_RCR4_FCONT_MASK (0x10000000U) +#define I2S_RCR4_FCONT_SHIFT (28U) +#define I2S_RCR4_FCONT(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FCONT_SHIFT)) & I2S_RCR4_FCONT_MASK) + +/*! @name RCR5 - SAI Receive Configuration 5 Register */ +#define I2S_RCR5_FBT_MASK (0x1F00U) +#define I2S_RCR5_FBT_SHIFT (8U) +#define I2S_RCR5_FBT(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_FBT_SHIFT)) & I2S_RCR5_FBT_MASK) +#define I2S_RCR5_W0W_MASK (0x1F0000U) +#define I2S_RCR5_W0W_SHIFT (16U) +#define I2S_RCR5_W0W(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_W0W_SHIFT)) & I2S_RCR5_W0W_MASK) +#define I2S_RCR5_WNW_MASK (0x1F000000U) +#define I2S_RCR5_WNW_SHIFT (24U) +#define I2S_RCR5_WNW(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_WNW_SHIFT)) & I2S_RCR5_WNW_MASK) + +/*! @name RDR - SAI Receive Data Register */ +#define I2S_RDR_RDR_MASK (0xFFFFFFFFU) +#define I2S_RDR_RDR_SHIFT (0U) +#define I2S_RDR_RDR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RDR_RDR_SHIFT)) & I2S_RDR_RDR_MASK) + +/* The count of I2S_RDR */ +#define I2S_RDR_COUNT (1U) + +/*! @name RMR - SAI Receive Mask Register */ +#define I2S_RMR_RWM_MASK (0x3U) +#define I2S_RMR_RWM_SHIFT (0U) +#define I2S_RMR_RWM(x) (((uint32_t)(((uint32_t)(x)) << I2S_RMR_RWM_SHIFT)) & I2S_RMR_RWM_MASK) + +/*! @name MCR - SAI MCLK Control Register */ +#define I2S_MCR_MICS_MASK (0x3000000U) +#define I2S_MCR_MICS_SHIFT (24U) +#define I2S_MCR_MICS(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_MICS_SHIFT)) & I2S_MCR_MICS_MASK) +#define I2S_MCR_MOE_MASK (0x40000000U) +#define I2S_MCR_MOE_SHIFT (30U) +#define I2S_MCR_MOE(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_MOE_SHIFT)) & I2S_MCR_MOE_MASK) +#define I2S_MCR_DUF_MASK (0x80000000U) +#define I2S_MCR_DUF_SHIFT (31U) +#define I2S_MCR_DUF(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_DUF_SHIFT)) & I2S_MCR_DUF_MASK) + + +/*! + * @} + */ /* end of group I2S_Register_Masks */ + + +/* I2S - Peripheral instance base addresses */ +/** Peripheral I2S0 base address */ +#define I2S0_BASE (0x4002F000u) +/** Peripheral I2S0 base pointer */ +#define I2S0 ((I2S_Type *)I2S0_BASE) +/** Array initializer of I2S peripheral base addresses */ +#define I2S_BASE_ADDRS { I2S0_BASE } +/** Array initializer of I2S peripheral base pointers */ +#define I2S_BASE_PTRS { I2S0 } +/** Interrupt vectors for the I2S peripheral type */ +#define I2S_RX_IRQS { I2S0_IRQn } +#define I2S_TX_IRQS { I2S0_IRQn } + +/*! + * @} + */ /* end of group I2S_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LCD Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LCD_Peripheral_Access_Layer LCD Peripheral Access Layer + * @{ + */ + +/** LCD - Register Layout Typedef */ +typedef struct { + __IO uint32_t GCR; /**< LCD General Control Register, offset: 0x0 */ + __IO uint32_t AR; /**< LCD Auxiliary Register, offset: 0x4 */ + __IO uint32_t FDCR; /**< LCD Fault Detect Control Register, offset: 0x8 */ + __IO uint32_t FDSR; /**< LCD Fault Detect Status Register, offset: 0xC */ + __IO uint32_t PEN[2]; /**< LCD Pin Enable register, array offset: 0x10, array step: 0x4 */ + __IO uint32_t BPEN[2]; /**< LCD Back Plane Enable register, array offset: 0x18, array step: 0x4 */ + union { /* offset: 0x20 */ + __IO uint32_t WF[16]; /**< LCD Waveform register, array offset: 0x20, array step: 0x4 */ + __IO uint8_t WF8B[64]; /**< LCD Waveform Register 0...LCD Waveform Register 63., array offset: 0x20, array step: 0x1 */ + }; +} LCD_Type; + +/* ---------------------------------------------------------------------------- + -- LCD Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LCD_Register_Masks LCD Register Masks + * @{ + */ + +/*! @name GCR - LCD General Control Register */ +#define LCD_GCR_DUTY_MASK (0x7U) +#define LCD_GCR_DUTY_SHIFT (0U) +#define LCD_GCR_DUTY(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_DUTY_SHIFT)) & LCD_GCR_DUTY_MASK) +#define LCD_GCR_LCLK_MASK (0x38U) +#define LCD_GCR_LCLK_SHIFT (3U) +#define LCD_GCR_LCLK(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_LCLK_SHIFT)) & LCD_GCR_LCLK_MASK) +#define LCD_GCR_SOURCE_MASK (0x40U) +#define LCD_GCR_SOURCE_SHIFT (6U) +#define LCD_GCR_SOURCE(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_SOURCE_SHIFT)) & LCD_GCR_SOURCE_MASK) +#define LCD_GCR_LCDEN_MASK (0x80U) +#define LCD_GCR_LCDEN_SHIFT (7U) +#define LCD_GCR_LCDEN(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_LCDEN_SHIFT)) & LCD_GCR_LCDEN_MASK) +#define LCD_GCR_LCDSTP_MASK (0x100U) +#define LCD_GCR_LCDSTP_SHIFT (8U) +#define LCD_GCR_LCDSTP(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_LCDSTP_SHIFT)) & LCD_GCR_LCDSTP_MASK) +#define LCD_GCR_LCDDOZE_MASK (0x200U) +#define LCD_GCR_LCDDOZE_SHIFT (9U) +#define LCD_GCR_LCDDOZE(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_LCDDOZE_SHIFT)) & LCD_GCR_LCDDOZE_MASK) +#define LCD_GCR_FFR_MASK (0x400U) +#define LCD_GCR_FFR_SHIFT (10U) +#define LCD_GCR_FFR(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_FFR_SHIFT)) & LCD_GCR_FFR_MASK) +#define LCD_GCR_ALTSOURCE_MASK (0x800U) +#define LCD_GCR_ALTSOURCE_SHIFT (11U) +#define LCD_GCR_ALTSOURCE(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_ALTSOURCE_SHIFT)) & LCD_GCR_ALTSOURCE_MASK) +#define LCD_GCR_ALTDIV_MASK (0x3000U) +#define LCD_GCR_ALTDIV_SHIFT (12U) +#define LCD_GCR_ALTDIV(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_ALTDIV_SHIFT)) & LCD_GCR_ALTDIV_MASK) +#define LCD_GCR_FDCIEN_MASK (0x4000U) +#define LCD_GCR_FDCIEN_SHIFT (14U) +#define LCD_GCR_FDCIEN(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_FDCIEN_SHIFT)) & LCD_GCR_FDCIEN_MASK) +#define LCD_GCR_PADSAFE_MASK (0x8000U) +#define LCD_GCR_PADSAFE_SHIFT (15U) +#define LCD_GCR_PADSAFE(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_PADSAFE_SHIFT)) & LCD_GCR_PADSAFE_MASK) +#define LCD_GCR_VSUPPLY_MASK (0x20000U) +#define LCD_GCR_VSUPPLY_SHIFT (17U) +#define LCD_GCR_VSUPPLY(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_VSUPPLY_SHIFT)) & LCD_GCR_VSUPPLY_MASK) +#define LCD_GCR_LADJ_MASK (0x300000U) +#define LCD_GCR_LADJ_SHIFT (20U) +#define LCD_GCR_LADJ(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_LADJ_SHIFT)) & LCD_GCR_LADJ_MASK) +#define LCD_GCR_CPSEL_MASK (0x800000U) +#define LCD_GCR_CPSEL_SHIFT (23U) +#define LCD_GCR_CPSEL(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_CPSEL_SHIFT)) & LCD_GCR_CPSEL_MASK) +#define LCD_GCR_RVTRIM_MASK (0xF000000U) +#define LCD_GCR_RVTRIM_SHIFT (24U) +#define LCD_GCR_RVTRIM(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_RVTRIM_SHIFT)) & LCD_GCR_RVTRIM_MASK) +#define LCD_GCR_RVEN_MASK (0x80000000U) +#define LCD_GCR_RVEN_SHIFT (31U) +#define LCD_GCR_RVEN(x) (((uint32_t)(((uint32_t)(x)) << LCD_GCR_RVEN_SHIFT)) & LCD_GCR_RVEN_MASK) + +/*! @name AR - LCD Auxiliary Register */ +#define LCD_AR_BRATE_MASK (0x7U) +#define LCD_AR_BRATE_SHIFT (0U) +#define LCD_AR_BRATE(x) (((uint32_t)(((uint32_t)(x)) << LCD_AR_BRATE_SHIFT)) & LCD_AR_BRATE_MASK) +#define LCD_AR_BMODE_MASK (0x8U) +#define LCD_AR_BMODE_SHIFT (3U) +#define LCD_AR_BMODE(x) (((uint32_t)(((uint32_t)(x)) << LCD_AR_BMODE_SHIFT)) & LCD_AR_BMODE_MASK) +#define LCD_AR_BLANK_MASK (0x20U) +#define LCD_AR_BLANK_SHIFT (5U) +#define LCD_AR_BLANK(x) (((uint32_t)(((uint32_t)(x)) << LCD_AR_BLANK_SHIFT)) & LCD_AR_BLANK_MASK) +#define LCD_AR_ALT_MASK (0x40U) +#define LCD_AR_ALT_SHIFT (6U) +#define LCD_AR_ALT(x) (((uint32_t)(((uint32_t)(x)) << LCD_AR_ALT_SHIFT)) & LCD_AR_ALT_MASK) +#define LCD_AR_BLINK_MASK (0x80U) +#define LCD_AR_BLINK_SHIFT (7U) +#define LCD_AR_BLINK(x) (((uint32_t)(((uint32_t)(x)) << LCD_AR_BLINK_SHIFT)) & LCD_AR_BLINK_MASK) + +/*! @name FDCR - LCD Fault Detect Control Register */ +#define LCD_FDCR_FDPINID_MASK (0x3FU) +#define LCD_FDCR_FDPINID_SHIFT (0U) +#define LCD_FDCR_FDPINID(x) (((uint32_t)(((uint32_t)(x)) << LCD_FDCR_FDPINID_SHIFT)) & LCD_FDCR_FDPINID_MASK) +#define LCD_FDCR_FDBPEN_MASK (0x40U) +#define LCD_FDCR_FDBPEN_SHIFT (6U) +#define LCD_FDCR_FDBPEN(x) (((uint32_t)(((uint32_t)(x)) << LCD_FDCR_FDBPEN_SHIFT)) & LCD_FDCR_FDBPEN_MASK) +#define LCD_FDCR_FDEN_MASK (0x80U) +#define LCD_FDCR_FDEN_SHIFT (7U) +#define LCD_FDCR_FDEN(x) (((uint32_t)(((uint32_t)(x)) << LCD_FDCR_FDEN_SHIFT)) & LCD_FDCR_FDEN_MASK) +#define LCD_FDCR_FDSWW_MASK (0xE00U) +#define LCD_FDCR_FDSWW_SHIFT (9U) +#define LCD_FDCR_FDSWW(x) (((uint32_t)(((uint32_t)(x)) << LCD_FDCR_FDSWW_SHIFT)) & LCD_FDCR_FDSWW_MASK) +#define LCD_FDCR_FDPRS_MASK (0x7000U) +#define LCD_FDCR_FDPRS_SHIFT (12U) +#define LCD_FDCR_FDPRS(x) (((uint32_t)(((uint32_t)(x)) << LCD_FDCR_FDPRS_SHIFT)) & LCD_FDCR_FDPRS_MASK) + +/*! @name FDSR - LCD Fault Detect Status Register */ +#define LCD_FDSR_FDCNT_MASK (0xFFU) +#define LCD_FDSR_FDCNT_SHIFT (0U) +#define LCD_FDSR_FDCNT(x) (((uint32_t)(((uint32_t)(x)) << LCD_FDSR_FDCNT_SHIFT)) & LCD_FDSR_FDCNT_MASK) +#define LCD_FDSR_FDCF_MASK (0x8000U) +#define LCD_FDSR_FDCF_SHIFT (15U) +#define LCD_FDSR_FDCF(x) (((uint32_t)(((uint32_t)(x)) << LCD_FDSR_FDCF_SHIFT)) & LCD_FDSR_FDCF_MASK) + +/*! @name PEN - LCD Pin Enable register */ +#define LCD_PEN_PEN_MASK (0xFFFFFFFFU) +#define LCD_PEN_PEN_SHIFT (0U) +#define LCD_PEN_PEN(x) (((uint32_t)(((uint32_t)(x)) << LCD_PEN_PEN_SHIFT)) & LCD_PEN_PEN_MASK) + +/* The count of LCD_PEN */ +#define LCD_PEN_COUNT (2U) + +/*! @name BPEN - LCD Back Plane Enable register */ +#define LCD_BPEN_BPEN_MASK (0xFFFFFFFFU) +#define LCD_BPEN_BPEN_SHIFT (0U) +#define LCD_BPEN_BPEN(x) (((uint32_t)(((uint32_t)(x)) << LCD_BPEN_BPEN_SHIFT)) & LCD_BPEN_BPEN_MASK) + +/* The count of LCD_BPEN */ +#define LCD_BPEN_COUNT (2U) + +/*! @name WF - LCD Waveform register */ +#define LCD_WF_WF0_MASK (0xFFU) +#define LCD_WF_WF0_SHIFT (0U) +#define LCD_WF_WF0(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF0_SHIFT)) & LCD_WF_WF0_MASK) +#define LCD_WF_WF60_MASK (0xFFU) +#define LCD_WF_WF60_SHIFT (0U) +#define LCD_WF_WF60(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF60_SHIFT)) & LCD_WF_WF60_MASK) +#define LCD_WF_WF56_MASK (0xFFU) +#define LCD_WF_WF56_SHIFT (0U) +#define LCD_WF_WF56(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF56_SHIFT)) & LCD_WF_WF56_MASK) +#define LCD_WF_WF52_MASK (0xFFU) +#define LCD_WF_WF52_SHIFT (0U) +#define LCD_WF_WF52(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF52_SHIFT)) & LCD_WF_WF52_MASK) +#define LCD_WF_WF4_MASK (0xFFU) +#define LCD_WF_WF4_SHIFT (0U) +#define LCD_WF_WF4(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF4_SHIFT)) & LCD_WF_WF4_MASK) +#define LCD_WF_WF48_MASK (0xFFU) +#define LCD_WF_WF48_SHIFT (0U) +#define LCD_WF_WF48(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF48_SHIFT)) & LCD_WF_WF48_MASK) +#define LCD_WF_WF44_MASK (0xFFU) +#define LCD_WF_WF44_SHIFT (0U) +#define LCD_WF_WF44(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF44_SHIFT)) & LCD_WF_WF44_MASK) +#define LCD_WF_WF40_MASK (0xFFU) +#define LCD_WF_WF40_SHIFT (0U) +#define LCD_WF_WF40(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF40_SHIFT)) & LCD_WF_WF40_MASK) +#define LCD_WF_WF8_MASK (0xFFU) +#define LCD_WF_WF8_SHIFT (0U) +#define LCD_WF_WF8(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF8_SHIFT)) & LCD_WF_WF8_MASK) +#define LCD_WF_WF36_MASK (0xFFU) +#define LCD_WF_WF36_SHIFT (0U) +#define LCD_WF_WF36(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF36_SHIFT)) & LCD_WF_WF36_MASK) +#define LCD_WF_WF32_MASK (0xFFU) +#define LCD_WF_WF32_SHIFT (0U) +#define LCD_WF_WF32(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF32_SHIFT)) & LCD_WF_WF32_MASK) +#define LCD_WF_WF28_MASK (0xFFU) +#define LCD_WF_WF28_SHIFT (0U) +#define LCD_WF_WF28(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF28_SHIFT)) & LCD_WF_WF28_MASK) +#define LCD_WF_WF12_MASK (0xFFU) +#define LCD_WF_WF12_SHIFT (0U) +#define LCD_WF_WF12(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF12_SHIFT)) & LCD_WF_WF12_MASK) +#define LCD_WF_WF24_MASK (0xFFU) +#define LCD_WF_WF24_SHIFT (0U) +#define LCD_WF_WF24(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF24_SHIFT)) & LCD_WF_WF24_MASK) +#define LCD_WF_WF20_MASK (0xFFU) +#define LCD_WF_WF20_SHIFT (0U) +#define LCD_WF_WF20(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF20_SHIFT)) & LCD_WF_WF20_MASK) +#define LCD_WF_WF16_MASK (0xFFU) +#define LCD_WF_WF16_SHIFT (0U) +#define LCD_WF_WF16(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF16_SHIFT)) & LCD_WF_WF16_MASK) +#define LCD_WF_WF5_MASK (0xFF00U) +#define LCD_WF_WF5_SHIFT (8U) +#define LCD_WF_WF5(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF5_SHIFT)) & LCD_WF_WF5_MASK) +#define LCD_WF_WF49_MASK (0xFF00U) +#define LCD_WF_WF49_SHIFT (8U) +#define LCD_WF_WF49(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF49_SHIFT)) & LCD_WF_WF49_MASK) +#define LCD_WF_WF45_MASK (0xFF00U) +#define LCD_WF_WF45_SHIFT (8U) +#define LCD_WF_WF45(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF45_SHIFT)) & LCD_WF_WF45_MASK) +#define LCD_WF_WF61_MASK (0xFF00U) +#define LCD_WF_WF61_SHIFT (8U) +#define LCD_WF_WF61(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF61_SHIFT)) & LCD_WF_WF61_MASK) +#define LCD_WF_WF25_MASK (0xFF00U) +#define LCD_WF_WF25_SHIFT (8U) +#define LCD_WF_WF25(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF25_SHIFT)) & LCD_WF_WF25_MASK) +#define LCD_WF_WF17_MASK (0xFF00U) +#define LCD_WF_WF17_SHIFT (8U) +#define LCD_WF_WF17(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF17_SHIFT)) & LCD_WF_WF17_MASK) +#define LCD_WF_WF41_MASK (0xFF00U) +#define LCD_WF_WF41_SHIFT (8U) +#define LCD_WF_WF41(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF41_SHIFT)) & LCD_WF_WF41_MASK) +#define LCD_WF_WF13_MASK (0xFF00U) +#define LCD_WF_WF13_SHIFT (8U) +#define LCD_WF_WF13(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF13_SHIFT)) & LCD_WF_WF13_MASK) +#define LCD_WF_WF57_MASK (0xFF00U) +#define LCD_WF_WF57_SHIFT (8U) +#define LCD_WF_WF57(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF57_SHIFT)) & LCD_WF_WF57_MASK) +#define LCD_WF_WF53_MASK (0xFF00U) +#define LCD_WF_WF53_SHIFT (8U) +#define LCD_WF_WF53(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF53_SHIFT)) & LCD_WF_WF53_MASK) +#define LCD_WF_WF37_MASK (0xFF00U) +#define LCD_WF_WF37_SHIFT (8U) +#define LCD_WF_WF37(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF37_SHIFT)) & LCD_WF_WF37_MASK) +#define LCD_WF_WF9_MASK (0xFF00U) +#define LCD_WF_WF9_SHIFT (8U) +#define LCD_WF_WF9(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF9_SHIFT)) & LCD_WF_WF9_MASK) +#define LCD_WF_WF1_MASK (0xFF00U) +#define LCD_WF_WF1_SHIFT (8U) +#define LCD_WF_WF1(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF1_SHIFT)) & LCD_WF_WF1_MASK) +#define LCD_WF_WF29_MASK (0xFF00U) +#define LCD_WF_WF29_SHIFT (8U) +#define LCD_WF_WF29(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF29_SHIFT)) & LCD_WF_WF29_MASK) +#define LCD_WF_WF33_MASK (0xFF00U) +#define LCD_WF_WF33_SHIFT (8U) +#define LCD_WF_WF33(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF33_SHIFT)) & LCD_WF_WF33_MASK) +#define LCD_WF_WF21_MASK (0xFF00U) +#define LCD_WF_WF21_SHIFT (8U) +#define LCD_WF_WF21(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF21_SHIFT)) & LCD_WF_WF21_MASK) +#define LCD_WF_WF26_MASK (0xFF0000U) +#define LCD_WF_WF26_SHIFT (16U) +#define LCD_WF_WF26(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF26_SHIFT)) & LCD_WF_WF26_MASK) +#define LCD_WF_WF46_MASK (0xFF0000U) +#define LCD_WF_WF46_SHIFT (16U) +#define LCD_WF_WF46(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF46_SHIFT)) & LCD_WF_WF46_MASK) +#define LCD_WF_WF6_MASK (0xFF0000U) +#define LCD_WF_WF6_SHIFT (16U) +#define LCD_WF_WF6(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF6_SHIFT)) & LCD_WF_WF6_MASK) +#define LCD_WF_WF42_MASK (0xFF0000U) +#define LCD_WF_WF42_SHIFT (16U) +#define LCD_WF_WF42(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF42_SHIFT)) & LCD_WF_WF42_MASK) +#define LCD_WF_WF18_MASK (0xFF0000U) +#define LCD_WF_WF18_SHIFT (16U) +#define LCD_WF_WF18(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF18_SHIFT)) & LCD_WF_WF18_MASK) +#define LCD_WF_WF38_MASK (0xFF0000U) +#define LCD_WF_WF38_SHIFT (16U) +#define LCD_WF_WF38(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF38_SHIFT)) & LCD_WF_WF38_MASK) +#define LCD_WF_WF22_MASK (0xFF0000U) +#define LCD_WF_WF22_SHIFT (16U) +#define LCD_WF_WF22(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF22_SHIFT)) & LCD_WF_WF22_MASK) +#define LCD_WF_WF34_MASK (0xFF0000U) +#define LCD_WF_WF34_SHIFT (16U) +#define LCD_WF_WF34(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF34_SHIFT)) & LCD_WF_WF34_MASK) +#define LCD_WF_WF50_MASK (0xFF0000U) +#define LCD_WF_WF50_SHIFT (16U) +#define LCD_WF_WF50(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF50_SHIFT)) & LCD_WF_WF50_MASK) +#define LCD_WF_WF14_MASK (0xFF0000U) +#define LCD_WF_WF14_SHIFT (16U) +#define LCD_WF_WF14(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF14_SHIFT)) & LCD_WF_WF14_MASK) +#define LCD_WF_WF54_MASK (0xFF0000U) +#define LCD_WF_WF54_SHIFT (16U) +#define LCD_WF_WF54(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF54_SHIFT)) & LCD_WF_WF54_MASK) +#define LCD_WF_WF2_MASK (0xFF0000U) +#define LCD_WF_WF2_SHIFT (16U) +#define LCD_WF_WF2(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF2_SHIFT)) & LCD_WF_WF2_MASK) +#define LCD_WF_WF58_MASK (0xFF0000U) +#define LCD_WF_WF58_SHIFT (16U) +#define LCD_WF_WF58(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF58_SHIFT)) & LCD_WF_WF58_MASK) +#define LCD_WF_WF30_MASK (0xFF0000U) +#define LCD_WF_WF30_SHIFT (16U) +#define LCD_WF_WF30(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF30_SHIFT)) & LCD_WF_WF30_MASK) +#define LCD_WF_WF62_MASK (0xFF0000U) +#define LCD_WF_WF62_SHIFT (16U) +#define LCD_WF_WF62(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF62_SHIFT)) & LCD_WF_WF62_MASK) +#define LCD_WF_WF10_MASK (0xFF0000U) +#define LCD_WF_WF10_SHIFT (16U) +#define LCD_WF_WF10(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF10_SHIFT)) & LCD_WF_WF10_MASK) +#define LCD_WF_WF63_MASK (0xFF000000U) +#define LCD_WF_WF63_SHIFT (24U) +#define LCD_WF_WF63(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF63_SHIFT)) & LCD_WF_WF63_MASK) +#define LCD_WF_WF59_MASK (0xFF000000U) +#define LCD_WF_WF59_SHIFT (24U) +#define LCD_WF_WF59(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF59_SHIFT)) & LCD_WF_WF59_MASK) +#define LCD_WF_WF55_MASK (0xFF000000U) +#define LCD_WF_WF55_SHIFT (24U) +#define LCD_WF_WF55(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF55_SHIFT)) & LCD_WF_WF55_MASK) +#define LCD_WF_WF3_MASK (0xFF000000U) +#define LCD_WF_WF3_SHIFT (24U) +#define LCD_WF_WF3(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF3_SHIFT)) & LCD_WF_WF3_MASK) +#define LCD_WF_WF51_MASK (0xFF000000U) +#define LCD_WF_WF51_SHIFT (24U) +#define LCD_WF_WF51(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF51_SHIFT)) & LCD_WF_WF51_MASK) +#define LCD_WF_WF47_MASK (0xFF000000U) +#define LCD_WF_WF47_SHIFT (24U) +#define LCD_WF_WF47(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF47_SHIFT)) & LCD_WF_WF47_MASK) +#define LCD_WF_WF43_MASK (0xFF000000U) +#define LCD_WF_WF43_SHIFT (24U) +#define LCD_WF_WF43(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF43_SHIFT)) & LCD_WF_WF43_MASK) +#define LCD_WF_WF7_MASK (0xFF000000U) +#define LCD_WF_WF7_SHIFT (24U) +#define LCD_WF_WF7(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF7_SHIFT)) & LCD_WF_WF7_MASK) +#define LCD_WF_WF39_MASK (0xFF000000U) +#define LCD_WF_WF39_SHIFT (24U) +#define LCD_WF_WF39(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF39_SHIFT)) & LCD_WF_WF39_MASK) +#define LCD_WF_WF35_MASK (0xFF000000U) +#define LCD_WF_WF35_SHIFT (24U) +#define LCD_WF_WF35(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF35_SHIFT)) & LCD_WF_WF35_MASK) +#define LCD_WF_WF31_MASK (0xFF000000U) +#define LCD_WF_WF31_SHIFT (24U) +#define LCD_WF_WF31(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF31_SHIFT)) & LCD_WF_WF31_MASK) +#define LCD_WF_WF11_MASK (0xFF000000U) +#define LCD_WF_WF11_SHIFT (24U) +#define LCD_WF_WF11(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF11_SHIFT)) & LCD_WF_WF11_MASK) +#define LCD_WF_WF27_MASK (0xFF000000U) +#define LCD_WF_WF27_SHIFT (24U) +#define LCD_WF_WF27(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF27_SHIFT)) & LCD_WF_WF27_MASK) +#define LCD_WF_WF23_MASK (0xFF000000U) +#define LCD_WF_WF23_SHIFT (24U) +#define LCD_WF_WF23(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF23_SHIFT)) & LCD_WF_WF23_MASK) +#define LCD_WF_WF19_MASK (0xFF000000U) +#define LCD_WF_WF19_SHIFT (24U) +#define LCD_WF_WF19(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF19_SHIFT)) & LCD_WF_WF19_MASK) +#define LCD_WF_WF15_MASK (0xFF000000U) +#define LCD_WF_WF15_SHIFT (24U) +#define LCD_WF_WF15(x) (((uint32_t)(((uint32_t)(x)) << LCD_WF_WF15_SHIFT)) & LCD_WF_WF15_MASK) + +/* The count of LCD_WF */ +#define LCD_WF_COUNT (16U) + +/*! @name WF8B - LCD Waveform Register 0...LCD Waveform Register 63. */ +#define LCD_WF8B_BPALCD0_MASK (0x1U) +#define LCD_WF8B_BPALCD0_SHIFT (0U) +#define LCD_WF8B_BPALCD0(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD0_SHIFT)) & LCD_WF8B_BPALCD0_MASK) +#define LCD_WF8B_BPALCD63_MASK (0x1U) +#define LCD_WF8B_BPALCD63_SHIFT (0U) +#define LCD_WF8B_BPALCD63(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD63_SHIFT)) & LCD_WF8B_BPALCD63_MASK) +#define LCD_WF8B_BPALCD62_MASK (0x1U) +#define LCD_WF8B_BPALCD62_SHIFT (0U) +#define LCD_WF8B_BPALCD62(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD62_SHIFT)) & LCD_WF8B_BPALCD62_MASK) +#define LCD_WF8B_BPALCD61_MASK (0x1U) +#define LCD_WF8B_BPALCD61_SHIFT (0U) +#define LCD_WF8B_BPALCD61(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD61_SHIFT)) & LCD_WF8B_BPALCD61_MASK) +#define LCD_WF8B_BPALCD60_MASK (0x1U) +#define LCD_WF8B_BPALCD60_SHIFT (0U) +#define LCD_WF8B_BPALCD60(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD60_SHIFT)) & LCD_WF8B_BPALCD60_MASK) +#define LCD_WF8B_BPALCD59_MASK (0x1U) +#define LCD_WF8B_BPALCD59_SHIFT (0U) +#define LCD_WF8B_BPALCD59(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD59_SHIFT)) & LCD_WF8B_BPALCD59_MASK) +#define LCD_WF8B_BPALCD58_MASK (0x1U) +#define LCD_WF8B_BPALCD58_SHIFT (0U) +#define LCD_WF8B_BPALCD58(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD58_SHIFT)) & LCD_WF8B_BPALCD58_MASK) +#define LCD_WF8B_BPALCD57_MASK (0x1U) +#define LCD_WF8B_BPALCD57_SHIFT (0U) +#define LCD_WF8B_BPALCD57(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD57_SHIFT)) & LCD_WF8B_BPALCD57_MASK) +#define LCD_WF8B_BPALCD1_MASK (0x1U) +#define LCD_WF8B_BPALCD1_SHIFT (0U) +#define LCD_WF8B_BPALCD1(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD1_SHIFT)) & LCD_WF8B_BPALCD1_MASK) +#define LCD_WF8B_BPALCD56_MASK (0x1U) +#define LCD_WF8B_BPALCD56_SHIFT (0U) +#define LCD_WF8B_BPALCD56(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD56_SHIFT)) & LCD_WF8B_BPALCD56_MASK) +#define LCD_WF8B_BPALCD55_MASK (0x1U) +#define LCD_WF8B_BPALCD55_SHIFT (0U) +#define LCD_WF8B_BPALCD55(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD55_SHIFT)) & LCD_WF8B_BPALCD55_MASK) +#define LCD_WF8B_BPALCD54_MASK (0x1U) +#define LCD_WF8B_BPALCD54_SHIFT (0U) +#define LCD_WF8B_BPALCD54(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD54_SHIFT)) & LCD_WF8B_BPALCD54_MASK) +#define LCD_WF8B_BPALCD53_MASK (0x1U) +#define LCD_WF8B_BPALCD53_SHIFT (0U) +#define LCD_WF8B_BPALCD53(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD53_SHIFT)) & LCD_WF8B_BPALCD53_MASK) +#define LCD_WF8B_BPALCD52_MASK (0x1U) +#define LCD_WF8B_BPALCD52_SHIFT (0U) +#define LCD_WF8B_BPALCD52(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD52_SHIFT)) & LCD_WF8B_BPALCD52_MASK) +#define LCD_WF8B_BPALCD51_MASK (0x1U) +#define LCD_WF8B_BPALCD51_SHIFT (0U) +#define LCD_WF8B_BPALCD51(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD51_SHIFT)) & LCD_WF8B_BPALCD51_MASK) +#define LCD_WF8B_BPALCD50_MASK (0x1U) +#define LCD_WF8B_BPALCD50_SHIFT (0U) +#define LCD_WF8B_BPALCD50(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD50_SHIFT)) & LCD_WF8B_BPALCD50_MASK) +#define LCD_WF8B_BPALCD2_MASK (0x1U) +#define LCD_WF8B_BPALCD2_SHIFT (0U) +#define LCD_WF8B_BPALCD2(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD2_SHIFT)) & LCD_WF8B_BPALCD2_MASK) +#define LCD_WF8B_BPALCD49_MASK (0x1U) +#define LCD_WF8B_BPALCD49_SHIFT (0U) +#define LCD_WF8B_BPALCD49(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD49_SHIFT)) & LCD_WF8B_BPALCD49_MASK) +#define LCD_WF8B_BPALCD48_MASK (0x1U) +#define LCD_WF8B_BPALCD48_SHIFT (0U) +#define LCD_WF8B_BPALCD48(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD48_SHIFT)) & LCD_WF8B_BPALCD48_MASK) +#define LCD_WF8B_BPALCD47_MASK (0x1U) +#define LCD_WF8B_BPALCD47_SHIFT (0U) +#define LCD_WF8B_BPALCD47(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD47_SHIFT)) & LCD_WF8B_BPALCD47_MASK) +#define LCD_WF8B_BPALCD46_MASK (0x1U) +#define LCD_WF8B_BPALCD46_SHIFT (0U) +#define LCD_WF8B_BPALCD46(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD46_SHIFT)) & LCD_WF8B_BPALCD46_MASK) +#define LCD_WF8B_BPALCD45_MASK (0x1U) +#define LCD_WF8B_BPALCD45_SHIFT (0U) +#define LCD_WF8B_BPALCD45(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD45_SHIFT)) & LCD_WF8B_BPALCD45_MASK) +#define LCD_WF8B_BPALCD44_MASK (0x1U) +#define LCD_WF8B_BPALCD44_SHIFT (0U) +#define LCD_WF8B_BPALCD44(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD44_SHIFT)) & LCD_WF8B_BPALCD44_MASK) +#define LCD_WF8B_BPALCD43_MASK (0x1U) +#define LCD_WF8B_BPALCD43_SHIFT (0U) +#define LCD_WF8B_BPALCD43(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD43_SHIFT)) & LCD_WF8B_BPALCD43_MASK) +#define LCD_WF8B_BPALCD3_MASK (0x1U) +#define LCD_WF8B_BPALCD3_SHIFT (0U) +#define LCD_WF8B_BPALCD3(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD3_SHIFT)) & LCD_WF8B_BPALCD3_MASK) +#define LCD_WF8B_BPALCD42_MASK (0x1U) +#define LCD_WF8B_BPALCD42_SHIFT (0U) +#define LCD_WF8B_BPALCD42(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD42_SHIFT)) & LCD_WF8B_BPALCD42_MASK) +#define LCD_WF8B_BPALCD41_MASK (0x1U) +#define LCD_WF8B_BPALCD41_SHIFT (0U) +#define LCD_WF8B_BPALCD41(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD41_SHIFT)) & LCD_WF8B_BPALCD41_MASK) +#define LCD_WF8B_BPALCD40_MASK (0x1U) +#define LCD_WF8B_BPALCD40_SHIFT (0U) +#define LCD_WF8B_BPALCD40(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD40_SHIFT)) & LCD_WF8B_BPALCD40_MASK) +#define LCD_WF8B_BPALCD39_MASK (0x1U) +#define LCD_WF8B_BPALCD39_SHIFT (0U) +#define LCD_WF8B_BPALCD39(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD39_SHIFT)) & LCD_WF8B_BPALCD39_MASK) +#define LCD_WF8B_BPALCD38_MASK (0x1U) +#define LCD_WF8B_BPALCD38_SHIFT (0U) +#define LCD_WF8B_BPALCD38(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD38_SHIFT)) & LCD_WF8B_BPALCD38_MASK) +#define LCD_WF8B_BPALCD37_MASK (0x1U) +#define LCD_WF8B_BPALCD37_SHIFT (0U) +#define LCD_WF8B_BPALCD37(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD37_SHIFT)) & LCD_WF8B_BPALCD37_MASK) +#define LCD_WF8B_BPALCD36_MASK (0x1U) +#define LCD_WF8B_BPALCD36_SHIFT (0U) +#define LCD_WF8B_BPALCD36(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD36_SHIFT)) & LCD_WF8B_BPALCD36_MASK) +#define LCD_WF8B_BPALCD4_MASK (0x1U) +#define LCD_WF8B_BPALCD4_SHIFT (0U) +#define LCD_WF8B_BPALCD4(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD4_SHIFT)) & LCD_WF8B_BPALCD4_MASK) +#define LCD_WF8B_BPALCD35_MASK (0x1U) +#define LCD_WF8B_BPALCD35_SHIFT (0U) +#define LCD_WF8B_BPALCD35(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD35_SHIFT)) & LCD_WF8B_BPALCD35_MASK) +#define LCD_WF8B_BPALCD34_MASK (0x1U) +#define LCD_WF8B_BPALCD34_SHIFT (0U) +#define LCD_WF8B_BPALCD34(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD34_SHIFT)) & LCD_WF8B_BPALCD34_MASK) +#define LCD_WF8B_BPALCD33_MASK (0x1U) +#define LCD_WF8B_BPALCD33_SHIFT (0U) +#define LCD_WF8B_BPALCD33(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD33_SHIFT)) & LCD_WF8B_BPALCD33_MASK) +#define LCD_WF8B_BPALCD32_MASK (0x1U) +#define LCD_WF8B_BPALCD32_SHIFT (0U) +#define LCD_WF8B_BPALCD32(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD32_SHIFT)) & LCD_WF8B_BPALCD32_MASK) +#define LCD_WF8B_BPALCD31_MASK (0x1U) +#define LCD_WF8B_BPALCD31_SHIFT (0U) +#define LCD_WF8B_BPALCD31(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD31_SHIFT)) & LCD_WF8B_BPALCD31_MASK) +#define LCD_WF8B_BPALCD30_MASK (0x1U) +#define LCD_WF8B_BPALCD30_SHIFT (0U) +#define LCD_WF8B_BPALCD30(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD30_SHIFT)) & LCD_WF8B_BPALCD30_MASK) +#define LCD_WF8B_BPALCD29_MASK (0x1U) +#define LCD_WF8B_BPALCD29_SHIFT (0U) +#define LCD_WF8B_BPALCD29(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD29_SHIFT)) & LCD_WF8B_BPALCD29_MASK) +#define LCD_WF8B_BPALCD5_MASK (0x1U) +#define LCD_WF8B_BPALCD5_SHIFT (0U) +#define LCD_WF8B_BPALCD5(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD5_SHIFT)) & LCD_WF8B_BPALCD5_MASK) +#define LCD_WF8B_BPALCD28_MASK (0x1U) +#define LCD_WF8B_BPALCD28_SHIFT (0U) +#define LCD_WF8B_BPALCD28(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD28_SHIFT)) & LCD_WF8B_BPALCD28_MASK) +#define LCD_WF8B_BPALCD27_MASK (0x1U) +#define LCD_WF8B_BPALCD27_SHIFT (0U) +#define LCD_WF8B_BPALCD27(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD27_SHIFT)) & LCD_WF8B_BPALCD27_MASK) +#define LCD_WF8B_BPALCD26_MASK (0x1U) +#define LCD_WF8B_BPALCD26_SHIFT (0U) +#define LCD_WF8B_BPALCD26(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD26_SHIFT)) & LCD_WF8B_BPALCD26_MASK) +#define LCD_WF8B_BPALCD25_MASK (0x1U) +#define LCD_WF8B_BPALCD25_SHIFT (0U) +#define LCD_WF8B_BPALCD25(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD25_SHIFT)) & LCD_WF8B_BPALCD25_MASK) +#define LCD_WF8B_BPALCD24_MASK (0x1U) +#define LCD_WF8B_BPALCD24_SHIFT (0U) +#define LCD_WF8B_BPALCD24(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD24_SHIFT)) & LCD_WF8B_BPALCD24_MASK) +#define LCD_WF8B_BPALCD23_MASK (0x1U) +#define LCD_WF8B_BPALCD23_SHIFT (0U) +#define LCD_WF8B_BPALCD23(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD23_SHIFT)) & LCD_WF8B_BPALCD23_MASK) +#define LCD_WF8B_BPALCD22_MASK (0x1U) +#define LCD_WF8B_BPALCD22_SHIFT (0U) +#define LCD_WF8B_BPALCD22(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD22_SHIFT)) & LCD_WF8B_BPALCD22_MASK) +#define LCD_WF8B_BPALCD6_MASK (0x1U) +#define LCD_WF8B_BPALCD6_SHIFT (0U) +#define LCD_WF8B_BPALCD6(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD6_SHIFT)) & LCD_WF8B_BPALCD6_MASK) +#define LCD_WF8B_BPALCD21_MASK (0x1U) +#define LCD_WF8B_BPALCD21_SHIFT (0U) +#define LCD_WF8B_BPALCD21(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD21_SHIFT)) & LCD_WF8B_BPALCD21_MASK) +#define LCD_WF8B_BPALCD20_MASK (0x1U) +#define LCD_WF8B_BPALCD20_SHIFT (0U) +#define LCD_WF8B_BPALCD20(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD20_SHIFT)) & LCD_WF8B_BPALCD20_MASK) +#define LCD_WF8B_BPALCD19_MASK (0x1U) +#define LCD_WF8B_BPALCD19_SHIFT (0U) +#define LCD_WF8B_BPALCD19(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD19_SHIFT)) & LCD_WF8B_BPALCD19_MASK) +#define LCD_WF8B_BPALCD18_MASK (0x1U) +#define LCD_WF8B_BPALCD18_SHIFT (0U) +#define LCD_WF8B_BPALCD18(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD18_SHIFT)) & LCD_WF8B_BPALCD18_MASK) +#define LCD_WF8B_BPALCD17_MASK (0x1U) +#define LCD_WF8B_BPALCD17_SHIFT (0U) +#define LCD_WF8B_BPALCD17(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD17_SHIFT)) & LCD_WF8B_BPALCD17_MASK) +#define LCD_WF8B_BPALCD16_MASK (0x1U) +#define LCD_WF8B_BPALCD16_SHIFT (0U) +#define LCD_WF8B_BPALCD16(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD16_SHIFT)) & LCD_WF8B_BPALCD16_MASK) +#define LCD_WF8B_BPALCD15_MASK (0x1U) +#define LCD_WF8B_BPALCD15_SHIFT (0U) +#define LCD_WF8B_BPALCD15(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD15_SHIFT)) & LCD_WF8B_BPALCD15_MASK) +#define LCD_WF8B_BPALCD7_MASK (0x1U) +#define LCD_WF8B_BPALCD7_SHIFT (0U) +#define LCD_WF8B_BPALCD7(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD7_SHIFT)) & LCD_WF8B_BPALCD7_MASK) +#define LCD_WF8B_BPALCD14_MASK (0x1U) +#define LCD_WF8B_BPALCD14_SHIFT (0U) +#define LCD_WF8B_BPALCD14(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD14_SHIFT)) & LCD_WF8B_BPALCD14_MASK) +#define LCD_WF8B_BPALCD13_MASK (0x1U) +#define LCD_WF8B_BPALCD13_SHIFT (0U) +#define LCD_WF8B_BPALCD13(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD13_SHIFT)) & LCD_WF8B_BPALCD13_MASK) +#define LCD_WF8B_BPALCD12_MASK (0x1U) +#define LCD_WF8B_BPALCD12_SHIFT (0U) +#define LCD_WF8B_BPALCD12(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD12_SHIFT)) & LCD_WF8B_BPALCD12_MASK) +#define LCD_WF8B_BPALCD11_MASK (0x1U) +#define LCD_WF8B_BPALCD11_SHIFT (0U) +#define LCD_WF8B_BPALCD11(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD11_SHIFT)) & LCD_WF8B_BPALCD11_MASK) +#define LCD_WF8B_BPALCD10_MASK (0x1U) +#define LCD_WF8B_BPALCD10_SHIFT (0U) +#define LCD_WF8B_BPALCD10(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD10_SHIFT)) & LCD_WF8B_BPALCD10_MASK) +#define LCD_WF8B_BPALCD9_MASK (0x1U) +#define LCD_WF8B_BPALCD9_SHIFT (0U) +#define LCD_WF8B_BPALCD9(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD9_SHIFT)) & LCD_WF8B_BPALCD9_MASK) +#define LCD_WF8B_BPALCD8_MASK (0x1U) +#define LCD_WF8B_BPALCD8_SHIFT (0U) +#define LCD_WF8B_BPALCD8(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPALCD8_SHIFT)) & LCD_WF8B_BPALCD8_MASK) +#define LCD_WF8B_BPBLCD1_MASK (0x2U) +#define LCD_WF8B_BPBLCD1_SHIFT (1U) +#define LCD_WF8B_BPBLCD1(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD1_SHIFT)) & LCD_WF8B_BPBLCD1_MASK) +#define LCD_WF8B_BPBLCD32_MASK (0x2U) +#define LCD_WF8B_BPBLCD32_SHIFT (1U) +#define LCD_WF8B_BPBLCD32(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD32_SHIFT)) & LCD_WF8B_BPBLCD32_MASK) +#define LCD_WF8B_BPBLCD30_MASK (0x2U) +#define LCD_WF8B_BPBLCD30_SHIFT (1U) +#define LCD_WF8B_BPBLCD30(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD30_SHIFT)) & LCD_WF8B_BPBLCD30_MASK) +#define LCD_WF8B_BPBLCD60_MASK (0x2U) +#define LCD_WF8B_BPBLCD60_SHIFT (1U) +#define LCD_WF8B_BPBLCD60(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD60_SHIFT)) & LCD_WF8B_BPBLCD60_MASK) +#define LCD_WF8B_BPBLCD24_MASK (0x2U) +#define LCD_WF8B_BPBLCD24_SHIFT (1U) +#define LCD_WF8B_BPBLCD24(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD24_SHIFT)) & LCD_WF8B_BPBLCD24_MASK) +#define LCD_WF8B_BPBLCD28_MASK (0x2U) +#define LCD_WF8B_BPBLCD28_SHIFT (1U) +#define LCD_WF8B_BPBLCD28(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD28_SHIFT)) & LCD_WF8B_BPBLCD28_MASK) +#define LCD_WF8B_BPBLCD23_MASK (0x2U) +#define LCD_WF8B_BPBLCD23_SHIFT (1U) +#define LCD_WF8B_BPBLCD23(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD23_SHIFT)) & LCD_WF8B_BPBLCD23_MASK) +#define LCD_WF8B_BPBLCD48_MASK (0x2U) +#define LCD_WF8B_BPBLCD48_SHIFT (1U) +#define LCD_WF8B_BPBLCD48(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD48_SHIFT)) & LCD_WF8B_BPBLCD48_MASK) +#define LCD_WF8B_BPBLCD10_MASK (0x2U) +#define LCD_WF8B_BPBLCD10_SHIFT (1U) +#define LCD_WF8B_BPBLCD10(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD10_SHIFT)) & LCD_WF8B_BPBLCD10_MASK) +#define LCD_WF8B_BPBLCD15_MASK (0x2U) +#define LCD_WF8B_BPBLCD15_SHIFT (1U) +#define LCD_WF8B_BPBLCD15(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD15_SHIFT)) & LCD_WF8B_BPBLCD15_MASK) +#define LCD_WF8B_BPBLCD36_MASK (0x2U) +#define LCD_WF8B_BPBLCD36_SHIFT (1U) +#define LCD_WF8B_BPBLCD36(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD36_SHIFT)) & LCD_WF8B_BPBLCD36_MASK) +#define LCD_WF8B_BPBLCD44_MASK (0x2U) +#define LCD_WF8B_BPBLCD44_SHIFT (1U) +#define LCD_WF8B_BPBLCD44(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD44_SHIFT)) & LCD_WF8B_BPBLCD44_MASK) +#define LCD_WF8B_BPBLCD62_MASK (0x2U) +#define LCD_WF8B_BPBLCD62_SHIFT (1U) +#define LCD_WF8B_BPBLCD62(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD62_SHIFT)) & LCD_WF8B_BPBLCD62_MASK) +#define LCD_WF8B_BPBLCD53_MASK (0x2U) +#define LCD_WF8B_BPBLCD53_SHIFT (1U) +#define LCD_WF8B_BPBLCD53(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD53_SHIFT)) & LCD_WF8B_BPBLCD53_MASK) +#define LCD_WF8B_BPBLCD22_MASK (0x2U) +#define LCD_WF8B_BPBLCD22_SHIFT (1U) +#define LCD_WF8B_BPBLCD22(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD22_SHIFT)) & LCD_WF8B_BPBLCD22_MASK) +#define LCD_WF8B_BPBLCD47_MASK (0x2U) +#define LCD_WF8B_BPBLCD47_SHIFT (1U) +#define LCD_WF8B_BPBLCD47(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD47_SHIFT)) & LCD_WF8B_BPBLCD47_MASK) +#define LCD_WF8B_BPBLCD33_MASK (0x2U) +#define LCD_WF8B_BPBLCD33_SHIFT (1U) +#define LCD_WF8B_BPBLCD33(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD33_SHIFT)) & LCD_WF8B_BPBLCD33_MASK) +#define LCD_WF8B_BPBLCD2_MASK (0x2U) +#define LCD_WF8B_BPBLCD2_SHIFT (1U) +#define LCD_WF8B_BPBLCD2(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD2_SHIFT)) & LCD_WF8B_BPBLCD2_MASK) +#define LCD_WF8B_BPBLCD49_MASK (0x2U) +#define LCD_WF8B_BPBLCD49_SHIFT (1U) +#define LCD_WF8B_BPBLCD49(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD49_SHIFT)) & LCD_WF8B_BPBLCD49_MASK) +#define LCD_WF8B_BPBLCD0_MASK (0x2U) +#define LCD_WF8B_BPBLCD0_SHIFT (1U) +#define LCD_WF8B_BPBLCD0(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD0_SHIFT)) & LCD_WF8B_BPBLCD0_MASK) +#define LCD_WF8B_BPBLCD55_MASK (0x2U) +#define LCD_WF8B_BPBLCD55_SHIFT (1U) +#define LCD_WF8B_BPBLCD55(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD55_SHIFT)) & LCD_WF8B_BPBLCD55_MASK) +#define LCD_WF8B_BPBLCD56_MASK (0x2U) +#define LCD_WF8B_BPBLCD56_SHIFT (1U) +#define LCD_WF8B_BPBLCD56(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD56_SHIFT)) & LCD_WF8B_BPBLCD56_MASK) +#define LCD_WF8B_BPBLCD21_MASK (0x2U) +#define LCD_WF8B_BPBLCD21_SHIFT (1U) +#define LCD_WF8B_BPBLCD21(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD21_SHIFT)) & LCD_WF8B_BPBLCD21_MASK) +#define LCD_WF8B_BPBLCD6_MASK (0x2U) +#define LCD_WF8B_BPBLCD6_SHIFT (1U) +#define LCD_WF8B_BPBLCD6(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD6_SHIFT)) & LCD_WF8B_BPBLCD6_MASK) +#define LCD_WF8B_BPBLCD29_MASK (0x2U) +#define LCD_WF8B_BPBLCD29_SHIFT (1U) +#define LCD_WF8B_BPBLCD29(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD29_SHIFT)) & LCD_WF8B_BPBLCD29_MASK) +#define LCD_WF8B_BPBLCD25_MASK (0x2U) +#define LCD_WF8B_BPBLCD25_SHIFT (1U) +#define LCD_WF8B_BPBLCD25(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD25_SHIFT)) & LCD_WF8B_BPBLCD25_MASK) +#define LCD_WF8B_BPBLCD8_MASK (0x2U) +#define LCD_WF8B_BPBLCD8_SHIFT (1U) +#define LCD_WF8B_BPBLCD8(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD8_SHIFT)) & LCD_WF8B_BPBLCD8_MASK) +#define LCD_WF8B_BPBLCD54_MASK (0x2U) +#define LCD_WF8B_BPBLCD54_SHIFT (1U) +#define LCD_WF8B_BPBLCD54(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD54_SHIFT)) & LCD_WF8B_BPBLCD54_MASK) +#define LCD_WF8B_BPBLCD38_MASK (0x2U) +#define LCD_WF8B_BPBLCD38_SHIFT (1U) +#define LCD_WF8B_BPBLCD38(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD38_SHIFT)) & LCD_WF8B_BPBLCD38_MASK) +#define LCD_WF8B_BPBLCD43_MASK (0x2U) +#define LCD_WF8B_BPBLCD43_SHIFT (1U) +#define LCD_WF8B_BPBLCD43(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD43_SHIFT)) & LCD_WF8B_BPBLCD43_MASK) +#define LCD_WF8B_BPBLCD20_MASK (0x2U) +#define LCD_WF8B_BPBLCD20_SHIFT (1U) +#define LCD_WF8B_BPBLCD20(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD20_SHIFT)) & LCD_WF8B_BPBLCD20_MASK) +#define LCD_WF8B_BPBLCD9_MASK (0x2U) +#define LCD_WF8B_BPBLCD9_SHIFT (1U) +#define LCD_WF8B_BPBLCD9(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD9_SHIFT)) & LCD_WF8B_BPBLCD9_MASK) +#define LCD_WF8B_BPBLCD7_MASK (0x2U) +#define LCD_WF8B_BPBLCD7_SHIFT (1U) +#define LCD_WF8B_BPBLCD7(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD7_SHIFT)) & LCD_WF8B_BPBLCD7_MASK) +#define LCD_WF8B_BPBLCD50_MASK (0x2U) +#define LCD_WF8B_BPBLCD50_SHIFT (1U) +#define LCD_WF8B_BPBLCD50(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD50_SHIFT)) & LCD_WF8B_BPBLCD50_MASK) +#define LCD_WF8B_BPBLCD40_MASK (0x2U) +#define LCD_WF8B_BPBLCD40_SHIFT (1U) +#define LCD_WF8B_BPBLCD40(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD40_SHIFT)) & LCD_WF8B_BPBLCD40_MASK) +#define LCD_WF8B_BPBLCD63_MASK (0x2U) +#define LCD_WF8B_BPBLCD63_SHIFT (1U) +#define LCD_WF8B_BPBLCD63(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD63_SHIFT)) & LCD_WF8B_BPBLCD63_MASK) +#define LCD_WF8B_BPBLCD26_MASK (0x2U) +#define LCD_WF8B_BPBLCD26_SHIFT (1U) +#define LCD_WF8B_BPBLCD26(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD26_SHIFT)) & LCD_WF8B_BPBLCD26_MASK) +#define LCD_WF8B_BPBLCD12_MASK (0x2U) +#define LCD_WF8B_BPBLCD12_SHIFT (1U) +#define LCD_WF8B_BPBLCD12(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD12_SHIFT)) & LCD_WF8B_BPBLCD12_MASK) +#define LCD_WF8B_BPBLCD19_MASK (0x2U) +#define LCD_WF8B_BPBLCD19_SHIFT (1U) +#define LCD_WF8B_BPBLCD19(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD19_SHIFT)) & LCD_WF8B_BPBLCD19_MASK) +#define LCD_WF8B_BPBLCD34_MASK (0x2U) +#define LCD_WF8B_BPBLCD34_SHIFT (1U) +#define LCD_WF8B_BPBLCD34(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD34_SHIFT)) & LCD_WF8B_BPBLCD34_MASK) +#define LCD_WF8B_BPBLCD39_MASK (0x2U) +#define LCD_WF8B_BPBLCD39_SHIFT (1U) +#define LCD_WF8B_BPBLCD39(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD39_SHIFT)) & LCD_WF8B_BPBLCD39_MASK) +#define LCD_WF8B_BPBLCD59_MASK (0x2U) +#define LCD_WF8B_BPBLCD59_SHIFT (1U) +#define LCD_WF8B_BPBLCD59(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD59_SHIFT)) & LCD_WF8B_BPBLCD59_MASK) +#define LCD_WF8B_BPBLCD61_MASK (0x2U) +#define LCD_WF8B_BPBLCD61_SHIFT (1U) +#define LCD_WF8B_BPBLCD61(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD61_SHIFT)) & LCD_WF8B_BPBLCD61_MASK) +#define LCD_WF8B_BPBLCD37_MASK (0x2U) +#define LCD_WF8B_BPBLCD37_SHIFT (1U) +#define LCD_WF8B_BPBLCD37(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD37_SHIFT)) & LCD_WF8B_BPBLCD37_MASK) +#define LCD_WF8B_BPBLCD31_MASK (0x2U) +#define LCD_WF8B_BPBLCD31_SHIFT (1U) +#define LCD_WF8B_BPBLCD31(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD31_SHIFT)) & LCD_WF8B_BPBLCD31_MASK) +#define LCD_WF8B_BPBLCD58_MASK (0x2U) +#define LCD_WF8B_BPBLCD58_SHIFT (1U) +#define LCD_WF8B_BPBLCD58(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD58_SHIFT)) & LCD_WF8B_BPBLCD58_MASK) +#define LCD_WF8B_BPBLCD18_MASK (0x2U) +#define LCD_WF8B_BPBLCD18_SHIFT (1U) +#define LCD_WF8B_BPBLCD18(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD18_SHIFT)) & LCD_WF8B_BPBLCD18_MASK) +#define LCD_WF8B_BPBLCD45_MASK (0x2U) +#define LCD_WF8B_BPBLCD45_SHIFT (1U) +#define LCD_WF8B_BPBLCD45(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD45_SHIFT)) & LCD_WF8B_BPBLCD45_MASK) +#define LCD_WF8B_BPBLCD27_MASK (0x2U) +#define LCD_WF8B_BPBLCD27_SHIFT (1U) +#define LCD_WF8B_BPBLCD27(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD27_SHIFT)) & LCD_WF8B_BPBLCD27_MASK) +#define LCD_WF8B_BPBLCD14_MASK (0x2U) +#define LCD_WF8B_BPBLCD14_SHIFT (1U) +#define LCD_WF8B_BPBLCD14(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD14_SHIFT)) & LCD_WF8B_BPBLCD14_MASK) +#define LCD_WF8B_BPBLCD51_MASK (0x2U) +#define LCD_WF8B_BPBLCD51_SHIFT (1U) +#define LCD_WF8B_BPBLCD51(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD51_SHIFT)) & LCD_WF8B_BPBLCD51_MASK) +#define LCD_WF8B_BPBLCD52_MASK (0x2U) +#define LCD_WF8B_BPBLCD52_SHIFT (1U) +#define LCD_WF8B_BPBLCD52(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD52_SHIFT)) & LCD_WF8B_BPBLCD52_MASK) +#define LCD_WF8B_BPBLCD4_MASK (0x2U) +#define LCD_WF8B_BPBLCD4_SHIFT (1U) +#define LCD_WF8B_BPBLCD4(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD4_SHIFT)) & LCD_WF8B_BPBLCD4_MASK) +#define LCD_WF8B_BPBLCD35_MASK (0x2U) +#define LCD_WF8B_BPBLCD35_SHIFT (1U) +#define LCD_WF8B_BPBLCD35(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD35_SHIFT)) & LCD_WF8B_BPBLCD35_MASK) +#define LCD_WF8B_BPBLCD17_MASK (0x2U) +#define LCD_WF8B_BPBLCD17_SHIFT (1U) +#define LCD_WF8B_BPBLCD17(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD17_SHIFT)) & LCD_WF8B_BPBLCD17_MASK) +#define LCD_WF8B_BPBLCD41_MASK (0x2U) +#define LCD_WF8B_BPBLCD41_SHIFT (1U) +#define LCD_WF8B_BPBLCD41(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD41_SHIFT)) & LCD_WF8B_BPBLCD41_MASK) +#define LCD_WF8B_BPBLCD11_MASK (0x2U) +#define LCD_WF8B_BPBLCD11_SHIFT (1U) +#define LCD_WF8B_BPBLCD11(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD11_SHIFT)) & LCD_WF8B_BPBLCD11_MASK) +#define LCD_WF8B_BPBLCD46_MASK (0x2U) +#define LCD_WF8B_BPBLCD46_SHIFT (1U) +#define LCD_WF8B_BPBLCD46(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD46_SHIFT)) & LCD_WF8B_BPBLCD46_MASK) +#define LCD_WF8B_BPBLCD57_MASK (0x2U) +#define LCD_WF8B_BPBLCD57_SHIFT (1U) +#define LCD_WF8B_BPBLCD57(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD57_SHIFT)) & LCD_WF8B_BPBLCD57_MASK) +#define LCD_WF8B_BPBLCD42_MASK (0x2U) +#define LCD_WF8B_BPBLCD42_SHIFT (1U) +#define LCD_WF8B_BPBLCD42(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD42_SHIFT)) & LCD_WF8B_BPBLCD42_MASK) +#define LCD_WF8B_BPBLCD5_MASK (0x2U) +#define LCD_WF8B_BPBLCD5_SHIFT (1U) +#define LCD_WF8B_BPBLCD5(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD5_SHIFT)) & LCD_WF8B_BPBLCD5_MASK) +#define LCD_WF8B_BPBLCD3_MASK (0x2U) +#define LCD_WF8B_BPBLCD3_SHIFT (1U) +#define LCD_WF8B_BPBLCD3(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD3_SHIFT)) & LCD_WF8B_BPBLCD3_MASK) +#define LCD_WF8B_BPBLCD16_MASK (0x2U) +#define LCD_WF8B_BPBLCD16_SHIFT (1U) +#define LCD_WF8B_BPBLCD16(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD16_SHIFT)) & LCD_WF8B_BPBLCD16_MASK) +#define LCD_WF8B_BPBLCD13_MASK (0x2U) +#define LCD_WF8B_BPBLCD13_SHIFT (1U) +#define LCD_WF8B_BPBLCD13(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPBLCD13_SHIFT)) & LCD_WF8B_BPBLCD13_MASK) +#define LCD_WF8B_BPCLCD10_MASK (0x4U) +#define LCD_WF8B_BPCLCD10_SHIFT (2U) +#define LCD_WF8B_BPCLCD10(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD10_SHIFT)) & LCD_WF8B_BPCLCD10_MASK) +#define LCD_WF8B_BPCLCD55_MASK (0x4U) +#define LCD_WF8B_BPCLCD55_SHIFT (2U) +#define LCD_WF8B_BPCLCD55(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD55_SHIFT)) & LCD_WF8B_BPCLCD55_MASK) +#define LCD_WF8B_BPCLCD2_MASK (0x4U) +#define LCD_WF8B_BPCLCD2_SHIFT (2U) +#define LCD_WF8B_BPCLCD2(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD2_SHIFT)) & LCD_WF8B_BPCLCD2_MASK) +#define LCD_WF8B_BPCLCD23_MASK (0x4U) +#define LCD_WF8B_BPCLCD23_SHIFT (2U) +#define LCD_WF8B_BPCLCD23(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD23_SHIFT)) & LCD_WF8B_BPCLCD23_MASK) +#define LCD_WF8B_BPCLCD48_MASK (0x4U) +#define LCD_WF8B_BPCLCD48_SHIFT (2U) +#define LCD_WF8B_BPCLCD48(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD48_SHIFT)) & LCD_WF8B_BPCLCD48_MASK) +#define LCD_WF8B_BPCLCD24_MASK (0x4U) +#define LCD_WF8B_BPCLCD24_SHIFT (2U) +#define LCD_WF8B_BPCLCD24(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD24_SHIFT)) & LCD_WF8B_BPCLCD24_MASK) +#define LCD_WF8B_BPCLCD60_MASK (0x4U) +#define LCD_WF8B_BPCLCD60_SHIFT (2U) +#define LCD_WF8B_BPCLCD60(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD60_SHIFT)) & LCD_WF8B_BPCLCD60_MASK) +#define LCD_WF8B_BPCLCD47_MASK (0x4U) +#define LCD_WF8B_BPCLCD47_SHIFT (2U) +#define LCD_WF8B_BPCLCD47(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD47_SHIFT)) & LCD_WF8B_BPCLCD47_MASK) +#define LCD_WF8B_BPCLCD22_MASK (0x4U) +#define LCD_WF8B_BPCLCD22_SHIFT (2U) +#define LCD_WF8B_BPCLCD22(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD22_SHIFT)) & LCD_WF8B_BPCLCD22_MASK) +#define LCD_WF8B_BPCLCD8_MASK (0x4U) +#define LCD_WF8B_BPCLCD8_SHIFT (2U) +#define LCD_WF8B_BPCLCD8(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD8_SHIFT)) & LCD_WF8B_BPCLCD8_MASK) +#define LCD_WF8B_BPCLCD21_MASK (0x4U) +#define LCD_WF8B_BPCLCD21_SHIFT (2U) +#define LCD_WF8B_BPCLCD21(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD21_SHIFT)) & LCD_WF8B_BPCLCD21_MASK) +#define LCD_WF8B_BPCLCD49_MASK (0x4U) +#define LCD_WF8B_BPCLCD49_SHIFT (2U) +#define LCD_WF8B_BPCLCD49(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD49_SHIFT)) & LCD_WF8B_BPCLCD49_MASK) +#define LCD_WF8B_BPCLCD25_MASK (0x4U) +#define LCD_WF8B_BPCLCD25_SHIFT (2U) +#define LCD_WF8B_BPCLCD25(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD25_SHIFT)) & LCD_WF8B_BPCLCD25_MASK) +#define LCD_WF8B_BPCLCD1_MASK (0x4U) +#define LCD_WF8B_BPCLCD1_SHIFT (2U) +#define LCD_WF8B_BPCLCD1(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD1_SHIFT)) & LCD_WF8B_BPCLCD1_MASK) +#define LCD_WF8B_BPCLCD20_MASK (0x4U) +#define LCD_WF8B_BPCLCD20_SHIFT (2U) +#define LCD_WF8B_BPCLCD20(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD20_SHIFT)) & LCD_WF8B_BPCLCD20_MASK) +#define LCD_WF8B_BPCLCD50_MASK (0x4U) +#define LCD_WF8B_BPCLCD50_SHIFT (2U) +#define LCD_WF8B_BPCLCD50(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD50_SHIFT)) & LCD_WF8B_BPCLCD50_MASK) +#define LCD_WF8B_BPCLCD19_MASK (0x4U) +#define LCD_WF8B_BPCLCD19_SHIFT (2U) +#define LCD_WF8B_BPCLCD19(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD19_SHIFT)) & LCD_WF8B_BPCLCD19_MASK) +#define LCD_WF8B_BPCLCD26_MASK (0x4U) +#define LCD_WF8B_BPCLCD26_SHIFT (2U) +#define LCD_WF8B_BPCLCD26(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD26_SHIFT)) & LCD_WF8B_BPCLCD26_MASK) +#define LCD_WF8B_BPCLCD59_MASK (0x4U) +#define LCD_WF8B_BPCLCD59_SHIFT (2U) +#define LCD_WF8B_BPCLCD59(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD59_SHIFT)) & LCD_WF8B_BPCLCD59_MASK) +#define LCD_WF8B_BPCLCD61_MASK (0x4U) +#define LCD_WF8B_BPCLCD61_SHIFT (2U) +#define LCD_WF8B_BPCLCD61(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD61_SHIFT)) & LCD_WF8B_BPCLCD61_MASK) +#define LCD_WF8B_BPCLCD46_MASK (0x4U) +#define LCD_WF8B_BPCLCD46_SHIFT (2U) +#define LCD_WF8B_BPCLCD46(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD46_SHIFT)) & LCD_WF8B_BPCLCD46_MASK) +#define LCD_WF8B_BPCLCD18_MASK (0x4U) +#define LCD_WF8B_BPCLCD18_SHIFT (2U) +#define LCD_WF8B_BPCLCD18(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD18_SHIFT)) & LCD_WF8B_BPCLCD18_MASK) +#define LCD_WF8B_BPCLCD5_MASK (0x4U) +#define LCD_WF8B_BPCLCD5_SHIFT (2U) +#define LCD_WF8B_BPCLCD5(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD5_SHIFT)) & LCD_WF8B_BPCLCD5_MASK) +#define LCD_WF8B_BPCLCD63_MASK (0x4U) +#define LCD_WF8B_BPCLCD63_SHIFT (2U) +#define LCD_WF8B_BPCLCD63(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD63_SHIFT)) & LCD_WF8B_BPCLCD63_MASK) +#define LCD_WF8B_BPCLCD27_MASK (0x4U) +#define LCD_WF8B_BPCLCD27_SHIFT (2U) +#define LCD_WF8B_BPCLCD27(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD27_SHIFT)) & LCD_WF8B_BPCLCD27_MASK) +#define LCD_WF8B_BPCLCD17_MASK (0x4U) +#define LCD_WF8B_BPCLCD17_SHIFT (2U) +#define LCD_WF8B_BPCLCD17(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD17_SHIFT)) & LCD_WF8B_BPCLCD17_MASK) +#define LCD_WF8B_BPCLCD51_MASK (0x4U) +#define LCD_WF8B_BPCLCD51_SHIFT (2U) +#define LCD_WF8B_BPCLCD51(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD51_SHIFT)) & LCD_WF8B_BPCLCD51_MASK) +#define LCD_WF8B_BPCLCD9_MASK (0x4U) +#define LCD_WF8B_BPCLCD9_SHIFT (2U) +#define LCD_WF8B_BPCLCD9(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD9_SHIFT)) & LCD_WF8B_BPCLCD9_MASK) +#define LCD_WF8B_BPCLCD54_MASK (0x4U) +#define LCD_WF8B_BPCLCD54_SHIFT (2U) +#define LCD_WF8B_BPCLCD54(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD54_SHIFT)) & LCD_WF8B_BPCLCD54_MASK) +#define LCD_WF8B_BPCLCD15_MASK (0x4U) +#define LCD_WF8B_BPCLCD15_SHIFT (2U) +#define LCD_WF8B_BPCLCD15(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD15_SHIFT)) & LCD_WF8B_BPCLCD15_MASK) +#define LCD_WF8B_BPCLCD16_MASK (0x4U) +#define LCD_WF8B_BPCLCD16_SHIFT (2U) +#define LCD_WF8B_BPCLCD16(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD16_SHIFT)) & LCD_WF8B_BPCLCD16_MASK) +#define LCD_WF8B_BPCLCD14_MASK (0x4U) +#define LCD_WF8B_BPCLCD14_SHIFT (2U) +#define LCD_WF8B_BPCLCD14(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD14_SHIFT)) & LCD_WF8B_BPCLCD14_MASK) +#define LCD_WF8B_BPCLCD32_MASK (0x4U) +#define LCD_WF8B_BPCLCD32_SHIFT (2U) +#define LCD_WF8B_BPCLCD32(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD32_SHIFT)) & LCD_WF8B_BPCLCD32_MASK) +#define LCD_WF8B_BPCLCD28_MASK (0x4U) +#define LCD_WF8B_BPCLCD28_SHIFT (2U) +#define LCD_WF8B_BPCLCD28(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD28_SHIFT)) & LCD_WF8B_BPCLCD28_MASK) +#define LCD_WF8B_BPCLCD53_MASK (0x4U) +#define LCD_WF8B_BPCLCD53_SHIFT (2U) +#define LCD_WF8B_BPCLCD53(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD53_SHIFT)) & LCD_WF8B_BPCLCD53_MASK) +#define LCD_WF8B_BPCLCD33_MASK (0x4U) +#define LCD_WF8B_BPCLCD33_SHIFT (2U) +#define LCD_WF8B_BPCLCD33(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD33_SHIFT)) & LCD_WF8B_BPCLCD33_MASK) +#define LCD_WF8B_BPCLCD0_MASK (0x4U) +#define LCD_WF8B_BPCLCD0_SHIFT (2U) +#define LCD_WF8B_BPCLCD0(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD0_SHIFT)) & LCD_WF8B_BPCLCD0_MASK) +#define LCD_WF8B_BPCLCD43_MASK (0x4U) +#define LCD_WF8B_BPCLCD43_SHIFT (2U) +#define LCD_WF8B_BPCLCD43(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD43_SHIFT)) & LCD_WF8B_BPCLCD43_MASK) +#define LCD_WF8B_BPCLCD7_MASK (0x4U) +#define LCD_WF8B_BPCLCD7_SHIFT (2U) +#define LCD_WF8B_BPCLCD7(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD7_SHIFT)) & LCD_WF8B_BPCLCD7_MASK) +#define LCD_WF8B_BPCLCD4_MASK (0x4U) +#define LCD_WF8B_BPCLCD4_SHIFT (2U) +#define LCD_WF8B_BPCLCD4(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD4_SHIFT)) & LCD_WF8B_BPCLCD4_MASK) +#define LCD_WF8B_BPCLCD34_MASK (0x4U) +#define LCD_WF8B_BPCLCD34_SHIFT (2U) +#define LCD_WF8B_BPCLCD34(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD34_SHIFT)) & LCD_WF8B_BPCLCD34_MASK) +#define LCD_WF8B_BPCLCD29_MASK (0x4U) +#define LCD_WF8B_BPCLCD29_SHIFT (2U) +#define LCD_WF8B_BPCLCD29(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD29_SHIFT)) & LCD_WF8B_BPCLCD29_MASK) +#define LCD_WF8B_BPCLCD45_MASK (0x4U) +#define LCD_WF8B_BPCLCD45_SHIFT (2U) +#define LCD_WF8B_BPCLCD45(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD45_SHIFT)) & LCD_WF8B_BPCLCD45_MASK) +#define LCD_WF8B_BPCLCD57_MASK (0x4U) +#define LCD_WF8B_BPCLCD57_SHIFT (2U) +#define LCD_WF8B_BPCLCD57(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD57_SHIFT)) & LCD_WF8B_BPCLCD57_MASK) +#define LCD_WF8B_BPCLCD42_MASK (0x4U) +#define LCD_WF8B_BPCLCD42_SHIFT (2U) +#define LCD_WF8B_BPCLCD42(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD42_SHIFT)) & LCD_WF8B_BPCLCD42_MASK) +#define LCD_WF8B_BPCLCD35_MASK (0x4U) +#define LCD_WF8B_BPCLCD35_SHIFT (2U) +#define LCD_WF8B_BPCLCD35(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD35_SHIFT)) & LCD_WF8B_BPCLCD35_MASK) +#define LCD_WF8B_BPCLCD13_MASK (0x4U) +#define LCD_WF8B_BPCLCD13_SHIFT (2U) +#define LCD_WF8B_BPCLCD13(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD13_SHIFT)) & LCD_WF8B_BPCLCD13_MASK) +#define LCD_WF8B_BPCLCD36_MASK (0x4U) +#define LCD_WF8B_BPCLCD36_SHIFT (2U) +#define LCD_WF8B_BPCLCD36(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD36_SHIFT)) & LCD_WF8B_BPCLCD36_MASK) +#define LCD_WF8B_BPCLCD30_MASK (0x4U) +#define LCD_WF8B_BPCLCD30_SHIFT (2U) +#define LCD_WF8B_BPCLCD30(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD30_SHIFT)) & LCD_WF8B_BPCLCD30_MASK) +#define LCD_WF8B_BPCLCD52_MASK (0x4U) +#define LCD_WF8B_BPCLCD52_SHIFT (2U) +#define LCD_WF8B_BPCLCD52(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD52_SHIFT)) & LCD_WF8B_BPCLCD52_MASK) +#define LCD_WF8B_BPCLCD58_MASK (0x4U) +#define LCD_WF8B_BPCLCD58_SHIFT (2U) +#define LCD_WF8B_BPCLCD58(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD58_SHIFT)) & LCD_WF8B_BPCLCD58_MASK) +#define LCD_WF8B_BPCLCD41_MASK (0x4U) +#define LCD_WF8B_BPCLCD41_SHIFT (2U) +#define LCD_WF8B_BPCLCD41(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD41_SHIFT)) & LCD_WF8B_BPCLCD41_MASK) +#define LCD_WF8B_BPCLCD37_MASK (0x4U) +#define LCD_WF8B_BPCLCD37_SHIFT (2U) +#define LCD_WF8B_BPCLCD37(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD37_SHIFT)) & LCD_WF8B_BPCLCD37_MASK) +#define LCD_WF8B_BPCLCD3_MASK (0x4U) +#define LCD_WF8B_BPCLCD3_SHIFT (2U) +#define LCD_WF8B_BPCLCD3(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD3_SHIFT)) & LCD_WF8B_BPCLCD3_MASK) +#define LCD_WF8B_BPCLCD12_MASK (0x4U) +#define LCD_WF8B_BPCLCD12_SHIFT (2U) +#define LCD_WF8B_BPCLCD12(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD12_SHIFT)) & LCD_WF8B_BPCLCD12_MASK) +#define LCD_WF8B_BPCLCD11_MASK (0x4U) +#define LCD_WF8B_BPCLCD11_SHIFT (2U) +#define LCD_WF8B_BPCLCD11(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD11_SHIFT)) & LCD_WF8B_BPCLCD11_MASK) +#define LCD_WF8B_BPCLCD38_MASK (0x4U) +#define LCD_WF8B_BPCLCD38_SHIFT (2U) +#define LCD_WF8B_BPCLCD38(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD38_SHIFT)) & LCD_WF8B_BPCLCD38_MASK) +#define LCD_WF8B_BPCLCD44_MASK (0x4U) +#define LCD_WF8B_BPCLCD44_SHIFT (2U) +#define LCD_WF8B_BPCLCD44(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD44_SHIFT)) & LCD_WF8B_BPCLCD44_MASK) +#define LCD_WF8B_BPCLCD31_MASK (0x4U) +#define LCD_WF8B_BPCLCD31_SHIFT (2U) +#define LCD_WF8B_BPCLCD31(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD31_SHIFT)) & LCD_WF8B_BPCLCD31_MASK) +#define LCD_WF8B_BPCLCD40_MASK (0x4U) +#define LCD_WF8B_BPCLCD40_SHIFT (2U) +#define LCD_WF8B_BPCLCD40(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD40_SHIFT)) & LCD_WF8B_BPCLCD40_MASK) +#define LCD_WF8B_BPCLCD62_MASK (0x4U) +#define LCD_WF8B_BPCLCD62_SHIFT (2U) +#define LCD_WF8B_BPCLCD62(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD62_SHIFT)) & LCD_WF8B_BPCLCD62_MASK) +#define LCD_WF8B_BPCLCD56_MASK (0x4U) +#define LCD_WF8B_BPCLCD56_SHIFT (2U) +#define LCD_WF8B_BPCLCD56(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD56_SHIFT)) & LCD_WF8B_BPCLCD56_MASK) +#define LCD_WF8B_BPCLCD39_MASK (0x4U) +#define LCD_WF8B_BPCLCD39_SHIFT (2U) +#define LCD_WF8B_BPCLCD39(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD39_SHIFT)) & LCD_WF8B_BPCLCD39_MASK) +#define LCD_WF8B_BPCLCD6_MASK (0x4U) +#define LCD_WF8B_BPCLCD6_SHIFT (2U) +#define LCD_WF8B_BPCLCD6(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPCLCD6_SHIFT)) & LCD_WF8B_BPCLCD6_MASK) +#define LCD_WF8B_BPDLCD47_MASK (0x8U) +#define LCD_WF8B_BPDLCD47_SHIFT (3U) +#define LCD_WF8B_BPDLCD47(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD47_SHIFT)) & LCD_WF8B_BPDLCD47_MASK) +#define LCD_WF8B_BPDLCD23_MASK (0x8U) +#define LCD_WF8B_BPDLCD23_SHIFT (3U) +#define LCD_WF8B_BPDLCD23(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD23_SHIFT)) & LCD_WF8B_BPDLCD23_MASK) +#define LCD_WF8B_BPDLCD48_MASK (0x8U) +#define LCD_WF8B_BPDLCD48_SHIFT (3U) +#define LCD_WF8B_BPDLCD48(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD48_SHIFT)) & LCD_WF8B_BPDLCD48_MASK) +#define LCD_WF8B_BPDLCD24_MASK (0x8U) +#define LCD_WF8B_BPDLCD24_SHIFT (3U) +#define LCD_WF8B_BPDLCD24(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD24_SHIFT)) & LCD_WF8B_BPDLCD24_MASK) +#define LCD_WF8B_BPDLCD15_MASK (0x8U) +#define LCD_WF8B_BPDLCD15_SHIFT (3U) +#define LCD_WF8B_BPDLCD15(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD15_SHIFT)) & LCD_WF8B_BPDLCD15_MASK) +#define LCD_WF8B_BPDLCD22_MASK (0x8U) +#define LCD_WF8B_BPDLCD22_SHIFT (3U) +#define LCD_WF8B_BPDLCD22(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD22_SHIFT)) & LCD_WF8B_BPDLCD22_MASK) +#define LCD_WF8B_BPDLCD60_MASK (0x8U) +#define LCD_WF8B_BPDLCD60_SHIFT (3U) +#define LCD_WF8B_BPDLCD60(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD60_SHIFT)) & LCD_WF8B_BPDLCD60_MASK) +#define LCD_WF8B_BPDLCD10_MASK (0x8U) +#define LCD_WF8B_BPDLCD10_SHIFT (3U) +#define LCD_WF8B_BPDLCD10(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD10_SHIFT)) & LCD_WF8B_BPDLCD10_MASK) +#define LCD_WF8B_BPDLCD21_MASK (0x8U) +#define LCD_WF8B_BPDLCD21_SHIFT (3U) +#define LCD_WF8B_BPDLCD21(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD21_SHIFT)) & LCD_WF8B_BPDLCD21_MASK) +#define LCD_WF8B_BPDLCD49_MASK (0x8U) +#define LCD_WF8B_BPDLCD49_SHIFT (3U) +#define LCD_WF8B_BPDLCD49(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD49_SHIFT)) & LCD_WF8B_BPDLCD49_MASK) +#define LCD_WF8B_BPDLCD1_MASK (0x8U) +#define LCD_WF8B_BPDLCD1_SHIFT (3U) +#define LCD_WF8B_BPDLCD1(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD1_SHIFT)) & LCD_WF8B_BPDLCD1_MASK) +#define LCD_WF8B_BPDLCD25_MASK (0x8U) +#define LCD_WF8B_BPDLCD25_SHIFT (3U) +#define LCD_WF8B_BPDLCD25(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD25_SHIFT)) & LCD_WF8B_BPDLCD25_MASK) +#define LCD_WF8B_BPDLCD20_MASK (0x8U) +#define LCD_WF8B_BPDLCD20_SHIFT (3U) +#define LCD_WF8B_BPDLCD20(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD20_SHIFT)) & LCD_WF8B_BPDLCD20_MASK) +#define LCD_WF8B_BPDLCD2_MASK (0x8U) +#define LCD_WF8B_BPDLCD2_SHIFT (3U) +#define LCD_WF8B_BPDLCD2(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD2_SHIFT)) & LCD_WF8B_BPDLCD2_MASK) +#define LCD_WF8B_BPDLCD55_MASK (0x8U) +#define LCD_WF8B_BPDLCD55_SHIFT (3U) +#define LCD_WF8B_BPDLCD55(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD55_SHIFT)) & LCD_WF8B_BPDLCD55_MASK) +#define LCD_WF8B_BPDLCD59_MASK (0x8U) +#define LCD_WF8B_BPDLCD59_SHIFT (3U) +#define LCD_WF8B_BPDLCD59(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD59_SHIFT)) & LCD_WF8B_BPDLCD59_MASK) +#define LCD_WF8B_BPDLCD5_MASK (0x8U) +#define LCD_WF8B_BPDLCD5_SHIFT (3U) +#define LCD_WF8B_BPDLCD5(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD5_SHIFT)) & LCD_WF8B_BPDLCD5_MASK) +#define LCD_WF8B_BPDLCD19_MASK (0x8U) +#define LCD_WF8B_BPDLCD19_SHIFT (3U) +#define LCD_WF8B_BPDLCD19(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD19_SHIFT)) & LCD_WF8B_BPDLCD19_MASK) +#define LCD_WF8B_BPDLCD6_MASK (0x8U) +#define LCD_WF8B_BPDLCD6_SHIFT (3U) +#define LCD_WF8B_BPDLCD6(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD6_SHIFT)) & LCD_WF8B_BPDLCD6_MASK) +#define LCD_WF8B_BPDLCD26_MASK (0x8U) +#define LCD_WF8B_BPDLCD26_SHIFT (3U) +#define LCD_WF8B_BPDLCD26(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD26_SHIFT)) & LCD_WF8B_BPDLCD26_MASK) +#define LCD_WF8B_BPDLCD0_MASK (0x8U) +#define LCD_WF8B_BPDLCD0_SHIFT (3U) +#define LCD_WF8B_BPDLCD0(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD0_SHIFT)) & LCD_WF8B_BPDLCD0_MASK) +#define LCD_WF8B_BPDLCD50_MASK (0x8U) +#define LCD_WF8B_BPDLCD50_SHIFT (3U) +#define LCD_WF8B_BPDLCD50(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD50_SHIFT)) & LCD_WF8B_BPDLCD50_MASK) +#define LCD_WF8B_BPDLCD46_MASK (0x8U) +#define LCD_WF8B_BPDLCD46_SHIFT (3U) +#define LCD_WF8B_BPDLCD46(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD46_SHIFT)) & LCD_WF8B_BPDLCD46_MASK) +#define LCD_WF8B_BPDLCD18_MASK (0x8U) +#define LCD_WF8B_BPDLCD18_SHIFT (3U) +#define LCD_WF8B_BPDLCD18(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD18_SHIFT)) & LCD_WF8B_BPDLCD18_MASK) +#define LCD_WF8B_BPDLCD61_MASK (0x8U) +#define LCD_WF8B_BPDLCD61_SHIFT (3U) +#define LCD_WF8B_BPDLCD61(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD61_SHIFT)) & LCD_WF8B_BPDLCD61_MASK) +#define LCD_WF8B_BPDLCD9_MASK (0x8U) +#define LCD_WF8B_BPDLCD9_SHIFT (3U) +#define LCD_WF8B_BPDLCD9(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD9_SHIFT)) & LCD_WF8B_BPDLCD9_MASK) +#define LCD_WF8B_BPDLCD17_MASK (0x8U) +#define LCD_WF8B_BPDLCD17_SHIFT (3U) +#define LCD_WF8B_BPDLCD17(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD17_SHIFT)) & LCD_WF8B_BPDLCD17_MASK) +#define LCD_WF8B_BPDLCD27_MASK (0x8U) +#define LCD_WF8B_BPDLCD27_SHIFT (3U) +#define LCD_WF8B_BPDLCD27(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD27_SHIFT)) & LCD_WF8B_BPDLCD27_MASK) +#define LCD_WF8B_BPDLCD53_MASK (0x8U) +#define LCD_WF8B_BPDLCD53_SHIFT (3U) +#define LCD_WF8B_BPDLCD53(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD53_SHIFT)) & LCD_WF8B_BPDLCD53_MASK) +#define LCD_WF8B_BPDLCD51_MASK (0x8U) +#define LCD_WF8B_BPDLCD51_SHIFT (3U) +#define LCD_WF8B_BPDLCD51(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD51_SHIFT)) & LCD_WF8B_BPDLCD51_MASK) +#define LCD_WF8B_BPDLCD54_MASK (0x8U) +#define LCD_WF8B_BPDLCD54_SHIFT (3U) +#define LCD_WF8B_BPDLCD54(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD54_SHIFT)) & LCD_WF8B_BPDLCD54_MASK) +#define LCD_WF8B_BPDLCD13_MASK (0x8U) +#define LCD_WF8B_BPDLCD13_SHIFT (3U) +#define LCD_WF8B_BPDLCD13(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD13_SHIFT)) & LCD_WF8B_BPDLCD13_MASK) +#define LCD_WF8B_BPDLCD16_MASK (0x8U) +#define LCD_WF8B_BPDLCD16_SHIFT (3U) +#define LCD_WF8B_BPDLCD16(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD16_SHIFT)) & LCD_WF8B_BPDLCD16_MASK) +#define LCD_WF8B_BPDLCD32_MASK (0x8U) +#define LCD_WF8B_BPDLCD32_SHIFT (3U) +#define LCD_WF8B_BPDLCD32(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD32_SHIFT)) & LCD_WF8B_BPDLCD32_MASK) +#define LCD_WF8B_BPDLCD14_MASK (0x8U) +#define LCD_WF8B_BPDLCD14_SHIFT (3U) +#define LCD_WF8B_BPDLCD14(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD14_SHIFT)) & LCD_WF8B_BPDLCD14_MASK) +#define LCD_WF8B_BPDLCD28_MASK (0x8U) +#define LCD_WF8B_BPDLCD28_SHIFT (3U) +#define LCD_WF8B_BPDLCD28(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD28_SHIFT)) & LCD_WF8B_BPDLCD28_MASK) +#define LCD_WF8B_BPDLCD43_MASK (0x8U) +#define LCD_WF8B_BPDLCD43_SHIFT (3U) +#define LCD_WF8B_BPDLCD43(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD43_SHIFT)) & LCD_WF8B_BPDLCD43_MASK) +#define LCD_WF8B_BPDLCD4_MASK (0x8U) +#define LCD_WF8B_BPDLCD4_SHIFT (3U) +#define LCD_WF8B_BPDLCD4(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD4_SHIFT)) & LCD_WF8B_BPDLCD4_MASK) +#define LCD_WF8B_BPDLCD45_MASK (0x8U) +#define LCD_WF8B_BPDLCD45_SHIFT (3U) +#define LCD_WF8B_BPDLCD45(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD45_SHIFT)) & LCD_WF8B_BPDLCD45_MASK) +#define LCD_WF8B_BPDLCD8_MASK (0x8U) +#define LCD_WF8B_BPDLCD8_SHIFT (3U) +#define LCD_WF8B_BPDLCD8(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD8_SHIFT)) & LCD_WF8B_BPDLCD8_MASK) +#define LCD_WF8B_BPDLCD62_MASK (0x8U) +#define LCD_WF8B_BPDLCD62_SHIFT (3U) +#define LCD_WF8B_BPDLCD62(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD62_SHIFT)) & LCD_WF8B_BPDLCD62_MASK) +#define LCD_WF8B_BPDLCD33_MASK (0x8U) +#define LCD_WF8B_BPDLCD33_SHIFT (3U) +#define LCD_WF8B_BPDLCD33(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD33_SHIFT)) & LCD_WF8B_BPDLCD33_MASK) +#define LCD_WF8B_BPDLCD34_MASK (0x8U) +#define LCD_WF8B_BPDLCD34_SHIFT (3U) +#define LCD_WF8B_BPDLCD34(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD34_SHIFT)) & LCD_WF8B_BPDLCD34_MASK) +#define LCD_WF8B_BPDLCD29_MASK (0x8U) +#define LCD_WF8B_BPDLCD29_SHIFT (3U) +#define LCD_WF8B_BPDLCD29(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD29_SHIFT)) & LCD_WF8B_BPDLCD29_MASK) +#define LCD_WF8B_BPDLCD58_MASK (0x8U) +#define LCD_WF8B_BPDLCD58_SHIFT (3U) +#define LCD_WF8B_BPDLCD58(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD58_SHIFT)) & LCD_WF8B_BPDLCD58_MASK) +#define LCD_WF8B_BPDLCD57_MASK (0x8U) +#define LCD_WF8B_BPDLCD57_SHIFT (3U) +#define LCD_WF8B_BPDLCD57(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD57_SHIFT)) & LCD_WF8B_BPDLCD57_MASK) +#define LCD_WF8B_BPDLCD42_MASK (0x8U) +#define LCD_WF8B_BPDLCD42_SHIFT (3U) +#define LCD_WF8B_BPDLCD42(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD42_SHIFT)) & LCD_WF8B_BPDLCD42_MASK) +#define LCD_WF8B_BPDLCD35_MASK (0x8U) +#define LCD_WF8B_BPDLCD35_SHIFT (3U) +#define LCD_WF8B_BPDLCD35(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD35_SHIFT)) & LCD_WF8B_BPDLCD35_MASK) +#define LCD_WF8B_BPDLCD52_MASK (0x8U) +#define LCD_WF8B_BPDLCD52_SHIFT (3U) +#define LCD_WF8B_BPDLCD52(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD52_SHIFT)) & LCD_WF8B_BPDLCD52_MASK) +#define LCD_WF8B_BPDLCD7_MASK (0x8U) +#define LCD_WF8B_BPDLCD7_SHIFT (3U) +#define LCD_WF8B_BPDLCD7(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD7_SHIFT)) & LCD_WF8B_BPDLCD7_MASK) +#define LCD_WF8B_BPDLCD36_MASK (0x8U) +#define LCD_WF8B_BPDLCD36_SHIFT (3U) +#define LCD_WF8B_BPDLCD36(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD36_SHIFT)) & LCD_WF8B_BPDLCD36_MASK) +#define LCD_WF8B_BPDLCD30_MASK (0x8U) +#define LCD_WF8B_BPDLCD30_SHIFT (3U) +#define LCD_WF8B_BPDLCD30(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD30_SHIFT)) & LCD_WF8B_BPDLCD30_MASK) +#define LCD_WF8B_BPDLCD41_MASK (0x8U) +#define LCD_WF8B_BPDLCD41_SHIFT (3U) +#define LCD_WF8B_BPDLCD41(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD41_SHIFT)) & LCD_WF8B_BPDLCD41_MASK) +#define LCD_WF8B_BPDLCD37_MASK (0x8U) +#define LCD_WF8B_BPDLCD37_SHIFT (3U) +#define LCD_WF8B_BPDLCD37(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD37_SHIFT)) & LCD_WF8B_BPDLCD37_MASK) +#define LCD_WF8B_BPDLCD44_MASK (0x8U) +#define LCD_WF8B_BPDLCD44_SHIFT (3U) +#define LCD_WF8B_BPDLCD44(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD44_SHIFT)) & LCD_WF8B_BPDLCD44_MASK) +#define LCD_WF8B_BPDLCD63_MASK (0x8U) +#define LCD_WF8B_BPDLCD63_SHIFT (3U) +#define LCD_WF8B_BPDLCD63(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD63_SHIFT)) & LCD_WF8B_BPDLCD63_MASK) +#define LCD_WF8B_BPDLCD38_MASK (0x8U) +#define LCD_WF8B_BPDLCD38_SHIFT (3U) +#define LCD_WF8B_BPDLCD38(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD38_SHIFT)) & LCD_WF8B_BPDLCD38_MASK) +#define LCD_WF8B_BPDLCD56_MASK (0x8U) +#define LCD_WF8B_BPDLCD56_SHIFT (3U) +#define LCD_WF8B_BPDLCD56(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD56_SHIFT)) & LCD_WF8B_BPDLCD56_MASK) +#define LCD_WF8B_BPDLCD40_MASK (0x8U) +#define LCD_WF8B_BPDLCD40_SHIFT (3U) +#define LCD_WF8B_BPDLCD40(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD40_SHIFT)) & LCD_WF8B_BPDLCD40_MASK) +#define LCD_WF8B_BPDLCD31_MASK (0x8U) +#define LCD_WF8B_BPDLCD31_SHIFT (3U) +#define LCD_WF8B_BPDLCD31(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD31_SHIFT)) & LCD_WF8B_BPDLCD31_MASK) +#define LCD_WF8B_BPDLCD12_MASK (0x8U) +#define LCD_WF8B_BPDLCD12_SHIFT (3U) +#define LCD_WF8B_BPDLCD12(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD12_SHIFT)) & LCD_WF8B_BPDLCD12_MASK) +#define LCD_WF8B_BPDLCD39_MASK (0x8U) +#define LCD_WF8B_BPDLCD39_SHIFT (3U) +#define LCD_WF8B_BPDLCD39(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD39_SHIFT)) & LCD_WF8B_BPDLCD39_MASK) +#define LCD_WF8B_BPDLCD3_MASK (0x8U) +#define LCD_WF8B_BPDLCD3_SHIFT (3U) +#define LCD_WF8B_BPDLCD3(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD3_SHIFT)) & LCD_WF8B_BPDLCD3_MASK) +#define LCD_WF8B_BPDLCD11_MASK (0x8U) +#define LCD_WF8B_BPDLCD11_SHIFT (3U) +#define LCD_WF8B_BPDLCD11(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPDLCD11_SHIFT)) & LCD_WF8B_BPDLCD11_MASK) +#define LCD_WF8B_BPELCD12_MASK (0x10U) +#define LCD_WF8B_BPELCD12_SHIFT (4U) +#define LCD_WF8B_BPELCD12(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD12_SHIFT)) & LCD_WF8B_BPELCD12_MASK) +#define LCD_WF8B_BPELCD39_MASK (0x10U) +#define LCD_WF8B_BPELCD39_SHIFT (4U) +#define LCD_WF8B_BPELCD39(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD39_SHIFT)) & LCD_WF8B_BPELCD39_MASK) +#define LCD_WF8B_BPELCD3_MASK (0x10U) +#define LCD_WF8B_BPELCD3_SHIFT (4U) +#define LCD_WF8B_BPELCD3(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD3_SHIFT)) & LCD_WF8B_BPELCD3_MASK) +#define LCD_WF8B_BPELCD38_MASK (0x10U) +#define LCD_WF8B_BPELCD38_SHIFT (4U) +#define LCD_WF8B_BPELCD38(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD38_SHIFT)) & LCD_WF8B_BPELCD38_MASK) +#define LCD_WF8B_BPELCD40_MASK (0x10U) +#define LCD_WF8B_BPELCD40_SHIFT (4U) +#define LCD_WF8B_BPELCD40(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD40_SHIFT)) & LCD_WF8B_BPELCD40_MASK) +#define LCD_WF8B_BPELCD37_MASK (0x10U) +#define LCD_WF8B_BPELCD37_SHIFT (4U) +#define LCD_WF8B_BPELCD37(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD37_SHIFT)) & LCD_WF8B_BPELCD37_MASK) +#define LCD_WF8B_BPELCD41_MASK (0x10U) +#define LCD_WF8B_BPELCD41_SHIFT (4U) +#define LCD_WF8B_BPELCD41(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD41_SHIFT)) & LCD_WF8B_BPELCD41_MASK) +#define LCD_WF8B_BPELCD36_MASK (0x10U) +#define LCD_WF8B_BPELCD36_SHIFT (4U) +#define LCD_WF8B_BPELCD36(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD36_SHIFT)) & LCD_WF8B_BPELCD36_MASK) +#define LCD_WF8B_BPELCD8_MASK (0x10U) +#define LCD_WF8B_BPELCD8_SHIFT (4U) +#define LCD_WF8B_BPELCD8(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD8_SHIFT)) & LCD_WF8B_BPELCD8_MASK) +#define LCD_WF8B_BPELCD35_MASK (0x10U) +#define LCD_WF8B_BPELCD35_SHIFT (4U) +#define LCD_WF8B_BPELCD35(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD35_SHIFT)) & LCD_WF8B_BPELCD35_MASK) +#define LCD_WF8B_BPELCD42_MASK (0x10U) +#define LCD_WF8B_BPELCD42_SHIFT (4U) +#define LCD_WF8B_BPELCD42(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD42_SHIFT)) & LCD_WF8B_BPELCD42_MASK) +#define LCD_WF8B_BPELCD34_MASK (0x10U) +#define LCD_WF8B_BPELCD34_SHIFT (4U) +#define LCD_WF8B_BPELCD34(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD34_SHIFT)) & LCD_WF8B_BPELCD34_MASK) +#define LCD_WF8B_BPELCD33_MASK (0x10U) +#define LCD_WF8B_BPELCD33_SHIFT (4U) +#define LCD_WF8B_BPELCD33(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD33_SHIFT)) & LCD_WF8B_BPELCD33_MASK) +#define LCD_WF8B_BPELCD11_MASK (0x10U) +#define LCD_WF8B_BPELCD11_SHIFT (4U) +#define LCD_WF8B_BPELCD11(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD11_SHIFT)) & LCD_WF8B_BPELCD11_MASK) +#define LCD_WF8B_BPELCD43_MASK (0x10U) +#define LCD_WF8B_BPELCD43_SHIFT (4U) +#define LCD_WF8B_BPELCD43(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD43_SHIFT)) & LCD_WF8B_BPELCD43_MASK) +#define LCD_WF8B_BPELCD32_MASK (0x10U) +#define LCD_WF8B_BPELCD32_SHIFT (4U) +#define LCD_WF8B_BPELCD32(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD32_SHIFT)) & LCD_WF8B_BPELCD32_MASK) +#define LCD_WF8B_BPELCD31_MASK (0x10U) +#define LCD_WF8B_BPELCD31_SHIFT (4U) +#define LCD_WF8B_BPELCD31(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD31_SHIFT)) & LCD_WF8B_BPELCD31_MASK) +#define LCD_WF8B_BPELCD44_MASK (0x10U) +#define LCD_WF8B_BPELCD44_SHIFT (4U) +#define LCD_WF8B_BPELCD44(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD44_SHIFT)) & LCD_WF8B_BPELCD44_MASK) +#define LCD_WF8B_BPELCD30_MASK (0x10U) +#define LCD_WF8B_BPELCD30_SHIFT (4U) +#define LCD_WF8B_BPELCD30(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD30_SHIFT)) & LCD_WF8B_BPELCD30_MASK) +#define LCD_WF8B_BPELCD29_MASK (0x10U) +#define LCD_WF8B_BPELCD29_SHIFT (4U) +#define LCD_WF8B_BPELCD29(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD29_SHIFT)) & LCD_WF8B_BPELCD29_MASK) +#define LCD_WF8B_BPELCD7_MASK (0x10U) +#define LCD_WF8B_BPELCD7_SHIFT (4U) +#define LCD_WF8B_BPELCD7(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD7_SHIFT)) & LCD_WF8B_BPELCD7_MASK) +#define LCD_WF8B_BPELCD45_MASK (0x10U) +#define LCD_WF8B_BPELCD45_SHIFT (4U) +#define LCD_WF8B_BPELCD45(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD45_SHIFT)) & LCD_WF8B_BPELCD45_MASK) +#define LCD_WF8B_BPELCD28_MASK (0x10U) +#define LCD_WF8B_BPELCD28_SHIFT (4U) +#define LCD_WF8B_BPELCD28(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD28_SHIFT)) & LCD_WF8B_BPELCD28_MASK) +#define LCD_WF8B_BPELCD2_MASK (0x10U) +#define LCD_WF8B_BPELCD2_SHIFT (4U) +#define LCD_WF8B_BPELCD2(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD2_SHIFT)) & LCD_WF8B_BPELCD2_MASK) +#define LCD_WF8B_BPELCD27_MASK (0x10U) +#define LCD_WF8B_BPELCD27_SHIFT (4U) +#define LCD_WF8B_BPELCD27(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD27_SHIFT)) & LCD_WF8B_BPELCD27_MASK) +#define LCD_WF8B_BPELCD46_MASK (0x10U) +#define LCD_WF8B_BPELCD46_SHIFT (4U) +#define LCD_WF8B_BPELCD46(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD46_SHIFT)) & LCD_WF8B_BPELCD46_MASK) +#define LCD_WF8B_BPELCD26_MASK (0x10U) +#define LCD_WF8B_BPELCD26_SHIFT (4U) +#define LCD_WF8B_BPELCD26(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD26_SHIFT)) & LCD_WF8B_BPELCD26_MASK) +#define LCD_WF8B_BPELCD10_MASK (0x10U) +#define LCD_WF8B_BPELCD10_SHIFT (4U) +#define LCD_WF8B_BPELCD10(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD10_SHIFT)) & LCD_WF8B_BPELCD10_MASK) +#define LCD_WF8B_BPELCD13_MASK (0x10U) +#define LCD_WF8B_BPELCD13_SHIFT (4U) +#define LCD_WF8B_BPELCD13(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD13_SHIFT)) & LCD_WF8B_BPELCD13_MASK) +#define LCD_WF8B_BPELCD25_MASK (0x10U) +#define LCD_WF8B_BPELCD25_SHIFT (4U) +#define LCD_WF8B_BPELCD25(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD25_SHIFT)) & LCD_WF8B_BPELCD25_MASK) +#define LCD_WF8B_BPELCD5_MASK (0x10U) +#define LCD_WF8B_BPELCD5_SHIFT (4U) +#define LCD_WF8B_BPELCD5(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD5_SHIFT)) & LCD_WF8B_BPELCD5_MASK) +#define LCD_WF8B_BPELCD24_MASK (0x10U) +#define LCD_WF8B_BPELCD24_SHIFT (4U) +#define LCD_WF8B_BPELCD24(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD24_SHIFT)) & LCD_WF8B_BPELCD24_MASK) +#define LCD_WF8B_BPELCD47_MASK (0x10U) +#define LCD_WF8B_BPELCD47_SHIFT (4U) +#define LCD_WF8B_BPELCD47(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD47_SHIFT)) & LCD_WF8B_BPELCD47_MASK) +#define LCD_WF8B_BPELCD23_MASK (0x10U) +#define LCD_WF8B_BPELCD23_SHIFT (4U) +#define LCD_WF8B_BPELCD23(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD23_SHIFT)) & LCD_WF8B_BPELCD23_MASK) +#define LCD_WF8B_BPELCD22_MASK (0x10U) +#define LCD_WF8B_BPELCD22_SHIFT (4U) +#define LCD_WF8B_BPELCD22(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD22_SHIFT)) & LCD_WF8B_BPELCD22_MASK) +#define LCD_WF8B_BPELCD48_MASK (0x10U) +#define LCD_WF8B_BPELCD48_SHIFT (4U) +#define LCD_WF8B_BPELCD48(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD48_SHIFT)) & LCD_WF8B_BPELCD48_MASK) +#define LCD_WF8B_BPELCD21_MASK (0x10U) +#define LCD_WF8B_BPELCD21_SHIFT (4U) +#define LCD_WF8B_BPELCD21(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD21_SHIFT)) & LCD_WF8B_BPELCD21_MASK) +#define LCD_WF8B_BPELCD49_MASK (0x10U) +#define LCD_WF8B_BPELCD49_SHIFT (4U) +#define LCD_WF8B_BPELCD49(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD49_SHIFT)) & LCD_WF8B_BPELCD49_MASK) +#define LCD_WF8B_BPELCD20_MASK (0x10U) +#define LCD_WF8B_BPELCD20_SHIFT (4U) +#define LCD_WF8B_BPELCD20(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD20_SHIFT)) & LCD_WF8B_BPELCD20_MASK) +#define LCD_WF8B_BPELCD19_MASK (0x10U) +#define LCD_WF8B_BPELCD19_SHIFT (4U) +#define LCD_WF8B_BPELCD19(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD19_SHIFT)) & LCD_WF8B_BPELCD19_MASK) +#define LCD_WF8B_BPELCD9_MASK (0x10U) +#define LCD_WF8B_BPELCD9_SHIFT (4U) +#define LCD_WF8B_BPELCD9(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD9_SHIFT)) & LCD_WF8B_BPELCD9_MASK) +#define LCD_WF8B_BPELCD50_MASK (0x10U) +#define LCD_WF8B_BPELCD50_SHIFT (4U) +#define LCD_WF8B_BPELCD50(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD50_SHIFT)) & LCD_WF8B_BPELCD50_MASK) +#define LCD_WF8B_BPELCD18_MASK (0x10U) +#define LCD_WF8B_BPELCD18_SHIFT (4U) +#define LCD_WF8B_BPELCD18(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD18_SHIFT)) & LCD_WF8B_BPELCD18_MASK) +#define LCD_WF8B_BPELCD6_MASK (0x10U) +#define LCD_WF8B_BPELCD6_SHIFT (4U) +#define LCD_WF8B_BPELCD6(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD6_SHIFT)) & LCD_WF8B_BPELCD6_MASK) +#define LCD_WF8B_BPELCD17_MASK (0x10U) +#define LCD_WF8B_BPELCD17_SHIFT (4U) +#define LCD_WF8B_BPELCD17(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD17_SHIFT)) & LCD_WF8B_BPELCD17_MASK) +#define LCD_WF8B_BPELCD51_MASK (0x10U) +#define LCD_WF8B_BPELCD51_SHIFT (4U) +#define LCD_WF8B_BPELCD51(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD51_SHIFT)) & LCD_WF8B_BPELCD51_MASK) +#define LCD_WF8B_BPELCD16_MASK (0x10U) +#define LCD_WF8B_BPELCD16_SHIFT (4U) +#define LCD_WF8B_BPELCD16(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD16_SHIFT)) & LCD_WF8B_BPELCD16_MASK) +#define LCD_WF8B_BPELCD56_MASK (0x10U) +#define LCD_WF8B_BPELCD56_SHIFT (4U) +#define LCD_WF8B_BPELCD56(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD56_SHIFT)) & LCD_WF8B_BPELCD56_MASK) +#define LCD_WF8B_BPELCD57_MASK (0x10U) +#define LCD_WF8B_BPELCD57_SHIFT (4U) +#define LCD_WF8B_BPELCD57(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD57_SHIFT)) & LCD_WF8B_BPELCD57_MASK) +#define LCD_WF8B_BPELCD52_MASK (0x10U) +#define LCD_WF8B_BPELCD52_SHIFT (4U) +#define LCD_WF8B_BPELCD52(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD52_SHIFT)) & LCD_WF8B_BPELCD52_MASK) +#define LCD_WF8B_BPELCD1_MASK (0x10U) +#define LCD_WF8B_BPELCD1_SHIFT (4U) +#define LCD_WF8B_BPELCD1(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD1_SHIFT)) & LCD_WF8B_BPELCD1_MASK) +#define LCD_WF8B_BPELCD58_MASK (0x10U) +#define LCD_WF8B_BPELCD58_SHIFT (4U) +#define LCD_WF8B_BPELCD58(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD58_SHIFT)) & LCD_WF8B_BPELCD58_MASK) +#define LCD_WF8B_BPELCD59_MASK (0x10U) +#define LCD_WF8B_BPELCD59_SHIFT (4U) +#define LCD_WF8B_BPELCD59(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD59_SHIFT)) & LCD_WF8B_BPELCD59_MASK) +#define LCD_WF8B_BPELCD53_MASK (0x10U) +#define LCD_WF8B_BPELCD53_SHIFT (4U) +#define LCD_WF8B_BPELCD53(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD53_SHIFT)) & LCD_WF8B_BPELCD53_MASK) +#define LCD_WF8B_BPELCD14_MASK (0x10U) +#define LCD_WF8B_BPELCD14_SHIFT (4U) +#define LCD_WF8B_BPELCD14(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD14_SHIFT)) & LCD_WF8B_BPELCD14_MASK) +#define LCD_WF8B_BPELCD0_MASK (0x10U) +#define LCD_WF8B_BPELCD0_SHIFT (4U) +#define LCD_WF8B_BPELCD0(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD0_SHIFT)) & LCD_WF8B_BPELCD0_MASK) +#define LCD_WF8B_BPELCD60_MASK (0x10U) +#define LCD_WF8B_BPELCD60_SHIFT (4U) +#define LCD_WF8B_BPELCD60(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD60_SHIFT)) & LCD_WF8B_BPELCD60_MASK) +#define LCD_WF8B_BPELCD15_MASK (0x10U) +#define LCD_WF8B_BPELCD15_SHIFT (4U) +#define LCD_WF8B_BPELCD15(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD15_SHIFT)) & LCD_WF8B_BPELCD15_MASK) +#define LCD_WF8B_BPELCD61_MASK (0x10U) +#define LCD_WF8B_BPELCD61_SHIFT (4U) +#define LCD_WF8B_BPELCD61(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD61_SHIFT)) & LCD_WF8B_BPELCD61_MASK) +#define LCD_WF8B_BPELCD54_MASK (0x10U) +#define LCD_WF8B_BPELCD54_SHIFT (4U) +#define LCD_WF8B_BPELCD54(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD54_SHIFT)) & LCD_WF8B_BPELCD54_MASK) +#define LCD_WF8B_BPELCD62_MASK (0x10U) +#define LCD_WF8B_BPELCD62_SHIFT (4U) +#define LCD_WF8B_BPELCD62(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD62_SHIFT)) & LCD_WF8B_BPELCD62_MASK) +#define LCD_WF8B_BPELCD63_MASK (0x10U) +#define LCD_WF8B_BPELCD63_SHIFT (4U) +#define LCD_WF8B_BPELCD63(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD63_SHIFT)) & LCD_WF8B_BPELCD63_MASK) +#define LCD_WF8B_BPELCD55_MASK (0x10U) +#define LCD_WF8B_BPELCD55_SHIFT (4U) +#define LCD_WF8B_BPELCD55(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD55_SHIFT)) & LCD_WF8B_BPELCD55_MASK) +#define LCD_WF8B_BPELCD4_MASK (0x10U) +#define LCD_WF8B_BPELCD4_SHIFT (4U) +#define LCD_WF8B_BPELCD4(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPELCD4_SHIFT)) & LCD_WF8B_BPELCD4_MASK) +#define LCD_WF8B_BPFLCD13_MASK (0x20U) +#define LCD_WF8B_BPFLCD13_SHIFT (5U) +#define LCD_WF8B_BPFLCD13(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD13_SHIFT)) & LCD_WF8B_BPFLCD13_MASK) +#define LCD_WF8B_BPFLCD39_MASK (0x20U) +#define LCD_WF8B_BPFLCD39_SHIFT (5U) +#define LCD_WF8B_BPFLCD39(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD39_SHIFT)) & LCD_WF8B_BPFLCD39_MASK) +#define LCD_WF8B_BPFLCD55_MASK (0x20U) +#define LCD_WF8B_BPFLCD55_SHIFT (5U) +#define LCD_WF8B_BPFLCD55(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD55_SHIFT)) & LCD_WF8B_BPFLCD55_MASK) +#define LCD_WF8B_BPFLCD47_MASK (0x20U) +#define LCD_WF8B_BPFLCD47_SHIFT (5U) +#define LCD_WF8B_BPFLCD47(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD47_SHIFT)) & LCD_WF8B_BPFLCD47_MASK) +#define LCD_WF8B_BPFLCD63_MASK (0x20U) +#define LCD_WF8B_BPFLCD63_SHIFT (5U) +#define LCD_WF8B_BPFLCD63(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD63_SHIFT)) & LCD_WF8B_BPFLCD63_MASK) +#define LCD_WF8B_BPFLCD43_MASK (0x20U) +#define LCD_WF8B_BPFLCD43_SHIFT (5U) +#define LCD_WF8B_BPFLCD43(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD43_SHIFT)) & LCD_WF8B_BPFLCD43_MASK) +#define LCD_WF8B_BPFLCD5_MASK (0x20U) +#define LCD_WF8B_BPFLCD5_SHIFT (5U) +#define LCD_WF8B_BPFLCD5(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD5_SHIFT)) & LCD_WF8B_BPFLCD5_MASK) +#define LCD_WF8B_BPFLCD62_MASK (0x20U) +#define LCD_WF8B_BPFLCD62_SHIFT (5U) +#define LCD_WF8B_BPFLCD62(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD62_SHIFT)) & LCD_WF8B_BPFLCD62_MASK) +#define LCD_WF8B_BPFLCD14_MASK (0x20U) +#define LCD_WF8B_BPFLCD14_SHIFT (5U) +#define LCD_WF8B_BPFLCD14(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD14_SHIFT)) & LCD_WF8B_BPFLCD14_MASK) +#define LCD_WF8B_BPFLCD24_MASK (0x20U) +#define LCD_WF8B_BPFLCD24_SHIFT (5U) +#define LCD_WF8B_BPFLCD24(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD24_SHIFT)) & LCD_WF8B_BPFLCD24_MASK) +#define LCD_WF8B_BPFLCD54_MASK (0x20U) +#define LCD_WF8B_BPFLCD54_SHIFT (5U) +#define LCD_WF8B_BPFLCD54(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD54_SHIFT)) & LCD_WF8B_BPFLCD54_MASK) +#define LCD_WF8B_BPFLCD15_MASK (0x20U) +#define LCD_WF8B_BPFLCD15_SHIFT (5U) +#define LCD_WF8B_BPFLCD15(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD15_SHIFT)) & LCD_WF8B_BPFLCD15_MASK) +#define LCD_WF8B_BPFLCD32_MASK (0x20U) +#define LCD_WF8B_BPFLCD32_SHIFT (5U) +#define LCD_WF8B_BPFLCD32(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD32_SHIFT)) & LCD_WF8B_BPFLCD32_MASK) +#define LCD_WF8B_BPFLCD61_MASK (0x20U) +#define LCD_WF8B_BPFLCD61_SHIFT (5U) +#define LCD_WF8B_BPFLCD61(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD61_SHIFT)) & LCD_WF8B_BPFLCD61_MASK) +#define LCD_WF8B_BPFLCD25_MASK (0x20U) +#define LCD_WF8B_BPFLCD25_SHIFT (5U) +#define LCD_WF8B_BPFLCD25(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD25_SHIFT)) & LCD_WF8B_BPFLCD25_MASK) +#define LCD_WF8B_BPFLCD60_MASK (0x20U) +#define LCD_WF8B_BPFLCD60_SHIFT (5U) +#define LCD_WF8B_BPFLCD60(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD60_SHIFT)) & LCD_WF8B_BPFLCD60_MASK) +#define LCD_WF8B_BPFLCD41_MASK (0x20U) +#define LCD_WF8B_BPFLCD41_SHIFT (5U) +#define LCD_WF8B_BPFLCD41(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD41_SHIFT)) & LCD_WF8B_BPFLCD41_MASK) +#define LCD_WF8B_BPFLCD33_MASK (0x20U) +#define LCD_WF8B_BPFLCD33_SHIFT (5U) +#define LCD_WF8B_BPFLCD33(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD33_SHIFT)) & LCD_WF8B_BPFLCD33_MASK) +#define LCD_WF8B_BPFLCD53_MASK (0x20U) +#define LCD_WF8B_BPFLCD53_SHIFT (5U) +#define LCD_WF8B_BPFLCD53(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD53_SHIFT)) & LCD_WF8B_BPFLCD53_MASK) +#define LCD_WF8B_BPFLCD59_MASK (0x20U) +#define LCD_WF8B_BPFLCD59_SHIFT (5U) +#define LCD_WF8B_BPFLCD59(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD59_SHIFT)) & LCD_WF8B_BPFLCD59_MASK) +#define LCD_WF8B_BPFLCD0_MASK (0x20U) +#define LCD_WF8B_BPFLCD0_SHIFT (5U) +#define LCD_WF8B_BPFLCD0(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD0_SHIFT)) & LCD_WF8B_BPFLCD0_MASK) +#define LCD_WF8B_BPFLCD46_MASK (0x20U) +#define LCD_WF8B_BPFLCD46_SHIFT (5U) +#define LCD_WF8B_BPFLCD46(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD46_SHIFT)) & LCD_WF8B_BPFLCD46_MASK) +#define LCD_WF8B_BPFLCD58_MASK (0x20U) +#define LCD_WF8B_BPFLCD58_SHIFT (5U) +#define LCD_WF8B_BPFLCD58(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD58_SHIFT)) & LCD_WF8B_BPFLCD58_MASK) +#define LCD_WF8B_BPFLCD26_MASK (0x20U) +#define LCD_WF8B_BPFLCD26_SHIFT (5U) +#define LCD_WF8B_BPFLCD26(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD26_SHIFT)) & LCD_WF8B_BPFLCD26_MASK) +#define LCD_WF8B_BPFLCD36_MASK (0x20U) +#define LCD_WF8B_BPFLCD36_SHIFT (5U) +#define LCD_WF8B_BPFLCD36(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD36_SHIFT)) & LCD_WF8B_BPFLCD36_MASK) +#define LCD_WF8B_BPFLCD10_MASK (0x20U) +#define LCD_WF8B_BPFLCD10_SHIFT (5U) +#define LCD_WF8B_BPFLCD10(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD10_SHIFT)) & LCD_WF8B_BPFLCD10_MASK) +#define LCD_WF8B_BPFLCD52_MASK (0x20U) +#define LCD_WF8B_BPFLCD52_SHIFT (5U) +#define LCD_WF8B_BPFLCD52(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD52_SHIFT)) & LCD_WF8B_BPFLCD52_MASK) +#define LCD_WF8B_BPFLCD57_MASK (0x20U) +#define LCD_WF8B_BPFLCD57_SHIFT (5U) +#define LCD_WF8B_BPFLCD57(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD57_SHIFT)) & LCD_WF8B_BPFLCD57_MASK) +#define LCD_WF8B_BPFLCD27_MASK (0x20U) +#define LCD_WF8B_BPFLCD27_SHIFT (5U) +#define LCD_WF8B_BPFLCD27(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD27_SHIFT)) & LCD_WF8B_BPFLCD27_MASK) +#define LCD_WF8B_BPFLCD11_MASK (0x20U) +#define LCD_WF8B_BPFLCD11_SHIFT (5U) +#define LCD_WF8B_BPFLCD11(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD11_SHIFT)) & LCD_WF8B_BPFLCD11_MASK) +#define LCD_WF8B_BPFLCD56_MASK (0x20U) +#define LCD_WF8B_BPFLCD56_SHIFT (5U) +#define LCD_WF8B_BPFLCD56(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD56_SHIFT)) & LCD_WF8B_BPFLCD56_MASK) +#define LCD_WF8B_BPFLCD1_MASK (0x20U) +#define LCD_WF8B_BPFLCD1_SHIFT (5U) +#define LCD_WF8B_BPFLCD1(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD1_SHIFT)) & LCD_WF8B_BPFLCD1_MASK) +#define LCD_WF8B_BPFLCD8_MASK (0x20U) +#define LCD_WF8B_BPFLCD8_SHIFT (5U) +#define LCD_WF8B_BPFLCD8(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD8_SHIFT)) & LCD_WF8B_BPFLCD8_MASK) +#define LCD_WF8B_BPFLCD40_MASK (0x20U) +#define LCD_WF8B_BPFLCD40_SHIFT (5U) +#define LCD_WF8B_BPFLCD40(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD40_SHIFT)) & LCD_WF8B_BPFLCD40_MASK) +#define LCD_WF8B_BPFLCD51_MASK (0x20U) +#define LCD_WF8B_BPFLCD51_SHIFT (5U) +#define LCD_WF8B_BPFLCD51(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD51_SHIFT)) & LCD_WF8B_BPFLCD51_MASK) +#define LCD_WF8B_BPFLCD16_MASK (0x20U) +#define LCD_WF8B_BPFLCD16_SHIFT (5U) +#define LCD_WF8B_BPFLCD16(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD16_SHIFT)) & LCD_WF8B_BPFLCD16_MASK) +#define LCD_WF8B_BPFLCD45_MASK (0x20U) +#define LCD_WF8B_BPFLCD45_SHIFT (5U) +#define LCD_WF8B_BPFLCD45(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD45_SHIFT)) & LCD_WF8B_BPFLCD45_MASK) +#define LCD_WF8B_BPFLCD6_MASK (0x20U) +#define LCD_WF8B_BPFLCD6_SHIFT (5U) +#define LCD_WF8B_BPFLCD6(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD6_SHIFT)) & LCD_WF8B_BPFLCD6_MASK) +#define LCD_WF8B_BPFLCD17_MASK (0x20U) +#define LCD_WF8B_BPFLCD17_SHIFT (5U) +#define LCD_WF8B_BPFLCD17(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD17_SHIFT)) & LCD_WF8B_BPFLCD17_MASK) +#define LCD_WF8B_BPFLCD28_MASK (0x20U) +#define LCD_WF8B_BPFLCD28_SHIFT (5U) +#define LCD_WF8B_BPFLCD28(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD28_SHIFT)) & LCD_WF8B_BPFLCD28_MASK) +#define LCD_WF8B_BPFLCD42_MASK (0x20U) +#define LCD_WF8B_BPFLCD42_SHIFT (5U) +#define LCD_WF8B_BPFLCD42(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD42_SHIFT)) & LCD_WF8B_BPFLCD42_MASK) +#define LCD_WF8B_BPFLCD29_MASK (0x20U) +#define LCD_WF8B_BPFLCD29_SHIFT (5U) +#define LCD_WF8B_BPFLCD29(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD29_SHIFT)) & LCD_WF8B_BPFLCD29_MASK) +#define LCD_WF8B_BPFLCD50_MASK (0x20U) +#define LCD_WF8B_BPFLCD50_SHIFT (5U) +#define LCD_WF8B_BPFLCD50(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD50_SHIFT)) & LCD_WF8B_BPFLCD50_MASK) +#define LCD_WF8B_BPFLCD18_MASK (0x20U) +#define LCD_WF8B_BPFLCD18_SHIFT (5U) +#define LCD_WF8B_BPFLCD18(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD18_SHIFT)) & LCD_WF8B_BPFLCD18_MASK) +#define LCD_WF8B_BPFLCD34_MASK (0x20U) +#define LCD_WF8B_BPFLCD34_SHIFT (5U) +#define LCD_WF8B_BPFLCD34(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD34_SHIFT)) & LCD_WF8B_BPFLCD34_MASK) +#define LCD_WF8B_BPFLCD19_MASK (0x20U) +#define LCD_WF8B_BPFLCD19_SHIFT (5U) +#define LCD_WF8B_BPFLCD19(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD19_SHIFT)) & LCD_WF8B_BPFLCD19_MASK) +#define LCD_WF8B_BPFLCD2_MASK (0x20U) +#define LCD_WF8B_BPFLCD2_SHIFT (5U) +#define LCD_WF8B_BPFLCD2(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD2_SHIFT)) & LCD_WF8B_BPFLCD2_MASK) +#define LCD_WF8B_BPFLCD9_MASK (0x20U) +#define LCD_WF8B_BPFLCD9_SHIFT (5U) +#define LCD_WF8B_BPFLCD9(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD9_SHIFT)) & LCD_WF8B_BPFLCD9_MASK) +#define LCD_WF8B_BPFLCD3_MASK (0x20U) +#define LCD_WF8B_BPFLCD3_SHIFT (5U) +#define LCD_WF8B_BPFLCD3(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD3_SHIFT)) & LCD_WF8B_BPFLCD3_MASK) +#define LCD_WF8B_BPFLCD37_MASK (0x20U) +#define LCD_WF8B_BPFLCD37_SHIFT (5U) +#define LCD_WF8B_BPFLCD37(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD37_SHIFT)) & LCD_WF8B_BPFLCD37_MASK) +#define LCD_WF8B_BPFLCD49_MASK (0x20U) +#define LCD_WF8B_BPFLCD49_SHIFT (5U) +#define LCD_WF8B_BPFLCD49(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD49_SHIFT)) & LCD_WF8B_BPFLCD49_MASK) +#define LCD_WF8B_BPFLCD20_MASK (0x20U) +#define LCD_WF8B_BPFLCD20_SHIFT (5U) +#define LCD_WF8B_BPFLCD20(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD20_SHIFT)) & LCD_WF8B_BPFLCD20_MASK) +#define LCD_WF8B_BPFLCD44_MASK (0x20U) +#define LCD_WF8B_BPFLCD44_SHIFT (5U) +#define LCD_WF8B_BPFLCD44(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD44_SHIFT)) & LCD_WF8B_BPFLCD44_MASK) +#define LCD_WF8B_BPFLCD30_MASK (0x20U) +#define LCD_WF8B_BPFLCD30_SHIFT (5U) +#define LCD_WF8B_BPFLCD30(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD30_SHIFT)) & LCD_WF8B_BPFLCD30_MASK) +#define LCD_WF8B_BPFLCD21_MASK (0x20U) +#define LCD_WF8B_BPFLCD21_SHIFT (5U) +#define LCD_WF8B_BPFLCD21(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD21_SHIFT)) & LCD_WF8B_BPFLCD21_MASK) +#define LCD_WF8B_BPFLCD35_MASK (0x20U) +#define LCD_WF8B_BPFLCD35_SHIFT (5U) +#define LCD_WF8B_BPFLCD35(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD35_SHIFT)) & LCD_WF8B_BPFLCD35_MASK) +#define LCD_WF8B_BPFLCD4_MASK (0x20U) +#define LCD_WF8B_BPFLCD4_SHIFT (5U) +#define LCD_WF8B_BPFLCD4(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD4_SHIFT)) & LCD_WF8B_BPFLCD4_MASK) +#define LCD_WF8B_BPFLCD31_MASK (0x20U) +#define LCD_WF8B_BPFLCD31_SHIFT (5U) +#define LCD_WF8B_BPFLCD31(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD31_SHIFT)) & LCD_WF8B_BPFLCD31_MASK) +#define LCD_WF8B_BPFLCD48_MASK (0x20U) +#define LCD_WF8B_BPFLCD48_SHIFT (5U) +#define LCD_WF8B_BPFLCD48(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD48_SHIFT)) & LCD_WF8B_BPFLCD48_MASK) +#define LCD_WF8B_BPFLCD7_MASK (0x20U) +#define LCD_WF8B_BPFLCD7_SHIFT (5U) +#define LCD_WF8B_BPFLCD7(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD7_SHIFT)) & LCD_WF8B_BPFLCD7_MASK) +#define LCD_WF8B_BPFLCD22_MASK (0x20U) +#define LCD_WF8B_BPFLCD22_SHIFT (5U) +#define LCD_WF8B_BPFLCD22(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD22_SHIFT)) & LCD_WF8B_BPFLCD22_MASK) +#define LCD_WF8B_BPFLCD38_MASK (0x20U) +#define LCD_WF8B_BPFLCD38_SHIFT (5U) +#define LCD_WF8B_BPFLCD38(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD38_SHIFT)) & LCD_WF8B_BPFLCD38_MASK) +#define LCD_WF8B_BPFLCD12_MASK (0x20U) +#define LCD_WF8B_BPFLCD12_SHIFT (5U) +#define LCD_WF8B_BPFLCD12(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD12_SHIFT)) & LCD_WF8B_BPFLCD12_MASK) +#define LCD_WF8B_BPFLCD23_MASK (0x20U) +#define LCD_WF8B_BPFLCD23_SHIFT (5U) +#define LCD_WF8B_BPFLCD23(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPFLCD23_SHIFT)) & LCD_WF8B_BPFLCD23_MASK) +#define LCD_WF8B_BPGLCD14_MASK (0x40U) +#define LCD_WF8B_BPGLCD14_SHIFT (6U) +#define LCD_WF8B_BPGLCD14(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD14_SHIFT)) & LCD_WF8B_BPGLCD14_MASK) +#define LCD_WF8B_BPGLCD55_MASK (0x40U) +#define LCD_WF8B_BPGLCD55_SHIFT (6U) +#define LCD_WF8B_BPGLCD55(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD55_SHIFT)) & LCD_WF8B_BPGLCD55_MASK) +#define LCD_WF8B_BPGLCD63_MASK (0x40U) +#define LCD_WF8B_BPGLCD63_SHIFT (6U) +#define LCD_WF8B_BPGLCD63(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD63_SHIFT)) & LCD_WF8B_BPGLCD63_MASK) +#define LCD_WF8B_BPGLCD15_MASK (0x40U) +#define LCD_WF8B_BPGLCD15_SHIFT (6U) +#define LCD_WF8B_BPGLCD15(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD15_SHIFT)) & LCD_WF8B_BPGLCD15_MASK) +#define LCD_WF8B_BPGLCD62_MASK (0x40U) +#define LCD_WF8B_BPGLCD62_SHIFT (6U) +#define LCD_WF8B_BPGLCD62(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD62_SHIFT)) & LCD_WF8B_BPGLCD62_MASK) +#define LCD_WF8B_BPGLCD54_MASK (0x40U) +#define LCD_WF8B_BPGLCD54_SHIFT (6U) +#define LCD_WF8B_BPGLCD54(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD54_SHIFT)) & LCD_WF8B_BPGLCD54_MASK) +#define LCD_WF8B_BPGLCD61_MASK (0x40U) +#define LCD_WF8B_BPGLCD61_SHIFT (6U) +#define LCD_WF8B_BPGLCD61(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD61_SHIFT)) & LCD_WF8B_BPGLCD61_MASK) +#define LCD_WF8B_BPGLCD60_MASK (0x40U) +#define LCD_WF8B_BPGLCD60_SHIFT (6U) +#define LCD_WF8B_BPGLCD60(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD60_SHIFT)) & LCD_WF8B_BPGLCD60_MASK) +#define LCD_WF8B_BPGLCD59_MASK (0x40U) +#define LCD_WF8B_BPGLCD59_SHIFT (6U) +#define LCD_WF8B_BPGLCD59(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD59_SHIFT)) & LCD_WF8B_BPGLCD59_MASK) +#define LCD_WF8B_BPGLCD53_MASK (0x40U) +#define LCD_WF8B_BPGLCD53_SHIFT (6U) +#define LCD_WF8B_BPGLCD53(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD53_SHIFT)) & LCD_WF8B_BPGLCD53_MASK) +#define LCD_WF8B_BPGLCD58_MASK (0x40U) +#define LCD_WF8B_BPGLCD58_SHIFT (6U) +#define LCD_WF8B_BPGLCD58(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD58_SHIFT)) & LCD_WF8B_BPGLCD58_MASK) +#define LCD_WF8B_BPGLCD0_MASK (0x40U) +#define LCD_WF8B_BPGLCD0_SHIFT (6U) +#define LCD_WF8B_BPGLCD0(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD0_SHIFT)) & LCD_WF8B_BPGLCD0_MASK) +#define LCD_WF8B_BPGLCD57_MASK (0x40U) +#define LCD_WF8B_BPGLCD57_SHIFT (6U) +#define LCD_WF8B_BPGLCD57(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD57_SHIFT)) & LCD_WF8B_BPGLCD57_MASK) +#define LCD_WF8B_BPGLCD52_MASK (0x40U) +#define LCD_WF8B_BPGLCD52_SHIFT (6U) +#define LCD_WF8B_BPGLCD52(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD52_SHIFT)) & LCD_WF8B_BPGLCD52_MASK) +#define LCD_WF8B_BPGLCD7_MASK (0x40U) +#define LCD_WF8B_BPGLCD7_SHIFT (6U) +#define LCD_WF8B_BPGLCD7(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD7_SHIFT)) & LCD_WF8B_BPGLCD7_MASK) +#define LCD_WF8B_BPGLCD56_MASK (0x40U) +#define LCD_WF8B_BPGLCD56_SHIFT (6U) +#define LCD_WF8B_BPGLCD56(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD56_SHIFT)) & LCD_WF8B_BPGLCD56_MASK) +#define LCD_WF8B_BPGLCD6_MASK (0x40U) +#define LCD_WF8B_BPGLCD6_SHIFT (6U) +#define LCD_WF8B_BPGLCD6(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD6_SHIFT)) & LCD_WF8B_BPGLCD6_MASK) +#define LCD_WF8B_BPGLCD51_MASK (0x40U) +#define LCD_WF8B_BPGLCD51_SHIFT (6U) +#define LCD_WF8B_BPGLCD51(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD51_SHIFT)) & LCD_WF8B_BPGLCD51_MASK) +#define LCD_WF8B_BPGLCD16_MASK (0x40U) +#define LCD_WF8B_BPGLCD16_SHIFT (6U) +#define LCD_WF8B_BPGLCD16(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD16_SHIFT)) & LCD_WF8B_BPGLCD16_MASK) +#define LCD_WF8B_BPGLCD1_MASK (0x40U) +#define LCD_WF8B_BPGLCD1_SHIFT (6U) +#define LCD_WF8B_BPGLCD1(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD1_SHIFT)) & LCD_WF8B_BPGLCD1_MASK) +#define LCD_WF8B_BPGLCD17_MASK (0x40U) +#define LCD_WF8B_BPGLCD17_SHIFT (6U) +#define LCD_WF8B_BPGLCD17(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD17_SHIFT)) & LCD_WF8B_BPGLCD17_MASK) +#define LCD_WF8B_BPGLCD50_MASK (0x40U) +#define LCD_WF8B_BPGLCD50_SHIFT (6U) +#define LCD_WF8B_BPGLCD50(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD50_SHIFT)) & LCD_WF8B_BPGLCD50_MASK) +#define LCD_WF8B_BPGLCD18_MASK (0x40U) +#define LCD_WF8B_BPGLCD18_SHIFT (6U) +#define LCD_WF8B_BPGLCD18(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD18_SHIFT)) & LCD_WF8B_BPGLCD18_MASK) +#define LCD_WF8B_BPGLCD19_MASK (0x40U) +#define LCD_WF8B_BPGLCD19_SHIFT (6U) +#define LCD_WF8B_BPGLCD19(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD19_SHIFT)) & LCD_WF8B_BPGLCD19_MASK) +#define LCD_WF8B_BPGLCD8_MASK (0x40U) +#define LCD_WF8B_BPGLCD8_SHIFT (6U) +#define LCD_WF8B_BPGLCD8(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD8_SHIFT)) & LCD_WF8B_BPGLCD8_MASK) +#define LCD_WF8B_BPGLCD49_MASK (0x40U) +#define LCD_WF8B_BPGLCD49_SHIFT (6U) +#define LCD_WF8B_BPGLCD49(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD49_SHIFT)) & LCD_WF8B_BPGLCD49_MASK) +#define LCD_WF8B_BPGLCD20_MASK (0x40U) +#define LCD_WF8B_BPGLCD20_SHIFT (6U) +#define LCD_WF8B_BPGLCD20(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD20_SHIFT)) & LCD_WF8B_BPGLCD20_MASK) +#define LCD_WF8B_BPGLCD9_MASK (0x40U) +#define LCD_WF8B_BPGLCD9_SHIFT (6U) +#define LCD_WF8B_BPGLCD9(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD9_SHIFT)) & LCD_WF8B_BPGLCD9_MASK) +#define LCD_WF8B_BPGLCD21_MASK (0x40U) +#define LCD_WF8B_BPGLCD21_SHIFT (6U) +#define LCD_WF8B_BPGLCD21(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD21_SHIFT)) & LCD_WF8B_BPGLCD21_MASK) +#define LCD_WF8B_BPGLCD13_MASK (0x40U) +#define LCD_WF8B_BPGLCD13_SHIFT (6U) +#define LCD_WF8B_BPGLCD13(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD13_SHIFT)) & LCD_WF8B_BPGLCD13_MASK) +#define LCD_WF8B_BPGLCD48_MASK (0x40U) +#define LCD_WF8B_BPGLCD48_SHIFT (6U) +#define LCD_WF8B_BPGLCD48(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD48_SHIFT)) & LCD_WF8B_BPGLCD48_MASK) +#define LCD_WF8B_BPGLCD22_MASK (0x40U) +#define LCD_WF8B_BPGLCD22_SHIFT (6U) +#define LCD_WF8B_BPGLCD22(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD22_SHIFT)) & LCD_WF8B_BPGLCD22_MASK) +#define LCD_WF8B_BPGLCD5_MASK (0x40U) +#define LCD_WF8B_BPGLCD5_SHIFT (6U) +#define LCD_WF8B_BPGLCD5(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD5_SHIFT)) & LCD_WF8B_BPGLCD5_MASK) +#define LCD_WF8B_BPGLCD47_MASK (0x40U) +#define LCD_WF8B_BPGLCD47_SHIFT (6U) +#define LCD_WF8B_BPGLCD47(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD47_SHIFT)) & LCD_WF8B_BPGLCD47_MASK) +#define LCD_WF8B_BPGLCD23_MASK (0x40U) +#define LCD_WF8B_BPGLCD23_SHIFT (6U) +#define LCD_WF8B_BPGLCD23(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD23_SHIFT)) & LCD_WF8B_BPGLCD23_MASK) +#define LCD_WF8B_BPGLCD24_MASK (0x40U) +#define LCD_WF8B_BPGLCD24_SHIFT (6U) +#define LCD_WF8B_BPGLCD24(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD24_SHIFT)) & LCD_WF8B_BPGLCD24_MASK) +#define LCD_WF8B_BPGLCD25_MASK (0x40U) +#define LCD_WF8B_BPGLCD25_SHIFT (6U) +#define LCD_WF8B_BPGLCD25(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD25_SHIFT)) & LCD_WF8B_BPGLCD25_MASK) +#define LCD_WF8B_BPGLCD46_MASK (0x40U) +#define LCD_WF8B_BPGLCD46_SHIFT (6U) +#define LCD_WF8B_BPGLCD46(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD46_SHIFT)) & LCD_WF8B_BPGLCD46_MASK) +#define LCD_WF8B_BPGLCD26_MASK (0x40U) +#define LCD_WF8B_BPGLCD26_SHIFT (6U) +#define LCD_WF8B_BPGLCD26(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD26_SHIFT)) & LCD_WF8B_BPGLCD26_MASK) +#define LCD_WF8B_BPGLCD27_MASK (0x40U) +#define LCD_WF8B_BPGLCD27_SHIFT (6U) +#define LCD_WF8B_BPGLCD27(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD27_SHIFT)) & LCD_WF8B_BPGLCD27_MASK) +#define LCD_WF8B_BPGLCD10_MASK (0x40U) +#define LCD_WF8B_BPGLCD10_SHIFT (6U) +#define LCD_WF8B_BPGLCD10(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD10_SHIFT)) & LCD_WF8B_BPGLCD10_MASK) +#define LCD_WF8B_BPGLCD45_MASK (0x40U) +#define LCD_WF8B_BPGLCD45_SHIFT (6U) +#define LCD_WF8B_BPGLCD45(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD45_SHIFT)) & LCD_WF8B_BPGLCD45_MASK) +#define LCD_WF8B_BPGLCD28_MASK (0x40U) +#define LCD_WF8B_BPGLCD28_SHIFT (6U) +#define LCD_WF8B_BPGLCD28(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD28_SHIFT)) & LCD_WF8B_BPGLCD28_MASK) +#define LCD_WF8B_BPGLCD29_MASK (0x40U) +#define LCD_WF8B_BPGLCD29_SHIFT (6U) +#define LCD_WF8B_BPGLCD29(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD29_SHIFT)) & LCD_WF8B_BPGLCD29_MASK) +#define LCD_WF8B_BPGLCD4_MASK (0x40U) +#define LCD_WF8B_BPGLCD4_SHIFT (6U) +#define LCD_WF8B_BPGLCD4(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD4_SHIFT)) & LCD_WF8B_BPGLCD4_MASK) +#define LCD_WF8B_BPGLCD44_MASK (0x40U) +#define LCD_WF8B_BPGLCD44_SHIFT (6U) +#define LCD_WF8B_BPGLCD44(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD44_SHIFT)) & LCD_WF8B_BPGLCD44_MASK) +#define LCD_WF8B_BPGLCD30_MASK (0x40U) +#define LCD_WF8B_BPGLCD30_SHIFT (6U) +#define LCD_WF8B_BPGLCD30(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD30_SHIFT)) & LCD_WF8B_BPGLCD30_MASK) +#define LCD_WF8B_BPGLCD2_MASK (0x40U) +#define LCD_WF8B_BPGLCD2_SHIFT (6U) +#define LCD_WF8B_BPGLCD2(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD2_SHIFT)) & LCD_WF8B_BPGLCD2_MASK) +#define LCD_WF8B_BPGLCD31_MASK (0x40U) +#define LCD_WF8B_BPGLCD31_SHIFT (6U) +#define LCD_WF8B_BPGLCD31(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD31_SHIFT)) & LCD_WF8B_BPGLCD31_MASK) +#define LCD_WF8B_BPGLCD43_MASK (0x40U) +#define LCD_WF8B_BPGLCD43_SHIFT (6U) +#define LCD_WF8B_BPGLCD43(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD43_SHIFT)) & LCD_WF8B_BPGLCD43_MASK) +#define LCD_WF8B_BPGLCD32_MASK (0x40U) +#define LCD_WF8B_BPGLCD32_SHIFT (6U) +#define LCD_WF8B_BPGLCD32(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD32_SHIFT)) & LCD_WF8B_BPGLCD32_MASK) +#define LCD_WF8B_BPGLCD33_MASK (0x40U) +#define LCD_WF8B_BPGLCD33_SHIFT (6U) +#define LCD_WF8B_BPGLCD33(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD33_SHIFT)) & LCD_WF8B_BPGLCD33_MASK) +#define LCD_WF8B_BPGLCD42_MASK (0x40U) +#define LCD_WF8B_BPGLCD42_SHIFT (6U) +#define LCD_WF8B_BPGLCD42(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD42_SHIFT)) & LCD_WF8B_BPGLCD42_MASK) +#define LCD_WF8B_BPGLCD34_MASK (0x40U) +#define LCD_WF8B_BPGLCD34_SHIFT (6U) +#define LCD_WF8B_BPGLCD34(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD34_SHIFT)) & LCD_WF8B_BPGLCD34_MASK) +#define LCD_WF8B_BPGLCD11_MASK (0x40U) +#define LCD_WF8B_BPGLCD11_SHIFT (6U) +#define LCD_WF8B_BPGLCD11(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD11_SHIFT)) & LCD_WF8B_BPGLCD11_MASK) +#define LCD_WF8B_BPGLCD35_MASK (0x40U) +#define LCD_WF8B_BPGLCD35_SHIFT (6U) +#define LCD_WF8B_BPGLCD35(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD35_SHIFT)) & LCD_WF8B_BPGLCD35_MASK) +#define LCD_WF8B_BPGLCD12_MASK (0x40U) +#define LCD_WF8B_BPGLCD12_SHIFT (6U) +#define LCD_WF8B_BPGLCD12(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD12_SHIFT)) & LCD_WF8B_BPGLCD12_MASK) +#define LCD_WF8B_BPGLCD41_MASK (0x40U) +#define LCD_WF8B_BPGLCD41_SHIFT (6U) +#define LCD_WF8B_BPGLCD41(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD41_SHIFT)) & LCD_WF8B_BPGLCD41_MASK) +#define LCD_WF8B_BPGLCD36_MASK (0x40U) +#define LCD_WF8B_BPGLCD36_SHIFT (6U) +#define LCD_WF8B_BPGLCD36(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD36_SHIFT)) & LCD_WF8B_BPGLCD36_MASK) +#define LCD_WF8B_BPGLCD3_MASK (0x40U) +#define LCD_WF8B_BPGLCD3_SHIFT (6U) +#define LCD_WF8B_BPGLCD3(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD3_SHIFT)) & LCD_WF8B_BPGLCD3_MASK) +#define LCD_WF8B_BPGLCD37_MASK (0x40U) +#define LCD_WF8B_BPGLCD37_SHIFT (6U) +#define LCD_WF8B_BPGLCD37(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD37_SHIFT)) & LCD_WF8B_BPGLCD37_MASK) +#define LCD_WF8B_BPGLCD40_MASK (0x40U) +#define LCD_WF8B_BPGLCD40_SHIFT (6U) +#define LCD_WF8B_BPGLCD40(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD40_SHIFT)) & LCD_WF8B_BPGLCD40_MASK) +#define LCD_WF8B_BPGLCD38_MASK (0x40U) +#define LCD_WF8B_BPGLCD38_SHIFT (6U) +#define LCD_WF8B_BPGLCD38(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD38_SHIFT)) & LCD_WF8B_BPGLCD38_MASK) +#define LCD_WF8B_BPGLCD39_MASK (0x40U) +#define LCD_WF8B_BPGLCD39_SHIFT (6U) +#define LCD_WF8B_BPGLCD39(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPGLCD39_SHIFT)) & LCD_WF8B_BPGLCD39_MASK) +#define LCD_WF8B_BPHLCD63_MASK (0x80U) +#define LCD_WF8B_BPHLCD63_SHIFT (7U) +#define LCD_WF8B_BPHLCD63(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD63_SHIFT)) & LCD_WF8B_BPHLCD63_MASK) +#define LCD_WF8B_BPHLCD62_MASK (0x80U) +#define LCD_WF8B_BPHLCD62_SHIFT (7U) +#define LCD_WF8B_BPHLCD62(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD62_SHIFT)) & LCD_WF8B_BPHLCD62_MASK) +#define LCD_WF8B_BPHLCD61_MASK (0x80U) +#define LCD_WF8B_BPHLCD61_SHIFT (7U) +#define LCD_WF8B_BPHLCD61(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD61_SHIFT)) & LCD_WF8B_BPHLCD61_MASK) +#define LCD_WF8B_BPHLCD60_MASK (0x80U) +#define LCD_WF8B_BPHLCD60_SHIFT (7U) +#define LCD_WF8B_BPHLCD60(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD60_SHIFT)) & LCD_WF8B_BPHLCD60_MASK) +#define LCD_WF8B_BPHLCD59_MASK (0x80U) +#define LCD_WF8B_BPHLCD59_SHIFT (7U) +#define LCD_WF8B_BPHLCD59(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD59_SHIFT)) & LCD_WF8B_BPHLCD59_MASK) +#define LCD_WF8B_BPHLCD58_MASK (0x80U) +#define LCD_WF8B_BPHLCD58_SHIFT (7U) +#define LCD_WF8B_BPHLCD58(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD58_SHIFT)) & LCD_WF8B_BPHLCD58_MASK) +#define LCD_WF8B_BPHLCD57_MASK (0x80U) +#define LCD_WF8B_BPHLCD57_SHIFT (7U) +#define LCD_WF8B_BPHLCD57(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD57_SHIFT)) & LCD_WF8B_BPHLCD57_MASK) +#define LCD_WF8B_BPHLCD0_MASK (0x80U) +#define LCD_WF8B_BPHLCD0_SHIFT (7U) +#define LCD_WF8B_BPHLCD0(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD0_SHIFT)) & LCD_WF8B_BPHLCD0_MASK) +#define LCD_WF8B_BPHLCD56_MASK (0x80U) +#define LCD_WF8B_BPHLCD56_SHIFT (7U) +#define LCD_WF8B_BPHLCD56(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD56_SHIFT)) & LCD_WF8B_BPHLCD56_MASK) +#define LCD_WF8B_BPHLCD55_MASK (0x80U) +#define LCD_WF8B_BPHLCD55_SHIFT (7U) +#define LCD_WF8B_BPHLCD55(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD55_SHIFT)) & LCD_WF8B_BPHLCD55_MASK) +#define LCD_WF8B_BPHLCD54_MASK (0x80U) +#define LCD_WF8B_BPHLCD54_SHIFT (7U) +#define LCD_WF8B_BPHLCD54(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD54_SHIFT)) & LCD_WF8B_BPHLCD54_MASK) +#define LCD_WF8B_BPHLCD53_MASK (0x80U) +#define LCD_WF8B_BPHLCD53_SHIFT (7U) +#define LCD_WF8B_BPHLCD53(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD53_SHIFT)) & LCD_WF8B_BPHLCD53_MASK) +#define LCD_WF8B_BPHLCD52_MASK (0x80U) +#define LCD_WF8B_BPHLCD52_SHIFT (7U) +#define LCD_WF8B_BPHLCD52(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD52_SHIFT)) & LCD_WF8B_BPHLCD52_MASK) +#define LCD_WF8B_BPHLCD51_MASK (0x80U) +#define LCD_WF8B_BPHLCD51_SHIFT (7U) +#define LCD_WF8B_BPHLCD51(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD51_SHIFT)) & LCD_WF8B_BPHLCD51_MASK) +#define LCD_WF8B_BPHLCD50_MASK (0x80U) +#define LCD_WF8B_BPHLCD50_SHIFT (7U) +#define LCD_WF8B_BPHLCD50(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD50_SHIFT)) & LCD_WF8B_BPHLCD50_MASK) +#define LCD_WF8B_BPHLCD1_MASK (0x80U) +#define LCD_WF8B_BPHLCD1_SHIFT (7U) +#define LCD_WF8B_BPHLCD1(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD1_SHIFT)) & LCD_WF8B_BPHLCD1_MASK) +#define LCD_WF8B_BPHLCD49_MASK (0x80U) +#define LCD_WF8B_BPHLCD49_SHIFT (7U) +#define LCD_WF8B_BPHLCD49(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD49_SHIFT)) & LCD_WF8B_BPHLCD49_MASK) +#define LCD_WF8B_BPHLCD48_MASK (0x80U) +#define LCD_WF8B_BPHLCD48_SHIFT (7U) +#define LCD_WF8B_BPHLCD48(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD48_SHIFT)) & LCD_WF8B_BPHLCD48_MASK) +#define LCD_WF8B_BPHLCD47_MASK (0x80U) +#define LCD_WF8B_BPHLCD47_SHIFT (7U) +#define LCD_WF8B_BPHLCD47(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD47_SHIFT)) & LCD_WF8B_BPHLCD47_MASK) +#define LCD_WF8B_BPHLCD46_MASK (0x80U) +#define LCD_WF8B_BPHLCD46_SHIFT (7U) +#define LCD_WF8B_BPHLCD46(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD46_SHIFT)) & LCD_WF8B_BPHLCD46_MASK) +#define LCD_WF8B_BPHLCD45_MASK (0x80U) +#define LCD_WF8B_BPHLCD45_SHIFT (7U) +#define LCD_WF8B_BPHLCD45(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD45_SHIFT)) & LCD_WF8B_BPHLCD45_MASK) +#define LCD_WF8B_BPHLCD44_MASK (0x80U) +#define LCD_WF8B_BPHLCD44_SHIFT (7U) +#define LCD_WF8B_BPHLCD44(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD44_SHIFT)) & LCD_WF8B_BPHLCD44_MASK) +#define LCD_WF8B_BPHLCD43_MASK (0x80U) +#define LCD_WF8B_BPHLCD43_SHIFT (7U) +#define LCD_WF8B_BPHLCD43(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD43_SHIFT)) & LCD_WF8B_BPHLCD43_MASK) +#define LCD_WF8B_BPHLCD2_MASK (0x80U) +#define LCD_WF8B_BPHLCD2_SHIFT (7U) +#define LCD_WF8B_BPHLCD2(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD2_SHIFT)) & LCD_WF8B_BPHLCD2_MASK) +#define LCD_WF8B_BPHLCD42_MASK (0x80U) +#define LCD_WF8B_BPHLCD42_SHIFT (7U) +#define LCD_WF8B_BPHLCD42(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD42_SHIFT)) & LCD_WF8B_BPHLCD42_MASK) +#define LCD_WF8B_BPHLCD41_MASK (0x80U) +#define LCD_WF8B_BPHLCD41_SHIFT (7U) +#define LCD_WF8B_BPHLCD41(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD41_SHIFT)) & LCD_WF8B_BPHLCD41_MASK) +#define LCD_WF8B_BPHLCD40_MASK (0x80U) +#define LCD_WF8B_BPHLCD40_SHIFT (7U) +#define LCD_WF8B_BPHLCD40(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD40_SHIFT)) & LCD_WF8B_BPHLCD40_MASK) +#define LCD_WF8B_BPHLCD39_MASK (0x80U) +#define LCD_WF8B_BPHLCD39_SHIFT (7U) +#define LCD_WF8B_BPHLCD39(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD39_SHIFT)) & LCD_WF8B_BPHLCD39_MASK) +#define LCD_WF8B_BPHLCD38_MASK (0x80U) +#define LCD_WF8B_BPHLCD38_SHIFT (7U) +#define LCD_WF8B_BPHLCD38(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD38_SHIFT)) & LCD_WF8B_BPHLCD38_MASK) +#define LCD_WF8B_BPHLCD37_MASK (0x80U) +#define LCD_WF8B_BPHLCD37_SHIFT (7U) +#define LCD_WF8B_BPHLCD37(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD37_SHIFT)) & LCD_WF8B_BPHLCD37_MASK) +#define LCD_WF8B_BPHLCD36_MASK (0x80U) +#define LCD_WF8B_BPHLCD36_SHIFT (7U) +#define LCD_WF8B_BPHLCD36(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD36_SHIFT)) & LCD_WF8B_BPHLCD36_MASK) +#define LCD_WF8B_BPHLCD3_MASK (0x80U) +#define LCD_WF8B_BPHLCD3_SHIFT (7U) +#define LCD_WF8B_BPHLCD3(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD3_SHIFT)) & LCD_WF8B_BPHLCD3_MASK) +#define LCD_WF8B_BPHLCD35_MASK (0x80U) +#define LCD_WF8B_BPHLCD35_SHIFT (7U) +#define LCD_WF8B_BPHLCD35(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD35_SHIFT)) & LCD_WF8B_BPHLCD35_MASK) +#define LCD_WF8B_BPHLCD34_MASK (0x80U) +#define LCD_WF8B_BPHLCD34_SHIFT (7U) +#define LCD_WF8B_BPHLCD34(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD34_SHIFT)) & LCD_WF8B_BPHLCD34_MASK) +#define LCD_WF8B_BPHLCD33_MASK (0x80U) +#define LCD_WF8B_BPHLCD33_SHIFT (7U) +#define LCD_WF8B_BPHLCD33(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD33_SHIFT)) & LCD_WF8B_BPHLCD33_MASK) +#define LCD_WF8B_BPHLCD32_MASK (0x80U) +#define LCD_WF8B_BPHLCD32_SHIFT (7U) +#define LCD_WF8B_BPHLCD32(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD32_SHIFT)) & LCD_WF8B_BPHLCD32_MASK) +#define LCD_WF8B_BPHLCD31_MASK (0x80U) +#define LCD_WF8B_BPHLCD31_SHIFT (7U) +#define LCD_WF8B_BPHLCD31(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD31_SHIFT)) & LCD_WF8B_BPHLCD31_MASK) +#define LCD_WF8B_BPHLCD30_MASK (0x80U) +#define LCD_WF8B_BPHLCD30_SHIFT (7U) +#define LCD_WF8B_BPHLCD30(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD30_SHIFT)) & LCD_WF8B_BPHLCD30_MASK) +#define LCD_WF8B_BPHLCD29_MASK (0x80U) +#define LCD_WF8B_BPHLCD29_SHIFT (7U) +#define LCD_WF8B_BPHLCD29(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD29_SHIFT)) & LCD_WF8B_BPHLCD29_MASK) +#define LCD_WF8B_BPHLCD4_MASK (0x80U) +#define LCD_WF8B_BPHLCD4_SHIFT (7U) +#define LCD_WF8B_BPHLCD4(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD4_SHIFT)) & LCD_WF8B_BPHLCD4_MASK) +#define LCD_WF8B_BPHLCD28_MASK (0x80U) +#define LCD_WF8B_BPHLCD28_SHIFT (7U) +#define LCD_WF8B_BPHLCD28(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD28_SHIFT)) & LCD_WF8B_BPHLCD28_MASK) +#define LCD_WF8B_BPHLCD27_MASK (0x80U) +#define LCD_WF8B_BPHLCD27_SHIFT (7U) +#define LCD_WF8B_BPHLCD27(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD27_SHIFT)) & LCD_WF8B_BPHLCD27_MASK) +#define LCD_WF8B_BPHLCD26_MASK (0x80U) +#define LCD_WF8B_BPHLCD26_SHIFT (7U) +#define LCD_WF8B_BPHLCD26(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD26_SHIFT)) & LCD_WF8B_BPHLCD26_MASK) +#define LCD_WF8B_BPHLCD25_MASK (0x80U) +#define LCD_WF8B_BPHLCD25_SHIFT (7U) +#define LCD_WF8B_BPHLCD25(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD25_SHIFT)) & LCD_WF8B_BPHLCD25_MASK) +#define LCD_WF8B_BPHLCD24_MASK (0x80U) +#define LCD_WF8B_BPHLCD24_SHIFT (7U) +#define LCD_WF8B_BPHLCD24(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD24_SHIFT)) & LCD_WF8B_BPHLCD24_MASK) +#define LCD_WF8B_BPHLCD23_MASK (0x80U) +#define LCD_WF8B_BPHLCD23_SHIFT (7U) +#define LCD_WF8B_BPHLCD23(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD23_SHIFT)) & LCD_WF8B_BPHLCD23_MASK) +#define LCD_WF8B_BPHLCD22_MASK (0x80U) +#define LCD_WF8B_BPHLCD22_SHIFT (7U) +#define LCD_WF8B_BPHLCD22(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD22_SHIFT)) & LCD_WF8B_BPHLCD22_MASK) +#define LCD_WF8B_BPHLCD5_MASK (0x80U) +#define LCD_WF8B_BPHLCD5_SHIFT (7U) +#define LCD_WF8B_BPHLCD5(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD5_SHIFT)) & LCD_WF8B_BPHLCD5_MASK) +#define LCD_WF8B_BPHLCD21_MASK (0x80U) +#define LCD_WF8B_BPHLCD21_SHIFT (7U) +#define LCD_WF8B_BPHLCD21(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD21_SHIFT)) & LCD_WF8B_BPHLCD21_MASK) +#define LCD_WF8B_BPHLCD20_MASK (0x80U) +#define LCD_WF8B_BPHLCD20_SHIFT (7U) +#define LCD_WF8B_BPHLCD20(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD20_SHIFT)) & LCD_WF8B_BPHLCD20_MASK) +#define LCD_WF8B_BPHLCD19_MASK (0x80U) +#define LCD_WF8B_BPHLCD19_SHIFT (7U) +#define LCD_WF8B_BPHLCD19(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD19_SHIFT)) & LCD_WF8B_BPHLCD19_MASK) +#define LCD_WF8B_BPHLCD18_MASK (0x80U) +#define LCD_WF8B_BPHLCD18_SHIFT (7U) +#define LCD_WF8B_BPHLCD18(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD18_SHIFT)) & LCD_WF8B_BPHLCD18_MASK) +#define LCD_WF8B_BPHLCD17_MASK (0x80U) +#define LCD_WF8B_BPHLCD17_SHIFT (7U) +#define LCD_WF8B_BPHLCD17(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD17_SHIFT)) & LCD_WF8B_BPHLCD17_MASK) +#define LCD_WF8B_BPHLCD16_MASK (0x80U) +#define LCD_WF8B_BPHLCD16_SHIFT (7U) +#define LCD_WF8B_BPHLCD16(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD16_SHIFT)) & LCD_WF8B_BPHLCD16_MASK) +#define LCD_WF8B_BPHLCD15_MASK (0x80U) +#define LCD_WF8B_BPHLCD15_SHIFT (7U) +#define LCD_WF8B_BPHLCD15(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD15_SHIFT)) & LCD_WF8B_BPHLCD15_MASK) +#define LCD_WF8B_BPHLCD6_MASK (0x80U) +#define LCD_WF8B_BPHLCD6_SHIFT (7U) +#define LCD_WF8B_BPHLCD6(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD6_SHIFT)) & LCD_WF8B_BPHLCD6_MASK) +#define LCD_WF8B_BPHLCD14_MASK (0x80U) +#define LCD_WF8B_BPHLCD14_SHIFT (7U) +#define LCD_WF8B_BPHLCD14(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD14_SHIFT)) & LCD_WF8B_BPHLCD14_MASK) +#define LCD_WF8B_BPHLCD13_MASK (0x80U) +#define LCD_WF8B_BPHLCD13_SHIFT (7U) +#define LCD_WF8B_BPHLCD13(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD13_SHIFT)) & LCD_WF8B_BPHLCD13_MASK) +#define LCD_WF8B_BPHLCD12_MASK (0x80U) +#define LCD_WF8B_BPHLCD12_SHIFT (7U) +#define LCD_WF8B_BPHLCD12(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD12_SHIFT)) & LCD_WF8B_BPHLCD12_MASK) +#define LCD_WF8B_BPHLCD11_MASK (0x80U) +#define LCD_WF8B_BPHLCD11_SHIFT (7U) +#define LCD_WF8B_BPHLCD11(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD11_SHIFT)) & LCD_WF8B_BPHLCD11_MASK) +#define LCD_WF8B_BPHLCD10_MASK (0x80U) +#define LCD_WF8B_BPHLCD10_SHIFT (7U) +#define LCD_WF8B_BPHLCD10(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD10_SHIFT)) & LCD_WF8B_BPHLCD10_MASK) +#define LCD_WF8B_BPHLCD9_MASK (0x80U) +#define LCD_WF8B_BPHLCD9_SHIFT (7U) +#define LCD_WF8B_BPHLCD9(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD9_SHIFT)) & LCD_WF8B_BPHLCD9_MASK) +#define LCD_WF8B_BPHLCD8_MASK (0x80U) +#define LCD_WF8B_BPHLCD8_SHIFT (7U) +#define LCD_WF8B_BPHLCD8(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD8_SHIFT)) & LCD_WF8B_BPHLCD8_MASK) +#define LCD_WF8B_BPHLCD7_MASK (0x80U) +#define LCD_WF8B_BPHLCD7_SHIFT (7U) +#define LCD_WF8B_BPHLCD7(x) (((uint8_t)(((uint8_t)(x)) << LCD_WF8B_BPHLCD7_SHIFT)) & LCD_WF8B_BPHLCD7_MASK) + +/* The count of LCD_WF8B */ +#define LCD_WF8B_COUNT (64U) + + +/*! + * @} + */ /* end of group LCD_Register_Masks */ + + +/* LCD - Peripheral instance base addresses */ +/** Peripheral LCD base address */ +#define LCD_BASE (0x40053000u) +/** Peripheral LCD base pointer */ +#define LCD ((LCD_Type *)LCD_BASE) +/** Array initializer of LCD peripheral base addresses */ +#define LCD_BASE_ADDRS { LCD_BASE } +/** Array initializer of LCD peripheral base pointers */ +#define LCD_BASE_PTRS { LCD } +/** Interrupt vectors for the LCD peripheral type */ +#define LCD_LCD_IRQS { LCD_IRQn } + +/*! + * @} + */ /* end of group LCD_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LLWU Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LLWU_Peripheral_Access_Layer LLWU Peripheral Access Layer + * @{ + */ + +/** LLWU - Register Layout Typedef */ +typedef struct { + __IO uint8_t PE1; /**< LLWU Pin Enable 1 register, offset: 0x0 */ + __IO uint8_t PE2; /**< LLWU Pin Enable 2 register, offset: 0x1 */ + __IO uint8_t PE3; /**< LLWU Pin Enable 3 register, offset: 0x2 */ + __IO uint8_t PE4; /**< LLWU Pin Enable 4 register, offset: 0x3 */ + __IO uint8_t ME; /**< LLWU Module Enable register, offset: 0x4 */ + __IO uint8_t F1; /**< LLWU Flag 1 register, offset: 0x5 */ + __IO uint8_t F2; /**< LLWU Flag 2 register, offset: 0x6 */ + __I uint8_t F3; /**< LLWU Flag 3 register, offset: 0x7 */ + __IO uint8_t FILT1; /**< LLWU Pin Filter 1 register, offset: 0x8 */ + __IO uint8_t FILT2; /**< LLWU Pin Filter 2 register, offset: 0x9 */ +} LLWU_Type; + +/* ---------------------------------------------------------------------------- + -- LLWU Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LLWU_Register_Masks LLWU Register Masks + * @{ + */ + +/*! @name PE1 - LLWU Pin Enable 1 register */ +#define LLWU_PE1_WUPE0_MASK (0x3U) +#define LLWU_PE1_WUPE0_SHIFT (0U) +#define LLWU_PE1_WUPE0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE0_SHIFT)) & LLWU_PE1_WUPE0_MASK) +#define LLWU_PE1_WUPE1_MASK (0xCU) +#define LLWU_PE1_WUPE1_SHIFT (2U) +#define LLWU_PE1_WUPE1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE1_SHIFT)) & LLWU_PE1_WUPE1_MASK) +#define LLWU_PE1_WUPE2_MASK (0x30U) +#define LLWU_PE1_WUPE2_SHIFT (4U) +#define LLWU_PE1_WUPE2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE2_SHIFT)) & LLWU_PE1_WUPE2_MASK) +#define LLWU_PE1_WUPE3_MASK (0xC0U) +#define LLWU_PE1_WUPE3_SHIFT (6U) +#define LLWU_PE1_WUPE3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE3_SHIFT)) & LLWU_PE1_WUPE3_MASK) + +/*! @name PE2 - LLWU Pin Enable 2 register */ +#define LLWU_PE2_WUPE4_MASK (0x3U) +#define LLWU_PE2_WUPE4_SHIFT (0U) +#define LLWU_PE2_WUPE4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE4_SHIFT)) & LLWU_PE2_WUPE4_MASK) +#define LLWU_PE2_WUPE5_MASK (0xCU) +#define LLWU_PE2_WUPE5_SHIFT (2U) +#define LLWU_PE2_WUPE5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE5_SHIFT)) & LLWU_PE2_WUPE5_MASK) +#define LLWU_PE2_WUPE6_MASK (0x30U) +#define LLWU_PE2_WUPE6_SHIFT (4U) +#define LLWU_PE2_WUPE6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE6_SHIFT)) & LLWU_PE2_WUPE6_MASK) +#define LLWU_PE2_WUPE7_MASK (0xC0U) +#define LLWU_PE2_WUPE7_SHIFT (6U) +#define LLWU_PE2_WUPE7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE7_SHIFT)) & LLWU_PE2_WUPE7_MASK) + +/*! @name PE3 - LLWU Pin Enable 3 register */ +#define LLWU_PE3_WUPE8_MASK (0x3U) +#define LLWU_PE3_WUPE8_SHIFT (0U) +#define LLWU_PE3_WUPE8(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE8_SHIFT)) & LLWU_PE3_WUPE8_MASK) +#define LLWU_PE3_WUPE9_MASK (0xCU) +#define LLWU_PE3_WUPE9_SHIFT (2U) +#define LLWU_PE3_WUPE9(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE9_SHIFT)) & LLWU_PE3_WUPE9_MASK) +#define LLWU_PE3_WUPE10_MASK (0x30U) +#define LLWU_PE3_WUPE10_SHIFT (4U) +#define LLWU_PE3_WUPE10(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE10_SHIFT)) & LLWU_PE3_WUPE10_MASK) +#define LLWU_PE3_WUPE11_MASK (0xC0U) +#define LLWU_PE3_WUPE11_SHIFT (6U) +#define LLWU_PE3_WUPE11(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE11_SHIFT)) & LLWU_PE3_WUPE11_MASK) + +/*! @name PE4 - LLWU Pin Enable 4 register */ +#define LLWU_PE4_WUPE12_MASK (0x3U) +#define LLWU_PE4_WUPE12_SHIFT (0U) +#define LLWU_PE4_WUPE12(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE12_SHIFT)) & LLWU_PE4_WUPE12_MASK) +#define LLWU_PE4_WUPE13_MASK (0xCU) +#define LLWU_PE4_WUPE13_SHIFT (2U) +#define LLWU_PE4_WUPE13(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE13_SHIFT)) & LLWU_PE4_WUPE13_MASK) +#define LLWU_PE4_WUPE14_MASK (0x30U) +#define LLWU_PE4_WUPE14_SHIFT (4U) +#define LLWU_PE4_WUPE14(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE14_SHIFT)) & LLWU_PE4_WUPE14_MASK) +#define LLWU_PE4_WUPE15_MASK (0xC0U) +#define LLWU_PE4_WUPE15_SHIFT (6U) +#define LLWU_PE4_WUPE15(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE15_SHIFT)) & LLWU_PE4_WUPE15_MASK) + +/*! @name ME - LLWU Module Enable register */ +#define LLWU_ME_WUME0_MASK (0x1U) +#define LLWU_ME_WUME0_SHIFT (0U) +#define LLWU_ME_WUME0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME0_SHIFT)) & LLWU_ME_WUME0_MASK) +#define LLWU_ME_WUME1_MASK (0x2U) +#define LLWU_ME_WUME1_SHIFT (1U) +#define LLWU_ME_WUME1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME1_SHIFT)) & LLWU_ME_WUME1_MASK) +#define LLWU_ME_WUME2_MASK (0x4U) +#define LLWU_ME_WUME2_SHIFT (2U) +#define LLWU_ME_WUME2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME2_SHIFT)) & LLWU_ME_WUME2_MASK) +#define LLWU_ME_WUME3_MASK (0x8U) +#define LLWU_ME_WUME3_SHIFT (3U) +#define LLWU_ME_WUME3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME3_SHIFT)) & LLWU_ME_WUME3_MASK) +#define LLWU_ME_WUME4_MASK (0x10U) +#define LLWU_ME_WUME4_SHIFT (4U) +#define LLWU_ME_WUME4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME4_SHIFT)) & LLWU_ME_WUME4_MASK) +#define LLWU_ME_WUME5_MASK (0x20U) +#define LLWU_ME_WUME5_SHIFT (5U) +#define LLWU_ME_WUME5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME5_SHIFT)) & LLWU_ME_WUME5_MASK) +#define LLWU_ME_WUME6_MASK (0x40U) +#define LLWU_ME_WUME6_SHIFT (6U) +#define LLWU_ME_WUME6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME6_SHIFT)) & LLWU_ME_WUME6_MASK) +#define LLWU_ME_WUME7_MASK (0x80U) +#define LLWU_ME_WUME7_SHIFT (7U) +#define LLWU_ME_WUME7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME7_SHIFT)) & LLWU_ME_WUME7_MASK) + +/*! @name F1 - LLWU Flag 1 register */ +#define LLWU_F1_WUF0_MASK (0x1U) +#define LLWU_F1_WUF0_SHIFT (0U) +#define LLWU_F1_WUF0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF0_SHIFT)) & LLWU_F1_WUF0_MASK) +#define LLWU_F1_WUF1_MASK (0x2U) +#define LLWU_F1_WUF1_SHIFT (1U) +#define LLWU_F1_WUF1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF1_SHIFT)) & LLWU_F1_WUF1_MASK) +#define LLWU_F1_WUF2_MASK (0x4U) +#define LLWU_F1_WUF2_SHIFT (2U) +#define LLWU_F1_WUF2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF2_SHIFT)) & LLWU_F1_WUF2_MASK) +#define LLWU_F1_WUF3_MASK (0x8U) +#define LLWU_F1_WUF3_SHIFT (3U) +#define LLWU_F1_WUF3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF3_SHIFT)) & LLWU_F1_WUF3_MASK) +#define LLWU_F1_WUF4_MASK (0x10U) +#define LLWU_F1_WUF4_SHIFT (4U) +#define LLWU_F1_WUF4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF4_SHIFT)) & LLWU_F1_WUF4_MASK) +#define LLWU_F1_WUF5_MASK (0x20U) +#define LLWU_F1_WUF5_SHIFT (5U) +#define LLWU_F1_WUF5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF5_SHIFT)) & LLWU_F1_WUF5_MASK) +#define LLWU_F1_WUF6_MASK (0x40U) +#define LLWU_F1_WUF6_SHIFT (6U) +#define LLWU_F1_WUF6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF6_SHIFT)) & LLWU_F1_WUF6_MASK) +#define LLWU_F1_WUF7_MASK (0x80U) +#define LLWU_F1_WUF7_SHIFT (7U) +#define LLWU_F1_WUF7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF7_SHIFT)) & LLWU_F1_WUF7_MASK) + +/*! @name F2 - LLWU Flag 2 register */ +#define LLWU_F2_WUF8_MASK (0x1U) +#define LLWU_F2_WUF8_SHIFT (0U) +#define LLWU_F2_WUF8(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF8_SHIFT)) & LLWU_F2_WUF8_MASK) +#define LLWU_F2_WUF9_MASK (0x2U) +#define LLWU_F2_WUF9_SHIFT (1U) +#define LLWU_F2_WUF9(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF9_SHIFT)) & LLWU_F2_WUF9_MASK) +#define LLWU_F2_WUF10_MASK (0x4U) +#define LLWU_F2_WUF10_SHIFT (2U) +#define LLWU_F2_WUF10(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF10_SHIFT)) & LLWU_F2_WUF10_MASK) +#define LLWU_F2_WUF11_MASK (0x8U) +#define LLWU_F2_WUF11_SHIFT (3U) +#define LLWU_F2_WUF11(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF11_SHIFT)) & LLWU_F2_WUF11_MASK) +#define LLWU_F2_WUF12_MASK (0x10U) +#define LLWU_F2_WUF12_SHIFT (4U) +#define LLWU_F2_WUF12(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF12_SHIFT)) & LLWU_F2_WUF12_MASK) +#define LLWU_F2_WUF13_MASK (0x20U) +#define LLWU_F2_WUF13_SHIFT (5U) +#define LLWU_F2_WUF13(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF13_SHIFT)) & LLWU_F2_WUF13_MASK) +#define LLWU_F2_WUF14_MASK (0x40U) +#define LLWU_F2_WUF14_SHIFT (6U) +#define LLWU_F2_WUF14(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF14_SHIFT)) & LLWU_F2_WUF14_MASK) +#define LLWU_F2_WUF15_MASK (0x80U) +#define LLWU_F2_WUF15_SHIFT (7U) +#define LLWU_F2_WUF15(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF15_SHIFT)) & LLWU_F2_WUF15_MASK) + +/*! @name F3 - LLWU Flag 3 register */ +#define LLWU_F3_MWUF0_MASK (0x1U) +#define LLWU_F3_MWUF0_SHIFT (0U) +#define LLWU_F3_MWUF0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF0_SHIFT)) & LLWU_F3_MWUF0_MASK) +#define LLWU_F3_MWUF1_MASK (0x2U) +#define LLWU_F3_MWUF1_SHIFT (1U) +#define LLWU_F3_MWUF1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF1_SHIFT)) & LLWU_F3_MWUF1_MASK) +#define LLWU_F3_MWUF2_MASK (0x4U) +#define LLWU_F3_MWUF2_SHIFT (2U) +#define LLWU_F3_MWUF2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF2_SHIFT)) & LLWU_F3_MWUF2_MASK) +#define LLWU_F3_MWUF3_MASK (0x8U) +#define LLWU_F3_MWUF3_SHIFT (3U) +#define LLWU_F3_MWUF3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF3_SHIFT)) & LLWU_F3_MWUF3_MASK) +#define LLWU_F3_MWUF4_MASK (0x10U) +#define LLWU_F3_MWUF4_SHIFT (4U) +#define LLWU_F3_MWUF4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF4_SHIFT)) & LLWU_F3_MWUF4_MASK) +#define LLWU_F3_MWUF5_MASK (0x20U) +#define LLWU_F3_MWUF5_SHIFT (5U) +#define LLWU_F3_MWUF5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF5_SHIFT)) & LLWU_F3_MWUF5_MASK) +#define LLWU_F3_MWUF6_MASK (0x40U) +#define LLWU_F3_MWUF6_SHIFT (6U) +#define LLWU_F3_MWUF6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF6_SHIFT)) & LLWU_F3_MWUF6_MASK) +#define LLWU_F3_MWUF7_MASK (0x80U) +#define LLWU_F3_MWUF7_SHIFT (7U) +#define LLWU_F3_MWUF7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF7_SHIFT)) & LLWU_F3_MWUF7_MASK) + +/*! @name FILT1 - LLWU Pin Filter 1 register */ +#define LLWU_FILT1_FILTSEL_MASK (0xFU) +#define LLWU_FILT1_FILTSEL_SHIFT (0U) +#define LLWU_FILT1_FILTSEL(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTSEL_SHIFT)) & LLWU_FILT1_FILTSEL_MASK) +#define LLWU_FILT1_FILTE_MASK (0x60U) +#define LLWU_FILT1_FILTE_SHIFT (5U) +#define LLWU_FILT1_FILTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTE_SHIFT)) & LLWU_FILT1_FILTE_MASK) +#define LLWU_FILT1_FILTF_MASK (0x80U) +#define LLWU_FILT1_FILTF_SHIFT (7U) +#define LLWU_FILT1_FILTF(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTF_SHIFT)) & LLWU_FILT1_FILTF_MASK) + +/*! @name FILT2 - LLWU Pin Filter 2 register */ +#define LLWU_FILT2_FILTSEL_MASK (0xFU) +#define LLWU_FILT2_FILTSEL_SHIFT (0U) +#define LLWU_FILT2_FILTSEL(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTSEL_SHIFT)) & LLWU_FILT2_FILTSEL_MASK) +#define LLWU_FILT2_FILTE_MASK (0x60U) +#define LLWU_FILT2_FILTE_SHIFT (5U) +#define LLWU_FILT2_FILTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTE_SHIFT)) & LLWU_FILT2_FILTE_MASK) +#define LLWU_FILT2_FILTF_MASK (0x80U) +#define LLWU_FILT2_FILTF_SHIFT (7U) +#define LLWU_FILT2_FILTF(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTF_SHIFT)) & LLWU_FILT2_FILTF_MASK) + + +/*! + * @} + */ /* end of group LLWU_Register_Masks */ + + +/* LLWU - Peripheral instance base addresses */ +/** Peripheral LLWU base address */ +#define LLWU_BASE (0x4007C000u) +/** Peripheral LLWU base pointer */ +#define LLWU ((LLWU_Type *)LLWU_BASE) +/** Array initializer of LLWU peripheral base addresses */ +#define LLWU_BASE_ADDRS { LLWU_BASE } +/** Array initializer of LLWU peripheral base pointers */ +#define LLWU_BASE_PTRS { LLWU } +/** Interrupt vectors for the LLWU peripheral type */ +#define LLWU_IRQS { LLWU_IRQn } + +/*! + * @} + */ /* end of group LLWU_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LPTMR Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPTMR_Peripheral_Access_Layer LPTMR Peripheral Access Layer + * @{ + */ + +/** LPTMR - Register Layout Typedef */ +typedef struct { + __IO uint32_t CSR; /**< Low Power Timer Control Status Register, offset: 0x0 */ + __IO uint32_t PSR; /**< Low Power Timer Prescale Register, offset: 0x4 */ + __IO uint32_t CMR; /**< Low Power Timer Compare Register, offset: 0x8 */ + __IO uint32_t CNR; /**< Low Power Timer Counter Register, offset: 0xC */ +} LPTMR_Type; + +/* ---------------------------------------------------------------------------- + -- LPTMR Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPTMR_Register_Masks LPTMR Register Masks + * @{ + */ + +/*! @name CSR - Low Power Timer Control Status Register */ +#define LPTMR_CSR_TEN_MASK (0x1U) +#define LPTMR_CSR_TEN_SHIFT (0U) +#define LPTMR_CSR_TEN(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TEN_SHIFT)) & LPTMR_CSR_TEN_MASK) +#define LPTMR_CSR_TMS_MASK (0x2U) +#define LPTMR_CSR_TMS_SHIFT (1U) +#define LPTMR_CSR_TMS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TMS_SHIFT)) & LPTMR_CSR_TMS_MASK) +#define LPTMR_CSR_TFC_MASK (0x4U) +#define LPTMR_CSR_TFC_SHIFT (2U) +#define LPTMR_CSR_TFC(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TFC_SHIFT)) & LPTMR_CSR_TFC_MASK) +#define LPTMR_CSR_TPP_MASK (0x8U) +#define LPTMR_CSR_TPP_SHIFT (3U) +#define LPTMR_CSR_TPP(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TPP_SHIFT)) & LPTMR_CSR_TPP_MASK) +#define LPTMR_CSR_TPS_MASK (0x30U) +#define LPTMR_CSR_TPS_SHIFT (4U) +#define LPTMR_CSR_TPS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TPS_SHIFT)) & LPTMR_CSR_TPS_MASK) +#define LPTMR_CSR_TIE_MASK (0x40U) +#define LPTMR_CSR_TIE_SHIFT (6U) +#define LPTMR_CSR_TIE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TIE_SHIFT)) & LPTMR_CSR_TIE_MASK) +#define LPTMR_CSR_TCF_MASK (0x80U) +#define LPTMR_CSR_TCF_SHIFT (7U) +#define LPTMR_CSR_TCF(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TCF_SHIFT)) & LPTMR_CSR_TCF_MASK) + +/*! @name PSR - Low Power Timer Prescale Register */ +#define LPTMR_PSR_PCS_MASK (0x3U) +#define LPTMR_PSR_PCS_SHIFT (0U) +#define LPTMR_PSR_PCS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PCS_SHIFT)) & LPTMR_PSR_PCS_MASK) +#define LPTMR_PSR_PBYP_MASK (0x4U) +#define LPTMR_PSR_PBYP_SHIFT (2U) +#define LPTMR_PSR_PBYP(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PBYP_SHIFT)) & LPTMR_PSR_PBYP_MASK) +#define LPTMR_PSR_PRESCALE_MASK (0x78U) +#define LPTMR_PSR_PRESCALE_SHIFT (3U) +#define LPTMR_PSR_PRESCALE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PRESCALE_SHIFT)) & LPTMR_PSR_PRESCALE_MASK) + +/*! @name CMR - Low Power Timer Compare Register */ +#define LPTMR_CMR_COMPARE_MASK (0xFFFFU) +#define LPTMR_CMR_COMPARE_SHIFT (0U) +#define LPTMR_CMR_COMPARE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CMR_COMPARE_SHIFT)) & LPTMR_CMR_COMPARE_MASK) + +/*! @name CNR - Low Power Timer Counter Register */ +#define LPTMR_CNR_COUNTER_MASK (0xFFFFU) +#define LPTMR_CNR_COUNTER_SHIFT (0U) +#define LPTMR_CNR_COUNTER(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CNR_COUNTER_SHIFT)) & LPTMR_CNR_COUNTER_MASK) + + +/*! + * @} + */ /* end of group LPTMR_Register_Masks */ + + +/* LPTMR - Peripheral instance base addresses */ +/** Peripheral LPTMR0 base address */ +#define LPTMR0_BASE (0x40040000u) +/** Peripheral LPTMR0 base pointer */ +#define LPTMR0 ((LPTMR_Type *)LPTMR0_BASE) +/** Array initializer of LPTMR peripheral base addresses */ +#define LPTMR_BASE_ADDRS { LPTMR0_BASE } +/** Array initializer of LPTMR peripheral base pointers */ +#define LPTMR_BASE_PTRS { LPTMR0 } +/** Interrupt vectors for the LPTMR peripheral type */ +#define LPTMR_IRQS { LPTMR0_IRQn } + +/*! + * @} + */ /* end of group LPTMR_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LPUART Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPUART_Peripheral_Access_Layer LPUART Peripheral Access Layer + * @{ + */ + +/** LPUART - Register Layout Typedef */ +typedef struct { + __IO uint32_t BAUD; /**< LPUART Baud Rate Register, offset: 0x0 */ + __IO uint32_t STAT; /**< LPUART Status Register, offset: 0x4 */ + __IO uint32_t CTRL; /**< LPUART Control Register, offset: 0x8 */ + __IO uint32_t DATA; /**< LPUART Data Register, offset: 0xC */ + __IO uint32_t MATCH; /**< LPUART Match Address Register, offset: 0x10 */ +} LPUART_Type; + +/* ---------------------------------------------------------------------------- + -- LPUART Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPUART_Register_Masks LPUART Register Masks + * @{ + */ + +/*! @name BAUD - LPUART Baud Rate Register */ +#define LPUART_BAUD_SBR_MASK (0x1FFFU) +#define LPUART_BAUD_SBR_SHIFT (0U) +#define LPUART_BAUD_SBR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_SBR_SHIFT)) & LPUART_BAUD_SBR_MASK) +#define LPUART_BAUD_SBNS_MASK (0x2000U) +#define LPUART_BAUD_SBNS_SHIFT (13U) +#define LPUART_BAUD_SBNS(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_SBNS_SHIFT)) & LPUART_BAUD_SBNS_MASK) +#define LPUART_BAUD_RXEDGIE_MASK (0x4000U) +#define LPUART_BAUD_RXEDGIE_SHIFT (14U) +#define LPUART_BAUD_RXEDGIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_RXEDGIE_SHIFT)) & LPUART_BAUD_RXEDGIE_MASK) +#define LPUART_BAUD_LBKDIE_MASK (0x8000U) +#define LPUART_BAUD_LBKDIE_SHIFT (15U) +#define LPUART_BAUD_LBKDIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_LBKDIE_SHIFT)) & LPUART_BAUD_LBKDIE_MASK) +#define LPUART_BAUD_RESYNCDIS_MASK (0x10000U) +#define LPUART_BAUD_RESYNCDIS_SHIFT (16U) +#define LPUART_BAUD_RESYNCDIS(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_RESYNCDIS_SHIFT)) & LPUART_BAUD_RESYNCDIS_MASK) +#define LPUART_BAUD_BOTHEDGE_MASK (0x20000U) +#define LPUART_BAUD_BOTHEDGE_SHIFT (17U) +#define LPUART_BAUD_BOTHEDGE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_BOTHEDGE_SHIFT)) & LPUART_BAUD_BOTHEDGE_MASK) +#define LPUART_BAUD_MATCFG_MASK (0xC0000U) +#define LPUART_BAUD_MATCFG_SHIFT (18U) +#define LPUART_BAUD_MATCFG(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_MATCFG_SHIFT)) & LPUART_BAUD_MATCFG_MASK) +#define LPUART_BAUD_RDMAE_MASK (0x200000U) +#define LPUART_BAUD_RDMAE_SHIFT (21U) +#define LPUART_BAUD_RDMAE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_RDMAE_SHIFT)) & LPUART_BAUD_RDMAE_MASK) +#define LPUART_BAUD_TDMAE_MASK (0x800000U) +#define LPUART_BAUD_TDMAE_SHIFT (23U) +#define LPUART_BAUD_TDMAE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_TDMAE_SHIFT)) & LPUART_BAUD_TDMAE_MASK) +#define LPUART_BAUD_OSR_MASK (0x1F000000U) +#define LPUART_BAUD_OSR_SHIFT (24U) +#define LPUART_BAUD_OSR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_OSR_SHIFT)) & LPUART_BAUD_OSR_MASK) +#define LPUART_BAUD_M10_MASK (0x20000000U) +#define LPUART_BAUD_M10_SHIFT (29U) +#define LPUART_BAUD_M10(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_M10_SHIFT)) & LPUART_BAUD_M10_MASK) +#define LPUART_BAUD_MAEN2_MASK (0x40000000U) +#define LPUART_BAUD_MAEN2_SHIFT (30U) +#define LPUART_BAUD_MAEN2(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_MAEN2_SHIFT)) & LPUART_BAUD_MAEN2_MASK) +#define LPUART_BAUD_MAEN1_MASK (0x80000000U) +#define LPUART_BAUD_MAEN1_SHIFT (31U) +#define LPUART_BAUD_MAEN1(x) (((uint32_t)(((uint32_t)(x)) << LPUART_BAUD_MAEN1_SHIFT)) & LPUART_BAUD_MAEN1_MASK) + +/*! @name STAT - LPUART Status Register */ +#define LPUART_STAT_MA2F_MASK (0x4000U) +#define LPUART_STAT_MA2F_SHIFT (14U) +#define LPUART_STAT_MA2F(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_MA2F_SHIFT)) & LPUART_STAT_MA2F_MASK) +#define LPUART_STAT_MA1F_MASK (0x8000U) +#define LPUART_STAT_MA1F_SHIFT (15U) +#define LPUART_STAT_MA1F(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_MA1F_SHIFT)) & LPUART_STAT_MA1F_MASK) +#define LPUART_STAT_PF_MASK (0x10000U) +#define LPUART_STAT_PF_SHIFT (16U) +#define LPUART_STAT_PF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_PF_SHIFT)) & LPUART_STAT_PF_MASK) +#define LPUART_STAT_FE_MASK (0x20000U) +#define LPUART_STAT_FE_SHIFT (17U) +#define LPUART_STAT_FE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_FE_SHIFT)) & LPUART_STAT_FE_MASK) +#define LPUART_STAT_NF_MASK (0x40000U) +#define LPUART_STAT_NF_SHIFT (18U) +#define LPUART_STAT_NF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_NF_SHIFT)) & LPUART_STAT_NF_MASK) +#define LPUART_STAT_OR_MASK (0x80000U) +#define LPUART_STAT_OR_SHIFT (19U) +#define LPUART_STAT_OR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_OR_SHIFT)) & LPUART_STAT_OR_MASK) +#define LPUART_STAT_IDLE_MASK (0x100000U) +#define LPUART_STAT_IDLE_SHIFT (20U) +#define LPUART_STAT_IDLE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_IDLE_SHIFT)) & LPUART_STAT_IDLE_MASK) +#define LPUART_STAT_RDRF_MASK (0x200000U) +#define LPUART_STAT_RDRF_SHIFT (21U) +#define LPUART_STAT_RDRF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RDRF_SHIFT)) & LPUART_STAT_RDRF_MASK) +#define LPUART_STAT_TC_MASK (0x400000U) +#define LPUART_STAT_TC_SHIFT (22U) +#define LPUART_STAT_TC(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_TC_SHIFT)) & LPUART_STAT_TC_MASK) +#define LPUART_STAT_TDRE_MASK (0x800000U) +#define LPUART_STAT_TDRE_SHIFT (23U) +#define LPUART_STAT_TDRE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_TDRE_SHIFT)) & LPUART_STAT_TDRE_MASK) +#define LPUART_STAT_RAF_MASK (0x1000000U) +#define LPUART_STAT_RAF_SHIFT (24U) +#define LPUART_STAT_RAF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RAF_SHIFT)) & LPUART_STAT_RAF_MASK) +#define LPUART_STAT_LBKDE_MASK (0x2000000U) +#define LPUART_STAT_LBKDE_SHIFT (25U) +#define LPUART_STAT_LBKDE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_LBKDE_SHIFT)) & LPUART_STAT_LBKDE_MASK) +#define LPUART_STAT_BRK13_MASK (0x4000000U) +#define LPUART_STAT_BRK13_SHIFT (26U) +#define LPUART_STAT_BRK13(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_BRK13_SHIFT)) & LPUART_STAT_BRK13_MASK) +#define LPUART_STAT_RWUID_MASK (0x8000000U) +#define LPUART_STAT_RWUID_SHIFT (27U) +#define LPUART_STAT_RWUID(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RWUID_SHIFT)) & LPUART_STAT_RWUID_MASK) +#define LPUART_STAT_RXINV_MASK (0x10000000U) +#define LPUART_STAT_RXINV_SHIFT (28U) +#define LPUART_STAT_RXINV(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RXINV_SHIFT)) & LPUART_STAT_RXINV_MASK) +#define LPUART_STAT_MSBF_MASK (0x20000000U) +#define LPUART_STAT_MSBF_SHIFT (29U) +#define LPUART_STAT_MSBF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_MSBF_SHIFT)) & LPUART_STAT_MSBF_MASK) +#define LPUART_STAT_RXEDGIF_MASK (0x40000000U) +#define LPUART_STAT_RXEDGIF_SHIFT (30U) +#define LPUART_STAT_RXEDGIF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_RXEDGIF_SHIFT)) & LPUART_STAT_RXEDGIF_MASK) +#define LPUART_STAT_LBKDIF_MASK (0x80000000U) +#define LPUART_STAT_LBKDIF_SHIFT (31U) +#define LPUART_STAT_LBKDIF(x) (((uint32_t)(((uint32_t)(x)) << LPUART_STAT_LBKDIF_SHIFT)) & LPUART_STAT_LBKDIF_MASK) + +/*! @name CTRL - LPUART Control Register */ +#define LPUART_CTRL_PT_MASK (0x1U) +#define LPUART_CTRL_PT_SHIFT (0U) +#define LPUART_CTRL_PT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_PT_SHIFT)) & LPUART_CTRL_PT_MASK) +#define LPUART_CTRL_PE_MASK (0x2U) +#define LPUART_CTRL_PE_SHIFT (1U) +#define LPUART_CTRL_PE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_PE_SHIFT)) & LPUART_CTRL_PE_MASK) +#define LPUART_CTRL_ILT_MASK (0x4U) +#define LPUART_CTRL_ILT_SHIFT (2U) +#define LPUART_CTRL_ILT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_ILT_SHIFT)) & LPUART_CTRL_ILT_MASK) +#define LPUART_CTRL_WAKE_MASK (0x8U) +#define LPUART_CTRL_WAKE_SHIFT (3U) +#define LPUART_CTRL_WAKE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_WAKE_SHIFT)) & LPUART_CTRL_WAKE_MASK) +#define LPUART_CTRL_M_MASK (0x10U) +#define LPUART_CTRL_M_SHIFT (4U) +#define LPUART_CTRL_M(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_M_SHIFT)) & LPUART_CTRL_M_MASK) +#define LPUART_CTRL_RSRC_MASK (0x20U) +#define LPUART_CTRL_RSRC_SHIFT (5U) +#define LPUART_CTRL_RSRC(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_RSRC_SHIFT)) & LPUART_CTRL_RSRC_MASK) +#define LPUART_CTRL_DOZEEN_MASK (0x40U) +#define LPUART_CTRL_DOZEEN_SHIFT (6U) +#define LPUART_CTRL_DOZEEN(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_DOZEEN_SHIFT)) & LPUART_CTRL_DOZEEN_MASK) +#define LPUART_CTRL_LOOPS_MASK (0x80U) +#define LPUART_CTRL_LOOPS_SHIFT (7U) +#define LPUART_CTRL_LOOPS(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_LOOPS_SHIFT)) & LPUART_CTRL_LOOPS_MASK) +#define LPUART_CTRL_IDLECFG_MASK (0x700U) +#define LPUART_CTRL_IDLECFG_SHIFT (8U) +#define LPUART_CTRL_IDLECFG(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_IDLECFG_SHIFT)) & LPUART_CTRL_IDLECFG_MASK) +#define LPUART_CTRL_MA2IE_MASK (0x4000U) +#define LPUART_CTRL_MA2IE_SHIFT (14U) +#define LPUART_CTRL_MA2IE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_MA2IE_SHIFT)) & LPUART_CTRL_MA2IE_MASK) +#define LPUART_CTRL_MA1IE_MASK (0x8000U) +#define LPUART_CTRL_MA1IE_SHIFT (15U) +#define LPUART_CTRL_MA1IE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_MA1IE_SHIFT)) & LPUART_CTRL_MA1IE_MASK) +#define LPUART_CTRL_SBK_MASK (0x10000U) +#define LPUART_CTRL_SBK_SHIFT (16U) +#define LPUART_CTRL_SBK(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_SBK_SHIFT)) & LPUART_CTRL_SBK_MASK) +#define LPUART_CTRL_RWU_MASK (0x20000U) +#define LPUART_CTRL_RWU_SHIFT (17U) +#define LPUART_CTRL_RWU(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_RWU_SHIFT)) & LPUART_CTRL_RWU_MASK) +#define LPUART_CTRL_RE_MASK (0x40000U) +#define LPUART_CTRL_RE_SHIFT (18U) +#define LPUART_CTRL_RE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_RE_SHIFT)) & LPUART_CTRL_RE_MASK) +#define LPUART_CTRL_TE_MASK (0x80000U) +#define LPUART_CTRL_TE_SHIFT (19U) +#define LPUART_CTRL_TE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TE_SHIFT)) & LPUART_CTRL_TE_MASK) +#define LPUART_CTRL_ILIE_MASK (0x100000U) +#define LPUART_CTRL_ILIE_SHIFT (20U) +#define LPUART_CTRL_ILIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_ILIE_SHIFT)) & LPUART_CTRL_ILIE_MASK) +#define LPUART_CTRL_RIE_MASK (0x200000U) +#define LPUART_CTRL_RIE_SHIFT (21U) +#define LPUART_CTRL_RIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_RIE_SHIFT)) & LPUART_CTRL_RIE_MASK) +#define LPUART_CTRL_TCIE_MASK (0x400000U) +#define LPUART_CTRL_TCIE_SHIFT (22U) +#define LPUART_CTRL_TCIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TCIE_SHIFT)) & LPUART_CTRL_TCIE_MASK) +#define LPUART_CTRL_TIE_MASK (0x800000U) +#define LPUART_CTRL_TIE_SHIFT (23U) +#define LPUART_CTRL_TIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TIE_SHIFT)) & LPUART_CTRL_TIE_MASK) +#define LPUART_CTRL_PEIE_MASK (0x1000000U) +#define LPUART_CTRL_PEIE_SHIFT (24U) +#define LPUART_CTRL_PEIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_PEIE_SHIFT)) & LPUART_CTRL_PEIE_MASK) +#define LPUART_CTRL_FEIE_MASK (0x2000000U) +#define LPUART_CTRL_FEIE_SHIFT (25U) +#define LPUART_CTRL_FEIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_FEIE_SHIFT)) & LPUART_CTRL_FEIE_MASK) +#define LPUART_CTRL_NEIE_MASK (0x4000000U) +#define LPUART_CTRL_NEIE_SHIFT (26U) +#define LPUART_CTRL_NEIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_NEIE_SHIFT)) & LPUART_CTRL_NEIE_MASK) +#define LPUART_CTRL_ORIE_MASK (0x8000000U) +#define LPUART_CTRL_ORIE_SHIFT (27U) +#define LPUART_CTRL_ORIE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_ORIE_SHIFT)) & LPUART_CTRL_ORIE_MASK) +#define LPUART_CTRL_TXINV_MASK (0x10000000U) +#define LPUART_CTRL_TXINV_SHIFT (28U) +#define LPUART_CTRL_TXINV(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TXINV_SHIFT)) & LPUART_CTRL_TXINV_MASK) +#define LPUART_CTRL_TXDIR_MASK (0x20000000U) +#define LPUART_CTRL_TXDIR_SHIFT (29U) +#define LPUART_CTRL_TXDIR(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_TXDIR_SHIFT)) & LPUART_CTRL_TXDIR_MASK) +#define LPUART_CTRL_R9T8_MASK (0x40000000U) +#define LPUART_CTRL_R9T8_SHIFT (30U) +#define LPUART_CTRL_R9T8(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_R9T8_SHIFT)) & LPUART_CTRL_R9T8_MASK) +#define LPUART_CTRL_R8T9_MASK (0x80000000U) +#define LPUART_CTRL_R8T9_SHIFT (31U) +#define LPUART_CTRL_R8T9(x) (((uint32_t)(((uint32_t)(x)) << LPUART_CTRL_R8T9_SHIFT)) & LPUART_CTRL_R8T9_MASK) + +/*! @name DATA - LPUART Data Register */ +#define LPUART_DATA_R0T0_MASK (0x1U) +#define LPUART_DATA_R0T0_SHIFT (0U) +#define LPUART_DATA_R0T0(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R0T0_SHIFT)) & LPUART_DATA_R0T0_MASK) +#define LPUART_DATA_R1T1_MASK (0x2U) +#define LPUART_DATA_R1T1_SHIFT (1U) +#define LPUART_DATA_R1T1(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R1T1_SHIFT)) & LPUART_DATA_R1T1_MASK) +#define LPUART_DATA_R2T2_MASK (0x4U) +#define LPUART_DATA_R2T2_SHIFT (2U) +#define LPUART_DATA_R2T2(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R2T2_SHIFT)) & LPUART_DATA_R2T2_MASK) +#define LPUART_DATA_R3T3_MASK (0x8U) +#define LPUART_DATA_R3T3_SHIFT (3U) +#define LPUART_DATA_R3T3(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R3T3_SHIFT)) & LPUART_DATA_R3T3_MASK) +#define LPUART_DATA_R4T4_MASK (0x10U) +#define LPUART_DATA_R4T4_SHIFT (4U) +#define LPUART_DATA_R4T4(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R4T4_SHIFT)) & LPUART_DATA_R4T4_MASK) +#define LPUART_DATA_R5T5_MASK (0x20U) +#define LPUART_DATA_R5T5_SHIFT (5U) +#define LPUART_DATA_R5T5(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R5T5_SHIFT)) & LPUART_DATA_R5T5_MASK) +#define LPUART_DATA_R6T6_MASK (0x40U) +#define LPUART_DATA_R6T6_SHIFT (6U) +#define LPUART_DATA_R6T6(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R6T6_SHIFT)) & LPUART_DATA_R6T6_MASK) +#define LPUART_DATA_R7T7_MASK (0x80U) +#define LPUART_DATA_R7T7_SHIFT (7U) +#define LPUART_DATA_R7T7(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R7T7_SHIFT)) & LPUART_DATA_R7T7_MASK) +#define LPUART_DATA_R8T8_MASK (0x100U) +#define LPUART_DATA_R8T8_SHIFT (8U) +#define LPUART_DATA_R8T8(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R8T8_SHIFT)) & LPUART_DATA_R8T8_MASK) +#define LPUART_DATA_R9T9_MASK (0x200U) +#define LPUART_DATA_R9T9_SHIFT (9U) +#define LPUART_DATA_R9T9(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_R9T9_SHIFT)) & LPUART_DATA_R9T9_MASK) +#define LPUART_DATA_IDLINE_MASK (0x800U) +#define LPUART_DATA_IDLINE_SHIFT (11U) +#define LPUART_DATA_IDLINE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_IDLINE_SHIFT)) & LPUART_DATA_IDLINE_MASK) +#define LPUART_DATA_RXEMPT_MASK (0x1000U) +#define LPUART_DATA_RXEMPT_SHIFT (12U) +#define LPUART_DATA_RXEMPT(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_RXEMPT_SHIFT)) & LPUART_DATA_RXEMPT_MASK) +#define LPUART_DATA_FRETSC_MASK (0x2000U) +#define LPUART_DATA_FRETSC_SHIFT (13U) +#define LPUART_DATA_FRETSC(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_FRETSC_SHIFT)) & LPUART_DATA_FRETSC_MASK) +#define LPUART_DATA_PARITYE_MASK (0x4000U) +#define LPUART_DATA_PARITYE_SHIFT (14U) +#define LPUART_DATA_PARITYE(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_PARITYE_SHIFT)) & LPUART_DATA_PARITYE_MASK) +#define LPUART_DATA_NOISY_MASK (0x8000U) +#define LPUART_DATA_NOISY_SHIFT (15U) +#define LPUART_DATA_NOISY(x) (((uint32_t)(((uint32_t)(x)) << LPUART_DATA_NOISY_SHIFT)) & LPUART_DATA_NOISY_MASK) + +/*! @name MATCH - LPUART Match Address Register */ +#define LPUART_MATCH_MA1_MASK (0x3FFU) +#define LPUART_MATCH_MA1_SHIFT (0U) +#define LPUART_MATCH_MA1(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MATCH_MA1_SHIFT)) & LPUART_MATCH_MA1_MASK) +#define LPUART_MATCH_MA2_MASK (0x3FF0000U) +#define LPUART_MATCH_MA2_SHIFT (16U) +#define LPUART_MATCH_MA2(x) (((uint32_t)(((uint32_t)(x)) << LPUART_MATCH_MA2_SHIFT)) & LPUART_MATCH_MA2_MASK) + + +/*! + * @} + */ /* end of group LPUART_Register_Masks */ + + +/* LPUART - Peripheral instance base addresses */ +/** Peripheral LPUART0 base address */ +#define LPUART0_BASE (0x40054000u) +/** Peripheral LPUART0 base pointer */ +#define LPUART0 ((LPUART_Type *)LPUART0_BASE) +/** Peripheral LPUART1 base address */ +#define LPUART1_BASE (0x40055000u) +/** Peripheral LPUART1 base pointer */ +#define LPUART1 ((LPUART_Type *)LPUART1_BASE) +/** Array initializer of LPUART peripheral base addresses */ +#define LPUART_BASE_ADDRS { LPUART0_BASE, LPUART1_BASE } +/** Array initializer of LPUART peripheral base pointers */ +#define LPUART_BASE_PTRS { LPUART0, LPUART1 } +/** Interrupt vectors for the LPUART peripheral type */ +#define LPUART_RX_TX_IRQS { LPUART0_IRQn, LPUART1_IRQn } +#define LPUART_ERR_IRQS { LPUART0_IRQn, LPUART1_IRQn } + +/*! + * @} + */ /* end of group LPUART_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MCG Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCG_Peripheral_Access_Layer MCG Peripheral Access Layer + * @{ + */ + +/** MCG - Register Layout Typedef */ +typedef struct { + __IO uint8_t C1; /**< MCG Control Register 1, offset: 0x0 */ + __IO uint8_t C2; /**< MCG Control Register 2, offset: 0x1 */ + uint8_t RESERVED_0[4]; + __I uint8_t S; /**< MCG Status Register, offset: 0x6 */ + uint8_t RESERVED_1[1]; + __IO uint8_t SC; /**< MCG Status and Control Register, offset: 0x8 */ + uint8_t RESERVED_2[11]; + __I uint8_t HCTRIM; /**< MCG High-frequency IRC Coarse Trim Register, offset: 0x14 */ + __I uint8_t HTTRIM; /**< MCG High-frequency IRC Tempco (Temperature Coefficient) Trim Register, offset: 0x15 */ + __I uint8_t HFTRIM; /**< MCG High-frequency IRC Fine Trim Register, offset: 0x16 */ + uint8_t RESERVED_3[1]; + __IO uint8_t MC; /**< MCG Miscellaneous Control Register, offset: 0x18 */ + __I uint8_t LTRIMRNG; /**< MCG Low-frequency IRC Trim Range Register, offset: 0x19 */ + __I uint8_t LFTRIM; /**< MCG Low-frequency IRC8M Trim Register, offset: 0x1A */ + __I uint8_t LSTRIM; /**< MCG Low-frequency IRC2M Trim Register, offset: 0x1B */ +} MCG_Type; + +/* ---------------------------------------------------------------------------- + -- MCG Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCG_Register_Masks MCG Register Masks + * @{ + */ + +/*! @name C1 - MCG Control Register 1 */ +#define MCG_C1_IREFSTEN_MASK (0x1U) +#define MCG_C1_IREFSTEN_SHIFT (0U) +#define MCG_C1_IREFSTEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_IREFSTEN_SHIFT)) & MCG_C1_IREFSTEN_MASK) +#define MCG_C1_IRCLKEN_MASK (0x2U) +#define MCG_C1_IRCLKEN_SHIFT (1U) +#define MCG_C1_IRCLKEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_IRCLKEN_SHIFT)) & MCG_C1_IRCLKEN_MASK) +#define MCG_C1_CLKS_MASK (0xC0U) +#define MCG_C1_CLKS_SHIFT (6U) +#define MCG_C1_CLKS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_CLKS_SHIFT)) & MCG_C1_CLKS_MASK) + +/*! @name C2 - MCG Control Register 2 */ +#define MCG_C2_IRCS_MASK (0x1U) +#define MCG_C2_IRCS_SHIFT (0U) +#define MCG_C2_IRCS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_IRCS_SHIFT)) & MCG_C2_IRCS_MASK) +#define MCG_C2_EREFS0_MASK (0x4U) +#define MCG_C2_EREFS0_SHIFT (2U) +#define MCG_C2_EREFS0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_EREFS0_SHIFT)) & MCG_C2_EREFS0_MASK) +#define MCG_C2_HGO0_MASK (0x8U) +#define MCG_C2_HGO0_SHIFT (3U) +#define MCG_C2_HGO0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_HGO0_SHIFT)) & MCG_C2_HGO0_MASK) +#define MCG_C2_RANGE0_MASK (0x30U) +#define MCG_C2_RANGE0_SHIFT (4U) +#define MCG_C2_RANGE0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_RANGE0_SHIFT)) & MCG_C2_RANGE0_MASK) + +/*! @name S - MCG Status Register */ +#define MCG_S_OSCINIT0_MASK (0x2U) +#define MCG_S_OSCINIT0_SHIFT (1U) +#define MCG_S_OSCINIT0(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_OSCINIT0_SHIFT)) & MCG_S_OSCINIT0_MASK) +#define MCG_S_CLKST_MASK (0xCU) +#define MCG_S_CLKST_SHIFT (2U) +#define MCG_S_CLKST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_CLKST_SHIFT)) & MCG_S_CLKST_MASK) + +/*! @name SC - MCG Status and Control Register */ +#define MCG_SC_FCRDIV_MASK (0xEU) +#define MCG_SC_FCRDIV_SHIFT (1U) +#define MCG_SC_FCRDIV(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_FCRDIV_SHIFT)) & MCG_SC_FCRDIV_MASK) + +/*! @name HCTRIM - MCG High-frequency IRC Coarse Trim Register */ +#define MCG_HCTRIM_COARSE_TRIM_MASK (0x3FU) +#define MCG_HCTRIM_COARSE_TRIM_SHIFT (0U) +#define MCG_HCTRIM_COARSE_TRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_HCTRIM_COARSE_TRIM_SHIFT)) & MCG_HCTRIM_COARSE_TRIM_MASK) + +/*! @name HTTRIM - MCG High-frequency IRC Tempco (Temperature Coefficient) Trim Register */ +#define MCG_HTTRIM_TEMPCO_TRIM_MASK (0x1FU) +#define MCG_HTTRIM_TEMPCO_TRIM_SHIFT (0U) +#define MCG_HTTRIM_TEMPCO_TRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_HTTRIM_TEMPCO_TRIM_SHIFT)) & MCG_HTTRIM_TEMPCO_TRIM_MASK) + +/*! @name HFTRIM - MCG High-frequency IRC Fine Trim Register */ +#define MCG_HFTRIM_FINE_TRIM_MASK (0x7FU) +#define MCG_HFTRIM_FINE_TRIM_SHIFT (0U) +#define MCG_HFTRIM_FINE_TRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_HFTRIM_FINE_TRIM_SHIFT)) & MCG_HFTRIM_FINE_TRIM_MASK) + +/*! @name MC - MCG Miscellaneous Control Register */ +#define MCG_MC_LIRC_DIV2_MASK (0x7U) +#define MCG_MC_LIRC_DIV2_SHIFT (0U) +#define MCG_MC_LIRC_DIV2(x) (((uint8_t)(((uint8_t)(x)) << MCG_MC_LIRC_DIV2_SHIFT)) & MCG_MC_LIRC_DIV2_MASK) +#define MCG_MC_HIRCEN_MASK (0x80U) +#define MCG_MC_HIRCEN_SHIFT (7U) +#define MCG_MC_HIRCEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_MC_HIRCEN_SHIFT)) & MCG_MC_HIRCEN_MASK) + +/*! @name LTRIMRNG - MCG Low-frequency IRC Trim Range Register */ +#define MCG_LTRIMRNG_STRIMRNG_MASK (0x3U) +#define MCG_LTRIMRNG_STRIMRNG_SHIFT (0U) +#define MCG_LTRIMRNG_STRIMRNG(x) (((uint8_t)(((uint8_t)(x)) << MCG_LTRIMRNG_STRIMRNG_SHIFT)) & MCG_LTRIMRNG_STRIMRNG_MASK) +#define MCG_LTRIMRNG_FTRIMRNG_MASK (0xCU) +#define MCG_LTRIMRNG_FTRIMRNG_SHIFT (2U) +#define MCG_LTRIMRNG_FTRIMRNG(x) (((uint8_t)(((uint8_t)(x)) << MCG_LTRIMRNG_FTRIMRNG_SHIFT)) & MCG_LTRIMRNG_FTRIMRNG_MASK) + +/*! @name LFTRIM - MCG Low-frequency IRC8M Trim Register */ +#define MCG_LFTRIM_LIRC_FTRIM_MASK (0x7FU) +#define MCG_LFTRIM_LIRC_FTRIM_SHIFT (0U) +#define MCG_LFTRIM_LIRC_FTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_LFTRIM_LIRC_FTRIM_SHIFT)) & MCG_LFTRIM_LIRC_FTRIM_MASK) + +/*! @name LSTRIM - MCG Low-frequency IRC2M Trim Register */ +#define MCG_LSTRIM_LIRC_STRIM_MASK (0x7FU) +#define MCG_LSTRIM_LIRC_STRIM_SHIFT (0U) +#define MCG_LSTRIM_LIRC_STRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_LSTRIM_LIRC_STRIM_SHIFT)) & MCG_LSTRIM_LIRC_STRIM_MASK) + + +/*! + * @} + */ /* end of group MCG_Register_Masks */ + + +/* MCG - Peripheral instance base addresses */ +/** Peripheral MCG base address */ +#define MCG_BASE (0x40064000u) +/** Peripheral MCG base pointer */ +#define MCG ((MCG_Type *)MCG_BASE) +/** Array initializer of MCG peripheral base addresses */ +#define MCG_BASE_ADDRS { MCG_BASE } +/** Array initializer of MCG peripheral base pointers */ +#define MCG_BASE_PTRS { MCG } + +/*! + * @} + */ /* end of group MCG_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MCM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCM_Peripheral_Access_Layer MCM Peripheral Access Layer + * @{ + */ + +/** MCM - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[8]; + __I uint16_t PLASC; /**< Crossbar Switch (AXBS) Slave Configuration, offset: 0x8 */ + __I uint16_t PLAMC; /**< Crossbar Switch (AXBS) Master Configuration, offset: 0xA */ + __IO uint32_t PLACR; /**< Platform Control Register, offset: 0xC */ + uint8_t RESERVED_1[48]; + __IO uint32_t CPO; /**< Compute Operation Control Register, offset: 0x40 */ +} MCM_Type; + +/* ---------------------------------------------------------------------------- + -- MCM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCM_Register_Masks MCM Register Masks + * @{ + */ + +/*! @name PLASC - Crossbar Switch (AXBS) Slave Configuration */ +#define MCM_PLASC_ASC_MASK (0xFFU) +#define MCM_PLASC_ASC_SHIFT (0U) +#define MCM_PLASC_ASC(x) (((uint16_t)(((uint16_t)(x)) << MCM_PLASC_ASC_SHIFT)) & MCM_PLASC_ASC_MASK) + +/*! @name PLAMC - Crossbar Switch (AXBS) Master Configuration */ +#define MCM_PLAMC_AMC_MASK (0xFFU) +#define MCM_PLAMC_AMC_SHIFT (0U) +#define MCM_PLAMC_AMC(x) (((uint16_t)(((uint16_t)(x)) << MCM_PLAMC_AMC_SHIFT)) & MCM_PLAMC_AMC_MASK) + +/*! @name PLACR - Platform Control Register */ +#define MCM_PLACR_ARB_MASK (0x200U) +#define MCM_PLACR_ARB_SHIFT (9U) +#define MCM_PLACR_ARB(x) (((uint32_t)(((uint32_t)(x)) << MCM_PLACR_ARB_SHIFT)) & MCM_PLACR_ARB_MASK) +#define MCM_PLACR_CFCC_MASK (0x400U) +#define MCM_PLACR_CFCC_SHIFT (10U) +#define MCM_PLACR_CFCC(x) (((uint32_t)(((uint32_t)(x)) << MCM_PLACR_CFCC_SHIFT)) & MCM_PLACR_CFCC_MASK) +#define MCM_PLACR_DFCDA_MASK (0x800U) +#define MCM_PLACR_DFCDA_SHIFT (11U) +#define MCM_PLACR_DFCDA(x) (((uint32_t)(((uint32_t)(x)) << MCM_PLACR_DFCDA_SHIFT)) & MCM_PLACR_DFCDA_MASK) +#define MCM_PLACR_DFCIC_MASK (0x1000U) +#define MCM_PLACR_DFCIC_SHIFT (12U) +#define MCM_PLACR_DFCIC(x) (((uint32_t)(((uint32_t)(x)) << MCM_PLACR_DFCIC_SHIFT)) & MCM_PLACR_DFCIC_MASK) +#define MCM_PLACR_DFCC_MASK (0x2000U) +#define MCM_PLACR_DFCC_SHIFT (13U) +#define MCM_PLACR_DFCC(x) (((uint32_t)(((uint32_t)(x)) << MCM_PLACR_DFCC_SHIFT)) & MCM_PLACR_DFCC_MASK) +#define MCM_PLACR_EFDS_MASK (0x4000U) +#define MCM_PLACR_EFDS_SHIFT (14U) +#define MCM_PLACR_EFDS(x) (((uint32_t)(((uint32_t)(x)) << MCM_PLACR_EFDS_SHIFT)) & MCM_PLACR_EFDS_MASK) +#define MCM_PLACR_DFCS_MASK (0x8000U) +#define MCM_PLACR_DFCS_SHIFT (15U) +#define MCM_PLACR_DFCS(x) (((uint32_t)(((uint32_t)(x)) << MCM_PLACR_DFCS_SHIFT)) & MCM_PLACR_DFCS_MASK) +#define MCM_PLACR_ESFC_MASK (0x10000U) +#define MCM_PLACR_ESFC_SHIFT (16U) +#define MCM_PLACR_ESFC(x) (((uint32_t)(((uint32_t)(x)) << MCM_PLACR_ESFC_SHIFT)) & MCM_PLACR_ESFC_MASK) + +/*! @name CPO - Compute Operation Control Register */ +#define MCM_CPO_CPOREQ_MASK (0x1U) +#define MCM_CPO_CPOREQ_SHIFT (0U) +#define MCM_CPO_CPOREQ(x) (((uint32_t)(((uint32_t)(x)) << MCM_CPO_CPOREQ_SHIFT)) & MCM_CPO_CPOREQ_MASK) +#define MCM_CPO_CPOACK_MASK (0x2U) +#define MCM_CPO_CPOACK_SHIFT (1U) +#define MCM_CPO_CPOACK(x) (((uint32_t)(((uint32_t)(x)) << MCM_CPO_CPOACK_SHIFT)) & MCM_CPO_CPOACK_MASK) +#define MCM_CPO_CPOWOI_MASK (0x4U) +#define MCM_CPO_CPOWOI_SHIFT (2U) +#define MCM_CPO_CPOWOI(x) (((uint32_t)(((uint32_t)(x)) << MCM_CPO_CPOWOI_SHIFT)) & MCM_CPO_CPOWOI_MASK) + + +/*! + * @} + */ /* end of group MCM_Register_Masks */ + + +/* MCM - Peripheral instance base addresses */ +/** Peripheral MCM base address */ +#define MCM_BASE (0xF0003000u) +/** Peripheral MCM base pointer */ +#define MCM ((MCM_Type *)MCM_BASE) +/** Array initializer of MCM peripheral base addresses */ +#define MCM_BASE_ADDRS { MCM_BASE } +/** Array initializer of MCM peripheral base pointers */ +#define MCM_BASE_PTRS { MCM } + +/*! + * @} + */ /* end of group MCM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MTB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MTB_Peripheral_Access_Layer MTB Peripheral Access Layer + * @{ + */ + +/** MTB - Register Layout Typedef */ +typedef struct { + __IO uint32_t POSITION; /**< MTB Position Register, offset: 0x0 */ + __IO uint32_t MASTER; /**< MTB Master Register, offset: 0x4 */ + __IO uint32_t FLOW; /**< MTB Flow Register, offset: 0x8 */ + __I uint32_t BASE; /**< MTB Base Register, offset: 0xC */ + uint8_t RESERVED_0[3824]; + __I uint32_t MODECTRL; /**< Integration Mode Control Register, offset: 0xF00 */ + uint8_t RESERVED_1[156]; + __I uint32_t TAGSET; /**< Claim TAG Set Register, offset: 0xFA0 */ + __I uint32_t TAGCLEAR; /**< Claim TAG Clear Register, offset: 0xFA4 */ + uint8_t RESERVED_2[8]; + __I uint32_t LOCKACCESS; /**< Lock Access Register, offset: 0xFB0 */ + __I uint32_t LOCKSTAT; /**< Lock Status Register, offset: 0xFB4 */ + __I uint32_t AUTHSTAT; /**< Authentication Status Register, offset: 0xFB8 */ + __I uint32_t DEVICEARCH; /**< Device Architecture Register, offset: 0xFBC */ + uint8_t RESERVED_3[8]; + __I uint32_t DEVICECFG; /**< Device Configuration Register, offset: 0xFC8 */ + __I uint32_t DEVICETYPID; /**< Device Type Identifier Register, offset: 0xFCC */ + __I uint32_t PERIPHID[8]; /**< Peripheral ID Register, array offset: 0xFD0, array step: 0x4 */ + __I uint32_t COMPID[4]; /**< Component ID Register, array offset: 0xFF0, array step: 0x4 */ +} MTB_Type; + +/* ---------------------------------------------------------------------------- + -- MTB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MTB_Register_Masks MTB Register Masks + * @{ + */ + +/*! @name POSITION - MTB Position Register */ +#define MTB_POSITION_WRAP_MASK (0x4U) +#define MTB_POSITION_WRAP_SHIFT (2U) +#define MTB_POSITION_WRAP(x) (((uint32_t)(((uint32_t)(x)) << MTB_POSITION_WRAP_SHIFT)) & MTB_POSITION_WRAP_MASK) +#define MTB_POSITION_POINTER_MASK (0xFFFFFFF8U) +#define MTB_POSITION_POINTER_SHIFT (3U) +#define MTB_POSITION_POINTER(x) (((uint32_t)(((uint32_t)(x)) << MTB_POSITION_POINTER_SHIFT)) & MTB_POSITION_POINTER_MASK) + +/*! @name MASTER - MTB Master Register */ +#define MTB_MASTER_MASK_MASK (0x1FU) +#define MTB_MASTER_MASK_SHIFT (0U) +#define MTB_MASTER_MASK(x) (((uint32_t)(((uint32_t)(x)) << MTB_MASTER_MASK_SHIFT)) & MTB_MASTER_MASK_MASK) +#define MTB_MASTER_TSTARTEN_MASK (0x20U) +#define MTB_MASTER_TSTARTEN_SHIFT (5U) +#define MTB_MASTER_TSTARTEN(x) (((uint32_t)(((uint32_t)(x)) << MTB_MASTER_TSTARTEN_SHIFT)) & MTB_MASTER_TSTARTEN_MASK) +#define MTB_MASTER_TSTOPEN_MASK (0x40U) +#define MTB_MASTER_TSTOPEN_SHIFT (6U) +#define MTB_MASTER_TSTOPEN(x) (((uint32_t)(((uint32_t)(x)) << MTB_MASTER_TSTOPEN_SHIFT)) & MTB_MASTER_TSTOPEN_MASK) +#define MTB_MASTER_SFRWPRIV_MASK (0x80U) +#define MTB_MASTER_SFRWPRIV_SHIFT (7U) +#define MTB_MASTER_SFRWPRIV(x) (((uint32_t)(((uint32_t)(x)) << MTB_MASTER_SFRWPRIV_SHIFT)) & MTB_MASTER_SFRWPRIV_MASK) +#define MTB_MASTER_RAMPRIV_MASK (0x100U) +#define MTB_MASTER_RAMPRIV_SHIFT (8U) +#define MTB_MASTER_RAMPRIV(x) (((uint32_t)(((uint32_t)(x)) << MTB_MASTER_RAMPRIV_SHIFT)) & MTB_MASTER_RAMPRIV_MASK) +#define MTB_MASTER_HALTREQ_MASK (0x200U) +#define MTB_MASTER_HALTREQ_SHIFT (9U) +#define MTB_MASTER_HALTREQ(x) (((uint32_t)(((uint32_t)(x)) << MTB_MASTER_HALTREQ_SHIFT)) & MTB_MASTER_HALTREQ_MASK) +#define MTB_MASTER_EN_MASK (0x80000000U) +#define MTB_MASTER_EN_SHIFT (31U) +#define MTB_MASTER_EN(x) (((uint32_t)(((uint32_t)(x)) << MTB_MASTER_EN_SHIFT)) & MTB_MASTER_EN_MASK) + +/*! @name FLOW - MTB Flow Register */ +#define MTB_FLOW_AUTOSTOP_MASK (0x1U) +#define MTB_FLOW_AUTOSTOP_SHIFT (0U) +#define MTB_FLOW_AUTOSTOP(x) (((uint32_t)(((uint32_t)(x)) << MTB_FLOW_AUTOSTOP_SHIFT)) & MTB_FLOW_AUTOSTOP_MASK) +#define MTB_FLOW_AUTOHALT_MASK (0x2U) +#define MTB_FLOW_AUTOHALT_SHIFT (1U) +#define MTB_FLOW_AUTOHALT(x) (((uint32_t)(((uint32_t)(x)) << MTB_FLOW_AUTOHALT_SHIFT)) & MTB_FLOW_AUTOHALT_MASK) +#define MTB_FLOW_WATERMARK_MASK (0xFFFFFFF8U) +#define MTB_FLOW_WATERMARK_SHIFT (3U) +#define MTB_FLOW_WATERMARK(x) (((uint32_t)(((uint32_t)(x)) << MTB_FLOW_WATERMARK_SHIFT)) & MTB_FLOW_WATERMARK_MASK) + +/*! @name BASE - MTB Base Register */ +#define MTB_BASE_BASEADDR_MASK (0xFFFFFFFFU) +#define MTB_BASE_BASEADDR_SHIFT (0U) +#define MTB_BASE_BASEADDR(x) (((uint32_t)(((uint32_t)(x)) << MTB_BASE_BASEADDR_SHIFT)) & MTB_BASE_BASEADDR_MASK) + +/*! @name MODECTRL - Integration Mode Control Register */ +#define MTB_MODECTRL_MODECTRL_MASK (0xFFFFFFFFU) +#define MTB_MODECTRL_MODECTRL_SHIFT (0U) +#define MTB_MODECTRL_MODECTRL(x) (((uint32_t)(((uint32_t)(x)) << MTB_MODECTRL_MODECTRL_SHIFT)) & MTB_MODECTRL_MODECTRL_MASK) + +/*! @name TAGSET - Claim TAG Set Register */ +#define MTB_TAGSET_TAGSET_MASK (0xFFFFFFFFU) +#define MTB_TAGSET_TAGSET_SHIFT (0U) +#define MTB_TAGSET_TAGSET(x) (((uint32_t)(((uint32_t)(x)) << MTB_TAGSET_TAGSET_SHIFT)) & MTB_TAGSET_TAGSET_MASK) + +/*! @name TAGCLEAR - Claim TAG Clear Register */ +#define MTB_TAGCLEAR_TAGCLEAR_MASK (0xFFFFFFFFU) +#define MTB_TAGCLEAR_TAGCLEAR_SHIFT (0U) +#define MTB_TAGCLEAR_TAGCLEAR(x) (((uint32_t)(((uint32_t)(x)) << MTB_TAGCLEAR_TAGCLEAR_SHIFT)) & MTB_TAGCLEAR_TAGCLEAR_MASK) + +/*! @name LOCKACCESS - Lock Access Register */ +#define MTB_LOCKACCESS_LOCKACCESS_MASK (0xFFFFFFFFU) +#define MTB_LOCKACCESS_LOCKACCESS_SHIFT (0U) +#define MTB_LOCKACCESS_LOCKACCESS(x) (((uint32_t)(((uint32_t)(x)) << MTB_LOCKACCESS_LOCKACCESS_SHIFT)) & MTB_LOCKACCESS_LOCKACCESS_MASK) + +/*! @name LOCKSTAT - Lock Status Register */ +#define MTB_LOCKSTAT_LOCKSTAT_MASK (0xFFFFFFFFU) +#define MTB_LOCKSTAT_LOCKSTAT_SHIFT (0U) +#define MTB_LOCKSTAT_LOCKSTAT(x) (((uint32_t)(((uint32_t)(x)) << MTB_LOCKSTAT_LOCKSTAT_SHIFT)) & MTB_LOCKSTAT_LOCKSTAT_MASK) + +/*! @name AUTHSTAT - Authentication Status Register */ +#define MTB_AUTHSTAT_BIT0_MASK (0x1U) +#define MTB_AUTHSTAT_BIT0_SHIFT (0U) +#define MTB_AUTHSTAT_BIT0(x) (((uint32_t)(((uint32_t)(x)) << MTB_AUTHSTAT_BIT0_SHIFT)) & MTB_AUTHSTAT_BIT0_MASK) +#define MTB_AUTHSTAT_BIT1_MASK (0x2U) +#define MTB_AUTHSTAT_BIT1_SHIFT (1U) +#define MTB_AUTHSTAT_BIT1(x) (((uint32_t)(((uint32_t)(x)) << MTB_AUTHSTAT_BIT1_SHIFT)) & MTB_AUTHSTAT_BIT1_MASK) +#define MTB_AUTHSTAT_BIT2_MASK (0x4U) +#define MTB_AUTHSTAT_BIT2_SHIFT (2U) +#define MTB_AUTHSTAT_BIT2(x) (((uint32_t)(((uint32_t)(x)) << MTB_AUTHSTAT_BIT2_SHIFT)) & MTB_AUTHSTAT_BIT2_MASK) +#define MTB_AUTHSTAT_BIT3_MASK (0x8U) +#define MTB_AUTHSTAT_BIT3_SHIFT (3U) +#define MTB_AUTHSTAT_BIT3(x) (((uint32_t)(((uint32_t)(x)) << MTB_AUTHSTAT_BIT3_SHIFT)) & MTB_AUTHSTAT_BIT3_MASK) + +/*! @name DEVICEARCH - Device Architecture Register */ +#define MTB_DEVICEARCH_DEVICEARCH_MASK (0xFFFFFFFFU) +#define MTB_DEVICEARCH_DEVICEARCH_SHIFT (0U) +#define MTB_DEVICEARCH_DEVICEARCH(x) (((uint32_t)(((uint32_t)(x)) << MTB_DEVICEARCH_DEVICEARCH_SHIFT)) & MTB_DEVICEARCH_DEVICEARCH_MASK) + +/*! @name DEVICECFG - Device Configuration Register */ +#define MTB_DEVICECFG_DEVICECFG_MASK (0xFFFFFFFFU) +#define MTB_DEVICECFG_DEVICECFG_SHIFT (0U) +#define MTB_DEVICECFG_DEVICECFG(x) (((uint32_t)(((uint32_t)(x)) << MTB_DEVICECFG_DEVICECFG_SHIFT)) & MTB_DEVICECFG_DEVICECFG_MASK) + +/*! @name DEVICETYPID - Device Type Identifier Register */ +#define MTB_DEVICETYPID_DEVICETYPID_MASK (0xFFFFFFFFU) +#define MTB_DEVICETYPID_DEVICETYPID_SHIFT (0U) +#define MTB_DEVICETYPID_DEVICETYPID(x) (((uint32_t)(((uint32_t)(x)) << MTB_DEVICETYPID_DEVICETYPID_SHIFT)) & MTB_DEVICETYPID_DEVICETYPID_MASK) + +/*! @name PERIPHID - Peripheral ID Register */ +#define MTB_PERIPHID_PERIPHID_MASK (0xFFFFFFFFU) +#define MTB_PERIPHID_PERIPHID_SHIFT (0U) +#define MTB_PERIPHID_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << MTB_PERIPHID_PERIPHID_SHIFT)) & MTB_PERIPHID_PERIPHID_MASK) + +/* The count of MTB_PERIPHID */ +#define MTB_PERIPHID_COUNT (8U) + +/*! @name COMPID - Component ID Register */ +#define MTB_COMPID_COMPID_MASK (0xFFFFFFFFU) +#define MTB_COMPID_COMPID_SHIFT (0U) +#define MTB_COMPID_COMPID(x) (((uint32_t)(((uint32_t)(x)) << MTB_COMPID_COMPID_SHIFT)) & MTB_COMPID_COMPID_MASK) + +/* The count of MTB_COMPID */ +#define MTB_COMPID_COUNT (4U) + + +/*! + * @} + */ /* end of group MTB_Register_Masks */ + + +/* MTB - Peripheral instance base addresses */ +/** Peripheral MTB base address */ +#define MTB_BASE (0xF0000000u) +/** Peripheral MTB base pointer */ +#define MTB ((MTB_Type *)MTB_BASE) +/** Array initializer of MTB peripheral base addresses */ +#define MTB_BASE_ADDRS { MTB_BASE } +/** Array initializer of MTB peripheral base pointers */ +#define MTB_BASE_PTRS { MTB } + +/*! + * @} + */ /* end of group MTB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MTBDWT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MTBDWT_Peripheral_Access_Layer MTBDWT Peripheral Access Layer + * @{ + */ + +/** MTBDWT - Register Layout Typedef */ +typedef struct { + __I uint32_t CTRL; /**< MTB DWT Control Register, offset: 0x0 */ + uint8_t RESERVED_0[28]; + struct { /* offset: 0x20, array step: 0x10 */ + __IO uint32_t COMP; /**< MTB_DWT Comparator Register, array offset: 0x20, array step: 0x10 */ + __IO uint32_t MASK; /**< MTB_DWT Comparator Mask Register, array offset: 0x24, array step: 0x10 */ + __IO uint32_t FCT; /**< MTB_DWT Comparator Function Register 0..MTB_DWT Comparator Function Register 1, array offset: 0x28, array step: 0x10 */ + uint8_t RESERVED_0[4]; + } COMPARATOR[2]; + uint8_t RESERVED_1[448]; + __IO uint32_t TBCTRL; /**< MTB_DWT Trace Buffer Control Register, offset: 0x200 */ + uint8_t RESERVED_2[3524]; + __I uint32_t DEVICECFG; /**< Device Configuration Register, offset: 0xFC8 */ + __I uint32_t DEVICETYPID; /**< Device Type Identifier Register, offset: 0xFCC */ + __I uint32_t PERIPHID[8]; /**< Peripheral ID Register, array offset: 0xFD0, array step: 0x4 */ + __I uint32_t COMPID[4]; /**< Component ID Register, array offset: 0xFF0, array step: 0x4 */ +} MTBDWT_Type; + +/* ---------------------------------------------------------------------------- + -- MTBDWT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MTBDWT_Register_Masks MTBDWT Register Masks + * @{ + */ + +/*! @name CTRL - MTB DWT Control Register */ +#define MTBDWT_CTRL_DWTCFGCTRL_MASK (0xFFFFFFFU) +#define MTBDWT_CTRL_DWTCFGCTRL_SHIFT (0U) +#define MTBDWT_CTRL_DWTCFGCTRL(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_CTRL_DWTCFGCTRL_SHIFT)) & MTBDWT_CTRL_DWTCFGCTRL_MASK) +#define MTBDWT_CTRL_NUMCMP_MASK (0xF0000000U) +#define MTBDWT_CTRL_NUMCMP_SHIFT (28U) +#define MTBDWT_CTRL_NUMCMP(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_CTRL_NUMCMP_SHIFT)) & MTBDWT_CTRL_NUMCMP_MASK) + +/*! @name COMP - MTB_DWT Comparator Register */ +#define MTBDWT_COMP_COMP_MASK (0xFFFFFFFFU) +#define MTBDWT_COMP_COMP_SHIFT (0U) +#define MTBDWT_COMP_COMP(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_COMP_COMP_SHIFT)) & MTBDWT_COMP_COMP_MASK) + +/* The count of MTBDWT_COMP */ +#define MTBDWT_COMP_COUNT (2U) + +/*! @name MASK - MTB_DWT Comparator Mask Register */ +#define MTBDWT_MASK_MASK_MASK (0x1FU) +#define MTBDWT_MASK_MASK_SHIFT (0U) +#define MTBDWT_MASK_MASK(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_MASK_MASK_SHIFT)) & MTBDWT_MASK_MASK_MASK) + +/* The count of MTBDWT_MASK */ +#define MTBDWT_MASK_COUNT (2U) + +/*! @name FCT - MTB_DWT Comparator Function Register 0..MTB_DWT Comparator Function Register 1 */ +#define MTBDWT_FCT_FUNCTION_MASK (0xFU) +#define MTBDWT_FCT_FUNCTION_SHIFT (0U) +#define MTBDWT_FCT_FUNCTION(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_FCT_FUNCTION_SHIFT)) & MTBDWT_FCT_FUNCTION_MASK) +#define MTBDWT_FCT_DATAVMATCH_MASK (0x100U) +#define MTBDWT_FCT_DATAVMATCH_SHIFT (8U) +#define MTBDWT_FCT_DATAVMATCH(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_FCT_DATAVMATCH_SHIFT)) & MTBDWT_FCT_DATAVMATCH_MASK) +#define MTBDWT_FCT_DATAVSIZE_MASK (0xC00U) +#define MTBDWT_FCT_DATAVSIZE_SHIFT (10U) +#define MTBDWT_FCT_DATAVSIZE(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_FCT_DATAVSIZE_SHIFT)) & MTBDWT_FCT_DATAVSIZE_MASK) +#define MTBDWT_FCT_DATAVADDR0_MASK (0xF000U) +#define MTBDWT_FCT_DATAVADDR0_SHIFT (12U) +#define MTBDWT_FCT_DATAVADDR0(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_FCT_DATAVADDR0_SHIFT)) & MTBDWT_FCT_DATAVADDR0_MASK) +#define MTBDWT_FCT_MATCHED_MASK (0x1000000U) +#define MTBDWT_FCT_MATCHED_SHIFT (24U) +#define MTBDWT_FCT_MATCHED(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_FCT_MATCHED_SHIFT)) & MTBDWT_FCT_MATCHED_MASK) + +/* The count of MTBDWT_FCT */ +#define MTBDWT_FCT_COUNT (2U) + +/*! @name TBCTRL - MTB_DWT Trace Buffer Control Register */ +#define MTBDWT_TBCTRL_ACOMP0_MASK (0x1U) +#define MTBDWT_TBCTRL_ACOMP0_SHIFT (0U) +#define MTBDWT_TBCTRL_ACOMP0(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_TBCTRL_ACOMP0_SHIFT)) & MTBDWT_TBCTRL_ACOMP0_MASK) +#define MTBDWT_TBCTRL_ACOMP1_MASK (0x2U) +#define MTBDWT_TBCTRL_ACOMP1_SHIFT (1U) +#define MTBDWT_TBCTRL_ACOMP1(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_TBCTRL_ACOMP1_SHIFT)) & MTBDWT_TBCTRL_ACOMP1_MASK) +#define MTBDWT_TBCTRL_NUMCOMP_MASK (0xF0000000U) +#define MTBDWT_TBCTRL_NUMCOMP_SHIFT (28U) +#define MTBDWT_TBCTRL_NUMCOMP(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_TBCTRL_NUMCOMP_SHIFT)) & MTBDWT_TBCTRL_NUMCOMP_MASK) + +/*! @name DEVICECFG - Device Configuration Register */ +#define MTBDWT_DEVICECFG_DEVICECFG_MASK (0xFFFFFFFFU) +#define MTBDWT_DEVICECFG_DEVICECFG_SHIFT (0U) +#define MTBDWT_DEVICECFG_DEVICECFG(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_DEVICECFG_DEVICECFG_SHIFT)) & MTBDWT_DEVICECFG_DEVICECFG_MASK) + +/*! @name DEVICETYPID - Device Type Identifier Register */ +#define MTBDWT_DEVICETYPID_DEVICETYPID_MASK (0xFFFFFFFFU) +#define MTBDWT_DEVICETYPID_DEVICETYPID_SHIFT (0U) +#define MTBDWT_DEVICETYPID_DEVICETYPID(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_DEVICETYPID_DEVICETYPID_SHIFT)) & MTBDWT_DEVICETYPID_DEVICETYPID_MASK) + +/*! @name PERIPHID - Peripheral ID Register */ +#define MTBDWT_PERIPHID_PERIPHID_MASK (0xFFFFFFFFU) +#define MTBDWT_PERIPHID_PERIPHID_SHIFT (0U) +#define MTBDWT_PERIPHID_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_PERIPHID_PERIPHID_SHIFT)) & MTBDWT_PERIPHID_PERIPHID_MASK) + +/* The count of MTBDWT_PERIPHID */ +#define MTBDWT_PERIPHID_COUNT (8U) + +/*! @name COMPID - Component ID Register */ +#define MTBDWT_COMPID_COMPID_MASK (0xFFFFFFFFU) +#define MTBDWT_COMPID_COMPID_SHIFT (0U) +#define MTBDWT_COMPID_COMPID(x) (((uint32_t)(((uint32_t)(x)) << MTBDWT_COMPID_COMPID_SHIFT)) & MTBDWT_COMPID_COMPID_MASK) + +/* The count of MTBDWT_COMPID */ +#define MTBDWT_COMPID_COUNT (4U) + + +/*! + * @} + */ /* end of group MTBDWT_Register_Masks */ + + +/* MTBDWT - Peripheral instance base addresses */ +/** Peripheral MTBDWT base address */ +#define MTBDWT_BASE (0xF0001000u) +/** Peripheral MTBDWT base pointer */ +#define MTBDWT ((MTBDWT_Type *)MTBDWT_BASE) +/** Array initializer of MTBDWT peripheral base addresses */ +#define MTBDWT_BASE_ADDRS { MTBDWT_BASE } +/** Array initializer of MTBDWT peripheral base pointers */ +#define MTBDWT_BASE_PTRS { MTBDWT } + +/*! + * @} + */ /* end of group MTBDWT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- NV Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup NV_Peripheral_Access_Layer NV Peripheral Access Layer + * @{ + */ + +/** NV - Register Layout Typedef */ +typedef struct { + __I uint8_t BACKKEY3; /**< Backdoor Comparison Key 3., offset: 0x0 */ + __I uint8_t BACKKEY2; /**< Backdoor Comparison Key 2., offset: 0x1 */ + __I uint8_t BACKKEY1; /**< Backdoor Comparison Key 1., offset: 0x2 */ + __I uint8_t BACKKEY0; /**< Backdoor Comparison Key 0., offset: 0x3 */ + __I uint8_t BACKKEY7; /**< Backdoor Comparison Key 7., offset: 0x4 */ + __I uint8_t BACKKEY6; /**< Backdoor Comparison Key 6., offset: 0x5 */ + __I uint8_t BACKKEY5; /**< Backdoor Comparison Key 5., offset: 0x6 */ + __I uint8_t BACKKEY4; /**< Backdoor Comparison Key 4., offset: 0x7 */ + __I uint8_t FPROT3; /**< Non-volatile P-Flash Protection 1 - Low Register, offset: 0x8 */ + __I uint8_t FPROT2; /**< Non-volatile P-Flash Protection 1 - High Register, offset: 0x9 */ + __I uint8_t FPROT1; /**< Non-volatile P-Flash Protection 0 - Low Register, offset: 0xA */ + __I uint8_t FPROT0; /**< Non-volatile P-Flash Protection 0 - High Register, offset: 0xB */ + __I uint8_t FSEC; /**< Non-volatile Flash Security Register, offset: 0xC */ + __I uint8_t FOPT; /**< Non-volatile Flash Option Register, offset: 0xD */ +} NV_Type; + +/* ---------------------------------------------------------------------------- + -- NV Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup NV_Register_Masks NV Register Masks + * @{ + */ + +/*! @name BACKKEY3 - Backdoor Comparison Key 3. */ +#define NV_BACKKEY3_KEY_MASK (0xFFU) +#define NV_BACKKEY3_KEY_SHIFT (0U) +#define NV_BACKKEY3_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY3_KEY_SHIFT)) & NV_BACKKEY3_KEY_MASK) + +/*! @name BACKKEY2 - Backdoor Comparison Key 2. */ +#define NV_BACKKEY2_KEY_MASK (0xFFU) +#define NV_BACKKEY2_KEY_SHIFT (0U) +#define NV_BACKKEY2_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY2_KEY_SHIFT)) & NV_BACKKEY2_KEY_MASK) + +/*! @name BACKKEY1 - Backdoor Comparison Key 1. */ +#define NV_BACKKEY1_KEY_MASK (0xFFU) +#define NV_BACKKEY1_KEY_SHIFT (0U) +#define NV_BACKKEY1_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY1_KEY_SHIFT)) & NV_BACKKEY1_KEY_MASK) + +/*! @name BACKKEY0 - Backdoor Comparison Key 0. */ +#define NV_BACKKEY0_KEY_MASK (0xFFU) +#define NV_BACKKEY0_KEY_SHIFT (0U) +#define NV_BACKKEY0_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY0_KEY_SHIFT)) & NV_BACKKEY0_KEY_MASK) + +/*! @name BACKKEY7 - Backdoor Comparison Key 7. */ +#define NV_BACKKEY7_KEY_MASK (0xFFU) +#define NV_BACKKEY7_KEY_SHIFT (0U) +#define NV_BACKKEY7_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY7_KEY_SHIFT)) & NV_BACKKEY7_KEY_MASK) + +/*! @name BACKKEY6 - Backdoor Comparison Key 6. */ +#define NV_BACKKEY6_KEY_MASK (0xFFU) +#define NV_BACKKEY6_KEY_SHIFT (0U) +#define NV_BACKKEY6_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY6_KEY_SHIFT)) & NV_BACKKEY6_KEY_MASK) + +/*! @name BACKKEY5 - Backdoor Comparison Key 5. */ +#define NV_BACKKEY5_KEY_MASK (0xFFU) +#define NV_BACKKEY5_KEY_SHIFT (0U) +#define NV_BACKKEY5_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY5_KEY_SHIFT)) & NV_BACKKEY5_KEY_MASK) + +/*! @name BACKKEY4 - Backdoor Comparison Key 4. */ +#define NV_BACKKEY4_KEY_MASK (0xFFU) +#define NV_BACKKEY4_KEY_SHIFT (0U) +#define NV_BACKKEY4_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY4_KEY_SHIFT)) & NV_BACKKEY4_KEY_MASK) + +/*! @name FPROT3 - Non-volatile P-Flash Protection 1 - Low Register */ +#define NV_FPROT3_PROT_MASK (0xFFU) +#define NV_FPROT3_PROT_SHIFT (0U) +#define NV_FPROT3_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT3_PROT_SHIFT)) & NV_FPROT3_PROT_MASK) + +/*! @name FPROT2 - Non-volatile P-Flash Protection 1 - High Register */ +#define NV_FPROT2_PROT_MASK (0xFFU) +#define NV_FPROT2_PROT_SHIFT (0U) +#define NV_FPROT2_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT2_PROT_SHIFT)) & NV_FPROT2_PROT_MASK) + +/*! @name FPROT1 - Non-volatile P-Flash Protection 0 - Low Register */ +#define NV_FPROT1_PROT_MASK (0xFFU) +#define NV_FPROT1_PROT_SHIFT (0U) +#define NV_FPROT1_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT1_PROT_SHIFT)) & NV_FPROT1_PROT_MASK) + +/*! @name FPROT0 - Non-volatile P-Flash Protection 0 - High Register */ +#define NV_FPROT0_PROT_MASK (0xFFU) +#define NV_FPROT0_PROT_SHIFT (0U) +#define NV_FPROT0_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT0_PROT_SHIFT)) & NV_FPROT0_PROT_MASK) + +/*! @name FSEC - Non-volatile Flash Security Register */ +#define NV_FSEC_SEC_MASK (0x3U) +#define NV_FSEC_SEC_SHIFT (0U) +#define NV_FSEC_SEC(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_SEC_SHIFT)) & NV_FSEC_SEC_MASK) +#define NV_FSEC_FSLACC_MASK (0xCU) +#define NV_FSEC_FSLACC_SHIFT (2U) +#define NV_FSEC_FSLACC(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_FSLACC_SHIFT)) & NV_FSEC_FSLACC_MASK) +#define NV_FSEC_MEEN_MASK (0x30U) +#define NV_FSEC_MEEN_SHIFT (4U) +#define NV_FSEC_MEEN(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_MEEN_SHIFT)) & NV_FSEC_MEEN_MASK) +#define NV_FSEC_KEYEN_MASK (0xC0U) +#define NV_FSEC_KEYEN_SHIFT (6U) +#define NV_FSEC_KEYEN(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_KEYEN_SHIFT)) & NV_FSEC_KEYEN_MASK) + +/*! @name FOPT - Non-volatile Flash Option Register */ +#define NV_FOPT_LPBOOT0_MASK (0x1U) +#define NV_FOPT_LPBOOT0_SHIFT (0U) +#define NV_FOPT_LPBOOT0(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_LPBOOT0_SHIFT)) & NV_FOPT_LPBOOT0_MASK) +#define NV_FOPT_BOOTPIN_OPT_MASK (0x2U) +#define NV_FOPT_BOOTPIN_OPT_SHIFT (1U) +#define NV_FOPT_BOOTPIN_OPT(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_BOOTPIN_OPT_SHIFT)) & NV_FOPT_BOOTPIN_OPT_MASK) +#define NV_FOPT_NMI_DIS_MASK (0x4U) +#define NV_FOPT_NMI_DIS_SHIFT (2U) +#define NV_FOPT_NMI_DIS(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_NMI_DIS_SHIFT)) & NV_FOPT_NMI_DIS_MASK) +#define NV_FOPT_RESET_PIN_CFG_MASK (0x8U) +#define NV_FOPT_RESET_PIN_CFG_SHIFT (3U) +#define NV_FOPT_RESET_PIN_CFG(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_RESET_PIN_CFG_SHIFT)) & NV_FOPT_RESET_PIN_CFG_MASK) +#define NV_FOPT_LPBOOT1_MASK (0x10U) +#define NV_FOPT_LPBOOT1_SHIFT (4U) +#define NV_FOPT_LPBOOT1(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_LPBOOT1_SHIFT)) & NV_FOPT_LPBOOT1_MASK) +#define NV_FOPT_FAST_INIT_MASK (0x20U) +#define NV_FOPT_FAST_INIT_SHIFT (5U) +#define NV_FOPT_FAST_INIT(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_FAST_INIT_SHIFT)) & NV_FOPT_FAST_INIT_MASK) +#define NV_FOPT_BOOTSRC_SEL_MASK (0xC0U) +#define NV_FOPT_BOOTSRC_SEL_SHIFT (6U) +#define NV_FOPT_BOOTSRC_SEL(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_BOOTSRC_SEL_SHIFT)) & NV_FOPT_BOOTSRC_SEL_MASK) + + +/*! + * @} + */ /* end of group NV_Register_Masks */ + + +/* NV - Peripheral instance base addresses */ +/** Peripheral FTFA_FlashConfig base address */ +#define FTFA_FlashConfig_BASE (0x400u) +/** Peripheral FTFA_FlashConfig base pointer */ +#define FTFA_FlashConfig ((NV_Type *)FTFA_FlashConfig_BASE) +/** Array initializer of NV peripheral base addresses */ +#define NV_BASE_ADDRS { FTFA_FlashConfig_BASE } +/** Array initializer of NV peripheral base pointers */ +#define NV_BASE_PTRS { FTFA_FlashConfig } + +/*! + * @} + */ /* end of group NV_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- OSC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup OSC_Peripheral_Access_Layer OSC Peripheral Access Layer + * @{ + */ + +/** OSC - Register Layout Typedef */ +typedef struct { + __IO uint8_t CR; /**< OSC Control Register, offset: 0x0 */ +} OSC_Type; + +/* ---------------------------------------------------------------------------- + -- OSC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup OSC_Register_Masks OSC Register Masks + * @{ + */ + +/*! @name CR - OSC Control Register */ +#define OSC_CR_SC16P_MASK (0x1U) +#define OSC_CR_SC16P_SHIFT (0U) +#define OSC_CR_SC16P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC16P_SHIFT)) & OSC_CR_SC16P_MASK) +#define OSC_CR_SC8P_MASK (0x2U) +#define OSC_CR_SC8P_SHIFT (1U) +#define OSC_CR_SC8P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC8P_SHIFT)) & OSC_CR_SC8P_MASK) +#define OSC_CR_SC4P_MASK (0x4U) +#define OSC_CR_SC4P_SHIFT (2U) +#define OSC_CR_SC4P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC4P_SHIFT)) & OSC_CR_SC4P_MASK) +#define OSC_CR_SC2P_MASK (0x8U) +#define OSC_CR_SC2P_SHIFT (3U) +#define OSC_CR_SC2P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC2P_SHIFT)) & OSC_CR_SC2P_MASK) +#define OSC_CR_EREFSTEN_MASK (0x20U) +#define OSC_CR_EREFSTEN_SHIFT (5U) +#define OSC_CR_EREFSTEN(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_EREFSTEN_SHIFT)) & OSC_CR_EREFSTEN_MASK) +#define OSC_CR_ERCLKEN_MASK (0x80U) +#define OSC_CR_ERCLKEN_SHIFT (7U) +#define OSC_CR_ERCLKEN(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_ERCLKEN_SHIFT)) & OSC_CR_ERCLKEN_MASK) + + +/*! + * @} + */ /* end of group OSC_Register_Masks */ + + +/* OSC - Peripheral instance base addresses */ +/** Peripheral OSC0 base address */ +#define OSC0_BASE (0x40065000u) +/** Peripheral OSC0 base pointer */ +#define OSC0 ((OSC_Type *)OSC0_BASE) +/** Array initializer of OSC peripheral base addresses */ +#define OSC_BASE_ADDRS { OSC0_BASE } +/** Array initializer of OSC peripheral base pointers */ +#define OSC_BASE_PTRS { OSC0 } + +/*! + * @} + */ /* end of group OSC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PIT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PIT_Peripheral_Access_Layer PIT Peripheral Access Layer + * @{ + */ + +/** PIT - Register Layout Typedef */ +typedef struct { + __IO uint32_t MCR; /**< PIT Module Control Register, offset: 0x0 */ + uint8_t RESERVED_0[220]; + __I uint32_t LTMR64H; /**< PIT Upper Lifetime Timer Register, offset: 0xE0 */ + __I uint32_t LTMR64L; /**< PIT Lower Lifetime Timer Register, offset: 0xE4 */ + uint8_t RESERVED_1[24]; + struct { /* offset: 0x100, array step: 0x10 */ + __IO uint32_t LDVAL; /**< Timer Load Value Register, array offset: 0x100, array step: 0x10 */ + __I uint32_t CVAL; /**< Current Timer Value Register, array offset: 0x104, array step: 0x10 */ + __IO uint32_t TCTRL; /**< Timer Control Register, array offset: 0x108, array step: 0x10 */ + __IO uint32_t TFLG; /**< Timer Flag Register, array offset: 0x10C, array step: 0x10 */ + } CHANNEL[2]; +} PIT_Type; + +/* ---------------------------------------------------------------------------- + -- PIT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PIT_Register_Masks PIT Register Masks + * @{ + */ + +/*! @name MCR - PIT Module Control Register */ +#define PIT_MCR_FRZ_MASK (0x1U) +#define PIT_MCR_FRZ_SHIFT (0U) +#define PIT_MCR_FRZ(x) (((uint32_t)(((uint32_t)(x)) << PIT_MCR_FRZ_SHIFT)) & PIT_MCR_FRZ_MASK) +#define PIT_MCR_MDIS_MASK (0x2U) +#define PIT_MCR_MDIS_SHIFT (1U) +#define PIT_MCR_MDIS(x) (((uint32_t)(((uint32_t)(x)) << PIT_MCR_MDIS_SHIFT)) & PIT_MCR_MDIS_MASK) + +/*! @name LTMR64H - PIT Upper Lifetime Timer Register */ +#define PIT_LTMR64H_LTH_MASK (0xFFFFFFFFU) +#define PIT_LTMR64H_LTH_SHIFT (0U) +#define PIT_LTMR64H_LTH(x) (((uint32_t)(((uint32_t)(x)) << PIT_LTMR64H_LTH_SHIFT)) & PIT_LTMR64H_LTH_MASK) + +/*! @name LTMR64L - PIT Lower Lifetime Timer Register */ +#define PIT_LTMR64L_LTL_MASK (0xFFFFFFFFU) +#define PIT_LTMR64L_LTL_SHIFT (0U) +#define PIT_LTMR64L_LTL(x) (((uint32_t)(((uint32_t)(x)) << PIT_LTMR64L_LTL_SHIFT)) & PIT_LTMR64L_LTL_MASK) + +/*! @name LDVAL - Timer Load Value Register */ +#define PIT_LDVAL_TSV_MASK (0xFFFFFFFFU) +#define PIT_LDVAL_TSV_SHIFT (0U) +#define PIT_LDVAL_TSV(x) (((uint32_t)(((uint32_t)(x)) << PIT_LDVAL_TSV_SHIFT)) & PIT_LDVAL_TSV_MASK) + +/* The count of PIT_LDVAL */ +#define PIT_LDVAL_COUNT (2U) + +/*! @name CVAL - Current Timer Value Register */ +#define PIT_CVAL_TVL_MASK (0xFFFFFFFFU) +#define PIT_CVAL_TVL_SHIFT (0U) +#define PIT_CVAL_TVL(x) (((uint32_t)(((uint32_t)(x)) << PIT_CVAL_TVL_SHIFT)) & PIT_CVAL_TVL_MASK) + +/* The count of PIT_CVAL */ +#define PIT_CVAL_COUNT (2U) + +/*! @name TCTRL - Timer Control Register */ +#define PIT_TCTRL_TEN_MASK (0x1U) +#define PIT_TCTRL_TEN_SHIFT (0U) +#define PIT_TCTRL_TEN(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_TEN_SHIFT)) & PIT_TCTRL_TEN_MASK) +#define PIT_TCTRL_TIE_MASK (0x2U) +#define PIT_TCTRL_TIE_SHIFT (1U) +#define PIT_TCTRL_TIE(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_TIE_SHIFT)) & PIT_TCTRL_TIE_MASK) +#define PIT_TCTRL_CHN_MASK (0x4U) +#define PIT_TCTRL_CHN_SHIFT (2U) +#define PIT_TCTRL_CHN(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_CHN_SHIFT)) & PIT_TCTRL_CHN_MASK) + +/* The count of PIT_TCTRL */ +#define PIT_TCTRL_COUNT (2U) + +/*! @name TFLG - Timer Flag Register */ +#define PIT_TFLG_TIF_MASK (0x1U) +#define PIT_TFLG_TIF_SHIFT (0U) +#define PIT_TFLG_TIF(x) (((uint32_t)(((uint32_t)(x)) << PIT_TFLG_TIF_SHIFT)) & PIT_TFLG_TIF_MASK) + +/* The count of PIT_TFLG */ +#define PIT_TFLG_COUNT (2U) + + +/*! + * @} + */ /* end of group PIT_Register_Masks */ + + +/* PIT - Peripheral instance base addresses */ +/** Peripheral PIT base address */ +#define PIT_BASE (0x40037000u) +/** Peripheral PIT base pointer */ +#define PIT ((PIT_Type *)PIT_BASE) +/** Array initializer of PIT peripheral base addresses */ +#define PIT_BASE_ADDRS { PIT_BASE } +/** Array initializer of PIT peripheral base pointers */ +#define PIT_BASE_PTRS { PIT } +/** Interrupt vectors for the PIT peripheral type */ +#define PIT_IRQS { PIT_IRQn, PIT_IRQn } + +/*! + * @} + */ /* end of group PIT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PMC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PMC_Peripheral_Access_Layer PMC Peripheral Access Layer + * @{ + */ + +/** PMC - Register Layout Typedef */ +typedef struct { + __IO uint8_t LVDSC1; /**< Low Voltage Detect Status And Control 1 register, offset: 0x0 */ + __IO uint8_t LVDSC2; /**< Low Voltage Detect Status And Control 2 register, offset: 0x1 */ + __IO uint8_t REGSC; /**< Regulator Status And Control register, offset: 0x2 */ +} PMC_Type; + +/* ---------------------------------------------------------------------------- + -- PMC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PMC_Register_Masks PMC Register Masks + * @{ + */ + +/*! @name LVDSC1 - Low Voltage Detect Status And Control 1 register */ +#define PMC_LVDSC1_LVDV_MASK (0x3U) +#define PMC_LVDSC1_LVDV_SHIFT (0U) +#define PMC_LVDSC1_LVDV(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDV_SHIFT)) & PMC_LVDSC1_LVDV_MASK) +#define PMC_LVDSC1_LVDRE_MASK (0x10U) +#define PMC_LVDSC1_LVDRE_SHIFT (4U) +#define PMC_LVDSC1_LVDRE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDRE_SHIFT)) & PMC_LVDSC1_LVDRE_MASK) +#define PMC_LVDSC1_LVDIE_MASK (0x20U) +#define PMC_LVDSC1_LVDIE_SHIFT (5U) +#define PMC_LVDSC1_LVDIE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDIE_SHIFT)) & PMC_LVDSC1_LVDIE_MASK) +#define PMC_LVDSC1_LVDACK_MASK (0x40U) +#define PMC_LVDSC1_LVDACK_SHIFT (6U) +#define PMC_LVDSC1_LVDACK(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDACK_SHIFT)) & PMC_LVDSC1_LVDACK_MASK) +#define PMC_LVDSC1_LVDF_MASK (0x80U) +#define PMC_LVDSC1_LVDF_SHIFT (7U) +#define PMC_LVDSC1_LVDF(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDF_SHIFT)) & PMC_LVDSC1_LVDF_MASK) + +/*! @name LVDSC2 - Low Voltage Detect Status And Control 2 register */ +#define PMC_LVDSC2_LVWV_MASK (0x3U) +#define PMC_LVDSC2_LVWV_SHIFT (0U) +#define PMC_LVDSC2_LVWV(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWV_SHIFT)) & PMC_LVDSC2_LVWV_MASK) +#define PMC_LVDSC2_LVWIE_MASK (0x20U) +#define PMC_LVDSC2_LVWIE_SHIFT (5U) +#define PMC_LVDSC2_LVWIE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWIE_SHIFT)) & PMC_LVDSC2_LVWIE_MASK) +#define PMC_LVDSC2_LVWACK_MASK (0x40U) +#define PMC_LVDSC2_LVWACK_SHIFT (6U) +#define PMC_LVDSC2_LVWACK(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWACK_SHIFT)) & PMC_LVDSC2_LVWACK_MASK) +#define PMC_LVDSC2_LVWF_MASK (0x80U) +#define PMC_LVDSC2_LVWF_SHIFT (7U) +#define PMC_LVDSC2_LVWF(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWF_SHIFT)) & PMC_LVDSC2_LVWF_MASK) + +/*! @name REGSC - Regulator Status And Control register */ +#define PMC_REGSC_BGBE_MASK (0x1U) +#define PMC_REGSC_BGBE_SHIFT (0U) +#define PMC_REGSC_BGBE(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_BGBE_SHIFT)) & PMC_REGSC_BGBE_MASK) +#define PMC_REGSC_REGONS_MASK (0x4U) +#define PMC_REGSC_REGONS_SHIFT (2U) +#define PMC_REGSC_REGONS(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_REGONS_SHIFT)) & PMC_REGSC_REGONS_MASK) +#define PMC_REGSC_ACKISO_MASK (0x8U) +#define PMC_REGSC_ACKISO_SHIFT (3U) +#define PMC_REGSC_ACKISO(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_ACKISO_SHIFT)) & PMC_REGSC_ACKISO_MASK) +#define PMC_REGSC_BGEN_MASK (0x10U) +#define PMC_REGSC_BGEN_SHIFT (4U) +#define PMC_REGSC_BGEN(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_BGEN_SHIFT)) & PMC_REGSC_BGEN_MASK) + + +/*! + * @} + */ /* end of group PMC_Register_Masks */ + + +/* PMC - Peripheral instance base addresses */ +/** Peripheral PMC base address */ +#define PMC_BASE (0x4007D000u) +/** Peripheral PMC base pointer */ +#define PMC ((PMC_Type *)PMC_BASE) +/** Array initializer of PMC peripheral base addresses */ +#define PMC_BASE_ADDRS { PMC_BASE } +/** Array initializer of PMC peripheral base pointers */ +#define PMC_BASE_PTRS { PMC } +/** Interrupt vectors for the PMC peripheral type */ +#define PMC_IRQS { PMC_IRQn } + +/*! + * @} + */ /* end of group PMC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PORT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PORT_Peripheral_Access_Layer PORT Peripheral Access Layer + * @{ + */ + +/** PORT - Register Layout Typedef */ +typedef struct { + __IO uint32_t PCR[32]; /**< Pin Control Register n, array offset: 0x0, array step: 0x4 */ + __O uint32_t GPCLR; /**< Global Pin Control Low Register, offset: 0x80 */ + __O uint32_t GPCHR; /**< Global Pin Control High Register, offset: 0x84 */ + uint8_t RESERVED_0[24]; + __IO uint32_t ISFR; /**< Interrupt Status Flag Register, offset: 0xA0 */ +} PORT_Type; + +/* ---------------------------------------------------------------------------- + -- PORT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PORT_Register_Masks PORT Register Masks + * @{ + */ + +/*! @name PCR - Pin Control Register n */ +#define PORT_PCR_PS_MASK (0x1U) +#define PORT_PCR_PS_SHIFT (0U) +#define PORT_PCR_PS(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PS_SHIFT)) & PORT_PCR_PS_MASK) +#define PORT_PCR_PE_MASK (0x2U) +#define PORT_PCR_PE_SHIFT (1U) +#define PORT_PCR_PE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PE_SHIFT)) & PORT_PCR_PE_MASK) +#define PORT_PCR_SRE_MASK (0x4U) +#define PORT_PCR_SRE_SHIFT (2U) +#define PORT_PCR_SRE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_SRE_SHIFT)) & PORT_PCR_SRE_MASK) +#define PORT_PCR_PFE_MASK (0x10U) +#define PORT_PCR_PFE_SHIFT (4U) +#define PORT_PCR_PFE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PFE_SHIFT)) & PORT_PCR_PFE_MASK) +#define PORT_PCR_DSE_MASK (0x40U) +#define PORT_PCR_DSE_SHIFT (6U) +#define PORT_PCR_DSE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_DSE_SHIFT)) & PORT_PCR_DSE_MASK) +#define PORT_PCR_MUX_MASK (0x700U) +#define PORT_PCR_MUX_SHIFT (8U) +#define PORT_PCR_MUX(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_MUX_SHIFT)) & PORT_PCR_MUX_MASK) +#define PORT_PCR_IRQC_MASK (0xF0000U) +#define PORT_PCR_IRQC_SHIFT (16U) +#define PORT_PCR_IRQC(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_IRQC_SHIFT)) & PORT_PCR_IRQC_MASK) +#define PORT_PCR_ISF_MASK (0x1000000U) +#define PORT_PCR_ISF_SHIFT (24U) +#define PORT_PCR_ISF(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_ISF_SHIFT)) & PORT_PCR_ISF_MASK) + +/* The count of PORT_PCR */ +#define PORT_PCR_COUNT (32U) + +/*! @name GPCLR - Global Pin Control Low Register */ +#define PORT_GPCLR_GPWD_MASK (0xFFFFU) +#define PORT_GPCLR_GPWD_SHIFT (0U) +#define PORT_GPCLR_GPWD(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCLR_GPWD_SHIFT)) & PORT_GPCLR_GPWD_MASK) +#define PORT_GPCLR_GPWE_MASK (0xFFFF0000U) +#define PORT_GPCLR_GPWE_SHIFT (16U) +#define PORT_GPCLR_GPWE(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCLR_GPWE_SHIFT)) & PORT_GPCLR_GPWE_MASK) + +/*! @name GPCHR - Global Pin Control High Register */ +#define PORT_GPCHR_GPWD_MASK (0xFFFFU) +#define PORT_GPCHR_GPWD_SHIFT (0U) +#define PORT_GPCHR_GPWD(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCHR_GPWD_SHIFT)) & PORT_GPCHR_GPWD_MASK) +#define PORT_GPCHR_GPWE_MASK (0xFFFF0000U) +#define PORT_GPCHR_GPWE_SHIFT (16U) +#define PORT_GPCHR_GPWE(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCHR_GPWE_SHIFT)) & PORT_GPCHR_GPWE_MASK) + +/*! @name ISFR - Interrupt Status Flag Register */ +#define PORT_ISFR_ISF_MASK (0xFFFFFFFFU) +#define PORT_ISFR_ISF_SHIFT (0U) +#define PORT_ISFR_ISF(x) (((uint32_t)(((uint32_t)(x)) << PORT_ISFR_ISF_SHIFT)) & PORT_ISFR_ISF_MASK) + + +/*! + * @} + */ /* end of group PORT_Register_Masks */ + + +/* PORT - Peripheral instance base addresses */ +/** Peripheral PORTA base address */ +#define PORTA_BASE (0x40049000u) +/** Peripheral PORTA base pointer */ +#define PORTA ((PORT_Type *)PORTA_BASE) +/** Peripheral PORTB base address */ +#define PORTB_BASE (0x4004A000u) +/** Peripheral PORTB base pointer */ +#define PORTB ((PORT_Type *)PORTB_BASE) +/** Peripheral PORTC base address */ +#define PORTC_BASE (0x4004B000u) +/** Peripheral PORTC base pointer */ +#define PORTC ((PORT_Type *)PORTC_BASE) +/** Peripheral PORTD base address */ +#define PORTD_BASE (0x4004C000u) +/** Peripheral PORTD base pointer */ +#define PORTD ((PORT_Type *)PORTD_BASE) +/** Peripheral PORTE base address */ +#define PORTE_BASE (0x4004D000u) +/** Peripheral PORTE base pointer */ +#define PORTE ((PORT_Type *)PORTE_BASE) +/** Array initializer of PORT peripheral base addresses */ +#define PORT_BASE_ADDRS { PORTA_BASE, PORTB_BASE, PORTC_BASE, PORTD_BASE, PORTE_BASE } +/** Array initializer of PORT peripheral base pointers */ +#define PORT_BASE_PTRS { PORTA, PORTB, PORTC, PORTD, PORTE } +/** Interrupt vectors for the PORT peripheral type */ +#define PORT_IRQS { PORTA_IRQn, NotAvail_IRQn, PORTC_PORTD_IRQn, PORTC_PORTD_IRQn, NotAvail_IRQn } + +/*! + * @} + */ /* end of group PORT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RCM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RCM_Peripheral_Access_Layer RCM Peripheral Access Layer + * @{ + */ + +/** RCM - Register Layout Typedef */ +typedef struct { + __I uint8_t SRS0; /**< System Reset Status Register 0, offset: 0x0 */ + __I uint8_t SRS1; /**< System Reset Status Register 1, offset: 0x1 */ + uint8_t RESERVED_0[2]; + __IO uint8_t RPFC; /**< Reset Pin Filter Control register, offset: 0x4 */ + __IO uint8_t RPFW; /**< Reset Pin Filter Width register, offset: 0x5 */ + __IO uint8_t FM; /**< Force Mode Register, offset: 0x6 */ + __IO uint8_t MR; /**< Mode Register, offset: 0x7 */ + __IO uint8_t SSRS0; /**< Sticky System Reset Status Register 0, offset: 0x8 */ + __IO uint8_t SSRS1; /**< Sticky System Reset Status Register 1, offset: 0x9 */ +} RCM_Type; + +/* ---------------------------------------------------------------------------- + -- RCM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RCM_Register_Masks RCM Register Masks + * @{ + */ + +/*! @name SRS0 - System Reset Status Register 0 */ +#define RCM_SRS0_WAKEUP_MASK (0x1U) +#define RCM_SRS0_WAKEUP_SHIFT (0U) +#define RCM_SRS0_WAKEUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_WAKEUP_SHIFT)) & RCM_SRS0_WAKEUP_MASK) +#define RCM_SRS0_LVD_MASK (0x2U) +#define RCM_SRS0_LVD_SHIFT (1U) +#define RCM_SRS0_LVD(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_LVD_SHIFT)) & RCM_SRS0_LVD_MASK) +#define RCM_SRS0_WDOG_MASK (0x20U) +#define RCM_SRS0_WDOG_SHIFT (5U) +#define RCM_SRS0_WDOG(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_WDOG_SHIFT)) & RCM_SRS0_WDOG_MASK) +#define RCM_SRS0_PIN_MASK (0x40U) +#define RCM_SRS0_PIN_SHIFT (6U) +#define RCM_SRS0_PIN(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_PIN_SHIFT)) & RCM_SRS0_PIN_MASK) +#define RCM_SRS0_POR_MASK (0x80U) +#define RCM_SRS0_POR_SHIFT (7U) +#define RCM_SRS0_POR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_POR_SHIFT)) & RCM_SRS0_POR_MASK) + +/*! @name SRS1 - System Reset Status Register 1 */ +#define RCM_SRS1_LOCKUP_MASK (0x2U) +#define RCM_SRS1_LOCKUP_SHIFT (1U) +#define RCM_SRS1_LOCKUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_LOCKUP_SHIFT)) & RCM_SRS1_LOCKUP_MASK) +#define RCM_SRS1_SW_MASK (0x4U) +#define RCM_SRS1_SW_SHIFT (2U) +#define RCM_SRS1_SW(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_SW_SHIFT)) & RCM_SRS1_SW_MASK) +#define RCM_SRS1_MDM_AP_MASK (0x8U) +#define RCM_SRS1_MDM_AP_SHIFT (3U) +#define RCM_SRS1_MDM_AP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_MDM_AP_SHIFT)) & RCM_SRS1_MDM_AP_MASK) +#define RCM_SRS1_SACKERR_MASK (0x20U) +#define RCM_SRS1_SACKERR_SHIFT (5U) +#define RCM_SRS1_SACKERR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_SACKERR_SHIFT)) & RCM_SRS1_SACKERR_MASK) + +/*! @name RPFC - Reset Pin Filter Control register */ +#define RCM_RPFC_RSTFLTSRW_MASK (0x3U) +#define RCM_RPFC_RSTFLTSRW_SHIFT (0U) +#define RCM_RPFC_RSTFLTSRW(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFC_RSTFLTSRW_SHIFT)) & RCM_RPFC_RSTFLTSRW_MASK) +#define RCM_RPFC_RSTFLTSS_MASK (0x4U) +#define RCM_RPFC_RSTFLTSS_SHIFT (2U) +#define RCM_RPFC_RSTFLTSS(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFC_RSTFLTSS_SHIFT)) & RCM_RPFC_RSTFLTSS_MASK) + +/*! @name RPFW - Reset Pin Filter Width register */ +#define RCM_RPFW_RSTFLTSEL_MASK (0x1FU) +#define RCM_RPFW_RSTFLTSEL_SHIFT (0U) +#define RCM_RPFW_RSTFLTSEL(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFW_RSTFLTSEL_SHIFT)) & RCM_RPFW_RSTFLTSEL_MASK) + +/*! @name FM - Force Mode Register */ +#define RCM_FM_FORCEROM_MASK (0x6U) +#define RCM_FM_FORCEROM_SHIFT (1U) +#define RCM_FM_FORCEROM(x) (((uint8_t)(((uint8_t)(x)) << RCM_FM_FORCEROM_SHIFT)) & RCM_FM_FORCEROM_MASK) + +/*! @name MR - Mode Register */ +#define RCM_MR_BOOTROM_MASK (0x6U) +#define RCM_MR_BOOTROM_SHIFT (1U) +#define RCM_MR_BOOTROM(x) (((uint8_t)(((uint8_t)(x)) << RCM_MR_BOOTROM_SHIFT)) & RCM_MR_BOOTROM_MASK) + +/*! @name SSRS0 - Sticky System Reset Status Register 0 */ +#define RCM_SSRS0_SWAKEUP_MASK (0x1U) +#define RCM_SSRS0_SWAKEUP_SHIFT (0U) +#define RCM_SSRS0_SWAKEUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SWAKEUP_SHIFT)) & RCM_SSRS0_SWAKEUP_MASK) +#define RCM_SSRS0_SLVD_MASK (0x2U) +#define RCM_SSRS0_SLVD_SHIFT (1U) +#define RCM_SSRS0_SLVD(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SLVD_SHIFT)) & RCM_SSRS0_SLVD_MASK) +#define RCM_SSRS0_SWDOG_MASK (0x20U) +#define RCM_SSRS0_SWDOG_SHIFT (5U) +#define RCM_SSRS0_SWDOG(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SWDOG_SHIFT)) & RCM_SSRS0_SWDOG_MASK) +#define RCM_SSRS0_SPIN_MASK (0x40U) +#define RCM_SSRS0_SPIN_SHIFT (6U) +#define RCM_SSRS0_SPIN(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SPIN_SHIFT)) & RCM_SSRS0_SPIN_MASK) +#define RCM_SSRS0_SPOR_MASK (0x80U) +#define RCM_SSRS0_SPOR_SHIFT (7U) +#define RCM_SSRS0_SPOR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS0_SPOR_SHIFT)) & RCM_SSRS0_SPOR_MASK) + +/*! @name SSRS1 - Sticky System Reset Status Register 1 */ +#define RCM_SSRS1_SLOCKUP_MASK (0x2U) +#define RCM_SSRS1_SLOCKUP_SHIFT (1U) +#define RCM_SSRS1_SLOCKUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SLOCKUP_SHIFT)) & RCM_SSRS1_SLOCKUP_MASK) +#define RCM_SSRS1_SSW_MASK (0x4U) +#define RCM_SSRS1_SSW_SHIFT (2U) +#define RCM_SSRS1_SSW(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SSW_SHIFT)) & RCM_SSRS1_SSW_MASK) +#define RCM_SSRS1_SMDM_AP_MASK (0x8U) +#define RCM_SSRS1_SMDM_AP_SHIFT (3U) +#define RCM_SSRS1_SMDM_AP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SMDM_AP_SHIFT)) & RCM_SSRS1_SMDM_AP_MASK) +#define RCM_SSRS1_SSACKERR_MASK (0x20U) +#define RCM_SSRS1_SSACKERR_SHIFT (5U) +#define RCM_SSRS1_SSACKERR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SSRS1_SSACKERR_SHIFT)) & RCM_SSRS1_SSACKERR_MASK) + + +/*! + * @} + */ /* end of group RCM_Register_Masks */ + + +/* RCM - Peripheral instance base addresses */ +/** Peripheral RCM base address */ +#define RCM_BASE (0x4007F000u) +/** Peripheral RCM base pointer */ +#define RCM ((RCM_Type *)RCM_BASE) +/** Array initializer of RCM peripheral base addresses */ +#define RCM_BASE_ADDRS { RCM_BASE } +/** Array initializer of RCM peripheral base pointers */ +#define RCM_BASE_PTRS { RCM } + +/*! + * @} + */ /* end of group RCM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RFSYS Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFSYS_Peripheral_Access_Layer RFSYS Peripheral Access Layer + * @{ + */ + +/** RFSYS - Register Layout Typedef */ +typedef struct { + __IO uint32_t REG[8]; /**< Register file register, array offset: 0x0, array step: 0x4 */ +} RFSYS_Type; + +/* ---------------------------------------------------------------------------- + -- RFSYS Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFSYS_Register_Masks RFSYS Register Masks + * @{ + */ + +/*! @name REG - Register file register */ +#define RFSYS_REG_LL_MASK (0xFFU) +#define RFSYS_REG_LL_SHIFT (0U) +#define RFSYS_REG_LL(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_LL_SHIFT)) & RFSYS_REG_LL_MASK) +#define RFSYS_REG_LH_MASK (0xFF00U) +#define RFSYS_REG_LH_SHIFT (8U) +#define RFSYS_REG_LH(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_LH_SHIFT)) & RFSYS_REG_LH_MASK) +#define RFSYS_REG_HL_MASK (0xFF0000U) +#define RFSYS_REG_HL_SHIFT (16U) +#define RFSYS_REG_HL(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_HL_SHIFT)) & RFSYS_REG_HL_MASK) +#define RFSYS_REG_HH_MASK (0xFF000000U) +#define RFSYS_REG_HH_SHIFT (24U) +#define RFSYS_REG_HH(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_HH_SHIFT)) & RFSYS_REG_HH_MASK) + +/* The count of RFSYS_REG */ +#define RFSYS_REG_COUNT (8U) + + +/*! + * @} + */ /* end of group RFSYS_Register_Masks */ + + +/* RFSYS - Peripheral instance base addresses */ +/** Peripheral RFSYS base address */ +#define RFSYS_BASE (0x40041000u) +/** Peripheral RFSYS base pointer */ +#define RFSYS ((RFSYS_Type *)RFSYS_BASE) +/** Array initializer of RFSYS peripheral base addresses */ +#define RFSYS_BASE_ADDRS { RFSYS_BASE } +/** Array initializer of RFSYS peripheral base pointers */ +#define RFSYS_BASE_PTRS { RFSYS } + +/*! + * @} + */ /* end of group RFSYS_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- ROM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ROM_Peripheral_Access_Layer ROM Peripheral Access Layer + * @{ + */ + +/** ROM - Register Layout Typedef */ +typedef struct { + __I uint32_t ENTRY[3]; /**< Entry, array offset: 0x0, array step: 0x4 */ + __I uint32_t TABLEMARK; /**< End of Table Marker Register, offset: 0xC */ + uint8_t RESERVED_0[4028]; + __I uint32_t SYSACCESS; /**< System Access Register, offset: 0xFCC */ + __I uint32_t PERIPHID4; /**< Peripheral ID Register, offset: 0xFD0 */ + __I uint32_t PERIPHID5; /**< Peripheral ID Register, offset: 0xFD4 */ + __I uint32_t PERIPHID6; /**< Peripheral ID Register, offset: 0xFD8 */ + __I uint32_t PERIPHID7; /**< Peripheral ID Register, offset: 0xFDC */ + __I uint32_t PERIPHID0; /**< Peripheral ID Register, offset: 0xFE0 */ + __I uint32_t PERIPHID1; /**< Peripheral ID Register, offset: 0xFE4 */ + __I uint32_t PERIPHID2; /**< Peripheral ID Register, offset: 0xFE8 */ + __I uint32_t PERIPHID3; /**< Peripheral ID Register, offset: 0xFEC */ + __I uint32_t COMPID[4]; /**< Component ID Register, array offset: 0xFF0, array step: 0x4 */ +} ROM_Type; + +/* ---------------------------------------------------------------------------- + -- ROM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ROM_Register_Masks ROM Register Masks + * @{ + */ + +/*! @name ENTRY - Entry */ +#define ROM_ENTRY_ENTRY_MASK (0xFFFFFFFFU) +#define ROM_ENTRY_ENTRY_SHIFT (0U) +#define ROM_ENTRY_ENTRY(x) (((uint32_t)(((uint32_t)(x)) << ROM_ENTRY_ENTRY_SHIFT)) & ROM_ENTRY_ENTRY_MASK) + +/* The count of ROM_ENTRY */ +#define ROM_ENTRY_COUNT (3U) + +/*! @name TABLEMARK - End of Table Marker Register */ +#define ROM_TABLEMARK_MARK_MASK (0xFFFFFFFFU) +#define ROM_TABLEMARK_MARK_SHIFT (0U) +#define ROM_TABLEMARK_MARK(x) (((uint32_t)(((uint32_t)(x)) << ROM_TABLEMARK_MARK_SHIFT)) & ROM_TABLEMARK_MARK_MASK) + +/*! @name SYSACCESS - System Access Register */ +#define ROM_SYSACCESS_SYSACCESS_MASK (0xFFFFFFFFU) +#define ROM_SYSACCESS_SYSACCESS_SHIFT (0U) +#define ROM_SYSACCESS_SYSACCESS(x) (((uint32_t)(((uint32_t)(x)) << ROM_SYSACCESS_SYSACCESS_SHIFT)) & ROM_SYSACCESS_SYSACCESS_MASK) + +/*! @name PERIPHID4 - Peripheral ID Register */ +#define ROM_PERIPHID4_PERIPHID_MASK (0xFFFFFFFFU) +#define ROM_PERIPHID4_PERIPHID_SHIFT (0U) +#define ROM_PERIPHID4_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << ROM_PERIPHID4_PERIPHID_SHIFT)) & ROM_PERIPHID4_PERIPHID_MASK) + +/*! @name PERIPHID5 - Peripheral ID Register */ +#define ROM_PERIPHID5_PERIPHID_MASK (0xFFFFFFFFU) +#define ROM_PERIPHID5_PERIPHID_SHIFT (0U) +#define ROM_PERIPHID5_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << ROM_PERIPHID5_PERIPHID_SHIFT)) & ROM_PERIPHID5_PERIPHID_MASK) + +/*! @name PERIPHID6 - Peripheral ID Register */ +#define ROM_PERIPHID6_PERIPHID_MASK (0xFFFFFFFFU) +#define ROM_PERIPHID6_PERIPHID_SHIFT (0U) +#define ROM_PERIPHID6_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << ROM_PERIPHID6_PERIPHID_SHIFT)) & ROM_PERIPHID6_PERIPHID_MASK) + +/*! @name PERIPHID7 - Peripheral ID Register */ +#define ROM_PERIPHID7_PERIPHID_MASK (0xFFFFFFFFU) +#define ROM_PERIPHID7_PERIPHID_SHIFT (0U) +#define ROM_PERIPHID7_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << ROM_PERIPHID7_PERIPHID_SHIFT)) & ROM_PERIPHID7_PERIPHID_MASK) + +/*! @name PERIPHID0 - Peripheral ID Register */ +#define ROM_PERIPHID0_PERIPHID_MASK (0xFFFFFFFFU) +#define ROM_PERIPHID0_PERIPHID_SHIFT (0U) +#define ROM_PERIPHID0_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << ROM_PERIPHID0_PERIPHID_SHIFT)) & ROM_PERIPHID0_PERIPHID_MASK) + +/*! @name PERIPHID1 - Peripheral ID Register */ +#define ROM_PERIPHID1_PERIPHID_MASK (0xFFFFFFFFU) +#define ROM_PERIPHID1_PERIPHID_SHIFT (0U) +#define ROM_PERIPHID1_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << ROM_PERIPHID1_PERIPHID_SHIFT)) & ROM_PERIPHID1_PERIPHID_MASK) + +/*! @name PERIPHID2 - Peripheral ID Register */ +#define ROM_PERIPHID2_PERIPHID_MASK (0xFFFFFFFFU) +#define ROM_PERIPHID2_PERIPHID_SHIFT (0U) +#define ROM_PERIPHID2_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << ROM_PERIPHID2_PERIPHID_SHIFT)) & ROM_PERIPHID2_PERIPHID_MASK) + +/*! @name PERIPHID3 - Peripheral ID Register */ +#define ROM_PERIPHID3_PERIPHID_MASK (0xFFFFFFFFU) +#define ROM_PERIPHID3_PERIPHID_SHIFT (0U) +#define ROM_PERIPHID3_PERIPHID(x) (((uint32_t)(((uint32_t)(x)) << ROM_PERIPHID3_PERIPHID_SHIFT)) & ROM_PERIPHID3_PERIPHID_MASK) + +/*! @name COMPID - Component ID Register */ +#define ROM_COMPID_COMPID_MASK (0xFFFFFFFFU) +#define ROM_COMPID_COMPID_SHIFT (0U) +#define ROM_COMPID_COMPID(x) (((uint32_t)(((uint32_t)(x)) << ROM_COMPID_COMPID_SHIFT)) & ROM_COMPID_COMPID_MASK) + +/* The count of ROM_COMPID */ +#define ROM_COMPID_COUNT (4U) + + +/*! + * @} + */ /* end of group ROM_Register_Masks */ + + +/* ROM - Peripheral instance base addresses */ +/** Peripheral ROM base address */ +#define ROM_BASE (0xF0002000u) +/** Peripheral ROM base pointer */ +#define ROM ((ROM_Type *)ROM_BASE) +/** Array initializer of ROM peripheral base addresses */ +#define ROM_BASE_ADDRS { ROM_BASE } +/** Array initializer of ROM peripheral base pointers */ +#define ROM_BASE_PTRS { ROM } + +/*! + * @} + */ /* end of group ROM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RTC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Peripheral_Access_Layer RTC Peripheral Access Layer + * @{ + */ + +/** RTC - Register Layout Typedef */ +typedef struct { + __IO uint32_t TSR; /**< RTC Time Seconds Register, offset: 0x0 */ + __IO uint32_t TPR; /**< RTC Time Prescaler Register, offset: 0x4 */ + __IO uint32_t TAR; /**< RTC Time Alarm Register, offset: 0x8 */ + __IO uint32_t TCR; /**< RTC Time Compensation Register, offset: 0xC */ + __IO uint32_t CR; /**< RTC Control Register, offset: 0x10 */ + __IO uint32_t SR; /**< RTC Status Register, offset: 0x14 */ + __IO uint32_t LR; /**< RTC Lock Register, offset: 0x18 */ + __IO uint32_t IER; /**< RTC Interrupt Enable Register, offset: 0x1C */ +} RTC_Type; + +/* ---------------------------------------------------------------------------- + -- RTC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Register_Masks RTC Register Masks + * @{ + */ + +/*! @name TSR - RTC Time Seconds Register */ +#define RTC_TSR_TSR_MASK (0xFFFFFFFFU) +#define RTC_TSR_TSR_SHIFT (0U) +#define RTC_TSR_TSR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TSR_TSR_SHIFT)) & RTC_TSR_TSR_MASK) + +/*! @name TPR - RTC Time Prescaler Register */ +#define RTC_TPR_TPR_MASK (0xFFFFU) +#define RTC_TPR_TPR_SHIFT (0U) +#define RTC_TPR_TPR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TPR_TPR_SHIFT)) & RTC_TPR_TPR_MASK) + +/*! @name TAR - RTC Time Alarm Register */ +#define RTC_TAR_TAR_MASK (0xFFFFFFFFU) +#define RTC_TAR_TAR_SHIFT (0U) +#define RTC_TAR_TAR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TAR_TAR_SHIFT)) & RTC_TAR_TAR_MASK) + +/*! @name TCR - RTC Time Compensation Register */ +#define RTC_TCR_TCR_MASK (0xFFU) +#define RTC_TCR_TCR_SHIFT (0U) +#define RTC_TCR_TCR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_TCR_SHIFT)) & RTC_TCR_TCR_MASK) +#define RTC_TCR_CIR_MASK (0xFF00U) +#define RTC_TCR_CIR_SHIFT (8U) +#define RTC_TCR_CIR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_CIR_SHIFT)) & RTC_TCR_CIR_MASK) +#define RTC_TCR_TCV_MASK (0xFF0000U) +#define RTC_TCR_TCV_SHIFT (16U) +#define RTC_TCR_TCV(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_TCV_SHIFT)) & RTC_TCR_TCV_MASK) +#define RTC_TCR_CIC_MASK (0xFF000000U) +#define RTC_TCR_CIC_SHIFT (24U) +#define RTC_TCR_CIC(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_CIC_SHIFT)) & RTC_TCR_CIC_MASK) + +/*! @name CR - RTC Control Register */ +#define RTC_CR_SWR_MASK (0x1U) +#define RTC_CR_SWR_SHIFT (0U) +#define RTC_CR_SWR(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SWR_SHIFT)) & RTC_CR_SWR_MASK) +#define RTC_CR_WPE_MASK (0x2U) +#define RTC_CR_WPE_SHIFT (1U) +#define RTC_CR_WPE(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_WPE_SHIFT)) & RTC_CR_WPE_MASK) +#define RTC_CR_SUP_MASK (0x4U) +#define RTC_CR_SUP_SHIFT (2U) +#define RTC_CR_SUP(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SUP_SHIFT)) & RTC_CR_SUP_MASK) +#define RTC_CR_UM_MASK (0x8U) +#define RTC_CR_UM_SHIFT (3U) +#define RTC_CR_UM(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_UM_SHIFT)) & RTC_CR_UM_MASK) +#define RTC_CR_WPS_MASK (0x10U) +#define RTC_CR_WPS_SHIFT (4U) +#define RTC_CR_WPS(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_WPS_SHIFT)) & RTC_CR_WPS_MASK) +#define RTC_CR_OSCE_MASK (0x100U) +#define RTC_CR_OSCE_SHIFT (8U) +#define RTC_CR_OSCE(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_OSCE_SHIFT)) & RTC_CR_OSCE_MASK) +#define RTC_CR_CLKO_MASK (0x200U) +#define RTC_CR_CLKO_SHIFT (9U) +#define RTC_CR_CLKO(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_CLKO_SHIFT)) & RTC_CR_CLKO_MASK) +#define RTC_CR_SC16P_MASK (0x400U) +#define RTC_CR_SC16P_SHIFT (10U) +#define RTC_CR_SC16P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC16P_SHIFT)) & RTC_CR_SC16P_MASK) +#define RTC_CR_SC8P_MASK (0x800U) +#define RTC_CR_SC8P_SHIFT (11U) +#define RTC_CR_SC8P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC8P_SHIFT)) & RTC_CR_SC8P_MASK) +#define RTC_CR_SC4P_MASK (0x1000U) +#define RTC_CR_SC4P_SHIFT (12U) +#define RTC_CR_SC4P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC4P_SHIFT)) & RTC_CR_SC4P_MASK) +#define RTC_CR_SC2P_MASK (0x2000U) +#define RTC_CR_SC2P_SHIFT (13U) +#define RTC_CR_SC2P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC2P_SHIFT)) & RTC_CR_SC2P_MASK) + +/*! @name SR - RTC Status Register */ +#define RTC_SR_TIF_MASK (0x1U) +#define RTC_SR_TIF_SHIFT (0U) +#define RTC_SR_TIF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TIF_SHIFT)) & RTC_SR_TIF_MASK) +#define RTC_SR_TOF_MASK (0x2U) +#define RTC_SR_TOF_SHIFT (1U) +#define RTC_SR_TOF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TOF_SHIFT)) & RTC_SR_TOF_MASK) +#define RTC_SR_TAF_MASK (0x4U) +#define RTC_SR_TAF_SHIFT (2U) +#define RTC_SR_TAF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TAF_SHIFT)) & RTC_SR_TAF_MASK) +#define RTC_SR_TCE_MASK (0x10U) +#define RTC_SR_TCE_SHIFT (4U) +#define RTC_SR_TCE(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TCE_SHIFT)) & RTC_SR_TCE_MASK) + +/*! @name LR - RTC Lock Register */ +#define RTC_LR_TCL_MASK (0x8U) +#define RTC_LR_TCL_SHIFT (3U) +#define RTC_LR_TCL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_TCL_SHIFT)) & RTC_LR_TCL_MASK) +#define RTC_LR_CRL_MASK (0x10U) +#define RTC_LR_CRL_SHIFT (4U) +#define RTC_LR_CRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_CRL_SHIFT)) & RTC_LR_CRL_MASK) +#define RTC_LR_SRL_MASK (0x20U) +#define RTC_LR_SRL_SHIFT (5U) +#define RTC_LR_SRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_SRL_SHIFT)) & RTC_LR_SRL_MASK) +#define RTC_LR_LRL_MASK (0x40U) +#define RTC_LR_LRL_SHIFT (6U) +#define RTC_LR_LRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_LRL_SHIFT)) & RTC_LR_LRL_MASK) + +/*! @name IER - RTC Interrupt Enable Register */ +#define RTC_IER_TIIE_MASK (0x1U) +#define RTC_IER_TIIE_SHIFT (0U) +#define RTC_IER_TIIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TIIE_SHIFT)) & RTC_IER_TIIE_MASK) +#define RTC_IER_TOIE_MASK (0x2U) +#define RTC_IER_TOIE_SHIFT (1U) +#define RTC_IER_TOIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TOIE_SHIFT)) & RTC_IER_TOIE_MASK) +#define RTC_IER_TAIE_MASK (0x4U) +#define RTC_IER_TAIE_SHIFT (2U) +#define RTC_IER_TAIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TAIE_SHIFT)) & RTC_IER_TAIE_MASK) +#define RTC_IER_TSIE_MASK (0x10U) +#define RTC_IER_TSIE_SHIFT (4U) +#define RTC_IER_TSIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TSIE_SHIFT)) & RTC_IER_TSIE_MASK) +#define RTC_IER_WPON_MASK (0x80U) +#define RTC_IER_WPON_SHIFT (7U) +#define RTC_IER_WPON(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_WPON_SHIFT)) & RTC_IER_WPON_MASK) + + +/*! + * @} + */ /* end of group RTC_Register_Masks */ + + +/* RTC - Peripheral instance base addresses */ +/** Peripheral RTC base address */ +#define RTC_BASE (0x4003D000u) +/** Peripheral RTC base pointer */ +#define RTC ((RTC_Type *)RTC_BASE) +/** Array initializer of RTC peripheral base addresses */ +#define RTC_BASE_ADDRS { RTC_BASE } +/** Array initializer of RTC peripheral base pointers */ +#define RTC_BASE_PTRS { RTC } +/** Interrupt vectors for the RTC peripheral type */ +#define RTC_IRQS { RTC_IRQn } +#define RTC_SECONDS_IRQS { RTC_Seconds_IRQn } + +/*! + * @} + */ /* end of group RTC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SIM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SIM_Peripheral_Access_Layer SIM Peripheral Access Layer + * @{ + */ + +/** SIM - Register Layout Typedef */ +typedef struct { + __IO uint32_t SOPT1; /**< System Options Register 1, offset: 0x0 */ + __IO uint32_t SOPT1CFG; /**< SOPT1 Configuration Register, offset: 0x4 */ + uint8_t RESERVED_0[4092]; + __IO uint32_t SOPT2; /**< System Options Register 2, offset: 0x1004 */ + uint8_t RESERVED_1[4]; + __IO uint32_t SOPT4; /**< System Options Register 4, offset: 0x100C */ + __IO uint32_t SOPT5; /**< System Options Register 5, offset: 0x1010 */ + uint8_t RESERVED_2[4]; + __IO uint32_t SOPT7; /**< System Options Register 7, offset: 0x1018 */ + uint8_t RESERVED_3[8]; + __I uint32_t SDID; /**< System Device Identification Register, offset: 0x1024 */ + uint8_t RESERVED_4[12]; + __IO uint32_t SCGC4; /**< System Clock Gating Control Register 4, offset: 0x1034 */ + __IO uint32_t SCGC5; /**< System Clock Gating Control Register 5, offset: 0x1038 */ + __IO uint32_t SCGC6; /**< System Clock Gating Control Register 6, offset: 0x103C */ + __IO uint32_t SCGC7; /**< System Clock Gating Control Register 7, offset: 0x1040 */ + __IO uint32_t CLKDIV1; /**< System Clock Divider Register 1, offset: 0x1044 */ + uint8_t RESERVED_5[4]; + __IO uint32_t FCFG1; /**< Flash Configuration Register 1, offset: 0x104C */ + __I uint32_t FCFG2; /**< Flash Configuration Register 2, offset: 0x1050 */ + uint8_t RESERVED_6[4]; + __I uint32_t UIDMH; /**< Unique Identification Register Mid-High, offset: 0x1058 */ + __I uint32_t UIDML; /**< Unique Identification Register Mid Low, offset: 0x105C */ + __I uint32_t UIDL; /**< Unique Identification Register Low, offset: 0x1060 */ + uint8_t RESERVED_7[156]; + __IO uint32_t COPC; /**< COP Control Register, offset: 0x1100 */ + __O uint32_t SRVCOP; /**< Service COP, offset: 0x1104 */ +} SIM_Type; + +/* ---------------------------------------------------------------------------- + -- SIM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SIM_Register_Masks SIM Register Masks + * @{ + */ + +/*! @name SOPT1 - System Options Register 1 */ +#define SIM_SOPT1_OSC32KOUT_MASK (0x30000U) +#define SIM_SOPT1_OSC32KOUT_SHIFT (16U) +#define SIM_SOPT1_OSC32KOUT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_OSC32KOUT_SHIFT)) & SIM_SOPT1_OSC32KOUT_MASK) +#define SIM_SOPT1_OSC32KSEL_MASK (0xC0000U) +#define SIM_SOPT1_OSC32KSEL_SHIFT (18U) +#define SIM_SOPT1_OSC32KSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_OSC32KSEL_SHIFT)) & SIM_SOPT1_OSC32KSEL_MASK) +#define SIM_SOPT1_USBVSTBY_MASK (0x20000000U) +#define SIM_SOPT1_USBVSTBY_SHIFT (29U) +#define SIM_SOPT1_USBVSTBY(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBVSTBY_SHIFT)) & SIM_SOPT1_USBVSTBY_MASK) +#define SIM_SOPT1_USBSSTBY_MASK (0x40000000U) +#define SIM_SOPT1_USBSSTBY_SHIFT (30U) +#define SIM_SOPT1_USBSSTBY(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBSSTBY_SHIFT)) & SIM_SOPT1_USBSSTBY_MASK) +#define SIM_SOPT1_USBREGEN_MASK (0x80000000U) +#define SIM_SOPT1_USBREGEN_SHIFT (31U) +#define SIM_SOPT1_USBREGEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBREGEN_SHIFT)) & SIM_SOPT1_USBREGEN_MASK) + +/*! @name SOPT1CFG - SOPT1 Configuration Register */ +#define SIM_SOPT1CFG_URWE_MASK (0x1000000U) +#define SIM_SOPT1CFG_URWE_SHIFT (24U) +#define SIM_SOPT1CFG_URWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_URWE_SHIFT)) & SIM_SOPT1CFG_URWE_MASK) +#define SIM_SOPT1CFG_UVSWE_MASK (0x2000000U) +#define SIM_SOPT1CFG_UVSWE_SHIFT (25U) +#define SIM_SOPT1CFG_UVSWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_UVSWE_SHIFT)) & SIM_SOPT1CFG_UVSWE_MASK) +#define SIM_SOPT1CFG_USSWE_MASK (0x4000000U) +#define SIM_SOPT1CFG_USSWE_SHIFT (26U) +#define SIM_SOPT1CFG_USSWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_USSWE_SHIFT)) & SIM_SOPT1CFG_USSWE_MASK) + +/*! @name SOPT2 - System Options Register 2 */ +#define SIM_SOPT2_RTCCLKOUTSEL_MASK (0x10U) +#define SIM_SOPT2_RTCCLKOUTSEL_SHIFT (4U) +#define SIM_SOPT2_RTCCLKOUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_RTCCLKOUTSEL_SHIFT)) & SIM_SOPT2_RTCCLKOUTSEL_MASK) +#define SIM_SOPT2_CLKOUTSEL_MASK (0xE0U) +#define SIM_SOPT2_CLKOUTSEL_SHIFT (5U) +#define SIM_SOPT2_CLKOUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_CLKOUTSEL_SHIFT)) & SIM_SOPT2_CLKOUTSEL_MASK) +#define SIM_SOPT2_USBSRC_MASK (0x40000U) +#define SIM_SOPT2_USBSRC_SHIFT (18U) +#define SIM_SOPT2_USBSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_USBSRC_SHIFT)) & SIM_SOPT2_USBSRC_MASK) +#define SIM_SOPT2_FLEXIOSRC_MASK (0xC00000U) +#define SIM_SOPT2_FLEXIOSRC_SHIFT (22U) +#define SIM_SOPT2_FLEXIOSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_FLEXIOSRC_SHIFT)) & SIM_SOPT2_FLEXIOSRC_MASK) +#define SIM_SOPT2_TPMSRC_MASK (0x3000000U) +#define SIM_SOPT2_TPMSRC_SHIFT (24U) +#define SIM_SOPT2_TPMSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_TPMSRC_SHIFT)) & SIM_SOPT2_TPMSRC_MASK) +#define SIM_SOPT2_LPUART0SRC_MASK (0xC000000U) +#define SIM_SOPT2_LPUART0SRC_SHIFT (26U) +#define SIM_SOPT2_LPUART0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_LPUART0SRC_SHIFT)) & SIM_SOPT2_LPUART0SRC_MASK) +#define SIM_SOPT2_LPUART1SRC_MASK (0x30000000U) +#define SIM_SOPT2_LPUART1SRC_SHIFT (28U) +#define SIM_SOPT2_LPUART1SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_LPUART1SRC_SHIFT)) & SIM_SOPT2_LPUART1SRC_MASK) + +/*! @name SOPT4 - System Options Register 4 */ +#define SIM_SOPT4_TPM1CH0SRC_MASK (0xC0000U) +#define SIM_SOPT4_TPM1CH0SRC_SHIFT (18U) +#define SIM_SOPT4_TPM1CH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_TPM1CH0SRC_SHIFT)) & SIM_SOPT4_TPM1CH0SRC_MASK) +#define SIM_SOPT4_TPM2CH0SRC_MASK (0x100000U) +#define SIM_SOPT4_TPM2CH0SRC_SHIFT (20U) +#define SIM_SOPT4_TPM2CH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_TPM2CH0SRC_SHIFT)) & SIM_SOPT4_TPM2CH0SRC_MASK) +#define SIM_SOPT4_TPM0CLKSEL_MASK (0x1000000U) +#define SIM_SOPT4_TPM0CLKSEL_SHIFT (24U) +#define SIM_SOPT4_TPM0CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_TPM0CLKSEL_SHIFT)) & SIM_SOPT4_TPM0CLKSEL_MASK) +#define SIM_SOPT4_TPM1CLKSEL_MASK (0x2000000U) +#define SIM_SOPT4_TPM1CLKSEL_SHIFT (25U) +#define SIM_SOPT4_TPM1CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_TPM1CLKSEL_SHIFT)) & SIM_SOPT4_TPM1CLKSEL_MASK) +#define SIM_SOPT4_TPM2CLKSEL_MASK (0x4000000U) +#define SIM_SOPT4_TPM2CLKSEL_SHIFT (26U) +#define SIM_SOPT4_TPM2CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_TPM2CLKSEL_SHIFT)) & SIM_SOPT4_TPM2CLKSEL_MASK) + +/*! @name SOPT5 - System Options Register 5 */ +#define SIM_SOPT5_LPUART0TXSRC_MASK (0x3U) +#define SIM_SOPT5_LPUART0TXSRC_SHIFT (0U) +#define SIM_SOPT5_LPUART0TXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART0TXSRC_SHIFT)) & SIM_SOPT5_LPUART0TXSRC_MASK) +#define SIM_SOPT5_LPUART0RXSRC_MASK (0x4U) +#define SIM_SOPT5_LPUART0RXSRC_SHIFT (2U) +#define SIM_SOPT5_LPUART0RXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART0RXSRC_SHIFT)) & SIM_SOPT5_LPUART0RXSRC_MASK) +#define SIM_SOPT5_LPUART1TXSRC_MASK (0x30U) +#define SIM_SOPT5_LPUART1TXSRC_SHIFT (4U) +#define SIM_SOPT5_LPUART1TXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART1TXSRC_SHIFT)) & SIM_SOPT5_LPUART1TXSRC_MASK) +#define SIM_SOPT5_LPUART1RXSRC_MASK (0x40U) +#define SIM_SOPT5_LPUART1RXSRC_SHIFT (6U) +#define SIM_SOPT5_LPUART1RXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART1RXSRC_SHIFT)) & SIM_SOPT5_LPUART1RXSRC_MASK) +#define SIM_SOPT5_LPUART0ODE_MASK (0x10000U) +#define SIM_SOPT5_LPUART0ODE_SHIFT (16U) +#define SIM_SOPT5_LPUART0ODE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART0ODE_SHIFT)) & SIM_SOPT5_LPUART0ODE_MASK) +#define SIM_SOPT5_LPUART1ODE_MASK (0x20000U) +#define SIM_SOPT5_LPUART1ODE_SHIFT (17U) +#define SIM_SOPT5_LPUART1ODE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_LPUART1ODE_SHIFT)) & SIM_SOPT5_LPUART1ODE_MASK) +#define SIM_SOPT5_UART2ODE_MASK (0x40000U) +#define SIM_SOPT5_UART2ODE_SHIFT (18U) +#define SIM_SOPT5_UART2ODE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_UART2ODE_SHIFT)) & SIM_SOPT5_UART2ODE_MASK) + +/*! @name SOPT7 - System Options Register 7 */ +#define SIM_SOPT7_ADC0TRGSEL_MASK (0xFU) +#define SIM_SOPT7_ADC0TRGSEL_SHIFT (0U) +#define SIM_SOPT7_ADC0TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0TRGSEL_SHIFT)) & SIM_SOPT7_ADC0TRGSEL_MASK) +#define SIM_SOPT7_ADC0PRETRGSEL_MASK (0x10U) +#define SIM_SOPT7_ADC0PRETRGSEL_SHIFT (4U) +#define SIM_SOPT7_ADC0PRETRGSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0PRETRGSEL_SHIFT)) & SIM_SOPT7_ADC0PRETRGSEL_MASK) +#define SIM_SOPT7_ADC0ALTTRGEN_MASK (0x80U) +#define SIM_SOPT7_ADC0ALTTRGEN_SHIFT (7U) +#define SIM_SOPT7_ADC0ALTTRGEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0ALTTRGEN_SHIFT)) & SIM_SOPT7_ADC0ALTTRGEN_MASK) + +/*! @name SDID - System Device Identification Register */ +#define SIM_SDID_PINID_MASK (0xFU) +#define SIM_SDID_PINID_SHIFT (0U) +#define SIM_SDID_PINID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_PINID_SHIFT)) & SIM_SDID_PINID_MASK) +#define SIM_SDID_REVID_MASK (0xF000U) +#define SIM_SDID_REVID_SHIFT (12U) +#define SIM_SDID_REVID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_REVID_SHIFT)) & SIM_SDID_REVID_MASK) +#define SIM_SDID_SRAMSIZE_MASK (0xF0000U) +#define SIM_SDID_SRAMSIZE_SHIFT (16U) +#define SIM_SDID_SRAMSIZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_SRAMSIZE_SHIFT)) & SIM_SDID_SRAMSIZE_MASK) +#define SIM_SDID_SERIESID_MASK (0xF00000U) +#define SIM_SDID_SERIESID_SHIFT (20U) +#define SIM_SDID_SERIESID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_SERIESID_SHIFT)) & SIM_SDID_SERIESID_MASK) +#define SIM_SDID_SUBFAMID_MASK (0xF000000U) +#define SIM_SDID_SUBFAMID_SHIFT (24U) +#define SIM_SDID_SUBFAMID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_SUBFAMID_SHIFT)) & SIM_SDID_SUBFAMID_MASK) +#define SIM_SDID_FAMID_MASK (0xF0000000U) +#define SIM_SDID_FAMID_SHIFT (28U) +#define SIM_SDID_FAMID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_FAMID_SHIFT)) & SIM_SDID_FAMID_MASK) + +/*! @name SCGC4 - System Clock Gating Control Register 4 */ +#define SIM_SCGC4_I2C0_MASK (0x40U) +#define SIM_SCGC4_I2C0_SHIFT (6U) +#define SIM_SCGC4_I2C0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_I2C0_SHIFT)) & SIM_SCGC4_I2C0_MASK) +#define SIM_SCGC4_I2C1_MASK (0x80U) +#define SIM_SCGC4_I2C1_SHIFT (7U) +#define SIM_SCGC4_I2C1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_I2C1_SHIFT)) & SIM_SCGC4_I2C1_MASK) +#define SIM_SCGC4_UART2_MASK (0x1000U) +#define SIM_SCGC4_UART2_SHIFT (12U) +#define SIM_SCGC4_UART2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_UART2_SHIFT)) & SIM_SCGC4_UART2_MASK) +#define SIM_SCGC4_USBFS_MASK (0x40000U) +#define SIM_SCGC4_USBFS_SHIFT (18U) +#define SIM_SCGC4_USBFS(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_USBFS_SHIFT)) & SIM_SCGC4_USBFS_MASK) +#define SIM_SCGC4_CMP0_MASK (0x80000U) +#define SIM_SCGC4_CMP0_SHIFT (19U) +#define SIM_SCGC4_CMP0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_CMP0_SHIFT)) & SIM_SCGC4_CMP0_MASK) +#define SIM_SCGC4_VREF_MASK (0x100000U) +#define SIM_SCGC4_VREF_SHIFT (20U) +#define SIM_SCGC4_VREF(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_VREF_SHIFT)) & SIM_SCGC4_VREF_MASK) +#define SIM_SCGC4_SPI0_MASK (0x400000U) +#define SIM_SCGC4_SPI0_SHIFT (22U) +#define SIM_SCGC4_SPI0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_SPI0_SHIFT)) & SIM_SCGC4_SPI0_MASK) +#define SIM_SCGC4_SPI1_MASK (0x800000U) +#define SIM_SCGC4_SPI1_SHIFT (23U) +#define SIM_SCGC4_SPI1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_SPI1_SHIFT)) & SIM_SCGC4_SPI1_MASK) + +/*! @name SCGC5 - System Clock Gating Control Register 5 */ +#define SIM_SCGC5_LPTMR_MASK (0x1U) +#define SIM_SCGC5_LPTMR_SHIFT (0U) +#define SIM_SCGC5_LPTMR(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_LPTMR_SHIFT)) & SIM_SCGC5_LPTMR_MASK) +#define SIM_SCGC5_PORTA_MASK (0x200U) +#define SIM_SCGC5_PORTA_SHIFT (9U) +#define SIM_SCGC5_PORTA(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTA_SHIFT)) & SIM_SCGC5_PORTA_MASK) +#define SIM_SCGC5_PORTB_MASK (0x400U) +#define SIM_SCGC5_PORTB_SHIFT (10U) +#define SIM_SCGC5_PORTB(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTB_SHIFT)) & SIM_SCGC5_PORTB_MASK) +#define SIM_SCGC5_PORTC_MASK (0x800U) +#define SIM_SCGC5_PORTC_SHIFT (11U) +#define SIM_SCGC5_PORTC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTC_SHIFT)) & SIM_SCGC5_PORTC_MASK) +#define SIM_SCGC5_PORTD_MASK (0x1000U) +#define SIM_SCGC5_PORTD_SHIFT (12U) +#define SIM_SCGC5_PORTD(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTD_SHIFT)) & SIM_SCGC5_PORTD_MASK) +#define SIM_SCGC5_PORTE_MASK (0x2000U) +#define SIM_SCGC5_PORTE_SHIFT (13U) +#define SIM_SCGC5_PORTE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTE_SHIFT)) & SIM_SCGC5_PORTE_MASK) +#define SIM_SCGC5_SLCD_MASK (0x80000U) +#define SIM_SCGC5_SLCD_SHIFT (19U) +#define SIM_SCGC5_SLCD(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_SLCD_SHIFT)) & SIM_SCGC5_SLCD_MASK) +#define SIM_SCGC5_LPUART0_MASK (0x100000U) +#define SIM_SCGC5_LPUART0_SHIFT (20U) +#define SIM_SCGC5_LPUART0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_LPUART0_SHIFT)) & SIM_SCGC5_LPUART0_MASK) +#define SIM_SCGC5_LPUART1_MASK (0x200000U) +#define SIM_SCGC5_LPUART1_SHIFT (21U) +#define SIM_SCGC5_LPUART1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_LPUART1_SHIFT)) & SIM_SCGC5_LPUART1_MASK) +#define SIM_SCGC5_FLEXIO_MASK (0x80000000U) +#define SIM_SCGC5_FLEXIO_SHIFT (31U) +#define SIM_SCGC5_FLEXIO(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_FLEXIO_SHIFT)) & SIM_SCGC5_FLEXIO_MASK) + +/*! @name SCGC6 - System Clock Gating Control Register 6 */ +#define SIM_SCGC6_FTF_MASK (0x1U) +#define SIM_SCGC6_FTF_SHIFT (0U) +#define SIM_SCGC6_FTF(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTF_SHIFT)) & SIM_SCGC6_FTF_MASK) +#define SIM_SCGC6_DMAMUX_MASK (0x2U) +#define SIM_SCGC6_DMAMUX_SHIFT (1U) +#define SIM_SCGC6_DMAMUX(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_DMAMUX_SHIFT)) & SIM_SCGC6_DMAMUX_MASK) +#define SIM_SCGC6_I2S_MASK (0x8000U) +#define SIM_SCGC6_I2S_SHIFT (15U) +#define SIM_SCGC6_I2S(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_I2S_SHIFT)) & SIM_SCGC6_I2S_MASK) +#define SIM_SCGC6_PIT_MASK (0x800000U) +#define SIM_SCGC6_PIT_SHIFT (23U) +#define SIM_SCGC6_PIT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_PIT_SHIFT)) & SIM_SCGC6_PIT_MASK) +#define SIM_SCGC6_TPM0_MASK (0x1000000U) +#define SIM_SCGC6_TPM0_SHIFT (24U) +#define SIM_SCGC6_TPM0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_TPM0_SHIFT)) & SIM_SCGC6_TPM0_MASK) +#define SIM_SCGC6_TPM1_MASK (0x2000000U) +#define SIM_SCGC6_TPM1_SHIFT (25U) +#define SIM_SCGC6_TPM1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_TPM1_SHIFT)) & SIM_SCGC6_TPM1_MASK) +#define SIM_SCGC6_TPM2_MASK (0x4000000U) +#define SIM_SCGC6_TPM2_SHIFT (26U) +#define SIM_SCGC6_TPM2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_TPM2_SHIFT)) & SIM_SCGC6_TPM2_MASK) +#define SIM_SCGC6_ADC0_MASK (0x8000000U) +#define SIM_SCGC6_ADC0_SHIFT (27U) +#define SIM_SCGC6_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_ADC0_SHIFT)) & SIM_SCGC6_ADC0_MASK) +#define SIM_SCGC6_RTC_MASK (0x20000000U) +#define SIM_SCGC6_RTC_SHIFT (29U) +#define SIM_SCGC6_RTC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_RTC_SHIFT)) & SIM_SCGC6_RTC_MASK) +#define SIM_SCGC6_DAC0_MASK (0x80000000U) +#define SIM_SCGC6_DAC0_SHIFT (31U) +#define SIM_SCGC6_DAC0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_DAC0_SHIFT)) & SIM_SCGC6_DAC0_MASK) + +/*! @name SCGC7 - System Clock Gating Control Register 7 */ +#define SIM_SCGC7_DMA_MASK (0x100U) +#define SIM_SCGC7_DMA_SHIFT (8U) +#define SIM_SCGC7_DMA(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC7_DMA_SHIFT)) & SIM_SCGC7_DMA_MASK) + +/*! @name CLKDIV1 - System Clock Divider Register 1 */ +#define SIM_CLKDIV1_OUTDIV4_MASK (0x70000U) +#define SIM_CLKDIV1_OUTDIV4_SHIFT (16U) +#define SIM_CLKDIV1_OUTDIV4(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV4_SHIFT)) & SIM_CLKDIV1_OUTDIV4_MASK) +#define SIM_CLKDIV1_OUTDIV1_MASK (0xF0000000U) +#define SIM_CLKDIV1_OUTDIV1_SHIFT (28U) +#define SIM_CLKDIV1_OUTDIV1(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV1_SHIFT)) & SIM_CLKDIV1_OUTDIV1_MASK) + +/*! @name FCFG1 - Flash Configuration Register 1 */ +#define SIM_FCFG1_FLASHDIS_MASK (0x1U) +#define SIM_FCFG1_FLASHDIS_SHIFT (0U) +#define SIM_FCFG1_FLASHDIS(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_FLASHDIS_SHIFT)) & SIM_FCFG1_FLASHDIS_MASK) +#define SIM_FCFG1_FLASHDOZE_MASK (0x2U) +#define SIM_FCFG1_FLASHDOZE_SHIFT (1U) +#define SIM_FCFG1_FLASHDOZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_FLASHDOZE_SHIFT)) & SIM_FCFG1_FLASHDOZE_MASK) +#define SIM_FCFG1_PFSIZE_MASK (0xF000000U) +#define SIM_FCFG1_PFSIZE_SHIFT (24U) +#define SIM_FCFG1_PFSIZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_PFSIZE_SHIFT)) & SIM_FCFG1_PFSIZE_MASK) + +/*! @name FCFG2 - Flash Configuration Register 2 */ +#define SIM_FCFG2_MAXADDR1_MASK (0x7F0000U) +#define SIM_FCFG2_MAXADDR1_SHIFT (16U) +#define SIM_FCFG2_MAXADDR1(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG2_MAXADDR1_SHIFT)) & SIM_FCFG2_MAXADDR1_MASK) +#define SIM_FCFG2_MAXADDR0_MASK (0x7F000000U) +#define SIM_FCFG2_MAXADDR0_SHIFT (24U) +#define SIM_FCFG2_MAXADDR0(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG2_MAXADDR0_SHIFT)) & SIM_FCFG2_MAXADDR0_MASK) + +/*! @name UIDMH - Unique Identification Register Mid-High */ +#define SIM_UIDMH_UID_MASK (0xFFFFU) +#define SIM_UIDMH_UID_SHIFT (0U) +#define SIM_UIDMH_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDMH_UID_SHIFT)) & SIM_UIDMH_UID_MASK) + +/*! @name UIDML - Unique Identification Register Mid Low */ +#define SIM_UIDML_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDML_UID_SHIFT (0U) +#define SIM_UIDML_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDML_UID_SHIFT)) & SIM_UIDML_UID_MASK) + +/*! @name UIDL - Unique Identification Register Low */ +#define SIM_UIDL_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDL_UID_SHIFT (0U) +#define SIM_UIDL_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDL_UID_SHIFT)) & SIM_UIDL_UID_MASK) + +/*! @name COPC - COP Control Register */ +#define SIM_COPC_COPW_MASK (0x1U) +#define SIM_COPC_COPW_SHIFT (0U) +#define SIM_COPC_COPW(x) (((uint32_t)(((uint32_t)(x)) << SIM_COPC_COPW_SHIFT)) & SIM_COPC_COPW_MASK) +#define SIM_COPC_COPCLKS_MASK (0x2U) +#define SIM_COPC_COPCLKS_SHIFT (1U) +#define SIM_COPC_COPCLKS(x) (((uint32_t)(((uint32_t)(x)) << SIM_COPC_COPCLKS_SHIFT)) & SIM_COPC_COPCLKS_MASK) +#define SIM_COPC_COPT_MASK (0xCU) +#define SIM_COPC_COPT_SHIFT (2U) +#define SIM_COPC_COPT(x) (((uint32_t)(((uint32_t)(x)) << SIM_COPC_COPT_SHIFT)) & SIM_COPC_COPT_MASK) +#define SIM_COPC_COPSTPEN_MASK (0x10U) +#define SIM_COPC_COPSTPEN_SHIFT (4U) +#define SIM_COPC_COPSTPEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_COPC_COPSTPEN_SHIFT)) & SIM_COPC_COPSTPEN_MASK) +#define SIM_COPC_COPDBGEN_MASK (0x20U) +#define SIM_COPC_COPDBGEN_SHIFT (5U) +#define SIM_COPC_COPDBGEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_COPC_COPDBGEN_SHIFT)) & SIM_COPC_COPDBGEN_MASK) +#define SIM_COPC_COPCLKSEL_MASK (0xC0U) +#define SIM_COPC_COPCLKSEL_SHIFT (6U) +#define SIM_COPC_COPCLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_COPC_COPCLKSEL_SHIFT)) & SIM_COPC_COPCLKSEL_MASK) + +/*! @name SRVCOP - Service COP */ +#define SIM_SRVCOP_SRVCOP_MASK (0xFFU) +#define SIM_SRVCOP_SRVCOP_SHIFT (0U) +#define SIM_SRVCOP_SRVCOP(x) (((uint32_t)(((uint32_t)(x)) << SIM_SRVCOP_SRVCOP_SHIFT)) & SIM_SRVCOP_SRVCOP_MASK) + + +/*! + * @} + */ /* end of group SIM_Register_Masks */ + + +/* SIM - Peripheral instance base addresses */ +/** Peripheral SIM base address */ +#define SIM_BASE (0x40047000u) +/** Peripheral SIM base pointer */ +#define SIM ((SIM_Type *)SIM_BASE) +/** Array initializer of SIM peripheral base addresses */ +#define SIM_BASE_ADDRS { SIM_BASE } +/** Array initializer of SIM peripheral base pointers */ +#define SIM_BASE_PTRS { SIM } + +/*! + * @} + */ /* end of group SIM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SMC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SMC_Peripheral_Access_Layer SMC Peripheral Access Layer + * @{ + */ + +/** SMC - Register Layout Typedef */ +typedef struct { + __IO uint8_t PMPROT; /**< Power Mode Protection register, offset: 0x0 */ + __IO uint8_t PMCTRL; /**< Power Mode Control register, offset: 0x1 */ + __IO uint8_t STOPCTRL; /**< Stop Control Register, offset: 0x2 */ + __I uint8_t PMSTAT; /**< Power Mode Status register, offset: 0x3 */ +} SMC_Type; + +/* ---------------------------------------------------------------------------- + -- SMC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SMC_Register_Masks SMC Register Masks + * @{ + */ + +/*! @name PMPROT - Power Mode Protection register */ +#define SMC_PMPROT_AVLLS_MASK (0x2U) +#define SMC_PMPROT_AVLLS_SHIFT (1U) +#define SMC_PMPROT_AVLLS(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_AVLLS_SHIFT)) & SMC_PMPROT_AVLLS_MASK) +#define SMC_PMPROT_ALLS_MASK (0x8U) +#define SMC_PMPROT_ALLS_SHIFT (3U) +#define SMC_PMPROT_ALLS(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_ALLS_SHIFT)) & SMC_PMPROT_ALLS_MASK) +#define SMC_PMPROT_AVLP_MASK (0x20U) +#define SMC_PMPROT_AVLP_SHIFT (5U) +#define SMC_PMPROT_AVLP(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_AVLP_SHIFT)) & SMC_PMPROT_AVLP_MASK) + +/*! @name PMCTRL - Power Mode Control register */ +#define SMC_PMCTRL_STOPM_MASK (0x7U) +#define SMC_PMCTRL_STOPM_SHIFT (0U) +#define SMC_PMCTRL_STOPM(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_STOPM_SHIFT)) & SMC_PMCTRL_STOPM_MASK) +#define SMC_PMCTRL_STOPA_MASK (0x8U) +#define SMC_PMCTRL_STOPA_SHIFT (3U) +#define SMC_PMCTRL_STOPA(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_STOPA_SHIFT)) & SMC_PMCTRL_STOPA_MASK) +#define SMC_PMCTRL_RUNM_MASK (0x60U) +#define SMC_PMCTRL_RUNM_SHIFT (5U) +#define SMC_PMCTRL_RUNM(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_RUNM_SHIFT)) & SMC_PMCTRL_RUNM_MASK) + +/*! @name STOPCTRL - Stop Control Register */ +#define SMC_STOPCTRL_VLLSM_MASK (0x7U) +#define SMC_STOPCTRL_VLLSM_SHIFT (0U) +#define SMC_STOPCTRL_VLLSM(x) (((uint8_t)(((uint8_t)(x)) << SMC_STOPCTRL_VLLSM_SHIFT)) & SMC_STOPCTRL_VLLSM_MASK) +#define SMC_STOPCTRL_PORPO_MASK (0x20U) +#define SMC_STOPCTRL_PORPO_SHIFT (5U) +#define SMC_STOPCTRL_PORPO(x) (((uint8_t)(((uint8_t)(x)) << SMC_STOPCTRL_PORPO_SHIFT)) & SMC_STOPCTRL_PORPO_MASK) +#define SMC_STOPCTRL_PSTOPO_MASK (0xC0U) +#define SMC_STOPCTRL_PSTOPO_SHIFT (6U) +#define SMC_STOPCTRL_PSTOPO(x) (((uint8_t)(((uint8_t)(x)) << SMC_STOPCTRL_PSTOPO_SHIFT)) & SMC_STOPCTRL_PSTOPO_MASK) + +/*! @name PMSTAT - Power Mode Status register */ +#define SMC_PMSTAT_PMSTAT_MASK (0xFFU) +#define SMC_PMSTAT_PMSTAT_SHIFT (0U) +#define SMC_PMSTAT_PMSTAT(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMSTAT_PMSTAT_SHIFT)) & SMC_PMSTAT_PMSTAT_MASK) + + +/*! + * @} + */ /* end of group SMC_Register_Masks */ + + +/* SMC - Peripheral instance base addresses */ +/** Peripheral SMC base address */ +#define SMC_BASE (0x4007E000u) +/** Peripheral SMC base pointer */ +#define SMC ((SMC_Type *)SMC_BASE) +/** Array initializer of SMC peripheral base addresses */ +#define SMC_BASE_ADDRS { SMC_BASE } +/** Array initializer of SMC peripheral base pointers */ +#define SMC_BASE_PTRS { SMC } + +/*! + * @} + */ /* end of group SMC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SPI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Peripheral_Access_Layer SPI Peripheral Access Layer + * @{ + */ + +/** SPI - Register Layout Typedef */ +typedef struct { + __IO uint8_t S; /**< SPI Status Register, offset: 0x0 */ + __IO uint8_t BR; /**< SPI Baud Rate Register, offset: 0x1 */ + __IO uint8_t C2; /**< SPI Control Register 2, offset: 0x2 */ + __IO uint8_t C1; /**< SPI Control Register 1, offset: 0x3 */ + __IO uint8_t ML; /**< SPI Match Register low, offset: 0x4 */ + __IO uint8_t MH; /**< SPI match register high, offset: 0x5 */ + __IO uint8_t DL; /**< SPI Data Register low, offset: 0x6 */ + __IO uint8_t DH; /**< SPI data register high, offset: 0x7 */ + uint8_t RESERVED_0[2]; + __IO uint8_t CI; /**< SPI clear interrupt register, offset: 0xA */ + __IO uint8_t C3; /**< SPI control register 3, offset: 0xB */ +} SPI_Type; + +/* ---------------------------------------------------------------------------- + -- SPI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Register_Masks SPI Register Masks + * @{ + */ + +/*! @name S - SPI Status Register */ +#define SPI_S_RFIFOEF_MASK (0x1U) +#define SPI_S_RFIFOEF_SHIFT (0U) +#define SPI_S_RFIFOEF(x) (((uint8_t)(((uint8_t)(x)) << SPI_S_RFIFOEF_SHIFT)) & SPI_S_RFIFOEF_MASK) +#define SPI_S_TXFULLF_MASK (0x2U) +#define SPI_S_TXFULLF_SHIFT (1U) +#define SPI_S_TXFULLF(x) (((uint8_t)(((uint8_t)(x)) << SPI_S_TXFULLF_SHIFT)) & SPI_S_TXFULLF_MASK) +#define SPI_S_TNEAREF_MASK (0x4U) +#define SPI_S_TNEAREF_SHIFT (2U) +#define SPI_S_TNEAREF(x) (((uint8_t)(((uint8_t)(x)) << SPI_S_TNEAREF_SHIFT)) & SPI_S_TNEAREF_MASK) +#define SPI_S_RNFULLF_MASK (0x8U) +#define SPI_S_RNFULLF_SHIFT (3U) +#define SPI_S_RNFULLF(x) (((uint8_t)(((uint8_t)(x)) << SPI_S_RNFULLF_SHIFT)) & SPI_S_RNFULLF_MASK) +#define SPI_S_MODF_MASK (0x10U) +#define SPI_S_MODF_SHIFT (4U) +#define SPI_S_MODF(x) (((uint8_t)(((uint8_t)(x)) << SPI_S_MODF_SHIFT)) & SPI_S_MODF_MASK) +#define SPI_S_SPTEF_MASK (0x20U) +#define SPI_S_SPTEF_SHIFT (5U) +#define SPI_S_SPTEF(x) (((uint8_t)(((uint8_t)(x)) << SPI_S_SPTEF_SHIFT)) & SPI_S_SPTEF_MASK) +#define SPI_S_SPMF_MASK (0x40U) +#define SPI_S_SPMF_SHIFT (6U) +#define SPI_S_SPMF(x) (((uint8_t)(((uint8_t)(x)) << SPI_S_SPMF_SHIFT)) & SPI_S_SPMF_MASK) +#define SPI_S_SPRF_MASK (0x80U) +#define SPI_S_SPRF_SHIFT (7U) +#define SPI_S_SPRF(x) (((uint8_t)(((uint8_t)(x)) << SPI_S_SPRF_SHIFT)) & SPI_S_SPRF_MASK) + +/*! @name BR - SPI Baud Rate Register */ +#define SPI_BR_SPR_MASK (0xFU) +#define SPI_BR_SPR_SHIFT (0U) +#define SPI_BR_SPR(x) (((uint8_t)(((uint8_t)(x)) << SPI_BR_SPR_SHIFT)) & SPI_BR_SPR_MASK) +#define SPI_BR_SPPR_MASK (0x70U) +#define SPI_BR_SPPR_SHIFT (4U) +#define SPI_BR_SPPR(x) (((uint8_t)(((uint8_t)(x)) << SPI_BR_SPPR_SHIFT)) & SPI_BR_SPPR_MASK) + +/*! @name C2 - SPI Control Register 2 */ +#define SPI_C2_SPC0_MASK (0x1U) +#define SPI_C2_SPC0_SHIFT (0U) +#define SPI_C2_SPC0(x) (((uint8_t)(((uint8_t)(x)) << SPI_C2_SPC0_SHIFT)) & SPI_C2_SPC0_MASK) +#define SPI_C2_SPISWAI_MASK (0x2U) +#define SPI_C2_SPISWAI_SHIFT (1U) +#define SPI_C2_SPISWAI(x) (((uint8_t)(((uint8_t)(x)) << SPI_C2_SPISWAI_SHIFT)) & SPI_C2_SPISWAI_MASK) +#define SPI_C2_RXDMAE_MASK (0x4U) +#define SPI_C2_RXDMAE_SHIFT (2U) +#define SPI_C2_RXDMAE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C2_RXDMAE_SHIFT)) & SPI_C2_RXDMAE_MASK) +#define SPI_C2_BIDIROE_MASK (0x8U) +#define SPI_C2_BIDIROE_SHIFT (3U) +#define SPI_C2_BIDIROE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C2_BIDIROE_SHIFT)) & SPI_C2_BIDIROE_MASK) +#define SPI_C2_MODFEN_MASK (0x10U) +#define SPI_C2_MODFEN_SHIFT (4U) +#define SPI_C2_MODFEN(x) (((uint8_t)(((uint8_t)(x)) << SPI_C2_MODFEN_SHIFT)) & SPI_C2_MODFEN_MASK) +#define SPI_C2_TXDMAE_MASK (0x20U) +#define SPI_C2_TXDMAE_SHIFT (5U) +#define SPI_C2_TXDMAE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C2_TXDMAE_SHIFT)) & SPI_C2_TXDMAE_MASK) +#define SPI_C2_SPIMODE_MASK (0x40U) +#define SPI_C2_SPIMODE_SHIFT (6U) +#define SPI_C2_SPIMODE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C2_SPIMODE_SHIFT)) & SPI_C2_SPIMODE_MASK) +#define SPI_C2_SPMIE_MASK (0x80U) +#define SPI_C2_SPMIE_SHIFT (7U) +#define SPI_C2_SPMIE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C2_SPMIE_SHIFT)) & SPI_C2_SPMIE_MASK) + +/*! @name C1 - SPI Control Register 1 */ +#define SPI_C1_LSBFE_MASK (0x1U) +#define SPI_C1_LSBFE_SHIFT (0U) +#define SPI_C1_LSBFE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C1_LSBFE_SHIFT)) & SPI_C1_LSBFE_MASK) +#define SPI_C1_SSOE_MASK (0x2U) +#define SPI_C1_SSOE_SHIFT (1U) +#define SPI_C1_SSOE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C1_SSOE_SHIFT)) & SPI_C1_SSOE_MASK) +#define SPI_C1_CPHA_MASK (0x4U) +#define SPI_C1_CPHA_SHIFT (2U) +#define SPI_C1_CPHA(x) (((uint8_t)(((uint8_t)(x)) << SPI_C1_CPHA_SHIFT)) & SPI_C1_CPHA_MASK) +#define SPI_C1_CPOL_MASK (0x8U) +#define SPI_C1_CPOL_SHIFT (3U) +#define SPI_C1_CPOL(x) (((uint8_t)(((uint8_t)(x)) << SPI_C1_CPOL_SHIFT)) & SPI_C1_CPOL_MASK) +#define SPI_C1_MSTR_MASK (0x10U) +#define SPI_C1_MSTR_SHIFT (4U) +#define SPI_C1_MSTR(x) (((uint8_t)(((uint8_t)(x)) << SPI_C1_MSTR_SHIFT)) & SPI_C1_MSTR_MASK) +#define SPI_C1_SPTIE_MASK (0x20U) +#define SPI_C1_SPTIE_SHIFT (5U) +#define SPI_C1_SPTIE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C1_SPTIE_SHIFT)) & SPI_C1_SPTIE_MASK) +#define SPI_C1_SPE_MASK (0x40U) +#define SPI_C1_SPE_SHIFT (6U) +#define SPI_C1_SPE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C1_SPE_SHIFT)) & SPI_C1_SPE_MASK) +#define SPI_C1_SPIE_MASK (0x80U) +#define SPI_C1_SPIE_SHIFT (7U) +#define SPI_C1_SPIE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C1_SPIE_SHIFT)) & SPI_C1_SPIE_MASK) + +/*! @name ML - SPI Match Register low */ +#define SPI_ML_Bits_MASK (0xFFU) +#define SPI_ML_Bits_SHIFT (0U) +#define SPI_ML_Bits(x) (((uint8_t)(((uint8_t)(x)) << SPI_ML_Bits_SHIFT)) & SPI_ML_Bits_MASK) + +/*! @name MH - SPI match register high */ +#define SPI_MH_Bits_MASK (0xFFU) +#define SPI_MH_Bits_SHIFT (0U) +#define SPI_MH_Bits(x) (((uint8_t)(((uint8_t)(x)) << SPI_MH_Bits_SHIFT)) & SPI_MH_Bits_MASK) + +/*! @name DL - SPI Data Register low */ +#define SPI_DL_Bits_MASK (0xFFU) +#define SPI_DL_Bits_SHIFT (0U) +#define SPI_DL_Bits(x) (((uint8_t)(((uint8_t)(x)) << SPI_DL_Bits_SHIFT)) & SPI_DL_Bits_MASK) + +/*! @name DH - SPI data register high */ +#define SPI_DH_Bits_MASK (0xFFU) +#define SPI_DH_Bits_SHIFT (0U) +#define SPI_DH_Bits(x) (((uint8_t)(((uint8_t)(x)) << SPI_DH_Bits_SHIFT)) & SPI_DH_Bits_MASK) + +/*! @name CI - SPI clear interrupt register */ +#define SPI_CI_SPRFCI_MASK (0x1U) +#define SPI_CI_SPRFCI_SHIFT (0U) +#define SPI_CI_SPRFCI(x) (((uint8_t)(((uint8_t)(x)) << SPI_CI_SPRFCI_SHIFT)) & SPI_CI_SPRFCI_MASK) +#define SPI_CI_SPTEFCI_MASK (0x2U) +#define SPI_CI_SPTEFCI_SHIFT (1U) +#define SPI_CI_SPTEFCI(x) (((uint8_t)(((uint8_t)(x)) << SPI_CI_SPTEFCI_SHIFT)) & SPI_CI_SPTEFCI_MASK) +#define SPI_CI_RNFULLFCI_MASK (0x4U) +#define SPI_CI_RNFULLFCI_SHIFT (2U) +#define SPI_CI_RNFULLFCI(x) (((uint8_t)(((uint8_t)(x)) << SPI_CI_RNFULLFCI_SHIFT)) & SPI_CI_RNFULLFCI_MASK) +#define SPI_CI_TNEAREFCI_MASK (0x8U) +#define SPI_CI_TNEAREFCI_SHIFT (3U) +#define SPI_CI_TNEAREFCI(x) (((uint8_t)(((uint8_t)(x)) << SPI_CI_TNEAREFCI_SHIFT)) & SPI_CI_TNEAREFCI_MASK) +#define SPI_CI_RXFOF_MASK (0x10U) +#define SPI_CI_RXFOF_SHIFT (4U) +#define SPI_CI_RXFOF(x) (((uint8_t)(((uint8_t)(x)) << SPI_CI_RXFOF_SHIFT)) & SPI_CI_RXFOF_MASK) +#define SPI_CI_TXFOF_MASK (0x20U) +#define SPI_CI_TXFOF_SHIFT (5U) +#define SPI_CI_TXFOF(x) (((uint8_t)(((uint8_t)(x)) << SPI_CI_TXFOF_SHIFT)) & SPI_CI_TXFOF_MASK) +#define SPI_CI_RXFERR_MASK (0x40U) +#define SPI_CI_RXFERR_SHIFT (6U) +#define SPI_CI_RXFERR(x) (((uint8_t)(((uint8_t)(x)) << SPI_CI_RXFERR_SHIFT)) & SPI_CI_RXFERR_MASK) +#define SPI_CI_TXFERR_MASK (0x80U) +#define SPI_CI_TXFERR_SHIFT (7U) +#define SPI_CI_TXFERR(x) (((uint8_t)(((uint8_t)(x)) << SPI_CI_TXFERR_SHIFT)) & SPI_CI_TXFERR_MASK) + +/*! @name C3 - SPI control register 3 */ +#define SPI_C3_FIFOMODE_MASK (0x1U) +#define SPI_C3_FIFOMODE_SHIFT (0U) +#define SPI_C3_FIFOMODE(x) (((uint8_t)(((uint8_t)(x)) << SPI_C3_FIFOMODE_SHIFT)) & SPI_C3_FIFOMODE_MASK) +#define SPI_C3_RNFULLIEN_MASK (0x2U) +#define SPI_C3_RNFULLIEN_SHIFT (1U) +#define SPI_C3_RNFULLIEN(x) (((uint8_t)(((uint8_t)(x)) << SPI_C3_RNFULLIEN_SHIFT)) & SPI_C3_RNFULLIEN_MASK) +#define SPI_C3_TNEARIEN_MASK (0x4U) +#define SPI_C3_TNEARIEN_SHIFT (2U) +#define SPI_C3_TNEARIEN(x) (((uint8_t)(((uint8_t)(x)) << SPI_C3_TNEARIEN_SHIFT)) & SPI_C3_TNEARIEN_MASK) +#define SPI_C3_INTCLR_MASK (0x8U) +#define SPI_C3_INTCLR_SHIFT (3U) +#define SPI_C3_INTCLR(x) (((uint8_t)(((uint8_t)(x)) << SPI_C3_INTCLR_SHIFT)) & SPI_C3_INTCLR_MASK) +#define SPI_C3_RNFULLF_MARK_MASK (0x10U) +#define SPI_C3_RNFULLF_MARK_SHIFT (4U) +#define SPI_C3_RNFULLF_MARK(x) (((uint8_t)(((uint8_t)(x)) << SPI_C3_RNFULLF_MARK_SHIFT)) & SPI_C3_RNFULLF_MARK_MASK) +#define SPI_C3_TNEAREF_MARK_MASK (0x20U) +#define SPI_C3_TNEAREF_MARK_SHIFT (5U) +#define SPI_C3_TNEAREF_MARK(x) (((uint8_t)(((uint8_t)(x)) << SPI_C3_TNEAREF_MARK_SHIFT)) & SPI_C3_TNEAREF_MARK_MASK) + + +/*! + * @} + */ /* end of group SPI_Register_Masks */ + + +/* SPI - Peripheral instance base addresses */ +/** Peripheral SPI0 base address */ +#define SPI0_BASE (0x40076000u) +/** Peripheral SPI0 base pointer */ +#define SPI0 ((SPI_Type *)SPI0_BASE) +/** Peripheral SPI1 base address */ +#define SPI1_BASE (0x40077000u) +/** Peripheral SPI1 base pointer */ +#define SPI1 ((SPI_Type *)SPI1_BASE) +/** Array initializer of SPI peripheral base addresses */ +#define SPI_BASE_ADDRS { SPI0_BASE, SPI1_BASE } +/** Array initializer of SPI peripheral base pointers */ +#define SPI_BASE_PTRS { SPI0, SPI1 } +/** Interrupt vectors for the SPI peripheral type */ +#define SPI_IRQS { SPI0_IRQn, SPI1_IRQn } + +/*! + * @} + */ /* end of group SPI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- TPM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup TPM_Peripheral_Access_Layer TPM Peripheral Access Layer + * @{ + */ + +/** TPM - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC; /**< Status and Control, offset: 0x0 */ + __IO uint32_t CNT; /**< Counter, offset: 0x4 */ + __IO uint32_t MOD; /**< Modulo, offset: 0x8 */ + struct { /* offset: 0xC, array step: 0x8 */ + __IO uint32_t CnSC; /**< Channel (n) Status and Control, array offset: 0xC, array step: 0x8 */ + __IO uint32_t CnV; /**< Channel (n) Value, array offset: 0x10, array step: 0x8 */ + } CONTROLS[6]; + uint8_t RESERVED_0[20]; + __IO uint32_t STATUS; /**< Capture and Compare Status, offset: 0x50 */ + uint8_t RESERVED_1[28]; + __IO uint32_t POL; /**< Channel Polarity, offset: 0x70 */ + uint8_t RESERVED_2[16]; + __IO uint32_t CONF; /**< Configuration, offset: 0x84 */ +} TPM_Type; + +/* ---------------------------------------------------------------------------- + -- TPM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup TPM_Register_Masks TPM Register Masks + * @{ + */ + +/*! @name SC - Status and Control */ +#define TPM_SC_PS_MASK (0x7U) +#define TPM_SC_PS_SHIFT (0U) +#define TPM_SC_PS(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_PS_SHIFT)) & TPM_SC_PS_MASK) +#define TPM_SC_CMOD_MASK (0x18U) +#define TPM_SC_CMOD_SHIFT (3U) +#define TPM_SC_CMOD(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_CMOD_SHIFT)) & TPM_SC_CMOD_MASK) +#define TPM_SC_CPWMS_MASK (0x20U) +#define TPM_SC_CPWMS_SHIFT (5U) +#define TPM_SC_CPWMS(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_CPWMS_SHIFT)) & TPM_SC_CPWMS_MASK) +#define TPM_SC_TOIE_MASK (0x40U) +#define TPM_SC_TOIE_SHIFT (6U) +#define TPM_SC_TOIE(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_TOIE_SHIFT)) & TPM_SC_TOIE_MASK) +#define TPM_SC_TOF_MASK (0x80U) +#define TPM_SC_TOF_SHIFT (7U) +#define TPM_SC_TOF(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_TOF_SHIFT)) & TPM_SC_TOF_MASK) +#define TPM_SC_DMA_MASK (0x100U) +#define TPM_SC_DMA_SHIFT (8U) +#define TPM_SC_DMA(x) (((uint32_t)(((uint32_t)(x)) << TPM_SC_DMA_SHIFT)) & TPM_SC_DMA_MASK) + +/*! @name CNT - Counter */ +#define TPM_CNT_COUNT_MASK (0xFFFFU) +#define TPM_CNT_COUNT_SHIFT (0U) +#define TPM_CNT_COUNT(x) (((uint32_t)(((uint32_t)(x)) << TPM_CNT_COUNT_SHIFT)) & TPM_CNT_COUNT_MASK) + +/*! @name MOD - Modulo */ +#define TPM_MOD_MOD_MASK (0xFFFFU) +#define TPM_MOD_MOD_SHIFT (0U) +#define TPM_MOD_MOD(x) (((uint32_t)(((uint32_t)(x)) << TPM_MOD_MOD_SHIFT)) & TPM_MOD_MOD_MASK) + +/*! @name CnSC - Channel (n) Status and Control */ +#define TPM_CnSC_DMA_MASK (0x1U) +#define TPM_CnSC_DMA_SHIFT (0U) +#define TPM_CnSC_DMA(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_DMA_SHIFT)) & TPM_CnSC_DMA_MASK) +#define TPM_CnSC_ELSA_MASK (0x4U) +#define TPM_CnSC_ELSA_SHIFT (2U) +#define TPM_CnSC_ELSA(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_ELSA_SHIFT)) & TPM_CnSC_ELSA_MASK) +#define TPM_CnSC_ELSB_MASK (0x8U) +#define TPM_CnSC_ELSB_SHIFT (3U) +#define TPM_CnSC_ELSB(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_ELSB_SHIFT)) & TPM_CnSC_ELSB_MASK) +#define TPM_CnSC_MSA_MASK (0x10U) +#define TPM_CnSC_MSA_SHIFT (4U) +#define TPM_CnSC_MSA(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_MSA_SHIFT)) & TPM_CnSC_MSA_MASK) +#define TPM_CnSC_MSB_MASK (0x20U) +#define TPM_CnSC_MSB_SHIFT (5U) +#define TPM_CnSC_MSB(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_MSB_SHIFT)) & TPM_CnSC_MSB_MASK) +#define TPM_CnSC_CHIE_MASK (0x40U) +#define TPM_CnSC_CHIE_SHIFT (6U) +#define TPM_CnSC_CHIE(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_CHIE_SHIFT)) & TPM_CnSC_CHIE_MASK) +#define TPM_CnSC_CHF_MASK (0x80U) +#define TPM_CnSC_CHF_SHIFT (7U) +#define TPM_CnSC_CHF(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnSC_CHF_SHIFT)) & TPM_CnSC_CHF_MASK) + +/* The count of TPM_CnSC */ +#define TPM_CnSC_COUNT (6U) + +/*! @name CnV - Channel (n) Value */ +#define TPM_CnV_VAL_MASK (0xFFFFU) +#define TPM_CnV_VAL_SHIFT (0U) +#define TPM_CnV_VAL(x) (((uint32_t)(((uint32_t)(x)) << TPM_CnV_VAL_SHIFT)) & TPM_CnV_VAL_MASK) + +/* The count of TPM_CnV */ +#define TPM_CnV_COUNT (6U) + +/*! @name STATUS - Capture and Compare Status */ +#define TPM_STATUS_CH0F_MASK (0x1U) +#define TPM_STATUS_CH0F_SHIFT (0U) +#define TPM_STATUS_CH0F(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_CH0F_SHIFT)) & TPM_STATUS_CH0F_MASK) +#define TPM_STATUS_CH1F_MASK (0x2U) +#define TPM_STATUS_CH1F_SHIFT (1U) +#define TPM_STATUS_CH1F(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_CH1F_SHIFT)) & TPM_STATUS_CH1F_MASK) +#define TPM_STATUS_CH2F_MASK (0x4U) +#define TPM_STATUS_CH2F_SHIFT (2U) +#define TPM_STATUS_CH2F(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_CH2F_SHIFT)) & TPM_STATUS_CH2F_MASK) +#define TPM_STATUS_CH3F_MASK (0x8U) +#define TPM_STATUS_CH3F_SHIFT (3U) +#define TPM_STATUS_CH3F(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_CH3F_SHIFT)) & TPM_STATUS_CH3F_MASK) +#define TPM_STATUS_CH4F_MASK (0x10U) +#define TPM_STATUS_CH4F_SHIFT (4U) +#define TPM_STATUS_CH4F(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_CH4F_SHIFT)) & TPM_STATUS_CH4F_MASK) +#define TPM_STATUS_CH5F_MASK (0x20U) +#define TPM_STATUS_CH5F_SHIFT (5U) +#define TPM_STATUS_CH5F(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_CH5F_SHIFT)) & TPM_STATUS_CH5F_MASK) +#define TPM_STATUS_TOF_MASK (0x100U) +#define TPM_STATUS_TOF_SHIFT (8U) +#define TPM_STATUS_TOF(x) (((uint32_t)(((uint32_t)(x)) << TPM_STATUS_TOF_SHIFT)) & TPM_STATUS_TOF_MASK) + +/*! @name POL - Channel Polarity */ +#define TPM_POL_POL0_MASK (0x1U) +#define TPM_POL_POL0_SHIFT (0U) +#define TPM_POL_POL0(x) (((uint32_t)(((uint32_t)(x)) << TPM_POL_POL0_SHIFT)) & TPM_POL_POL0_MASK) +#define TPM_POL_POL1_MASK (0x2U) +#define TPM_POL_POL1_SHIFT (1U) +#define TPM_POL_POL1(x) (((uint32_t)(((uint32_t)(x)) << TPM_POL_POL1_SHIFT)) & TPM_POL_POL1_MASK) +#define TPM_POL_POL2_MASK (0x4U) +#define TPM_POL_POL2_SHIFT (2U) +#define TPM_POL_POL2(x) (((uint32_t)(((uint32_t)(x)) << TPM_POL_POL2_SHIFT)) & TPM_POL_POL2_MASK) +#define TPM_POL_POL3_MASK (0x8U) +#define TPM_POL_POL3_SHIFT (3U) +#define TPM_POL_POL3(x) (((uint32_t)(((uint32_t)(x)) << TPM_POL_POL3_SHIFT)) & TPM_POL_POL3_MASK) +#define TPM_POL_POL4_MASK (0x10U) +#define TPM_POL_POL4_SHIFT (4U) +#define TPM_POL_POL4(x) (((uint32_t)(((uint32_t)(x)) << TPM_POL_POL4_SHIFT)) & TPM_POL_POL4_MASK) +#define TPM_POL_POL5_MASK (0x20U) +#define TPM_POL_POL5_SHIFT (5U) +#define TPM_POL_POL5(x) (((uint32_t)(((uint32_t)(x)) << TPM_POL_POL5_SHIFT)) & TPM_POL_POL5_MASK) + +/*! @name CONF - Configuration */ +#define TPM_CONF_DOZEEN_MASK (0x20U) +#define TPM_CONF_DOZEEN_SHIFT (5U) +#define TPM_CONF_DOZEEN(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_DOZEEN_SHIFT)) & TPM_CONF_DOZEEN_MASK) +#define TPM_CONF_DBGMODE_MASK (0xC0U) +#define TPM_CONF_DBGMODE_SHIFT (6U) +#define TPM_CONF_DBGMODE(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_DBGMODE_SHIFT)) & TPM_CONF_DBGMODE_MASK) +#define TPM_CONF_GTBSYNC_MASK (0x100U) +#define TPM_CONF_GTBSYNC_SHIFT (8U) +#define TPM_CONF_GTBSYNC(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_GTBSYNC_SHIFT)) & TPM_CONF_GTBSYNC_MASK) +#define TPM_CONF_GTBEEN_MASK (0x200U) +#define TPM_CONF_GTBEEN_SHIFT (9U) +#define TPM_CONF_GTBEEN(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_GTBEEN_SHIFT)) & TPM_CONF_GTBEEN_MASK) +#define TPM_CONF_CSOT_MASK (0x10000U) +#define TPM_CONF_CSOT_SHIFT (16U) +#define TPM_CONF_CSOT(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_CSOT_SHIFT)) & TPM_CONF_CSOT_MASK) +#define TPM_CONF_CSOO_MASK (0x20000U) +#define TPM_CONF_CSOO_SHIFT (17U) +#define TPM_CONF_CSOO(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_CSOO_SHIFT)) & TPM_CONF_CSOO_MASK) +#define TPM_CONF_CROT_MASK (0x40000U) +#define TPM_CONF_CROT_SHIFT (18U) +#define TPM_CONF_CROT(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_CROT_SHIFT)) & TPM_CONF_CROT_MASK) +#define TPM_CONF_CPOT_MASK (0x80000U) +#define TPM_CONF_CPOT_SHIFT (19U) +#define TPM_CONF_CPOT(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_CPOT_SHIFT)) & TPM_CONF_CPOT_MASK) +#define TPM_CONF_TRGPOL_MASK (0x400000U) +#define TPM_CONF_TRGPOL_SHIFT (22U) +#define TPM_CONF_TRGPOL(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_TRGPOL_SHIFT)) & TPM_CONF_TRGPOL_MASK) +#define TPM_CONF_TRGSRC_MASK (0x800000U) +#define TPM_CONF_TRGSRC_SHIFT (23U) +#define TPM_CONF_TRGSRC(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_TRGSRC_SHIFT)) & TPM_CONF_TRGSRC_MASK) +#define TPM_CONF_TRGSEL_MASK (0xF000000U) +#define TPM_CONF_TRGSEL_SHIFT (24U) +#define TPM_CONF_TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << TPM_CONF_TRGSEL_SHIFT)) & TPM_CONF_TRGSEL_MASK) + + +/*! + * @} + */ /* end of group TPM_Register_Masks */ + + +/* TPM - Peripheral instance base addresses */ +/** Peripheral TPM0 base address */ +#define TPM0_BASE (0x40038000u) +/** Peripheral TPM0 base pointer */ +#define TPM0 ((TPM_Type *)TPM0_BASE) +/** Peripheral TPM1 base address */ +#define TPM1_BASE (0x40039000u) +/** Peripheral TPM1 base pointer */ +#define TPM1 ((TPM_Type *)TPM1_BASE) +/** Peripheral TPM2 base address */ +#define TPM2_BASE (0x4003A000u) +/** Peripheral TPM2 base pointer */ +#define TPM2 ((TPM_Type *)TPM2_BASE) +/** Array initializer of TPM peripheral base addresses */ +#define TPM_BASE_ADDRS { TPM0_BASE, TPM1_BASE, TPM2_BASE } +/** Array initializer of TPM peripheral base pointers */ +#define TPM_BASE_PTRS { TPM0, TPM1, TPM2 } +/** Interrupt vectors for the TPM peripheral type */ +#define TPM_IRQS { TPM0_IRQn, TPM1_IRQn, TPM2_IRQn } + +/*! + * @} + */ /* end of group TPM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- UART Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UART_Peripheral_Access_Layer UART Peripheral Access Layer + * @{ + */ + +/** UART - Register Layout Typedef */ +typedef struct { + __IO uint8_t BDH; /**< UART Baud Rate Registers: High, offset: 0x0 */ + __IO uint8_t BDL; /**< UART Baud Rate Registers: Low, offset: 0x1 */ + __IO uint8_t C1; /**< UART Control Register 1, offset: 0x2 */ + __IO uint8_t C2; /**< UART Control Register 2, offset: 0x3 */ + __I uint8_t S1; /**< UART Status Register 1, offset: 0x4 */ + __IO uint8_t S2; /**< UART Status Register 2, offset: 0x5 */ + __IO uint8_t C3; /**< UART Control Register 3, offset: 0x6 */ + __IO uint8_t D; /**< UART Data Register, offset: 0x7 */ + __IO uint8_t MA1; /**< UART Match Address Registers 1, offset: 0x8 */ + __IO uint8_t MA2; /**< UART Match Address Registers 2, offset: 0x9 */ + __IO uint8_t C4; /**< UART Control Register 4, offset: 0xA */ + __IO uint8_t C5; /**< UART Control Register 5, offset: 0xB */ + uint8_t RESERVED_0[12]; + __IO uint8_t C7816; /**< UART 7816 Control Register, offset: 0x18 */ + __IO uint8_t IE7816; /**< UART 7816 Interrupt Enable Register, offset: 0x19 */ + __IO uint8_t IS7816; /**< UART 7816 Interrupt Status Register, offset: 0x1A */ + __IO uint8_t WP7816; /**< UART 7816 Wait Parameter Register, offset: 0x1B */ + __IO uint8_t WN7816; /**< UART 7816 Wait N Register, offset: 0x1C */ + __IO uint8_t WF7816; /**< UART 7816 Wait FD Register, offset: 0x1D */ + __IO uint8_t ET7816; /**< UART 7816 Error Threshold Register, offset: 0x1E */ + __IO uint8_t TL7816; /**< UART 7816 Transmit Length Register, offset: 0x1F */ + uint8_t RESERVED_1[26]; + __IO uint8_t AP7816A_T0; /**< UART 7816 ATR Duration Timer Register A, offset: 0x3A */ + __IO uint8_t AP7816B_T0; /**< UART 7816 ATR Duration Timer Register B, offset: 0x3B */ + union { /* offset: 0x3C */ + struct { /* offset: 0x3C */ + __IO uint8_t WP7816A_T0; /**< UART 7816 Wait Parameter Register A, offset: 0x3C */ + __IO uint8_t WP7816B_T0; /**< UART 7816 Wait Parameter Register B, offset: 0x3D */ + } TYPE0; + struct { /* offset: 0x3C */ + __IO uint8_t WP7816A_T1; /**< UART 7816 Wait Parameter Register A, offset: 0x3C */ + __IO uint8_t WP7816B_T1; /**< UART 7816 Wait Parameter Register B, offset: 0x3D */ + } TYPE1; + }; + __IO uint8_t WGP7816_T1; /**< UART 7816 Wait and Guard Parameter Register, offset: 0x3E */ + __IO uint8_t WP7816C_T1; /**< UART 7816 Wait Parameter Register C, offset: 0x3F */ +} UART_Type; + +/* ---------------------------------------------------------------------------- + -- UART Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UART_Register_Masks UART Register Masks + * @{ + */ + +/*! @name BDH - UART Baud Rate Registers: High */ +#define UART_BDH_SBR_MASK (0x1FU) +#define UART_BDH_SBR_SHIFT (0U) +#define UART_BDH_SBR(x) (((uint8_t)(((uint8_t)(x)) << UART_BDH_SBR_SHIFT)) & UART_BDH_SBR_MASK) +#define UART_BDH_RXEDGIE_MASK (0x40U) +#define UART_BDH_RXEDGIE_SHIFT (6U) +#define UART_BDH_RXEDGIE(x) (((uint8_t)(((uint8_t)(x)) << UART_BDH_RXEDGIE_SHIFT)) & UART_BDH_RXEDGIE_MASK) + +/*! @name BDL - UART Baud Rate Registers: Low */ +#define UART_BDL_SBR_MASK (0xFFU) +#define UART_BDL_SBR_SHIFT (0U) +#define UART_BDL_SBR(x) (((uint8_t)(((uint8_t)(x)) << UART_BDL_SBR_SHIFT)) & UART_BDL_SBR_MASK) + +/*! @name C1 - UART Control Register 1 */ +#define UART_C1_PT_MASK (0x1U) +#define UART_C1_PT_SHIFT (0U) +#define UART_C1_PT(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_PT_SHIFT)) & UART_C1_PT_MASK) +#define UART_C1_PE_MASK (0x2U) +#define UART_C1_PE_SHIFT (1U) +#define UART_C1_PE(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_PE_SHIFT)) & UART_C1_PE_MASK) +#define UART_C1_ILT_MASK (0x4U) +#define UART_C1_ILT_SHIFT (2U) +#define UART_C1_ILT(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_ILT_SHIFT)) & UART_C1_ILT_MASK) +#define UART_C1_WAKE_MASK (0x8U) +#define UART_C1_WAKE_SHIFT (3U) +#define UART_C1_WAKE(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_WAKE_SHIFT)) & UART_C1_WAKE_MASK) +#define UART_C1_M_MASK (0x10U) +#define UART_C1_M_SHIFT (4U) +#define UART_C1_M(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_M_SHIFT)) & UART_C1_M_MASK) +#define UART_C1_RSRC_MASK (0x20U) +#define UART_C1_RSRC_SHIFT (5U) +#define UART_C1_RSRC(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_RSRC_SHIFT)) & UART_C1_RSRC_MASK) +#define UART_C1_LOOPS_MASK (0x80U) +#define UART_C1_LOOPS_SHIFT (7U) +#define UART_C1_LOOPS(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_LOOPS_SHIFT)) & UART_C1_LOOPS_MASK) + +/*! @name C2 - UART Control Register 2 */ +#define UART_C2_SBK_MASK (0x1U) +#define UART_C2_SBK_SHIFT (0U) +#define UART_C2_SBK(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_SBK_SHIFT)) & UART_C2_SBK_MASK) +#define UART_C2_RWU_MASK (0x2U) +#define UART_C2_RWU_SHIFT (1U) +#define UART_C2_RWU(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_RWU_SHIFT)) & UART_C2_RWU_MASK) +#define UART_C2_RE_MASK (0x4U) +#define UART_C2_RE_SHIFT (2U) +#define UART_C2_RE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_RE_SHIFT)) & UART_C2_RE_MASK) +#define UART_C2_TE_MASK (0x8U) +#define UART_C2_TE_SHIFT (3U) +#define UART_C2_TE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_TE_SHIFT)) & UART_C2_TE_MASK) +#define UART_C2_ILIE_MASK (0x10U) +#define UART_C2_ILIE_SHIFT (4U) +#define UART_C2_ILIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_ILIE_SHIFT)) & UART_C2_ILIE_MASK) +#define UART_C2_RIE_MASK (0x20U) +#define UART_C2_RIE_SHIFT (5U) +#define UART_C2_RIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_RIE_SHIFT)) & UART_C2_RIE_MASK) +#define UART_C2_TCIE_MASK (0x40U) +#define UART_C2_TCIE_SHIFT (6U) +#define UART_C2_TCIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_TCIE_SHIFT)) & UART_C2_TCIE_MASK) +#define UART_C2_TIE_MASK (0x80U) +#define UART_C2_TIE_SHIFT (7U) +#define UART_C2_TIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_TIE_SHIFT)) & UART_C2_TIE_MASK) + +/*! @name S1 - UART Status Register 1 */ +#define UART_S1_PF_MASK (0x1U) +#define UART_S1_PF_SHIFT (0U) +#define UART_S1_PF(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_PF_SHIFT)) & UART_S1_PF_MASK) +#define UART_S1_FE_MASK (0x2U) +#define UART_S1_FE_SHIFT (1U) +#define UART_S1_FE(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_FE_SHIFT)) & UART_S1_FE_MASK) +#define UART_S1_NF_MASK (0x4U) +#define UART_S1_NF_SHIFT (2U) +#define UART_S1_NF(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_NF_SHIFT)) & UART_S1_NF_MASK) +#define UART_S1_OR_MASK (0x8U) +#define UART_S1_OR_SHIFT (3U) +#define UART_S1_OR(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_OR_SHIFT)) & UART_S1_OR_MASK) +#define UART_S1_IDLE_MASK (0x10U) +#define UART_S1_IDLE_SHIFT (4U) +#define UART_S1_IDLE(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_IDLE_SHIFT)) & UART_S1_IDLE_MASK) +#define UART_S1_RDRF_MASK (0x20U) +#define UART_S1_RDRF_SHIFT (5U) +#define UART_S1_RDRF(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_RDRF_SHIFT)) & UART_S1_RDRF_MASK) +#define UART_S1_TC_MASK (0x40U) +#define UART_S1_TC_SHIFT (6U) +#define UART_S1_TC(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_TC_SHIFT)) & UART_S1_TC_MASK) +#define UART_S1_TDRE_MASK (0x80U) +#define UART_S1_TDRE_SHIFT (7U) +#define UART_S1_TDRE(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_TDRE_SHIFT)) & UART_S1_TDRE_MASK) + +/*! @name S2 - UART Status Register 2 */ +#define UART_S2_RAF_MASK (0x1U) +#define UART_S2_RAF_SHIFT (0U) +#define UART_S2_RAF(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_RAF_SHIFT)) & UART_S2_RAF_MASK) +#define UART_S2_BRK13_MASK (0x4U) +#define UART_S2_BRK13_SHIFT (2U) +#define UART_S2_BRK13(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_BRK13_SHIFT)) & UART_S2_BRK13_MASK) +#define UART_S2_RWUID_MASK (0x8U) +#define UART_S2_RWUID_SHIFT (3U) +#define UART_S2_RWUID(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_RWUID_SHIFT)) & UART_S2_RWUID_MASK) +#define UART_S2_RXINV_MASK (0x10U) +#define UART_S2_RXINV_SHIFT (4U) +#define UART_S2_RXINV(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_RXINV_SHIFT)) & UART_S2_RXINV_MASK) +#define UART_S2_MSBF_MASK (0x20U) +#define UART_S2_MSBF_SHIFT (5U) +#define UART_S2_MSBF(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_MSBF_SHIFT)) & UART_S2_MSBF_MASK) +#define UART_S2_RXEDGIF_MASK (0x40U) +#define UART_S2_RXEDGIF_SHIFT (6U) +#define UART_S2_RXEDGIF(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_RXEDGIF_SHIFT)) & UART_S2_RXEDGIF_MASK) + +/*! @name C3 - UART Control Register 3 */ +#define UART_C3_PEIE_MASK (0x1U) +#define UART_C3_PEIE_SHIFT (0U) +#define UART_C3_PEIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_PEIE_SHIFT)) & UART_C3_PEIE_MASK) +#define UART_C3_FEIE_MASK (0x2U) +#define UART_C3_FEIE_SHIFT (1U) +#define UART_C3_FEIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_FEIE_SHIFT)) & UART_C3_FEIE_MASK) +#define UART_C3_NEIE_MASK (0x4U) +#define UART_C3_NEIE_SHIFT (2U) +#define UART_C3_NEIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_NEIE_SHIFT)) & UART_C3_NEIE_MASK) +#define UART_C3_ORIE_MASK (0x8U) +#define UART_C3_ORIE_SHIFT (3U) +#define UART_C3_ORIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_ORIE_SHIFT)) & UART_C3_ORIE_MASK) +#define UART_C3_TXINV_MASK (0x10U) +#define UART_C3_TXINV_SHIFT (4U) +#define UART_C3_TXINV(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_TXINV_SHIFT)) & UART_C3_TXINV_MASK) +#define UART_C3_TXDIR_MASK (0x20U) +#define UART_C3_TXDIR_SHIFT (5U) +#define UART_C3_TXDIR(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_TXDIR_SHIFT)) & UART_C3_TXDIR_MASK) +#define UART_C3_T8_MASK (0x40U) +#define UART_C3_T8_SHIFT (6U) +#define UART_C3_T8(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_T8_SHIFT)) & UART_C3_T8_MASK) +#define UART_C3_R8_MASK (0x80U) +#define UART_C3_R8_SHIFT (7U) +#define UART_C3_R8(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_R8_SHIFT)) & UART_C3_R8_MASK) + +/*! @name D - UART Data Register */ +#define UART_D_RT_MASK (0xFFU) +#define UART_D_RT_SHIFT (0U) +#define UART_D_RT(x) (((uint8_t)(((uint8_t)(x)) << UART_D_RT_SHIFT)) & UART_D_RT_MASK) + +/*! @name MA1 - UART Match Address Registers 1 */ +#define UART_MA1_MA_MASK (0xFFU) +#define UART_MA1_MA_SHIFT (0U) +#define UART_MA1_MA(x) (((uint8_t)(((uint8_t)(x)) << UART_MA1_MA_SHIFT)) & UART_MA1_MA_MASK) + +/*! @name MA2 - UART Match Address Registers 2 */ +#define UART_MA2_MA_MASK (0xFFU) +#define UART_MA2_MA_SHIFT (0U) +#define UART_MA2_MA(x) (((uint8_t)(((uint8_t)(x)) << UART_MA2_MA_SHIFT)) & UART_MA2_MA_MASK) + +/*! @name C4 - UART Control Register 4 */ +#define UART_C4_BRFA_MASK (0x1FU) +#define UART_C4_BRFA_SHIFT (0U) +#define UART_C4_BRFA(x) (((uint8_t)(((uint8_t)(x)) << UART_C4_BRFA_SHIFT)) & UART_C4_BRFA_MASK) +#define UART_C4_M10_MASK (0x20U) +#define UART_C4_M10_SHIFT (5U) +#define UART_C4_M10(x) (((uint8_t)(((uint8_t)(x)) << UART_C4_M10_SHIFT)) & UART_C4_M10_MASK) +#define UART_C4_MAEN2_MASK (0x40U) +#define UART_C4_MAEN2_SHIFT (6U) +#define UART_C4_MAEN2(x) (((uint8_t)(((uint8_t)(x)) << UART_C4_MAEN2_SHIFT)) & UART_C4_MAEN2_MASK) +#define UART_C4_MAEN1_MASK (0x80U) +#define UART_C4_MAEN1_SHIFT (7U) +#define UART_C4_MAEN1(x) (((uint8_t)(((uint8_t)(x)) << UART_C4_MAEN1_SHIFT)) & UART_C4_MAEN1_MASK) + +/*! @name C5 - UART Control Register 5 */ +#define UART_C5_RDMAS_MASK (0x20U) +#define UART_C5_RDMAS_SHIFT (5U) +#define UART_C5_RDMAS(x) (((uint8_t)(((uint8_t)(x)) << UART_C5_RDMAS_SHIFT)) & UART_C5_RDMAS_MASK) +#define UART_C5_TDMAS_MASK (0x80U) +#define UART_C5_TDMAS_SHIFT (7U) +#define UART_C5_TDMAS(x) (((uint8_t)(((uint8_t)(x)) << UART_C5_TDMAS_SHIFT)) & UART_C5_TDMAS_MASK) + +/*! @name C7816 - UART 7816 Control Register */ +#define UART_C7816_ISO_7816E_MASK (0x1U) +#define UART_C7816_ISO_7816E_SHIFT (0U) +#define UART_C7816_ISO_7816E(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_ISO_7816E_SHIFT)) & UART_C7816_ISO_7816E_MASK) +#define UART_C7816_TTYPE_MASK (0x2U) +#define UART_C7816_TTYPE_SHIFT (1U) +#define UART_C7816_TTYPE(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_TTYPE_SHIFT)) & UART_C7816_TTYPE_MASK) +#define UART_C7816_INIT_MASK (0x4U) +#define UART_C7816_INIT_SHIFT (2U) +#define UART_C7816_INIT(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_INIT_SHIFT)) & UART_C7816_INIT_MASK) +#define UART_C7816_ANACK_MASK (0x8U) +#define UART_C7816_ANACK_SHIFT (3U) +#define UART_C7816_ANACK(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_ANACK_SHIFT)) & UART_C7816_ANACK_MASK) +#define UART_C7816_ONACK_MASK (0x10U) +#define UART_C7816_ONACK_SHIFT (4U) +#define UART_C7816_ONACK(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_ONACK_SHIFT)) & UART_C7816_ONACK_MASK) + +/*! @name IE7816 - UART 7816 Interrupt Enable Register */ +#define UART_IE7816_RXTE_MASK (0x1U) +#define UART_IE7816_RXTE_SHIFT (0U) +#define UART_IE7816_RXTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_RXTE_SHIFT)) & UART_IE7816_RXTE_MASK) +#define UART_IE7816_TXTE_MASK (0x2U) +#define UART_IE7816_TXTE_SHIFT (1U) +#define UART_IE7816_TXTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_TXTE_SHIFT)) & UART_IE7816_TXTE_MASK) +#define UART_IE7816_GTVE_MASK (0x4U) +#define UART_IE7816_GTVE_SHIFT (2U) +#define UART_IE7816_GTVE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_GTVE_SHIFT)) & UART_IE7816_GTVE_MASK) +#define UART_IE7816_ADTE_MASK (0x8U) +#define UART_IE7816_ADTE_SHIFT (3U) +#define UART_IE7816_ADTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_ADTE_SHIFT)) & UART_IE7816_ADTE_MASK) +#define UART_IE7816_INITDE_MASK (0x10U) +#define UART_IE7816_INITDE_SHIFT (4U) +#define UART_IE7816_INITDE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_INITDE_SHIFT)) & UART_IE7816_INITDE_MASK) +#define UART_IE7816_BWTE_MASK (0x20U) +#define UART_IE7816_BWTE_SHIFT (5U) +#define UART_IE7816_BWTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_BWTE_SHIFT)) & UART_IE7816_BWTE_MASK) +#define UART_IE7816_CWTE_MASK (0x40U) +#define UART_IE7816_CWTE_SHIFT (6U) +#define UART_IE7816_CWTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_CWTE_SHIFT)) & UART_IE7816_CWTE_MASK) +#define UART_IE7816_WTE_MASK (0x80U) +#define UART_IE7816_WTE_SHIFT (7U) +#define UART_IE7816_WTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_WTE_SHIFT)) & UART_IE7816_WTE_MASK) + +/*! @name IS7816 - UART 7816 Interrupt Status Register */ +#define UART_IS7816_RXT_MASK (0x1U) +#define UART_IS7816_RXT_SHIFT (0U) +#define UART_IS7816_RXT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_RXT_SHIFT)) & UART_IS7816_RXT_MASK) +#define UART_IS7816_TXT_MASK (0x2U) +#define UART_IS7816_TXT_SHIFT (1U) +#define UART_IS7816_TXT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_TXT_SHIFT)) & UART_IS7816_TXT_MASK) +#define UART_IS7816_GTV_MASK (0x4U) +#define UART_IS7816_GTV_SHIFT (2U) +#define UART_IS7816_GTV(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_GTV_SHIFT)) & UART_IS7816_GTV_MASK) +#define UART_IS7816_ADT_MASK (0x8U) +#define UART_IS7816_ADT_SHIFT (3U) +#define UART_IS7816_ADT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_ADT_SHIFT)) & UART_IS7816_ADT_MASK) +#define UART_IS7816_INITD_MASK (0x10U) +#define UART_IS7816_INITD_SHIFT (4U) +#define UART_IS7816_INITD(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_INITD_SHIFT)) & UART_IS7816_INITD_MASK) +#define UART_IS7816_BWT_MASK (0x20U) +#define UART_IS7816_BWT_SHIFT (5U) +#define UART_IS7816_BWT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_BWT_SHIFT)) & UART_IS7816_BWT_MASK) +#define UART_IS7816_CWT_MASK (0x40U) +#define UART_IS7816_CWT_SHIFT (6U) +#define UART_IS7816_CWT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_CWT_SHIFT)) & UART_IS7816_CWT_MASK) +#define UART_IS7816_WT_MASK (0x80U) +#define UART_IS7816_WT_SHIFT (7U) +#define UART_IS7816_WT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_WT_SHIFT)) & UART_IS7816_WT_MASK) + +/*! @name WP7816 - UART 7816 Wait Parameter Register */ +#define UART_WP7816_WTX_MASK (0xFFU) +#define UART_WP7816_WTX_SHIFT (0U) +#define UART_WP7816_WTX(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816_WTX_SHIFT)) & UART_WP7816_WTX_MASK) + +/*! @name WN7816 - UART 7816 Wait N Register */ +#define UART_WN7816_GTN_MASK (0xFFU) +#define UART_WN7816_GTN_SHIFT (0U) +#define UART_WN7816_GTN(x) (((uint8_t)(((uint8_t)(x)) << UART_WN7816_GTN_SHIFT)) & UART_WN7816_GTN_MASK) + +/*! @name WF7816 - UART 7816 Wait FD Register */ +#define UART_WF7816_GTFD_MASK (0xFFU) +#define UART_WF7816_GTFD_SHIFT (0U) +#define UART_WF7816_GTFD(x) (((uint8_t)(((uint8_t)(x)) << UART_WF7816_GTFD_SHIFT)) & UART_WF7816_GTFD_MASK) + +/*! @name ET7816 - UART 7816 Error Threshold Register */ +#define UART_ET7816_RXTHRESHOLD_MASK (0xFU) +#define UART_ET7816_RXTHRESHOLD_SHIFT (0U) +#define UART_ET7816_RXTHRESHOLD(x) (((uint8_t)(((uint8_t)(x)) << UART_ET7816_RXTHRESHOLD_SHIFT)) & UART_ET7816_RXTHRESHOLD_MASK) +#define UART_ET7816_TXTHRESHOLD_MASK (0xF0U) +#define UART_ET7816_TXTHRESHOLD_SHIFT (4U) +#define UART_ET7816_TXTHRESHOLD(x) (((uint8_t)(((uint8_t)(x)) << UART_ET7816_TXTHRESHOLD_SHIFT)) & UART_ET7816_TXTHRESHOLD_MASK) + +/*! @name TL7816 - UART 7816 Transmit Length Register */ +#define UART_TL7816_TLEN_MASK (0xFFU) +#define UART_TL7816_TLEN_SHIFT (0U) +#define UART_TL7816_TLEN(x) (((uint8_t)(((uint8_t)(x)) << UART_TL7816_TLEN_SHIFT)) & UART_TL7816_TLEN_MASK) + +/*! @name AP7816A_T0 - UART 7816 ATR Duration Timer Register A */ +#define UART_AP7816A_T0_ADTI_H_MASK (0xFFU) +#define UART_AP7816A_T0_ADTI_H_SHIFT (0U) +#define UART_AP7816A_T0_ADTI_H(x) (((uint8_t)(((uint8_t)(x)) << UART_AP7816A_T0_ADTI_H_SHIFT)) & UART_AP7816A_T0_ADTI_H_MASK) + +/*! @name AP7816B_T0 - UART 7816 ATR Duration Timer Register B */ +#define UART_AP7816B_T0_ADTI_L_MASK (0xFFU) +#define UART_AP7816B_T0_ADTI_L_SHIFT (0U) +#define UART_AP7816B_T0_ADTI_L(x) (((uint8_t)(((uint8_t)(x)) << UART_AP7816B_T0_ADTI_L_SHIFT)) & UART_AP7816B_T0_ADTI_L_MASK) + +/*! @name WP7816A_T0 - UART 7816 Wait Parameter Register A */ +#define UART_WP7816A_T0_WI_H_MASK (0xFFU) +#define UART_WP7816A_T0_WI_H_SHIFT (0U) +#define UART_WP7816A_T0_WI_H(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816A_T0_WI_H_SHIFT)) & UART_WP7816A_T0_WI_H_MASK) + +/*! @name WP7816B_T0 - UART 7816 Wait Parameter Register B */ +#define UART_WP7816B_T0_WI_L_MASK (0xFFU) +#define UART_WP7816B_T0_WI_L_SHIFT (0U) +#define UART_WP7816B_T0_WI_L(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816B_T0_WI_L_SHIFT)) & UART_WP7816B_T0_WI_L_MASK) + +/*! @name WP7816A_T1 - UART 7816 Wait Parameter Register A */ +#define UART_WP7816A_T1_BWI_H_MASK (0xFFU) +#define UART_WP7816A_T1_BWI_H_SHIFT (0U) +#define UART_WP7816A_T1_BWI_H(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816A_T1_BWI_H_SHIFT)) & UART_WP7816A_T1_BWI_H_MASK) + +/*! @name WP7816B_T1 - UART 7816 Wait Parameter Register B */ +#define UART_WP7816B_T1_BWI_L_MASK (0xFFU) +#define UART_WP7816B_T1_BWI_L_SHIFT (0U) +#define UART_WP7816B_T1_BWI_L(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816B_T1_BWI_L_SHIFT)) & UART_WP7816B_T1_BWI_L_MASK) + +/*! @name WGP7816_T1 - UART 7816 Wait and Guard Parameter Register */ +#define UART_WGP7816_T1_BGI_MASK (0xFU) +#define UART_WGP7816_T1_BGI_SHIFT (0U) +#define UART_WGP7816_T1_BGI(x) (((uint8_t)(((uint8_t)(x)) << UART_WGP7816_T1_BGI_SHIFT)) & UART_WGP7816_T1_BGI_MASK) +#define UART_WGP7816_T1_CWI1_MASK (0xF0U) +#define UART_WGP7816_T1_CWI1_SHIFT (4U) +#define UART_WGP7816_T1_CWI1(x) (((uint8_t)(((uint8_t)(x)) << UART_WGP7816_T1_CWI1_SHIFT)) & UART_WGP7816_T1_CWI1_MASK) + +/*! @name WP7816C_T1 - UART 7816 Wait Parameter Register C */ +#define UART_WP7816C_T1_CWI2_MASK (0x1FU) +#define UART_WP7816C_T1_CWI2_SHIFT (0U) +#define UART_WP7816C_T1_CWI2(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816C_T1_CWI2_SHIFT)) & UART_WP7816C_T1_CWI2_MASK) + + +/*! + * @} + */ /* end of group UART_Register_Masks */ + + +/* UART - Peripheral instance base addresses */ +/** Peripheral UART2 base address */ +#define UART2_BASE (0x4006C000u) +/** Peripheral UART2 base pointer */ +#define UART2 ((UART_Type *)UART2_BASE) +/** Array initializer of UART peripheral base addresses */ +#define UART_BASE_ADDRS { 0u, 0u, UART2_BASE } +/** Array initializer of UART peripheral base pointers */ +#define UART_BASE_PTRS { (UART_Type *)0u, (UART_Type *)0u, UART2 } +/** Interrupt vectors for the UART peripheral type */ +#define UART_RX_TX_IRQS { NotAvail_IRQn, NotAvail_IRQn, UART2_FLEXIO_IRQn } +#define UART_ERR_IRQS { NotAvail_IRQn, NotAvail_IRQn, UART2_FLEXIO_IRQn } + +/*! + * @} + */ /* end of group UART_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USB_Peripheral_Access_Layer USB Peripheral Access Layer + * @{ + */ + +/** USB - Register Layout Typedef */ +typedef struct { + __I uint8_t PERID; /**< Peripheral ID register, offset: 0x0 */ + uint8_t RESERVED_0[3]; + __I uint8_t IDCOMP; /**< Peripheral ID Complement register, offset: 0x4 */ + uint8_t RESERVED_1[3]; + __I uint8_t REV; /**< Peripheral Revision register, offset: 0x8 */ + uint8_t RESERVED_2[3]; + __I uint8_t ADDINFO; /**< Peripheral Additional Info register, offset: 0xC */ + uint8_t RESERVED_3[15]; + __IO uint8_t OTGCTL; /**< OTG Control register, offset: 0x1C */ + uint8_t RESERVED_4[99]; + __IO uint8_t ISTAT; /**< Interrupt Status register, offset: 0x80 */ + uint8_t RESERVED_5[3]; + __IO uint8_t INTEN; /**< Interrupt Enable register, offset: 0x84 */ + uint8_t RESERVED_6[3]; + __IO uint8_t ERRSTAT; /**< Error Interrupt Status register, offset: 0x88 */ + uint8_t RESERVED_7[3]; + __IO uint8_t ERREN; /**< Error Interrupt Enable register, offset: 0x8C */ + uint8_t RESERVED_8[3]; + __I uint8_t STAT; /**< Status register, offset: 0x90 */ + uint8_t RESERVED_9[3]; + __IO uint8_t CTL; /**< Control register, offset: 0x94 */ + uint8_t RESERVED_10[3]; + __IO uint8_t ADDR; /**< Address register, offset: 0x98 */ + uint8_t RESERVED_11[3]; + __IO uint8_t BDTPAGE1; /**< BDT Page register 1, offset: 0x9C */ + uint8_t RESERVED_12[3]; + __IO uint8_t FRMNUML; /**< Frame Number register Low, offset: 0xA0 */ + uint8_t RESERVED_13[3]; + __IO uint8_t FRMNUMH; /**< Frame Number register High, offset: 0xA4 */ + uint8_t RESERVED_14[11]; + __IO uint8_t BDTPAGE2; /**< BDT Page Register 2, offset: 0xB0 */ + uint8_t RESERVED_15[3]; + __IO uint8_t BDTPAGE3; /**< BDT Page Register 3, offset: 0xB4 */ + uint8_t RESERVED_16[11]; + struct { /* offset: 0xC0, array step: 0x4 */ + __IO uint8_t ENDPT; /**< Endpoint Control register, array offset: 0xC0, array step: 0x4 */ + uint8_t RESERVED_0[3]; + } ENDPOINT[16]; + __IO uint8_t USBCTRL; /**< USB Control register, offset: 0x100 */ + uint8_t RESERVED_17[3]; + __I uint8_t OBSERVE; /**< USB OTG Observe register, offset: 0x104 */ + uint8_t RESERVED_18[3]; + __IO uint8_t CONTROL; /**< USB OTG Control register, offset: 0x108 */ + uint8_t RESERVED_19[3]; + __IO uint8_t USBTRC0; /**< USB Transceiver Control register 0, offset: 0x10C */ + uint8_t RESERVED_20[7]; + __IO uint8_t USBFRMADJUST; /**< Frame Adjust Register, offset: 0x114 */ + uint8_t RESERVED_21[43]; + __IO uint8_t CLK_RECOVER_CTRL; /**< USB Clock recovery control, offset: 0x140 */ + uint8_t RESERVED_22[3]; + __IO uint8_t CLK_RECOVER_IRC_EN; /**< IRC48M oscillator enable register, offset: 0x144 */ + uint8_t RESERVED_23[15]; + __IO uint8_t CLK_RECOVER_INT_EN; /**< Clock recovery combined interrupt enable, offset: 0x154 */ + uint8_t RESERVED_24[7]; + __IO uint8_t CLK_RECOVER_INT_STATUS; /**< Clock recovery separated interrupt status, offset: 0x15C */ +} USB_Type; + +/* ---------------------------------------------------------------------------- + -- USB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USB_Register_Masks USB Register Masks + * @{ + */ + +/*! @name PERID - Peripheral ID register */ +#define USB_PERID_ID_MASK (0x3FU) +#define USB_PERID_ID_SHIFT (0U) +#define USB_PERID_ID(x) (((uint8_t)(((uint8_t)(x)) << USB_PERID_ID_SHIFT)) & USB_PERID_ID_MASK) + +/*! @name IDCOMP - Peripheral ID Complement register */ +#define USB_IDCOMP_NID_MASK (0x3FU) +#define USB_IDCOMP_NID_SHIFT (0U) +#define USB_IDCOMP_NID(x) (((uint8_t)(((uint8_t)(x)) << USB_IDCOMP_NID_SHIFT)) & USB_IDCOMP_NID_MASK) + +/*! @name REV - Peripheral Revision register */ +#define USB_REV_REV_MASK (0xFFU) +#define USB_REV_REV_SHIFT (0U) +#define USB_REV_REV(x) (((uint8_t)(((uint8_t)(x)) << USB_REV_REV_SHIFT)) & USB_REV_REV_MASK) + +/*! @name ADDINFO - Peripheral Additional Info register */ +#define USB_ADDINFO_IEHOST_MASK (0x1U) +#define USB_ADDINFO_IEHOST_SHIFT (0U) +#define USB_ADDINFO_IEHOST(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDINFO_IEHOST_SHIFT)) & USB_ADDINFO_IEHOST_MASK) + +/*! @name OTGCTL - OTG Control register */ +#define USB_OTGCTL_DPHIGH_MASK (0x80U) +#define USB_OTGCTL_DPHIGH_SHIFT (7U) +#define USB_OTGCTL_DPHIGH(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DPHIGH_SHIFT)) & USB_OTGCTL_DPHIGH_MASK) + +/*! @name ISTAT - Interrupt Status register */ +#define USB_ISTAT_USBRST_MASK (0x1U) +#define USB_ISTAT_USBRST_SHIFT (0U) +#define USB_ISTAT_USBRST(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_USBRST_SHIFT)) & USB_ISTAT_USBRST_MASK) +#define USB_ISTAT_ERROR_MASK (0x2U) +#define USB_ISTAT_ERROR_SHIFT (1U) +#define USB_ISTAT_ERROR(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_ERROR_SHIFT)) & USB_ISTAT_ERROR_MASK) +#define USB_ISTAT_SOFTOK_MASK (0x4U) +#define USB_ISTAT_SOFTOK_SHIFT (2U) +#define USB_ISTAT_SOFTOK(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_SOFTOK_SHIFT)) & USB_ISTAT_SOFTOK_MASK) +#define USB_ISTAT_TOKDNE_MASK (0x8U) +#define USB_ISTAT_TOKDNE_SHIFT (3U) +#define USB_ISTAT_TOKDNE(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_TOKDNE_SHIFT)) & USB_ISTAT_TOKDNE_MASK) +#define USB_ISTAT_SLEEP_MASK (0x10U) +#define USB_ISTAT_SLEEP_SHIFT (4U) +#define USB_ISTAT_SLEEP(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_SLEEP_SHIFT)) & USB_ISTAT_SLEEP_MASK) +#define USB_ISTAT_RESUME_MASK (0x20U) +#define USB_ISTAT_RESUME_SHIFT (5U) +#define USB_ISTAT_RESUME(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_RESUME_SHIFT)) & USB_ISTAT_RESUME_MASK) +#define USB_ISTAT_STALL_MASK (0x80U) +#define USB_ISTAT_STALL_SHIFT (7U) +#define USB_ISTAT_STALL(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_STALL_SHIFT)) & USB_ISTAT_STALL_MASK) + +/*! @name INTEN - Interrupt Enable register */ +#define USB_INTEN_USBRSTEN_MASK (0x1U) +#define USB_INTEN_USBRSTEN_SHIFT (0U) +#define USB_INTEN_USBRSTEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_USBRSTEN_SHIFT)) & USB_INTEN_USBRSTEN_MASK) +#define USB_INTEN_ERROREN_MASK (0x2U) +#define USB_INTEN_ERROREN_SHIFT (1U) +#define USB_INTEN_ERROREN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_ERROREN_SHIFT)) & USB_INTEN_ERROREN_MASK) +#define USB_INTEN_SOFTOKEN_MASK (0x4U) +#define USB_INTEN_SOFTOKEN_SHIFT (2U) +#define USB_INTEN_SOFTOKEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_SOFTOKEN_SHIFT)) & USB_INTEN_SOFTOKEN_MASK) +#define USB_INTEN_TOKDNEEN_MASK (0x8U) +#define USB_INTEN_TOKDNEEN_SHIFT (3U) +#define USB_INTEN_TOKDNEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_TOKDNEEN_SHIFT)) & USB_INTEN_TOKDNEEN_MASK) +#define USB_INTEN_SLEEPEN_MASK (0x10U) +#define USB_INTEN_SLEEPEN_SHIFT (4U) +#define USB_INTEN_SLEEPEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_SLEEPEN_SHIFT)) & USB_INTEN_SLEEPEN_MASK) +#define USB_INTEN_RESUMEEN_MASK (0x20U) +#define USB_INTEN_RESUMEEN_SHIFT (5U) +#define USB_INTEN_RESUMEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_RESUMEEN_SHIFT)) & USB_INTEN_RESUMEEN_MASK) +#define USB_INTEN_STALLEN_MASK (0x80U) +#define USB_INTEN_STALLEN_SHIFT (7U) +#define USB_INTEN_STALLEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_STALLEN_SHIFT)) & USB_INTEN_STALLEN_MASK) + +/*! @name ERRSTAT - Error Interrupt Status register */ +#define USB_ERRSTAT_PIDERR_MASK (0x1U) +#define USB_ERRSTAT_PIDERR_SHIFT (0U) +#define USB_ERRSTAT_PIDERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_PIDERR_SHIFT)) & USB_ERRSTAT_PIDERR_MASK) +#define USB_ERRSTAT_CRC5_MASK (0x2U) +#define USB_ERRSTAT_CRC5_SHIFT (1U) +#define USB_ERRSTAT_CRC5(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_CRC5_SHIFT)) & USB_ERRSTAT_CRC5_MASK) +#define USB_ERRSTAT_CRC16_MASK (0x4U) +#define USB_ERRSTAT_CRC16_SHIFT (2U) +#define USB_ERRSTAT_CRC16(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_CRC16_SHIFT)) & USB_ERRSTAT_CRC16_MASK) +#define USB_ERRSTAT_DFN8_MASK (0x8U) +#define USB_ERRSTAT_DFN8_SHIFT (3U) +#define USB_ERRSTAT_DFN8(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_DFN8_SHIFT)) & USB_ERRSTAT_DFN8_MASK) +#define USB_ERRSTAT_BTOERR_MASK (0x10U) +#define USB_ERRSTAT_BTOERR_SHIFT (4U) +#define USB_ERRSTAT_BTOERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_BTOERR_SHIFT)) & USB_ERRSTAT_BTOERR_MASK) +#define USB_ERRSTAT_DMAERR_MASK (0x20U) +#define USB_ERRSTAT_DMAERR_SHIFT (5U) +#define USB_ERRSTAT_DMAERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_DMAERR_SHIFT)) & USB_ERRSTAT_DMAERR_MASK) +#define USB_ERRSTAT_BTSERR_MASK (0x80U) +#define USB_ERRSTAT_BTSERR_SHIFT (7U) +#define USB_ERRSTAT_BTSERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_BTSERR_SHIFT)) & USB_ERRSTAT_BTSERR_MASK) + +/*! @name ERREN - Error Interrupt Enable register */ +#define USB_ERREN_PIDERREN_MASK (0x1U) +#define USB_ERREN_PIDERREN_SHIFT (0U) +#define USB_ERREN_PIDERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_PIDERREN_SHIFT)) & USB_ERREN_PIDERREN_MASK) +#define USB_ERREN_CRC5EOFEN_MASK (0x2U) +#define USB_ERREN_CRC5EOFEN_SHIFT (1U) +#define USB_ERREN_CRC5EOFEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_CRC5EOFEN_SHIFT)) & USB_ERREN_CRC5EOFEN_MASK) +#define USB_ERREN_CRC16EN_MASK (0x4U) +#define USB_ERREN_CRC16EN_SHIFT (2U) +#define USB_ERREN_CRC16EN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_CRC16EN_SHIFT)) & USB_ERREN_CRC16EN_MASK) +#define USB_ERREN_DFN8EN_MASK (0x8U) +#define USB_ERREN_DFN8EN_SHIFT (3U) +#define USB_ERREN_DFN8EN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_DFN8EN_SHIFT)) & USB_ERREN_DFN8EN_MASK) +#define USB_ERREN_BTOERREN_MASK (0x10U) +#define USB_ERREN_BTOERREN_SHIFT (4U) +#define USB_ERREN_BTOERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_BTOERREN_SHIFT)) & USB_ERREN_BTOERREN_MASK) +#define USB_ERREN_DMAERREN_MASK (0x20U) +#define USB_ERREN_DMAERREN_SHIFT (5U) +#define USB_ERREN_DMAERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_DMAERREN_SHIFT)) & USB_ERREN_DMAERREN_MASK) +#define USB_ERREN_BTSERREN_MASK (0x80U) +#define USB_ERREN_BTSERREN_SHIFT (7U) +#define USB_ERREN_BTSERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_BTSERREN_SHIFT)) & USB_ERREN_BTSERREN_MASK) + +/*! @name STAT - Status register */ +#define USB_STAT_ODD_MASK (0x4U) +#define USB_STAT_ODD_SHIFT (2U) +#define USB_STAT_ODD(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_ODD_SHIFT)) & USB_STAT_ODD_MASK) +#define USB_STAT_TX_MASK (0x8U) +#define USB_STAT_TX_SHIFT (3U) +#define USB_STAT_TX(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_TX_SHIFT)) & USB_STAT_TX_MASK) +#define USB_STAT_ENDP_MASK (0xF0U) +#define USB_STAT_ENDP_SHIFT (4U) +#define USB_STAT_ENDP(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_ENDP_SHIFT)) & USB_STAT_ENDP_MASK) + +/*! @name CTL - Control register */ +#define USB_CTL_USBENSOFEN_MASK (0x1U) +#define USB_CTL_USBENSOFEN_SHIFT (0U) +#define USB_CTL_USBENSOFEN(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_USBENSOFEN_SHIFT)) & USB_CTL_USBENSOFEN_MASK) +#define USB_CTL_ODDRST_MASK (0x2U) +#define USB_CTL_ODDRST_SHIFT (1U) +#define USB_CTL_ODDRST(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_ODDRST_SHIFT)) & USB_CTL_ODDRST_MASK) +#define USB_CTL_TXSUSPENDTOKENBUSY_MASK (0x20U) +#define USB_CTL_TXSUSPENDTOKENBUSY_SHIFT (5U) +#define USB_CTL_TXSUSPENDTOKENBUSY(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_TXSUSPENDTOKENBUSY_SHIFT)) & USB_CTL_TXSUSPENDTOKENBUSY_MASK) +#define USB_CTL_SE0_MASK (0x40U) +#define USB_CTL_SE0_SHIFT (6U) +#define USB_CTL_SE0(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_SE0_SHIFT)) & USB_CTL_SE0_MASK) +#define USB_CTL_JSTATE_MASK (0x80U) +#define USB_CTL_JSTATE_SHIFT (7U) +#define USB_CTL_JSTATE(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_JSTATE_SHIFT)) & USB_CTL_JSTATE_MASK) + +/*! @name ADDR - Address register */ +#define USB_ADDR_ADDR_MASK (0x7FU) +#define USB_ADDR_ADDR_SHIFT (0U) +#define USB_ADDR_ADDR(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDR_ADDR_SHIFT)) & USB_ADDR_ADDR_MASK) + +/*! @name BDTPAGE1 - BDT Page register 1 */ +#define USB_BDTPAGE1_BDTBA_MASK (0xFEU) +#define USB_BDTPAGE1_BDTBA_SHIFT (1U) +#define USB_BDTPAGE1_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE1_BDTBA_SHIFT)) & USB_BDTPAGE1_BDTBA_MASK) + +/*! @name FRMNUML - Frame Number register Low */ +#define USB_FRMNUML_FRM_MASK (0xFFU) +#define USB_FRMNUML_FRM_SHIFT (0U) +#define USB_FRMNUML_FRM(x) (((uint8_t)(((uint8_t)(x)) << USB_FRMNUML_FRM_SHIFT)) & USB_FRMNUML_FRM_MASK) + +/*! @name FRMNUMH - Frame Number register High */ +#define USB_FRMNUMH_FRM_MASK (0x7U) +#define USB_FRMNUMH_FRM_SHIFT (0U) +#define USB_FRMNUMH_FRM(x) (((uint8_t)(((uint8_t)(x)) << USB_FRMNUMH_FRM_SHIFT)) & USB_FRMNUMH_FRM_MASK) + +/*! @name BDTPAGE2 - BDT Page Register 2 */ +#define USB_BDTPAGE2_BDTBA_MASK (0xFFU) +#define USB_BDTPAGE2_BDTBA_SHIFT (0U) +#define USB_BDTPAGE2_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE2_BDTBA_SHIFT)) & USB_BDTPAGE2_BDTBA_MASK) + +/*! @name BDTPAGE3 - BDT Page Register 3 */ +#define USB_BDTPAGE3_BDTBA_MASK (0xFFU) +#define USB_BDTPAGE3_BDTBA_SHIFT (0U) +#define USB_BDTPAGE3_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE3_BDTBA_SHIFT)) & USB_BDTPAGE3_BDTBA_MASK) + +/*! @name ENDPT - Endpoint Control register */ +#define USB_ENDPT_EPHSHK_MASK (0x1U) +#define USB_ENDPT_EPHSHK_SHIFT (0U) +#define USB_ENDPT_EPHSHK(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPHSHK_SHIFT)) & USB_ENDPT_EPHSHK_MASK) +#define USB_ENDPT_EPSTALL_MASK (0x2U) +#define USB_ENDPT_EPSTALL_SHIFT (1U) +#define USB_ENDPT_EPSTALL(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPSTALL_SHIFT)) & USB_ENDPT_EPSTALL_MASK) +#define USB_ENDPT_EPTXEN_MASK (0x4U) +#define USB_ENDPT_EPTXEN_SHIFT (2U) +#define USB_ENDPT_EPTXEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPTXEN_SHIFT)) & USB_ENDPT_EPTXEN_MASK) +#define USB_ENDPT_EPRXEN_MASK (0x8U) +#define USB_ENDPT_EPRXEN_SHIFT (3U) +#define USB_ENDPT_EPRXEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPRXEN_SHIFT)) & USB_ENDPT_EPRXEN_MASK) +#define USB_ENDPT_EPCTLDIS_MASK (0x10U) +#define USB_ENDPT_EPCTLDIS_SHIFT (4U) +#define USB_ENDPT_EPCTLDIS(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPCTLDIS_SHIFT)) & USB_ENDPT_EPCTLDIS_MASK) + +/* The count of USB_ENDPT */ +#define USB_ENDPT_COUNT (16U) + +/*! @name USBCTRL - USB Control register */ +#define USB_USBCTRL_PDE_MASK (0x40U) +#define USB_USBCTRL_PDE_SHIFT (6U) +#define USB_USBCTRL_PDE(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_PDE_SHIFT)) & USB_USBCTRL_PDE_MASK) +#define USB_USBCTRL_SUSP_MASK (0x80U) +#define USB_USBCTRL_SUSP_SHIFT (7U) +#define USB_USBCTRL_SUSP(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_SUSP_SHIFT)) & USB_USBCTRL_SUSP_MASK) + +/*! @name OBSERVE - USB OTG Observe register */ +#define USB_OBSERVE_DMPD_MASK (0x10U) +#define USB_OBSERVE_DMPD_SHIFT (4U) +#define USB_OBSERVE_DMPD(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DMPD_SHIFT)) & USB_OBSERVE_DMPD_MASK) +#define USB_OBSERVE_DPPD_MASK (0x40U) +#define USB_OBSERVE_DPPD_SHIFT (6U) +#define USB_OBSERVE_DPPD(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DPPD_SHIFT)) & USB_OBSERVE_DPPD_MASK) +#define USB_OBSERVE_DPPU_MASK (0x80U) +#define USB_OBSERVE_DPPU_SHIFT (7U) +#define USB_OBSERVE_DPPU(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DPPU_SHIFT)) & USB_OBSERVE_DPPU_MASK) + +/*! @name CONTROL - USB OTG Control register */ +#define USB_CONTROL_DPPULLUPNONOTG_MASK (0x10U) +#define USB_CONTROL_DPPULLUPNONOTG_SHIFT (4U) +#define USB_CONTROL_DPPULLUPNONOTG(x) (((uint8_t)(((uint8_t)(x)) << USB_CONTROL_DPPULLUPNONOTG_SHIFT)) & USB_CONTROL_DPPULLUPNONOTG_MASK) + +/*! @name USBTRC0 - USB Transceiver Control register 0 */ +#define USB_USBTRC0_USB_RESUME_INT_MASK (0x1U) +#define USB_USBTRC0_USB_RESUME_INT_SHIFT (0U) +#define USB_USBTRC0_USB_RESUME_INT(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USB_RESUME_INT_SHIFT)) & USB_USBTRC0_USB_RESUME_INT_MASK) +#define USB_USBTRC0_SYNC_DET_MASK (0x2U) +#define USB_USBTRC0_SYNC_DET_SHIFT (1U) +#define USB_USBTRC0_SYNC_DET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_SYNC_DET_SHIFT)) & USB_USBTRC0_SYNC_DET_MASK) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT_MASK (0x4U) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT_SHIFT (2U) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USB_CLK_RECOVERY_INT_SHIFT)) & USB_USBTRC0_USB_CLK_RECOVERY_INT_MASK) +#define USB_USBTRC0_USBRESMEN_MASK (0x20U) +#define USB_USBTRC0_USBRESMEN_SHIFT (5U) +#define USB_USBTRC0_USBRESMEN(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USBRESMEN_SHIFT)) & USB_USBTRC0_USBRESMEN_MASK) +#define USB_USBTRC0_USBRESET_MASK (0x80U) +#define USB_USBTRC0_USBRESET_SHIFT (7U) +#define USB_USBTRC0_USBRESET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USBRESET_SHIFT)) & USB_USBTRC0_USBRESET_MASK) + +/*! @name USBFRMADJUST - Frame Adjust Register */ +#define USB_USBFRMADJUST_ADJ_MASK (0xFFU) +#define USB_USBFRMADJUST_ADJ_SHIFT (0U) +#define USB_USBFRMADJUST_ADJ(x) (((uint8_t)(((uint8_t)(x)) << USB_USBFRMADJUST_ADJ_SHIFT)) & USB_USBFRMADJUST_ADJ_MASK) + +/*! @name CLK_RECOVER_CTRL - USB Clock recovery control */ +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_MASK (0x20U) +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_SHIFT (5U) +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_MASK) +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_MASK (0x40U) +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_SHIFT (6U) +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_MASK) +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK (0x80U) +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_SHIFT (7U) +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK) + +/*! @name CLK_RECOVER_IRC_EN - IRC48M oscillator enable register */ +#define USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK (0x2U) +#define USB_CLK_RECOVER_IRC_EN_IRC_EN_SHIFT (1U) +#define USB_CLK_RECOVER_IRC_EN_IRC_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_IRC_EN_IRC_EN_SHIFT)) & USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK) + +/*! @name CLK_RECOVER_INT_EN - Clock recovery combined interrupt enable */ +#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_MASK (0x10U) +#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_SHIFT (4U) +#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_SHIFT)) & USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_MASK) + +/*! @name CLK_RECOVER_INT_STATUS - Clock recovery separated interrupt status */ +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK (0x10U) +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_SHIFT (4U) +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_SHIFT)) & USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK) + + +/*! + * @} + */ /* end of group USB_Register_Masks */ + + +/* USB - Peripheral instance base addresses */ +/** Peripheral USB0 base address */ +#define USB0_BASE (0x40072000u) +/** Peripheral USB0 base pointer */ +#define USB0 ((USB_Type *)USB0_BASE) +/** Array initializer of USB peripheral base addresses */ +#define USB_BASE_ADDRS { USB0_BASE } +/** Array initializer of USB peripheral base pointers */ +#define USB_BASE_PTRS { USB0 } +/** Interrupt vectors for the USB peripheral type */ +#define USB_IRQS { USB0_IRQn } + +/*! + * @} + */ /* end of group USB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- VREF Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VREF_Peripheral_Access_Layer VREF Peripheral Access Layer + * @{ + */ + +/** VREF - Register Layout Typedef */ +typedef struct { + __IO uint8_t TRM; /**< VREF Trim Register, offset: 0x0 */ + __IO uint8_t SC; /**< VREF Status and Control Register, offset: 0x1 */ +} VREF_Type; + +/* ---------------------------------------------------------------------------- + -- VREF Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VREF_Register_Masks VREF Register Masks + * @{ + */ + +/*! @name TRM - VREF Trim Register */ +#define VREF_TRM_TRIM_MASK (0x3FU) +#define VREF_TRM_TRIM_SHIFT (0U) +#define VREF_TRM_TRIM(x) (((uint8_t)(((uint8_t)(x)) << VREF_TRM_TRIM_SHIFT)) & VREF_TRM_TRIM_MASK) +#define VREF_TRM_CHOPEN_MASK (0x40U) +#define VREF_TRM_CHOPEN_SHIFT (6U) +#define VREF_TRM_CHOPEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_TRM_CHOPEN_SHIFT)) & VREF_TRM_CHOPEN_MASK) + +/*! @name SC - VREF Status and Control Register */ +#define VREF_SC_MODE_LV_MASK (0x3U) +#define VREF_SC_MODE_LV_SHIFT (0U) +#define VREF_SC_MODE_LV(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_MODE_LV_SHIFT)) & VREF_SC_MODE_LV_MASK) +#define VREF_SC_VREFST_MASK (0x4U) +#define VREF_SC_VREFST_SHIFT (2U) +#define VREF_SC_VREFST(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_VREFST_SHIFT)) & VREF_SC_VREFST_MASK) +#define VREF_SC_ICOMPEN_MASK (0x20U) +#define VREF_SC_ICOMPEN_SHIFT (5U) +#define VREF_SC_ICOMPEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_ICOMPEN_SHIFT)) & VREF_SC_ICOMPEN_MASK) +#define VREF_SC_REGEN_MASK (0x40U) +#define VREF_SC_REGEN_SHIFT (6U) +#define VREF_SC_REGEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_REGEN_SHIFT)) & VREF_SC_REGEN_MASK) +#define VREF_SC_VREFEN_MASK (0x80U) +#define VREF_SC_VREFEN_SHIFT (7U) +#define VREF_SC_VREFEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_VREFEN_SHIFT)) & VREF_SC_VREFEN_MASK) + + +/*! + * @} + */ /* end of group VREF_Register_Masks */ + + +/* VREF - Peripheral instance base addresses */ +/** Peripheral VREF base address */ +#define VREF_BASE (0x40074000u) +/** Peripheral VREF base pointer */ +#define VREF ((VREF_Type *)VREF_BASE) +/** Array initializer of VREF peripheral base addresses */ +#define VREF_BASE_ADDRS { VREF_BASE } +/** Array initializer of VREF peripheral base pointers */ +#define VREF_BASE_PTRS { VREF } + +/*! + * @} + */ /* end of group VREF_Peripheral_Access_Layer */ + + +/* +** End of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #pragma pop +#elif defined(__CWCC__) + #pragma pop +#elif defined(__GNUC__) + /* leave anonymous unions enabled */ +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=default +#else + #error Not supported compiler type +#endif + +/*! + * @} + */ /* end of group Peripheral_access_layer */ + + +/* ---------------------------------------------------------------------------- + -- SDK Compatibility + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDK_Compatibility_Symbols SDK Compatibility + * @{ + */ + +#define I2C_S1_RXAK_MASK I2C_S_RXAK_MASK +#define I2C_S1_RXAK_SHIFT I2C_S_RXAK_SHIFT +#define I2C_S1_IICIF_MASK I2C_S_IICIF_MASK +#define I2C_S1_IICIF_SHIFT I2C_S_IICIF_SHIFTFT +#define I2C_S1_SRW_MASK I2C_S_SRW_MASK +#define I2C_S1_SRW_SHIFT I2C_S_SRW_SHIFT +#define I2C_S1_RAM_MASK I2C_S_RAM_MASK +#define I2C_S1_RAM_SHIFT I2C_S_RAM_SHIFT +#define I2C_S1_ARBL_MASK I2C_S_ARBL_MASK +#define I2C_S1_ARBL_SHIFT I2C_S_ARBL_SHIFT +#define I2C_S1_BUSY_MASK I2C_S_BUSY_MASK +#define I2C_S1_BUSY_SHIFT I2C_S_BUSY_SHIFT +#define I2C_S1_IAAS_MASK I2C_S_IAAS_MASK +#define I2C_S1_IAAS_SHIFT I2C_S_IAAS_SHIFT +#define I2C_S1_TCF_MASK I2C_S_TCF_MASK +#define I2C_S1_TCF_SHIFT I2C_S_TCF_SHIFT +#define I2C_S1_REG(base) I2C_S_REG(base) +#define I2C0_S1 I2C0_S +#define I2C1_S1 I2C1_S +#define PTA_BASE GPIOA_BASE +#define PTB_BASE GPIOB_BASE +#define PTC_BASE GPIOC_BASE +#define PTD_BASE GPIOD_BASE +#define PTE_BASE GPIOE_BASE +#define PTA GPIOA +#define PTB GPIOB +#define PTC GPIOC +#define PTD GPIOD +#define PTE GPIOE +#define UART0_FLEXIO_IRQn UART2_FLEXIO_IRQn +#define UART0_FLEXIO_IRQHandler UART2_FLEXIO_IRQHandler +#define SIM_SOPT5_UART0ODE_MASK SIM_SOPT5_UART2ODE_MASK +#define SIM_SOPT5_UART0ODE_SHIFT SIM_SOPT5_UART2ODE_SHIFT +#define SIM_SCGC4_UART0_MASK SIM_SCGC4_UART2_MASK +#define SIM_SCGC4_UART0_SHIFT SIM_SCGC4_UART2_SHIFT +#define UART0_BASE UART2_BASE +#define UART0_BDH UART2_BDH +#define UART0_BDL UART2_BDL +#define UART0_C1 UART2_C1 +#define UART0_C2 UART2_C2 +#define UART0_S1 UART2_S1 +#define UART0_S2 UART2_S2 +#define UART0_C3 UART2_C3 +#define UART0_D UART2_D +#define UART0_MA1 UART2_MA1 +#define UART0_MA2 UART2_MA2 +#define UART0_C4 UART2_C4 +#define UART0_C5 UART2_C5 +#define UART0_ED UART2_ED +#define UART0_MODEM UART2_MODEM +#define UART0_IR UART2_IR +#define UART0_PFIFO UART2_PFIFO +#define UART0_CFIFO UART2_CFIFO +#define UART0_SFIFO UART2_SFIFO +#define UART0_TWFIFO UART2_TWFIFO +#define UART0_TCFIFO UART2_TCFIFO +#define UART0_RWFIFO UART2_RWFIFO +#define UART0_RCFIFO UART2_RCFIFO +#define UART0_C7816 UART2_C7816 +#define UART0_IE7816 UART2_IE7816 +#define UART0_IS7816 UART2_IS7816 +#define UART0_WP7816 UART2_WP7816 +#define UART0_WN7816 UART2_WN7816 +#define UART0_WF7816 UART2_WF7816 +#define UART0_ET7816 UART2_ET7816 +#define UART0_TL7816 UART2_TL7816 +#define UART0_AP7816A_T0 UART2_AP7816A_T0 +#define UART0_AP7816B_T0 UART2_AP7816B_T0 +#define UART0_WP7816A_T0 UART2_WP7816A_T0 +#define UART0_WP7816A_T1 UART2_WP7816A_T1 +#define UART0_WP7816B_T0 UART2_WP7816B_T0 +#define UART0_WP7816B_T1 UART2_WP7816B_T1 +#define UART0_WGP7816_T1 UART2_WGP7816_T1 +#define UART0_WP7816C_T1 UART2_WP7816C_T1 +#define I2S0_MDR This_symb_has_been_deprecated +#define I2S_MDR_DIVIDE_MASK This_symb_has_been_deprecated +#define I2S_MDR_DIVIDE_SHIFT This_symb_has_been_deprecated +#define I2S_MDR_DIVIDE(x) This_symb_has_been_deprecated +#define I2S_MDR_FRACT_MASK This_symb_has_been_deprecated +#define I2S_MDR_FRACT_SHIFT This_symb_has_been_deprecated +#define I2S_MDR_FRACT(x) This_symb_has_been_deprecated +#define I2S_MDR_REG(base) This_symb_has_been_deprecated +#define CTL0 OTGCTL +#define USB0_CTL0 USB0_OTGCTL +#define USB_CTL0_REG(base) USB_OTGCTL_REG(base) +#define USB_CTL0_DPHIGH_MASK USB_OTGCTL_DPHIGH_MASK +#define USB_CTL0_DPHIGH_SHIFT USB_OTGCTL_DPHIGH_SHIFT +#define CTL1 CTL +#define USB0_CTL1 USB0_CTL +#define USB_CTL1_REG(base) USB_CTL_REG(base) +#define USB_CTL1_USBEN_MASK USB_CTL_USBEN_MASK +#define USB_CTL1_USBEN_SHIFT USB_CTL_USBEN_SHIFT +#define USB_CTL1_ODDRST_MASK USB_CTL_ODDRST_MASK +#define USB_CTL1_ODDRST_SHIFT USB_CTL_ODDRST_SHIFT +#define USB_CTL1_TXSUSPENDTOKENBUSY_MASK USB_CTL_TXSUSPENDTOKENBUSY_MASK +#define USB_CTL1_TXSUSPENDTOKENBUSY_SHIFT USB_CTL_TXSUSPENDTOKENBUSY_SHIFT +#define USB_CTL1_SE0_MASK USB_CTL_SE0_MASK +#define USB_CTL1_SE0_SHIFT USB_CTL_SE0_SHIFT +#define USB_CTL1_JSTATE_MASK USB_CTL_JSTATE_MASK +#define USB_CTL1_JSTATE_SHIFT USB_CTL_JSTATE_SHIFT +#define USB_CTL_USBEN_MASK USB_CTL_USBENSOFEN_MASK +#define USB_CTL_USBEN_SHIFT USB_CTL_USBENSOFEN_SHIFT + +/*! + * @} + */ /* end of group SDK_Compatibility_Symbols */ + + +#endif /* _MKL43Z4_H_ */ + diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/MKL43Z4_features.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/MKL43Z4_features.h new file mode 100644 index 0000000000..c9b72c0f32 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/MKL43Z4_features.h @@ -0,0 +1,1773 @@ +/* +** ################################################################### +** Version: rev. 1.9, 2015-05-27 +** Build: b151216 +** +** Abstract: +** Chip specific module features. +** +** Copyright (c) 2015 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** Revisions: +** - rev. 1.0 (2014-03-27) +** Initial version. +** - rev. 1.1 (2014-05-26) +** I2S registers TCR2/RCR2 and others were changed. +** FLEXIO register FLEXIO_VERID has now bitfields: FEATURE, MINOR, MAJOR. +** Names of the bitfields of the FLEXIO_SHIFTBUF have been changed to the appropriate register name e.g.: FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS. +** Peripheral_BASES macros has been changed to Peripheral_BASE_PTRS, e.g.: ADC_BASES to ADC_BASE_PTRS. +** Clock configuration for high range external oscillator has been added. +** RFSYS module access has been added. +** - rev. 1.2 (2014-07-10) +** GPIO - Renamed modules PTA,PTB,PTC,PTD,PTE to GPIOA,GPIOB,GPIOC,GPIOD,GPIOE. +** UART0 - UART0 module renamed to UART2. +** I2S - removed MDR register. +** - rev. 1.3 (2014-08-21) +** UART2 - Removed ED register. +** UART2 - Removed MODEM register. +** UART2 - Removed IR register. +** UART2 - Removed PFIFO register. +** UART2 - Removed CFIFO register. +** UART2 - Removed SFIFO register. +** UART2 - Removed TWFIFO register. +** UART2 - Removed TCFIFO register. +** UART2 - Removed RWFIFO register. +** UART2 - Removed RCFIFO register. +** USB - Removed bitfield REG_EN in CLK_RECOVER_IRC_EN register. +** SIM - Changed bitfield value MCGIRCLK to LIRC_CLK of bitfield CLKOUTSEL in SOPT2 register. +** SIM - Removed bitfield DIEID in SDID register. +** - rev. 1.4 (2014-09-01) +** USB - USB0_CTL0 was renamed to USB0_OTGCTL register. +** USB - USB0_CTL1 was renamed to USB0_CTL register. +** - rev. 1.5 (2014-09-05) +** USB - Renamed USBEN bitfield of USB0_CTL was renamed to USBENSOFEN. +** - rev. 1.6 (2015-01-21) +** Added FSL_FEATURE_SOC_peripheral_COUNT with number of peripheral instances +** - rev. 1.7 (2015-05-19) +** FSL_FEATURE_SOC_CAU_COUNT remamed to FSL_FEATURE_SOC_MMCAU_COUNT. +** Added FSL_FEATURE_SOC_peripheral_COUNT for TRNG and HSADC. +** Added features for PORT. +** - rev. 1.8 (2015-05-25) +** Added FSL_FEATURE_FLASH_PFLASH_START_ADDRESS +** - rev. 1.9 (2015-05-27) +** Several USB features added. +** +** ################################################################### +*/ + +#ifndef _MKL43Z4_FEATURES_H_ +#define _MKL43Z4_FEATURES_H_ + +/* SOC module features */ + +/* @brief ACMP availability on the SoC. */ +#define FSL_FEATURE_SOC_ACMP_COUNT (0) +/* @brief ADC16 availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC16_COUNT (1) +/* @brief ADC12 availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC12_COUNT (0) +/* @brief AFE availability on the SoC. */ +#define FSL_FEATURE_SOC_AFE_COUNT (0) +/* @brief AIPS availability on the SoC. */ +#define FSL_FEATURE_SOC_AIPS_COUNT (0) +/* @brief AOI availability on the SoC. */ +#define FSL_FEATURE_SOC_AOI_COUNT (0) +/* @brief AXBS availability on the SoC. */ +#define FSL_FEATURE_SOC_AXBS_COUNT (0) +/* @brief ASMC availability on the SoC. */ +#define FSL_FEATURE_SOC_ASMC_COUNT (0) +/* @brief CADC availability on the SoC. */ +#define FSL_FEATURE_SOC_CADC_COUNT (0) +/* @brief FLEXCAN availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXCAN_COUNT (0) +/* @brief MMCAU availability on the SoC. */ +#define FSL_FEATURE_SOC_MMCAU_COUNT (0) +/* @brief CMP availability on the SoC. */ +#define FSL_FEATURE_SOC_CMP_COUNT (1) +/* @brief CMT availability on the SoC. */ +#define FSL_FEATURE_SOC_CMT_COUNT (0) +/* @brief CNC availability on the SoC. */ +#define FSL_FEATURE_SOC_CNC_COUNT (0) +/* @brief CRC availability on the SoC. */ +#define FSL_FEATURE_SOC_CRC_COUNT (0) +/* @brief DAC availability on the SoC. */ +#define FSL_FEATURE_SOC_DAC_COUNT (1) +/* @brief DAC32 availability on the SoC. */ +#define FSL_FEATURE_SOC_DAC32_COUNT (0) +/* @brief DCDC availability on the SoC. */ +#define FSL_FEATURE_SOC_DCDC_COUNT (0) +/* @brief DDR availability on the SoC. */ +#define FSL_FEATURE_SOC_DDR_COUNT (0) +/* @brief DMA availability on the SoC. */ +#define FSL_FEATURE_SOC_DMA_COUNT (1) +/* @brief EDMA availability on the SoC. */ +#define FSL_FEATURE_SOC_EDMA_COUNT (0) +/* @brief DMAMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_DMAMUX_COUNT (1) +/* @brief DRY availability on the SoC. */ +#define FSL_FEATURE_SOC_DRY_COUNT (0) +/* @brief DSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_DSPI_COUNT (0) +/* @brief EMVSIM availability on the SoC. */ +#define FSL_FEATURE_SOC_EMVSIM_COUNT (0) +/* @brief ENC availability on the SoC. */ +#define FSL_FEATURE_SOC_ENC_COUNT (0) +/* @brief ENET availability on the SoC. */ +#define FSL_FEATURE_SOC_ENET_COUNT (0) +/* @brief EWM availability on the SoC. */ +#define FSL_FEATURE_SOC_EWM_COUNT (0) +/* @brief FB availability on the SoC. */ +#define FSL_FEATURE_SOC_FB_COUNT (0) +/* @brief FGPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_FGPIO_COUNT (0) +/* @brief FLEXIO availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXIO_COUNT (1) +/* @brief FMC availability on the SoC. */ +#define FSL_FEATURE_SOC_FMC_COUNT (0) +/* @brief FSKDT availability on the SoC. */ +#define FSL_FEATURE_SOC_FSKDT_COUNT (0) +/* @brief FTFA availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFA_COUNT (1) +/* @brief FTFE availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFE_COUNT (0) +/* @brief FTFL availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFL_COUNT (0) +/* @brief FTM availability on the SoC. */ +#define FSL_FEATURE_SOC_FTM_COUNT (0) +/* @brief FTMRA availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRA_COUNT (0) +/* @brief FTMRE availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRE_COUNT (0) +/* @brief FTMRH availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRH_COUNT (0) +/* @brief GPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_GPIO_COUNT (5) +/* @brief HSADC availability on the SoC. */ +#define FSL_FEATURE_SOC_HSADC_COUNT (0) +/* @brief I2C availability on the SoC. */ +#define FSL_FEATURE_SOC_I2C_COUNT (2) +/* @brief I2S availability on the SoC. */ +#define FSL_FEATURE_SOC_I2S_COUNT (1) +/* @brief ICS availability on the SoC. */ +#define FSL_FEATURE_SOC_ICS_COUNT (0) +/* @brief INTMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_INTMUX_COUNT (0) +/* @brief IRQ availability on the SoC. */ +#define FSL_FEATURE_SOC_IRQ_COUNT (0) +/* @brief KBI availability on the SoC. */ +#define FSL_FEATURE_SOC_KBI_COUNT (0) +/* @brief SLCD availability on the SoC. */ +#define FSL_FEATURE_SOC_SLCD_COUNT (1) +/* @brief LCDC availability on the SoC. */ +#define FSL_FEATURE_SOC_LCDC_COUNT (0) +/* @brief LDO availability on the SoC. */ +#define FSL_FEATURE_SOC_LDO_COUNT (0) +/* @brief LLWU availability on the SoC. */ +#define FSL_FEATURE_SOC_LLWU_COUNT (1) +/* @brief LMEM availability on the SoC. */ +#define FSL_FEATURE_SOC_LMEM_COUNT (0) +/* @brief LPI2C availability on the SoC. */ +#define FSL_FEATURE_SOC_LPI2C_COUNT (0) +/* @brief LPIT availability on the SoC. */ +#define FSL_FEATURE_SOC_LPIT_COUNT (0) +/* @brief LPSCI availability on the SoC. */ +#define FSL_FEATURE_SOC_LPSCI_COUNT (0) +/* @brief LPSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_LPSPI_COUNT (0) +/* @brief LPTMR availability on the SoC. */ +#define FSL_FEATURE_SOC_LPTMR_COUNT (1) +/* @brief LPTPM availability on the SoC. */ +#define FSL_FEATURE_SOC_LPTPM_COUNT (0) +/* @brief LPUART availability on the SoC. */ +#define FSL_FEATURE_SOC_LPUART_COUNT (2) +/* @brief LTC availability on the SoC. */ +#define FSL_FEATURE_SOC_LTC_COUNT (0) +/* @brief MC availability on the SoC. */ +#define FSL_FEATURE_SOC_MC_COUNT (0) +/* @brief MCG availability on the SoC. */ +#define FSL_FEATURE_SOC_MCG_COUNT (0) +/* @brief MCGLITE availability on the SoC. */ +#define FSL_FEATURE_SOC_MCGLITE_COUNT (1) +/* @brief MCM availability on the SoC. */ +#define FSL_FEATURE_SOC_MCM_COUNT (1) +/* @brief MMAU availability on the SoC. */ +#define FSL_FEATURE_SOC_MMAU_COUNT (0) +/* @brief MMDVSQ availability on the SoC. */ +#define FSL_FEATURE_SOC_MMDVSQ_COUNT (0) +/* @brief MPU availability on the SoC. */ +#define FSL_FEATURE_SOC_MPU_COUNT (0) +/* @brief MSCAN availability on the SoC. */ +#define FSL_FEATURE_SOC_MSCAN_COUNT (0) +/* @brief MSCM availability on the SoC. */ +#define FSL_FEATURE_SOC_MSCM_COUNT (0) +/* @brief MTB availability on the SoC. */ +#define FSL_FEATURE_SOC_MTB_COUNT (1) +/* @brief MTBDWT availability on the SoC. */ +#define FSL_FEATURE_SOC_MTBDWT_COUNT (1) +/* @brief MU availability on the SoC. */ +#define FSL_FEATURE_SOC_MU_COUNT (0) +/* @brief NFC availability on the SoC. */ +#define FSL_FEATURE_SOC_NFC_COUNT (0) +/* @brief OPAMP availability on the SoC. */ +#define FSL_FEATURE_SOC_OPAMP_COUNT (0) +/* @brief OSC availability on the SoC. */ +#define FSL_FEATURE_SOC_OSC_COUNT (1) +/* @brief OSC32 availability on the SoC. */ +#define FSL_FEATURE_SOC_OSC32_COUNT (0) +/* @brief OTFAD availability on the SoC. */ +#define FSL_FEATURE_SOC_OTFAD_COUNT (0) +/* @brief PDB availability on the SoC. */ +#define FSL_FEATURE_SOC_PDB_COUNT (0) +/* @brief PCC availability on the SoC. */ +#define FSL_FEATURE_SOC_PCC_COUNT (0) +/* @brief PGA availability on the SoC. */ +#define FSL_FEATURE_SOC_PGA_COUNT (0) +/* @brief PIT availability on the SoC. */ +#define FSL_FEATURE_SOC_PIT_COUNT (1) +/* @brief PMC availability on the SoC. */ +#define FSL_FEATURE_SOC_PMC_COUNT (1) +/* @brief PORT availability on the SoC. */ +#define FSL_FEATURE_SOC_PORT_COUNT (5) +/* @brief PWM availability on the SoC. */ +#define FSL_FEATURE_SOC_PWM_COUNT (0) +/* @brief PWT availability on the SoC. */ +#define FSL_FEATURE_SOC_PWT_COUNT (0) +/* @brief QuadSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_QuadSPI_COUNT (0) +/* @brief RCM availability on the SoC. */ +#define FSL_FEATURE_SOC_RCM_COUNT (1) +/* @brief RFSYS availability on the SoC. */ +#define FSL_FEATURE_SOC_RFSYS_COUNT (0) +/* @brief RFVBAT availability on the SoC. */ +#define FSL_FEATURE_SOC_RFVBAT_COUNT (0) +/* @brief RNG availability on the SoC. */ +#define FSL_FEATURE_SOC_RNG_COUNT (0) +/* @brief RNGB availability on the SoC. */ +#define FSL_FEATURE_SOC_RNGB_COUNT (0) +/* @brief ROM availability on the SoC. */ +#define FSL_FEATURE_SOC_ROM_COUNT (1) +/* @brief RSIM availability on the SoC. */ +#define FSL_FEATURE_SOC_RSIM_COUNT (0) +/* @brief RTC availability on the SoC. */ +#define FSL_FEATURE_SOC_RTC_COUNT (1) +/* @brief SCG availability on the SoC. */ +#define FSL_FEATURE_SOC_SCG_COUNT (0) +/* @brief SCI availability on the SoC. */ +#define FSL_FEATURE_SOC_SCI_COUNT (0) +/* @brief SDHC availability on the SoC. */ +#define FSL_FEATURE_SOC_SDHC_COUNT (0) +/* @brief SDRAM availability on the SoC. */ +#define FSL_FEATURE_SOC_SDRAM_COUNT (0) +/* @brief SEMA42 availability on the SoC. */ +#define FSL_FEATURE_SOC_SEMA42_COUNT (0) +/* @brief SIM availability on the SoC. */ +#define FSL_FEATURE_SOC_SIM_COUNT (1) +/* @brief SMC availability on the SoC. */ +#define FSL_FEATURE_SOC_SMC_COUNT (1) +/* @brief SPI availability on the SoC. */ +#define FSL_FEATURE_SOC_SPI_COUNT (2) +/* @brief TMR availability on the SoC. */ +#define FSL_FEATURE_SOC_TMR_COUNT (0) +/* @brief TPM availability on the SoC. */ +#define FSL_FEATURE_SOC_TPM_COUNT (3) +/* @brief TRGMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_TRGMUX_COUNT (0) +/* @brief TRIAMP availability on the SoC. */ +#define FSL_FEATURE_SOC_TRIAMP_COUNT (0) +/* @brief TRNG availability on the SoC. */ +#define FSL_FEATURE_SOC_TRNG_COUNT (0) +/* @brief TSI availability on the SoC. */ +#define FSL_FEATURE_SOC_TSI_COUNT (0) +/* @brief TSTMR availability on the SoC. */ +#define FSL_FEATURE_SOC_TSTMR_COUNT (0) +/* @brief UART availability on the SoC. */ +#define FSL_FEATURE_SOC_UART_COUNT (1) +/* @brief USB availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_COUNT (1) +/* @brief USBDCD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBDCD_COUNT (0) +/* @brief USBHSDCD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHSDCD_COUNT (0) +/* @brief USBPHY availability on the SoC. */ +#define FSL_FEATURE_SOC_USBPHY_COUNT (0) +/* @brief VREF availability on the SoC. */ +#define FSL_FEATURE_SOC_VREF_COUNT (1) +/* @brief WDOG availability on the SoC. */ +#define FSL_FEATURE_SOC_WDOG_COUNT (0) +/* @brief XBAR availability on the SoC. */ +#define FSL_FEATURE_SOC_XBAR_COUNT (0) +/* @brief XBARA availability on the SoC. */ +#define FSL_FEATURE_SOC_XBARA_COUNT (0) +/* @brief XBARB availability on the SoC. */ +#define FSL_FEATURE_SOC_XBARB_COUNT (0) +/* @brief XCVR availability on the SoC. */ +#define FSL_FEATURE_SOC_XCVR_COUNT (0) +/* @brief XRDC availability on the SoC. */ +#define FSL_FEATURE_SOC_XRDC_COUNT (0) +/* @brief ZLL availability on the SoC. */ +#define FSL_FEATURE_SOC_ZLL_COUNT (0) + +/* ADC16 module features */ + +/* @brief Has Programmable Gain Amplifier (PGA) in ADC (register PGA). */ +#define FSL_FEATURE_ADC16_HAS_PGA (0) +/* @brief Has PGA chopping control in ADC (bit PGA[PGACHPb] or PGA[PGACHP]). */ +#define FSL_FEATURE_ADC16_HAS_PGA_CHOPPING (0) +/* @brief Has PGA offset measurement mode in ADC (bit PGA[PGAOFSM]). */ +#define FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT (0) +/* @brief Has DMA support (bit SC2[DMAEN] or SC4[DMAEN]). */ +#define FSL_FEATURE_ADC16_HAS_DMA (1) +/* @brief Has differential mode (bitfield SC1x[DIFF]). */ +#define FSL_FEATURE_ADC16_HAS_DIFF_MODE (1) +/* @brief Has FIFO (bit SC4[AFDEP]). */ +#define FSL_FEATURE_ADC16_HAS_FIFO (0) +/* @brief FIFO size if available (bitfield SC4[AFDEP]). */ +#define FSL_FEATURE_ADC16_FIFO_SIZE (0) +/* @brief Has channel set a/b multiplexor (bitfield CFG2[MUXSEL]). */ +#define FSL_FEATURE_ADC16_HAS_MUX_SELECT (1) +/* @brief Has HW trigger masking (bitfield SC5[HTRGMASKE]. */ +#define FSL_FEATURE_ADC16_HAS_HW_TRIGGER_MASK (0) +/* @brief Has calibration feature (bit SC3[CAL] and registers CLPx, CLMx). */ +#define FSL_FEATURE_ADC16_HAS_CALIBRATION (1) +/* @brief Has HW averaging (bit SC3[AVGE]). */ +#define FSL_FEATURE_ADC16_HAS_HW_AVERAGE (1) +/* @brief Has offset correction (register OFS). */ +#define FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION (1) +/* @brief Maximum ADC resolution. */ +#define FSL_FEATURE_ADC16_MAX_RESOLUTION (16) +/* @brief Number of SC1x and Rx register pairs (conversion control and result registers). */ +#define FSL_FEATURE_ADC16_CONVERSION_CONTROL_COUNT (2) + +/* CMP module features */ + +/* @brief Has Trigger mode in CMP (register bit field CR1[TRIGM]). */ +#define FSL_FEATURE_CMP_HAS_TRIGGER_MODE (1) +/* @brief Has Window mode in CMP (register bit field CR1[WE]). */ +#define FSL_FEATURE_CMP_HAS_WINDOW_MODE (0) +/* @brief Has External sample supported in CMP (register bit field CR1[SE]). */ +#define FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT (0) +/* @brief Has DMA support in CMP (register bit field SCR[DMAEN]). */ +#define FSL_FEATURE_CMP_HAS_DMA (1) +/* @brief Has Pass Through mode in CMP (register bit field MUXCR[PSTM]). */ +#define FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE (0) +/* @brief Has DAC Test function in CMP (register DACTEST). */ +#define FSL_FEATURE_CMP_HAS_DAC_TEST (0) + +/* COP module features */ + +/* @brief Has the COP Debug Enable bit (COPC[COPDBGEN]) */ +#define FSL_FEATURE_COP_HAS_DEBUG_ENABLE (1) +/* @brief Has the COP Stop mode Enable bit (COPC[COPSTPEN]) */ +#define FSL_FEATURE_COP_HAS_STOP_ENABLE (1) +/* @brief Has more clock sources like MCGIRC */ +#define FSL_FEATURE_COP_HAS_MORE_CLKSRC (1) +/* @brief Has the timeout long and short mode bit (COPC[COPCLKS]) */ +#define FSL_FEATURE_COP_HAS_LONGTIME_MODE (1) + +/* DAC module features */ + +/* @brief Define the size of hardware buffer */ +#define FSL_FEATURE_DAC_BUFFER_SIZE (2) +/* @brief Define whether the buffer supports watermark event detection or not. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION (0) +/* @brief Define whether the buffer supports watermark selection detection or not. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION (0) +/* @brief Define whether the buffer supports watermark event 1 word before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD (0) +/* @brief Define whether the buffer supports watermark event 2 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS (0) +/* @brief Define whether the buffer supports watermark event 3 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS (0) +/* @brief Define whether the buffer supports watermark event 4 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS (0) +/* @brief Define whether FIFO buffer mode is available or not. */ +#define FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE (1) +/* @brief Define whether swing buffer mode is available or not.. */ +#define FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE (0) + +/* DMA module features */ + +/* @brief Total number of DMA channels on all modules. */ +#define FSL_FEATURE_DMA_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMA_COUNT * 4) + +/* DMAMUX module features */ + +/* @brief Number of DMA channels (related to number of register CHCFGn). */ +#define FSL_FEATURE_DMAMUX_MODULE_CHANNEL (4) +/* @brief Total number of DMA channels on all modules. */ +#define FSL_FEATURE_DMAMUX_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMAMUX_COUNT * 4) +/* @brief Has the periodic trigger capability for the triggered DMA channel 0 (register bit CHCFG0[TRIG]). */ +#define FSL_FEATURE_DMAMUX_HAS_TRIG (1) + +/* FLEXIO module features */ + +/* @brief Has Shifter Status Register (FLEXIO_SHIFTSTAT) */ +#define FSL_FEATURE_FLEXIO_HAS_SHIFTER_STATUS (1) +/* @brief Has Pin Data Input Register (FLEXIO_PIN) */ +#define FSL_FEATURE_FLEXIO_HAS_PIN_STATUS (0) +/* @brief Has Shifter Buffer N Nibble Byte Swapped Register (FLEXIO_SHIFTBUFNBSn) */ +#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP (0) +/* @brief Has Shifter Buffer N Half Word Swapped Register (FLEXIO_SHIFTBUFHWSn) */ +#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP (0) +/* @brief Has Shifter Buffer N Nibble Swapped Register (FLEXIO_SHIFTBUFNISn) */ +#define FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP (0) +/* @brief Supports Shifter State Mode (FLEXIO_SHIFTCTLn[SMOD]) */ +#define FSL_FEATURE_FLEXIO_HAS_STATE_MODE (0) +/* @brief Supports Shifter Logic Mode (FLEXIO_SHIFTCTLn[SMOD]) */ +#define FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE (0) +/* @brief Supports paralle width (FLEXIO_SHIFTCFGn[PWIDTH]) */ +#define FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH (0) +/* @brief Reset value of the FLEXIO_VERID register */ +#define FSL_FEATURE_FLEXIO_VERID_RESET_VALUE (0x1000000) +/* @brief Reset value of the FLEXIO_PARAM register */ +#define FSL_FEATURE_FLEXIO_PARAM_RESET_VALUE (0x10080404) + +/* FLASH module features */ + +#if defined(CPU_MKL43Z128VLH4) || defined(CPU_MKL43Z128VMP4) + /* @brief Is of type FTFA. */ + #define FSL_FEATURE_FLASH_IS_FTFA (1) + /* @brief Is of type FTFE. */ + #define FSL_FEATURE_FLASH_IS_FTFE (0) + /* @brief Is of type FTFL. */ + #define FSL_FEATURE_FLASH_IS_FTFL (0) + /* @brief Has flags indicating the status of the FlexRAM (register bits FCNFG[EEERDY], FCNFG[RAMRDY] and FCNFG[PFLSH]). */ + #define FSL_FEATURE_FLASH_HAS_FLEX_RAM_FLAGS (0) + /* @brief Has program flash swapping status flag (register bit FCNFG[SWAP]). */ + #define FSL_FEATURE_FLASH_HAS_PFLASH_SWAPPING_STATUS_FLAG (0) + /* @brief Has EEPROM region protection (register FEPROT). */ + #define FSL_FEATURE_FLASH_HAS_EEROM_REGION_PROTECTION (0) + /* @brief Has data flash region protection (register FDPROT). */ + #define FSL_FEATURE_FLASH_HAS_DATA_FLASH_REGION_PROTECTION (0) + /* @brief Has flash access control (registers XACCHn, SACCHn, where n is a number, FACSS and FACSN). */ + #define FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL (0) + /* @brief Has flash cache control in FMC module. */ + #define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (0) + /* @brief Has flash cache control in MCM module. */ + #define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (1) + /* @brief P-Flash start address. */ + #define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) + /* @brief P-Flash block count. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT (2) + /* @brief P-Flash block size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE (65536) + /* @brief P-Flash sector size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE (1024) + /* @brief P-Flash write unit size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE (4) + /* @brief P-Flash data path width. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (4) + /* @brief P-Flash block swap feature. */ + #define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (0) + /* @brief Has FlexNVM memory. */ + #define FSL_FEATURE_FLASH_HAS_FLEX_NVM (0) + /* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ + #define FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS (0x00000000) + /* @brief FlexNVM block count. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT (0) + /* @brief FlexNVM block size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE (0) + /* @brief FlexNVM sector size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE (0) + /* @brief FlexNVM write unit size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE (0) + /* @brief FlexNVM data path width. */ + #define FSL_FEATURE_FLASH_FLEX_BLOCK_DATA_PATH_WIDTH (0) + /* @brief Has FlexRAM memory. */ + #define FSL_FEATURE_FLASH_HAS_FLEX_RAM (0) + /* @brief FlexRAM start address. (Valid only if FlexRAM is available.) */ + #define FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS (0x00000000) + /* @brief FlexRAM size. */ + #define FSL_FEATURE_FLASH_FLEX_RAM_SIZE (0) + /* @brief Has 0x00 Read 1s Block command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_BLOCK_CMD (1) + /* @brief Has 0x01 Read 1s Section command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_SECTION_CMD (1) + /* @brief Has 0x02 Program Check command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_CHECK_CMD (1) + /* @brief Has 0x03 Read Resource command. */ + #define FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD (1) + /* @brief Has 0x06 Program Longword command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_LONGWORD_CMD (1) + /* @brief Has 0x07 Program Phrase command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_PHRASE_CMD (0) + /* @brief Has 0x08 Erase Flash Block command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_BLOCK_CMD (1) + /* @brief Has 0x09 Erase Flash Sector command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_SECTOR_CMD (1) + /* @brief Has 0x0B Program Section command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD (0) + /* @brief Has 0x40 Read 1s All Blocks command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_BLOCKS_CMD (1) + /* @brief Has 0x41 Read Once command. */ + #define FSL_FEATURE_FLASH_HAS_READ_ONCE_CMD (1) + /* @brief Has 0x43 Program Once command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_ONCE_CMD (1) + /* @brief Has 0x44 Erase All Blocks command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_CMD (1) + /* @brief Has 0x45 Verify Backdoor Access Key command. */ + #define FSL_FEATURE_FLASH_HAS_VERIFY_BACKDOOR_ACCESS_KEY_CMD (1) + /* @brief Has 0x46 Swap Control command. */ + #define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (0) + /* @brief Has 0x49 Erase All Blocks Unsecure command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (1) + /* @brief Has 0x80 Program Partition command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (0) + /* @brief Has 0x81 Set FlexRAM Function command. */ + #define FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD (0) + /* @brief P-Flash Erase/Read 1st all block command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Erase sector command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Rrogram/Verify section command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Read resource command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Program check command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Program check command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Erase/Read 1st all block command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Erase sector command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Rrogram/Verify section command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Read resource command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Program check command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM partition code 0000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 (0xFFFFFFFF) + /* @brief Emulated eeprom size code 0000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000 (0xFFFF) + /* @brief Emulated eeprom size code 0001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001 (0xFFFF) + /* @brief Emulated eeprom size code 0010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010 (0xFFFF) + /* @brief Emulated eeprom size code 0011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011 (0xFFFF) + /* @brief Emulated eeprom size code 0100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100 (0xFFFF) + /* @brief Emulated eeprom size code 0101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101 (0xFFFF) + /* @brief Emulated eeprom size code 0110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110 (0xFFFF) + /* @brief Emulated eeprom size code 0111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111 (0xFFFF) + /* @brief Emulated eeprom size code 1000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000 (0xFFFF) + /* @brief Emulated eeprom size code 1001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001 (0xFFFF) + /* @brief Emulated eeprom size code 1010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010 (0xFFFF) + /* @brief Emulated eeprom size code 1011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011 (0xFFFF) + /* @brief Emulated eeprom size code 1100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100 (0xFFFF) + /* @brief Emulated eeprom size code 1101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101 (0xFFFF) + /* @brief Emulated eeprom size code 1110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110 (0xFFFF) + /* @brief Emulated eeprom size code 1111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111 (0xFFFF) +#elif defined(CPU_MKL43Z256VLH4) || defined(CPU_MKL43Z256VMP4) + /* @brief Is of type FTFA. */ + #define FSL_FEATURE_FLASH_IS_FTFA (1) + /* @brief Is of type FTFE. */ + #define FSL_FEATURE_FLASH_IS_FTFE (0) + /* @brief Is of type FTFL. */ + #define FSL_FEATURE_FLASH_IS_FTFL (0) + /* @brief Has flags indicating the status of the FlexRAM (register bits FCNFG[EEERDY], FCNFG[RAMRDY] and FCNFG[PFLSH]). */ + #define FSL_FEATURE_FLASH_HAS_FLEX_RAM_FLAGS (0) + /* @brief Has program flash swapping status flag (register bit FCNFG[SWAP]). */ + #define FSL_FEATURE_FLASH_HAS_PFLASH_SWAPPING_STATUS_FLAG (0) + /* @brief Has EEPROM region protection (register FEPROT). */ + #define FSL_FEATURE_FLASH_HAS_EEROM_REGION_PROTECTION (0) + /* @brief Has data flash region protection (register FDPROT). */ + #define FSL_FEATURE_FLASH_HAS_DATA_FLASH_REGION_PROTECTION (0) + /* @brief Has flash access control (registers XACCHn, SACCHn, where n is a number, FACSS and FACSN). */ + #define FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL (0) + /* @brief Has flash cache control in FMC module. */ + #define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (0) + /* @brief Has flash cache control in MCM module. */ + #define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (1) + /* @brief P-Flash start address. */ + #define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) + /* @brief P-Flash block count. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT (2) + /* @brief P-Flash block size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE (131072) + /* @brief P-Flash sector size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE (1024) + /* @brief P-Flash write unit size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE (4) + /* @brief P-Flash data path width. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (4) + /* @brief P-Flash block swap feature. */ + #define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (0) + /* @brief Has FlexNVM memory. */ + #define FSL_FEATURE_FLASH_HAS_FLEX_NVM (0) + /* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ + #define FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS (0x00000000) + /* @brief FlexNVM block count. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT (0) + /* @brief FlexNVM block size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE (0) + /* @brief FlexNVM sector size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE (0) + /* @brief FlexNVM write unit size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE (0) + /* @brief FlexNVM data path width. */ + #define FSL_FEATURE_FLASH_FLEX_BLOCK_DATA_PATH_WIDTH (0) + /* @brief Has FlexRAM memory. */ + #define FSL_FEATURE_FLASH_HAS_FLEX_RAM (0) + /* @brief FlexRAM start address. (Valid only if FlexRAM is available.) */ + #define FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS (0x00000000) + /* @brief FlexRAM size. */ + #define FSL_FEATURE_FLASH_FLEX_RAM_SIZE (0) + /* @brief Has 0x00 Read 1s Block command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_BLOCK_CMD (1) + /* @brief Has 0x01 Read 1s Section command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_SECTION_CMD (1) + /* @brief Has 0x02 Program Check command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_CHECK_CMD (1) + /* @brief Has 0x03 Read Resource command. */ + #define FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD (1) + /* @brief Has 0x06 Program Longword command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_LONGWORD_CMD (1) + /* @brief Has 0x07 Program Phrase command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_PHRASE_CMD (0) + /* @brief Has 0x08 Erase Flash Block command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_BLOCK_CMD (1) + /* @brief Has 0x09 Erase Flash Sector command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_SECTOR_CMD (1) + /* @brief Has 0x0B Program Section command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD (0) + /* @brief Has 0x40 Read 1s All Blocks command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_BLOCKS_CMD (1) + /* @brief Has 0x41 Read Once command. */ + #define FSL_FEATURE_FLASH_HAS_READ_ONCE_CMD (1) + /* @brief Has 0x43 Program Once command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_ONCE_CMD (1) + /* @brief Has 0x44 Erase All Blocks command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_CMD (1) + /* @brief Has 0x45 Verify Backdoor Access Key command. */ + #define FSL_FEATURE_FLASH_HAS_VERIFY_BACKDOOR_ACCESS_KEY_CMD (1) + /* @brief Has 0x46 Swap Control command. */ + #define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (0) + /* @brief Has 0x49 Erase All Blocks Unsecure command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (1) + /* @brief Has 0x80 Program Partition command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (0) + /* @brief Has 0x81 Set FlexRAM Function command. */ + #define FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD (0) + /* @brief P-Flash Erase/Read 1st all block command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Erase sector command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Rrogram/Verify section command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Read resource command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Program check command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Program check command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Erase/Read 1st all block command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Erase sector command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Rrogram/Verify section command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Read resource command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Program check command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM partition code 0000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 (0xFFFFFFFF) + /* @brief Emulated eeprom size code 0000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000 (0xFFFF) + /* @brief Emulated eeprom size code 0001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001 (0xFFFF) + /* @brief Emulated eeprom size code 0010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010 (0xFFFF) + /* @brief Emulated eeprom size code 0011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011 (0xFFFF) + /* @brief Emulated eeprom size code 0100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100 (0xFFFF) + /* @brief Emulated eeprom size code 0101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101 (0xFFFF) + /* @brief Emulated eeprom size code 0110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110 (0xFFFF) + /* @brief Emulated eeprom size code 0111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111 (0xFFFF) + /* @brief Emulated eeprom size code 1000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000 (0xFFFF) + /* @brief Emulated eeprom size code 1001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001 (0xFFFF) + /* @brief Emulated eeprom size code 1010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010 (0xFFFF) + /* @brief Emulated eeprom size code 1011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011 (0xFFFF) + /* @brief Emulated eeprom size code 1100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100 (0xFFFF) + /* @brief Emulated eeprom size code 1101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101 (0xFFFF) + /* @brief Emulated eeprom size code 1110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110 (0xFFFF) + /* @brief Emulated eeprom size code 1111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111 (0xFFFF) +#endif /* defined(CPU_MKL43Z128VLH4) || defined(CPU_MKL43Z128VMP4) */ + +/* GPIO module features */ + +/* @brief Has fast (single cycle) access capability via a dedicated memory region. */ +#define FSL_FEATURE_GPIO_HAS_FAST_GPIO (0) +/* @brief Has port input disable register (PIDR). */ +#define FSL_FEATURE_GPIO_HAS_INPUT_DISABLE (0) +/* @brief Has dedicated interrupt vector. */ +#define FSL_FEATURE_GPIO_HAS_PORT_INTERRUPT_VECTOR (1) + +/* I2C module features */ + +/* @brief Has System Management Bus support (registers SMB, A2, SLTL and SLTH). */ +#define FSL_FEATURE_I2C_HAS_SMBUS (1) +/* @brief Maximum supported baud rate in kilobit per second. */ +#define FSL_FEATURE_I2C_MAX_BAUD_KBPS (400) +/* @brief Is affected by errata with ID 6070 (repeat start cannot be generated if the F[MULT] bit field is set to a non-zero value). */ +#define FSL_FEATURE_I2C_HAS_ERRATA_6070 (0) +/* @brief Has DMA support (register bit C1[DMAEN]). */ +#define FSL_FEATURE_I2C_HAS_DMA_SUPPORT (1) +/* @brief Has I2C bus start and stop detection (register bits FLT[SSIE], FLT[STARTF] and FLT[STOPF]). */ +#define FSL_FEATURE_I2C_HAS_START_STOP_DETECT (1) +/* @brief Has I2C bus stop detection (register bits FLT[STOPIE] and FLT[STOPF]). */ +#define FSL_FEATURE_I2C_HAS_STOP_DETECT (0) +/* @brief Has I2C bus stop hold off (register bit FLT[SHEN]). */ +#define FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF (1) +/* @brief Maximum width of the glitch filter in number of bus clocks. */ +#define FSL_FEATURE_I2C_MAX_GLITCH_FILTER_WIDTH (15) +/* @brief Has control of the drive capability of the I2C pins. */ +#define FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION (1) +/* @brief Has double buffering support (register S2). */ +#define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING (1) + +/* SAI module features */ + +/* @brief Receive/transmit FIFO size in item count (register bit fields TCSR[FRDE], TCSR[FRIE], TCSR[FRF], TCR1[TFW], RCSR[FRDE], RCSR[FRIE], RCSR[FRF], RCR1[RFW], registers TFRn, RFRn). */ +#define FSL_FEATURE_SAI_FIFO_COUNT (1) +/* @brief Receive/transmit channel number (register bit fields TCR3[TCE], RCR3[RCE], registers TDRn and RDRn). */ +#define FSL_FEATURE_SAI_CHANNEL_COUNT (1) +/* @brief Maximum words per frame (register bit fields TCR3[WDFL], TCR4[FRSZ], TMR[TWM], RCR3[WDFL], RCR4[FRSZ], RMR[RWM]). */ +#define FSL_FEATURE_SAI_MAX_WORDS_PER_FRAME (2) +/* @brief Has support of combining multiple data channel FIFOs into single channel FIFO (register bit fields TCR3[CFR], TCR4[FCOMB], TFR0[WCP], TFR1[WCP], RCR3[CFR], RCR4[FCOMB], RFR0[RCP], RFR1[RCP]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE (0) +/* @brief Has packing of 8-bit and 16-bit data into each 32-bit FIFO word (register bit fields TCR4[FPACK], RCR4[FPACK]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_PACKING (1) +/* @brief Configures when the SAI will continue transmitting after a FIFO error has been detected (register bit fields TCR4[FCONT], RCR4[FCONT]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR (1) +/* @brief Configures if the frame sync is generated internally, a frame sync is only generated when the FIFO warning flag is clear or continuously (register bit fields TCR4[ONDEM], RCR4[ONDEM]). */ +#define FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE (1) +/* @brief Simplified bit clock source and asynchronous/synchronous mode selection (register bit fields TCR2[CLKMODE], RCR2[CLKMODE]), in comparison with the exclusively implemented TCR2[SYNC,BCS,BCI,MSEL], RCR2[SYNC,BCS,BCI,MSEL]. */ +#define FSL_FEATURE_SAI_HAS_CLOCKING_MODE (0) +/* @brief Has register for configuration of the MCLK divide ratio (register bit fields MDR[FRACT], MDR[DIVIDE]). */ +#define FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER (0) +/* @brief Ihe interrupt source number */ +#define FSL_FEATURE_SAI_INT_SOURCE_NUM (1) +/* @brief Has register of MCR. */ +#define FSL_FEATURE_SAI_HAS_MCR (1) +/* @brief Has register of MDR */ +#define FSL_FEATURE_SAI_HAS_MDR (0) + +/* SLCD module features */ + +/* @brief Has Multi Alternate Clock Source (register bit GCR[ATLSOURCE]). */ +#define FSL_FEATURE_SLCD_HAS_MULTI_ALTERNATE_CLOCK_SOURCE (1) +/* @brief Has fast frame rate (register bit GCR[FFR]). */ +#define FSL_FEATURE_SLCD_HAS_FAST_FRAME_RATE (1) +/* @brief Has frame frequency interrupt (register bit GCR[LCDIEN]). */ +#define FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT (0) +/* @brief Has high reference select (register bit GCR[HREFSEL]). */ +#define FSL_FEATURE_SLCD_HAS_HIGH_REFERENCE_SELECT (0) +/* @brief Has pad safe (register bit GCR[PADSAFE]). */ +#define FSL_FEATURE_SLCD_HAS_PAD_SAFE (1) +/* @brief Has lcd wait (register bit GCR[LCDWAIT]). */ +#define FSL_FEATURE_SLCD_HAS_LCD_WAIT (0) +/* @brief Has lcd doze enable (register bit GCR[LCDDOZE]). */ +#define FSL_FEATURE_SLCD_HAS_LCD_DOZE_ENABLE (1) +/* @brief Total pin number on LCD. */ +#define FSL_FEATURE_SLCD_HAS_PIN_NUM (64) +/* @brief Total phase number on SLCD. */ +#define FSL_FEATURE_SLCD_HAS_PHASE_NUM (8) + +/* LLWU module features */ + +/* @brief Maximum number of pins (maximal index plus one) connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN (16) +/* @brief Has pins 8-15 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_EXTERNAL_PIN_GROUP2 (1) +/* @brief Maximum number of internal modules connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE (8) +/* @brief Number of digital filters. */ +#define FSL_FEATURE_LLWU_HAS_PIN_FILTER (2) +/* @brief Has MF5 register. */ +#define FSL_FEATURE_LLWU_HAS_MF (0) +/* @brief Has PF register. */ +#define FSL_FEATURE_LLWU_HAS_PF (0) +/* @brief Has possibility to enable reset in low leakage power mode and enable digital filter for RESET pin (register LLWU_RST). */ +#define FSL_FEATURE_LLWU_HAS_RESET_ENABLE (0) +/* @brief Has external pin 0 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN0 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN0_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN0_GPIO_PIN (0) +/* @brief Has external pin 1 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN1 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN1_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN1_GPIO_PIN (0) +/* @brief Has external pin 2 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN2 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN2_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN2_GPIO_PIN (0) +/* @brief Has external pin 3 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN3 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN3_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN3_GPIO_PIN (0) +/* @brief Has external pin 4 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN4 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN4_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN4_GPIO_PIN (0) +/* @brief Has external pin 5 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN5 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN5_GPIO_IDX (GPIOB_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN5_GPIO_PIN (0) +/* @brief Has external pin 6 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN6 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN6_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN6_GPIO_PIN (1) +/* @brief Has external pin 7 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN7 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN7_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN7_GPIO_PIN (3) +/* @brief Has external pin 8 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN8 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN8_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN8_GPIO_PIN (4) +/* @brief Has external pin 9 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN9 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN9_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN9_GPIO_PIN (5) +/* @brief Has external pin 10 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN10 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN10_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN10_GPIO_PIN (6) +/* @brief Has external pin 11 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN11 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN11_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN11_GPIO_PIN (0) +/* @brief Has external pin 12 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN12 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN12_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN12_GPIO_PIN (0) +/* @brief Has external pin 13 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN13 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN13_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN13_GPIO_PIN (0) +/* @brief Has external pin 14 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN14 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN14_GPIO_IDX (GPIOD_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN14_GPIO_PIN (4) +/* @brief Has external pin 15 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN15 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN15_GPIO_IDX (GPIOD_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN15_GPIO_PIN (6) +/* @brief Has external pin 16 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN16 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN16_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN16_GPIO_PIN (0) +/* @brief Has external pin 17 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN17 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN17_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN17_GPIO_PIN (0) +/* @brief Has external pin 18 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN18 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN18_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN18_GPIO_PIN (0) +/* @brief Has external pin 19 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN19 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN19_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN19_GPIO_PIN (0) +/* @brief Has external pin 20 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN20 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN20_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN20_GPIO_PIN (0) +/* @brief Has external pin 21 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN21 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN21_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN21_GPIO_PIN (0) +/* @brief Has external pin 22 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN22 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN22_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN22_GPIO_PIN (0) +/* @brief Has external pin 23 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN23 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN23_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN23_GPIO_PIN (0) +/* @brief Has external pin 24 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN24 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN24_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN24_GPIO_PIN (0) +/* @brief Has external pin 25 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN25 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN25_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN25_GPIO_PIN (0) +/* @brief Has external pin 26 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN26 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN26_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN26_GPIO_PIN (0) +/* @brief Has external pin 27 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN27 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN27_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN27_GPIO_PIN (0) +/* @brief Has external pin 28 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN28 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN28_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN28_GPIO_PIN (0) +/* @brief Has external pin 29 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN29 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN29_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN29_GPIO_PIN (0) +/* @brief Has external pin 30 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN30 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN30_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN30_GPIO_PIN (0) +/* @brief Has external pin 31 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN31 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN31_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN31_GPIO_PIN (0) +/* @brief Has internal module 0 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE0 (1) +/* @brief Has internal module 1 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE1 (1) +/* @brief Has internal module 2 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE2 (0) +/* @brief Has internal module 3 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE3 (0) +/* @brief Has internal module 4 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE4 (0) +/* @brief Has internal module 5 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE5 (1) +/* @brief Has internal module 6 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE6 (0) +/* @brief Has internal module 7 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE7 (1) +/* @brief Has Version ID Register (LLWU_VERID). */ +#define FSL_FEATURE_LLWU_HAS_VERID (0) +/* @brief Has Parameter Register (LLWU_PARAM). */ +#define FSL_FEATURE_LLWU_HAS_PARAM (0) +/* @brief Width of registers of the LLWU. */ +#define FSL_FEATURE_LLWU_REG_BITWIDTH (8) +/* @brief Has DMA Enable register (LLWU_DE). */ +#define FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG (0) + +/* LPTMR module features */ + +/* @brief Has shared interrupt handler with another LPTMR module. */ +#define FSL_FEATURE_LPTMR_HAS_SHARED_IRQ_HANDLER (0) + +/* LPUART module features */ + +/* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */ +#define FSL_FEATURE_LPUART_HAS_IRQ_EXTENDED_FUNCTIONS (0) +/* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_LOW_POWER_UART_SUPPORT (1) +/* @brief Has extended data register ED (or extra flags in the DATA register if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS (1) +/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ +#define FSL_FEATURE_LPUART_HAS_FIFO (0) +/* @brief Has 32-bit register MODIR */ +#define FSL_FEATURE_LPUART_HAS_MODIR (0) +/* @brief Hardware flow control (RTS, CTS) is supported. */ +#define FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT (0) +/* @brief Infrared (modulation) is supported. */ +#define FSL_FEATURE_LPUART_HAS_IR_SUPPORT (0) +/* @brief 2 bits long stop bit is available. */ +#define FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT (1) +/* @brief Maximal data width without parity bit. */ +#define FSL_FEATURE_LPUART_HAS_10BIT_DATA_SUPPORT (1) +/* @brief Baud rate fine adjustment is available. */ +#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (0) +/* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_OVER_SAMPLING_SUPPORT (1) +/* @brief Baud rate oversampling is available. */ +#define FSL_FEATURE_LPUART_HAS_RX_RESYNC_SUPPORT (1) +/* @brief Baud rate oversampling is available. */ +#define FSL_FEATURE_LPUART_HAS_BOTH_EDGE_SAMPLING_SUPPORT (1) +/* @brief Peripheral type. */ +#define FSL_FEATURE_LPUART_IS_SCI (1) +/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ +#define FSL_FEATURE_LPUART_FIFO_SIZEn(x) (0) +/* @brief Maximal data width without parity bit. */ +#define FSL_FEATURE_LPUART_MAX_DATA_WIDTH_WITH_NO_PARITY (10) +/* @brief Maximal data width with parity bit. */ +#define FSL_FEATURE_LPUART_MAX_DATA_WIDTH_WITH_PARITY (9) +/* @brief Supports two match addresses to filter incoming frames. */ +#define FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING (1) +/* @brief Has transmitter/receiver DMA enable bits C5[TDMAE]/C5[RDMAE] (or BAUD[TDMAE]/BAUD[RDMAE] if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_DMA_ENABLE (1) +/* @brief Has transmitter/receiver DMA select bits C4[TDMAS]/C4[RDMAS], resp. C5[TDMAS]/C5[RDMAS] if IS_SCI = 0. */ +#define FSL_FEATURE_LPUART_HAS_DMA_SELECT (0) +/* @brief Data character bit order selection is supported (bit field S2[MSBF] or STAT[MSBF] if the registers are 32-bit wide). */ +#define FSL_FEATURE_LPUART_HAS_BIT_ORDER_SELECT (1) +/* @brief Has smart card (ISO7816 protocol) support and no improved smart card support. */ +#define FSL_FEATURE_LPUART_HAS_SMART_CARD_SUPPORT (0) +/* @brief Has improved smart card (ISO7816 protocol) support. */ +#define FSL_FEATURE_LPUART_HAS_IMPROVED_SMART_CARD_SUPPORT (0) +/* @brief Has local operation network (CEA709.1-B protocol) support. */ +#define FSL_FEATURE_LPUART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0) +/* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */ +#define FSL_FEATURE_LPUART_HAS_32BIT_REGISTERS (1) +/* @brief Lin break detect available (has bit BDH[LBKDIE]). */ +#define FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT (0) +/* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */ +#define FSL_FEATURE_LPUART_HAS_WAIT_MODE_OPERATION (0) +/* @brief Has separate DMA RX and TX requests. */ +#define FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1) +/* @brief Has LPAURT_PARAM. */ +#define FSL_FEATURE_LPUART_HAS_PARAM (0) +/* @brief Has LPUART_VERID. */ +#define FSL_FEATURE_LPUART_HAS_VERID (0) +/* @brief Has LPUART_GLOBAL. */ +#define FSL_FEATURE_LPUART_HAS_GLOBAL (0) +/* @brief Has LPUART_PINCFG. */ +#define FSL_FEATURE_LPUART_HAS_PINCFG (0) + +/* MCGLITE module features */ + +/* @brief Defines that clock generator is MCG Lite. */ +#define FSL_FEATURE_MCGLITE_MCGLITE (1) +/* @brief Has Crystal Oscillator Operation Mode Selection. */ +#define FSL_FEATURE_MCGLITE_HAS_HGO0 (1) +/* @brief Has HCTRIM register available. */ +#define FSL_FEATURE_MCGLITE_HAS_HCTRIM (1) +/* @brief Has HTTRIM register available. */ +#define FSL_FEATURE_MCGLITE_HAS_HTTRIM (1) +/* @brief Has HFTRIM register available. */ +#define FSL_FEATURE_MCGLITE_HAS_HFTRIM (1) +/* @brief Has LTRIMRNG register available. */ +#define FSL_FEATURE_MCGLITE_HAS_LTRIMRNG (1) +/* @brief Has LFTRIM register available. */ +#define FSL_FEATURE_MCGLITE_HAS_LFTRIM (1) +/* @brief Has LSTRIM register available. */ +#define FSL_FEATURE_MCGLITE_HAS_LSTRIM (1) +/* @brief Has External Clock Source Frequency Range Selection. */ +#define FSL_FEATURE_MCGLITE_HAS_RANGE0 (1) + +/* interrupt module features */ + +/* @brief Lowest interrupt request number. */ +#define FSL_FEATURE_INTERRUPT_IRQ_MIN (-14) +/* @brief Highest interrupt request number. */ +#define FSL_FEATURE_INTERRUPT_IRQ_MAX (31) + +/* OSC module features */ + +/* @brief Has OSC1 external oscillator. */ +#define FSL_FEATURE_OSC_HAS_OSC1 (0) +/* @brief Has OSC0 external oscillator. */ +#define FSL_FEATURE_OSC_HAS_OSC0 (1) +/* @brief Has OSC external oscillator (without index). */ +#define FSL_FEATURE_OSC_HAS_OSC (0) +/* @brief Number of OSC external oscillators. */ +#define FSL_FEATURE_OSC_OSC_COUNT (1) +/* @brief Has external reference clock divider (register bit field DIV[ERPS]). */ +#define FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER (0) + +/* PIT module features */ + +/* @brief Number of channels (related to number of registers LDVALn, CVALn, TCTRLn, TFLGn). */ +#define FSL_FEATURE_PIT_TIMER_COUNT (2) +/* @brief Has lifetime timer (related to existence of registers LTMR64L and LTMR64H). */ +#define FSL_FEATURE_PIT_HAS_LIFETIME_TIMER (1) +/* @brief Has chain mode (related to existence of register bit field TCTRLn[CHN]). */ +#define FSL_FEATURE_PIT_HAS_CHAIN_MODE (1) +/* @brief Has shared interrupt handler (has not individual interrupt handler for each channel). */ +#define FSL_FEATURE_PIT_HAS_SHARED_IRQ_HANDLER (1) + +/* PMC module features */ + +/* @brief Has Bandgap Enable In VLPx Operation support. */ +#define FSL_FEATURE_PMC_HAS_BGEN (1) +/* @brief Has Bandgap Buffer Enable. */ +#define FSL_FEATURE_PMC_HAS_BGBE (1) +/* @brief Has Bandgap Buffer Drive Select. */ +#define FSL_FEATURE_PMC_HAS_BGBDS (0) +/* @brief Has Low-Voltage Detect Voltage Select support. */ +#define FSL_FEATURE_PMC_HAS_LVDV (1) +/* @brief Has Low-Voltage Warning Voltage Select support. */ +#define FSL_FEATURE_PMC_HAS_LVWV (1) +/* @brief Has LPO. */ +#define FSL_FEATURE_PMC_HAS_LPO (0) +/* @brief Has VLPx option PMC_REGSC[VLPO]. */ +#define FSL_FEATURE_PMC_HAS_VLPO (0) +/* @brief Has acknowledge isolation support. */ +#define FSL_FEATURE_PMC_HAS_ACKISO (1) +/* @brief Has Regulator In Full Performance Mode Status Bit PMC_REGSC[REGFPM]. */ +#define FSL_FEATURE_PMC_HAS_REGFPM (0) +/* @brief Has Regulator In Run Regulation Status Bit PMC_REGSC[REGONS]. */ +#define FSL_FEATURE_PMC_HAS_REGONS (1) +/* @brief Has PMC_HVDSC1. */ +#define FSL_FEATURE_PMC_HAS_HVDSC1 (0) +/* @brief Has PMC_PARAM. */ +#define FSL_FEATURE_PMC_HAS_PARAM (0) +/* @brief Has PMC_VERID. */ +#define FSL_FEATURE_PMC_HAS_VERID (0) + +/* PORT module features */ + +/* @brief Has control lock (register bit PCR[LK]). */ +#define FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK (0) +/* @brief Has open drain control (register bit PCR[ODE]). */ +#define FSL_FEATURE_PORT_HAS_OPEN_DRAIN (0) +/* @brief Has digital filter (registers DFER, DFCR and DFWR). */ +#define FSL_FEATURE_PORT_HAS_DIGITAL_FILTER (0) +/* @brief Has DMA request (register bit field PCR[IRQC] values). */ +#define FSL_FEATURE_PORT_HAS_DMA_REQUEST (1) +/* @brief Has pull resistor selection available. */ +#define FSL_FEATURE_PORT_HAS_PULL_SELECTION (1) +/* @brief Has pull resistor enable (register bit PCR[PE]). */ +#define FSL_FEATURE_PORT_HAS_PULL_ENABLE (1) +/* @brief Has slew rate control (register bit PCR[SRE]). */ +#define FSL_FEATURE_PORT_HAS_SLEW_RATE (1) +/* @brief Has passive filter (register bit field PCR[PFE]). */ +#define FSL_FEATURE_PORT_HAS_PASSIVE_FILTER (1) +/* @brief Has drive strength control (register bit PCR[DSE]). */ +#define FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH (1) +/* @brief Has separate drive strength register (HDRVE). */ +#define FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH_REGISTER (0) +/* @brief Has glitch filter (register IOFLT). */ +#define FSL_FEATURE_PORT_HAS_GLITCH_FILTER (0) +/* @brief Defines width of PCR[MUX] field. */ +#define FSL_FEATURE_PORT_PCR_MUX_WIDTH (3) +/* @brief Has dedicated interrupt vector. */ +#define FSL_FEATURE_PORT_HAS_INTERRUPT_VECTOR (1) +/* @brief Defines whether PCR[IRQC] bit-field has flag states. */ +#define FSL_FEATURE_PORT_HAS_IRQC_FLAG (0) +/* @brief Defines whether PCR[IRQC] bit-field has trigger states. */ +#define FSL_FEATURE_PORT_HAS_IRQC_TRIGGER (0) + +/* RCM module features */ + +/* @brief Has Loss-of-Lock Reset support. */ +#define FSL_FEATURE_RCM_HAS_LOL (0) +/* @brief Has Loss-of-Clock Reset support. */ +#define FSL_FEATURE_RCM_HAS_LOC (0) +/* @brief Has JTAG generated Reset support. */ +#define FSL_FEATURE_RCM_HAS_JTAG (0) +/* @brief Has EzPort generated Reset support. */ +#define FSL_FEATURE_RCM_HAS_EZPORT (0) +/* @brief Has bit-field indicating EZP_MS_B pin state during last reset. */ +#define FSL_FEATURE_RCM_HAS_EZPMS (0) +/* @brief Has boot ROM configuration, MR[BOOTROM], FM[FORCEROM] */ +#define FSL_FEATURE_RCM_HAS_BOOTROM (1) +/* @brief Has sticky system reset status register RCM_SSRS0 and RCM_SSRS1. */ +#define FSL_FEATURE_RCM_HAS_SSRS (1) +/* @brief Has Version ID Register (RCM_VERID). */ +#define FSL_FEATURE_RCM_HAS_VERID (0) +/* @brief Has Parameter Register (RCM_PARAM). */ +#define FSL_FEATURE_RCM_HAS_PARAM (0) +/* @brief Has Reset Interrupt Enable Register RCM_SRIE. */ +#define FSL_FEATURE_RCM_HAS_SRIE (0) +/* @brief Width of registers of the RCM. */ +#define FSL_FEATURE_RCM_REG_WIDTH (8) +/* @brief Has Core 1 generated Reset support RCM_SRS[CORE1] */ +#define FSL_FEATURE_RCM_HAS_CORE1 (0) +/* @brief Has MDM-AP system reset support RCM_SRS1[MDM_AP] */ +#define FSL_FEATURE_RCM_HAS_MDM_AP (1) +/* @brief Has wakeup reset feature. Register bit SRS[WAKEUP]. */ +#define FSL_FEATURE_RCM_HAS_WAKEUP (1) + +/* RTC module features */ + +/* @brief Has wakeup pin. */ +#define FSL_FEATURE_RTC_HAS_WAKEUP_PIN (1) +/* @brief Has wakeup pin selection (bit field CR[WPS]). */ +#define FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION (1) +/* @brief Has low power features (registers MER, MCLR and MCHR). */ +#define FSL_FEATURE_RTC_HAS_MONOTONIC (0) +/* @brief Has read/write access control (registers WAR and RAR). */ +#define FSL_FEATURE_RTC_HAS_ACCESS_CONTROL (0) +/* @brief Has security features (registers TTSR, MER, MCLR and MCHR). */ +#define FSL_FEATURE_RTC_HAS_SECURITY (0) +/* @brief Has RTC_CLKIN available. */ +#define FSL_FEATURE_RTC_HAS_RTC_CLKIN (1) +/* @brief Has prescaler adjust for LPO. */ +#define FSL_FEATURE_RTC_HAS_LPO_ADJUST (0) +/* @brief Has Clock Pin Enable field. */ +#define FSL_FEATURE_RTC_HAS_CPE (0) +/* @brief Has Timer Seconds Interrupt Configuration field. */ +#define FSL_FEATURE_RTC_HAS_TSIC (0) +/* @brief Has OSC capacitor setting RTC_CR[SC2P ~ SC16P] */ +#define FSL_FEATURE_RTC_HAS_OSC_SCXP (1) + +/* SIM module features */ + +/* @brief Has USB FS divider. */ +#define FSL_FEATURE_SIM_USBFS_USE_SPECIAL_DIVIDER (0) +/* @brief Is PLL clock divided by 2 before MCG PLL/FLL clock selection. */ +#define FSL_FEATURE_SIM_PLLCLK_USE_SPECIAL_DIVIDER (0) +/* @brief Has RAM size specification (register bit field SOPT1[RAMSIZE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RAMSIZE (0) +/* @brief Has 32k oscillator clock output (register bit SOPT1[OSC32KOUT]). */ +#define FSL_FEATURE_SIM_OPT_HAS_OSC32K_OUT (1) +/* @brief Has 32k oscillator clock selection (register bit field SOPT1[OSC32KSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_OSC32K_SELECTION (1) +/* @brief 32k oscillator clock selection width (width of register bit field SOPT1[OSC32KSEL]). */ +#define FSL_FEATURE_SIM_OPT_OSC32K_SELECTION_WIDTH (2) +/* @brief Has RTC clock output selection (register bit SOPT2[RTCCLKOUTSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RTC_CLOCK_OUT_SELECTION (1) +/* @brief Has USB voltage regulator (register bits SOPT1[USBVSTBY], SOPT1[USBSSTBY], SOPT1[USBREGEN], SOPT1CFG[URWE], SOPT1CFG[UVSWE], SOPT1CFG[USSWE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR (1) +/* @brief USB has integrated PHY (register bits USBPHYCTL[USBVREGSEL], USBPHYCTL[USBVREGPD], USBPHYCTL[USB3VOUTTRG], USBPHYCTL[USBDISILIM], SOPT2[USBSLSRC], SOPT2[USBREGEN]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USB_PHY (0) +/* @brief Has PTD7 pad drive strength control (register bit SOPT2[PTD7PAD]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PTD7PAD (0) +/* @brief Has FlexBus security level selection (register bit SOPT2[FBSL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FBSL (0) +/* @brief Has number of FlexBus hold cycle before FlexBus can release bus (register bit SOPT6[PCR]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PCR (0) +/* @brief Has number of NFC hold cycle in case of FlexBus request (register bit SOPT6[MCC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_MCC (0) +/* @brief Has UART open drain enable (register bits UARTnODE, where n is a number, in register SOPT5). */ +#define FSL_FEATURE_SIM_OPT_HAS_ODE (1) +/* @brief Number of LPUART modules (number of register bits LPUARTn, where n is a number, in register SCGC5). */ +#define FSL_FEATURE_SIM_OPT_LPUART_COUNT (2) +/* @brief Number of UART modules (number of register bits UARTn, where n is a number, in register SCGC4). */ +#define FSL_FEATURE_SIM_OPT_UART_COUNT (1) +/* @brief Has UART0 open drain enable (register bit SOPT5[UART0ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_ODE (0) +/* @brief Has UART1 open drain enable (register bit SOPT5[UART1ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_ODE (0) +/* @brief Has UART2 open drain enable (register bit SOPT5[UART2ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART2_ODE (1) +/* @brief Has LPUART0 open drain enable (register bit SOPT5[LPUART0ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_ODE (1) +/* @brief Has LPUART1 open drain enable (register bit SOPT5[LPUART1ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_ODE (1) +/* @brief Has CMT/UART pad drive strength control (register bit SOPT2[CMTUARTPAD]). */ +#define FSL_FEATURE_SIM_OPT_HAS_CMTUARTPAD (0) +/* @brief Has LPUART0 transmit data source selection (register bit SOPT5[LPUART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_TX_SRC (1) +/* @brief Has LPUART0 receive data source selection (register bit SOPT5[LPUART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_RX_SRC (1) +/* @brief Has LPUART1 transmit data source selection (register bit SOPT5[LPUART1TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_TX_SRC (1) +/* @brief Has LPUART1 receive data source selection (register bit SOPT5[LPUART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_RX_SRC (1) +/* @brief Has UART0 transmit data source selection (register bit SOPT5[UART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_TX_SRC (0) +/* @brief UART0 transmit data source selection width (width of register bit SOPT5[UART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART0_TX_SRC_WIDTH (0) +/* @brief Has UART0 receive data source selection (register bit SOPT5[UART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_RX_SRC (0) +/* @brief UART0 receive data source selection width (width of register bit SOPT5[UART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART0_RX_SRC_WIDTH (0) +/* @brief Has UART1 transmit data source selection (register bit SOPT5[UART1TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_TX_SRC (0) +/* @brief Has UART1 receive data source selection (register bit SOPT5[UART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_RX_SRC (0) +/* @brief UART1 receive data source selection width (width of register bit SOPT5[UART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART1_RX_SRC_WIDTH (0) +/* @brief Has FTM module(s) configuration. */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM (0) +/* @brief Number of FTM modules. */ +#define FSL_FEATURE_SIM_OPT_FTM_COUNT (0) +/* @brief Number of FTM triggers with selectable source. */ +#define FSL_FEATURE_SIM_OPT_FTM_TRIGGER_COUNT (0) +/* @brief Has FTM0 triggers source selection (register bits SOPT4[FTM0TRGnSRC], where n is a number). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM0_TRIGGER (0) +/* @brief Has FTM3 triggers source selection (register bits SOPT4[FTM3TRGnSRC], where n is a number). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM3_TRIGGER (0) +/* @brief Has FTM1 channel 0 input capture source selection (register bit SOPT4[FTM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM1_CHANNELS (0) +/* @brief Has FTM2 channel 0 input capture source selection (register bit SOPT4[FTM2CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM2_CHANNELS (0) +/* @brief Has FTM3 channel 0 input capture source selection (register bit SOPT4[FTM3CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM3_CHANNELS (0) +/* @brief Has FTM2 channel 1 input capture source selection (register bit SOPT4[FTM2CH1SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM2_CHANNEL1 (0) +/* @brief Number of configurable FTM0 fault detection input (number of register bits SOPT4[FTM0FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM0_FAULT_COUNT (0) +/* @brief Number of configurable FTM1 fault detection input (number of register bits SOPT4[FTM1FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM1_FAULT_COUNT (0) +/* @brief Number of configurable FTM2 fault detection input (number of register bits SOPT4[FTM2FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM2_FAULT_COUNT (0) +/* @brief Number of configurable FTM3 fault detection input (number of register bits SOPT4[FTM3FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM3_FAULT_COUNT (0) +/* @brief Has FTM hardware trigger 0 software synchronization (register bit SOPT8[FTMnSYNCBIT], where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM_TRIGGER_SYNC (0) +/* @brief Has FTM channels output source selection (register bit SOPT8[FTMxOCHnSRC], where x is a module instance index and n is a channel index). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM_CHANNELS_OUTPUT_SRC (0) +/* @brief Has TPM module(s) configuration. */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM (1) +/* @brief The highest TPM module index. */ +#define FSL_FEATURE_SIM_OPT_MAX_TPM_INDEX (2) +/* @brief Has TPM module with index 0. */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM0 (1) +/* @brief Has TPM0 clock selection (register bit field SOPT4[TPM0CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM0_CLK_SEL (1) +/* @brief Is TPM channels configuration in the SOPT4 (not SOPT9) register (register bits TPMnCH0SRC, TPMnCLKSEL, where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM_CHANNELS_CONFIG_IN_SOPT4_REG (1) +/* @brief Has TPM1 channel 0 input capture source selection (register bit field SOPT4[TPM1CH0SRC] or SOPT9[TPM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM1_CH0_SRC_SELECTION (1) +/* @brief Has TPM1 clock selection (register bit field SOPT4[TPM1CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM1_CLK_SEL (1) +/* @brief TPM1 channel 0 input capture source selection width (width of register bit field SOPT4[TPM1CH0SRC] or SOPT9[TPM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_TPM1_CH0_SRC_SELECTION_WIDTH (2) +/* @brief Has TPM2 channel 0 input capture source selection (register bit field SOPT4[TPM2CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM2_CH0_SRC_SELECTION (1) +/* @brief Has TPM2 clock selection (register bit field SOPT4[TPM2CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM2_CLK_SEL (1) +/* @brief Has PLL/FLL clock selection (register bit field SOPT2[PLLFLLSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PLL_FLL_SELECTION (0) +/* @brief PLL/FLL clock selection width (width of register bit field SOPT2[PLLFLLSEL]). */ +#define FSL_FEATURE_SIM_OPT_PLL_FLL_SELECTION_WIDTH (0) +/* @brief Has NFC clock source selection (register bit SOPT2[NFCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_NFCSRC (0) +/* @brief Has eSDHC clock source selection (register bit SOPT2[ESDHCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_ESDHCSRC (0) +/* @brief Has SDHC clock source selection (register bit SOPT2[SDHCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_SDHCSRC (0) +/* @brief Has LCDC clock source selection (register bits SOPT2[LCDCSRC], SOPT2[LCDC_CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LCDCSRC (0) +/* @brief Has ENET timestamp clock source selection (register bit SOPT2[TIMESRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TIMESRC (0) +/* @brief Has ENET RMII clock source selection (register bit SOPT2[RMIISRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RMIISRC (0) +/* @brief Has USB clock source selection (register bit SOPT2[USBSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBSRC (1) +/* @brief Has USB FS clock source selection (register bit SOPT2[USBFSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBFSRC (0) +/* @brief Has USB HS clock source selection (register bit SOPT2[USBHSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBHSRC (0) +/* @brief Has LPUART clock source selection (register bit SOPT2[LPUARTSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUARTSRC (0) +/* @brief Has LPUART0 clock source selection (register bit SOPT2[LPUART0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0SRC (1) +/* @brief Has LPUART1 clock source selection (register bit SOPT2[LPUART1SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1SRC (1) +/* @brief Has FLEXIOSRC clock source selection (register bit SOPT2[FLEXIOSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FLEXIOSRC (1) +/* @brief Has UART0 clock source selection (register bit SOPT2[UART0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0SRC (0) +/* @brief Has TPM clock source selection (register bit SOPT2[TPMSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPMSRC (1) +/* @brief Has debug trace clock selection (register bit SOPT2[TRACECLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TRACE_CLKSEL (0) +/* @brief Number of ADC modules (register bits SOPT7[ADCnTRGSEL], SOPT7[ADCnPRETRGSEL], SOPT7[ADCnALTTRGSEL], where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_ADC_COUNT (1) +/* @brief Has clock 2 output divider (register bit field CLKDIV1[OUTDIV2]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV2 (0) +/* @brief Has clock 3 output divider (register bit field CLKDIV1[OUTDIV3]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV3 (0) +/* @brief Has clock 4 output divider (register bit field CLKDIV1[OUTDIV4]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV4 (1) +/* @brief Clock 4 output divider width (width of register bit field CLKDIV1[OUTDIV4]). */ +#define FSL_FEATURE_SIM_DIVIDER_OUTDIV4_WIDTH (3) +/* @brief Has clock 5 output divider (register bit field CLKDIV1[OUTDIV5]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV5 (0) +/* @brief Has USB clock divider (register bit field CLKDIV2[USBDIV] and CLKDIV2[USBFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBDIV (0) +/* @brief Has USB FS clock divider (register bit field CLKDIV2[USBFSDIV] and CLKDIV2[USBFSFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBFSDIV (0) +/* @brief Has USB HS clock divider (register bit field CLKDIV2[USBHSDIV] and CLKDIV2[USBHSFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBHSDIV (0) +/* @brief Has PLL/FLL clock divider (register bit field CLKDIV3[PLLFLLDIV] and CLKDIV3[PLLFLLFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_PLLFLLDIV (0) +/* @brief Has LCDC clock divider (register bit field CLKDIV3[LCDCDIV] and CLKDIV3[LCDCFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_LCDCDIV (0) +/* @brief Has trace clock divider (register bit field CLKDIV4[TRACEDIV] and CLKDIV4[TRACEFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_TRACEDIV (0) +/* @brief Has NFC clock divider (register bit field CLKDIV4[NFCDIV] and CLKDIV4[NFCFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_NFCDIV (0) +/* @brief Has Kinetis family ID (register bit field SDID[FAMILYID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_FAMILYID (0) +/* @brief Has Kinetis family ID (register bit field SDID[FAMID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_FAMID (1) +/* @brief Has Kinetis sub-family ID (register bit field SDID[SUBFAMID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SUBFAMID (1) +/* @brief Has Kinetis series ID (register bit field SDID[SERIESID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SERIESID (1) +/* @brief Has device die ID (register bit field SDID[DIEID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_DIEID (0) +/* @brief Has system SRAM size specifier (register bit field SDID[SRAMSIZE]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SRAMSIZE (1) +/* @brief Has flash mode (register bit FCFG1[FLASHDOZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FLASHDOZE (1) +/* @brief Has flash disable (register bit FCFG1[FLASHDIS]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FLASHDIS (1) +/* @brief Has FTFE disable (register bit FCFG1[FTFDIS]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FTFDIS (0) +/* @brief Has FlexNVM size specifier (register bit field FCFG1[NVMSIZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_NVMSIZE (0) +/* @brief Has EEPROM size specifier (register bit field FCFG1[EESIZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_EESIZE (0) +/* @brief Has FlexNVM partition (register bit field FCFG1[DEPART]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_DEPART (0) +/* @brief Maximum flash address block 0 address specifier (register bit field FCFG2[MAXADDR0]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR0 (1) +/* @brief Maximum flash address block 1 address specifier (register bit field FCFG2[MAXADDR1]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR1 (1) +/* @brief Maximum flash address block 0 or 1 address specifier (register bit field FCFG2[MAXADDR01]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR01 (0) +/* @brief Maximum flash address block 2 or 3 address specifier (register bit field FCFG2[MAXADDR23]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR23 (0) +/* @brief Has program flash availability specifier (register bit FCFG2[PFLSH]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_PFLSH (0) +/* @brief Has program flash swapping (register bit FCFG2[SWAPPFLSH]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_PFLSH_SWAP (0) +/* @brief Has miscellanious control register (register MCR). */ +#define FSL_FEATURE_SIM_HAS_MISC_CONTROLS (0) +/* @brief Has COP watchdog (registers COPC and SRVCOP). */ +#define FSL_FEATURE_SIM_HAS_COP_WATCHDOG (1) +/* @brief Has COP watchdog stop (register bits COPC[COPSTPEN], COPC[COPDBGEN] and COPC[COPCLKSEL]). */ +#define FSL_FEATURE_SIM_HAS_COP_STOP (1) +/* @brief Has LLWU clock gate bit (e.g SIM_SCGC4). */ +#define FSL_FEATURE_SIM_HAS_SCGC_LLWU (0) + +/* SMC module features */ + +/* @brief Has partial stop option (register bit STOPCTRL[PSTOPO]). */ +#define FSL_FEATURE_SMC_HAS_PSTOPO (1) +/* @brief Has LPO power option (register bit STOPCTRL[LPOPO]). */ +#define FSL_FEATURE_SMC_HAS_LPOPO (0) +/* @brief Has POR power option (register bit STOPCTRL[PORPO] or VLLSCTRL[PORPO]). */ +#define FSL_FEATURE_SMC_HAS_PORPO (1) +/* @brief Has low power wakeup on interrupt (register bit PMCTRL[LPWUI]). */ +#define FSL_FEATURE_SMC_HAS_LPWUI (0) +/* @brief Has LLS or VLLS mode control (register bit STOPCTRL[LLSM]). */ +#define FSL_FEATURE_SMC_HAS_LLS_SUBMODE (0) +/* @brief Has VLLS mode control (register bit VLLSCTRL[VLLSM]). */ +#define FSL_FEATURE_SMC_USE_VLLSCTRL_REG (0) +/* @brief Has VLLS mode control (register bit STOPCTRL[VLLSM]). */ +#define FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM (1) +/* @brief Has RAM partition 2 power option (register bit STOPCTRL[RAM2PO]). */ +#define FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION (0) +/* @brief Has high speed run mode (register bit PMPROT[AHSRUN]). */ +#define FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE (0) +/* @brief Has low leakage stop mode (register bit PMPROT[ALLS]). */ +#define FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE (1) +/* @brief Has very low leakage stop mode (register bit PMPROT[AVLLS]). */ +#define FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE (1) +/* @brief Has stop submode. */ +#define FSL_FEATURE_SMC_HAS_SUB_STOP_MODE (1) +/* @brief Has stop submode 0(VLLS0). */ +#define FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 (1) +/* @brief Has stop submode 2(VLLS2). */ +#define FSL_FEATURE_SMC_HAS_STOP_SUBMODE2 (0) +/* @brief Has SMC_PARAM. */ +#define FSL_FEATURE_SMC_HAS_PARAM (0) +/* @brief Has SMC_VERID. */ +#define FSL_FEATURE_SMC_HAS_VERID (0) + +/* SPI module features */ + +/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ +#define FSL_FEATURE_SPI_HAS_FIFO (1) +/* @brief Has DMA support (register bit fields C2[RXDMAE] and C2[TXDMAE]). */ +#define FSL_FEATURE_SPI_HAS_DMA_SUPPORT (1) +/* @brief Has separate DMA RX and TX requests. */ +#define FSL_FEATURE_SPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1) +/* @brief Receive/transmit FIFO size in number of 16-bit communication items. */ +#define FSL_FEATURE_SPI_FIFO_SIZEn(x) \ + ((x) == SPI0 ? (0) : \ + ((x) == SPI1 ? (4) : (-1))) +/* @brief Maximum transfer data width in bits. */ +#define FSL_FEATURE_SPI_MAX_DATA_WIDTH (16) +/* @brief The data register name has postfix (L as low and H as high). */ +#define FSL_FEATURE_SPI_DATA_REGISTER_HAS_POSTFIX (1) +/* @brief Has separated TXDATA and CMD FIFOs (register SREX). */ +#define FSL_FEATURE_SPI_HAS_SEPARATE_TXDATA_CMD_FIFO (0) +/* @brief Has 16-bit data transfer support. */ +#define FSL_FEATURE_SPI_16BIT_TRANSFERS (1) + +/* SysTick module features */ + +/* @brief Systick has external reference clock. */ +#define FSL_FEATURE_SYSTICK_HAS_EXT_REF (1) +/* @brief Systick external reference clock is core clock divided by this value. */ +#define FSL_FEATURE_SYSTICK_EXT_REF_CORE_DIV (16) + +/* TPM module features */ + +/* @brief Bus clock is the source clock for the module. */ +#define FSL_FEATURE_TPM_BUS_CLOCK (0) +/* @brief Number of channels. */ +#define FSL_FEATURE_TPM_CHANNEL_COUNTn(x) \ + ((x) == TPM0 ? (6) : \ + ((x) == TPM1 ? (2) : \ + ((x) == TPM2 ? (2) : (-1)))) +/* @brief Has counter reset by the selected input capture event (register bits C0SC[ICRST], C1SC[ICRST], ...). */ +#define FSL_FEATURE_TPM_HAS_COUNTER_RESET_BY_CAPTURE_EVENT (0) +/* @brief Has TPM_PARAM. */ +#define FSL_FEATURE_TPM_HAS_PARAM (0) +/* @brief Has TPM_VERID. */ +#define FSL_FEATURE_TPM_HAS_VERID (0) +/* @brief Has TPM_GLOBAL. */ +#define FSL_FEATURE_TPM_HAS_GLOBAL (0) +/* @brief Has TPM_TRIG. */ +#define FSL_FEATURE_TPM_HAS_TRIG (0) +/* @brief Has counter pause on trigger. */ +#define FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER (1) +/* @brief Has external trigger selection. */ +#define FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION (1) +/* @brief Has TPM_COMBINE. */ +#define FSL_FEATURE_TPM_HAS_COMBINE (0) +/* @brief Has TPM_FILTER. */ +#define FSL_FEATURE_TPM_HAS_FILTER (0) +/* @brief Has TPM_QDCTRL. */ +#define FSL_FEATURE_TPM_HAS_QDCTRL (0) + +/* UART module features */ + +/* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */ +#define FSL_FEATURE_UART_HAS_IRQ_EXTENDED_FUNCTIONS (0) +/* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */ +#define FSL_FEATURE_UART_HAS_LOW_POWER_UART_SUPPORT (0) +/* @brief Has extended data register ED (or extra flags in the DATA register if the registers are 32-bit wide). */ +#define FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS (0) +/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ +#define FSL_FEATURE_UART_HAS_FIFO (0) +/* @brief Hardware flow control (RTS, CTS) is supported. */ +#define FSL_FEATURE_UART_HAS_MODEM_SUPPORT (0) +/* @brief Infrared (modulation) is supported. */ +#define FSL_FEATURE_UART_HAS_IR_SUPPORT (0) +/* @brief 2 bits long stop bit is available. */ +#define FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT (0) +/* @brief Maximal data width without parity bit. */ +#define FSL_FEATURE_UART_HAS_10BIT_DATA_SUPPORT (0) +/* @brief Baud rate fine adjustment is available. */ +#define FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (1) +/* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */ +#define FSL_FEATURE_UART_HAS_BAUD_RATE_OVER_SAMPLING_SUPPORT (0) +/* @brief Baud rate oversampling is available. */ +#define FSL_FEATURE_UART_HAS_RX_RESYNC_SUPPORT (0) +/* @brief Baud rate oversampling is available. */ +#define FSL_FEATURE_UART_HAS_BOTH_EDGE_SAMPLING_SUPPORT (0) +/* @brief Peripheral type. */ +#define FSL_FEATURE_UART_IS_SCI (0) +/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ +#define FSL_FEATURE_UART_FIFO_SIZEn(x) (0) +/* @brief Maximal data width without parity bit. */ +#define FSL_FEATURE_UART_MAX_DATA_WIDTH_WITH_NO_PARITY (9) +/* @brief Maximal data width with parity bit. */ +#define FSL_FEATURE_UART_MAX_DATA_WIDTH_WITH_PARITY (10) +/* @brief Supports two match addresses to filter incoming frames. */ +#define FSL_FEATURE_UART_HAS_ADDRESS_MATCHING (1) +/* @brief Has transmitter/receiver DMA enable bits C5[TDMAE]/C5[RDMAE] (or BAUD[TDMAE]/BAUD[RDMAE] if the registers are 32-bit wide). */ +#define FSL_FEATURE_UART_HAS_DMA_ENABLE (0) +/* @brief Has transmitter/receiver DMA select bits C4[TDMAS]/C4[RDMAS], resp. C5[TDMAS]/C5[RDMAS] if IS_SCI = 0. */ +#define FSL_FEATURE_UART_HAS_DMA_SELECT (1) +/* @brief Data character bit order selection is supported (bit field S2[MSBF] or STAT[MSBF] if the registers are 32-bit wide). */ +#define FSL_FEATURE_UART_HAS_BIT_ORDER_SELECT (1) +/* @brief Has smart card (ISO7816 protocol) support and no improved smart card support. */ +#define FSL_FEATURE_UART_HAS_SMART_CARD_SUPPORT (1) +/* @brief Has improved smart card (ISO7816 protocol) support. */ +#define FSL_FEATURE_UART_HAS_IMPROVED_SMART_CARD_SUPPORT (1) +/* @brief Has local operation network (CEA709.1-B protocol) support. */ +#define FSL_FEATURE_UART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0) +/* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */ +#define FSL_FEATURE_UART_HAS_32BIT_REGISTERS (0) +/* @brief Lin break detect available (has bit BDH[LBKDIE]). */ +#define FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT (0) +/* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */ +#define FSL_FEATURE_UART_HAS_WAIT_MODE_OPERATION (0) +/* @brief Has separate DMA RX and TX requests. */ +#define FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1) + +/* USB module features */ + +/* @brief HOST mode enabled */ +#define FSL_FEATURE_USB_KHCI_HOST_ENABLED (0) +/* @brief OTG mode enabled */ +#define FSL_FEATURE_USB_KHCI_OTG_ENABLED (0) +/* @brief Size of the USB dedicated RAM */ +#define FSL_FEATURE_USB_KHCI_USB_RAM (0) +/* @brief Has KEEP_ALIVE_CTRL register */ +#define FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED (0) +/* @brief Has the Dynamic SOF threshold compare support */ +#define FSL_FEATURE_USB_KHCI_DYNAMIC_SOF_THRESHOLD_COMPARE_ENABLED (0) +/* @brief Has the VBUS detect support */ +#define FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED (0) +/* @brief Has the IRC48M module clock support */ +#define FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED (1) +/* @brief Number of endpoints supported */ +#define FSL_FEATURE_USB_ENDPT_COUNT (16) + +/* VREF module features */ + +/* @brief Has chop oscillator (bit TRM[CHOPEN]) */ +#define FSL_FEATURE_VREF_HAS_CHOP_OSC (1) +/* @brief Has second order curvature compensation (bit SC[ICOMPEN]) */ +#define FSL_FEATURE_VREF_HAS_COMPENSATION (1) +/* @brief Describes the set of SC[MODE_LV] bitfield values */ +#define FSL_FEATURE_VREF_MODE_LV_TYPE (1) +/* @brief Module has also low reference (registers VREFL/VREFH) */ +#define FSL_FEATURE_VREF_HAS_LOW_REFERENCE (0) +/* @brief Has VREF_TRM4. */ +#define FSL_FEATURE_VREF_HAS_TRM4 (0) + +#endif /* _MKL43Z4_FEATURES_H_ */ + diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/MKL43Z256xxx4.sct b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/MKL43Z256xxx4.sct new file mode 100644 index 0000000000..770f1cdd78 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/MKL43Z256xxx4.sct @@ -0,0 +1,113 @@ +#! armcc -E +/* +** ################################################################### +** Processors: MKL43Z256VLH4 +** MKL43Z256VMP4 +** +** Compiler: Keil ARM C/C++ Compiler +** Reference manual: KL43P64M48SF6RM, Rev.3, Aug 2014 +** Version: rev. 1.6, 2015-07-29 +** Build: b160406 +** +** Abstract: +** Linker file for the Keil ARM C/C++ Compiler +** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** ################################################################### +*/ +#define __ram_vector_table__ 1 + +/* Heap 1/4 of ram and stack 1/8 */ +#define __stack_size__ 0x1000 +#define __heap_size__ 0x2800 + +#if (defined(__ram_vector_table__)) + #define __ram_vector_table_size__ 0x00000200 +#else + #define __ram_vector_table_size__ 0x00000000 +#endif + +#define m_interrupts_start 0x00000000 +#define m_interrupts_size 0x00000200 + +#define m_flash_config_start 0x00000400 +#define m_flash_config_size 0x00000010 + +#define m_text_start 0x00000410 +#define m_text_size 0x0003FBF0 + +#define m_interrupts_ram_start 0x1FFFE000 +#define m_interrupts_ram_size __ram_vector_table_size__ + +#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size) +#define m_data_size (0x00008000 - m_interrupts_ram_size) + +/* Sizes */ +#if (defined(__stack_size__)) + #define Stack_Size __stack_size__ +#else + #define Stack_Size 0x0400 +#endif + +#if (defined(__heap_size__)) + #define Heap_Size __heap_size__ +#else + #define Heap_Size 0x0400 +#endif + +LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region + VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address + * (RESET,+FIRST) + } + ER_m_flash_config m_flash_config_start FIXED m_flash_config_size { ; load address = execution address + * (FlashConfig) + } + ER_m_text m_text_start m_text_size { ; load address = execution address + * (InRoot$$Sections) + .ANY (+RO) + } + +#if (defined(__ram_vector_table__)) + VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size { + } +#else + VECTOR_RAM m_interrupts_start EMPTY 0 { + } +#endif + RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data + .ANY (+RW +ZI) + } + RW_IRAM1 +0 EMPTY Heap_Size { ; Heap region growing up + } +} + diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_ARM_STD/startup_MKL43Z4.S b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/startup_MKL43Z4.s similarity index 80% rename from hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_ARM_STD/startup_MKL43Z4.S rename to hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/startup_MKL43Z4.s index 58abd545d5..0715690483 100644 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_ARM_STD/startup_MKL43Z4.S +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/startup_MKL43Z4.s @@ -2,12 +2,12 @@ ; * @file: startup_MKL43Z4.s ; * @purpose: CMSIS Cortex-M0P Core Device Startup File ; * MKL43Z4 -; * @version: 1.3 -; * @date: 2014-8-21 -; * @build: b140821 +; * @version: 1.8 +; * @date: 2016-6-24 +; * @build: b160627 ; * --------------------------------------------------------------------------------------- ; * -; * Copyright (c) 1997 - 2014 , Freescale Semiconductor, Inc. +; * Copyright (c) 1997 - 2016 , Freescale Semiconductor, Inc. ; * All rights reserved. ; * ; * Redistribution and use in source and binary forms, with or without modification, @@ -39,9 +39,7 @@ ; * ; *****************************************************************************/ - -__initial_sp EQU 0x20006000 ; Top of RAM - +__initial_sp EQU 0x20006000 ; Top of RAM PRESERVE8 THUMB @@ -102,10 +100,10 @@ __Vectors DCD __initial_sp ; Top of Stack DCD LPTMR0_IRQHandler ;LPTMR0 interrupt DCD LCD_IRQHandler ;LCD interrupt DCD PORTA_IRQHandler ;PORTA Pin detect - DCD PORTCD_IRQHandler ;Single interrupt vector for PORTC; PORTD Pin detect + DCD PORTC_PORTD_IRQHandler ;Single interrupt vector for PORTC; PORTD Pin detect __Vectors_End -__Vectors_Size EQU __Vectors_End - __Vectors +__Vectors_Size EQU __Vectors_End - __Vectors ; Flash Configuration ; 16-byte flash configuration field that stores default protection settings (loaded on reset) @@ -237,7 +235,7 @@ FSEC EQU 0xFE ; ; IF :LNOT::DEF:RAM_TARGET - AREA |.ARM.__at_0x400|, DATA, READONLY + AREA FlashConfig, DATA, READONLY __FlashConfig DCB BackDoorK0, BackDoorK1, BackDoorK2, BackDoorK3 DCB BackDoorK4, BackDoorK5, BackDoorK6, BackDoorK7 @@ -245,6 +243,7 @@ __FlashConfig DCB FSEC , FOPT , 0xFF , 0xFF ENDIF + AREA |.text|, CODE, READONLY ; Reset Handler @@ -253,8 +252,18 @@ Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main + + IF :LNOT::DEF:RAM_TARGET + REQUIRE FlashConfig + ENDIF + + CPSID I ; Mask interrupts + LDR R0, =0xE000ED08 + LDR R1, =__Vectors + STR R1, [R0] LDR R0, =SystemInit BLX R0 + CPSIE i ; Unmask interrupts LDR R0, =__main BX R0 ENDP @@ -286,23 +295,107 @@ SysTick_Handler\ EXPORT SysTick_Handler [WEAK] B . ENDP -Default_Handler\ +DMA0_IRQHandler\ PROC EXPORT DMA0_IRQHandler [WEAK] + LDR R0, =DMA0_DriverIRQHandler + BX R0 + ENDP + +DMA1_IRQHandler\ + PROC EXPORT DMA1_IRQHandler [WEAK] + LDR R0, =DMA1_DriverIRQHandler + BX R0 + ENDP + +DMA2_IRQHandler\ + PROC EXPORT DMA2_IRQHandler [WEAK] + LDR R0, =DMA2_DriverIRQHandler + BX R0 + ENDP + +DMA3_IRQHandler\ + PROC EXPORT DMA3_IRQHandler [WEAK] + LDR R0, =DMA3_DriverIRQHandler + BX R0 + ENDP + +I2C0_IRQHandler\ + PROC + EXPORT I2C0_IRQHandler [WEAK] + LDR R0, =I2C0_DriverIRQHandler + BX R0 + ENDP + +I2C1_IRQHandler\ + PROC + EXPORT I2C1_IRQHandler [WEAK] + LDR R0, =I2C1_DriverIRQHandler + BX R0 + ENDP + +SPI0_IRQHandler\ + PROC + EXPORT SPI0_IRQHandler [WEAK] + LDR R0, =SPI0_DriverIRQHandler + BX R0 + ENDP + +SPI1_IRQHandler\ + PROC + EXPORT SPI1_IRQHandler [WEAK] + LDR R0, =SPI1_DriverIRQHandler + BX R0 + ENDP + +LPUART0_IRQHandler\ + PROC + EXPORT LPUART0_IRQHandler [WEAK] + LDR R0, =LPUART0_DriverIRQHandler + BX R0 + ENDP + +LPUART1_IRQHandler\ + PROC + EXPORT LPUART1_IRQHandler [WEAK] + LDR R0, =LPUART1_DriverIRQHandler + BX R0 + ENDP + +UART2_FLEXIO_IRQHandler\ + PROC + EXPORT UART2_FLEXIO_IRQHandler [WEAK] + LDR R0, =UART2_FLEXIO_DriverIRQHandler + BX R0 + ENDP + +I2S0_IRQHandler\ + PROC + EXPORT I2S0_IRQHandler [WEAK] + LDR R0, =I2S0_DriverIRQHandler + BX R0 + ENDP + +Default_Handler\ + PROC + EXPORT DMA0_DriverIRQHandler [WEAK] + EXPORT DMA1_DriverIRQHandler [WEAK] + EXPORT DMA2_DriverIRQHandler [WEAK] + EXPORT DMA3_DriverIRQHandler [WEAK] EXPORT Reserved20_IRQHandler [WEAK] EXPORT FTFA_IRQHandler [WEAK] EXPORT PMC_IRQHandler [WEAK] EXPORT LLWU_IRQHandler [WEAK] - EXPORT I2C0_IRQHandler [WEAK] - EXPORT I2C1_IRQHandler [WEAK] - EXPORT SPI0_IRQHandler [WEAK] - EXPORT SPI1_IRQHandler [WEAK] - EXPORT LPUART0_IRQHandler [WEAK] - EXPORT LPUART1_IRQHandler [WEAK] - EXPORT UART2_FLEXIO_IRQHandler [WEAK] + EXPORT I2C0_DriverIRQHandler [WEAK] + EXPORT I2C1_DriverIRQHandler [WEAK] + EXPORT SPI0_DriverIRQHandler [WEAK] + EXPORT SPI1_DriverIRQHandler [WEAK] + EXPORT LPUART0_DriverIRQHandler [WEAK] + EXPORT LPUART1_DriverIRQHandler [WEAK] + EXPORT UART2_FLEXIO_DriverIRQHandler [WEAK] EXPORT ADC0_IRQHandler [WEAK] EXPORT CMP0_IRQHandler [WEAK] EXPORT TPM0_IRQHandler [WEAK] @@ -311,7 +404,7 @@ Default_Handler\ EXPORT RTC_IRQHandler [WEAK] EXPORT RTC_Seconds_IRQHandler [WEAK] EXPORT PIT_IRQHandler [WEAK] - EXPORT I2S0_IRQHandler [WEAK] + EXPORT I2S0_DriverIRQHandler [WEAK] EXPORT USB0_IRQHandler [WEAK] EXPORT DAC0_IRQHandler [WEAK] EXPORT Reserved42_IRQHandler [WEAK] @@ -319,23 +412,23 @@ Default_Handler\ EXPORT LPTMR0_IRQHandler [WEAK] EXPORT LCD_IRQHandler [WEAK] EXPORT PORTA_IRQHandler [WEAK] - EXPORT PORTCD_IRQHandler [WEAK] + EXPORT PORTC_PORTD_IRQHandler [WEAK] EXPORT DefaultISR [WEAK] -DMA0_IRQHandler -DMA1_IRQHandler -DMA2_IRQHandler -DMA3_IRQHandler +DMA0_DriverIRQHandler +DMA1_DriverIRQHandler +DMA2_DriverIRQHandler +DMA3_DriverIRQHandler Reserved20_IRQHandler FTFA_IRQHandler PMC_IRQHandler LLWU_IRQHandler -I2C0_IRQHandler -I2C1_IRQHandler -SPI0_IRQHandler -SPI1_IRQHandler -LPUART0_IRQHandler -LPUART1_IRQHandler -UART2_FLEXIO_IRQHandler +I2C0_DriverIRQHandler +I2C1_DriverIRQHandler +SPI0_DriverIRQHandler +SPI1_DriverIRQHandler +LPUART0_DriverIRQHandler +LPUART1_DriverIRQHandler +UART2_FLEXIO_DriverIRQHandler ADC0_IRQHandler CMP0_IRQHandler TPM0_IRQHandler @@ -344,7 +437,7 @@ TPM2_IRQHandler RTC_IRQHandler RTC_Seconds_IRQHandler PIT_IRQHandler -I2S0_IRQHandler +I2S0_DriverIRQHandler USB0_IRQHandler DAC0_IRQHandler Reserved42_IRQHandler @@ -352,9 +445,10 @@ Reserved43_IRQHandler LPTMR0_IRQHandler LCD_IRQHandler PORTA_IRQHandler -PORTCD_IRQHandler +PORTC_PORTD_IRQHandler DefaultISR - B . + LDR R0, =DefaultISR + BX R0 ENDP ALIGN diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_ARM_STD/sys.cpp b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/sys.cpp similarity index 91% rename from hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_ARM_STD/sys.cpp rename to hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/sys.cpp index 2f1024ace8..b129b2c2a5 100644 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_ARM_STD/sys.cpp +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_ARM_STD/sys.cpp @@ -1,13 +1,13 @@ /* mbed Microcontroller Library - stackheap * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * Setup a fixed single stack/heap memory model, + * + * Setup a fixed single stack/heap memory model, * between the top of the RW/ZI region and the stackpointer */ #ifdef __cplusplus extern "C" { -#endif +#endif #include #include @@ -28,4 +28,4 @@ extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_ #ifdef __cplusplus } -#endif +#endif diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/MKL43Z256xxx4.ld b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/MKL43Z256xxx4.ld new file mode 100644 index 0000000000..08920c6e25 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/MKL43Z256xxx4.ld @@ -0,0 +1,274 @@ +/* +** ################################################################### +** Processors: MKL43Z256VLH4 +** MKL43Z256VMP4 +** +** Compiler: GNU C Compiler +** Reference manual: KL43P64M48SF6RM, Rev.3, Aug 2014 +** Version: rev. 1.6, 2015-07-29 +** Build: b160613 +** +** Abstract: +** Linker file for the GNU C Compiler +** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +__ram_vector_table__ = 1; + +/* Heap 1/4 of ram and stack 1/8 */ +__stack_size__ = 0x1000; +__heap_size__ = 0x2800; + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; +M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0200 : 0x0; + +/* Specify the memory areas */ +MEMORY +{ + m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000200 + m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010 + m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0003FBF0 + m_data (RW) : ORIGIN = 0x1FFFE000, LENGTH = 0x00008000 +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into internal flash */ + .interrupts : + { + __VECTOR_TABLE = .; + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + .flash_config : + { + . = ALIGN(4); + KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ + . = ALIGN(4); + } > m_flash_config + + /* The program code and other data goes into internal flash */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + /* reserve MTB memory at the beginning of m_data */ + .mtb : /* MTB buffer address as defined by the hardware */ + { + . = ALIGN(8); + _mtb_start = .; + KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ + . = ALIGN(8); + _mtb_end = .; + } > m_data + + .interrupts_ram : + { + . = ALIGN(4); + __VECTOR_RAM__ = .; + __interrupts_ram_start__ = .; /* Create a global symbol at data start */ + *(.m_interrupts_ram) /* This is a user defined section */ + . += M_VECTOR_RAM_SIZE; + . = ALIGN(4); + __interrupts_ram_end__ = .; /* Define a global symbol at data end */ + } > m_data + + __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); + __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_data + + __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + USB_RAM_GAP = DEFINED(__usb_ram_size__) ? __usb_ram_size__ : 0x00; + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(.bss) + *(.bss*) + . = ALIGN(512); + USB_RAM_START = .; + . += USB_RAM_GAP; + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_data + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > m_data + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_data + + m_usb_bdt USB_RAM_START (NOLOAD) : + { + *(m_usb_bdt) + USB_RAM_BDT_END = .; + } + + m_usb_global USB_RAM_BDT_END (NOLOAD) : + { + *(m_usb_global) + } + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_data) + LENGTH(m_data); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") +} + diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/startup_MKL43Z4.S b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/startup_MKL43Z4.S new file mode 100644 index 0000000000..d00ce74401 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/startup_MKL43Z4.S @@ -0,0 +1,391 @@ +/* ---------------------------------------------------------------------------------------*/ +/* @file: startup_MKL43Z4.s */ +/* @purpose: CMSIS Cortex-M0P Core Device Startup File */ +/* MKL43Z4 */ +/* @version: 1.8 */ +/* @date: 2016-6-24 */ +/* @build: b160627 */ +/* ---------------------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 1997 - 2016 , Freescale Semiconductor, Inc. */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or without modification, */ +/* are permitted provided that the following conditions are met: */ +/* */ +/* o Redistributions of source code must retain the above copyright notice, this list */ +/* of conditions and the following disclaimer. */ +/* */ +/* o Redistributions in binary form must reproduce the above copyright notice, this */ +/* list of conditions and the following disclaimer in the documentation and/or */ +/* other materials provided with the distribution. */ +/* */ +/* o Neither the name of Freescale Semiconductor, Inc. nor the names of its */ +/* contributors may be used to endorse or promote products derived from this */ +/* software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ +/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ +/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ +/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ +/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ +/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ +/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*****************************************************************************/ +/* Version: GCC for ARM Embedded Processors */ +/*****************************************************************************/ + .syntax unified + .arch armv6-m + + .section .isr_vector, "a" + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler*/ + .long HardFault_Handler /* Hard Fault Handler*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long SVC_Handler /* SVCall Handler*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long PendSV_Handler /* PendSV Handler*/ + .long SysTick_Handler /* SysTick Handler*/ + + /* External Interrupts*/ + .long DMA0_IRQHandler /* DMA channel 0 transfer complete*/ + .long DMA1_IRQHandler /* DMA channel 1 transfer complete*/ + .long DMA2_IRQHandler /* DMA channel 2 transfer complete*/ + .long DMA3_IRQHandler /* DMA channel 3 transfer complete*/ + .long Reserved20_IRQHandler /* Reserved interrupt*/ + .long FTFA_IRQHandler /* Command complete and read collision*/ + .long PMC_IRQHandler /* Low-voltage detect, low-voltage warning*/ + .long LLWU_IRQHandler /* Low leakage wakeup*/ + .long I2C0_IRQHandler /* I2C0 interrupt*/ + .long I2C1_IRQHandler /* I2C1 interrupt*/ + .long SPI0_IRQHandler /* SPI0 single interrupt vector for all sources*/ + .long SPI1_IRQHandler /* SPI1 single interrupt vector for all sources*/ + .long LPUART0_IRQHandler /* LPUART0 status and error*/ + .long LPUART1_IRQHandler /* LPUART1 status and error*/ + .long UART2_FLEXIO_IRQHandler /* UART2 or FLEXIO*/ + .long ADC0_IRQHandler /* ADC0 interrupt*/ + .long CMP0_IRQHandler /* CMP0 interrupt*/ + .long TPM0_IRQHandler /* TPM0 single interrupt vector for all sources*/ + .long TPM1_IRQHandler /* TPM1 single interrupt vector for all sources*/ + .long TPM2_IRQHandler /* TPM2 single interrupt vector for all sources*/ + .long RTC_IRQHandler /* RTC alarm*/ + .long RTC_Seconds_IRQHandler /* RTC seconds*/ + .long PIT_IRQHandler /* PIT interrupt*/ + .long I2S0_IRQHandler /* I2S0 interrupt*/ + .long USB0_IRQHandler /* USB0 interrupt*/ + .long DAC0_IRQHandler /* DAC0 interrupt*/ + .long Reserved42_IRQHandler /* Reserved interrupt*/ + .long Reserved43_IRQHandler /* Reserved interrupt*/ + .long LPTMR0_IRQHandler /* LPTMR0 interrupt*/ + .long LCD_IRQHandler /* LCD interrupt*/ + .long PORTA_IRQHandler /* PORTA Pin detect*/ + .long PORTC_PORTD_IRQHandler /* Single interrupt vector for PORTC; PORTD Pin detect*/ + + .size __isr_vector, . - __isr_vector + +/* Flash Configuration */ + .section .FlashConfig, "a" + .long 0xFFFFFFFF + .long 0xFFFFFFFF + .long 0xFFFFFFFF + .long 0xFFFF3FFE + + .text + .thumb + +/* Reset Handler */ + + .thumb_func + .align 2 + .globl Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + cpsid i /* Mask interrupts */ + .equ VTOR, 0xE000ED08 + ldr r0, =VTOR + ldr r1, =__isr_vector + str r1, [r0] +#ifndef __NO_SYSTEM_INIT + ldr r0,=SystemInit + blx r0 +#endif +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * __etext: End of code section, i.e., begin of data sections to copy from. + * __data_start__/__data_end__: RAM address range that data should be + * copied to. Both must be aligned to 4 bytes boundary. */ + + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + + subs r3, r2 + ble .LC0 + +.LC1: + subs r3, 4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .LC1 +.LC0: + +#ifdef __STARTUP_CLEAR_BSS +/* This part of work usually is done in C library startup code. Otherwise, + * define this macro to enable it in this startup. + * + * Loop to zero out BSS section, which uses following symbols + * in linker script: + * __bss_start__: start of BSS section. Must align to 4 + * __bss_end__: end of BSS section. Must align to 4 + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + subs r2, r1 + ble .LC3 + + movs r0, 0 +.LC2: + str r0, [r1, r2] + subs r2, 4 + bge .LC2 +.LC3: +#endif + cpsie i /* Unmask interrupts */ +#ifndef __START +#define __START _start +#endif +#ifndef __ATOLLIC__ + ldr r0,=__START + blx r0 +#else + ldr r0,=__libc_init_array + blx r0 + ldr r0,=main + bx r0 +#endif + .pool + .size Reset_Handler, . - Reset_Handler + + .align 1 + .thumb_func + .weak DefaultISR + .type DefaultISR, %function +DefaultISR: + ldr r0, =DefaultISR + bx r0 + .size DefaultISR, . - DefaultISR + + .align 1 + .thumb_func + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + ldr r0,=NMI_Handler + bx r0 + .size NMI_Handler, . - NMI_Handler + + .align 1 + .thumb_func + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + ldr r0,=HardFault_Handler + bx r0 + .size HardFault_Handler, . - HardFault_Handler + + .align 1 + .thumb_func + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + ldr r0,=SVC_Handler + bx r0 + .size SVC_Handler, . - SVC_Handler + + .align 1 + .thumb_func + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + ldr r0,=PendSV_Handler + bx r0 + .size PendSV_Handler, . - PendSV_Handler + + .align 1 + .thumb_func + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + ldr r0,=SysTick_Handler + bx r0 + .size SysTick_Handler, . - SysTick_Handler + + .align 1 + .thumb_func + .weak DMA0_IRQHandler + .type DMA0_IRQHandler, %function +DMA0_IRQHandler: + ldr r0,=DMA0_DriverIRQHandler + bx r0 + .size DMA0_IRQHandler, . - DMA0_IRQHandler + + .align 1 + .thumb_func + .weak DMA1_IRQHandler + .type DMA1_IRQHandler, %function +DMA1_IRQHandler: + ldr r0,=DMA1_DriverIRQHandler + bx r0 + .size DMA1_IRQHandler, . - DMA1_IRQHandler + + .align 1 + .thumb_func + .weak DMA2_IRQHandler + .type DMA2_IRQHandler, %function +DMA2_IRQHandler: + ldr r0,=DMA2_DriverIRQHandler + bx r0 + .size DMA2_IRQHandler, . - DMA2_IRQHandler + + .align 1 + .thumb_func + .weak DMA3_IRQHandler + .type DMA3_IRQHandler, %function +DMA3_IRQHandler: + ldr r0,=DMA3_DriverIRQHandler + bx r0 + .size DMA3_IRQHandler, . - DMA3_IRQHandler + + .align 1 + .thumb_func + .weak I2C0_IRQHandler + .type I2C0_IRQHandler, %function +I2C0_IRQHandler: + ldr r0,=I2C0_DriverIRQHandler + bx r0 + .size I2C0_IRQHandler, . - I2C0_IRQHandler + + .align 1 + .thumb_func + .weak I2C1_IRQHandler + .type I2C1_IRQHandler, %function +I2C1_IRQHandler: + ldr r0,=I2C1_DriverIRQHandler + bx r0 + .size I2C1_IRQHandler, . - I2C1_IRQHandler + + .align 1 + .thumb_func + .weak SPI0_IRQHandler + .type SPI0_IRQHandler, %function +SPI0_IRQHandler: + ldr r0,=SPI0_DriverIRQHandler + bx r0 + .size SPI0_IRQHandler, . - SPI0_IRQHandler + + .align 1 + .thumb_func + .weak SPI1_IRQHandler + .type SPI1_IRQHandler, %function +SPI1_IRQHandler: + ldr r0,=SPI1_DriverIRQHandler + bx r0 + .size SPI1_IRQHandler, . - SPI1_IRQHandler + + .align 1 + .thumb_func + .weak LPUART0_IRQHandler + .type LPUART0_IRQHandler, %function +LPUART0_IRQHandler: + ldr r0,=LPUART0_DriverIRQHandler + bx r0 + .size LPUART0_IRQHandler, . - LPUART0_IRQHandler + + .align 1 + .thumb_func + .weak LPUART1_IRQHandler + .type LPUART1_IRQHandler, %function +LPUART1_IRQHandler: + ldr r0,=LPUART1_DriverIRQHandler + bx r0 + .size LPUART1_IRQHandler, . - LPUART1_IRQHandler + + .align 1 + .thumb_func + .weak UART2_FLEXIO_IRQHandler + .type UART2_FLEXIO_IRQHandler, %function +UART2_FLEXIO_IRQHandler: + ldr r0,=UART2_FLEXIO_DriverIRQHandler + bx r0 + .size UART2_FLEXIO_IRQHandler, . - UART2_FLEXIO_IRQHandler + + .align 1 + .thumb_func + .weak I2S0_IRQHandler + .type I2S0_IRQHandler, %function +I2S0_IRQHandler: + ldr r0,=I2S0_DriverIRQHandler + bx r0 + .size I2S0_IRQHandler, . - I2S0_IRQHandler + + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .set \handler_name, DefaultISR + .endm + +/* Exception Handlers */ + def_irq_handler DMA0_DriverIRQHandler + def_irq_handler DMA1_DriverIRQHandler + def_irq_handler DMA2_DriverIRQHandler + def_irq_handler DMA3_DriverIRQHandler + def_irq_handler Reserved20_IRQHandler + def_irq_handler FTFA_IRQHandler + def_irq_handler PMC_IRQHandler + def_irq_handler LLWU_IRQHandler + def_irq_handler I2C0_DriverIRQHandler + def_irq_handler I2C1_DriverIRQHandler + def_irq_handler SPI0_DriverIRQHandler + def_irq_handler SPI1_DriverIRQHandler + def_irq_handler LPUART0_DriverIRQHandler + def_irq_handler LPUART1_DriverIRQHandler + def_irq_handler UART2_FLEXIO_DriverIRQHandler + def_irq_handler ADC0_IRQHandler + def_irq_handler CMP0_IRQHandler + def_irq_handler TPM0_IRQHandler + def_irq_handler TPM1_IRQHandler + def_irq_handler TPM2_IRQHandler + def_irq_handler RTC_IRQHandler + def_irq_handler RTC_Seconds_IRQHandler + def_irq_handler PIT_IRQHandler + def_irq_handler I2S0_DriverIRQHandler + def_irq_handler USB0_IRQHandler + def_irq_handler DAC0_IRQHandler + def_irq_handler Reserved42_IRQHandler + def_irq_handler Reserved43_IRQHandler + def_irq_handler LPTMR0_IRQHandler + def_irq_handler LCD_IRQHandler + def_irq_handler PORTA_IRQHandler + def_irq_handler PORTC_PORTD_IRQHandler + + .end diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_IAR/MKL43Z256xxx4.icf b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_IAR/MKL43Z256xxx4.icf new file mode 100644 index 0000000000..6b645fee86 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_IAR/MKL43Z256xxx4.icf @@ -0,0 +1,112 @@ +/* +** ################################################################### +** Processors: MKL43Z256VLH4 +** MKL43Z256VMP4 +** +** Compiler: IAR ANSI C/C++ Compiler for ARM +** Reference manual: KL43P64M48SF6RM, Rev.3, Aug 2014 +** Version: rev. 1.6, 2015-07-29 +** Build: b160406 +** +** Abstract: +** Linker file for the IAR ANSI C/C++ Compiler for ARM +** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** ################################################################### +*/ +define symbol __ram_vector_table__ = 1; + +/* Heap 1/4 of ram and stack 1/8 */ +define symbol __stack_size__=0x1000; +define symbol __heap_size__=0x2800; + +define symbol __ram_vector_table_size__ = isdefinedsymbol(__ram_vector_table__) ? 0x00000200 : 0; +define symbol __ram_vector_table_offset__ = isdefinedsymbol(__ram_vector_table__) ? 0x000001FF : 0; + +define symbol m_interrupts_start = 0x00000000; +define symbol m_interrupts_end = 0x000001FF; + +define symbol m_flash_config_start = 0x00000400; +define symbol m_flash_config_end = 0x0000040F; + +define symbol m_text_start = 0x00000410; +define symbol m_text_end = 0x0003FFFF; + +define symbol m_interrupts_ram_start = 0x1FFFE000; +define symbol m_interrupts_ram_end = 0x1FFFE000 + __ram_vector_table_offset__; + +define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__; +define symbol m_data_end = 0x20005FFF; + +/* Sizes */ +if (isdefinedsymbol(__stack_size__)) { + define symbol __size_cstack__ = __stack_size__; +} else { + define symbol __size_cstack__ = 0x0400; +} + +if (isdefinedsymbol(__heap_size__)) { + define symbol __size_heap__ = __heap_size__; +} else { + define symbol __size_heap__ = 0x0400; +} + +define exported symbol __VECTOR_TABLE = m_interrupts_start; +define exported symbol __VECTOR_RAM = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start; +define exported symbol __RAM_VECTOR_TABLE_SIZE = __ram_vector_table_size__; + +define memory mem with size = 4G; +define region m_flash_config_region = mem:[from m_flash_config_start to m_flash_config_end]; +define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end] + | mem:[from m_text_start to m_text_end]; +define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]; +define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end]; +define region m_interrupts_ram_region = mem:[from m_interrupts_ram_start to m_interrupts_ram_end]; + +define block CSTACK with alignment = 8, size = __size_cstack__ { }; +define block HEAP with alignment = 8, size = __size_heap__ { }; +define block RW { readwrite }; +define block ZI { zi }; + +initialize by copy { readwrite, section .textrw }; +do not initialize { section .noinit }; + +place at address mem: m_interrupts_start { readonly section .intvec }; +place in m_flash_config_region { section FlashConfig }; +place in TEXT_region { readonly }; +place in DATA_region { block RW }; +place in DATA_region { block ZI }; +place in DATA_region { last block HEAP }; +place in CSTACK_region { block CSTACK }; +place in m_interrupts_ram_region { section m_interrupts_ram }; + diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_IAR/startup_MKL43Z4.s b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_IAR/startup_MKL43Z4.s new file mode 100644 index 0000000000..efcb4d3874 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/TOOLCHAIN_IAR/startup_MKL43Z4.s @@ -0,0 +1,323 @@ +; --------------------------------------------------------------------------------------- +; @file: startup_MKL43Z4.s +; @purpose: CMSIS Cortex-M0P Core Device Startup File +; MKL43Z4 +; @version: 1.8 +; @date: 2016-6-24 +; @build: b160627 +; --------------------------------------------------------------------------------------- +; +; Copyright (c) 1997 - 2016 , Freescale Semiconductor, Inc. +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without modification, +; are permitted provided that the following conditions are met: +; +; o Redistributions of source code must retain the above copyright notice, this list +; of conditions and the following disclaimer. +; +; o Redistributions in binary form must reproduce the above copyright notice, this +; list of conditions and the following disclaimer in the documentation and/or +; other materials provided with the distribution. +; +; o Neither the name of Freescale Semiconductor, Inc. nor the names of its +; contributors may be used to endorse or promote products derived from this +; software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +; ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + + DCD NMI_Handler ;NMI Handler + DCD HardFault_Handler ;Hard Fault Handler + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD 0 ;Reserved +__vector_table_0x1c + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD SVC_Handler ;SVCall Handler + DCD 0 ;Reserved + DCD 0 ;Reserved + DCD PendSV_Handler ;PendSV Handler + DCD SysTick_Handler ;SysTick Handler + + ;External Interrupts + DCD DMA0_IRQHandler ;DMA channel 0 transfer complete + DCD DMA1_IRQHandler ;DMA channel 1 transfer complete + DCD DMA2_IRQHandler ;DMA channel 2 transfer complete + DCD DMA3_IRQHandler ;DMA channel 3 transfer complete + DCD Reserved20_IRQHandler ;Reserved interrupt + DCD FTFA_IRQHandler ;Command complete and read collision + DCD PMC_IRQHandler ;Low-voltage detect, low-voltage warning + DCD LLWU_IRQHandler ;Low leakage wakeup + DCD I2C0_IRQHandler ;I2C0 interrupt + DCD I2C1_IRQHandler ;I2C1 interrupt + DCD SPI0_IRQHandler ;SPI0 single interrupt vector for all sources + DCD SPI1_IRQHandler ;SPI1 single interrupt vector for all sources + DCD LPUART0_IRQHandler ;LPUART0 status and error + DCD LPUART1_IRQHandler ;LPUART1 status and error + DCD UART2_FLEXIO_IRQHandler ;UART2 or FLEXIO + DCD ADC0_IRQHandler ;ADC0 interrupt + DCD CMP0_IRQHandler ;CMP0 interrupt + DCD TPM0_IRQHandler ;TPM0 single interrupt vector for all sources + DCD TPM1_IRQHandler ;TPM1 single interrupt vector for all sources + DCD TPM2_IRQHandler ;TPM2 single interrupt vector for all sources + DCD RTC_IRQHandler ;RTC alarm + DCD RTC_Seconds_IRQHandler ;RTC seconds + DCD PIT_IRQHandler ;PIT interrupt + DCD I2S0_IRQHandler ;I2S0 interrupt + DCD USB0_IRQHandler ;USB0 interrupt + DCD DAC0_IRQHandler ;DAC0 interrupt + DCD Reserved42_IRQHandler ;Reserved interrupt + DCD Reserved43_IRQHandler ;Reserved interrupt + DCD LPTMR0_IRQHandler ;LPTMR0 interrupt + DCD LCD_IRQHandler ;LCD interrupt + DCD PORTA_IRQHandler ;PORTA Pin detect + DCD PORTC_PORTD_IRQHandler ;Single interrupt vector for PORTC; PORTD Pin detect +__Vectors_End + + SECTION FlashConfig:CODE +__FlashConfig + DCD 0xFFFFFFFF + DCD 0xFFFFFFFF + DCD 0xFFFFFFFF + DCD 0xFFFF3FFE +__FlashConfig_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + CPSID I ; Mask interrupts + LDR R0, =0xE000ED08 + LDR R1, =__vector_table + STR R1, [R0] + LDR R0, =SystemInit + BLX R0 + CPSIE I ; Unmask interrupts + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + PUBWEAK DMA0_IRQHandler + PUBWEAK DMA0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA0_IRQHandler + LDR R0, =DMA0_DriverIRQHandler + BX R0 + + PUBWEAK DMA1_IRQHandler + PUBWEAK DMA1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA1_IRQHandler + LDR R0, =DMA1_DriverIRQHandler + BX R0 + + PUBWEAK DMA2_IRQHandler + PUBWEAK DMA2_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA2_IRQHandler + LDR R0, =DMA2_DriverIRQHandler + BX R0 + + PUBWEAK DMA3_IRQHandler + PUBWEAK DMA3_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +DMA3_IRQHandler + LDR R0, =DMA3_DriverIRQHandler + BX R0 + + PUBWEAK Reserved20_IRQHandler + PUBWEAK FTFA_IRQHandler + PUBWEAK PMC_IRQHandler + PUBWEAK LLWU_IRQHandler + PUBWEAK I2C0_IRQHandler + PUBWEAK I2C0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2C0_IRQHandler + LDR R0, =I2C0_DriverIRQHandler + BX R0 + + PUBWEAK I2C1_IRQHandler + PUBWEAK I2C1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2C1_IRQHandler + LDR R0, =I2C1_DriverIRQHandler + BX R0 + + PUBWEAK SPI0_IRQHandler + PUBWEAK SPI0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SPI0_IRQHandler + LDR R0, =SPI0_DriverIRQHandler + BX R0 + + PUBWEAK SPI1_IRQHandler + PUBWEAK SPI1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +SPI1_IRQHandler + LDR R0, =SPI1_DriverIRQHandler + BX R0 + + PUBWEAK LPUART0_IRQHandler + PUBWEAK LPUART0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LPUART0_IRQHandler + LDR R0, =LPUART0_DriverIRQHandler + BX R0 + + PUBWEAK LPUART1_IRQHandler + PUBWEAK LPUART1_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +LPUART1_IRQHandler + LDR R0, =LPUART1_DriverIRQHandler + BX R0 + + PUBWEAK UART2_FLEXIO_IRQHandler + PUBWEAK UART2_FLEXIO_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +UART2_FLEXIO_IRQHandler + LDR R0, =UART2_FLEXIO_DriverIRQHandler + BX R0 + + PUBWEAK ADC0_IRQHandler + PUBWEAK CMP0_IRQHandler + PUBWEAK TPM0_IRQHandler + PUBWEAK TPM1_IRQHandler + PUBWEAK TPM2_IRQHandler + PUBWEAK RTC_IRQHandler + PUBWEAK RTC_Seconds_IRQHandler + PUBWEAK PIT_IRQHandler + PUBWEAK I2S0_IRQHandler + PUBWEAK I2S0_DriverIRQHandler + SECTION .text:CODE:REORDER:NOROOT(2) +I2S0_IRQHandler + LDR R0, =I2S0_DriverIRQHandler + BX R0 + + PUBWEAK USB0_IRQHandler + PUBWEAK DAC0_IRQHandler + PUBWEAK Reserved42_IRQHandler + PUBWEAK Reserved43_IRQHandler + PUBWEAK LPTMR0_IRQHandler + PUBWEAK LCD_IRQHandler + PUBWEAK PORTA_IRQHandler + PUBWEAK PORTC_PORTD_IRQHandler + PUBWEAK DefaultISR + SECTION .text:CODE:REORDER:NOROOT(2) +DMA0_DriverIRQHandler +DMA1_DriverIRQHandler +DMA2_DriverIRQHandler +DMA3_DriverIRQHandler +Reserved20_IRQHandler +FTFA_IRQHandler +PMC_IRQHandler +LLWU_IRQHandler +I2C0_DriverIRQHandler +I2C1_DriverIRQHandler +SPI0_DriverIRQHandler +SPI1_DriverIRQHandler +LPUART0_DriverIRQHandler +LPUART1_DriverIRQHandler +UART2_FLEXIO_DriverIRQHandler +ADC0_IRQHandler +CMP0_IRQHandler +TPM0_IRQHandler +TPM1_IRQHandler +TPM2_IRQHandler +RTC_IRQHandler +RTC_Seconds_IRQHandler +PIT_IRQHandler +I2S0_DriverIRQHandler +USB0_IRQHandler +DAC0_IRQHandler +Reserved42_IRQHandler +Reserved43_IRQHandler +LPTMR0_IRQHandler +LCD_IRQHandler +PORTA_IRQHandler +PORTC_PORTD_IRQHandler +DefaultISR + LDR R0, =DefaultISR + BX R0 + + END diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis.h similarity index 86% rename from hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis.h rename to hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis.h index c7bc71154e..7423a125ba 100644 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis.h +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis.h @@ -1,13 +1,13 @@ /* mbed Microcontroller Library - CMSIS * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * + * * A generic CMSIS include header, pulling in LPC11U24 specifics */ #ifndef MBED_CMSIS_H #define MBED_CMSIS_H -#include "MKL43Z4.h" +#include "fsl_device_registers.h" #include "cmsis_nvic.h" #endif diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis_nvic.c b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis_nvic.c new file mode 100644 index 0000000000..59b37502b2 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis_nvic.c @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2011 ARM Limited. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of ARM Limited nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis_nvic.h" + +extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { + InstallIRQHandler(IRQn, vector); +} + +uint32_t NVIC_GetVector(IRQn_Type IRQn) { + uint32_t *vectors = (uint32_t*)SCB->VTOR; + return vectors[IRQn + 16]; +} diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis_nvic.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis_nvic.h new file mode 100644 index 0000000000..64f36b3167 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/cmsis_nvic.h @@ -0,0 +1,51 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2011 ARM Limited. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of ARM Limited nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_USER_IRQ_OFFSET 16 + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/fsl_device_registers.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/fsl_device_registers.h new file mode 100644 index 0000000000..32b01f90b3 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/fsl_device_registers.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_DEVICE_REGISTERS_H__ +#define __FSL_DEVICE_REGISTERS_H__ + +/* + * Include the cpu specific register header files. + * + * The CPU macro should be declared in the project or makefile. + */ +#if (defined(CPU_MKL43Z128VLH4) || defined(CPU_MKL43Z256VLH4) || defined(CPU_MKL43Z128VMP4) || \ + defined(CPU_MKL43Z256VMP4)) + +#define KL43Z4_SERIES + +/* CMSIS-style register definitions */ +#include "MKL43Z4.h" +/* CPU specific feature definitions */ +#include "MKL43Z4_features.h" + +#else + #error "No valid CPU defined!" +#endif + +#endif /* __FSL_DEVICE_REGISTERS_H__ */ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/system_MKL43Z4.c b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/system_MKL43Z4.c similarity index 61% rename from hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/system_MKL43Z4.c rename to hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/system_MKL43Z4.c index e17528f3b2..bd560b4acb 100644 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/system_MKL43Z4.c +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/system_MKL43Z4.c @@ -1,28 +1,25 @@ /* ** ################################################################### -** Processors: MKL43Z256VLH4 -** MKL43Z128VLH4 -** MKL43Z64VLH4 -** MKL43Z256VMP4 +** Processors: MKL43Z128VLH4 ** MKL43Z128VMP4 -** MKL43Z64VMP4 +** MKL43Z256VLH4 +** MKL43Z256VMP4 ** ** Compilers: Keil ARM C/C++ Compiler ** Freescale C/C++ for Embedded ARM ** GNU C Compiler -** GNU C Compiler - CodeSourcery Sourcery G++ ** IAR ANSI C/C++ Compiler for ARM ** ** Reference manual: KL43P64M48SF6RM, Rev.3, Aug 2014 -** Version: rev. 1.4, 2014-09-01 -** Build: b140904 +** Version: rev. 1.6, 2015-07-29 +** Build: b151217 ** ** Abstract: ** Provides a system configuration function and a global variable that ** contains the system frequency. It configures the device and initializes ** the oscillator (PLL) that is part of the microcontroller device. ** -** Copyright (c) 2014 Freescale Semiconductor, Inc. +** Copyright (c) 2015 Freescale Semiconductor, Inc. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without modification, @@ -84,14 +81,18 @@ ** - rev. 1.4 (2014-09-01) ** USB - USB0_CTL0 was renamed to USB0_OTGCTL register. ** USB - USB0_CTL1 was renamed to USB0_CTL register. +** - rev. 1.5 (2014-09-05) +** USB - Renamed USBEN bitfield of USB0_CTL was renamed to USBENSOFEN. +** - rev. 1.6 (2015-07-29) +** Correction of backward compatibility. ** ** ################################################################### */ /*! * @file MKL43Z4 - * @version 1.4 - * @date 2014-09-01 + * @version 1.6 + * @date 2015-07-29 * @brief Device specific configuration file for MKL43Z4 (implementation file) * * Provides a system configuration function and a global variable that contains @@ -100,7 +101,7 @@ */ #include -#include "MKL43Z4.h" +#include "fsl_device_registers.h" @@ -127,73 +128,6 @@ void SystemInit (void) { SIM->COPC = (uint32_t)0x00u; #endif /* (DISABLE_WDOG) */ - /* Power mode protection initialization */ -#ifdef SMC_PMPROT_VALUE - SMC->PMPROT = SMC_PMPROT_VALUE; -#endif - - /* System clock initialization */ - - /* Set system prescalers and clock sources */ - SIM->CLKDIV1 = SYSTEM_SIM_CLKDIV1_VALUE; /* Set system prescalers */ - SIM->SOPT1 = ((SIM->SOPT1) & (uint32_t)(~(SIM_SOPT1_OSC32KSEL_MASK))) | ((SYSTEM_SIM_SOPT1_VALUE) & (SIM_SOPT1_OSC32KSEL_MASK)); /* Set 32 kHz clock source (ERCLK32K) */ -#define SOPT2_WRITE_MASK ((SIM_SOPT2_USBSRC_MASK) | (SIM_SOPT2_TPMSRC_MASK) | (SIM_SOPT2_LPUART0SRC_MASK) | (SIM_SOPT2_LPUART1SRC_MASK)) /* define mask of written bits. */ - SIM->SOPT2 = ((SIM->SOPT2) & (uint32_t)(~SOPT2_WRITE_MASK)) | ((SYSTEM_SIM_SOPT2_VALUE) & SOPT2_WRITE_MASK); /* Selects the clock source for the TPM counter clock. */ -#if (MCG_MODE == MCG_MODE_LIRC_2M || MCG_MODE == MCG_MODE_LIRC_8M || MCG_MODE == MCG_MODE_HIRC) - /* Set MCG and OSC0 */ -#if (((OSC0_CR_VALUE) & OSC_CR_ERCLKEN_MASK) != 0x00U) - /* SIM_SCGC5: PORTA=1 */ - SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; - /* PORTA_PCR3: ISF=0,MUX=0 */ - PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); - if (((MCG_C2_VALUE) & MCG_C2_EREFS0_MASK) != 0x00U) { - PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); - } -#endif - MCG->SC = MCG_SC_VALUE; /* Set SC (internal reference clock divider) */ - MCG->MC = MCG_MC_VALUE; /* Set MC (high-frequency IRC enable, second LIRC divider) */ - MCG->C1 = MCG_C1_VALUE; /* Set C1 (clock source selection, int. reference enable etc.) */ - MCG->C2 = MCG_C2_VALUE; /* Set C2 (ext. and int. reference clock selection) */ - OSC0->CR = OSC0_CR_VALUE; /* Set OSC0_CR (OSCERCLK enable, oscillator capacitor load) */ - -#else /* MCG_MODE */ - /* Set MCG and OSC0 */ - /* SIM_SCGC5: PORTA=1 */ - SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; - /* PORTA_PCR3: ISF=0,MUX=0 */ - PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); - if (((MCG_C2_VALUE) & MCG_C2_EREFS0_MASK) != 0x00U) { - PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); - } - MCG->SC = MCG_SC_VALUE; /* Set SC (internal reference clock divider) */ - MCG->C2 = MCG_C2_VALUE; /* Set C2 (ext. and int. reference clock selection) */ - OSC0->CR = OSC0_CR_VALUE; /* Set OSC0_CR (OSCERCLK enable, oscillator capacitor load) */ - MCG->C1 = MCG_C1_VALUE; /* Set C1 (clock source selection, int. reference enable etc.) */ - MCG->MC = MCG_MC_VALUE; /* Set MC (high-frequency IRC enable, second LIRC divider) */ - if (((MCG_C2_VALUE) & MCG_C2_EREFS0_MASK) != 0U) { - while((MCG->S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */ - } - } -#endif /* MCG_MODE */ - - /* Common for all MCG modes */ - -#if (MCG_MODE == MCG_MODE_HIRC) - while((MCG->S & MCG_S_CLKST_MASK) != 0x00U) { /* Wait until high internal reference clock is selected as MCG_Lite output */ - } -#elif (MCG_MODE == MCG_MODE_LIRC_2M || MCG_MODE == MCG_MODE_LIRC_8M) - while((MCG->S & MCG_S_CLKST_MASK) != 0x04U) { /* Wait until low internal reference clock is selected as MCG_Lite output */ - } -#elif (MCG_MODE == MCG_MODE_EXT) - while((MCG->S & MCG_S_CLKST_MASK) != 0x08U) { /* Wait until external reference clock is selected as MCG_Lite output */ - } -#endif - if (((SMC_PMCTRL_VALUE) & SMC_PMCTRL_RUNM_MASK) == SMC_PMCTRL_RUNM(0x02U)) { - SMC->PMCTRL = (uint8_t)((SMC_PMCTRL_VALUE) & (SMC_PMCTRL_RUNM_MASK)); /* Enable VLPR mode */ - while(SMC->PMSTAT != 0x04U) { /* Wait until the system is in VLPR mode */ - } - } - } /* ---------------------------------------------------------------------------- diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/system_MKL43Z4.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/system_MKL43Z4.h new file mode 100644 index 0000000000..def506fd24 --- /dev/null +++ b/hal/targets/cmsis/TARGET_Freescale/TARGET_KL43Z/system_MKL43Z4.h @@ -0,0 +1,166 @@ +/* +** ################################################################### +** Processors: MKL43Z128VLH4 +** MKL43Z128VMP4 +** MKL43Z256VLH4 +** MKL43Z256VMP4 +** +** Compilers: Keil ARM C/C++ Compiler +** Freescale C/C++ for Embedded ARM +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** +** Reference manual: KL43P64M48SF6RM, Rev.3, Aug 2014 +** Version: rev. 1.6, 2015-07-29 +** Build: b151217 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright (c) 2015 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** Revisions: +** - rev. 1.0 (2014-03-27) +** Initial version. +** - rev. 1.1 (2014-05-26) +** I2S registers TCR2/RCR2 and others were changed. +** FLEXIO register FLEXIO_VERID has now bitfields: FEATURE, MINOR, MAJOR. +** Names of the bitfields of the FLEXIO_SHIFTBUF have been changed to the appropriate register name e.g.: FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS. +** Peripheral_BASES macros has been changed to Peripheral_BASE_PTRS, e.g.: ADC_BASES to ADC_BASE_PTRS. +** Clock configuration for high range external oscillator has been added. +** RFSYS module access has been added. +** - rev. 1.2 (2014-07-10) +** GPIO - Renamed modules PTA,PTB,PTC,PTD,PTE to GPIOA,GPIOB,GPIOC,GPIOD,GPIOE. +** UART0 - UART0 module renamed to UART2. +** I2S - removed MDR register. +** - rev. 1.3 (2014-08-21) +** UART2 - Removed ED register. +** UART2 - Removed MODEM register. +** UART2 - Removed IR register. +** UART2 - Removed PFIFO register. +** UART2 - Removed CFIFO register. +** UART2 - Removed SFIFO register. +** UART2 - Removed TWFIFO register. +** UART2 - Removed TCFIFO register. +** UART2 - Removed RWFIFO register. +** UART2 - Removed RCFIFO register. +** USB - Removed bitfield REG_EN in CLK_RECOVER_IRC_EN register. +** SIM - Changed bitfield value MCGIRCLK to LIRC_CLK of bitfield CLKOUTSEL in SOPT2 register. +** SIM - Removed bitfield DIEID in SDID register. +** - rev. 1.4 (2014-09-01) +** USB - USB0_CTL0 was renamed to USB0_OTGCTL register. +** USB - USB0_CTL1 was renamed to USB0_CTL register. +** - rev. 1.5 (2014-09-05) +** USB - Renamed USBEN bitfield of USB0_CTL was renamed to USBENSOFEN. +** - rev. 1.6 (2015-07-29) +** Correction of backward compatibility. +** +** ################################################################### +*/ + +/*! + * @file MKL43Z4 + * @version 1.6 + * @date 2015-07-29 + * @brief Device specific configuration file for MKL43Z4 (header file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#ifndef _SYSTEM_MKL43Z4_H_ +#define _SYSTEM_MKL43Z4_H_ /**< Symbol preventing repeated inclusion */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#ifndef DISABLE_WDOG + #define DISABLE_WDOG 1 +#endif + +#define ACK_ISOLATION 1 + +/* Define clock source values */ + +#define CPU_XTAL_CLK_HZ 32768u /* Value of the external crystal or oscillator clock frequency in Hz */ +#define CPU_INT_FAST_CLK_HZ 48000000u /* Value of the fast internal oscillator clock frequency in Hz */ +#define CPU_INT_IRC_CLK_HZ 48000000u /* Value of the 48M internal oscillator clock frequency in Hz */ + +/* Low power mode enable */ +/* SMC_PMPROT: AVLP=1,AVLLS=1 */ +#define SYSTEM_SMC_PMPROT_VALUE 0x2Au /* SMC_PMPROT */ + +#define DEFAULT_SYSTEM_CLOCK 8000000u /* Default System clock value */ +#define CPU_INT_SLOW_CLK_HZ 8000000u /* Value of the slow internal oscillator clock frequency in Hz */ + + +/** + * @brief System clock frequency (core clock) + * + * The system clock frequency supplied to the SysTick timer and the processor + * core clock. This variable can be used by the user application to setup the + * SysTick timer or configure other parameters. It may also be used by debugger to + * query the frequency of the debug timer or configure the trace clock speed + * SystemCoreClock is initialized with a correct predefined value. + */ +extern uint32_t SystemCoreClock; + +/** + * @brief Setup the microcontroller system. + * + * Typically this function configures the oscillator (PLL) that is part of the + * microcontroller device. For systems with variable clock speed it also updates + * the variable SystemCoreClock. SystemInit is called from startup_device file. + */ +void SystemInit (void); + +/** + * @brief Updates the SystemCoreClock variable. + * + * It must be called whenever the core clock is changed during program + * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates + * the current core clock. + */ +void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_MKL43Z4_H_ */ diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/MKL43Z4.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/MKL43Z4.h deleted file mode 100644 index 96162e2a80..0000000000 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/MKL43Z4.h +++ /dev/null @@ -1,8856 +0,0 @@ -/* -** ################################################################### -** Processors: MKL43Z256VLH4 -** MKL43Z128VLH4 -** MKL43Z64VLH4 -** MKL43Z256VMP4 -** MKL43Z128VMP4 -** MKL43Z64VMP4 -** -** Compilers: Keil ARM C/C++ Compiler -** Freescale C/C++ for Embedded ARM -** GNU C Compiler -** GNU C Compiler - CodeSourcery Sourcery G++ -** IAR ANSI C/C++ Compiler for ARM -** -** Reference manual: KL43P64M48SF6RM, Rev.3, Aug 2014 -** Version: rev. 1.5, 2014-09-05 -** Build: b140905 -** -** Abstract: -** CMSIS Peripheral Access Layer for MKL43Z4 -** -** Copyright (c) 1997 - 2014 Freescale Semiconductor, Inc. -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without modification, -** are permitted provided that the following conditions are met: -** -** o Redistributions of source code must retain the above copyright notice, this list -** of conditions and the following disclaimer. -** -** o Redistributions in binary form must reproduce the above copyright notice, this -** list of conditions and the following disclaimer in the documentation and/or -** other materials provided with the distribution. -** -** o Neither the name of Freescale Semiconductor, Inc. nor the names of its -** contributors may be used to endorse or promote products derived from this -** software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -** http: www.freescale.com -** mail: support@freescale.com -** -** Revisions: -** - rev. 1.0 (2014-03-27) -** Initial version. -** - rev. 1.1 (2014-05-26) -** I2S registers TCR2/RCR2 and others were changed. -** FLEXIO register FLEXIO_VERID has now bitfields: FEATURE, MINOR, MAJOR. -** Names of the bitfields of the FLEXIO_SHIFTBUF have been changed to the appropriate register name e.g.: FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS. -** Peripheral_BASES macros has been changed to Peripheral_BASE_PTRS, e.g.: ADC_BASES to ADC_BASE_PTRS. -** Clock configuration for high range external oscillator has been added. -** RFSYS module access has been added. -** - rev. 1.2 (2014-07-10) -** GPIO - Renamed modules PTA,PTB,PTC,PTD,PTE to GPIOA,GPIOB,GPIOC,GPIOD,GPIOE. -** UART0 - UART0 module renamed to UART2. -** I2S - removed MDR register. -** - rev. 1.3 (2014-08-21) -** UART2 - Removed ED register. -** UART2 - Removed MODEM register. -** UART2 - Removed IR register. -** UART2 - Removed PFIFO register. -** UART2 - Removed CFIFO register. -** UART2 - Removed SFIFO register. -** UART2 - Removed TWFIFO register. -** UART2 - Removed TCFIFO register. -** UART2 - Removed RWFIFO register. -** UART2 - Removed RCFIFO register. -** USB - Removed bitfield REG_EN in CLK_RECOVER_IRC_EN register. -** SIM - Changed bitfield value MCGIRCLK to LIRC_CLK of bitfield CLKOUTSEL in SOPT2 register. -** SIM - Removed bitfield DIEID in SDID register. -** - rev. 1.4 (2014-09-01) -** USB - USB0_CTL0 was renamed to USB0_OTGCTL register. -** USB - USB0_CTL1 was renamed to USB0_CTL register. -** - rev. 1.5 (2014-09-05) -** USB - USBEN bitfield of the USB0_CTL renamed to USBENSOFEN. -** -** ################################################################### -*/ - -/*! - * @file MKL43Z4.h - * @version 1.5 - * @date 2014-09-05 - * @brief CMSIS Peripheral Access Layer for MKL43Z4 - * - * CMSIS Peripheral Access Layer for MKL43Z4 - */ - - -/* ---------------------------------------------------------------------------- - -- MCU activation - ---------------------------------------------------------------------------- */ - -/* Prevention from multiple including the same memory map */ -#if !defined(MKL43Z4_H_) /* Check if memory map has not been already included */ -#define MKL43Z4_H_ -#define MCU_MKL43Z4 - -/* Check if another memory map has not been also included */ -#if (defined(MCU_ACTIVE)) - #error MKL43Z4 memory map: There is already included another memory map. Only one memory map can be included. -#endif /* (defined(MCU_ACTIVE)) */ -#define MCU_ACTIVE - -#include - -/** Memory map major version (memory maps with equal major version number are - * compatible) */ -#define MCU_MEM_MAP_VERSION 0x0100u -/** Memory map minor version */ -#define MCU_MEM_MAP_VERSION_MINOR 0x0005u - - -/* ---------------------------------------------------------------------------- - -- Interrupt vector numbers - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup Interrupt_vector_numbers Interrupt vector numbers - * @{ - */ - -/** Interrupt Number Definitions */ -#define NUMBER_OF_INT_VECTORS 48 /**< Number of interrupts in the Vector table */ - -typedef enum IRQn { - /* Auxiliary constants */ - NotAvail_IRQn = -128, /**< Not available device specific interrupt */ - - /* Core interrupts */ - NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ - HardFault_IRQn = -13, /**< Cortex-M0 SV Hard Fault Interrupt */ - SVCall_IRQn = -5, /**< Cortex-M0 SV Call Interrupt */ - PendSV_IRQn = -2, /**< Cortex-M0 Pend SV Interrupt */ - SysTick_IRQn = -1, /**< Cortex-M0 System Tick Interrupt */ - - /* Device specific interrupts */ - DMA0_IRQn = 0, /**< DMA channel 0 transfer complete */ - DMA1_IRQn = 1, /**< DMA channel 1 transfer complete */ - DMA2_IRQn = 2, /**< DMA channel 2 transfer complete */ - DMA3_IRQn = 3, /**< DMA channel 3 transfer complete */ - Reserved20_IRQn = 4, /**< Reserved interrupt */ - FTFA_IRQn = 5, /**< Command complete and read collision */ - PMC_IRQn = 6, /**< Low-voltage detect, low-voltage warning */ - LLWU_IRQn = 7, /**< Low leakage wakeup */ - I2C0_IRQn = 8, /**< I2C0 interrupt */ - I2C1_IRQn = 9, /**< I2C1 interrupt */ - SPI0_IRQn = 10, /**< SPI0 single interrupt vector for all sources */ - SPI1_IRQn = 11, /**< SPI1 single interrupt vector for all sources */ - LPUART0_IRQn = 12, /**< LPUART0 status and error */ - LPUART1_IRQn = 13, /**< LPUART1 status and error */ - UART2_FLEXIO_IRQn = 14, /**< UART2 or FLEXIO */ - ADC0_IRQn = 15, /**< ADC0 interrupt */ - CMP0_IRQn = 16, /**< CMP0 interrupt */ - TPM0_IRQn = 17, /**< TPM0 single interrupt vector for all sources */ - TPM1_IRQn = 18, /**< TPM1 single interrupt vector for all sources */ - TPM2_IRQn = 19, /**< TPM2 single interrupt vector for all sources */ - RTC_IRQn = 20, /**< RTC alarm */ - RTC_Seconds_IRQn = 21, /**< RTC seconds */ - PIT_IRQn = 22, /**< PIT interrupt */ - I2S0_IRQn = 23, /**< I2S0 interrupt */ - USB0_IRQn = 24, /**< USB0 interrupt */ - DAC0_IRQn = 25, /**< DAC0 interrupt */ - Reserved42_IRQn = 26, /**< Reserved interrupt */ - Reserved43_IRQn = 27, /**< Reserved interrupt */ - LPTMR0_IRQn = 28, /**< LPTMR0 interrupt */ - LCD_IRQn = 29, /**< LCD interrupt */ - PORTA_IRQn = 30, /**< PORTA Pin detect */ - PORTCD_IRQn = 31 /**< Single interrupt vector for PORTC; PORTD Pin detect */ -} IRQn_Type; - -/*! - * @} - */ /* end of group Interrupt_vector_numbers */ - - -/* ---------------------------------------------------------------------------- - -- Cortex M0 Core Configuration - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup Cortex_Core_Configuration Cortex M0 Core Configuration - * @{ - */ - -#define __CM0PLUS_REV 0x0000 /**< Core revision r0p0 */ -#define __MPU_PRESENT 0 /**< Defines if an MPU is present or not */ -#define __VTOR_PRESENT 1 /**< Defines if an MPU is present or not */ -#define __NVIC_PRIO_BITS 2 /**< Number of priority bits implemented in the NVIC */ -#define __Vendor_SysTickConfig 0 /**< Vendor specific implementation of SysTickConfig is defined */ - -#include "core_cm0plus.h" /* Core Peripheral Access Layer */ -#include "system_MKL43Z4.h" /* Device specific configuration file */ - -/*! - * @} - */ /* end of group Cortex_Core_Configuration */ - - -/* ---------------------------------------------------------------------------- - -- Device Peripheral Access Layer - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup Peripheral_access_layer Device Peripheral Access Layer - * @{ - */ - - -/* -** Start of section using anonymous unions -*/ - -#if defined(__ARMCC_VERSION) - #pragma push - #pragma anon_unions -#elif defined(__CWCC__) - #pragma push - #pragma cpp_extensions on -#elif defined(__GNUC__) - /* anonymous unions are enabled by default */ -#elif defined(__IAR_SYSTEMS_ICC__) - #pragma language=extended -#else - #error Not supported compiler type -#endif - -/* ---------------------------------------------------------------------------- - -- ADC Peripheral Access Layer - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer - * @{ - */ - -/** ADC - Register Layout Typedef */ -typedef struct { - __IO uint32_t SC1[2]; /**< ADC Status and Control Registers 1, array offset: 0x0, array step: 0x4 */ - __IO uint32_t CFG1; /**< ADC Configuration Register 1, offset: 0x8 */ - __IO uint32_t CFG2; /**< ADC Configuration Register 2, offset: 0xC */ - __I uint32_t R[2]; /**< ADC Data Result Register, array offset: 0x10, array step: 0x4 */ - __IO uint32_t CV1; /**< Compare Value Registers, offset: 0x18 */ - __IO uint32_t CV2; /**< Compare Value Registers, offset: 0x1C */ - __IO uint32_t SC2; /**< Status and Control Register 2, offset: 0x20 */ - __IO uint32_t SC3; /**< Status and Control Register 3, offset: 0x24 */ - __IO uint32_t OFS; /**< ADC Offset Correction Register, offset: 0x28 */ - __IO uint32_t PG; /**< ADC Plus-Side Gain Register, offset: 0x2C */ - __IO uint32_t MG; /**< ADC Minus-Side Gain Register, offset: 0x30 */ - __IO uint32_t CLPD; /**< ADC Plus-Side General Calibration Value Register, offset: 0x34 */ - __IO uint32_t CLPS; /**< ADC Plus-Side General Calibration Value Register, offset: 0x38 */ - __IO uint32_t CLP4; /**< ADC Plus-Side General Calibration Value Register, offset: 0x3C */ - __IO uint32_t CLP3; /**< ADC Plus-Side General Calibration Value Register, offset: 0x40 */ - __IO uint32_t CLP2; /**< ADC Plus-Side General Calibration Value Register, offset: 0x44 */ - __IO uint32_t CLP1; /**< ADC Plus-Side General Calibration Value Register, offset: 0x48 */ - __IO uint32_t CLP0; /**< ADC Plus-Side General Calibration Value Register, offset: 0x4C */ - uint8_t RESERVED_0[4]; - __IO uint32_t CLMD; /**< ADC Minus-Side General Calibration Value Register, offset: 0x54 */ - __IO uint32_t CLMS; /**< ADC Minus-Side General Calibration Value Register, offset: 0x58 */ - __IO uint32_t CLM4; /**< ADC Minus-Side General Calibration Value Register, offset: 0x5C */ - __IO uint32_t CLM3; /**< ADC Minus-Side General Calibration Value Register, offset: 0x60 */ - __IO uint32_t CLM2; /**< ADC Minus-Side General Calibration Value Register, offset: 0x64 */ - __IO uint32_t CLM1; /**< ADC Minus-Side General Calibration Value Register, offset: 0x68 */ - __IO uint32_t CLM0; /**< ADC Minus-Side General Calibration Value Register, offset: 0x6C */ -} ADC_Type, *ADC_MemMapPtr; - -/* ---------------------------------------------------------------------------- - -- ADC - Register accessor macros - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup ADC_Register_Accessor_Macros ADC - Register accessor macros - * @{ - */ - - -/* ADC - Register accessors */ -#define ADC_SC1_REG(base,index) ((base)->SC1[index]) -#define ADC_CFG1_REG(base) ((base)->CFG1) -#define ADC_CFG2_REG(base) ((base)->CFG2) -#define ADC_R_REG(base,index) ((base)->R[index]) -#define ADC_CV1_REG(base) ((base)->CV1) -#define ADC_CV2_REG(base) ((base)->CV2) -#define ADC_SC2_REG(base) ((base)->SC2) -#define ADC_SC3_REG(base) ((base)->SC3) -#define ADC_OFS_REG(base) ((base)->OFS) -#define ADC_PG_REG(base) ((base)->PG) -#define ADC_MG_REG(base) ((base)->MG) -#define ADC_CLPD_REG(base) ((base)->CLPD) -#define ADC_CLPS_REG(base) ((base)->CLPS) -#define ADC_CLP4_REG(base) ((base)->CLP4) -#define ADC_CLP3_REG(base) ((base)->CLP3) -#define ADC_CLP2_REG(base) ((base)->CLP2) -#define ADC_CLP1_REG(base) ((base)->CLP1) -#define ADC_CLP0_REG(base) ((base)->CLP0) -#define ADC_CLMD_REG(base) ((base)->CLMD) -#define ADC_CLMS_REG(base) ((base)->CLMS) -#define ADC_CLM4_REG(base) ((base)->CLM4) -#define ADC_CLM3_REG(base) ((base)->CLM3) -#define ADC_CLM2_REG(base) ((base)->CLM2) -#define ADC_CLM1_REG(base) ((base)->CLM1) -#define ADC_CLM0_REG(base) ((base)->CLM0) - -/*! - * @} - */ /* end of group ADC_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- ADC Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup ADC_Register_Masks ADC Register Masks - * @{ - */ - -/* SC1 Bit Fields */ -#define ADC_SC1_ADCH_MASK 0x1Fu -#define ADC_SC1_ADCH_SHIFT 0 -#define ADC_SC1_ADCH(x) (((uint32_t)(((uint32_t)(x))<CR0) -#define CMP_CR1_REG(base) ((base)->CR1) -#define CMP_FPR_REG(base) ((base)->FPR) -#define CMP_SCR_REG(base) ((base)->SCR) -#define CMP_DACCR_REG(base) ((base)->DACCR) -#define CMP_MUXCR_REG(base) ((base)->MUXCR) - -/*! - * @} - */ /* end of group CMP_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- CMP Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup CMP_Register_Masks CMP Register Masks - * @{ - */ - -/* CR0 Bit Fields */ -#define CMP_CR0_HYSTCTR_MASK 0x3u -#define CMP_CR0_HYSTCTR_SHIFT 0 -#define CMP_CR0_HYSTCTR(x) (((uint8_t)(((uint8_t)(x))<DAT[index].DATL) -#define DAC_DATH_REG(base,index) ((base)->DAT[index].DATH) -#define DAC_SR_REG(base) ((base)->SR) -#define DAC_C0_REG(base) ((base)->C0) -#define DAC_C1_REG(base) ((base)->C1) -#define DAC_C2_REG(base) ((base)->C2) - -/*! - * @} - */ /* end of group DAC_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- DAC Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup DAC_Register_Masks DAC Register Masks - * @{ - */ - -/* DATL Bit Fields */ -#define DAC_DATL_DATA0_MASK 0xFFu -#define DAC_DATL_DATA0_SHIFT 0 -#define DAC_DATL_DATA0(x) (((uint8_t)(((uint8_t)(x))<DMA[index].SAR) -#define DMA_DAR_REG(base,index) ((base)->DMA[index].DAR) -#define DMA_DSR_BCR_REG(base,index) ((base)->DMA[index].DSR_BCR) -#define DMA_DSR_REG(base,index) ((base)->DMA[index].DMA_DSR_ACCESS8BIT.DSR) -#define DMA_DCR_REG(base,index) ((base)->DMA[index].DCR) - -/*! - * @} - */ /* end of group DMA_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- DMA Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup DMA_Register_Masks DMA Register Masks - * @{ - */ - -/* SAR Bit Fields */ -#define DMA_SAR_SAR_MASK 0xFFFFFFFFu -#define DMA_SAR_SAR_SHIFT 0 -#define DMA_SAR_SAR(x) (((uint32_t)(((uint32_t)(x))<CHCFG[index]) - -/*! - * @} - */ /* end of group DMAMUX_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- DMAMUX Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup DMAMUX_Register_Masks DMAMUX Register Masks - * @{ - */ - -/* CHCFG Bit Fields */ -#define DMAMUX_CHCFG_SOURCE_MASK 0x3Fu -#define DMAMUX_CHCFG_SOURCE_SHIFT 0 -#define DMAMUX_CHCFG_SOURCE(x) (((uint8_t)(((uint8_t)(x))<VERID) -#define FLEXIO_PARAM_REG(base) ((base)->PARAM) -#define FLEXIO_CTRL_REG(base) ((base)->CTRL) -#define FLEXIO_SHIFTSTAT_REG(base) ((base)->SHIFTSTAT) -#define FLEXIO_SHIFTERR_REG(base) ((base)->SHIFTERR) -#define FLEXIO_TIMSTAT_REG(base) ((base)->TIMSTAT) -#define FLEXIO_SHIFTSIEN_REG(base) ((base)->SHIFTSIEN) -#define FLEXIO_SHIFTEIEN_REG(base) ((base)->SHIFTEIEN) -#define FLEXIO_TIMIEN_REG(base) ((base)->TIMIEN) -#define FLEXIO_SHIFTSDEN_REG(base) ((base)->SHIFTSDEN) -#define FLEXIO_SHIFTCTL_REG(base,index) ((base)->SHIFTCTL[index]) -#define FLEXIO_SHIFTCFG_REG(base,index) ((base)->SHIFTCFG[index]) -#define FLEXIO_SHIFTBUF_REG(base,index) ((base)->SHIFTBUF[index]) -#define FLEXIO_SHIFTBUFBBS_REG(base,index) ((base)->SHIFTBUFBBS[index]) -#define FLEXIO_SHIFTBUFBYS_REG(base,index) ((base)->SHIFTBUFBYS[index]) -#define FLEXIO_SHIFTBUFBIS_REG(base,index) ((base)->SHIFTBUFBIS[index]) -#define FLEXIO_TIMCTL_REG(base,index) ((base)->TIMCTL[index]) -#define FLEXIO_TIMCFG_REG(base,index) ((base)->TIMCFG[index]) -#define FLEXIO_TIMCMP_REG(base,index) ((base)->TIMCMP[index]) - -/*! - * @} - */ /* end of group FLEXIO_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- FLEXIO Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup FLEXIO_Register_Masks FLEXIO Register Masks - * @{ - */ - -/* VERID Bit Fields */ -#define FLEXIO_VERID_FEATURE_MASK 0xFFFFu -#define FLEXIO_VERID_FEATURE_SHIFT 0 -#define FLEXIO_VERID_FEATURE(x) (((uint32_t)(((uint32_t)(x))<FSTAT) -#define FTFA_FCNFG_REG(base) ((base)->FCNFG) -#define FTFA_FSEC_REG(base) ((base)->FSEC) -#define FTFA_FOPT_REG(base) ((base)->FOPT) -#define FTFA_FCCOB3_REG(base) ((base)->FCCOB3) -#define FTFA_FCCOB2_REG(base) ((base)->FCCOB2) -#define FTFA_FCCOB1_REG(base) ((base)->FCCOB1) -#define FTFA_FCCOB0_REG(base) ((base)->FCCOB0) -#define FTFA_FCCOB7_REG(base) ((base)->FCCOB7) -#define FTFA_FCCOB6_REG(base) ((base)->FCCOB6) -#define FTFA_FCCOB5_REG(base) ((base)->FCCOB5) -#define FTFA_FCCOB4_REG(base) ((base)->FCCOB4) -#define FTFA_FCCOBB_REG(base) ((base)->FCCOBB) -#define FTFA_FCCOBA_REG(base) ((base)->FCCOBA) -#define FTFA_FCCOB9_REG(base) ((base)->FCCOB9) -#define FTFA_FCCOB8_REG(base) ((base)->FCCOB8) -#define FTFA_FPROT3_REG(base) ((base)->FPROT3) -#define FTFA_FPROT2_REG(base) ((base)->FPROT2) -#define FTFA_FPROT1_REG(base) ((base)->FPROT1) -#define FTFA_FPROT0_REG(base) ((base)->FPROT0) - -/*! - * @} - */ /* end of group FTFA_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- FTFA Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup FTFA_Register_Masks FTFA Register Masks - * @{ - */ - -/* FSTAT Bit Fields */ -#define FTFA_FSTAT_MGSTAT0_MASK 0x1u -#define FTFA_FSTAT_MGSTAT0_SHIFT 0 -#define FTFA_FSTAT_FPVIOL_MASK 0x10u -#define FTFA_FSTAT_FPVIOL_SHIFT 4 -#define FTFA_FSTAT_ACCERR_MASK 0x20u -#define FTFA_FSTAT_ACCERR_SHIFT 5 -#define FTFA_FSTAT_RDCOLERR_MASK 0x40u -#define FTFA_FSTAT_RDCOLERR_SHIFT 6 -#define FTFA_FSTAT_CCIF_MASK 0x80u -#define FTFA_FSTAT_CCIF_SHIFT 7 -/* FCNFG Bit Fields */ -#define FTFA_FCNFG_ERSSUSP_MASK 0x10u -#define FTFA_FCNFG_ERSSUSP_SHIFT 4 -#define FTFA_FCNFG_ERSAREQ_MASK 0x20u -#define FTFA_FCNFG_ERSAREQ_SHIFT 5 -#define FTFA_FCNFG_RDCOLLIE_MASK 0x40u -#define FTFA_FCNFG_RDCOLLIE_SHIFT 6 -#define FTFA_FCNFG_CCIE_MASK 0x80u -#define FTFA_FCNFG_CCIE_SHIFT 7 -/* FSEC Bit Fields */ -#define FTFA_FSEC_SEC_MASK 0x3u -#define FTFA_FSEC_SEC_SHIFT 0 -#define FTFA_FSEC_SEC(x) (((uint8_t)(((uint8_t)(x))<PDOR) -#define GPIO_PSOR_REG(base) ((base)->PSOR) -#define GPIO_PCOR_REG(base) ((base)->PCOR) -#define GPIO_PTOR_REG(base) ((base)->PTOR) -#define GPIO_PDIR_REG(base) ((base)->PDIR) -#define GPIO_PDDR_REG(base) ((base)->PDDR) - -/*! - * @} - */ /* end of group GPIO_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- GPIO Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup GPIO_Register_Masks GPIO Register Masks - * @{ - */ - -/* PDOR Bit Fields */ -#define GPIO_PDOR_PDO_MASK 0xFFFFFFFFu -#define GPIO_PDOR_PDO_SHIFT 0 -#define GPIO_PDOR_PDO(x) (((uint32_t)(((uint32_t)(x))<A1) -#define I2C_F_REG(base) ((base)->F) -#define I2C_C1_REG(base) ((base)->C1) -#define I2C_S_REG(base) ((base)->S) -#define I2C_D_REG(base) ((base)->D) -#define I2C_C2_REG(base) ((base)->C2) -#define I2C_FLT_REG(base) ((base)->FLT) -#define I2C_RA_REG(base) ((base)->RA) -#define I2C_SMB_REG(base) ((base)->SMB) -#define I2C_A2_REG(base) ((base)->A2) -#define I2C_SLTH_REG(base) ((base)->SLTH) -#define I2C_SLTL_REG(base) ((base)->SLTL) -#define I2C_S2_REG(base) ((base)->S2) - -/*! - * @} - */ /* end of group I2C_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- I2C Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup I2C_Register_Masks I2C Register Masks - * @{ - */ - -/* A1 Bit Fields */ -#define I2C_A1_AD_MASK 0xFEu -#define I2C_A1_AD_SHIFT 1 -#define I2C_A1_AD(x) (((uint8_t)(((uint8_t)(x))<TCSR) -#define I2S_TCR2_REG(base) ((base)->TCR2) -#define I2S_TCR3_REG(base) ((base)->TCR3) -#define I2S_TCR4_REG(base) ((base)->TCR4) -#define I2S_TCR5_REG(base) ((base)->TCR5) -#define I2S_TDR_REG(base,index) ((base)->TDR[index]) -#define I2S_TMR_REG(base) ((base)->TMR) -#define I2S_RCSR_REG(base) ((base)->RCSR) -#define I2S_RCR2_REG(base) ((base)->RCR2) -#define I2S_RCR3_REG(base) ((base)->RCR3) -#define I2S_RCR4_REG(base) ((base)->RCR4) -#define I2S_RCR5_REG(base) ((base)->RCR5) -#define I2S_RDR_REG(base,index) ((base)->RDR[index]) -#define I2S_RMR_REG(base) ((base)->RMR) -#define I2S_MCR_REG(base) ((base)->MCR) - -/*! - * @} - */ /* end of group I2S_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- I2S Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup I2S_Register_Masks I2S Register Masks - * @{ - */ - -/* TCSR Bit Fields */ -#define I2S_TCSR_FWDE_MASK 0x2u -#define I2S_TCSR_FWDE_SHIFT 1 -#define I2S_TCSR_FWIE_MASK 0x200u -#define I2S_TCSR_FWIE_SHIFT 9 -#define I2S_TCSR_FEIE_MASK 0x400u -#define I2S_TCSR_FEIE_SHIFT 10 -#define I2S_TCSR_SEIE_MASK 0x800u -#define I2S_TCSR_SEIE_SHIFT 11 -#define I2S_TCSR_WSIE_MASK 0x1000u -#define I2S_TCSR_WSIE_SHIFT 12 -#define I2S_TCSR_FWF_MASK 0x20000u -#define I2S_TCSR_FWF_SHIFT 17 -#define I2S_TCSR_FEF_MASK 0x40000u -#define I2S_TCSR_FEF_SHIFT 18 -#define I2S_TCSR_SEF_MASK 0x80000u -#define I2S_TCSR_SEF_SHIFT 19 -#define I2S_TCSR_WSF_MASK 0x100000u -#define I2S_TCSR_WSF_SHIFT 20 -#define I2S_TCSR_SR_MASK 0x1000000u -#define I2S_TCSR_SR_SHIFT 24 -#define I2S_TCSR_FR_MASK 0x2000000u -#define I2S_TCSR_FR_SHIFT 25 -#define I2S_TCSR_BCE_MASK 0x10000000u -#define I2S_TCSR_BCE_SHIFT 28 -#define I2S_TCSR_DBGE_MASK 0x20000000u -#define I2S_TCSR_DBGE_SHIFT 29 -#define I2S_TCSR_STOPE_MASK 0x40000000u -#define I2S_TCSR_STOPE_SHIFT 30 -#define I2S_TCSR_TE_MASK 0x80000000u -#define I2S_TCSR_TE_SHIFT 31 -/* TCR2 Bit Fields */ -#define I2S_TCR2_DIV_MASK 0xFFu -#define I2S_TCR2_DIV_SHIFT 0 -#define I2S_TCR2_DIV(x) (((uint32_t)(((uint32_t)(x))<GCR) -#define LCD_AR_REG(base) ((base)->AR) -#define LCD_FDCR_REG(base) ((base)->FDCR) -#define LCD_FDSR_REG(base) ((base)->FDSR) -#define LCD_PEN_REG(base,index) ((base)->PEN[index]) -#define LCD_BPEN_REG(base,index) ((base)->BPEN[index]) -#define LCD_WF_REG(base,index2) ((base)->WF[index2]) -#define LCD_WF8B_REG(base,index2) ((base)->WF8B[index2]) - -/*! - * @} - */ /* end of group LCD_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- LCD Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup LCD_Register_Masks LCD Register Masks - * @{ - */ - -/* GCR Bit Fields */ -#define LCD_GCR_DUTY_MASK 0x7u -#define LCD_GCR_DUTY_SHIFT 0 -#define LCD_GCR_DUTY(x) (((uint32_t)(((uint32_t)(x))<PE1) -#define LLWU_PE2_REG(base) ((base)->PE2) -#define LLWU_PE3_REG(base) ((base)->PE3) -#define LLWU_PE4_REG(base) ((base)->PE4) -#define LLWU_ME_REG(base) ((base)->ME) -#define LLWU_F1_REG(base) ((base)->F1) -#define LLWU_F2_REG(base) ((base)->F2) -#define LLWU_F3_REG(base) ((base)->F3) -#define LLWU_FILT1_REG(base) ((base)->FILT1) -#define LLWU_FILT2_REG(base) ((base)->FILT2) - -/*! - * @} - */ /* end of group LLWU_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- LLWU Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup LLWU_Register_Masks LLWU Register Masks - * @{ - */ - -/* PE1 Bit Fields */ -#define LLWU_PE1_WUPE0_MASK 0x3u -#define LLWU_PE1_WUPE0_SHIFT 0 -#define LLWU_PE1_WUPE0(x) (((uint8_t)(((uint8_t)(x))<CSR) -#define LPTMR_PSR_REG(base) ((base)->PSR) -#define LPTMR_CMR_REG(base) ((base)->CMR) -#define LPTMR_CNR_REG(base) ((base)->CNR) - -/*! - * @} - */ /* end of group LPTMR_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- LPTMR Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup LPTMR_Register_Masks LPTMR Register Masks - * @{ - */ - -/* CSR Bit Fields */ -#define LPTMR_CSR_TEN_MASK 0x1u -#define LPTMR_CSR_TEN_SHIFT 0 -#define LPTMR_CSR_TMS_MASK 0x2u -#define LPTMR_CSR_TMS_SHIFT 1 -#define LPTMR_CSR_TFC_MASK 0x4u -#define LPTMR_CSR_TFC_SHIFT 2 -#define LPTMR_CSR_TPP_MASK 0x8u -#define LPTMR_CSR_TPP_SHIFT 3 -#define LPTMR_CSR_TPS_MASK 0x30u -#define LPTMR_CSR_TPS_SHIFT 4 -#define LPTMR_CSR_TPS(x) (((uint32_t)(((uint32_t)(x))<BAUD) -#define LPUART_STAT_REG(base) ((base)->STAT) -#define LPUART_CTRL_REG(base) ((base)->CTRL) -#define LPUART_DATA_REG(base) ((base)->DATA) -#define LPUART_MATCH_REG(base) ((base)->MATCH) - -/*! - * @} - */ /* end of group LPUART_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- LPUART Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup LPUART_Register_Masks LPUART Register Masks - * @{ - */ - -/* BAUD Bit Fields */ -#define LPUART_BAUD_SBR_MASK 0x1FFFu -#define LPUART_BAUD_SBR_SHIFT 0 -#define LPUART_BAUD_SBR(x) (((uint32_t)(((uint32_t)(x))<C1) -#define MCG_C2_REG(base) ((base)->C2) -#define MCG_S_REG(base) ((base)->S) -#define MCG_SC_REG(base) ((base)->SC) -#define MCG_HCTRIM_REG(base) ((base)->HCTRIM) -#define MCG_HTTRIM_REG(base) ((base)->HTTRIM) -#define MCG_HFTRIM_REG(base) ((base)->HFTRIM) -#define MCG_MC_REG(base) ((base)->MC) -#define MCG_LTRIMRNG_REG(base) ((base)->LTRIMRNG) -#define MCG_LFTRIM_REG(base) ((base)->LFTRIM) -#define MCG_LSTRIM_REG(base) ((base)->LSTRIM) - -/*! - * @} - */ /* end of group MCG_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- MCG Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup MCG_Register_Masks MCG Register Masks - * @{ - */ - -/* C1 Bit Fields */ -#define MCG_C1_IREFSTEN_MASK 0x1u -#define MCG_C1_IREFSTEN_SHIFT 0 -#define MCG_C1_IRCLKEN_MASK 0x2u -#define MCG_C1_IRCLKEN_SHIFT 1 -#define MCG_C1_CLKS_MASK 0xC0u -#define MCG_C1_CLKS_SHIFT 6 -#define MCG_C1_CLKS(x) (((uint8_t)(((uint8_t)(x))<PLASC) -#define MCM_PLAMC_REG(base) ((base)->PLAMC) -#define MCM_PLACR_REG(base) ((base)->PLACR) -#define MCM_CPO_REG(base) ((base)->CPO) - -/*! - * @} - */ /* end of group MCM_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- MCM Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup MCM_Register_Masks MCM Register Masks - * @{ - */ - -/* PLASC Bit Fields */ -#define MCM_PLASC_ASC_MASK 0xFFu -#define MCM_PLASC_ASC_SHIFT 0 -#define MCM_PLASC_ASC(x) (((uint16_t)(((uint16_t)(x))<POSITION) -#define MTB_MASTER_REG(base) ((base)->MASTER) -#define MTB_FLOW_REG(base) ((base)->FLOW) -#define MTB_BASE_REG(base) ((base)->BASE) -#define MTB_MODECTRL_REG(base) ((base)->MODECTRL) -#define MTB_TAGSET_REG(base) ((base)->TAGSET) -#define MTB_TAGCLEAR_REG(base) ((base)->TAGCLEAR) -#define MTB_LOCKACCESS_REG(base) ((base)->LOCKACCESS) -#define MTB_LOCKSTAT_REG(base) ((base)->LOCKSTAT) -#define MTB_AUTHSTAT_REG(base) ((base)->AUTHSTAT) -#define MTB_DEVICEARCH_REG(base) ((base)->DEVICEARCH) -#define MTB_DEVICECFG_REG(base) ((base)->DEVICECFG) -#define MTB_DEVICETYPID_REG(base) ((base)->DEVICETYPID) -#define MTB_PERIPHID_REG(base,index) ((base)->PERIPHID[index]) -#define MTB_COMPID_REG(base,index) ((base)->COMPID[index]) - -/*! - * @} - */ /* end of group MTB_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- MTB Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup MTB_Register_Masks MTB Register Masks - * @{ - */ - -/* POSITION Bit Fields */ -#define MTB_POSITION_WRAP_MASK 0x4u -#define MTB_POSITION_WRAP_SHIFT 2 -#define MTB_POSITION_POINTER_MASK 0xFFFFFFF8u -#define MTB_POSITION_POINTER_SHIFT 3 -#define MTB_POSITION_POINTER(x) (((uint32_t)(((uint32_t)(x))<CTRL) -#define MTBDWT_COMP_REG(base,index) ((base)->COMPARATOR[index].COMP) -#define MTBDWT_MASK_REG(base,index) ((base)->COMPARATOR[index].MASK) -#define MTBDWT_FCT_REG(base,index) ((base)->COMPARATOR[index].FCT) -#define MTBDWT_TBCTRL_REG(base) ((base)->TBCTRL) -#define MTBDWT_DEVICECFG_REG(base) ((base)->DEVICECFG) -#define MTBDWT_DEVICETYPID_REG(base) ((base)->DEVICETYPID) -#define MTBDWT_PERIPHID_REG(base,index) ((base)->PERIPHID[index]) -#define MTBDWT_COMPID_REG(base,index) ((base)->COMPID[index]) - -/*! - * @} - */ /* end of group MTBDWT_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- MTBDWT Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup MTBDWT_Register_Masks MTBDWT Register Masks - * @{ - */ - -/* CTRL Bit Fields */ -#define MTBDWT_CTRL_DWTCFGCTRL_MASK 0xFFFFFFFu -#define MTBDWT_CTRL_DWTCFGCTRL_SHIFT 0 -#define MTBDWT_CTRL_DWTCFGCTRL(x) (((uint32_t)(((uint32_t)(x))<BACKKEY3) -#define NV_BACKKEY2_REG(base) ((base)->BACKKEY2) -#define NV_BACKKEY1_REG(base) ((base)->BACKKEY1) -#define NV_BACKKEY0_REG(base) ((base)->BACKKEY0) -#define NV_BACKKEY7_REG(base) ((base)->BACKKEY7) -#define NV_BACKKEY6_REG(base) ((base)->BACKKEY6) -#define NV_BACKKEY5_REG(base) ((base)->BACKKEY5) -#define NV_BACKKEY4_REG(base) ((base)->BACKKEY4) -#define NV_FPROT3_REG(base) ((base)->FPROT3) -#define NV_FPROT2_REG(base) ((base)->FPROT2) -#define NV_FPROT1_REG(base) ((base)->FPROT1) -#define NV_FPROT0_REG(base) ((base)->FPROT0) -#define NV_FSEC_REG(base) ((base)->FSEC) -#define NV_FOPT_REG(base) ((base)->FOPT) - -/*! - * @} - */ /* end of group NV_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- NV Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup NV_Register_Masks NV Register Masks - * @{ - */ - -/* BACKKEY3 Bit Fields */ -#define NV_BACKKEY3_KEY_MASK 0xFFu -#define NV_BACKKEY3_KEY_SHIFT 0 -#define NV_BACKKEY3_KEY(x) (((uint8_t)(((uint8_t)(x))<CR) - -/*! - * @} - */ /* end of group OSC_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- OSC Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup OSC_Register_Masks OSC Register Masks - * @{ - */ - -/* CR Bit Fields */ -#define OSC_CR_SC16P_MASK 0x1u -#define OSC_CR_SC16P_SHIFT 0 -#define OSC_CR_SC8P_MASK 0x2u -#define OSC_CR_SC8P_SHIFT 1 -#define OSC_CR_SC4P_MASK 0x4u -#define OSC_CR_SC4P_SHIFT 2 -#define OSC_CR_SC2P_MASK 0x8u -#define OSC_CR_SC2P_SHIFT 3 -#define OSC_CR_EREFSTEN_MASK 0x20u -#define OSC_CR_EREFSTEN_SHIFT 5 -#define OSC_CR_ERCLKEN_MASK 0x80u -#define OSC_CR_ERCLKEN_SHIFT 7 - -/*! - * @} - */ /* end of group OSC_Register_Masks */ - - -/* OSC - Peripheral instance base addresses */ -/** Peripheral OSC0 base address */ -#define OSC0_BASE (0x40065000u) -/** Peripheral OSC0 base pointer */ -#define OSC0 ((OSC_Type *)OSC0_BASE) -#define OSC0_BASE_PTR (OSC0) -/** Array initializer of OSC peripheral base addresses */ -#define OSC_BASE_ADDRS { OSC0_BASE } -/** Array initializer of OSC peripheral base pointers */ -#define OSC_BASE_PTRS { OSC0 } - -/* ---------------------------------------------------------------------------- - -- OSC - Register accessor macros - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup OSC_Register_Accessor_Macros OSC - Register accessor macros - * @{ - */ - - -/* OSC - Register instance definitions */ -/* OSC0 */ -#define OSC0_CR OSC_CR_REG(OSC0) - -/*! - * @} - */ /* end of group OSC_Register_Accessor_Macros */ - - -/*! - * @} - */ /* end of group OSC_Peripheral_Access_Layer */ - - -/* ---------------------------------------------------------------------------- - -- PIT Peripheral Access Layer - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup PIT_Peripheral_Access_Layer PIT Peripheral Access Layer - * @{ - */ - -/** PIT - Register Layout Typedef */ -typedef struct { - __IO uint32_t MCR; /**< PIT Module Control Register, offset: 0x0 */ - uint8_t RESERVED_0[220]; - __I uint32_t LTMR64H; /**< PIT Upper Lifetime Timer Register, offset: 0xE0 */ - __I uint32_t LTMR64L; /**< PIT Lower Lifetime Timer Register, offset: 0xE4 */ - uint8_t RESERVED_1[24]; - struct { /* offset: 0x100, array step: 0x10 */ - __IO uint32_t LDVAL; /**< Timer Load Value Register, array offset: 0x100, array step: 0x10 */ - __I uint32_t CVAL; /**< Current Timer Value Register, array offset: 0x104, array step: 0x10 */ - __IO uint32_t TCTRL; /**< Timer Control Register, array offset: 0x108, array step: 0x10 */ - __IO uint32_t TFLG; /**< Timer Flag Register, array offset: 0x10C, array step: 0x10 */ - } CHANNEL[2]; -} PIT_Type, *PIT_MemMapPtr; - -/* ---------------------------------------------------------------------------- - -- PIT - Register accessor macros - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup PIT_Register_Accessor_Macros PIT - Register accessor macros - * @{ - */ - - -/* PIT - Register accessors */ -#define PIT_MCR_REG(base) ((base)->MCR) -#define PIT_LTMR64H_REG(base) ((base)->LTMR64H) -#define PIT_LTMR64L_REG(base) ((base)->LTMR64L) -#define PIT_LDVAL_REG(base,index) ((base)->CHANNEL[index].LDVAL) -#define PIT_CVAL_REG(base,index) ((base)->CHANNEL[index].CVAL) -#define PIT_TCTRL_REG(base,index) ((base)->CHANNEL[index].TCTRL) -#define PIT_TFLG_REG(base,index) ((base)->CHANNEL[index].TFLG) - -/*! - * @} - */ /* end of group PIT_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- PIT Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup PIT_Register_Masks PIT Register Masks - * @{ - */ - -/* MCR Bit Fields */ -#define PIT_MCR_FRZ_MASK 0x1u -#define PIT_MCR_FRZ_SHIFT 0 -#define PIT_MCR_MDIS_MASK 0x2u -#define PIT_MCR_MDIS_SHIFT 1 -/* LTMR64H Bit Fields */ -#define PIT_LTMR64H_LTH_MASK 0xFFFFFFFFu -#define PIT_LTMR64H_LTH_SHIFT 0 -#define PIT_LTMR64H_LTH(x) (((uint32_t)(((uint32_t)(x))<LVDSC1) -#define PMC_LVDSC2_REG(base) ((base)->LVDSC2) -#define PMC_REGSC_REG(base) ((base)->REGSC) - -/*! - * @} - */ /* end of group PMC_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- PMC Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup PMC_Register_Masks PMC Register Masks - * @{ - */ - -/* LVDSC1 Bit Fields */ -#define PMC_LVDSC1_LVDV_MASK 0x3u -#define PMC_LVDSC1_LVDV_SHIFT 0 -#define PMC_LVDSC1_LVDV(x) (((uint8_t)(((uint8_t)(x))<PCR[index]) -#define PORT_GPCLR_REG(base) ((base)->GPCLR) -#define PORT_GPCHR_REG(base) ((base)->GPCHR) -#define PORT_ISFR_REG(base) ((base)->ISFR) - -/*! - * @} - */ /* end of group PORT_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- PORT Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup PORT_Register_Masks PORT Register Masks - * @{ - */ - -/* PCR Bit Fields */ -#define PORT_PCR_PS_MASK 0x1u -#define PORT_PCR_PS_SHIFT 0 -#define PORT_PCR_PE_MASK 0x2u -#define PORT_PCR_PE_SHIFT 1 -#define PORT_PCR_SRE_MASK 0x4u -#define PORT_PCR_SRE_SHIFT 2 -#define PORT_PCR_PFE_MASK 0x10u -#define PORT_PCR_PFE_SHIFT 4 -#define PORT_PCR_DSE_MASK 0x40u -#define PORT_PCR_DSE_SHIFT 6 -#define PORT_PCR_MUX_MASK 0x700u -#define PORT_PCR_MUX_SHIFT 8 -#define PORT_PCR_MUX(x) (((uint32_t)(((uint32_t)(x))<SRS0) -#define RCM_SRS1_REG(base) ((base)->SRS1) -#define RCM_RPFC_REG(base) ((base)->RPFC) -#define RCM_RPFW_REG(base) ((base)->RPFW) -#define RCM_FM_REG(base) ((base)->FM) -#define RCM_MR_REG(base) ((base)->MR) -#define RCM_SSRS0_REG(base) ((base)->SSRS0) -#define RCM_SSRS1_REG(base) ((base)->SSRS1) - -/*! - * @} - */ /* end of group RCM_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- RCM Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup RCM_Register_Masks RCM Register Masks - * @{ - */ - -/* SRS0 Bit Fields */ -#define RCM_SRS0_WAKEUP_MASK 0x1u -#define RCM_SRS0_WAKEUP_SHIFT 0 -#define RCM_SRS0_LVD_MASK 0x2u -#define RCM_SRS0_LVD_SHIFT 1 -#define RCM_SRS0_WDOG_MASK 0x20u -#define RCM_SRS0_WDOG_SHIFT 5 -#define RCM_SRS0_PIN_MASK 0x40u -#define RCM_SRS0_PIN_SHIFT 6 -#define RCM_SRS0_POR_MASK 0x80u -#define RCM_SRS0_POR_SHIFT 7 -/* SRS1 Bit Fields */ -#define RCM_SRS1_LOCKUP_MASK 0x2u -#define RCM_SRS1_LOCKUP_SHIFT 1 -#define RCM_SRS1_SW_MASK 0x4u -#define RCM_SRS1_SW_SHIFT 2 -#define RCM_SRS1_MDM_AP_MASK 0x8u -#define RCM_SRS1_MDM_AP_SHIFT 3 -#define RCM_SRS1_SACKERR_MASK 0x20u -#define RCM_SRS1_SACKERR_SHIFT 5 -/* RPFC Bit Fields */ -#define RCM_RPFC_RSTFLTSRW_MASK 0x3u -#define RCM_RPFC_RSTFLTSRW_SHIFT 0 -#define RCM_RPFC_RSTFLTSRW(x) (((uint8_t)(((uint8_t)(x))<REG[index]) - -/*! - * @} - */ /* end of group RFSYS_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- RFSYS Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup RFSYS_Register_Masks RFSYS Register Masks - * @{ - */ - -/* REG Bit Fields */ -#define RFSYS_REG_LL_MASK 0xFFu -#define RFSYS_REG_LL_SHIFT 0 -#define RFSYS_REG_LL(x) (((uint32_t)(((uint32_t)(x))<ENTRY[index]) -#define ROM_TABLEMARK_REG(base) ((base)->TABLEMARK) -#define ROM_SYSACCESS_REG(base) ((base)->SYSACCESS) -#define ROM_PERIPHID4_REG(base) ((base)->PERIPHID4) -#define ROM_PERIPHID5_REG(base) ((base)->PERIPHID5) -#define ROM_PERIPHID6_REG(base) ((base)->PERIPHID6) -#define ROM_PERIPHID7_REG(base) ((base)->PERIPHID7) -#define ROM_PERIPHID0_REG(base) ((base)->PERIPHID0) -#define ROM_PERIPHID1_REG(base) ((base)->PERIPHID1) -#define ROM_PERIPHID2_REG(base) ((base)->PERIPHID2) -#define ROM_PERIPHID3_REG(base) ((base)->PERIPHID3) -#define ROM_COMPID_REG(base,index) ((base)->COMPID[index]) - -/*! - * @} - */ /* end of group ROM_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- ROM Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup ROM_Register_Masks ROM Register Masks - * @{ - */ - -/* ENTRY Bit Fields */ -#define ROM_ENTRY_ENTRY_MASK 0xFFFFFFFFu -#define ROM_ENTRY_ENTRY_SHIFT 0 -#define ROM_ENTRY_ENTRY(x) (((uint32_t)(((uint32_t)(x))<TSR) -#define RTC_TPR_REG(base) ((base)->TPR) -#define RTC_TAR_REG(base) ((base)->TAR) -#define RTC_TCR_REG(base) ((base)->TCR) -#define RTC_CR_REG(base) ((base)->CR) -#define RTC_SR_REG(base) ((base)->SR) -#define RTC_LR_REG(base) ((base)->LR) -#define RTC_IER_REG(base) ((base)->IER) - -/*! - * @} - */ /* end of group RTC_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- RTC Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup RTC_Register_Masks RTC Register Masks - * @{ - */ - -/* TSR Bit Fields */ -#define RTC_TSR_TSR_MASK 0xFFFFFFFFu -#define RTC_TSR_TSR_SHIFT 0 -#define RTC_TSR_TSR(x) (((uint32_t)(((uint32_t)(x))<SOPT1) -#define SIM_SOPT1CFG_REG(base) ((base)->SOPT1CFG) -#define SIM_SOPT2_REG(base) ((base)->SOPT2) -#define SIM_SOPT4_REG(base) ((base)->SOPT4) -#define SIM_SOPT5_REG(base) ((base)->SOPT5) -#define SIM_SOPT7_REG(base) ((base)->SOPT7) -#define SIM_SDID_REG(base) ((base)->SDID) -#define SIM_SCGC4_REG(base) ((base)->SCGC4) -#define SIM_SCGC5_REG(base) ((base)->SCGC5) -#define SIM_SCGC6_REG(base) ((base)->SCGC6) -#define SIM_SCGC7_REG(base) ((base)->SCGC7) -#define SIM_CLKDIV1_REG(base) ((base)->CLKDIV1) -#define SIM_FCFG1_REG(base) ((base)->FCFG1) -#define SIM_FCFG2_REG(base) ((base)->FCFG2) -#define SIM_UIDMH_REG(base) ((base)->UIDMH) -#define SIM_UIDML_REG(base) ((base)->UIDML) -#define SIM_UIDL_REG(base) ((base)->UIDL) -#define SIM_COPC_REG(base) ((base)->COPC) -#define SIM_SRVCOP_REG(base) ((base)->SRVCOP) - -/*! - * @} - */ /* end of group SIM_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- SIM Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup SIM_Register_Masks SIM Register Masks - * @{ - */ - -/* SOPT1 Bit Fields */ -#define SIM_SOPT1_OSC32KOUT_MASK 0x30000u -#define SIM_SOPT1_OSC32KOUT_SHIFT 16 -#define SIM_SOPT1_OSC32KOUT(x) (((uint32_t)(((uint32_t)(x))<PMPROT) -#define SMC_PMCTRL_REG(base) ((base)->PMCTRL) -#define SMC_STOPCTRL_REG(base) ((base)->STOPCTRL) -#define SMC_PMSTAT_REG(base) ((base)->PMSTAT) - -/*! - * @} - */ /* end of group SMC_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- SMC Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup SMC_Register_Masks SMC Register Masks - * @{ - */ - -/* PMPROT Bit Fields */ -#define SMC_PMPROT_AVLLS_MASK 0x2u -#define SMC_PMPROT_AVLLS_SHIFT 1 -#define SMC_PMPROT_ALLS_MASK 0x8u -#define SMC_PMPROT_ALLS_SHIFT 3 -#define SMC_PMPROT_AVLP_MASK 0x20u -#define SMC_PMPROT_AVLP_SHIFT 5 -/* PMCTRL Bit Fields */ -#define SMC_PMCTRL_STOPM_MASK 0x7u -#define SMC_PMCTRL_STOPM_SHIFT 0 -#define SMC_PMCTRL_STOPM(x) (((uint8_t)(((uint8_t)(x))<S) -#define SPI_BR_REG(base) ((base)->BR) -#define SPI_C2_REG(base) ((base)->C2) -#define SPI_C1_REG(base) ((base)->C1) -#define SPI_ML_REG(base) ((base)->ML) -#define SPI_MH_REG(base) ((base)->MH) -#define SPI_DL_REG(base) ((base)->DL) -#define SPI_DH_REG(base) ((base)->DH) -#define SPI_CI_REG(base) ((base)->CI) -#define SPI_C3_REG(base) ((base)->C3) - -/*! - * @} - */ /* end of group SPI_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- SPI Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup SPI_Register_Masks SPI Register Masks - * @{ - */ - -/* S Bit Fields */ -#define SPI_S_RFIFOEF_MASK 0x1u -#define SPI_S_RFIFOEF_SHIFT 0 -#define SPI_S_TXFULLF_MASK 0x2u -#define SPI_S_TXFULLF_SHIFT 1 -#define SPI_S_TNEAREF_MASK 0x4u -#define SPI_S_TNEAREF_SHIFT 2 -#define SPI_S_RNFULLF_MASK 0x8u -#define SPI_S_RNFULLF_SHIFT 3 -#define SPI_S_MODF_MASK 0x10u -#define SPI_S_MODF_SHIFT 4 -#define SPI_S_SPTEF_MASK 0x20u -#define SPI_S_SPTEF_SHIFT 5 -#define SPI_S_SPMF_MASK 0x40u -#define SPI_S_SPMF_SHIFT 6 -#define SPI_S_SPRF_MASK 0x80u -#define SPI_S_SPRF_SHIFT 7 -/* BR Bit Fields */ -#define SPI_BR_SPR_MASK 0xFu -#define SPI_BR_SPR_SHIFT 0 -#define SPI_BR_SPR(x) (((uint8_t)(((uint8_t)(x))<SC) -#define TPM_CNT_REG(base) ((base)->CNT) -#define TPM_MOD_REG(base) ((base)->MOD) -#define TPM_CnSC_REG(base,index) ((base)->CONTROLS[index].CnSC) -#define TPM_CnV_REG(base,index) ((base)->CONTROLS[index].CnV) -#define TPM_STATUS_REG(base) ((base)->STATUS) -#define TPM_POL_REG(base) ((base)->POL) -#define TPM_CONF_REG(base) ((base)->CONF) - -/*! - * @} - */ /* end of group TPM_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- TPM Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup TPM_Register_Masks TPM Register Masks - * @{ - */ - -/* SC Bit Fields */ -#define TPM_SC_PS_MASK 0x7u -#define TPM_SC_PS_SHIFT 0 -#define TPM_SC_PS(x) (((uint32_t)(((uint32_t)(x))<BDH) -#define UART_BDL_REG(base) ((base)->BDL) -#define UART_C1_REG(base) ((base)->C1) -#define UART_C2_REG(base) ((base)->C2) -#define UART_S1_REG(base) ((base)->S1) -#define UART_S2_REG(base) ((base)->S2) -#define UART_C3_REG(base) ((base)->C3) -#define UART_D_REG(base) ((base)->D) -#define UART_MA1_REG(base) ((base)->MA1) -#define UART_MA2_REG(base) ((base)->MA2) -#define UART_C4_REG(base) ((base)->C4) -#define UART_C5_REG(base) ((base)->C5) -#define UART_C7816_REG(base) ((base)->C7816) -#define UART_IE7816_REG(base) ((base)->IE7816) -#define UART_IS7816_REG(base) ((base)->IS7816) -#define UART_WP7816_REG(base) ((base)->WP7816) -#define UART_WN7816_REG(base) ((base)->WN7816) -#define UART_WF7816_REG(base) ((base)->WF7816) -#define UART_ET7816_REG(base) ((base)->ET7816) -#define UART_TL7816_REG(base) ((base)->TL7816) -#define UART_AP7816A_T0_REG(base) ((base)->AP7816A_T0) -#define UART_AP7816B_T0_REG(base) ((base)->AP7816B_T0) -#define UART_WP7816A_T0_REG(base) ((base)->TYPE0.WP7816A_T0) -#define UART_WP7816B_T0_REG(base) ((base)->TYPE0.WP7816B_T0) -#define UART_WP7816A_T1_REG(base) ((base)->TYPE1.WP7816A_T1) -#define UART_WP7816B_T1_REG(base) ((base)->TYPE1.WP7816B_T1) -#define UART_WGP7816_T1_REG(base) ((base)->WGP7816_T1) -#define UART_WP7816C_T1_REG(base) ((base)->WP7816C_T1) - -/*! - * @} - */ /* end of group UART_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- UART Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup UART_Register_Masks UART Register Masks - * @{ - */ - -/* BDH Bit Fields */ -#define UART_BDH_SBR_MASK 0x1Fu -#define UART_BDH_SBR_SHIFT 0 -#define UART_BDH_SBR(x) (((uint8_t)(((uint8_t)(x))<PERID) -#define USB_IDCOMP_REG(base) ((base)->IDCOMP) -#define USB_REV_REG(base) ((base)->REV) -#define USB_ADDINFO_REG(base) ((base)->ADDINFO) -#define USB_OTGCTL_REG(base) ((base)->OTGCTL) -#define USB_ISTAT_REG(base) ((base)->ISTAT) -#define USB_INTEN_REG(base) ((base)->INTEN) -#define USB_ERRSTAT_REG(base) ((base)->ERRSTAT) -#define USB_ERREN_REG(base) ((base)->ERREN) -#define USB_STAT_REG(base) ((base)->STAT) -#define USB_CTL_REG(base) ((base)->CTL) -#define USB_ADDR_REG(base) ((base)->ADDR) -#define USB_BDTPAGE1_REG(base) ((base)->BDTPAGE1) -#define USB_FRMNUML_REG(base) ((base)->FRMNUML) -#define USB_FRMNUMH_REG(base) ((base)->FRMNUMH) -#define USB_BDTPAGE2_REG(base) ((base)->BDTPAGE2) -#define USB_BDTPAGE3_REG(base) ((base)->BDTPAGE3) -#define USB_ENDPT_REG(base,index) ((base)->ENDPOINT[index].ENDPT) -#define USB_USBCTRL_REG(base) ((base)->USBCTRL) -#define USB_OBSERVE_REG(base) ((base)->OBSERVE) -#define USB_CONTROL_REG(base) ((base)->CONTROL) -#define USB_USBTRC0_REG(base) ((base)->USBTRC0) -#define USB_USBFRMADJUST_REG(base) ((base)->USBFRMADJUST) -#define USB_CLK_RECOVER_CTRL_REG(base) ((base)->CLK_RECOVER_CTRL) -#define USB_CLK_RECOVER_IRC_EN_REG(base) ((base)->CLK_RECOVER_IRC_EN) -#define USB_CLK_RECOVER_INT_EN_REG(base) ((base)->CLK_RECOVER_INT_EN) -#define USB_CLK_RECOVER_INT_STATUS_REG(base) ((base)->CLK_RECOVER_INT_STATUS) - -/*! - * @} - */ /* end of group USB_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- USB Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup USB_Register_Masks USB Register Masks - * @{ - */ - -/* PERID Bit Fields */ -#define USB_PERID_ID_MASK 0x3Fu -#define USB_PERID_ID_SHIFT 0 -#define USB_PERID_ID(x) (((uint8_t)(((uint8_t)(x))<TRM) -#define VREF_SC_REG(base) ((base)->SC) - -/*! - * @} - */ /* end of group VREF_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- VREF Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup VREF_Register_Masks VREF Register Masks - * @{ - */ - -/* TRM Bit Fields */ -#define VREF_TRM_TRIM_MASK 0x3Fu -#define VREF_TRM_TRIM_SHIFT 0 -#define VREF_TRM_TRIM(x) (((uint8_t)(((uint8_t)(x))< VECTORS - - .flash_protect : - { - KEEP(*(.kinetis_flash_config_field)) - . = ALIGN(4); - } > FLASH_PROTECTION - - .text : - { - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - KEEP(*(.eh_frame*)) - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - __etext = .; - - .data : AT (__etext) - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP(*(SORT(.fini_array.*))) - KEEP(*(.fini_array)) - PROVIDE_HIDDEN (__fini_array_end = .); - - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - - } > RAM - - .bss : - { - __bss_start__ = .; - *(.bss*) - *(COMMON) - __bss_end__ = .; - } > RAM - - .heap : - { - __end__ = .; - end = __end__; - *(.heap*) - __HeapLimit = .; - } > RAM - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy : - { - *(.stack) - } > RAM - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") -} diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/startup_MKL43Z4.S b/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/startup_MKL43Z4.S deleted file mode 100644 index 7f1b04ccfe..0000000000 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/TOOLCHAIN_GCC_ARM/startup_MKL43Z4.S +++ /dev/null @@ -1,243 +0,0 @@ -/* KL43Z startup ARM GCC - * Purpose: startup file for Cortex-M0 devices. Should use with - * GCC for ARM Embedded Processors - * Version: V1.3 - * Date: 10 Nov 2014 - * - * Copyright (c) 2011, ARM Limited - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the ARM Limited nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL ARM LIMITED BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - .syntax unified - .arch armv6-m - -/* Memory Model - The HEAP starts at the end of the DATA section and grows upward. - - The STACK starts at the end of the RAM and grows downward. - - The HEAP and stack STACK are only checked at compile time: - (DATA_SIZE + HEAP_SIZE + STACK_SIZE) < RAM_SIZE - - This is just a check for the bare minimum for the Heap+Stack area before - aborting compilation, it is not the run time limit: - Heap_Size + Stack_Size = 0x200 + 0x400 = 0x600 - */ - .section .stack - .align 3 -#ifdef __STACK_SIZE - .equ Stack_Size, __STACK_SIZE -#else - .equ Stack_Size, 0x400 -#endif - .globl __StackTop - .globl __StackLimit -__StackLimit: - .space Stack_Size - .size __StackLimit, . - __StackLimit -__StackTop: - .size __StackTop, . - __StackTop - - .section .heap - .align 3 -#ifdef __HEAP_SIZE - .equ Heap_Size, __HEAP_SIZE -#else - .equ Heap_Size, 0x200 -#endif - .globl __HeapBase - .globl __HeapLimit -__HeapBase: - .space Heap_Size - .size __HeapBase, . - __HeapBase -__HeapLimit: - .size __HeapLimit, . - __HeapLimit - - .section .vector_table,"a",%progbits - .align 2 - .globl __isr_vector -__isr_vector: - .long __StackTop /* Top of Stack */ - .long Reset_Handler /* Reset Handler */ - .long NMI_Handler /* NMI Handler */ - .long HardFault_Handler /* Hard Fault Handler */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long SVC_Handler /* SVCall Handler */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long PendSV_Handler /* PendSV Handler */ - .long SysTick_Handler /* SysTick Handler */ - - /* External interrupts */ - .long DMA0_IRQHandler /* DMA channel 0 transfer complete interrupt */ - .long DMA1_IRQHandler /* DMA channel 1 transfer complete interrupt */ - .long DMA2_IRQHandler /* DMA channel 2 transfer complete interrupt */ - .long DMA3_IRQHandler /* DMA channel 3 transfer complete interrupt */ - .long Default_Handler /* Reserved interrupt 20 */ - .long FTFA_IRQHandler /* FTFA interrupt */ - .long PMC_IRQHandler /* Low-voltage detect, low-voltage warning*/ - .long LLWU_IRQHandler /* Low leakage wakeup*/ - .long I2C0_IRQHandler /* I2C0 interrupt*/ - .long I2C1_IRQHandler /* I2C1 interrupt*/ - .long SPI0_IRQHandler /* SPI0 single interrupt vector for all sources*/ - .long SPI1_IRQHandler /* SPI1 single interrupt vector for all sources*/ - .long LPUART0_IRQHandler /* LPUART0 status and error*/ - .long LPUART1_IRQHandler /* LPUART1 status and error*/ - .long UART2_FLEXIO_IRQHandler /* UART2 or FLEXIO*/ - .long ADC0_IRQHandler /* ADC0 interrupt*/ - .long CMP0_IRQHandler /* CMP0 interrupt*/ - .long TPM0_IRQHandler /* TPM0 single interrupt vector for all sources*/ - .long TPM1_IRQHandler /* TPM1 single interrupt vector for all sources*/ - .long TPM2_IRQHandler /* TPM2 single interrupt vector for all sources*/ - .long RTC_IRQHandler /* RTC alarm*/ - .long RTC_Seconds_IRQHandler /* RTC seconds*/ - .long PIT_IRQHandler /* PIT interrupt*/ - .long I2S0_IRQHandler /* I2S0 interrupt*/ - .long USB0_IRQHandler /* USB0 interrupt*/ - .long DAC0_IRQHandler /* DAC0 interrupt*/ - .long Reserved42_IRQHandler /* Reserved interrupt*/ - .long Reserved43_IRQHandler /* Reserved interrupt*/ - .long LPTMR0_IRQHandler /* LPTMR0 interrupt*/ - .long LCD_IRQHandler /* LCD interrupt*/ - .long PORTA_IRQHandler /* PORTA Pin detect*/ - .long PORTCD_IRQHandler /* Single interrupt vector for PORTC; PORTD Pin detect*/ - - .size __isr_vector, . - __isr_vector - - /* Reset Handler */ - .section .text.Reset_Handler - .thumb - .thumb_func - .align 2 - .globl Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - /* Loop to copy data from read only memory to RAM. The ranges - * of copy from/to are specified by following symbols evaluated in - * linker script. - * __etext: End of code section, i.e., begin of data sections to copy from. - * __data_start__/__data_end__: RAM address range that data should be - * copied to. Both must be aligned to 4 bytes boundary. */ - ldr r1, =__etext - ldr r2, =__data_start__ - ldr r3, =__data_end__ - - subs r3, r2 - ble .Lflash_to_ram_loop_end - - movs r4, 0 -.Lflash_to_ram_loop: - ldr r0, [r1,r4] - str r0, [r2,r4] - adds r4, 4 - cmp r4, r3 - blt .Lflash_to_ram_loop -.Lflash_to_ram_loop_end: - - ldr r0, =SystemInit - blx r0 - ldr r0, =_start - bx r0 - .pool - .size Reset_Handler, . - Reset_Handler - - - .text -/* Macro to define default handlers. Default handler - * will be weak symbol and just dead loops. They can be - * overwritten by other handlers */ - .macro def_default_handler handler_name - .align 1 - .thumb_func - .weak \handler_name - .type \handler_name, %function -\handler_name : - b . - .size \handler_name, . - \handler_name - .endm - - def_default_handler NMI_Handler - def_default_handler HardFault_Handler - def_default_handler SVC_Handler - def_default_handler PendSV_Handler - def_default_handler SysTick_Handler - def_default_handler Default_Handler - - .macro def_irq_default_handler handler_name - .weak \handler_name - .set \handler_name, Default_Handler - .endm - - def_irq_default_handler DMA0_IRQHandler - def_irq_default_handler DMA1_IRQHandler - def_irq_default_handler DMA2_IRQHandler - def_irq_default_handler DMA3_IRQHandler - def_irq_default_handler Reserved20_IRQHandler - def_irq_default_handler FTFA_IRQHandler - def_irq_default_handler PMC_IRQHandler - def_irq_default_handler LLWU_IRQHandler - def_irq_default_handler I2C0_IRQHandler - def_irq_default_handler I2C1_IRQHandler - def_irq_default_handler SPI0_IRQHandler - def_irq_default_handler SPI1_IRQHandler - def_irq_default_handler LPUART0_IRQHandler - def_irq_default_handler LPUART1_IRQHandler - def_irq_default_handler UART2_FLEXIO_IRQHandler - def_irq_default_handler ADC0_IRQHandler - def_irq_default_handler CMP0_IRQHandler - def_irq_default_handler TPM0_IRQHandler - def_irq_default_handler TPM1_IRQHandler - def_irq_default_handler TPM2_IRQHandler - def_irq_default_handler RTC_IRQHandler - def_irq_default_handler RTC_Seconds_IRQHandler - def_irq_default_handler PIT_IRQHandler - def_irq_default_handler I2S0_IRQHandler - def_irq_default_handler USB0_IRQHandler - def_irq_default_handler DAC0_IRQHandler - def_irq_default_handler Reserved42_IRQHandler - def_irq_default_handler Reserved43_IRQHandler - def_irq_default_handler LPTMR0_IRQHandler - def_irq_default_handler LCD_IRQHandler - def_irq_default_handler PORTA_IRQHandler - def_irq_default_handler PORTCD_IRQHandler - def_irq_default_handler DefaultISR - - /* Flash protection region, placed at 0x400 */ - .text - .thumb - .align 2 - .section .kinetis_flash_config_field,"a",%progbits -kinetis_flash_config: - .long 0xFFFFFFFF - .long 0xFFFFFFFF - .long 0xFFFFFFFF - .long 0xFFFF3FFE - - .end diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis_nvic.c b/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis_nvic.c deleted file mode 100644 index 8d64306859..0000000000 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis_nvic.c +++ /dev/null @@ -1,30 +0,0 @@ -/* mbed Microcontroller Library - cmsis_nvic for LPC11U24 - * Copyright (c) 2011 ARM Limited. All rights reserved. - * - * CMSIS-style functionality to support dynamic vectors - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFE000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis_nvic.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis_nvic.h deleted file mode 100644 index 6acdca9efd..0000000000 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/cmsis_nvic.h +++ /dev/null @@ -1,26 +0,0 @@ -/* mbed Microcontroller Library - cmsis_nvic - * Copyright (c) 2009-2011 ARM Limited. All rights reserved. - * - * CMSIS-style functionality to support dynamic vectors - */ - -#ifndef MBED_CMSIS_NVIC_H -#define MBED_CMSIS_NVIC_H - -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/system_MKL43Z4.h b/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/system_MKL43Z4.h deleted file mode 100644 index 4b07fde834..0000000000 --- a/hal/targets/cmsis/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/system_MKL43Z4.h +++ /dev/null @@ -1,335 +0,0 @@ -/* -** ################################################################### -** Processors: MKL43Z256VLH4 -** MKL43Z128VLH4 -** MKL43Z64VLH4 -** MKL43Z256VMP4 -** MKL43Z128VMP4 -** MKL43Z64VMP4 -** -** Compilers: Keil ARM C/C++ Compiler -** Freescale C/C++ for Embedded ARM -** GNU C Compiler -** GNU C Compiler - CodeSourcery Sourcery G++ -** IAR ANSI C/C++ Compiler for ARM -** -** Reference manual: KL43P64M48SF6RM, Rev.3, Aug 2014 -** Version: rev. 1.4, 2014-09-01 -** Build: b140904 -** -** Abstract: -** Provides a system configuration function and a global variable that -** contains the system frequency. It configures the device and initializes -** the oscillator (PLL) that is part of the microcontroller device. -** -** Copyright (c) 2014 Freescale Semiconductor, Inc. -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without modification, -** are permitted provided that the following conditions are met: -** -** o Redistributions of source code must retain the above copyright notice, this list -** of conditions and the following disclaimer. -** -** o Redistributions in binary form must reproduce the above copyright notice, this -** list of conditions and the following disclaimer in the documentation and/or -** other materials provided with the distribution. -** -** o Neither the name of Freescale Semiconductor, Inc. nor the names of its -** contributors may be used to endorse or promote products derived from this -** software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -** http: www.freescale.com -** mail: support@freescale.com -** -** Revisions: -** - rev. 1.0 (2014-03-27) -** Initial version. -** - rev. 1.1 (2014-05-26) -** I2S registers TCR2/RCR2 and others were changed. -** FLEXIO register FLEXIO_VERID has now bitfields: FEATURE, MINOR, MAJOR. -** Names of the bitfields of the FLEXIO_SHIFTBUF have been changed to the appropriate register name e.g.: FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS. -** Peripheral_BASES macros has been changed to Peripheral_BASE_PTRS, e.g.: ADC_BASES to ADC_BASE_PTRS. -** Clock configuration for high range external oscillator has been added. -** RFSYS module access has been added. -** - rev. 1.2 (2014-07-10) -** GPIO - Renamed modules PTA,PTB,PTC,PTD,PTE to GPIOA,GPIOB,GPIOC,GPIOD,GPIOE. -** UART0 - UART0 module renamed to UART2. -** I2S - removed MDR register. -** - rev. 1.3 (2014-08-21) -** UART2 - Removed ED register. -** UART2 - Removed MODEM register. -** UART2 - Removed IR register. -** UART2 - Removed PFIFO register. -** UART2 - Removed CFIFO register. -** UART2 - Removed SFIFO register. -** UART2 - Removed TWFIFO register. -** UART2 - Removed TCFIFO register. -** UART2 - Removed RWFIFO register. -** UART2 - Removed RCFIFO register. -** USB - Removed bitfield REG_EN in CLK_RECOVER_IRC_EN register. -** SIM - Changed bitfield value MCGIRCLK to LIRC_CLK of bitfield CLKOUTSEL in SOPT2 register. -** SIM - Removed bitfield DIEID in SDID register. -** - rev. 1.4 (2014-09-01) -** USB - USB0_CTL0 was renamed to USB0_OTGCTL register. -** USB - USB0_CTL1 was renamed to USB0_CTL register. -** -** ################################################################### -*/ - -/*! - * @file MKL43Z4 - * @version 1.4 - * @date 2014-09-01 - * @brief Device specific configuration file for MKL43Z4 (header file) - * - * Provides a system configuration function and a global variable that contains - * the system frequency. It configures the device and initializes the oscillator - * (PLL) that is part of the microcontroller device. - */ - -#ifndef SYSTEM_MKL43Z4_H_ -#define SYSTEM_MKL43Z4_H_ /**< Symbol preventing repeated inclusion */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - - -#ifndef DISABLE_WDOG - #define DISABLE_WDOG 1 -#endif - -#define ACK_ISOLATION 1 - -#ifndef CLOCK_SETUP - #define CLOCK_SETUP 1 -#endif - -/* MCG_Lite mode constants */ - -#define MCG_MODE_LIRC_8M 0U -#define MCG_MODE_HIRC 1U -#define MCG_MODE_LIRC_2M 2U -#define MCG_MODE_EXT 3U - -/* Predefined clock setups - 0 ... Multipurpose Clock Generator Lite (MCG_Lite) in Low-frequency Internal Reference Clock 8 MHz (LIRC 8 MHz) mode - Default part configuration. - Core clock/Bus clock derived from the internal clock source 8 MHz - Core clock = 4MHz, BusClock = 2MHz, USB FS clock derived from external clock USB_CLKIN (applicable only for derivatived with USB) - 1 ... Multipurpose Clock Generator Lite (MCG_Lite) in High-frequency Internal Reference Clock (HIRC) mode - Maximum achievable clock frequency configuration using internal clock. - Core clock/Bus clock derived from the internal clock source 48MHz - Core clock = 48MHz, BusClock = 24MHz, USB FS clock derived from external clock USB_CLKIN (applicable only for derivatived with USB) - 2 ... Multipurpose Clock Generator Lite (MCG_Lite) in External Oscillator (EXT) mode - Core clock/Bus clock derived directly from the external crystal 32.768kHz - The clock settings is ready for Very Low Power Run mode. - Core clock = 32.768kHz, BusClock = 32.768kHz, USB FS clock derived from external clock USB_CLKIN (applicable only for derivatived with USB) - 3 ... Multipurpose Clock Generator Lite (MCG_Lite) in Low-frequency Internal Reference Clock 2 MHz (LIRC 2 MHz) mode - Core clock/Bus clock derived from the internal clock source 2 MHz - The clock settings is ready for Very Low Power Run mode. - Core clock = 2MHz, BusClock = 1MHz, USB FS clock derived from external clock USB_CLKIN (applicable only for derivatived with USB) - 4 ... Multipurpose Clock Generator Lite (MCG_Lite) in High-frequency Internal Reference Clock (HIRC) mode - USB clock setup - for USB to receive internal 48MHz clock derived from HIRC. - Core clock/Bus clock derived from the internal clock source 48MHz - Core clock = 48MHz, BusClock = 24MHz, USB FS clock derived from HIRC (MCGPCLK) - 5 ... Multipurpose Clock Generator Lite (MCG_Lite) in External Oscillator (EXT) mode - Core clock/Bus clock derived directly from the external crystal 8 MHz - Core clock = 8MHz, BusClock = 4MHz, USB FS clock derived from external clock USB_CLKIN (applicable only for derivatived with USB) -*/ - -/* Define clock source values */ - -#define CPU_XTAL_CLK_HZ 32768u /* Value of the external crystal or oscillator clock frequency in Hz */ -#define CPU_INT_FAST_CLK_HZ 48000000u /* Value of the fast internal oscillator clock frequency in Hz */ -#define CPU_INT_IRC_CLK_HZ 48000000u /* Value of the 48M internal oscillator clock frequency in Hz */ - -/* Low power mode enable */ -/* SMC_PMPROT: AVLP=1,AVLLS=1 */ -#define SMC_PMPROT_VALUE 0x22u /* SMC_PMPROT */ - -#if (CLOCK_SETUP == 0) - #define DEFAULT_SYSTEM_CLOCK 4000000u /* Default System clock value */ - #define CPU_INT_SLOW_CLK_HZ 8000000u /* Value of the slow internal oscillator clock frequency in Hz */ - #define MCG_MODE MCG_MODE_LIRC_8M /* Clock generator mode */ - /* MCG_C1: CLKS=1,IRCLKEN=1,IREFSTEN=0 */ - #define MCG_C1_VALUE 0x42u /* MCG_C1 */ - /* MCG_C2: RANGE0=0,HGO0=0,EREFS0=0,IRCS=1 */ - #define MCG_C2_VALUE 0x01u /* MCG_C2 */ - /* MCG_SC: FCRDIV=0 */ - #define MCG_SC_VALUE 0x00u /* MCG_SC */ - /* MCG_MC: HIRCEN=0 LIRC_DIV2=0 */ - #define MCG_MC_VALUE 0x00u /* MCG_MC */ - /* OSC0_CR: ERCLKEN=0,EREFSTEN=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ - #define OSC0_CR_VALUE 0x00u /* OSC0_CR */ - /* SMC_PMCTRL: RUNM=0,STOPA=0,STOPM=0 */ - #define SMC_PMCTRL_VALUE 0x00u /* SMC_PMCTRL */ - /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV4=1 */ - #define SYSTEM_SIM_CLKDIV1_VALUE 0x10010000u /* SIM_CLKDIV1 */ - /* SIM_SOPT1: OSC32KSEL=0,OSC32KOUT=0 */ - #define SYSTEM_SIM_SOPT1_VALUE 0x00000000u /* SIM_SOPT1 */ - /* SIM_SOPT2: LPUART1SRC=0,LPUART0SRC=0,TPMSRC=3,FLEXIOSRC=0,USBSRC=0,CLKOUTSEL=0,RTCCLKOUTSEL=0 */ - #define SYSTEM_SIM_SOPT2_VALUE 0x03000000u /* SIM_SOPT2 */ -#elif (CLOCK_SETUP == 1) - #define DEFAULT_SYSTEM_CLOCK 48000000u /* Default System clock value */ - #define CPU_INT_SLOW_CLK_HZ 8000000u /* Value of the slow internal oscillator clock frequency in Hz */ - #define MCG_MODE MCG_MODE_HIRC /* Clock generator mode */ - /* MCG_C1: CLKS=0,IRCLKEN=0,IREFSTEN=0 */ - #define MCG_C1_VALUE 0x00u /* MCG_C1 */ - /* MCG_C2: RANGE0=0,HGO0=0,EREFS0=0,IRCS=1 */ - #define MCG_C2_VALUE 0x01u /* MCG_C2 */ - /* MCG_SC: FCRDIV=0 */ - #define MCG_SC_VALUE 0x00u /* MCG_SC */ - /* MCG_MC: HIRCEN=1 LIRC_DIV2=0 */ - #define MCG_MC_VALUE 0x80u /* MCG_MC */ - /* OSC0_CR: ERCLKEN=0,EREFSTEN=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ - #define OSC0_CR_VALUE 0x00u /* OSC0_CR */ - /* SMC_PMCTRL: RUNM=0,STOPA=0,STOPM=0 */ - #define SMC_PMCTRL_VALUE 0x00u /* SMC_PMCTRL */ - /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV4=1 */ - #define SYSTEM_SIM_CLKDIV1_VALUE 0x10000u /* SIM_CLKDIV1 */ - /* SIM_SOPT1: OSC32KSEL=0,OSC32KOUT=0 */ - #define SYSTEM_SIM_SOPT1_VALUE 0x00000000u /* SIM_SOPT1 */ - /* SIM_SOPT2: LPUART1SRC=0,LPUART0SRC=0,TPMSRC=3,FLEXIOSRC=0,USBSRC=0,CLKOUTSEL=0,RTCCLKOUTSEL=0 */ - #define SYSTEM_SIM_SOPT2_VALUE 0x03000000U /* SIM_SOPT2 */ -#elif (CLOCK_SETUP == 2) - #define DEFAULT_SYSTEM_CLOCK 32768u /* Default System clock value */ - #define CPU_INT_SLOW_CLK_HZ 8000000u /* Value of the slow internal oscillator clock frequency in Hz */ - #define MCG_MODE MCG_MODE_EXT /* Clock generator mode */ - /* MCG_C1: CLKS=2,IRCLKEN=1,IREFSTEN=0 */ - #define MCG_C1_VALUE 0x82u /* MCG_C1 */ - /* MCG_C2: RANGE0=0,HGO0=0,EREFS0=1,IRCS=1 */ - #define MCG_C2_VALUE 0x05u /* MCG_C2 */ - /* MCG_SC: FCRDIV=0 */ - #define MCG_SC_VALUE 0x00u /* MCG_SC */ - /* MCG_MC: HIRCEN=0 LIRC_DIV2=0 */ - #define MCG_MC_VALUE 0x00u /* MCG_MC */ - /* OSC0_CR: ERCLKEN=1,EREFSTEN=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ - #define OSC0_CR_VALUE 0x80u /* OSC0_CR */ - /* SMC_PMCTRL: RUNM=0,STOPA=0,STOPM=0 */ - #define SMC_PMCTRL_VALUE 0x00u /* SMC_PMCTRL */ - /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV4=0 */ - #define SYSTEM_SIM_CLKDIV1_VALUE 0x00u /* SIM_CLKDIV1 */ - /* SIM_SOPT1: OSC32KSEL=0,OSC32KOUT=0 */ - #define SYSTEM_SIM_SOPT1_VALUE 0x00000000u /* SIM_SOPT1 */ - /* SIM_SOPT2: LPUART1SRC=0,LPUART0SRC=0,TPMSRC=2,FLEXIOSRC=0,USBSRC=0,CLKOUTSEL=0,RTCCLKOUTSEL=0 */ - #define SYSTEM_SIM_SOPT2_VALUE 0x02000000u /* SIM_SOPT2 */ -#elif (CLOCK_SETUP == 3) - #define DEFAULT_SYSTEM_CLOCK 2000000u /* Default System clock value */ - #define CPU_INT_SLOW_CLK_HZ 2000000u /* Value of the slow internal oscillator clock frequency in Hz */ - #define MCG_MODE MCG_MODE_LIRC_2M /* Clock generator mode */ - /* MCG_C1: CLKS=1,IRCLKEN=1,IREFSTEN=0 */ - #define MCG_C1_VALUE 0x42u /* MCG_C1 */ - /* MCG_C2: RANGE0=0,HGO0=0,EREFS0=0,IRCS=0 */ - #define MCG_C2_VALUE 0x00u /* MCG_C2 */ - /* MCG_SC: FCRDIV=0 */ - #define MCG_SC_VALUE 0x00u /* MCG_SC */ - /* MCG_MC: HIRCEN=0 LIRC_DIV2=0 */ - #define MCG_MC_VALUE 0x00u /* MCG_MC */ - /* OSC0_CR: ERCLKEN=0,EREFSTEN=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ - #define OSC0_CR_VALUE 0x00u /* OSC0_CR */ - /* SMC_PMCTRL: RUNM=0,STOPA=0,STOPM=0 */ - #define SMC_PMCTRL_VALUE 0x00u /* SMC_PMCTRL */ - /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV4=1 */ - #define SYSTEM_SIM_CLKDIV1_VALUE 0x10000u /* SIM_CLKDIV1 */ - /* SIM_SOPT1: OSC32KSEL=0,OSC32KOUT=0 */ - #define SYSTEM_SIM_SOPT1_VALUE 0x00000000u /* SIM_SOPT1 */ - /* SIM_SOPT2: LPUART1SRC=0,LPUART0SRC=0,TPMSRC=3,FLEXIOSRC=0,USBSRC=0,CLKOUTSEL=0,RTCCLKOUTSEL=0 */ - #define SYSTEM_SIM_SOPT2_VALUE 0x03000000u /* SIM_SOPT2 */ -#elif (CLOCK_SETUP == 4) - #define DEFAULT_SYSTEM_CLOCK 2000000u /* Default System clock value */ - #define CPU_INT_SLOW_CLK_HZ 8000000u /* Value of the slow internal oscillator clock frequency in Hz */ - #define MCG_MODE MCG_MODE_LIRC_2M /* Clock generator mode */ - /* MCG_C1: CLKS=0,IRCLKEN=1,IREFSTEN=0 */ - #define MCG_C1_VALUE 0x02u /* MCG_C1 */ - /* MCG_C2: RANGE0=0,HGO0=0,EREFS0=0,IRCS=1 */ - #define MCG_C2_VALUE 0x01u /* MCG_C2 */ - /* MCG_SC: FCRDIV=0 */ - #define MCG_SC_VALUE 0x00u /* MCG_SC */ - /* MCG_MC: HIRCEN=1 LIRC_DIV2=0 */ - #define MCG_MC_VALUE 0x80u /* MCG_MC */ - /* OSC0_CR: ERCLKEN=0,EREFSTEN=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ - #define OSC0_CR_VALUE 0x00u /* OSC0_CR */ - /* SMC_PMCTRL: RUNM=0,STOPA=0,STOPM=0 */ - #define SMC_PMCTRL_VALUE 0x00u /* SMC_PMCTRL */ - /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV4=1 */ - #define SYSTEM_SIM_CLKDIV1_VALUE 0x10000u /* SIM_CLKDIV1 */ - /* SIM_SOPT1: OSC32KSEL=0,OSC32KOUT=0 */ - #define SYSTEM_SIM_SOPT1_VALUE 0x00000000u /* SIM_SOPT1 */ - /* SIM_SOPT2: LPUART1SRC=0,LPUART0SRC=0,TPMSRC=3,FLEXIOSRC=0,USBSRC=1,CLKOUTSEL=0,RTCCLKOUTSEL=0 */ - #define SYSTEM_SIM_SOPT2_VALUE 0x03040000u /* SIM_SOPT2 */ -#elif (CLOCK_SETUP == 5) - #define DEFAULT_SYSTEM_CLOCK 2000000u /* Default System clock value */ - #define CPU_INT_SLOW_CLK_HZ 2000000u /* Value of the slow internal oscillator clock frequency in Hz */ - #define MCG_MODE MCG_MODE_LIRC_2M /* Clock generator mode */ - /* MCG_C1: CLKS=2,IRCLKEN=0,IREFSTEN=0 */ - #define MCG_C1_VALUE 0x80u /* MCG_C1 */ - /* MCG_C2: RANGE0=1,HGO0=0,EREFS0=1,IRCS=1 */ - #define MCG_C2_VALUE 0x15u /* MCG_C2 */ - /* MCG_SC: FCRDIV=0 */ - #define MCG_SC_VALUE 0x00u /* MCG_SC */ - /* MCG_MC: HIRCEN=0 LIRC_DIV2=0 */ - #define MCG_MC_VALUE 0x00u /* MCG_MC */ - /* OSC0_CR: ERCLKEN=1,EREFSTEN=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ - #define OSC0_CR_VALUE 0x80u /* OSC0_CR */ - /* SMC_PMCTRL: RUNM=0,STOPA=0,STOPM=0 */ - #define SMC_PMCTRL_VALUE 0x00u /* SMC_PMCTRL */ - /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV4=1 */ - #define SYSTEM_SIM_CLKDIV1_VALUE 0x10000u /* SIM_CLKDIV1 */ - /* SIM_SOPT1: OSC32KSEL=0,OSC32KOUT=0 */ - #define SYSTEM_SIM_SOPT1_VALUE 0x00000000u /* SIM_SOPT1 */ - /* SIM_SOPT2: LPUART1SRC=0,LPUART0SRC=0,TPMSRC=3,FLEXIOSRC=0,USBSRC=0,CLKOUTSEL=0,RTCCLKOUTSEL=0 */ - #define SYSTEM_SIM_SOPT2_VALUE 0x03000000u /* SIM_SOPT2 */ -#else - #error The selected clock setup is not supported. -#endif /* (CLOCK_SETUP == 5) */ - - -/** - * @brief System clock frequency (core clock) - * - * The system clock frequency supplied to the SysTick timer and the processor - * core clock. This variable can be used by the user application to setup the - * SysTick timer or configure other parameters. It may also be used by debugger to - * query the frequency of the debug timer or configure the trace clock speed - * SystemCoreClock is initialized with a correct predefined value. - */ -extern uint32_t SystemCoreClock; - -/** - * @brief Setup the microcontroller system. - * - * Typically this function configures the oscillator (PLL) that is part of the - * microcontroller device. For systems with variable clock speed it also updates - * the variable SystemCoreClock. SystemInit is called from startup_device file. - */ -void SystemInit (void); - -/** - * @brief Updates the SystemCoreClock variable. - * - * It must be called whenever the core clock is changed during program - * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates - * the current core clock. - */ -void SystemCoreClockUpdate (void); - -#ifdef __cplusplus -} -#endif - -#endif /* #if !defined(SYSTEM_MKL43Z4_H_) */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PeripheralNames.h b/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PeripheralNames.h deleted file mode 100644 index 45df206627..0000000000 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PeripheralNames.h +++ /dev/null @@ -1,94 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_PERIPHERALNAMES_H -#define MBED_PERIPHERALNAMES_H - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - OSC32KCLK = 0, - RTC_CLKIN = 2 -} RTCName; - -typedef enum { - UART_0 = (int)LPUART0_BASE, - UART_1 = (int)LPUART1_BASE, - UART_2 = (int)UART2_BASE -} UARTName; -#define STDIO_UART_TX USBTX -#define STDIO_UART_RX USBRX -#define STDIO_UART UART_0 - -typedef enum { - I2C_0 = (int)I2C0_BASE, - I2C_1 = (int)I2C1_BASE, -} I2CName; - -#define TPM_SHIFT 8 -typedef enum { - PWM_1 = (0 << TPM_SHIFT) | (0), // TPM0 CH0 - PWM_2 = (0 << TPM_SHIFT) | (1), // TPM0 CH1 - PWM_3 = (0 << TPM_SHIFT) | (2), // TPM0 CH2 - PWM_4 = (0 << TPM_SHIFT) | (3), // TPM0 CH3 - PWM_5 = (0 << TPM_SHIFT) | (4), // TPM0 CH4 - PWM_6 = (0 << TPM_SHIFT) | (5), // TPM0 CH5 - - PWM_7 = (1 << TPM_SHIFT) | (0), // TPM1 CH0 - PWM_8 = (1 << TPM_SHIFT) | (1), // TPM1 CH1 - - PWM_9 = (2 << TPM_SHIFT) | (0), // TPM2 CH0 - PWM_10 = (2 << TPM_SHIFT) | (1) // TPM2 CH1 -} PWMName; - -#define CHANNELS_A_SHIFT 5 -typedef enum { - ADC0_SE0 = 0, - ADC0_SE3 = 3, - ADC0_SE4a = (1 << CHANNELS_A_SHIFT) | (4), - ADC0_SE4b = 4, - ADC0_SE5b = 5, - ADC0_SE6b = 6, - ADC0_SE7a = (1 << CHANNELS_A_SHIFT) | (7), - ADC0_SE7b = 7, - ADC0_SE8 = 8, - ADC0_SE9 = 9, - ADC0_SE11 = 11, - ADC0_SE12 = 12, - ADC0_SE13 = 13, - ADC0_SE14 = 14, - ADC0_SE15 = 15, - ADC0_SE23 = 23 -} ADCName; - -typedef enum { - DAC_0 = 0 -} DACName; - - -typedef enum { - SPI_0 = (int)SPI0_BASE, - SPI_1 = (int)SPI1_BASE, -} SPIName; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PinNames.h b/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PinNames.h deleted file mode 100644 index f9fd393e66..0000000000 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PinNames.h +++ /dev/null @@ -1,258 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_PINNAMES_H -#define MBED_PINNAMES_H - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - PIN_INPUT, - PIN_OUTPUT -} PinDirection; - -#define PORT_SHIFT 12 - -typedef enum { - PTA0 = 0x0, - PTA1 = 0x4, - PTA2 = 0x8, - PTA3 = 0xc, - PTA4 = 0x10, - PTA5 = 0x14, - PTA6 = 0x18, - PTA7 = 0x1c, - PTA8 = 0x20, - PTA9 = 0x24, - PTA10 = 0x28, - PTA11 = 0x2c, - PTA12 = 0x30, - PTA13 = 0x34, - PTA14 = 0x38, - PTA15 = 0x3c, - PTA16 = 0x40, - PTA17 = 0x44, - PTA18 = 0x48, - PTA19 = 0x4c, - PTA20 = 0x50, - PTA21 = 0x54, - PTA22 = 0x58, - PTA23 = 0x5c, - PTA24 = 0x60, - PTA25 = 0x64, - PTA26 = 0x68, - PTA27 = 0x6c, - PTA28 = 0x70, - PTA29 = 0x74, - PTA30 = 0x78, - PTA31 = 0x7c, - PTB0 = 0x1000, - PTB1 = 0x1004, - PTB2 = 0x1008, - PTB3 = 0x100c, - PTB4 = 0x1010, - PTB5 = 0x1014, - PTB6 = 0x1018, - PTB7 = 0x101c, - PTB8 = 0x1020, - PTB9 = 0x1024, - PTB10 = 0x1028, - PTB11 = 0x102c, - PTB12 = 0x1030, - PTB13 = 0x1034, - PTB14 = 0x1038, - PTB15 = 0x103c, - PTB16 = 0x1040, - PTB17 = 0x1044, - PTB18 = 0x1048, - PTB19 = 0x104c, - PTB20 = 0x1050, - PTB21 = 0x1054, - PTB22 = 0x1058, - PTB23 = 0x105c, - PTB24 = 0x1060, - PTB25 = 0x1064, - PTB26 = 0x1068, - PTB27 = 0x106c, - PTB28 = 0x1070, - PTB29 = 0x1074, - PTB30 = 0x1078, - PTB31 = 0x107c, - PTC0 = 0x2000, - PTC1 = 0x2004, - PTC2 = 0x2008, - PTC3 = 0x200c, - PTC4 = 0x2010, - PTC5 = 0x2014, - PTC6 = 0x2018, - PTC7 = 0x201c, - PTC8 = 0x2020, - PTC9 = 0x2024, - PTC10 = 0x2028, - PTC11 = 0x202c, - PTC12 = 0x2030, - PTC13 = 0x2034, - PTC14 = 0x2038, - PTC15 = 0x203c, - PTC16 = 0x2040, - PTC17 = 0x2044, - PTC18 = 0x2048, - PTC19 = 0x204c, - PTC20 = 0x2050, - PTC21 = 0x2054, - PTC22 = 0x2058, - PTC23 = 0x205c, - PTC24 = 0x2060, - PTC25 = 0x2064, - PTC26 = 0x2068, - PTC27 = 0x206c, - PTC28 = 0x2070, - PTC29 = 0x2074, - PTC30 = 0x2078, - PTC31 = 0x207c, - PTD0 = 0x3000, - PTD1 = 0x3004, - PTD2 = 0x3008, - PTD3 = 0x300c, - PTD4 = 0x3010, - PTD5 = 0x3014, - PTD6 = 0x3018, - PTD7 = 0x301c, - PTD8 = 0x3020, - PTD9 = 0x3024, - PTD10 = 0x3028, - PTD11 = 0x302c, - PTD12 = 0x3030, - PTD13 = 0x3034, - PTD14 = 0x3038, - PTD15 = 0x303c, - PTD16 = 0x3040, - PTD17 = 0x3044, - PTD18 = 0x3048, - PTD19 = 0x304c, - PTD20 = 0x3050, - PTD21 = 0x3054, - PTD22 = 0x3058, - PTD23 = 0x305c, - PTD24 = 0x3060, - PTD25 = 0x3064, - PTD26 = 0x3068, - PTD27 = 0x306c, - PTD28 = 0x3070, - PTD29 = 0x3074, - PTD30 = 0x3078, - PTD31 = 0x307c, - PTE0 = 0x4000, - PTE1 = 0x4004, - PTE2 = 0x4008, - PTE3 = 0x400c, - PTE4 = 0x4010, - PTE5 = 0x4014, - PTE6 = 0x4018, - PTE7 = 0x401c, - PTE8 = 0x4020, - PTE9 = 0x4024, - PTE10 = 0x4028, - PTE11 = 0x402c, - PTE12 = 0x4030, - PTE13 = 0x4034, - PTE14 = 0x4038, - PTE15 = 0x403c, - PTE16 = 0x4040, - PTE17 = 0x4044, - PTE18 = 0x4048, - PTE19 = 0x404c, - PTE20 = 0x4050, - PTE21 = 0x4054, - PTE22 = 0x4058, - PTE23 = 0x405c, - PTE24 = 0x4060, - PTE25 = 0x4064, - PTE26 = 0x4068, - PTE27 = 0x406c, - PTE28 = 0x4070, - PTE29 = 0x4074, - PTE30 = 0x4078, - PTE31 = 0x407c, - - LED_RED = PTE31, - LED_GREEN = PTD5, - - // mbed original LED naming - LED1 = LED_GREEN, - LED2 = LED_RED, - LED3 = LED_GREEN, - LED4 = LED_RED, - - //Push buttons - SW1 = PTA4, - SW3 = PTC3, - - // USB Pins - USBTX = PTA2, - USBRX = PTA1, - - // Arduino Headers - D0 = PTA1, - D1 = PTA2, - D2 = PTD3, - D3 = PTA12, - D4 = PTA4, - D5 = PTA5, - D6 = PTE29, - D7 = PTE30, - D8 = PTA13, - D9 = PTD2, - D10 = PTD4, - D11 = PTD6, - D12 = PTD7, - D13 = PTD5, - D14 = PTE0, - D15 = PTE1, - - A0 = PTB0, - A1 = PTB1, - A2 = PTB2, - A3 = PTB3, - A4 = PTC2, - A5 = PTC1, - - I2C_SCL = D15, - I2C_SDA = D14, - - TSI_ELEC0 = PTB16, - TSI_ELEC1 = PTB17, - - // Not connected - NC = (int)0xFFFFFFFF -} PinName; - -/* Pull modes for input pins */ -typedef enum { - PullNone = 0, - PullDown = 2, - PullUp = 3, - PullDefault = PullUp -} PinMode; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/gpio_irq_api.c b/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/gpio_irq_api.c deleted file mode 100644 index 13bb1a2396..0000000000 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/gpio_irq_api.c +++ /dev/null @@ -1,191 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include "cmsis.h" - -#include "gpio_irq_api.h" -#include "gpio_api.h" -#include "mbed_error.h" - -#define CHANNEL_NUM 96 - -static uint32_t channel_ids[CHANNEL_NUM] = {0}; -static gpio_irq_handler irq_handler; - -#define IRQ_DISABLED (0) -#define IRQ_RAISING_EDGE PORT_PCR_IRQC(9) -#define IRQ_FALLING_EDGE PORT_PCR_IRQC(10) -#define IRQ_EITHER_EDGE PORT_PCR_IRQC(11) - -const uint32_t search_bits[] = {0x0000FFFF, 0x000000FF, 0x0000000F, 0x00000003, 0x00000001}; - -static void handle_interrupt_in(PORT_Type *port, int ch_base) { - uint32_t isfr; - uint8_t location; - - while((isfr = port->ISFR) != 0) { - location = 0; - for (int i = 0; i < 5; i++) { - if (!(isfr & (search_bits[i] << location))) - location += 1 << (4 - i); - } - - uint32_t id = channel_ids[ch_base + location]; - if (id == 0) { - continue; - } - - GPIO_Type *gpio; - gpio_irq_event event = IRQ_NONE; - switch (port->PCR[location] & PORT_PCR_IRQC_MASK) { - case IRQ_RAISING_EDGE: - event = IRQ_RISE; - break; - - case IRQ_FALLING_EDGE: - event = IRQ_FALL; - break; - - case IRQ_EITHER_EDGE: - if (port == PORTA) { - gpio = GPIOA; - } else if (port == PORTC) { - gpio = GPIOC; - } else { - gpio = GPIOD; - } - event = (gpio->PDIR & (1<ISFR = 1 << location; - } -} - -void gpio_irqA(void) { - handle_interrupt_in(PORTA, 0); -} - -/* PORTC and PORTD share same vector */ -void gpio_irqCD(void) { - if ((SIM->SCGC5 & SIM_SCGC5_PORTC_MASK) && (PORTC->ISFR)) { - handle_interrupt_in(PORTC, 32); - } else if ((SIM->SCGC5 & SIM_SCGC5_PORTD_MASK) && (PORTD->ISFR)) { - handle_interrupt_in(PORTD, 64); - } -} - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { - if (pin == NC) - return -1; - - irq_handler = handler; - - obj->port = pin >> PORT_SHIFT; - obj->pin = (pin & 0x7F) >> 2; - - uint32_t ch_base, vector; - IRQn_Type irq_n; - switch (obj->port) { - case PortA: - ch_base = 0; irq_n = PORTA_IRQn; vector = (uint32_t)gpio_irqA; - break; - - case PortC: - ch_base = 32; irq_n = PORTCD_IRQn; vector = (uint32_t)gpio_irqCD; - break; - - case PortD: - ch_base = 64; irq_n = PORTCD_IRQn; vector = (uint32_t)gpio_irqCD; - break; - - default: - error("gpio_irq only supported on port A,C and D"); - break; - } - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - obj->ch = ch_base + obj->pin; - channel_ids[obj->ch] = id; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) { - channel_ids[obj->ch] = 0; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { - PORT_Type *port = (PORT_Type *)(PORTA_BASE + 0x1000 * obj->port); - - uint32_t irq_settings = IRQ_DISABLED; - - switch (port->PCR[obj->pin] & PORT_PCR_IRQC_MASK) { - case IRQ_DISABLED: - if (enable) { - irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_FALLING_EDGE); - } - break; - - case IRQ_RAISING_EDGE: - if (enable) { - irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_EITHER_EDGE); - } else { - if (event == IRQ_FALL) - irq_settings = IRQ_RAISING_EDGE; - } - break; - - case IRQ_FALLING_EDGE: - if (enable) { - irq_settings = (event == IRQ_FALL) ? (IRQ_FALLING_EDGE) : (IRQ_EITHER_EDGE); - } else { - if (event == IRQ_RISE) - irq_settings = IRQ_FALLING_EDGE; - } - break; - - case IRQ_EITHER_EDGE: - if (enable) { - irq_settings = IRQ_EITHER_EDGE; - } else { - irq_settings = (event == IRQ_RISE) ? (IRQ_FALLING_EDGE) : (IRQ_RAISING_EDGE); - } - break; - } - - // Interrupt configuration and clear interrupt - port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK; -} - -void gpio_irq_enable(gpio_irq_t *obj) { - if (obj->port == PortA) { - NVIC_EnableIRQ(PORTA_IRQn); - } else { - NVIC_EnableIRQ(PORTCD_IRQn); - } -} - -void gpio_irq_disable(gpio_irq_t *obj) { - if (obj->port == PortA) { - NVIC_DisableIRQ(PORTA_IRQn); - } else { - NVIC_DisableIRQ(PORTCD_IRQn); - } -} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/serial_api.c b/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/serial_api.c deleted file mode 100644 index 1a1c607e32..0000000000 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/serial_api.c +++ /dev/null @@ -1,316 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "mbed_assert.h" -#include "serial_api.h" - -// math.h required for floating point operations for baud rate calculation -#include - -#include - -#include "cmsis.h" -#include "pinmap.h" -#include "clk_freqs.h" -#include "PeripheralPins.h" - -#define UART_NUM 2 - -/****************************************************************************** - * INITIALIZATION - ******************************************************************************/ - -static uint32_t serial_irq_ids[UART_NUM] = {0}; -static uart_irq_handler irq_handler; - -int stdio_uart_inited = 0; -serial_t stdio_uart; - -static inline uint32_t serial_get_src_clock(serial_t *obj) { - uint32_t mux, srcclk; - - switch ((int)obj->uart) { - case UART_0: - mux = (SIM->SOPT2 & SIM_SOPT2_LPUART0SRC_MASK) >> SIM_SOPT2_LPUART0SRC_SHIFT; - break; - case UART_1: - mux = (SIM->SOPT2 & SIM_SOPT2_LPUART1SRC_MASK) >> SIM_SOPT2_LPUART1SRC_SHIFT; - break; - case UART_2: /* TODO: add UART2 support */ break; - } - - switch (mux) { - case 1: srcclk = fastirc_frequency(); break; - case 2: srcclk = extosc_frequency(); break; - case 3: srcclk = mcgirc_frequency(); break; - default: srcclk = 0; break; - } - - return srcclk; -} - -void serial_init(serial_t *obj, PinName tx, PinName rx) { - // determine the UART to use - UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); - UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); - UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); - MBED_ASSERT((int)uart != NC); - - obj->uart = (LPUART_Type *)uart; - - // enable clk - switch (uart) { - case UART_0: - SIM->SOPT2 |= SIM_SOPT2_LPUART0SRC(1); - SIM->SCGC5 |= SIM_SCGC5_LPUART0_MASK; - break; - case UART_1: - SIM->SOPT2 |= SIM_SOPT2_LPUART1SRC(1); - SIM->SCGC5 |= SIM_SCGC5_LPUART1_MASK; - break; - case UART_2: /* TODO: add UART2 support */ break; - } - - // reset UART registers - obj->uart->BAUD = 0x0F000004; - obj->uart->STAT = 0xC01FC000; - obj->uart->CTRL = 0x00000000; - obj->uart->MATCH = 0x00000000; - - switch (uart) { - case UART_0: obj->index = 0; break; - case UART_1: obj->index = 1; break; - case UART_2: /* TODO: add UART2 support */ break; - } - - // set default baud rate and format - serial_baud (obj, 9600); - serial_format(obj, 8, ParityNone, 1); - - // pinout the chosen uart - pinmap_pinout(tx, PinMap_UART_TX); - pinmap_pinout(rx, PinMap_UART_RX); - - // set rx/tx pins in PullUp mode - if (tx != NC) pin_mode(tx, PullUp); - if (rx != NC) pin_mode(rx, PullUp); - - obj->uart->CTRL |= (LPUART_CTRL_RE_MASK | LPUART_CTRL_TE_MASK); - - if (uart == STDIO_UART) { - stdio_uart_inited = 1; - memcpy(&stdio_uart, obj, sizeof(serial_t)); - } -} - -void serial_free(serial_t *obj) { - serial_irq_ids[obj->index] = 0; -} - -// serial_baud -// -// set the baud rate, taking in to account the current SystemFrequency -void serial_baud(serial_t *obj, int baudrate) { - int calcBaudrate; - uint32_t i, sbr, sbrTemp, osr, temp, baud, baudDiff; - - /* get value of serial source clock */ - uint32_t PCLK = serial_get_src_clock(obj); - - /* loop to find the best osr value possible, one that generates minimum baudDiff - * iterate through the rest of the supported values of osr */ - temp = 0xFFFFFFFF; - for (i = 5; i <= 33; i++) { - /* calculate the temporary sbr value */ - sbrTemp = PCLK / (baudrate * i); - - /* calculate the baud rate based on the temporary osr and sbr values */ - calcBaudrate = PCLK / (i * sbrTemp); - - if (calcBaudrate > baudrate) { - baudDiff = calcBaudrate - baudrate; - } else { - baudDiff = baudrate - calcBaudrate; - } - - if (baudDiff < temp) { - osr = i - 1; /* update and store the best osr value calculated */ - sbr = sbrTemp; /* update store the best sbr value calculated */ - - if(baudDiff == 0) { - break; /* end for loop if founded the best osr and sbr value */ - } else { - temp = baudDiff; - } - } - } - - - /* save C2 state */ - temp = obj->uart->CTRL & (LPUART_CTRL_RE_MASK | LPUART_CTRL_TE_MASK); - - /* disable UART before changing registers */ - obj->uart->CTRL &= ~(LPUART_CTRL_RE_MASK | LPUART_CTRL_TE_MASK); - - /* read BAUD register with clearing old baudrate settings into baud variable */ - baud = obj->uart->BAUD & ~(LPUART_BAUD_SBR_MASK | LPUART_BAUD_OSR_MASK | LPUART_BAUD_BOTHEDGE_MASK); - - /* write the new osr and sbr values */ - baud |= (LPUART_BAUD_SBR(sbr) | LPUART_BAUD_OSR(osr)); - - /* Check if osr is between 4x and 7x oversampling. - * If so, then "BOTHEDGE" sampling must be turned on */ - if ((osr > 3) && (osr < 8)) { - baud |= LPUART_BAUD_BOTHEDGE_MASK; - } - - /* write new values into BAUD register */ - obj->uart->BAUD = baud; - - /* restore C2 state */ - obj->uart->CTRL |= temp; -} - -void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { - MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); - MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven)); - MBED_ASSERT(data_bits == 8); // TODO: Support other number of data bits (also in the write method!) - - // save C2 state - uint32_t c2_state = obj->uart->CTRL & (LPUART_CTRL_RE_MASK | LPUART_CTRL_TE_MASK); - - // disable UART before changing registers - obj->uart->CTRL &= ~(LPUART_CTRL_RE_MASK | LPUART_CTRL_TE_MASK); - - - uint8_t parity_enable = 0, parity_select = 0; - switch (parity) { - case ParityNone: parity_enable = 0; parity_select = 0; break; - case ParityOdd : parity_enable = 1; parity_select = 1; data_bits++; break; - case ParityEven: parity_enable = 1; parity_select = 0; data_bits++; break; - default: - break; - } - - stop_bits -= 1; - - // data bits, parity and parity mode - obj->uart->CTRL = ((parity_enable << 1) | (parity_select << 0)); - - // stop bits - obj->uart->BAUD &= ~LPUART_BAUD_SBNS_MASK; - obj->uart->BAUD |= (stop_bits << LPUART_BAUD_SBNS_SHIFT); - - // restore C2 state - obj->uart->CTRL |= c2_state; -} - -/****************************************************************************** - * INTERRUPTS HANDLING - ******************************************************************************/ -static inline void uart_irq(uint32_t status, uint32_t index) { - if (serial_irq_ids[index] != 0) { - if (status & LPUART_STAT_TDRE_MASK) - irq_handler(serial_irq_ids[index], TxIrq); - - if (status & LPUART_STAT_RDRF_MASK) - irq_handler(serial_irq_ids[index], RxIrq); - } -} - -void uart0_irq() {uart_irq(LPUART0->STAT, 0);} -void uart1_irq() {uart_irq(LPUART1->STAT, 1);} - -void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { - irq_handler = handler; - serial_irq_ids[obj->index] = id; -} - -void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - switch ((int)obj->uart) { - case UART_0: irq_n=LPUART0_IRQn; vector = (uint32_t)&uart0_irq; break; - case UART_1: irq_n=LPUART1_IRQn; vector = (uint32_t)&uart1_irq; break; - } - - if (enable) { - switch (irq) { - case RxIrq: obj->uart->CTRL |= LPUART_CTRL_RIE_MASK; break; - case TxIrq: obj->uart->CTRL |= LPUART_CTRL_TIE_MASK; break; - } - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - } else { // disable - int all_disabled = 0; - SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); - switch (irq) { - case RxIrq: obj->uart->CTRL &= ~(LPUART_CTRL_RIE_MASK); break; - case TxIrq: obj->uart->CTRL &= ~(LPUART_CTRL_TIE_MASK); break; - } - switch (other_irq) { - case RxIrq: all_disabled = (obj->uart->CTRL & LPUART_CTRL_RIE_MASK) == 0; break; - case TxIrq: all_disabled = (obj->uart->CTRL & LPUART_CTRL_TIE_MASK) == 0; break; - } - if (all_disabled) - NVIC_DisableIRQ(irq_n); - } -} - -/****************************************************************************** - * READ/WRITE - ******************************************************************************/ -int serial_getc(serial_t *obj) { - while (!serial_readable(obj)); - return (obj->uart->DATA & 0xFFu); -} - -void serial_putc(serial_t *obj, int c) { - while (!serial_writable(obj)); - obj->uart->DATA = c; -} - -int serial_readable(serial_t *obj) { - // check overrun - if (obj->uart->STAT & LPUART_STAT_OR_MASK) { - obj->uart->STAT |= LPUART_STAT_OR_MASK; - } - return (obj->uart->STAT & LPUART_STAT_RDRF_MASK); -} - -int serial_writable(serial_t *obj) { - // check overrun - if (obj->uart->STAT & LPUART_STAT_OR_MASK) { - obj->uart->STAT |= LPUART_STAT_OR_MASK; - } - return (obj->uart->STAT & LPUART_STAT_TDRE_MASK); -} - -void serial_clear(serial_t *obj) { -} - -void serial_pinout_tx(PinName tx) { - pinmap_pinout(tx, PinMap_UART_TX); -} - -void serial_break_set(serial_t *obj) { - obj->uart->CTRL |= LPUART_CTRL_SBK_MASK; -} - -void serial_break_clear(serial_t *obj) { - obj->uart->CTRL &= ~LPUART_CTRL_SBK_MASK; -} - diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/spi_api.c b/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/spi_api.c deleted file mode 100644 index 128ea7f37a..0000000000 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/spi_api.c +++ /dev/null @@ -1,210 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "mbed_assert.h" -#include "spi_api.h" - -#include - -#include "cmsis.h" -#include "pinmap.h" - -static const PinMap PinMap_SPI_SCLK[] = { - {PTC3, SPI_1, 2}, - {PTC5, SPI_0, 2}, - {PTD1, SPI_0, 2}, - {PTD5, SPI_1, 2}, - {NC , NC , 0} -}; - -static const PinMap PinMap_SPI_MOSI[] = { - {PTB16, SPI_1, 2}, - {PTB17, SPI_1, 5}, - {PTC6, SPI_0, 2}, - {PTC7, SPI_0, 5}, - {PTD2, SPI_0, 2}, - {PTD3, SPI_0, 5}, - {PTD6, SPI_1, 2}, - {PTD7, SPI_1, 5}, - {PTE1, SPI_1, 2}, - {NC , NC , 0} -}; - -static const PinMap PinMap_SPI_MISO[] = { - {PTB16, SPI_1, 5}, - {PTB17, SPI_1, 2}, - {PTC6, SPI_0, 5}, - {PTC7, SPI_0, 2}, - {PTD2, SPI_0, 5}, - {PTD3, SPI_0, 2}, - {PTD6, SPI_1, 5}, - {PTD7, SPI_1, 2}, - {PTE0, SPI_1, 2}, - {PTE1, SPI_1, 5}, - {NC , NC , 0} -}; - -static const PinMap PinMap_SPI_SSEL[] = { - {PTC4, SPI_0, 2}, - {PTD0, SPI_0, 2}, - {PTD4, SPI_1, 2}, - {NC , NC , 0} -}; - -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { - // determine the SPI to use - SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); - SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); - SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); - SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); - SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); - SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); - - obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl); - MBED_ASSERT((int)obj->spi != NC); - - // enable power and clocking - switch ((int)obj->spi) { - case SPI_0: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 22; break; - case SPI_1: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 23; break; - } - - // enable SPI - obj->spi->C1 |= SPI_C1_SPE_MASK; - obj->spi->C2 &= ~SPI_C2_SPIMODE_MASK; //8bit - - // pin out the spi pins - pinmap_pinout(mosi, PinMap_SPI_MOSI); - pinmap_pinout(miso, PinMap_SPI_MISO); - pinmap_pinout(sclk, PinMap_SPI_SCLK); - if (ssel != NC) { - pinmap_pinout(ssel, PinMap_SPI_SSEL); - } -} - -void spi_free(spi_t *obj) { - // [TODO] -} - -void spi_format(spi_t *obj, int bits, int mode, int slave) { - MBED_ASSERT((bits == 8) || (bits == 16)); - MBED_ASSERT((mode >= 0) && (mode <= 3)); - - uint8_t polarity = (mode & 0x2) ? 1 : 0; - uint8_t phase = (mode & 0x1) ? 1 : 0; - uint8_t c1_data = ((!slave) << 4) | (polarity << 3) | (phase << 2); - - // clear MSTR, CPOL and CPHA bits - obj->spi->C1 &= ~(0x7 << 2); - - // write new value - obj->spi->C1 |= c1_data; - if (bits == 8) { - obj->spi->C2 &= ~SPI_C2_SPIMODE_MASK; - } else { - obj->spi->C2 |= SPI_C2_SPIMODE_MASK; - } -} - -void spi_frequency(spi_t *obj, int hz) { - uint32_t error = 0; - uint32_t p_error = 0xffffffff; - uint32_t ref = 0; - uint8_t spr = 0; - uint8_t ref_spr = 0; - uint8_t ref_prescaler = 0; - - // bus clk - uint32_t PCLK = SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1); - uint8_t prescaler = 1; - uint8_t divisor = 2; - - for (prescaler = 1; prescaler <= 8; prescaler++) { - divisor = 2; - for (spr = 0; spr <= 8; spr++, divisor *= 2) { - ref = PCLK / (prescaler*divisor); - if (ref > (uint32_t)hz) - continue; - error = hz - ref; - if (error < p_error) { - ref_spr = spr; - ref_prescaler = prescaler - 1; - p_error = error; - } - } - } - - // set SPPR and SPR - obj->spi->BR = ((ref_prescaler & 0x7) << 4) | (ref_spr & 0xf); -} - -static inline int spi_writeable(spi_t * obj) { - return (obj->spi->S & SPI_S_SPTEF_MASK) ? 1 : 0; -} - -static inline int spi_readable(spi_t * obj) { - return (obj->spi->S & SPI_S_SPRF_MASK) ? 1 : 0; -} - -int spi_master_write(spi_t *obj, int value) { - int ret; - if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) { - // 16bit - while(!spi_writeable(obj)); - obj->spi->DL = (value & 0xff); - obj->spi->DH = ((value >> 8) & 0xff); - - // wait rx buffer full - while (!spi_readable(obj)); - ret = obj->spi->DH; - ret = (ret << 8) | obj->spi->DL; - } else { - //8bit - while(!spi_writeable(obj)); - obj->spi->DL = (value & 0xff); - - // wait rx buffer full - while (!spi_readable(obj)); - ret = (obj->spi->DL & 0xff); - } - - return ret; -} - -int spi_slave_receive(spi_t *obj) { - return spi_readable(obj); -} - -int spi_slave_read(spi_t *obj) { - int ret; - if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) { - ret = obj->spi->DH; - ret = ((ret << 8) | obj->spi->DL); - } else { - ret = obj->spi->DL; - } - return ret; -} - -void spi_slave_write(spi_t *obj, int value) { - while (!spi_writeable(obj)); - if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) { - obj->spi->DL = (value & 0xff); - obj->spi->DH = ((value >> 8) & 0xff); - } else { - obj->spi->DL = value; - } - -} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PeripheralNames.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PeripheralNames.h new file mode 100644 index 0000000000..48e2fbccd8 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PeripheralNames.h @@ -0,0 +1,101 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + OSC32KCLK = 0, +} RTCName; + +/* LPUART */ +typedef enum { + LPUART_0 = 0, + LPUART_1 = 1, +} UARTName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART LPUART_0 + +typedef enum { + I2C_0 = 0, + I2C_1 = 1, +} I2CName; + +#define TPM_SHIFT 8 +typedef enum { + PWM_1 = (0 << TPM_SHIFT) | (0), // TPM0 CH0 + PWM_2 = (0 << TPM_SHIFT) | (1), // TPM0 CH1 + PWM_3 = (0 << TPM_SHIFT) | (2), // TPM0 CH2 + PWM_4 = (0 << TPM_SHIFT) | (3), // TPM0 CH3 + PWM_5 = (0 << TPM_SHIFT) | (4), // TPM0 CH4 + PWM_6 = (0 << TPM_SHIFT) | (5), // TPM0 CH5 + PWM_7 = (1 << TPM_SHIFT) | (0), // TPM1 CH0 + PWM_8 = (1 << TPM_SHIFT) | (1), // TPM1 CH1 + PWM_9 = (2 << TPM_SHIFT) | (0), // TPM2 CH0 + PWM_10 = (2 << TPM_SHIFT) | (1), // TPM2 CH1 +} PWMName; + +#define ADC_INSTANCE_SHIFT 8 +#define ADC_B_CHANNEL_SHIFT 5 +typedef enum { + ADC0_SE0 = (0 << ADC_INSTANCE_SHIFT) | 0, + ADC0_SE1 = (0 << ADC_INSTANCE_SHIFT) | 1, + ADC0_SE2 = (0 << ADC_INSTANCE_SHIFT) | 2, + ADC0_SE3 = (0 << ADC_INSTANCE_SHIFT) | 3, + ADC0_SE4a = (0 << ADC_INSTANCE_SHIFT) | 4, + ADC0_SE5a = (0 << ADC_INSTANCE_SHIFT) | 5, + ADC0_SE6a = (0 << ADC_INSTANCE_SHIFT) | 6, + ADC0_SE7a = (0 << ADC_INSTANCE_SHIFT) | 7, + ADC0_SE4b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 4, + ADC0_SE5b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 5, + ADC0_SE6b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 6, + ADC0_SE7b = (0 << ADC_INSTANCE_SHIFT) | (1 << ADC_B_CHANNEL_SHIFT) | 7, + ADC0_SE8 = (0 << ADC_INSTANCE_SHIFT) | 8, + ADC0_SE9 = (0 << ADC_INSTANCE_SHIFT) | 9, + ADC0_SE11 = (0 << ADC_INSTANCE_SHIFT) | 11, + ADC0_SE12 = (0 << ADC_INSTANCE_SHIFT) | 12, + ADC0_SE13 = (0 << ADC_INSTANCE_SHIFT) | 13, + ADC0_SE14 = (0 << ADC_INSTANCE_SHIFT) | 14, + ADC0_SE15 = (0 << ADC_INSTANCE_SHIFT) | 15, + ADC0_SE16 = (0 << ADC_INSTANCE_SHIFT) | 16, + ADC0_SE17 = (0 << ADC_INSTANCE_SHIFT) | 17, + ADC0_SE18 = (0 << ADC_INSTANCE_SHIFT) | 18, + ADC0_SE21 = (0 << ADC_INSTANCE_SHIFT) | 21, + ADC0_SE22 = (0 << ADC_INSTANCE_SHIFT) | 22, + ADC0_SE23 = (0 << ADC_INSTANCE_SHIFT) | 23, +} ADCName; + +typedef enum { + SPI_0 = 0, + SPI_1 = 1, +} SPIName; + +typedef enum { + DAC_0 = 0 +} DACName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PeripheralPins.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PeripheralPins.c similarity index 70% rename from hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PeripheralPins.c rename to hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PeripheralPins.c index 03baff7c2e..2fcfe76e65 100644 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/PeripheralPins.c +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PeripheralPins.c @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #include "PeripheralPins.h" /************RTC***************/ const PinMap PinMap_RTC[] = { - {NC, OSC32KCLK, 0}, + {NC, OSC32KCLK, 0}, }; /************ADC***************/ @@ -29,12 +29,12 @@ const PinMap PinMap_ADC[] = { {PTE29, ADC0_SE4b, 0}, {PTE30, ADC0_SE23, 0}, {PTE23, ADC0_SE7a, 0}, - {PTB0, ADC0_SE8, 0}, - {PTB1, ADC0_SE9, 0}, - {PTB2, ADC0_SE12, 0}, - {PTB3, ADC0_SE13, 0}, - {PTC0, ADC0_SE14, 0}, - {PTC1, ADC0_SE15, 0}, + {PTB0 , ADC0_SE8 , 0}, + {PTB1 , ADC0_SE9 , 0}, + {PTB2 , ADC0_SE12, 0}, + {PTB3 , ADC0_SE13, 0}, + {PTC0 , ADC0_SE14, 0}, + {PTC1 , ADC0_SE15, 0}, {PTC2, ADC0_SE11, 0}, {PTD1, ADC0_SE5b, 0}, {PTD5, ADC0_SE6b, 0}, @@ -45,100 +45,94 @@ const PinMap PinMap_ADC[] = { /************DAC***************/ const PinMap PinMap_DAC[] = { {PTE30, DAC_0, 0}, - {NC , NC , 0} + {NC , NC , 0} }; /************I2C***************/ const PinMap PinMap_I2C_SDA[] = { {PTA4, I2C_0, 2}, - {PTB1, I2C_0, 2}, - {PTB3, I2C_0, 2}, - {PTC2, I2C_1, 2}, + {PTB1 , I2C_0 , 2}, + {PTB3 , I2C_0 , 2}, + {PTC2 , I2C_1 , 2}, {PTE0, I2C_1, 6}, {PTE25, I2C_0, 5}, - {NC , NC , 0} + {NC , NC , 0} }; const PinMap PinMap_I2C_SCL[] = { {PTA3, I2C_0, 2}, - {PTB0, I2C_0, 2}, - {PTB2, I2C_0, 2}, - {PTC1, I2C_1, 2}, + {PTB0 , I2C_0 , 2}, + {PTB2 , I2C_0 , 2}, + {PTC1 , I2C_1 , 2}, {PTE1, I2C_1, 6}, {PTE24, I2C_0, 5}, - {NC , NC, 0} + {NC , NC , 0} }; -/************UART***************/ +/************LPUART***************/ const PinMap PinMap_UART_TX[] = { - {PTA2, UART_0, 2}, - {PTA19, UART_1, 3}, - {PTB17, UART_0, 3}, - {PTD3, UART_2, 3}, - {PTD5, UART_2, 3}, - {PTD7, UART_0, 3}, - {PTE0, UART_1, 3}, - {PTE20, UART_0, 4}, - {PTE22, UART_2, 4}, - {PTE30, UART_1, 5}, - {NC , NC , 0} + {PTA2, LPUART_0 , 2}, + {PTA19, LPUART_1 , 3}, + {PTB17, LPUART_0 , 3}, + {PTD7, LPUART_0 , 3}, + {PTE0 , LPUART_1 , 3}, + {PTE20 , LPUART_0 , 4}, + {PTE30 , LPUART_1 , 5}, + {NC , NC , 0} }; const PinMap PinMap_UART_RX[] = { - {PTA1, UART_0, 2}, - {PTA18, UART_1, 3}, - {PTB16, UART_0, 3}, - {PTC3, UART_1, 3}, - {PTD2, UART_2, 3}, - {PTD4, UART_2, 3}, - {PTD6, UART_0, 3}, - {PTE1, UART_1, 3}, - {PTE21, UART_0, 4}, - {PTE23, UART_2, 4}, - {NC , NC , 0} + {PTA1, LPUART_0, 2}, + {PTA18, LPUART_1, 3}, + {PTB16, LPUART_0, 3}, + {PTC3, LPUART_1, 3}, + {PTD6, LPUART_0, 3}, + {PTE1, LPUART_1, 3}, + {PTE21, LPUART_0, 4}, + {NC , NC , 0} }; /************SPI***************/ const PinMap PinMap_SPI_SCLK[] = { {PTC3, SPI_1, 2}, - {PTC5, SPI_0, 2}, - {PTD1, SPI_0, 2}, - {PTD5, SPI_1, 2}, - {NC , NC , 0} + {PTC5 , SPI_0, 2}, + {PTD1 , SPI_0, 2}, + {PTD5 , SPI_1, 2}, + {NC , NC , 0} }; const PinMap PinMap_SPI_MOSI[] = { {PTB16, SPI_1, 2}, {PTB17, SPI_1, 5}, - {PTC6, SPI_0, 2}, - {PTC7, SPI_0, 5}, - {PTD2, SPI_0, 2}, - {PTD3, SPI_0, 5}, - {PTD6, SPI_1, 2}, - {PTD7, SPI_1, 5}, + {PTC6 , SPI_0, 2}, + {PTC7 , SPI_0, 5}, + {PTD2 , SPI_0, 2}, + {PTD3 , SPI_0, 5}, + {PTD6 , SPI_1, 2}, + {PTD7 , SPI_1, 5}, {PTE1, SPI_1, 2}, - {NC , NC , 0} + {NC , NC , 0} }; const PinMap PinMap_SPI_MISO[] = { {PTB16, SPI_1, 5}, {PTB17, SPI_1, 2}, - {PTC6, SPI_0, 5}, - {PTC7, SPI_0, 2}, - {PTD2, SPI_0, 5}, - {PTD3, SPI_0, 2}, - {PTD6, SPI_1, 5}, - {PTD7, SPI_1, 2}, + {PTC6 , SPI_0, 5}, + {PTC7 , SPI_0, 2}, + {PTD2 , SPI_0, 5}, + {PTD3 , SPI_0, 2}, + {PTD6 , SPI_1, 5}, + {PTD7 , SPI_1, 2}, {PTE0, SPI_1, 2}, {PTE1, SPI_1, 5}, {NC , NC , 0} }; const PinMap PinMap_SPI_SSEL[] = { - {PTC4, SPI_0, 2}, - {PTD0, SPI_0, 2}, - {PTD4, SPI_1, 2}, - {NC , NC , 0} + {PTC4 , SPI_0, 2}, + {PTD0 , SPI_0, 2}, + {PTD4 , SPI_1, 2}, + {NC , NC , 0} }; /************PWM***************/ @@ -151,7 +145,7 @@ const PinMap PinMap_PWM[] = { {PTA5, PWM_3 , 3}, // PTA5 , TPM0 CH2 {PTA12, PWM_7 , 3}, // PTA12, TPM1 CH0 {PTA13, PWM_8 , 3}, // PTA13, TPM1 CH1 - + {PTB0, PWM_7, 3}, // PTB0 , TPM1 CH0 {PTB1, PWM_8, 3}, // PTB1 , TPM1 CH1 {PTB2, PWM_9, 3}, // PTB2 , TPM2 CH0 @@ -163,7 +157,7 @@ const PinMap PinMap_PWM[] = { {PTC2, PWM_2, 4}, // PTC2 , TPM0 CH1 {PTC3, PWM_3, 4}, // PTC3 , TPM0 CH2 {PTC4, PWM_4, 4}, // PTC4 , TPM0 CH3 - + {PTD0, PWM_1 , 4}, // PTD0 , TPM0 CH0 {PTD1, PWM_2 , 4}, // PTD0 , TPM0 CH1 {PTD2, PWM_3 , 4}, // PTD2 , TPM0 CH2 @@ -180,5 +174,6 @@ const PinMap PinMap_PWM[] = { {PTE29, PWM_3, 3}, // PTE29, TPM0 CH2 {PTE30, PWM_4, 3}, // PTE30, TPM0 CH3 {PTE31, PWM_5, 3}, // PTE31, TPM0 CH4 - {NC , NC, 0} + {NC , NC , 0} }; + diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PinNames.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PinNames.h new file mode 100644 index 0000000000..a767b72c21 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/PinNames.h @@ -0,0 +1,150 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define GPIO_PORT_SHIFT 12 + +typedef enum { + PTA0 = (0 << GPIO_PORT_SHIFT | 0 ), + PTA1 = (0 << GPIO_PORT_SHIFT | 1 ), + PTA2 = (0 << GPIO_PORT_SHIFT | 2 ), + PTA3 = (0 << GPIO_PORT_SHIFT | 3 ), + PTA4 = (0 << GPIO_PORT_SHIFT | 4 ), + PTA5 = (0 << GPIO_PORT_SHIFT | 5 ), + PTA12 = (0 << GPIO_PORT_SHIFT | 12), + PTA13 = (0 << GPIO_PORT_SHIFT | 13), + PTA18 = (0 << GPIO_PORT_SHIFT | 18), + PTA19 = (0 << GPIO_PORT_SHIFT | 19), + PTA20 = (0 << GPIO_PORT_SHIFT | 20), + PTB0 = (1 << GPIO_PORT_SHIFT | 0 ), + PTB1 = (1 << GPIO_PORT_SHIFT | 1 ), + PTB2 = (1 << GPIO_PORT_SHIFT | 2 ), + PTB3 = (1 << GPIO_PORT_SHIFT | 3 ), + PTB16 = (1 << GPIO_PORT_SHIFT | 16), + PTB17 = (1 << GPIO_PORT_SHIFT | 17), + PTB18 = (1 << GPIO_PORT_SHIFT | 18), + PTB19 = (1 << GPIO_PORT_SHIFT | 19), + PTC0 = (2 << GPIO_PORT_SHIFT | 0 ), + PTC1 = (2 << GPIO_PORT_SHIFT | 1 ), + PTC2 = (2 << GPIO_PORT_SHIFT | 2 ), + PTC3 = (2 << GPIO_PORT_SHIFT | 3 ), + PTC4 = (2 << GPIO_PORT_SHIFT | 4 ), + PTC5 = (2 << GPIO_PORT_SHIFT | 5 ), + PTC6 = (2 << GPIO_PORT_SHIFT | 6 ), + PTC7 = (2 << GPIO_PORT_SHIFT | 7 ), + PTC8 = (2 << GPIO_PORT_SHIFT | 8 ), + PTC9 = (2 << GPIO_PORT_SHIFT | 9 ), + PTC10 = (2 << GPIO_PORT_SHIFT | 10), + PTC11 = (2 << GPIO_PORT_SHIFT | 11), + PTD0 = (3 << GPIO_PORT_SHIFT | 0 ), + PTD1 = (3 << GPIO_PORT_SHIFT | 1 ), + PTD2 = (3 << GPIO_PORT_SHIFT | 2 ), + PTD3 = (3 << GPIO_PORT_SHIFT | 3 ), + PTD4 = (3 << GPIO_PORT_SHIFT | 4 ), + PTD5 = (3 << GPIO_PORT_SHIFT | 5 ), + PTD6 = (3 << GPIO_PORT_SHIFT | 6 ), + PTD7 = (3 << GPIO_PORT_SHIFT | 7 ), + PTE0 = (4 << GPIO_PORT_SHIFT | 0 ), + PTE1 = (4 << GPIO_PORT_SHIFT | 1 ), + PTE16 = (4 << GPIO_PORT_SHIFT | 16), + PTE17 = (4 << GPIO_PORT_SHIFT | 17), + PTE18 = (4 << GPIO_PORT_SHIFT | 18), + PTE19 = (4 << GPIO_PORT_SHIFT | 19), + PTE20 = (4 << GPIO_PORT_SHIFT | 20), + PTE21 = (4 << GPIO_PORT_SHIFT | 21), + PTE22 = (4 << GPIO_PORT_SHIFT | 22), + PTE23 = (4 << GPIO_PORT_SHIFT | 23), + PTE24 = (4 << GPIO_PORT_SHIFT | 24), + PTE25 = (4 << GPIO_PORT_SHIFT | 25), + PTE29 = (4 << GPIO_PORT_SHIFT | 29), + PTE30 = (4 << GPIO_PORT_SHIFT | 30), + PTE31 = (4 << GPIO_PORT_SHIFT | 31), + + LED_RED = PTE31, + LED_GREEN = PTD5, + + // mbed original LED naming + LED1 = LED_GREEN, + LED2 = LED_RED, + LED3 = LED_GREEN, + LED4 = LED_RED, + + //Push buttons + SW1 = PTA4, + SW3 = PTC3, + + // USB Pins + USBTX = PTA2, + USBRX = PTA1, + + // Arduino Headers + + D0 = PTA1, + D1 = PTA2, + D2 = PTD3, + D3 = PTA12, + D4 = PTA4, + D5 = PTA5, + D6 = PTE29, + D7 = PTE30, + D8 = PTA13, + D9 = PTD2, + D10 = PTD4, + D11 = PTD6, + D12 = PTD7, + D13 = PTD5, + D14 = PTE0, + D15 = PTE1, + + I2C_SCL = D15, + I2C_SDA = D14, + + A0 = PTB0, + A1 = PTB1, + A2 = PTB2, + A3 = PTB3, + A4 = PTC2, + A5 = PTC1, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + + +typedef enum { + PullNone = 0, + PullDown = 1, + PullUp = 2, + PullDefault = PullUp +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/device.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/device.h similarity index 100% rename from hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/device.h rename to hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/device.h diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/fsl_clock_config.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/fsl_clock_config.c new file mode 100644 index 0000000000..630742cd4b --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/fsl_clock_config.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_common.h" +#include "fsl_smc.h" +#include "fsl_clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Clock configuration structure. */ +typedef struct _clock_config +{ + mcglite_config_t mcgliteConfig; /*!< MCG configuration. */ + sim_clock_config_t simConfig; /*!< SIM configuration. */ + osc_config_t oscConfig; /*!< OSC configuration. */ + uint32_t coreClock; /*!< core clock frequency. */ +} clock_config_t; + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/* Configuration for enter VLPR mode. Core clock = 2MHz. */ +const clock_config_t g_defaultClockConfigVlpr = { + .mcgliteConfig = + { + .outSrc = kMCGLITE_ClkSrcLirc, + .irclkEnableMode = kMCGLITE_IrclkEnable, + .ircs = kMCGLITE_Lirc2M, + .fcrdiv = kMCGLITE_LircDivBy1, + .lircDiv2 = kMCGLITE_LircDivBy1, + .hircEnableInNotHircMode = false, + }, + .simConfig = + { + .clkdiv1 = 0x00010000U, /* SIM_CLKDIV1. */ + }, + .oscConfig = {.freq = BOARD_XTAL0_CLK_HZ, + .capLoad = 0U, + .workMode = kOSC_ModeOscLowPower, + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, +#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) + .erclkDiv = 0U, +#endif + }}, + .coreClock = 2000000U, /* Core clock frequency */ +}; + +/* Configuration for enter RUN mode. Core clock = 48000000Hz. */ +const clock_config_t g_defaultClockConfigRun = { + .mcgliteConfig = + { + .outSrc = kMCGLITE_ClkSrcHirc, + .irclkEnableMode = kMCGLITE_IrclkEnable, + .ircs = kMCGLITE_Lirc8M, + .fcrdiv = kMCGLITE_LircDivBy1, + .lircDiv2 = kMCGLITE_LircDivBy1, + .hircEnableInNotHircMode = true, + }, + .simConfig = + { + .clkdiv1 = 0x00010000U, /* SIM_CLKDIV1. */ + }, + .oscConfig = {.freq = BOARD_XTAL0_CLK_HZ, + .capLoad = 0U, + .workMode = kOSC_ModeOscLowPower, + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, +#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) + .erclkDiv = 0U, +#endif + }}, + .coreClock = 48000000U, /* Core clock frequency */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration. + * + * 3. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +void BOARD_BootClockVLPR(void) +{ + CLOCK_SetSimSafeDivs(); + + CLOCK_SetMcgliteConfig(&g_defaultClockConfigVlpr.mcgliteConfig); + + CLOCK_SetSimConfig(&g_defaultClockConfigVlpr.simConfig); + + SystemCoreClock = g_defaultClockConfigVlpr.coreClock; + + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + SMC_SetPowerModeVlpr(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } +} + +void BOARD_BootClockRUN(void) +{ + CLOCK_SetSimSafeDivs(); + + CLOCK_SetMcgliteConfig(&g_defaultClockConfigRun.mcgliteConfig); + + CLOCK_SetSimConfig(&g_defaultClockConfigRun.simConfig); + + SystemCoreClock = g_defaultClockConfigRun.coreClock; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/fsl_clock_config.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/fsl_clock_config.h new file mode 100644 index 0000000000..c435fb9e40 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/fsl_clock_config.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 32768U +#define BOARD_XTAL32K_CLK_HZ 0U + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +void BOARD_BootClockVLPR(void); +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/mbed_overrides.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/mbed_overrides.c similarity index 69% rename from hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/mbed_overrides.c rename to hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/mbed_overrides.c index b590bb0ebc..d4577de95f 100644 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/mbed_overrides.c +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/TARGET_FRDM/mbed_overrides.c @@ -14,15 +14,24 @@ * limitations under the License. */ #include "gpio_api.h" +#include "pinmap.h" +#include "fsl_clock_config.h" -// called before main - implement here if board needs it ortherwise, let +// called before main - implement here if board needs it otherwise, let // the application override this if necessary -//void mbed_sdk_init() -//{ -// -//} +void mbed_sdk_init() +{ + BOARD_BootClockRUN(); +} -// Change the NMI pin to an input. This allows NMI pin to +// Enable the RTC oscillator if available on the board +void rtc_setup_oscillator(RTC_Type *base) +{ + /* Enable the RTC oscillator */ + RTC->CR |= RTC_CR_OSCE_MASK; +} + +// Change the NMI pin to an input. This allows NMI pin to // be used as a low power mode wakeup. The application will // need to change the pin back to NMI_b or wakeup only occurs once! void NMI_Handler(void) diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_adc16.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_adc16.c new file mode 100644 index 0000000000..8f1aa77b2e --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_adc16.c @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_adc16.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for ADC16 module. + * + * @param base ADC16 peripheral base address + */ +static uint32_t ADC16_GetInstance(ADC_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to ADC16 bases for each instance. */ +static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS; + +/*! @brief Pointers to ADC16 clocks for each instance. */ +const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t ADC16_GetInstance(ADC_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_ADC16_COUNT; instance++) + { + if (s_adc16Bases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_ADC16_COUNT); + + return instance; +} + +void ADC16_Init(ADC_Type *base, const adc16_config_t *config) +{ + assert(NULL != config); + + uint32_t tmp32; + + /* Enable the clock. */ + CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]); + + /* ADCx_CFG1. */ + tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution); + if (kADC16_LongSampleDisabled != config->longSampleMode) + { + tmp32 |= ADC_CFG1_ADLSMP_MASK; + } + tmp32 |= ADC_CFG1_ADIV(config->clockDivider); + if (config->enableLowPower) + { + tmp32 |= ADC_CFG1_ADLPC_MASK; + } + base->CFG1 = tmp32; + + /* ADCx_CFG2. */ + tmp32 = base->CFG2 & ~(ADC_CFG2_ADACKEN_MASK | ADC_CFG2_ADHSC_MASK | ADC_CFG2_ADLSTS_MASK); + if (kADC16_LongSampleDisabled != config->longSampleMode) + { + tmp32 |= ADC_CFG2_ADLSTS(config->longSampleMode); + } + if (config->enableHighSpeed) + { + tmp32 |= ADC_CFG2_ADHSC_MASK; + } + if (config->enableAsynchronousClock) + { + tmp32 |= ADC_CFG2_ADACKEN_MASK; + } + base->CFG2 = tmp32; + + /* ADCx_SC2. */ + tmp32 = base->SC2 & ~(ADC_SC2_REFSEL_MASK); + tmp32 |= ADC_SC2_REFSEL(config->referenceVoltageSource); + base->SC2 = tmp32; + + /* ADCx_SC3. */ + if (config->enableContinuousConversion) + { + base->SC3 |= ADC_SC3_ADCO_MASK; + } + else + { + base->SC3 &= ~ADC_SC3_ADCO_MASK; + } +} + +void ADC16_Deinit(ADC_Type *base) +{ + /* Disable the clock. */ + CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]); +} + +void ADC16_GetDefaultConfig(adc16_config_t *config) +{ + assert(NULL != config); + + config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; + config->clockSource = kADC16_ClockSourceAsynchronousClock; + config->enableAsynchronousClock = true; + config->clockDivider = kADC16_ClockDivider8; + config->resolution = kADC16_ResolutionSE12Bit; + config->longSampleMode = kADC16_LongSampleDisabled; + config->enableHighSpeed = false; + config->enableLowPower = false; + config->enableContinuousConversion = false; +} + +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION +status_t ADC16_DoAutoCalibration(ADC_Type *base) +{ + bool bHWTrigger = false; + uint32_t tmp32; + status_t status = kStatus_Success; + + /* The calibration would be failed when in hardwar mode. + * Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/ + if (0U != (ADC_SC2_ADTRG_MASK & base->SC2)) + { + bHWTrigger = true; + base->SC2 &= ~ADC_SC2_ADTRG_MASK; + } + + /* Clear the CALF and launch the calibration. */ + base->SC3 |= ADC_SC3_CAL_MASK | ADC_SC3_CALF_MASK; + while (0U == (kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(base, 0U))) + { + /* Check the CALF when the calibration is active. */ + if (0U != (kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base))) + { + status = kStatus_Fail; + break; + } + } + + /* Restore the hardware trigger setting if it was enabled before. */ + if (bHWTrigger) + { + base->SC2 |= ADC_SC2_ADTRG_MASK; + } + /* Check the CALF at the end of calibration. */ + if (0U != (kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base))) + { + status = kStatus_Fail; + } + if (kStatus_Success != status) /* Check if the calibration process is succeed. */ + { + return status; + } + + /* Calculate the calibration values. */ + tmp32 = base->CLP0 + base->CLP1 + base->CLP2 + base->CLP3 + base->CLP4 + base->CLPS; + tmp32 = 0x8000U | (tmp32 >> 1U); + base->PG = tmp32; + +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + tmp32 = base->CLM0 + base->CLM1 + base->CLM2 + base->CLM3 + base->CLM4 + base->CLMS; + tmp32 = 0x8000U | (tmp32 >> 1U); + base->MG = tmp32; +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + + return kStatus_Success; +} +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + +#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT +void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode) +{ + if (kADC16_ChannelMuxA == mode) + { + base->CFG2 &= ~ADC_CFG2_MUXSEL_MASK; + } + else /* kADC16_ChannelMuxB. */ + { + base->CFG2 |= ADC_CFG2_MUXSEL_MASK; + } +} +#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ + +void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config) +{ + uint32_t tmp32 = base->SC2 & ~(ADC_SC2_ACFE_MASK | ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK); + + if (!config) /* Pass "NULL" to disable the feature. */ + { + base->SC2 = tmp32; + return; + } + /* Enable the feature. */ + tmp32 |= ADC_SC2_ACFE_MASK; + + /* Select the hardware compare working mode. */ + switch (config->hardwareCompareMode) + { + case kADC16_HardwareCompareMode0: + break; + case kADC16_HardwareCompareMode1: + tmp32 |= ADC_SC2_ACFGT_MASK; + break; + case kADC16_HardwareCompareMode2: + tmp32 |= ADC_SC2_ACREN_MASK; + break; + case kADC16_HardwareCompareMode3: + tmp32 |= ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK; + break; + default: + break; + } + base->SC2 = tmp32; + + /* Load the compare values. */ + base->CV1 = ADC_CV1_CV(config->value1); + base->CV2 = ADC_CV2_CV(config->value2); +} + +#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE +void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode) +{ + uint32_t tmp32 = base->SC3 & ~(ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK); + + if (kADC16_HardwareAverageDisabled != mode) + { + tmp32 |= ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(mode); + } + base->SC3 = tmp32; +} +#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ + +#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA +void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config) +{ + uint32_t tmp32; + + if (!config) /* Passing "NULL" is to disable the feature. */ + { + base->PGA = 0U; + return; + } + + /* Enable the PGA and set the gain value. */ + tmp32 = ADC_PGA_PGAEN_MASK | ADC_PGA_PGAG(config->pgaGain); + + /* Configure the misc features for PGA. */ + if (config->enableRunInNormalMode) + { + tmp32 |= ADC_PGA_PGALPb_MASK; + } +#if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING + if (config->disablePgaChopping) + { + tmp32 |= ADC_PGA_PGACHPb_MASK; + } +#endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */ +#if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT + if (config->enableRunInOffsetMeasurement) + { + tmp32 |= ADC_PGA_PGAOFSM_MASK; + } +#endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */ + base->PGA = tmp32; +} +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +uint32_t ADC16_GetStatusFlags(ADC_Type *base) +{ + uint32_t ret = 0; + + if (0U != (base->SC2 & ADC_SC2_ADACT_MASK)) + { + ret |= kADC16_ActiveFlag; + } +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION + if (0U != (base->SC3 & ADC_SC3_CALF_MASK)) + { + ret |= kADC16_CalibrationFailedFlag; + } +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + return ret; +} + +void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask) +{ +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION + if (0U != (mask & kADC16_CalibrationFailedFlag)) + { + base->SC3 |= ADC_SC3_CALF_MASK; + } +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ +} + +void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config) +{ + assert(channelGroup < ADC_SC1_COUNT); + assert(NULL != config); + + uint32_t sc1 = ADC_SC1_ADCH(config->channelNumber); /* Set the channel number. */ + +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + /* Enable the differential conversion. */ + if (config->enableDifferentialConversion) + { + sc1 |= ADC_SC1_DIFF_MASK; + } +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + /* Enable the interrupt when the conversion is done. */ + if (config->enableInterruptOnConversionCompleted) + { + sc1 |= ADC_SC1_AIEN_MASK; + } + base->SC1[channelGroup] = sc1; +} + +uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup) +{ + assert(channelGroup < ADC_SC1_COUNT); + + uint32_t ret = 0U; + + if (0U != (base->SC1[channelGroup] & ADC_SC1_COCO_MASK)) + { + ret |= kADC16_ChannelConversionDoneFlag; + } + return ret; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_adc16.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_adc16.h new file mode 100644 index 0000000000..c6b5bc0d1a --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_adc16.h @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_ADC16_H_ +#define _FSL_ADC16_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup adc16 + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief ADC16 driver version 2.0.0. */ +#define FSL_ADC16_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! + * @brief Channel status flags. + */ +enum _adc16_channel_status_flags +{ + kADC16_ChannelConversionDoneFlag = ADC_SC1_COCO_MASK, /*!< Conversion done. */ +}; + +/*! + * @brief Converter status flags. + */ +enum _adc16_status_flags +{ + kADC16_ActiveFlag = ADC_SC2_ADACT_MASK, /*!< Converter is active. */ +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION + kADC16_CalibrationFailedFlag = ADC_SC3_CALF_MASK, /*!< Calibration is failed. */ +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ +}; + +#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT +/*! + * @brief Channel multiplexer mode for each channel. + * + * For some ADC16 channels, there are two pin selections in channel multiplexer. For example, ADC0_SE4a and ADC0_SE4b + * are the different channels but share the same channel number. + */ +typedef enum _adc_channel_mux_mode +{ + kADC16_ChannelMuxA = 0U, /*!< For channel with channel mux a. */ + kADC16_ChannelMuxB = 1U, /*!< For channel with channel mux b. */ +} adc16_channel_mux_mode_t; +#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ + +/*! + * @brief Clock divider for the converter. + */ +typedef enum _adc16_clock_divider +{ + kADC16_ClockDivider1 = 0U, /*!< For divider 1 from the input clock to the module. */ + kADC16_ClockDivider2 = 1U, /*!< For divider 2 from the input clock to the module. */ + kADC16_ClockDivider4 = 2U, /*!< For divider 4 from the input clock to the module. */ + kADC16_ClockDivider8 = 3U, /*!< For divider 8 from the input clock to the module. */ +} adc16_clock_divider_t; + +/*! + *@brief Converter's resolution. + */ +typedef enum _adc16_resolution +{ + /* This group of enumeration is for internal use which is related to register setting. */ + kADC16_Resolution8or9Bit = 0U, /*!< Single End 8-bit or Differential Sample 9-bit. */ + kADC16_Resolution12or13Bit = 1U, /*!< Single End 12-bit or Differential Sample 13-bit. */ + kADC16_Resolution10or11Bit = 2U, /*!< Single End 10-bit or Differential Sample 11-bit. */ + + /* This group of enumeration is for public user. */ + kADC16_ResolutionSE8Bit = kADC16_Resolution8or9Bit, /*!< Single End 8-bit. */ + kADC16_ResolutionSE12Bit = kADC16_Resolution12or13Bit, /*!< Single End 12-bit. */ + kADC16_ResolutionSE10Bit = kADC16_Resolution10or11Bit, /*!< Single End 10-bit. */ +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + kADC16_ResolutionDF9Bit = kADC16_Resolution8or9Bit, /*!< Differential Sample 9-bit. */ + kADC16_ResolutionDF13Bit = kADC16_Resolution12or13Bit, /*!< Differential Sample 13-bit. */ + kADC16_ResolutionDF11Bit = kADC16_Resolution10or11Bit, /*!< Differential Sample 11-bit. */ +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ + +#if defined(FSL_FEATURE_ADC16_MAX_RESOLUTION) && (FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U) + /* 16-bit is supported by default. */ + kADC16_Resolution16Bit = 3U, /*!< Single End 16-bit or Differential Sample 16-bit. */ + kADC16_ResolutionSE16Bit = kADC16_Resolution16Bit, /*!< Single End 16-bit. */ +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + kADC16_ResolutionDF16Bit = kADC16_Resolution16Bit, /*!< Differential Sample 16-bit. */ +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ +#endif /* FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U */ +} adc16_resolution_t; + +/*! + * @brief Clock source. + */ +typedef enum _adc16_clock_source +{ + kADC16_ClockSourceAlt0 = 0U, /*!< Selection 0 of the clock source. */ + kADC16_ClockSourceAlt1 = 1U, /*!< Selection 1 of the clock source. */ + kADC16_ClockSourceAlt2 = 2U, /*!< Selection 2 of the clock source. */ + kADC16_ClockSourceAlt3 = 3U, /*!< Selection 3 of the clock source. */ + + /* Chip defined clock source */ + kADC16_ClockSourceAsynchronousClock = kADC16_ClockSourceAlt3, /*!< Using internal asynchronous clock. */ +} adc16_clock_source_t; + +/*! + * @brief Long sample mode. + */ +typedef enum _adc16_long_sample_mode +{ + kADC16_LongSampleCycle24 = 0U, /*!< 20 extra ADCK cycles, 24 ADCK cycles total. */ + kADC16_LongSampleCycle16 = 1U, /*!< 12 extra ADCK cycles, 16 ADCK cycles total. */ + kADC16_LongSampleCycle10 = 2U, /*!< 6 extra ADCK cycles, 10 ADCK cycles total. */ + kADC16_LongSampleCycle6 = 3U, /*!< 2 extra ADCK cycles, 6 ADCK cycles total. */ + kADC16_LongSampleDisabled = 4U, /*!< Disable the long sample feature. */ +} adc16_long_sample_mode_t; + +/*! + * @brief Reference voltage source. + */ +typedef enum _adc16_reference_voltage_source +{ + kADC16_ReferenceVoltageSourceVref = 0U, /*!< For external pins pair of VrefH and VrefL. */ + kADC16_ReferenceVoltageSourceValt = 1U, /*!< For alternate reference pair of ValtH and ValtL. */ +} adc16_reference_voltage_source_t; + +#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE +/*! + * @brief Hardware average mode. + */ +typedef enum _adc16_hardware_average_mode +{ + kADC16_HardwareAverageCount4 = 0U, /*!< For hardware average with 4 samples. */ + kADC16_HardwareAverageCount8 = 1U, /*!< For hardware average with 8 samples. */ + kADC16_HardwareAverageCount16 = 2U, /*!< For hardware average with 16 samples. */ + kADC16_HardwareAverageCount32 = 3U, /*!< For hardware average with 32 samples. */ + kADC16_HardwareAverageDisabled = 4U, /*!< Disable the hardware average feature.*/ +} adc16_hardware_average_mode_t; +#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ + +/*! + * @brief Hardware compare mode. + */ +typedef enum _adc16_hardware_compare_mode +{ + kADC16_HardwareCompareMode0 = 0U, /*!< x < value1. */ + kADC16_HardwareCompareMode1 = 1U, /*!< x > value1. */ + kADC16_HardwareCompareMode2 = 2U, /*!< if value1 <= value2, then x < value1 || x > value2; + else, value1 > x > value2. */ + kADC16_HardwareCompareMode3 = 3U, /*!< if value1 <= value2, then value1 <= x <= value2; + else x >= value1 || x <= value2. */ +} adc16_hardware_compare_mode_t; + +#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA +/*! + * @brief PGA's Gain mode. + */ +typedef enum _adc16_pga_gain +{ + kADC16_PGAGainValueOf1 = 0U, /*!< For amplifier gain of 1. */ + kADC16_PGAGainValueOf2 = 1U, /*!< For amplifier gain of 2. */ + kADC16_PGAGainValueOf4 = 2U, /*!< For amplifier gain of 4. */ + kADC16_PGAGainValueOf8 = 3U, /*!< For amplifier gain of 8. */ + kADC16_PGAGainValueOf16 = 4U, /*!< For amplifier gain of 16. */ + kADC16_PGAGainValueOf32 = 5U, /*!< For amplifier gain of 32. */ + kADC16_PGAGainValueOf64 = 6U, /*!< For amplifier gain of 64. */ +} adc16_pga_gain_t; +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +/*! + * @brief ADC16 converter configuration . + */ +typedef struct _adc16_config +{ + adc16_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */ + adc16_clock_source_t clockSource; /*!< Select the input clock source to converter. */ + bool enableAsynchronousClock; /*!< Enable the asynchronous clock output. */ + adc16_clock_divider_t clockDivider; /*!< Select the divider of input clock source. */ + adc16_resolution_t resolution; /*!< Select the sample resolution mode. */ + adc16_long_sample_mode_t longSampleMode; /*!< Select the long sample mode. */ + bool enableHighSpeed; /*!< Enable the high-speed mode. */ + bool enableLowPower; /*!< Enable low power. */ + bool enableContinuousConversion; /*!< Enable continuous conversion mode. */ +} adc16_config_t; + +/*! + * @brief ADC16 Hardware compare configuration. + */ +typedef struct _adc16_hardware_compare_config +{ + adc16_hardware_compare_mode_t hardwareCompareMode; /*!< Select the hardware compare mode. + See "adc16_hardware_compare_mode_t". */ + int16_t value1; /*!< Setting value1 for hardware compare mode. */ + int16_t value2; /*!< Setting value2 for hardware compare mode. */ +} adc16_hardware_compare_config_t; + +/*! + * @brief ADC16 channel conversion configuration. + */ +typedef struct _adc16_channel_config +{ + uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31. + See channel connection information for each chip in Reference + Manual document. */ + bool enableInterruptOnConversionCompleted; /*!< Generate a interrupt request once the conversion is completed. */ +#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE + bool enableDifferentialConversion; /*!< Using Differential sample mode. */ +#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ +} adc16_channel_config_t; + +#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA +/*! + * @brief ADC16 programmable gain amplifier configuration. + */ +typedef struct _adc16_pga_config +{ + adc16_pga_gain_t pgaGain; /*!< Setting PGA gain. */ + bool enableRunInNormalMode; /*!< Enable PGA working in normal mode, or low power mode by default. */ +#if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING + bool disablePgaChopping; /*!< Disable the PGA chopping function. + The PGA employs chopping to remove/reduce offset and 1/f noise and offers + an offset measurement configuration that aids the offset calibration. */ +#endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */ +#if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT + bool enableRunInOffsetMeasurement; /*!< Enable the PGA working in offset measurement mode. + When this feature is enabled, the PGA disconnects itself from the external + inputs and auto-configures into offset measurement mode. With this field + set, run the ADC in the recommended settings and enable the maximum hardware + averaging to get the PGA offset number. The output is the + (PGA offset * (64+1)) for the given PGA setting. */ +#endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */ +} adc16_pga_config_t; +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes the ADC16 module. + * + * @param base ADC16 peripheral base address. + * @param config Pointer to configuration structure. See "adc16_config_t". + */ +void ADC16_Init(ADC_Type *base, const adc16_config_t *config); + +/*! + * @brief De-initializes the ADC16 module. + * + * @param base ADC16 peripheral base address. + */ +void ADC16_Deinit(ADC_Type *base); + +/*! + * @brief Gets an available pre-defined settings for converter's configuration. + * + * This function initializes the converter configuration structure with an available settings. The default values are: + * @code + * config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; + * config->clockSource = kADC16_ClockSourceAsynchronousClock; + * config->enableAsynchronousClock = true; + * config->clockDivider = kADC16_ClockDivider8; + * config->resolution = kADC16_ResolutionSE12Bit; + * config->longSampleMode = kADC16_LongSampleDisabled; + * config->enableHighSpeed = false; + * config->enableLowPower = false; + * config->enableContinuousConversion = false; + * @endcode + * @param config Pointer to configuration structure. + */ +void ADC16_GetDefaultConfig(adc16_config_t *config); + +#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION +/*! + * @brief Automates the hardware calibration. + * + * This auto calibration helps to adjust the plus/minus side gain automatically on the converter's working situation. + * Execute the calibration before using the converter. Note that the hardware trigger should be used + * during calibration. + * + * @param base ADC16 peripheral base address. + * + * @return Execution status. + * @retval kStatus_Success Calibration is done successfully. + * @retval kStatus_Fail Calibration is failed. + */ +status_t ADC16_DoAutoCalibration(ADC_Type *base); +#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ + +#if defined(FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION) && FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION +/*! + * @brief Sets the offset value for the conversion result. + * + * This offset value takes effect on the conversion result. If the offset value is not zero, the reading result + * is subtracted by it. Note, the hardware calibration fills the offset value automatically. + * + * @param base ADC16 peripheral base address. + * @param value Setting offset value. + */ +static inline void ADC16_SetOffsetValue(ADC_Type *base, int16_t value) +{ + base->OFS = (uint32_t)(value); +} +#endif /* FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION */ + +/* @} */ + +/*! + * @name Advanced Feature + * @{ + */ + +#if defined(FSL_FEATURE_ADC16_HAS_DMA) && FSL_FEATURE_ADC16_HAS_DMA +/*! + * @brief Enables generating the DMA trigger when conversion is completed. + * + * @param base ADC16 peripheral base address. + * @param enable Switcher of DMA feature. "true" means to enable, "false" means not. + */ +static inline void ADC16_EnableDMA(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SC2 |= ADC_SC2_DMAEN_MASK; + } + else + { + base->SC2 &= ~ADC_SC2_DMAEN_MASK; + } +} +#endif /* FSL_FEATURE_ADC16_HAS_DMA */ + +/*! + * @brief Enables the hardware trigger mode. + * + * @param base ADC16 peripheral base address. + * @param enable Switcher of hardware trigger feature. "true" means to enable, "false" means not. + */ +static inline void ADC16_EnableHardwareTrigger(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SC2 |= ADC_SC2_ADTRG_MASK; + } + else + { + base->SC2 &= ~ADC_SC2_ADTRG_MASK; + } +} + +#if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT +/*! + * @brief Sets the channel mux mode. + * + * Some sample pins share the same channel index. The channel mux mode decides which pin is used for an + * indicated channel. + * + * @param base ADC16 peripheral base address. + * @param mode Setting channel mux mode. See "adc16_channel_mux_mode_t". + */ +void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode); +#endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ + +/*! + * @brief Configures the hardware compare mode. + * + * The hardware compare mode provides a way to process the conversion result automatically by hardware. Only the result + * in + * compare range is available. To compare the range, see "adc16_hardware_compare_mode_t", or the reference + * manual document for more detailed information. + * + * @param base ADC16 peripheral base address. + * @param config Pointer to "adc16_hardware_compare_config_t" structure. Passing "NULL" is to disable the feature. + */ +void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config); + +#if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE +/*! + * @brief Sets the hardware average mode. + * + * Hardware average mode provides a way to process the conversion result automatically by hardware. The multiple + * conversion results are accumulated and averaged internally. This aids reading results. + * + * @param base ADC16 peripheral base address. + * @param mode Setting hardware average mode. See "adc16_hardware_average_mode_t". + */ +void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode); +#endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ + +#if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA +/*! + * @brief Configures the PGA for converter's front end. + * + * @param base ADC16 peripheral base address. + * @param config Pointer to "adc16_pga_config_t" structure. Passing "NULL" is to disable the feature. + */ +void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config); +#endif /* FSL_FEATURE_ADC16_HAS_PGA */ + +/*! + * @brief Gets the status flags of the converter. + * + * @param base ADC16 peripheral base address. + * + * @return Flags' mask if indicated flags are asserted. See "_adc16_status_flags". + */ +uint32_t ADC16_GetStatusFlags(ADC_Type *base); + +/*! + * @brief Clears the status flags of the converter. + * + * @param base ADC16 peripheral base address. + * @param mask Mask value for the cleared flags. See "_adc16_status_flags". + */ +void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Conversion Channel + * @{ + */ + +/*! + * @brief Configures the conversion channel. + * + * This operation triggers the conversion if in software trigger mode. When in hardware trigger mode, this API + * configures the channel while the external trigger source helps to trigger the conversion. + * + * Note that the "Channel Group" has a detailed description. + * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC can have more than one + * group of status and control register, one for each conversion. The channel group parameter indicates which group of + * registers are used channel group 0 is for Group A registers and channel group 1 is for Group B registers. The + * channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of + * the channel groups is actively controlling ADC conversions. Channel group 0 is used for both software and hardware + * trigger modes of operation. Channel groups 1 and greater indicate potentially multiple channel group registers for + * use only in hardware trigger mode. See the chip configuration information in the MCU reference manual about the + * number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used + * for software trigger operation and therefore writes to these channel groups do not initiate a new conversion. + * Updating channel group 0 while a different channel group is actively controlling a conversion is allowed and + * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a + * conversion aborts the current conversion. + * + * @param base ADC16 peripheral base address. + * @param channelGroup Channel group index. + * @param config Pointer to "adc16_channel_config_t" structure for conversion channel. + */ +void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config); + +/*! + * @brief Gets the conversion value. + * + * @param base ADC16 peripheral base address. + * @param channelGroup Channel group index. + * + * @return Conversion value. + */ +static inline uint32_t ADC16_GetChannelConversionValue(ADC_Type *base, uint32_t channelGroup) +{ + assert(channelGroup < ADC_R_COUNT); + + return base->R[channelGroup]; +} + +/*! + * @brief Gets the status flags of channel. + * + * @param base ADC16 peripheral base address. + * @param channelGroup Channel group index. + * + * @return Flags' mask if indicated flags are asserted. See "_adc16_channel_status_flags". + */ +uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup); + +/* @} */ + +#if defined(__cplusplus) +} +#endif +/*! + * @} + */ +#endif /* _FSL_ADC16_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_clock.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_clock.c new file mode 100644 index 0000000000..5f0eba1d37 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_clock.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_common.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#if (defined(OSC) && !(defined(OSC0))) +#define OSC0 OSC +#endif + +#define MCG_HIRC_FREQ (48000000U) +#define MCG_LIRC_FREQ1 (2000000U) +#define MCG_LIRC_FREQ2 (8000000U) + +#define MCG_S_CLKST_VAL ((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) +#define MCG_SC_FCRDIV_VAL ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT) +#define MCG_MC_LIRC_DIV2_VAL ((MCG->MC & MCG_MC_LIRC_DIV2_MASK) >> MCG_MC_LIRC_DIV2_SHIFT) +#define MCG_C2_IRCS_VAL ((MCG->C2 & MCG_C2_IRCS_MASK) >> MCG_C2_IRCS_SHIFT) + +#define SIM_CLKDIV1_OUTDIV1_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT) +#define SIM_CLKDIV1_OUTDIV4_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) +#define SIM_SOPT1_OSC32KSEL_VAL ((SIM->SOPT1 & SIM_SOPT1_OSC32KSEL_MASK) >> SIM_SOPT1_OSC32KSEL_SHIFT) + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* External XTAL0 (OSC0) clock frequency. */ +uint32_t g_xtal0Freq; + +/* External XTAL32K clock frequency. */ +uint32_t g_xtal32Freq; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get the current MCG_Lite LIRC_CLK frequency in Hz. + * + * This function will return the LIRC_CLK value in frequency(Hz) based + * on current MCG_Lite configurations and settings. It is an internal function. + * + * @return MCG_Lite LIRC_CLK frequency. + */ +static uint32_t CLOCK_GetLircClkFreq(void); + +/*! + * @brief Get RANGE value based on OSC frequency. + * + * To setup external crystal oscillator, must set the register bits RANGE base + * on the crystal frequency. This function returns the RANGE base on the input + * frequency. This is an internal function. + * + * @return RANGE value. + */ +static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq); + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t CLOCK_GetLircClkFreq(void) +{ + static const uint32_t lircFreqs[] = {MCG_LIRC_FREQ1, MCG_LIRC_FREQ2}; + + /* Check whether the LIRC is enabled. */ + if ((MCG->C1 & MCG_C1_IRCLKEN_MASK) || (kMCGLITE_ClkSrcLirc == MCG_S_CLKST_VAL)) + { + return lircFreqs[MCG_C2_IRCS_VAL]; + } + else + { + return 0U; + } +} + +static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq) +{ + uint8_t range; + + if (freq <= 39063U) + { + range = 0U; + } + else if (freq <= 8000000U) + { + range = 1U; + } + else + { + range = 2U; + } + + return range; +} + +uint32_t CLOCK_GetOsc0ErClkFreq(void) +{ + if (OSC0->CR & OSC_CR_ERCLKEN_MASK) + { + /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */ + assert(g_xtal0Freq); + return g_xtal0Freq; + } + else + { + return 0U; + } +} + +uint32_t CLOCK_GetEr32kClkFreq(void) +{ + uint32_t freq; + + switch (SIM_SOPT1_OSC32KSEL_VAL) + { + case 0U: /* OSC 32k clock */ + freq = (CLOCK_GetOsc0ErClkFreq() == 32768U) ? 32768U : 0U; + break; + case 2U: /* RTC 32k clock */ + /* Please call CLOCK_SetXtal32Freq base on board setting before using XTAL32K/RTC_CLKIN clock. */ + assert(g_xtal32Freq); + freq = g_xtal32Freq; + break; + case 3U: /* LPO clock */ + freq = LPO_CLK_FREQ; + break; + default: + freq = 0U; + break; + } + return freq; +} + +uint32_t CLOCK_GetPlatClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); +} + +uint32_t CLOCK_GetFlashClkFreq(void) +{ + uint32_t freq; + + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); + freq /= (SIM_CLKDIV1_OUTDIV4_VAL + 1); + + return freq; +} + +uint32_t CLOCK_GetBusClkFreq(void) +{ + uint32_t freq; + + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); + freq /= (SIM_CLKDIV1_OUTDIV4_VAL + 1); + + return freq; +} + +uint32_t CLOCK_GetCoreSysClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); +} + +uint32_t CLOCK_GetFreq(clock_name_t clockName) +{ + uint32_t freq; + + switch (clockName) + { + case kCLOCK_CoreSysClk: + case kCLOCK_PlatClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); + break; + case kCLOCK_BusClk: + case kCLOCK_FlashClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); + freq /= (SIM_CLKDIV1_OUTDIV4_VAL + 1); + break; + case kCLOCK_Er32kClk: + freq = CLOCK_GetEr32kClkFreq(); + break; + case kCLOCK_Osc0ErClk: + freq = CLOCK_GetOsc0ErClkFreq(); + break; + case kCLOCK_McgInternalRefClk: + freq = CLOCK_GetInternalRefClkFreq(); + break; + case kCLOCK_McgPeriphClk: + case kCLOCK_McgIrc48MClk: + freq = CLOCK_GetPeriphClkFreq(); + break; + case kCLOCK_LpoClk: + freq = LPO_CLK_FREQ; + break; + default: + freq = 0U; + break; + } + + return freq; +} + +void CLOCK_SetSimConfig(sim_clock_config_t const *config) +{ + SIM->CLKDIV1 = config->clkdiv1; + CLOCK_SetEr32kClock(config->er32kSrc); +} + +bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq) +{ + bool ret = true; + + CLOCK_DisableClock(kCLOCK_Usbfs0); + + if (kCLOCK_UsbSrcExt == src) + { + SIM->SOPT2 &= ~SIM_SOPT2_USBSRC_MASK; + } + else + { + SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK; + } + + CLOCK_EnableClock(kCLOCK_Usbfs0); + + if (kCLOCK_UsbSrcIrc48M == src) + { + USB0->CLK_RECOVER_IRC_EN = 0x03U; + USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK; + } + + return ret; +} + +uint32_t CLOCK_GetInternalRefClkFreq(void) +{ + uint8_t divider1 = MCG_SC_FCRDIV_VAL; + uint8_t divider2 = MCG_MC_LIRC_DIV2_VAL; + /* LIRC internal reference clock is selected*/ + return CLOCK_GetLircClkFreq() >> (divider1 + divider2); +} + +uint32_t CLOCK_GetPeriphClkFreq(void) +{ + /* Check whether the HIRC is enabled. */ + if ((MCG->MC & MCG_MC_HIRCEN_MASK) || (kMCGLITE_ClkSrcHirc == MCG_S_CLKST_VAL)) + { + return MCG_HIRC_FREQ; + } + else + { + return 0U; + } +} + +uint32_t CLOCK_GetOutClkFreq(void) +{ + uint32_t freq; + + switch (MCG_S_CLKST_VAL) + { + case kMCGLITE_ClkSrcHirc: + freq = MCG_HIRC_FREQ; + break; + case kMCGLITE_ClkSrcLirc: + freq = CLOCK_GetLircClkFreq() >> MCG_SC_FCRDIV_VAL; + break; + case kMCGLITE_ClkSrcExt: + /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */ + assert(g_xtal0Freq); + freq = g_xtal0Freq; + break; + default: + freq = 0U; + break; + } + + return freq; +} + +mcglite_mode_t CLOCK_GetMode(void) +{ + mcglite_mode_t mode; + + switch (MCG_S_CLKST_VAL) + { + case kMCGLITE_ClkSrcHirc: /* HIRC */ + mode = kMCGLITE_ModeHirc48M; + break; + case kMCGLITE_ClkSrcLirc: /* LIRC */ + if (kMCGLITE_Lirc2M == MCG_C2_IRCS_VAL) + { + mode = kMCGLITE_ModeLirc2M; + } + else + { + mode = kMCGLITE_ModeLirc8M; + } + break; + case kMCGLITE_ClkSrcExt: /* EXT */ + mode = kMCGLITE_ModeExt; + break; + default: + mode = kMCGLITE_ModeError; + break; + } + + return mode; +} + +status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig) +{ + assert(targetConfig); + + /* + * If switch between LIRC8M and LIRC2M, need to switch to HIRC mode first, + * because could not switch directly. + */ + if ((kMCGLITE_ClkSrcLirc == MCG_S_CLKST_VAL) && (kMCGLITE_ClkSrcLirc == targetConfig->outSrc) && + (MCG_C2_IRCS_VAL != targetConfig->ircs)) + { + MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCGLITE_ClkSrcHirc); + while (kMCGLITE_ClkSrcHirc != MCG_S_CLKST_VAL) + { + } + } + + /* Set configuration now. */ + MCG->SC = MCG_SC_FCRDIV(targetConfig->fcrdiv); + MCG->MC = MCG_MC_HIRCEN(targetConfig->hircEnableInNotHircMode) | MCG_MC_LIRC_DIV2(targetConfig->lircDiv2); + MCG->C2 = (MCG->C2 & ~MCG_C2_IRCS_MASK) | MCG_C2_IRCS(targetConfig->ircs); + MCG->C1 = MCG_C1_CLKS(targetConfig->outSrc) | targetConfig->irclkEnableMode; + + /* + * If external oscillator used and MCG_Lite is set to EXT mode, need to + * wait for the OSC stable. + */ + if ((MCG->C2 & MCG_C2_EREFS0_MASK) && (kMCGLITE_ClkSrcExt == targetConfig->outSrc)) + { + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } + + /* Wait for clock source change completed. */ + while (targetConfig->outSrc != MCG_S_CLKST_VAL) + { + } + + return kStatus_Success; +} + +void CLOCK_InitOsc0(osc_config_t const *config) +{ + uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq); + + OSC_SetCapLoad(OSC0, config->capLoad); + OSC_SetExtRefClkConfig(OSC0, &config->oscerConfig); + + MCG->C2 = ((MCG->C2 & MCG_C2_IRCS_MASK) | MCG_C2_RANGE0(range) | (uint8_t)config->workMode); + + if ((kOSC_ModeExt != config->workMode) && (OSC0->CR & OSC_CR_ERCLKEN_MASK)) + { + /* Wait for stable. */ + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } +} + +void CLOCK_DeinitOsc0(void) +{ + OSC0->CR = 0U; + MCG->C2 &= MCG_C2_IRCS_MASK; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_clock.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_clock.h new file mode 100644 index 0000000000..dd5594b0be --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_clock.h @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_CLOCK_H_ +#define _FSL_CLOCK_H_ + +#include "fsl_device_registers.h" +#include +#include +#include + +/*! @addtogroup mcglite */ +/*! @{ */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Clock driver version. */ +#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */ + +/*! @brief External XTAL0 (OSC0) clock frequency. + * + * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz, when the clock is setup, use the + * function CLOCK_SetXtal0Freq to set the value in to clock driver. For example, + * if XTAL0 is 8MHz, + * @code + * CLOCK_InitOsc0(...); // Setup the OSC0 + * CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to clock driver. + * @endcode + * + * This is important for the multicore platforms, only one core needs to setup + * OSC0 using CLOCK_InitOsc0, all other cores need to call CLOCK_SetXtal0Freq + * to get valid clock frequency. + */ +extern uint32_t g_xtal0Freq; + +/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. + * + * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz, when the clock is setup, use the + * function CLOCK_SetXtal32Freq to set the value in to clock driver. + * + * This is important for the multicore platforms, only one core needs to setup + * the clock, all other cores need to call CLOCK_SetXtal32Freq + * to get valid clock frequency. + */ +extern uint32_t g_xtal32Freq; + +/*! @brief Clock ip name array for DMAMUX. */ +#define DMAMUX_CLOCKS \ + { \ + kCLOCK_Dmamux0 \ + } + +/*! @brief Clock ip name array for RTC. */ +#define RTC_CLOCKS \ + { \ + kCLOCK_Rtc0 \ + } + +/*! @brief Clock ip name array for SAI. */ +#define SAI_CLOCKS \ + { \ + kCLOCK_Sai0 \ + } + +/*! @brief Clock ip name array for SPI. */ +#define SPI_CLOCKS \ + { \ + kCLOCK_Spi0, kCLOCK_Spi1 \ + } + +/*! @brief Clock ip name array for SLCD. */ +#define SLCD_CLOCKS \ + { \ + kCLOCK_Slcd0 \ + } + +/*! @brief Clock ip name array for PIT. */ +#define PIT_CLOCKS \ + { \ + kCLOCK_Pit0 \ + } + +/*! @brief Clock ip name array for PORT. */ +#define PORT_CLOCKS \ + { \ + kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \ + } + +/*! @brief Clock ip name array for LPUART. */ +#define LPUART_CLOCKS \ + { \ + kCLOCK_Lpuart0, kCLOCK_Lpuart1 \ + } + +/*! @brief Clock ip name array for DAC. */ +#define DAC_CLOCKS \ + { \ + kCLOCK_Dac0 \ + } + +/*! @brief Clock ip name array for LPTMR. */ +#define LPTMR_CLOCKS \ + { \ + kCLOCK_Lptmr0 \ + } + +/*! @brief Clock ip name array for ADC16. */ +#define ADC16_CLOCKS \ + { \ + kCLOCK_Adc0 \ + } + +/*! @brief Clock ip name array for FLEXIO. */ +#define FLEXIO_CLOCKS \ + { \ + kCLOCK_Flexio0 \ + } + +/*! @brief Clock ip name array for VREF. */ +#define VREF_CLOCKS \ + { \ + kCLOCK_Vref0 \ + } + +/*! @brief Clock ip name array for DMA. */ +#define DMA_CLOCKS \ + { \ + kCLOCK_Dma0 \ + } + +/*! @brief Clock ip name array for UART. */ +#define UART_CLOCKS \ + { \ + kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_Uart2 \ + } + +/*! @brief Clock ip name array for TPM. */ +#define TPM_CLOCKS \ + { \ + kCLOCK_Tpm0, kCLOCK_Tpm1, kCLOCK_Tpm2 \ + } + +/*! @brief Clock ip name array for I2C. */ +#define I2C_CLOCKS \ + { \ + kCLOCK_I2c0, kCLOCK_I2c1 \ + } + +/*! @brief Clock ip name array for FTF. */ +#define FTF_CLOCKS \ + { \ + kCLOCK_Ftf0 \ + } + +/*! @brief Clock ip name array for CMP. */ +#define CMP_CLOCKS \ + { \ + kCLOCK_Cmp0, kCLOCK_Cmp1, kCLOCK_Cmp2 \ + } + +/*! + * @brief LPO clock frequency. + */ +#define LPO_CLK_FREQ 1000U + +/*! @brief Peripherals clock source definition. */ +#define SYS_CLK kCLOCK_CoreSysClk +#define BUS_CLK kCLOCK_BusClk + +#define I2C0_CLK_SRC SYS_CLK +#define I2C1_CLK_SRC SYS_CLK +#define SPI0_CLK_SRC BUS_CLK +#define SPI1_CLK_SRC SYS_CLK +#define UART2_CLK_SRC BUS_CLK + +/*! @brief Clock name used to get clock frequency. */ +typedef enum _clock_name +{ + + /* ----------------------------- System layer clock -------------------------------*/ + kCLOCK_CoreSysClk, /*!< Core/system clock */ + kCLOCK_PlatClk, /*!< Platform clock */ + kCLOCK_BusClk, /*!< Bus clock */ + kCLOCK_FlexBusClk, /*!< FlexBus clock */ + kCLOCK_FlashClk, /*!< Flash clock */ + kCLOCK_FastPeriphClk, /*!< Fast peripheral clock */ + kCLOCK_PllFllSelClk, /*!< The clock after SIM[PLLFLLSEL]. */ + + /* ---------------------------------- OSC clock -----------------------------------*/ + kCLOCK_Er32kClk, /*!< External reference 32K clock (ERCLK32K) */ + kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */ + kCLOCK_Osc1ErClk, /*!< OSC1 external reference clock (OSC1ERCLK) */ + kCLOCK_Osc0ErClkUndiv, /*!< OSC0 external reference undivided clock(OSC0ERCLK_UNDIV). */ + + /* ----------------------------- MCG and MCG-Lite clock ---------------------------*/ + kCLOCK_McgFixedFreqClk, /*!< MCG fixed frequency clock (MCGFFCLK) */ + kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK) */ + kCLOCK_McgFllClk, /*!< MCGFLLCLK */ + kCLOCK_McgPll0Clk, /*!< MCGPLL0CLK */ + kCLOCK_McgPll1Clk, /*!< MCGPLL1CLK */ + kCLOCK_McgExtPllClk, /*!< EXT_PLLCLK */ + kCLOCK_McgPeriphClk, /*!< MCG peripheral clock (MCGPCLK) */ + kCLOCK_McgIrc48MClk, /*!< MCG IRC48M clock */ + + /* --------------------------------- Other clock ----------------------------------*/ + kCLOCK_LpoClk, /*!< LPO clock */ + +} clock_name_t; + +/*! @brief USB clock source definition. */ +typedef enum _clock_usb_src +{ + kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U), /*!< Use IRC48M. */ + kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ +} clock_usb_src_t; +/*------------------------------------------------------------------------------ + + clock_gate_t definition: + + 31 16 0 + ----------------------------------------------------------------- + | SIM_SCGC register offset | control bit offset in SCGC | + ----------------------------------------------------------------- + + For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the + SIM_SCGC3 offset in SIM is 0x1030, then kCLOCK_GateSdhc0 is defined as + + kCLOCK_GateSdhc0 = (0x1030 << 16) | 17; + +------------------------------------------------------------------------------*/ + +#define CLK_GATE_REG_OFFSET_SHIFT 16U +#define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U +#define CLK_GATE_BIT_SHIFT_SHIFT 0U +#define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU + +#define CLK_GATE_DEFINE(reg_offset, bit_shift) \ + ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \ + (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK)) + +#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT) +#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT) + +/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */ +typedef enum _clock_ip_name +{ + kCLOCK_IpInvalid = 0U, + kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), + kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), + kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U), + kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), + kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), + kCLOCK_Spi0 = CLK_GATE_DEFINE(0x1034U, 22U), + kCLOCK_Spi1 = CLK_GATE_DEFINE(0x1034U, 23U), + + kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), + kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), + kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), + kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), + kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), + kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), + kCLOCK_Slcd0 = CLK_GATE_DEFINE(0x1038U, 19U), + kCLOCK_Lpuart0 = CLK_GATE_DEFINE(0x1038U, 20U), + kCLOCK_Lpuart1 = CLK_GATE_DEFINE(0x1038U, 21U), + kCLOCK_Flexio0 = CLK_GATE_DEFINE(0x1038U, 31U), + + kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), + kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), + kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U), + kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), + kCLOCK_Tpm0 = CLK_GATE_DEFINE(0x103CU, 24U), + kCLOCK_Tpm1 = CLK_GATE_DEFINE(0x103CU, 25U), + kCLOCK_Tpm2 = CLK_GATE_DEFINE(0x103CU, 26U), + kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), + kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), + kCLOCK_Dac0 = CLK_GATE_DEFINE(0x103CU, 31U), + + kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 8U), +} clock_ip_name_t; + +/*!@brief SIM configuration structure for clock setting. */ +typedef struct _sim_clock_config +{ + uint8_t er32kSrc; /*!< ERCLK32K source selection. */ + uint32_t clkdiv1; /*!< SIM_CLKDIV1. */ +} sim_clock_config_t; + +/*! @brief Oscillator capacitor load setting.*/ +enum _osc_cap_load +{ + kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ + kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ + kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ + kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ +}; + +/*! @brief OSCERCLK enable mode. */ +enum _oscer_enable_mode +{ + kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ + kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ +}; + +/*! @brief OSC configuration for OSCERCLK. */ +typedef struct _oscer_config +{ + uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of \ref _oscer_enable_mode. */ + +} oscer_config_t; + +/*! @brief OSC work mode. */ +typedef enum _osc_mode +{ + kOSC_ModeExt = 0U, /*!< Use external clock. */ + kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */ + kOSC_ModeOscHighGain = MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */ +} osc_mode_t; + +/*! + * @brief OSC Initialization Configuration Structure + * + * Defines the configuration data structure to initialize the OSC. + * When porting to a new board, set the following members + * according to board settings: + * 1. freq: The external frequency. + * 2. workMode: The OSC module mode. + */ +typedef struct _osc_config +{ + uint32_t freq; /*!< External clock frequency. */ + uint8_t capLoad; /*!< Capacitor load setting. */ + osc_mode_t workMode; /*!< OSC work mode setting. */ + oscer_config_t oscerConfig; /*!< Configuration for OSCERCLK. */ +} osc_config_t; + +/*! @brief MCG_Lite clock source selection. */ +typedef enum _mcglite_clkout_src +{ + kMCGLITE_ClkSrcHirc, /*!< MCGOUTCLK source is HIRC */ + kMCGLITE_ClkSrcLirc, /*!< MCGOUTCLK source is LIRC */ + kMCGLITE_ClkSrcExt, /*!< MCGOUTCLK source is external clock source */ + kMCGLITE_ClkSrcReserved +} mcglite_clkout_src_t; + +/*! @brief MCG_Lite LIRC select. */ +typedef enum _mcglite_lirc_mode +{ + kMCGLITE_Lirc2M, /*!< Slow internal reference(LIRC) 2MHz clock selected */ + kMCGLITE_Lirc8M, /*!< Slow internal reference(LIRC) 8MHz clock selected */ +} mcglite_lirc_mode_t; + +/*! @brief MCG_Lite divider factor selection for clock source*/ +typedef enum _mcglite_lirc_div +{ + kMCGLITE_LircDivBy1 = 0U, /*!< Divider is 1 */ + kMCGLITE_LircDivBy2, /*!< Divider is 2 */ + kMCGLITE_LircDivBy4, /*!< Divider is 4 */ + kMCGLITE_LircDivBy8, /*!< Divider is 8 */ + kMCGLITE_LircDivBy16, /*!< Divider is 16 */ + kMCGLITE_LircDivBy32, /*!< Divider is 32 */ + kMCGLITE_LircDivBy64, /*!< Divider is 64 */ + kMCGLITE_LircDivBy128 /*!< Divider is 128 */ +} mcglite_lirc_div_t; + +/*! @brief MCG_Lite clock mode definitions */ +typedef enum _mcglite_mode +{ + kMCGLITE_ModeHirc48M, /*!< Clock mode is HIRC 48 M */ + kMCGLITE_ModeLirc8M, /*!< Clock mode is LIRC 8 M */ + kMCGLITE_ModeLirc2M, /*!< Clock mode is LIRC 2 M */ + kMCGLITE_ModeExt, /*!< Clock mode is EXT */ + kMCGLITE_ModeError /*!< Unknown mode */ +} mcglite_mode_t; + +/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ +enum _mcglite_irclk_enable_mode +{ + kMCGLITE_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ + kMCGLITE_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ +}; + +/*! @brief MCG_Lite configure structure for mode change. */ +typedef struct _mcglite_config +{ + mcglite_clkout_src_t outSrc; /*!< MCGOUT clock select. */ + uint8_t irclkEnableMode; /*!< MCGIRCLK enable mode, OR'ed value of _mcglite_irclk_enable_mode. */ + mcglite_lirc_mode_t ircs; /*!< MCG_C2[IRCS]. */ + mcglite_lirc_div_t fcrdiv; /*!< MCG_SC[FCRDIV]. */ + mcglite_lirc_div_t lircDiv2; /*!< MCG_MC[LIRC_DIV2]. */ + bool hircEnableInNotHircMode; /*!< HIRC enable when not in HIRC mode. */ +} mcglite_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @brief Set the XTAL0 frequency based on board setting. + * + * @param freq The XTAL0/EXTAL0 input clock frequency in Hz. + */ +static inline void CLOCK_SetXtal0Freq(uint32_t freq) +{ + g_xtal0Freq = freq; +} + +/*! + * @brief Set the XTAL32/RTC_CLKIN frequency based on board setting. + * + * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz. + */ +static inline void CLOCK_SetXtal32Freq(uint32_t freq) +{ + g_xtal32Freq = freq; +} + +/*! + * @brief Enable the clock for specific IP. + * + * @param name Which clock to enable, see \ref clock_ip_name_t. + */ +static inline void CLOCK_EnableClock(clock_ip_name_t name) +{ + uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name); + (*(volatile uint32_t *)regAddr) |= (1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name)); +} + +/*! + * @brief Disable the clock for specific IP. + * + * @param name Which clock to disable, see \ref clock_ip_name_t. + */ +static inline void CLOCK_DisableClock(clock_ip_name_t name) +{ + uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name); + (*(volatile uint32_t *)regAddr) &= ~(1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name)); +} + +/*! + * @brief Set ERCLK32K source. + * + * @param src The value to set ERCLK32K clock source. + */ +static inline void CLOCK_SetEr32kClock(uint32_t src) +{ + SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(src)); +} + +/*! + * @brief Set LPUART0 clock source. + * + * @param src The value to set LPUART0 clock source. + */ +static inline void CLOCK_SetLpuart0Clock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_LPUART0SRC_MASK) | SIM_SOPT2_LPUART0SRC(src)); +} + +/*! + * @brief Set LPUART1 clock source. + * + * @param src The value to set LPUART1 clock source. + */ +static inline void CLOCK_SetLpuart1Clock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_LPUART1SRC_MASK) | SIM_SOPT2_LPUART1SRC(src)); +} + +/*! + * @brief Set TPM clock source. + * + * @param src The value to set TPM clock source. + */ +static inline void CLOCK_SetTpmClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(src)); +} + +/*! + * @brief Set FLEXIO clock source. + * + * @param src The value to set FLEXIO clock source. + */ +static inline void CLOCK_SetFlexio0Clock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_FLEXIOSRC_MASK) | SIM_SOPT2_FLEXIOSRC(src)); +} + +/*! @brief Enable USB FS clock. + * + * @param src USB FS clock source. + * @param freq The frequency specified by src. + * @retval true The clock is set successfully. + * @retval false The clock source is invalid to get proper USB FS clock. + */ +bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq); + +/*! @brief Disable USB FS clock. + * + * Disable USB FS clock. + */ +static inline void CLOCK_DisableUsbfs0Clock(void) +{ + CLOCK_DisableClock(kCLOCK_Usbfs0); +} + +/*! + * @brief Set CLKOUT source. + * + * @param src The value to set CLKOUT source. + */ +static inline void CLOCK_SetClkOutClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(src)); +} + +/*! + * @brief Set RTC_CLKOUT source. + * + * @param src The value to set RTC_CLKOUT source. + */ +static inline void CLOCK_SetRtcClkOutClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_RTCCLKOUTSEL_MASK) | SIM_SOPT2_RTCCLKOUTSEL(src)); +} + +/*! + * @brief System clock divider + * + * Set the SIM_CLKDIV1[OUTDIV1], SIM_CLKDIV1[OUTDIV4]. + * + * @param outdiv1 Clock 1 output divider value. + * + * @param outdiv4 Clock 4 output divider value. + */ +static inline void CLOCK_SetOutDiv(uint32_t outdiv1, uint32_t outdiv4) +{ + SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV4(outdiv4); +} + +/*! + * @brief Gets the clock frequency for a specific clock name. + * + * This function checks the current clock configurations and then calculates + * the clock frequency for a specific clock name defined in clock_name_t. + * The MCG must be properly configured before using this function. + * + * @param clockName Clock names defined in clock_name_t + * @return Clock frequency value in Hertz + */ +uint32_t CLOCK_GetFreq(clock_name_t clockName); + +/*! + * @brief Get the core clock or system clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetCoreSysClkFreq(void); + +/*! + * @brief Get the platform clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetPlatClkFreq(void); + +/*! + * @brief Get the bus clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetBusClkFreq(void); + +/*! + * @brief Get the flash clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetFlashClkFreq(void); + +/*! + * @brief Get the external reference 32K clock frequency (ERCLK32K). + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetEr32kClkFreq(void); + +/*! + * @brief Get the OSC0 external reference clock frequency (OSC0ERCLK). + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetOsc0ErClkFreq(void); + +/*! + * @brief Set the clock configure in SIM module. + * + * This function sets system layer clock settings in SIM module. + * + * @param config Pointer to the configure structure. + */ +void CLOCK_SetSimConfig(sim_clock_config_t const *config); + +/*! + * @brief Set the system clock dividers in SIM to safe value. + * + * The system level clocks (core clock, bus clock, flexbus clock and flash clock) + * must be in allowed ranges. During MCG clock mode switch, the MCG output clock + * changes then the system level clocks may be out of range. This function could + * be used before MCG mode change, to make sure system level clocks are in allowed + * range. + * + * @param config Pointer to the configure structure. + */ +static inline void CLOCK_SetSimSafeDivs(void) +{ + SIM->CLKDIV1 = 0x10030000U; +} + +/*! + * @name MCG_Lite clock frequency + * @{ + */ + +/*! + * @brief Gets the MCG_Lite output clock (MCGOUTCLK) frequency. + * + * This function gets the MCG_Lite output clock frequency (Hz) based on the current + * MCG_Lite register value. + * + * @return The frequency of MCGOUTCLK. + */ +uint32_t CLOCK_GetOutClkFreq(void); + +/*! + * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency. + * + * This function gets the MCG_Lite internal reference clock frequency (Hz) based + * on the current MCG register value. + * + * @return The frequency of MCGIRCLK. + */ +uint32_t CLOCK_GetInternalRefClkFreq(void); + +/*! +* @brief Gets the current MCGPCLK frequency. +* +* This function gets the MCGPCLK frequency (Hertz) based on the current MCG_Lite +* register settings. +* +* @return The frequency of MCGPCLK. +*/ +uint32_t CLOCK_GetPeriphClkFreq(void); + +/*! @}*/ + +/*! + * @name MCG_Lite mode. + * @{ + */ + +/*! + * @brief Gets the current MCG_Lite mode. + * + * This function checks the MCG_Lite registers and determines the current MCG_Lite mode. + * + * @return Current MCG_Lite mode or error code. + */ +mcglite_mode_t CLOCK_GetMode(void); + +/*! + * @brief Sets the MCG_Lite configuration. + * + * This function configures the MCG_Lite, include output clock source, MCGIRCLK + * setting, HIRC setting and so on, see @ref mcglite_config_t for details. + * + * @param targetConfig Pointer to the target MCG_Lite mode configuration structure. + * @return Error code. + */ +status_t CLOCK_SetMcgliteConfig(mcglite_config_t const *targetConfig); + +/*! @}*/ + +/*! + * @name OSC configuration + * @{ + */ + +/*! + * @brief Configures the OSC external reference clock (OSCERCLK). + * + * This function configures the OSC external reference clock (OSCERCLK). + * For example, to enable the OSCERCLK in normal mode and stop mode, and also set + * the output divider to 1, as follows: + * + @code + oscer_config_t config = + { + .enableMode = kOSC_ErClkEnable | kOSC_ErClkEnableInStop, + .erclkDiv = 1U, + }; + + OSC_SetExtRefClkConfig(OSC, &config); + @endcode + * + * @param base OSC peripheral address. + * @param config Pointer to the configuration structure. + */ +static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *config) +{ + uint8_t reg = base->CR; + + reg &= ~(OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK); + reg |= config->enableMode; + + base->CR = reg; +} + +/*! + * @brief Sets the capacitor load configuration for the oscillator. + * + * This function sets the specified capacitors configuration for the oscillator. + * This should be done in the early system level initialization function call + * based on the system configuration. + * + * @param base OSC peripheral address. + * @param capLoad OR'ed value for the capacitor load option, see \ref _osc_cap_load. + * + * Example: + @code + // To enable only 2 pF and 8 pF capacitor load, please use like this. + OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P); + @endcode + */ + +static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad) +{ + uint8_t reg = base->CR; + + reg &= ~(OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK); + reg |= capLoad; + + base->CR = reg; +} + +/*! + * @brief Initialize OSC0. + * + * This function initializes the OSC0 according to the board configuration. + * + * @param config Pointer to the OSC0 configuration structure. + */ +void CLOCK_InitOsc0(osc_config_t const *config); + +/*! + * @brief Deinitializes the OSC0. + * + * This function deinitializes the OSC0. + */ +void CLOCK_DeinitOsc0(void); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_CLOCK_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cmp.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cmp.c new file mode 100644 index 0000000000..09885e7421 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cmp.c @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_cmp.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for CMP module. + * + * @param base CMP peripheral base address + */ +static uint32_t CMP_GetInstance(CMP_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to CMP bases for each instance. */ +static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS; +/*! @brief Pointers to CMP clocks for each instance. */ +const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS; + +/******************************************************************************* + * Codes + ******************************************************************************/ +static uint32_t CMP_GetInstance(CMP_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_CMP_COUNT; instance++) + { + if (s_cmpBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_CMP_COUNT); + + return instance; +} + +void CMP_Init(CMP_Type *base, const cmp_config_t *config) +{ + assert(NULL != config); + + uint8_t tmp8; + + /* Enable the clock. */ + CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]); + + /* Configure. */ + CMP_Enable(base, false); /* Disable the CMP module during configuring. */ + /* CMPx_CR1. */ + tmp8 = base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK); + if (config->enableHighSpeed) + { + tmp8 |= CMP_CR1_PMODE_MASK; + } + if (config->enableInvertOutput) + { + tmp8 |= CMP_CR1_INV_MASK; + } + if (config->useUnfilteredOutput) + { + tmp8 |= CMP_CR1_COS_MASK; + } + if (config->enablePinOut) + { + tmp8 |= CMP_CR1_OPE_MASK; + } +#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE + if (config->enableTriggerMode) + { + tmp8 |= CMP_CR1_TRIGM_MASK; + } + else + { + tmp8 &= ~CMP_CR1_TRIGM_MASK; + } +#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ + base->CR1 = tmp8; + + /* CMPx_CR0. */ + tmp8 = base->CR0 & ~CMP_CR0_HYSTCTR_MASK; + tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode); + base->CR0 = tmp8; + + CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */ +} + +void CMP_Deinit(CMP_Type *base) +{ + /* Disable the CMP module. */ + CMP_Enable(base, false); + + /* Disable the clock. */ + CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]); +} + +void CMP_GetDefaultConfig(cmp_config_t *config) +{ + assert(NULL != config); + + config->enableCmp = true; /* Enable the CMP module after initialization. */ + config->hysteresisMode = kCMP_HysteresisLevel0; + config->enableHighSpeed = false; + config->enableInvertOutput = false; + config->useUnfilteredOutput = false; + config->enablePinOut = false; +#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE + config->enableTriggerMode = false; +#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ +} + +void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel) +{ + uint8_t tmp8 = base->MUXCR; + + tmp8 &= ~(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK); + tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel); + base->MUXCR = tmp8; +} + +#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA +void CMP_EnableDMA(CMP_Type *base, bool enable) +{ + uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */ + + if (enable) + { + tmp8 |= CMP_SCR_DMAEN_MASK; + } + else + { + tmp8 &= ~CMP_SCR_DMAEN_MASK; + } + base->SCR = tmp8; +} +#endif /* FSL_FEATURE_CMP_HAS_DMA */ + +void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config) +{ + assert(NULL != config); + + uint8_t tmp8; + +#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT + /* Choose the clock source for sampling. */ + if (config->enableSample) + { + base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */ + } + else + { + base->CR1 &= ~CMP_CR1_SE_MASK; /* Choose the internal divided bus clock. */ + } +#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ + /* Set the filter count. */ + tmp8 = base->CR0 & ~CMP_CR0_FILTER_CNT_MASK; + tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount); + base->CR0 = tmp8; + /* Set the filter period. It is used as the divider to bus clock. */ + base->FPR = CMP_FPR_FILT_PER(config->filterPeriod); +} + +void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config) +{ + uint8_t tmp8 = 0U; + + if (NULL == config) + { + /* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/ + base->DACCR = 0U; + return; + } + /* CMPx_DACCR. */ + tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */ + if (kCMP_VrefSourceVin2 == config->referenceVoltageSource) + { + tmp8 |= CMP_DACCR_VRSEL_MASK; + } + tmp8 |= CMP_DACCR_VOSEL(config->DACValue); + + base->DACCR = tmp8; +} + +void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask) +{ + uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */ + + if (0U != (kCMP_OutputRisingInterruptEnable & mask)) + { + tmp8 |= CMP_SCR_IER_MASK; + } + if (0U != (kCMP_OutputFallingInterruptEnable & mask)) + { + tmp8 |= CMP_SCR_IEF_MASK; + } + base->SCR = tmp8; +} + +void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask) +{ + uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */ + + if (0U != (kCMP_OutputRisingInterruptEnable & mask)) + { + tmp8 &= ~CMP_SCR_IER_MASK; + } + if (0U != (kCMP_OutputFallingInterruptEnable & mask)) + { + tmp8 &= ~CMP_SCR_IEF_MASK; + } + base->SCR = tmp8; +} + +uint32_t CMP_GetStatusFlags(CMP_Type *base) +{ + uint32_t ret32 = 0U; + + if (0U != (CMP_SCR_CFR_MASK & base->SCR)) + { + ret32 |= kCMP_OutputRisingEventFlag; + } + if (0U != (CMP_SCR_CFF_MASK & base->SCR)) + { + ret32 |= kCMP_OutputFallingEventFlag; + } + if (0U != (CMP_SCR_COUT_MASK & base->SCR)) + { + ret32 |= kCMP_OutputAssertEventFlag; + } + return ret32; +} + +void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask) +{ + uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */ + + if (0U != (kCMP_OutputRisingEventFlag & mask)) + { + tmp8 |= CMP_SCR_CFR_MASK; + } + if (0U != (kCMP_OutputFallingEventFlag & mask)) + { + tmp8 |= CMP_SCR_CFF_MASK; + } + base->SCR = tmp8; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cmp.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cmp.h new file mode 100644 index 0000000000..53d84a0f2d --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cmp.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_CMP_H_ +#define _FSL_CMP_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup cmp + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief CMP driver version 2.0.0. */ +#define FSL_CMP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! +* @brief Interrupt enable/disable mask. +*/ +enum _cmp_interrupt_enable +{ + kCMP_OutputRisingInterruptEnable = CMP_SCR_IER_MASK, /*!< Comparator interrupt enable rising. */ + kCMP_OutputFallingInterruptEnable = CMP_SCR_IEF_MASK, /*!< Comparator interrupt enable falling. */ +}; + +/*! + * @brief Status flags' mask. + */ +enum _cmp_status_flags +{ + kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on compare output has occurred. */ + kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on compare output has occurred. */ + kCMP_OutputAssertEventFlag = CMP_SCR_COUT_MASK, /*!< Return the current value of the analog comparator output. */ +}; + +/*! + * @brief CMP Hysteresis mode. + */ +typedef enum _cmp_hysteresis_mode +{ + kCMP_HysteresisLevel0 = 0U, /*!< Hysteresis level 0. */ + kCMP_HysteresisLevel1 = 1U, /*!< Hysteresis level 1. */ + kCMP_HysteresisLevel2 = 2U, /*!< Hysteresis level 2. */ + kCMP_HysteresisLevel3 = 3U, /*!< Hysteresis level 3. */ +} cmp_hysteresis_mode_t; + +/*! + * @brief CMP Voltage Reference source. + */ +typedef enum _cmp_reference_voltage_source +{ + kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as resistor ladder network supply reference Vin. */ + kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as resistor ladder network supply reference Vin. */ +} cmp_reference_voltage_source_t; + +/*! + * @brief Configure the comparator. + */ +typedef struct _cmp_config +{ + bool enableCmp; /*!< Enable the CMP module. */ + cmp_hysteresis_mode_t hysteresisMode; /*!< CMP Hysteresis mode. */ + bool enableHighSpeed; /*!< Enable High Speed (HS) comparison mode. */ + bool enableInvertOutput; /*!< Enable inverted comparator output. */ + bool useUnfilteredOutput; /*!< Set compare output(COUT) to equal COUTA(true) or COUT(false). */ + bool enablePinOut; /*!< The comparator output is available on the associated pin. */ +#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE + bool enableTriggerMode; /*!< Enable the trigger mode. */ +#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ +} cmp_config_t; + +/*! + * @brief Configure the filter. + */ +typedef struct _cmp_filter_config +{ +#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT + bool enableSample; /*!< Using external SAMPLE as sampling clock input, or using divided bus clock. */ +#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ + uint8_t filterCount; /*!< Filter Sample Count. Available range is 1-7, 0 would cause the filter disabled.*/ + uint8_t filterPeriod; /*!< Filter Sample Period. The divider to bus clock. Available range is 0-255. */ +} cmp_filter_config_t; + +/*! + * @brief Configure the internal DAC. + */ +typedef struct _cmp_dac_config +{ + cmp_reference_voltage_source_t referenceVoltageSource; /*!< Supply voltage reference source. */ + uint8_t DACValue; /*!< Value for DAC Output Voltage. Available range is 0-63.*/ +} cmp_dac_config_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes the CMP. + * + * This function initializes the CMP module. The operations included are: + * - Enabling the clock for CMP module. + * - Configuring the comparator. + * - Enabling the CMP module. + * Note: For some devices, multiple CMP instance share the same clock gate. In this case, to enable the clock for + * any instance enables all the CMPs. Check the chip reference manual for the clock assignment of the CMP. + * + * @param base CMP peripheral base address. + * @param config Pointer to configuration structure. + */ +void CMP_Init(CMP_Type *base, const cmp_config_t *config); + +/*! + * @brief De-initializes the CMP module. + * + * This function de-initializes the CMP module. The operations included are: + * - Disabling the CMP module. + * - Disabling the clock for CMP module. + * + * This function disables the clock for the CMP. + * Note: For some devices, multiple CMP instance shares the same clock gate. In this case, before disabling the + * clock for the CMP, ensure that all the CMP instances are not used. + * + * @param base CMP peripheral base address. + */ +void CMP_Deinit(CMP_Type *base); + +/*! + * @brief Enables/disables the CMP module. + * + * @param base CMP peripheral base address. + * @param enable Enable the module or not. + */ +static inline void CMP_Enable(CMP_Type *base, bool enable) +{ + if (enable) + { + base->CR1 |= CMP_CR1_EN_MASK; + } + else + { + base->CR1 &= ~CMP_CR1_EN_MASK; + } +} + +/*! +* @brief Initializes the CMP user configuration structure. +* +* This function initializes the user configure structure to these default values: +* @code +* config->enableCmp = true; +* config->hysteresisMode = kCMP_HysteresisLevel0; +* config->enableHighSpeed = false; +* config->enableInvertOutput = false; +* config->useUnfilteredOutput = false; +* config->enablePinOut = false; +* config->enableTriggerMode = false; +* @endcode +* @param config Pointer to the configuration structure. +*/ +void CMP_GetDefaultConfig(cmp_config_t *config); + +/*! + * @brief Sets the input channels for the comparator. + * + * This function sets the input channels for the comparator. + * Note that two input channels cannot be set as same in the application. When the user selects the same input + * from the analog mux to the positive and negative port, the comparator is disabled automatically. + * + * @param base CMP peripheral base address. + * @param positiveChannel Positive side input channel number. Available range is 0-7. + * @param negativeChannel Negative side input channel number. Available range is 0-7. + */ +void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel); + +/* @} */ + +/*! + * @name Advanced Features + * @{ + */ + +#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA +/*! + * @brief Enables/disables the DMA request for rising/falling events. + * + * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of + * the DMA + * request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from the CMP + * if the + * DMA is disabled. + * + * @param base CMP peripheral base address. + * @param enable Enable the feature or not. + */ +void CMP_EnableDMA(CMP_Type *base, bool enable); +#endif /* FSL_FEATURE_CMP_HAS_DMA */ + +#if defined(FSL_FEATURE_CMP_HAS_WINDOW_MODE) && FSL_FEATURE_CMP_HAS_WINDOW_MODE +/*! + * @brief Enables/disables the window mode. + * + * @param base CMP peripheral base address. + * @param enable Enable the feature or not. + */ +static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable) +{ + if (enable) + { + base->CR1 |= CMP_CR1_WE_MASK; + } + else + { + base->CR1 &= ~CMP_CR1_WE_MASK; + } +} +#endif /* FSL_FEATURE_CMP_HAS_WINDOW_MODE */ + +#if defined(FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE) && FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE +/*! + * @brief Enables/disables the pass through mode. + * + * @param base CMP peripheral base address. + * @param enable Enable the feature or not. + */ +static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable) +{ + if (enable) + { + base->MUXCR |= CMP_MUXCR_PSTM_MASK; + } + else + { + base->MUXCR &= ~CMP_MUXCR_PSTM_MASK; + } +} +#endif /* FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE */ + +/*! + * @brief Configures the filter. + * + * @param base CMP peripheral base address. + * @param config Pointer to configuration structure. + */ +void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config); + +/*! + * @brief Configures the internal DAC. + * + * @param base CMP peripheral base address. + * @param config Pointer to configuration structure. "NULL" is for disabling the feature. + */ +void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config); + +/*! + * @brief Enables the interrupts. + * + * @param base CMP peripheral base address. + * @param mask Mask value for interrupts. See "_cmp_interrupt_enable". + */ +void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask); + +/*! + * @brief Disables the interrupts. + * + * @param base CMP peripheral base address. + * @param mask Mask value for interrupts. See "_cmp_interrupt_enable". + */ +void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Results + * @{ + */ + +/*! + * @brief Gets the status flags. + * + * @param base CMP peripheral base address. + * + * @return Mask value for the asserted flags. See "_cmp_status_flags". + */ +uint32_t CMP_GetStatusFlags(CMP_Type *base); + +/*! + * @brief Clears the status flags. + * + * @param base CMP peripheral base address. + * @param mask Mask value for the flags. See "_cmp_status_flags". + */ +void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask); + +/* @} */ +#if defined(__cplusplus) +} +#endif +/*! + * @} + */ +#endif /* _FSL_CMP_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_common.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_common.c new file mode 100644 index 0000000000..9e21f7594d --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_common.c @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_common.h" +/* This is not needed for mbed */ +#if 0 +#include "fsl_debug_console.h" + +#ifndef NDEBUG +#if (defined(__CC_ARM)) || (defined(__ICCARM__)) +void __aeabi_assert(const char *failedExpr, const char *file, int line) +{ + PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line); + for (;;) + { + __asm("bkpt #0"); + } +} +#elif(defined(__GNUC__)) +void __assert_func(const char *file, int line, const char *func, const char *failedExpr) +{ + PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, func); + for (;;) + { + __asm("bkpt #0"); + } +} +#endif /* (defined(__CC_ARM)) || (defined (__ICCARM__)) */ +#endif /* NDEBUG */ +#endif +void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler) +{ +/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ +#if defined(__CC_ARM) + extern uint32_t Image$$VECTOR_ROM$$Base[]; + extern uint32_t Image$$VECTOR_RAM$$Base[]; + extern uint32_t Image$$RW_m_data$$Base[]; + +#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base)) +#elif defined(__ICCARM__) + extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; +#elif defined(__GNUC__) + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; + extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[]; + uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES); +#endif /* defined(__CC_ARM) */ + uint32_t n; + uint32_t interrupts_disabled; + + interrupts_disabled = __get_PRIMASK(); + __disable_irq(); + if (SCB->VTOR != (uint32_t)__VECTOR_RAM) + { + /* Copy the vector table from ROM to RAM */ + for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++) + { + __VECTOR_RAM[n] = __VECTOR_TABLE[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + + /* make sure the __VECTOR_RAM is noncachable */ + __VECTOR_RAM[irq + 16] = irqHandler; + + if (!interrupts_disabled) { + __enable_irq(); + } +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_common.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_common.h new file mode 100644 index 0000000000..105dca049a --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_common.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_COMMON_H_ +#define _FSL_COMMON_H_ + +#include +#include +#include +#include +#include "fsl_device_registers.h" + +/*! + * @addtogroup ksdk_common + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Construct a status code value from a group and code number. */ +#define MAKE_STATUS(group, code) ((((group)*100) + (code))) + +/*! @brief Construct the version number for drivers. */ +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +/* Debug console type definition. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */ + +/*! @brief Status group numbers. */ +enum _status_groups +{ + kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */ + kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */ + kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */ + kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */ + kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */ + kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */ + kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */ + kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */ + kStatusGroup_UART = 10, /*!< Group number for UART status codes. */ + kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */ + kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */ + kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */ + kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/ + kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/ + kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/ + kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */ + kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */ + kStatusGroup_SAI = 19, /*!< Group number for SAI status code */ + kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */ + kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */ + kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */ + kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */ + kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */ + kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */ + kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */ + kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */ + kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */ + kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */ + kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */ + kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */ + kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */ + kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */ + kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */ + kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */ + kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */ + kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */ + kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ + kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ + kStatusGroup_ApplicationRangeStart = 100, /*!< Starting number for application groups. */ +}; + +/*! @brief Generic status return codes. */ +enum _generic_status +{ + kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), + kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), + kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), + kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), + kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), + kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), + kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), +}; + +/*! @brief Type used for all status and error return values. */ +typedef int32_t status_t; + +/* + * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t + * defined in previous of this file. + */ +#include "fsl_clock.h" + +/*! @name Min/max macros */ +/* @{ */ +#if !defined(MIN) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#if !defined(MAX) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +/* @} */ + +/*! @brief Computes the number of elements in an array. */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/*! @name UINT16_MAX/UINT32_MAX value */ +/* @{ */ +#if !defined(UINT16_MAX) +#define UINT16_MAX ((uint16_t)-1) +#endif + +#if !defined(UINT32_MAX) +#define UINT32_MAX ((uint32_t)-1) +#endif +/* @} */ + +/*! @name Timer utilities */ +/* @{ */ +/*! Macro to convert a microsecond period to raw count value */ +#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)((uint64_t)us * clockFreqInHz / 1000000U) +/*! Macro to convert a raw count value to microsecond */ +#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz) + +/*! Macro to convert a millisecond period to raw count value */ +#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U) +/*! Macro to convert a raw count value to millisecond */ +#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz) +/* @} */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Enable specific interrupt. + * + * Enable the interrupt not routed from intmux. + * + * @param interrupt The IRQ number. + */ +static inline void EnableIRQ(IRQn_Type interrupt) +{ +#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0) + if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX) +#endif + { + NVIC_EnableIRQ(interrupt); + } +} + +/*! + * @brief Disable specific interrupt. + * + * Disable the interrupt not routed from intmux. + * + * @param interrupt The IRQ number. + */ +static inline void DisableIRQ(IRQn_Type interrupt) +{ +#if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0) + if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX) +#endif + { + NVIC_DisableIRQ(interrupt); + } +} + +/*! + * @brief Disable the global IRQ + * + * Disable the global interrupt and return the current primask register. User is required to provided the primask + * register for the EnableGlobalIRQ(). + * + * @return Current primask value. + */ +static inline uint32_t DisableGlobalIRQ(void) +{ + uint32_t regPrimask = __get_PRIMASK(); + + __disable_irq(); + + return regPrimask; +} + +/*! + * @brief Enaable the global IRQ + * + * Set the primask register with the provided primask value but not just enable the primask. The idea is for the + * convinience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to + * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair. + * + * @param primask value of primask register to be restored. The primask value is supposed to be provided by the + * DisableGlobalIRQ(). + */ +static inline void EnableGlobalIRQ(uint32_t primask) +{ + __set_PRIMASK(primask); +} + +/*! + * @brief install IRQ handler + * + * @param irq IRQ number + * @param irqHandler IRQ handler address + */ +void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_COMMON_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cop.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cop.c new file mode 100644 index 0000000000..16add3b261 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cop.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_cop.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +void COP_GetDefaultConfig(cop_config_t *config) +{ + assert(config); + + config->enableWindowMode = false; +#if defined(FSL_FEATURE_COP_HAS_LONGTIME_MODE) && FSL_FEATURE_COP_HAS_LONGTIME_MODE + config->timeoutMode = kCOP_LongTimeoutMode; + config->enableStop = false; + config->enableDebug = false; +#endif /* FSL_FEATURE_COP_HAS_LONGTIME_MODE */ + config->clockSource = kCOP_LpoClock; + config->timeoutCycles = kCOP_2Power10CyclesOr2Power18Cycles; +} + +void COP_Init(SIM_Type *base, const cop_config_t *config) +{ + assert(config); + + uint32_t value = 0U; + +#if defined(FSL_FEATURE_COP_HAS_LONGTIME_MODE) && FSL_FEATURE_COP_HAS_LONGTIME_MODE + value = SIM_COPC_COPW(config->enableWindowMode) | SIM_COPC_COPCLKS(config->timeoutMode) | + SIM_COPC_COPT(config->timeoutCycles) | SIM_COPC_COPSTPEN(config->enableStop) | + SIM_COPC_COPDBGEN(config->enableDebug) | SIM_COPC_COPCLKSEL(config->clockSource); +#else + value = SIM_COPC_COPW(config->enableWindowMode) | SIM_COPC_COPCLKS(config->clockSource) | + SIM_COPC_COPT(config->timeoutCycles); +#endif /* FSL_FEATURE_COP_HAS_LONGTIME_MODE */ + base->COPC = value; +} + +void COP_Refresh(SIM_Type *base) +{ + uint32_t primaskValue = 0U; + + /* Disable the global interrupt to protect refresh sequence */ + primaskValue = DisableGlobalIRQ(); + base->SRVCOP = COP_FIRST_BYTE_OF_REFRESH; + base->SRVCOP = COP_SECOND_BYTE_OF_REFRESH; + EnableGlobalIRQ(primaskValue); +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cop.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cop.h new file mode 100644 index 0000000000..1a7ab82fab --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_cop.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_COP_H_ +#define _FSL_COP_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup cop_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief COP driver version 2.0.0. */ +#define FSL_COP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @name COP refresh sequence. */ +/*@{*/ +#define COP_FIRST_BYTE_OF_REFRESH (0x55U) /*!< First byte of refresh sequence */ +#define COP_SECOND_BYTE_OF_REFRESH (0xAAU) /*!< Second byte of refresh sequence */ +/*@}*/ + +/*! @brief COP clock source selection. */ +typedef enum _cop_clock_source +{ + kCOP_LpoClock = 0U, /*!< COP clock sourced from LPO */ +#if defined(FSL_FEATURE_COP_HAS_MORE_CLKSRC) && FSL_FEATURE_COP_HAS_MORE_CLKSRC + kCOP_McgIrClock = 1U, /*!< COP clock sourced from MCGIRCLK */ + kCOP_OscErClock = 2U, /*!< COP clock sourced from OSCERCLK */ +#endif /* FSL_FEATURE_COP_HAS_MORE_CLKSRC */ + kCOP_BusClock = 3U, /*!< COP clock sourced from Bus clock */ +} cop_clock_source_t; + +/*! @brief Define the COP timeout cycles. */ +typedef enum _cop_timeout_cycles +{ + kCOP_2Power5CyclesOr2Power13Cycles = 1U, /*!< 2^5 or 2^13 clock cycles */ + kCOP_2Power8CyclesOr2Power16Cycles = 2U, /*!< 2^8 or 2^16 clock cycles */ + kCOP_2Power10CyclesOr2Power18Cycles = 3U, /*!< 2^10 or 2^18 clock cycles */ +} cop_timeout_cycles_t; + +#if defined(FSL_FEATURE_COP_HAS_LONGTIME_MODE) && FSL_FEATURE_COP_HAS_LONGTIME_MODE +/*! @breif Define the COP timeout mode. */ +typedef enum _cop_timeout_mode +{ + kCOP_ShortTimeoutMode = 0U, /*!< COP selects long timeout */ + kCOP_LongTimeoutMode = 1U, /*!< COP selects short timeout */ +} cop_timeout_mode_t; +#endif /* FSL_FEATURE_COP_HAS_LONGTIME_MODE */ + +/*! @brief Describes COP configuration structure. */ +typedef struct _cop_config +{ + bool enableWindowMode; /*!< COP run mode: window mode or normal mode */ +#if defined(FSL_FEATURE_COP_HAS_LONGTIME_MODE) && FSL_FEATURE_COP_HAS_LONGTIME_MODE + cop_timeout_mode_t timeoutMode; /*!< COP timeout mode: long timeout or short timeout */ + bool enableStop; /*!< Enable or disable COP in STOP mode */ + bool enableDebug; /*!< Enable or disable COP in DEBUG mode */ +#endif /* FSL_FEATURE_COP_HAS_LONGTIME_MODE */ + cop_clock_source_t clockSource; /*!< Set COP clock source */ + cop_timeout_cycles_t timeoutCycles; /*!< Set COP timeout value */ +} cop_config_t; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @name COP Functional Operation + * @{ + */ + +/*! + * @brief Initializes the COP configuration structure. + * + * This function initializes the COP configuration structure to default values. The default + * values are: + * @code + * copConfig->enableWindowMode = false; + * copConfig->timeoutMode = kCOP_LongTimeoutMode; + * copConfig->enableStop = false; + * copConfig->enableDebug = false; + * copConfig->clockSource = kCOP_LpoClock; + * copConfig->timeoutCycles = kCOP_2Power10CyclesOr2Power18Cycles; + * @endcode + * + * @param config Pointer to the COP configuration structure. + * @see cop_config_t + */ +void COP_GetDefaultConfig(cop_config_t *config); + +/*! + * @brief Initializes the COP module. + * + * This function configures the COP. After it is called, the COP + * starts running according to the configuration. + * Because all COP control registers are write-once only, the COP_Init function + * and the COP_Disable function can be called only once. A second call has no effect. + * + * Example: + * @code + * cop_config_t config; + * COP_GetDefaultConfig(&config); + * config.timeoutCycles = kCOP_2Power8CyclesOr2Power16Cycles; + * COP_Init(sim_base,&config); + * @endcode + * + * @param base SIM peripheral base address. + * @param config The configuration of COP. + */ +void COP_Init(SIM_Type *base, const cop_config_t *config); + +/*! + * @brief De-initializes the COP module. + * This dedicated function is not provided. Instead, the COP_Disable function can be used to disable the COP. + */ + +/*! + * @brief Disables the COP module. + * + * This function disables the COP Watchdog. + * Note: The COP configuration register is a write-once after reset. + * To disable the COP Watchdog, call this function first. + * + * @param base SIM peripheral base address. + */ +static inline void COP_Disable(SIM_Type *base) +{ + base->COPC &= ~SIM_COPC_COPT_MASK; +} + +/*! + * @brief Refreshes the COP timer + * + * This function feeds the COP. + * + * @param base SIM peripheral base address. + */ +void COP_Refresh(SIM_Type *base); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_COP_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dac.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dac.c new file mode 100644 index 0000000000..2f83f5ee9e --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dac.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_dac.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get instance number for DAC module. + * + * @param base DAC peripheral base address + */ +static uint32_t DAC_GetInstance(DAC_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to DAC bases for each instance. */ +static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS; +/*! @brief Pointers to DAC clocks for each instance. */ +const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS; + +/******************************************************************************* + * Codes + ******************************************************************************/ +static uint32_t DAC_GetInstance(DAC_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_DAC_COUNT; instance++) + { + if (s_dacBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_DAC_COUNT); + + return instance; +} + +void DAC_Init(DAC_Type *base, const dac_config_t *config) +{ + assert(NULL != config); + + uint8_t tmp8; + + /* Enable the clock. */ + CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]); + + /* Configure. */ + /* DACx_C0. */ + tmp8 = base->C0 & ~(DAC_C0_DACRFS_MASK | DAC_C0_LPEN_MASK); + if (kDAC_ReferenceVoltageSourceVref2 == config->referenceVoltageSource) + { + tmp8 |= DAC_C0_DACRFS_MASK; + } + if (config->enableLowPowerMode) + { + tmp8 |= DAC_C0_LPEN_MASK; + } + base->C0 = tmp8; + + DAC_Enable(base, true); +} + +void DAC_Deinit(DAC_Type *base) +{ + DAC_Enable(base, false); + + /* Disable the clock. */ + CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]); +} + +void DAC_GetDefaultConfig(dac_config_t *config) +{ + assert(NULL != config); + + config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; + config->enableLowPowerMode = false; +} + +void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config) +{ + assert(NULL != config); + + uint8_t tmp8; + + /* DACx_C0. */ + tmp8 = base->C0 & ~(DAC_C0_DACTRGSEL_MASK); + if (kDAC_BufferTriggerBySoftwareMode == config->triggerMode) + { + tmp8 |= DAC_C0_DACTRGSEL_MASK; + } + base->C0 = tmp8; + + /* DACx_C1. */ + tmp8 = base->C1 & + ~( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + DAC_C1_DACBFWM_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + DAC_C1_DACBFMD_MASK); +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + tmp8 |= DAC_C1_DACBFWM(config->watermark); +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + tmp8 |= DAC_C1_DACBFMD(config->workMode); + base->C1 = tmp8; + + /* DACx_C2. */ + tmp8 = base->C2 & ~DAC_C2_DACBFUP_MASK; + tmp8 |= DAC_C2_DACBFUP(config->upperLimit); + base->C2 = tmp8; +} + +void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config) +{ + assert(NULL != config); + + config->triggerMode = kDAC_BufferTriggerBySoftwareMode; +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + config->watermark = kDAC_BufferWatermark1Word; +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + config->workMode = kDAC_BufferWorkAsNormalMode; + config->upperLimit = DAC_DATL_COUNT - 1U; +} + +void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value) +{ + assert(index < DAC_DATL_COUNT); + + base->DAT[index].DATL = (uint8_t)(0xFFU & value); /* Low 8-bit. */ + base->DAT[index].DATH = (uint8_t)((0xF00U & value) >> 8); /* High 4-bit. */ +} + +void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index) +{ + assert(index < DAC_DATL_COUNT); + + uint8_t tmp8 = base->C2 & ~DAC_C2_DACBFRP_MASK; + + tmp8 |= DAC_C2_DACBFRP(index); + base->C2 = tmp8; +} + +void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask) +{ + mask &= ( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + DAC_C0_DACBWIEN_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK); + base->C0 |= ((uint8_t)mask); /* Write 1 to enable. */ +} + +void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask) +{ + mask &= ( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + DAC_C0_DACBWIEN_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK); + base->C0 &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to disable. */ +} + +uint32_t DAC_GetBufferStatusFlags(DAC_Type *base) +{ + return (uint32_t)(base->SR & ( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + DAC_SR_DACBFWMF_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK)); +} + +void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask) +{ + mask &= ( +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + DAC_SR_DACBFWMF_MASK | +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK); + base->SR &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to clear flags. */ +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dac.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dac.h new file mode 100644 index 0000000000..44e2d048bd --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dac.h @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_DAC_H_ +#define _FSL_DAC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup dac + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief DAC driver version 2.0.0. */ +#define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! + * @brief DAC buffer flags. + */ +enum _dac_buffer_status_flags +{ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + kDAC_BufferWatermarkFlag = DAC_SR_DACBFWMF_MASK, /*!< DAC Buffer Watermark Flag. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + kDAC_BufferReadPointerTopPositionFlag = DAC_SR_DACBFRPTF_MASK, /*!< DAC Buffer Read Pointer Top Position Flag. */ + kDAC_BufferReadPointerBottomPositionFlag = DAC_SR_DACBFRPBF_MASK, /*!< DAC Buffer Read Pointer Bottom Position + Flag. */ +}; + +/*! + * @brief DAC buffer interrupts. + */ +enum _dac_buffer_interrupt_enable +{ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION + kDAC_BufferWatermarkInterruptEnable = DAC_C0_DACBWIEN_MASK, /*!< DAC Buffer Watermark Interrupt Enable. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ + kDAC_BufferReadPointerTopInterruptEnable = DAC_C0_DACBTIEN_MASK, /*!< DAC Buffer Read Pointer Top Flag Interrupt + Enable. */ + kDAC_BufferReadPointerBottomInterruptEnable = DAC_C0_DACBBIEN_MASK, /*!< DAC Buffer Read Pointer Bottom Flag + Interrupt Enable */ +}; + +/*! + * @brief DAC reference voltage source. + */ +typedef enum _dac_reference_voltage_source +{ + kDAC_ReferenceVoltageSourceVref1 = 0U, /*!< The DAC selects DACREF_1 as the reference voltage. */ + kDAC_ReferenceVoltageSourceVref2 = 1U, /*!< The DAC selects DACREF_2 as the reference voltage. */ +} dac_reference_voltage_source_t; + +/*! + * @brief DAC buffer trigger mode. + */ +typedef enum _dac_buffer_trigger_mode +{ + kDAC_BufferTriggerByHardwareMode = 0U, /*!< The DAC hardware trigger is selected. */ + kDAC_BufferTriggerBySoftwareMode = 1U, /*!< The DAC software trigger is selected. */ +} dac_buffer_trigger_mode_t; + +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION +/*! + * @brief DAC buffer watermark. + */ +typedef enum _dac_buffer_watermark +{ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD + kDAC_BufferWatermark1Word = 0U, /*!< 1 word away from the upper limit. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD + kDAC_BufferWatermark2Word = 1U, /*!< 2 words away from the upper limit. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD + kDAC_BufferWatermark3Word = 2U, /*!< 3 words away from the upper limit. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD + kDAC_BufferWatermark4Word = 3U, /*!< 4 words away from the upper limit. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD */ +} dac_buffer_watermark_t; +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + +/*! + * @brief DAC buffer work mode. + */ +typedef enum _dac_buffer_work_mode +{ + kDAC_BufferWorkAsNormalMode = 0U, /*!< Normal mode. */ +#if defined(FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE) && FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE + kDAC_BufferWorkAsSwingMode, /*!< Swing mode. */ +#endif /* FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE */ + kDAC_BufferWorkAsOneTimeScanMode, /*!< One-Time Scan mode. */ +#if defined(FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE) && FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE + kDAC_BufferWorkAsFIFOMode, /*!< FIFO mode. */ +#endif /* FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE */ +} dac_buffer_work_mode_t; + +/*! + * @brief DAC module configuration. + */ +typedef struct _dac_config +{ + dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the DAC reference voltage source. */ + bool enableLowPowerMode; /*!< Enable the low power mode. */ +} dac_config_t; + +/*! + * @brief DAC buffer configuration. + */ +typedef struct _dac_buffer_config +{ + dac_buffer_trigger_mode_t triggerMode; /*!< Select the buffer's trigger mode. */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION + dac_buffer_watermark_t watermark; /*!< Select the buffer's watermark. */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ + dac_buffer_work_mode_t workMode; /*!< Select the buffer's work mode. */ + uint8_t upperLimit; /*!< Set the upper limit for buffer index. + Normally, 0-15 is available for buffer with 16 item. */ +} dac_buffer_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes the DAC module. + * + * This function initializes the DAC module, including: + * - Enabling the clock for DAC module. + * - Configuring the DAC converter with a user configuration. + * - Enabling the DAC module. + * + * @param base DAC peripheral base address. + * @param config Pointer to the configuration structure. See "dac_config_t". + */ +void DAC_Init(DAC_Type *base, const dac_config_t *config); + +/*! + * @brief De-initializes the DAC module. + * + * This function de-initializes the DAC module, including: + * - Disabling the DAC module. + * - Disabling the clock for the DAC module. + * + * @param base DAC peripheral base address. + */ +void DAC_Deinit(DAC_Type *base); + +/*! + * @brief Initializes the DAC user configuration structure. + * + * This function initializes the user configuration structure to a default value. The default values are: + * @code + * config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; + * config->enableLowPowerMode = false; + * @endcode + * @param config Pointer to the configuration structure. See "dac_config_t". + */ +void DAC_GetDefaultConfig(dac_config_t *config); + +/*! + * @brief Enables the DAC module. + * + * @param base DAC peripheral base address. + * @param enable Enables the feature or not. + */ +static inline void DAC_Enable(DAC_Type *base, bool enable) +{ + if (enable) + { + base->C0 |= DAC_C0_DACEN_MASK; + } + else + { + base->C0 &= ~DAC_C0_DACEN_MASK; + } +} + +/* @} */ + +/*! + * @name Buffer + * @{ + */ + +/*! + * @brief Enables the DAC buffer. + * + * @param base DAC peripheral base address. + * @param enable Enables the feature or not. + */ +static inline void DAC_EnableBuffer(DAC_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= DAC_C1_DACBFEN_MASK; + } + else + { + base->C1 &= ~DAC_C1_DACBFEN_MASK; + } +} + +/*! + * @brief Configures the CMP buffer. + * + * @param base DAC peripheral base address. + * @param config Pointer to the configuration structure. See "dac_buffer_config_t". + */ +void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config); + +/*! + * @brief Initializes the DAC buffer configuration structure. + * + * This function initializes the DAC buffer configuration structure to a default value. The default values are: + * @code + * config->triggerMode = kDAC_BufferTriggerBySoftwareMode; + * config->watermark = kDAC_BufferWatermark1Word; + * config->workMode = kDAC_BufferWorkAsNormalMode; + * config->upperLimit = DAC_DATL_COUNT - 1U; + * @endcode + * @param config Pointer to the configuration structure. See "dac_buffer_config_t". + */ +void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config); + +/*! + * @brief Enables the DMA for DAC buffer. + * + * @param base DAC peripheral base address. + * @param enable Enables the feature or not. + */ +static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= DAC_C1_DMAEN_MASK; + } + else + { + base->C1 &= ~DAC_C1_DMAEN_MASK; + } +} + +/*! + * @brief Sets the value for items in the buffer. + * + * @param base DAC peripheral base address. + * @param index Setting index for items in the buffer. The available index should not exceed the size of the DAC buffer. + * @param value Setting value for items in the buffer. 12-bits are available. + */ +void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value); + +/*! + * @brief Triggers the buffer by software and updates the read pointer of the DAC buffer. + * + * This function triggers the function by software. The read pointer of the DAC buffer is updated with one step + * after this function is called. Changing the read pointer depends on the buffer's work mode. + * + * @param base DAC peripheral base address. + */ +static inline void DAC_DoSoftwareTriggerBuffer(DAC_Type *base) +{ + base->C0 |= DAC_C0_DACSWTRG_MASK; +} + +/*! + * @brief Gets the current read pointer of the DAC buffer. + * + * This function gets the current read pointer of the DAC buffer. + * The current output value depends on the item indexed by the read pointer. It is updated + * by software trigger or hardware trigger. + * + * @param base DAC peripheral base address. + * + * @return Current read pointer of DAC buffer. + */ +static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base) +{ + return ((base->C2 & DAC_C2_DACBFRP_MASK) >> DAC_C2_DACBFRP_SHIFT); +} + +/*! + * @brief Sets the current read pointer of the DAC buffer. + * + * This function sets the current read pointer of the DAC buffer. + * The current output value depends on the item indexed by the read pointer. It is updated by + * software trigger or hardware trigger. After the read pointer changes, the DAC output value also changes. + * + * @param base DAC peripheral base address. + * @param index Setting index value for the pointer. + */ +void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index); + +/*! + * @brief Enables interrupts for the DAC buffer. + * + * @param base DAC peripheral base address. + * @param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable". + */ +void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask); + +/*! + * @brief Disables interrupts for the DAC buffer. + * + * @param base DAC peripheral base address. + * @param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable". + */ +void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask); + +/*! + * @brief Gets the flags of events for the DAC buffer. + * + * @param base DAC peripheral base address. + * + * @return Mask value for the asserted flags. See "_dac_buffer_status_flags". + */ +uint32_t DAC_GetBufferStatusFlags(DAC_Type *base); + +/*! + * @brief Clears the flags of events for the DAC buffer. + * + * @param base DAC peripheral base address. + * @param mask Mask value for flags. See "_dac_buffer_status_flags_t". + */ +void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask); + +/* @} */ + +#if defined(__cplusplus) +} +#endif +/*! + * @} + */ +#endif /* _FSL_DAC_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dma.c new file mode 100644 index 0000000000..6bef321ca7 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dma.c @@ -0,0 +1,306 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_dma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for DMA. + * + * @param base DMA peripheral base address. + */ +static uint32_t DMA_GetInstance(DMA_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map DMA instance number to base pointer. */ +static DMA_Type *const s_dmaBases[] = DMA_BASE_PTRS; + +/*! @brief Array to map DMA instance number to clock name. */ +static const clock_ip_name_t s_dmaClockName[] = DMA_CLOCKS; + +/*! @brief Array to map DMA instance number to IRQ number. */ +static const IRQn_Type s_dmaIRQNumber[] = DMA_CHN_IRQS; + +/*! @brief Pointers to transfer handle for each DMA channel. */ +static dma_handle_t *s_DMAHandle[FSL_FEATURE_DMAMUX_MODULE_CHANNEL * FSL_FEATURE_SOC_DMA_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t DMA_GetInstance(DMA_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_DMA_COUNT; instance++) + { + if (s_dmaBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_DMA_COUNT); + + return instance; +} + +void DMA_Init(DMA_Type *base) +{ + CLOCK_EnableClock(s_dmaClockName[DMA_GetInstance(base)]); +} + +void DMA_Deinit(DMA_Type *base) +{ + CLOCK_DisableClock(s_dmaClockName[DMA_GetInstance(base)]); +} + +void DMA_ResetChannel(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + /* clear all status bit */ + base->DMA[channel].DSR_BCR |= DMA_DSR_BCR_DONE(true); + /* clear all registers */ + base->DMA[channel].SAR = 0; + base->DMA[channel].DAR = 0; + base->DMA[channel].DSR_BCR = 0; + /* enable cycle steal and enable auto disable channel request */ + base->DMA[channel].DCR = DMA_DCR_D_REQ(true) | DMA_DCR_CS(true); +} + +void DMA_SetTransferConfig(DMA_Type *base, uint32_t channel, const dma_transfer_config_t *config) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + assert(config != NULL); + + uint32_t tmpreg; + + /* Set source address */ + base->DMA[channel].SAR = config->srcAddr; + /* Set destination address */ + base->DMA[channel].DAR = config->destAddr; + /* Set transfer bytes */ + base->DMA[channel].DSR_BCR = DMA_DSR_BCR_BCR(config->transferSize); + /* Set DMA Control Register */ + tmpreg = base->DMA[channel].DCR; + tmpreg &= ~(DMA_DCR_DSIZE_MASK | DMA_DCR_DINC_MASK | DMA_DCR_SSIZE_MASK | DMA_DCR_SINC_MASK); + tmpreg |= (DMA_DCR_DSIZE(config->destSize) | DMA_DCR_DINC(config->enableDestIncrement) | + DMA_DCR_SSIZE(config->srcSize) | DMA_DCR_SINC(config->enableSrcIncrement)); + base->DMA[channel].DCR = tmpreg; +} + +void DMA_SetChannelLinkConfig(DMA_Type *base, uint32_t channel, const dma_channel_link_config_t *config) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + assert(config != NULL); + + uint32_t tmpreg; + + tmpreg = base->DMA[channel].DCR; + tmpreg &= ~(DMA_DCR_LINKCC_MASK | DMA_DCR_LCH1_MASK | DMA_DCR_LCH2_MASK); + tmpreg |= (DMA_DCR_LINKCC(config->linkType) | DMA_DCR_LCH1(config->channel1) | DMA_DCR_LCH2(config->channel2)); + base->DMA[channel].DCR = tmpreg; +} + +void DMA_SetModulo(DMA_Type *base, uint32_t channel, dma_modulo_t srcModulo, dma_modulo_t destModulo) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + uint32_t tmpreg; + + tmpreg = base->DMA[channel].DCR; + tmpreg &= ~(DMA_DCR_SMOD_MASK | DMA_DCR_DMOD_MASK); + tmpreg |= (DMA_DCR_SMOD(srcModulo) | DMA_DCR_DMOD(destModulo)); + base->DMA[channel].DCR = tmpreg; +} + +void DMA_CreateHandle(dma_handle_t *handle, DMA_Type *base, uint32_t channel) +{ + assert(handle != NULL); + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + uint32_t dmaInstance; + uint32_t channelIndex; + + handle->base = base; + handle->channel = channel; + /* Get the DMA instance number */ + dmaInstance = DMA_GetInstance(base); + channelIndex = (dmaInstance * FSL_FEATURE_DMAMUX_MODULE_CHANNEL) + channel; + /* Store handle */ + s_DMAHandle[channelIndex] = handle; + /* Enable NVIC interrupt. */ + EnableIRQ(s_dmaIRQNumber[channelIndex]); +} + +void DMA_PrepareTransfer(dma_transfer_config_t *config, + void *srcAddr, + uint32_t srcWidth, + void *destAddr, + uint32_t destWidth, + uint32_t transferBytes, + dma_transfer_type_t type) +{ + assert(config != NULL); + assert(srcAddr != NULL); + assert(destAddr != NULL); + assert(srcWidth == 1U || srcWidth == 2U || srcWidth == 4U); + assert(destWidth == 1U || destWidth == 2U || destWidth == 4U); + + config->srcAddr = (uint32_t)srcAddr; + config->destAddr = (uint32_t)destAddr; + config->transferSize = transferBytes; + switch (srcWidth) + { + case 1U: + config->srcSize = kDMA_Transfersize8bits; + break; + case 2U: + config->srcSize = kDMA_Transfersize16bits; + break; + case 4U: + config->srcSize = kDMA_Transfersize32bits; + break; + default: + break; + } + switch (destWidth) + { + case 1U: + config->destSize = kDMA_Transfersize8bits; + break; + case 2U: + config->destSize = kDMA_Transfersize16bits; + break; + case 4U: + config->destSize = kDMA_Transfersize32bits; + break; + default: + break; + } + switch (type) + { + case kDMA_MemoryToMemory: + config->enableSrcIncrement = true; + config->enableDestIncrement = true; + break; + case kDMA_PeripheralToMemory: + config->enableSrcIncrement = false; + config->enableDestIncrement = true; + break; + case kDMA_MemoryToPeripheral: + config->enableSrcIncrement = true; + config->enableDestIncrement = false; + break; + default: + break; + } +} + +void DMA_SetCallback(dma_handle_t *handle, dma_callback callback, void *userData) +{ + assert(handle != NULL); + + handle->callback = callback; + handle->userData = userData; +} + +status_t DMA_SubmitTransfer(dma_handle_t *handle, const dma_transfer_config_t *config, uint32_t options) +{ + assert(handle != NULL); + assert(config != NULL); + + /* Check if DMA is busy */ + if (handle->base->DMA[handle->channel].DSR_BCR & DMA_DSR_BCR_BSY_MASK) + { + return kStatus_DMA_Busy; + } + DMA_ResetChannel(handle->base, handle->channel); + DMA_SetTransferConfig(handle->base, handle->channel, config); + if (options & kDMA_EnableInterrupt) + { + DMA_EnableInterrupts(handle->base, handle->channel); + } + return kStatus_Success; +} + +void DMA_AbortTransfer(dma_handle_t *handle) +{ + assert(handle != NULL); + + handle->base->DMA[handle->channel].DCR &= ~DMA_DCR_ERQ_MASK; + /* clear all status bit */ + handle->base->DMA[handle->channel].DSR_BCR |= DMA_DSR_BCR_DONE(true); +} + +void DMA_HandleIRQ(dma_handle_t *handle) +{ + assert(handle != NULL); + + /* Clear interrupt pending bit */ + DMA_ClearChannelStatusFlags(handle->base, handle->channel, kDMA_TransactionsDoneFlag); + if (handle->callback) + { + (handle->callback)(handle, handle->userData); + } +} + +#if defined(FSL_FEATURE_DMAMUX_MODULE_CHANNEL) && (FSL_FEATURE_DMAMUX_MODULE_CHANNEL == 4U) +void DMA0_DriverIRQHandler(void) +{ + DMA_HandleIRQ(s_DMAHandle[0]); +} + +void DMA1_DriverIRQHandler(void) +{ + DMA_HandleIRQ(s_DMAHandle[1]); +} + +void DMA2_DriverIRQHandler(void) +{ + DMA_HandleIRQ(s_DMAHandle[2]); +} + +void DMA3_DriverIRQHandler(void) +{ + DMA_HandleIRQ(s_DMAHandle[3]); +} +#endif /* FSL_FEATURE_DMAMUX_MODULE_CHANNEL */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dma.h new file mode 100644 index 0000000000..b7c00fc092 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dma.h @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_DMA_H_ +#define _FSL_DMA_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup dma_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief DMA driver version 2.0.0. */ +#define FSL_DMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @brief status flag for the DMA driver. */ +enum _dma_channel_status_flags +{ + kDMA_TransactionsBCRFlag = DMA_DSR_BCR_BCR_MASK, /*!< Contains the number of bytes yet to be + transferred for a given block */ + kDMA_TransactionsDoneFlag = DMA_DSR_BCR_DONE_MASK, /*!< Transactions Done */ + kDMA_TransactionsBusyFlag = DMA_DSR_BCR_BSY_MASK, /*!< Transactions Busy */ + kDMA_TransactionsRequestFlag = DMA_DSR_BCR_REQ_MASK, /*!< Transactions Request */ + kDMA_BusErrorOnDestinationFlag = DMA_DSR_BCR_BED_MASK, /*!< Bus Error on Destination */ + kDMA_BusErrorOnSourceFlag = DMA_DSR_BCR_BES_MASK, /*!< Bus Error on Source */ + kDMA_ConfigurationErrorFlag = DMA_DSR_BCR_CE_MASK, /*!< Configuration Error */ +}; + +/*! @brief DMA transfer size type*/ +typedef enum _dma_transfer_size +{ + kDMA_Transfersize32bits = 0x0U, /*!< 32 bits are transferred for every read/write */ + kDMA_Transfersize8bits, /*!< 8 bits are transferred for every read/write */ + kDMA_Transfersize16bits, /*!< 16b its are transferred for every read/write */ +} dma_transfer_size_t; + +/*! @brief Configuration type for the DMA modulo */ +typedef enum _dma_modulo +{ + kDMA_ModuloDisable = 0x0U, /*!< Buffer disabled */ + kDMA_Modulo16Bytes, /*!< Circular buffer size is 16 bytes. */ + kDMA_Modulo32Bytes, /*!< Circular buffer size is 32 bytes. */ + kDMA_Modulo64Bytes, /*!< Circular buffer size is 64 bytes. */ + kDMA_Modulo128Bytes, /*!< Circular buffer size is 128 bytes. */ + kDMA_Modulo256Bytes, /*!< Circular buffer size is 256 bytes. */ + kDMA_Modulo512Bytes, /*!< Circular buffer size is 512 bytes. */ + kDMA_Modulo1KBytes, /*!< Circular buffer size is 1 KB. */ + kDMA_Modulo2KBytes, /*!< Circular buffer size is 2 KB. */ + kDMA_Modulo4KBytes, /*!< Circular buffer size is 4 KB. */ + kDMA_Modulo8KBytes, /*!< Circular buffer size is 8 KB. */ + kDMA_Modulo16KBytes, /*!< Circular buffer size is 16 KB. */ + kDMA_Modulo32KBytes, /*!< Circular buffer size is 32 KB. */ + kDMA_Modulo64KBytes, /*!< Circular buffer size is 64 KB. */ + kDMA_Modulo128KBytes, /*!< Circular buffer size is 128 KB. */ + kDMA_Modulo256KBytes, /*!< Circular buffer size is 256 KB. */ +} dma_modulo_t; + +/*! @brief DMA channel link type */ +typedef enum _dma_channel_link_type +{ + kDMA_ChannelLinkDisable = 0x0U, /*!< No channel link. */ + kDMA_ChannelLinkChannel1AndChannel2, /*!< Perform a link to channel LCH1 after each cycle-steal transfer. + followed by a link to LCH2 after the BCR decrements to 0. */ + kDMA_ChannelLinkChannel1, /*!< Perform a link to LCH1 after each cycle-steal transfer. */ + kDMA_ChannelLinkChannel1AfterBCR0, /*!< Perform a link to LCH1 after the BCR decrements. */ +} dma_channel_link_type_t; + +/*! @brief DMA transfer type */ +typedef enum _dma_transfer_type +{ + kDMA_MemoryToMemory = 0x0U, /*!< Memory to Memory transfer. */ + kDMA_PeripheralToMemory, /*!< Peripheral to Memory transfer. */ + kDMA_MemoryToPeripheral, /*!< Memory to Peripheral transfer. */ +} dma_transfer_type_t; + +/*! @brief DMA transfer options */ +typedef enum _dma_transfer_options +{ + kDMA_NoOptions = 0x0U, /*!< Transfer without options. */ + kDMA_EnableInterrupt, /*!< Enable interrupt while transfer complete. */ +} dma_transfer_options_t; + +/*! @brief DMA transfer status */ +enum _dma_transfer_status +{ + kStatus_DMA_Busy = MAKE_STATUS(kStatusGroup_DMA, 0), +}; + +/*! @brief DMA transfer configuration structure */ +typedef struct _dma_transfer_config +{ + uint32_t srcAddr; /*!< DMA transfer source address. */ + uint32_t destAddr; /*!< DMA destination address.*/ + bool enableSrcIncrement; /*!< Source address increase after each transfer. */ + dma_transfer_size_t srcSize; /*!< Source transfer size unit. */ + bool enableDestIncrement; /*!< Destination address increase after each transfer. */ + dma_transfer_size_t destSize; /*!< Destination transfer unit.*/ + uint32_t transferSize; /*!< The number of bytes to be transferred. */ +} dma_transfer_config_t; + +/*! @brief DMA transfer configuration structure */ +typedef struct _dma_channel_link_config +{ + dma_channel_link_type_t linkType; /*!< Channel link type. */ + uint32_t channel1; /*!< The index of channel 1. */ + uint32_t channel2; /*!< The index of channel 2. */ +} dma_channel_link_config_t; + +struct _dma_handle; +/*! @brief Callback function prototype for the DMA driver. */ +typedef void (*dma_callback)(struct _dma_handle *handle, void *userData); + +/*! @brief DMA DMA handle structure */ +typedef struct _dma_handle +{ + DMA_Type *base; /*!< DMA peripheral address. */ + uint8_t channel; /*!< DMA channel used. */ + dma_callback callback; /*!< DMA callback function.*/ + void *userData; /*!< Callback parameter. */ +} dma_handle_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name DMA Initialization and De-initialization + * @{ + */ + +/*! + * @brief Initializes the DMA peripheral. + * + * This function ungates the DMA clock. + * + * @param base DMA peripheral base address. + */ +void DMA_Init(DMA_Type *base); + +/*! + * @brief Deinitializes the DMA peripheral. + * + * This function gates the DMA clock. + * + * @param base DMA peripheral base address. + */ +void DMA_Deinit(DMA_Type *base); + +/* @} */ +/*! + * @name DMA Channel Operation + * @{ + */ + +/*! + * @brief Resets the DMA channel. + * + * Sets all register values to reset values and enables + * the cycle steal and auto stop channel request features. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +void DMA_ResetChannel(DMA_Type *base, uint32_t channel); + +/*! + * @brief Configures the DMA transfer attribute. + * + * This function configures the transfer attribute including the source address, + * destination address, transfer size, and so on. + * This example shows how to set up the the dma_transfer_config_t + * parameters and how to call the DMA_ConfigBasicTransfer function. + * @code + * dma_transfer_config_t transferConfig; + * memset(&transferConfig, 0, sizeof(transferConfig)); + * transferConfig.srcAddr = (uint32_t)srcAddr; + * transferConfig.destAddr = (uint32_t)destAddr; + * transferConfig.enbaleSrcIncrement = true; + * transferConfig.enableDestIncrement = true; + * transferConfig.srcSize = kDMA_Transfersize32bits; + * transferConfig.destSize = kDMA_Transfersize32bits; + * transferConfig.transferSize = sizeof(uint32_t) * BUFF_LENGTH; + * DMA_SetTransferConfig(DMA0, 0, &transferConfig); + * @endcode + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param config Pointer to the DMA transfer configuration structure. + */ +void DMA_SetTransferConfig(DMA_Type *base, uint32_t channel, const dma_transfer_config_t *config); + +/*! + * @brief Configures the DMA channel link feature. + * + * This function allows DMA channels to have their transfers linked. The current DMA channel + * triggers a DMA request to the linked channels (LCH1 or LCH2) depending on the channel link + * type. + * Perform a link to channel LCH1 after each cycle-steal transfer followed by a link to LCH2 + * after the BCR decrements to 0 if the type is kDMA_ChannelLinkChannel1AndChannel2. + * Perform a link to LCH1 after each cycle-steal transfer if the type is kDMA_ChannelLinkChannel1. + * Perform a link to LCH1 after the BCR decrements to 0 if the type is kDMA_ChannelLinkChannel1AfterBCR0. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param config Pointer to the channel link configuration structure. + */ +void DMA_SetChannelLinkConfig(DMA_Type *base, uint32_t channel, const dma_channel_link_config_t *config); + +/*! + * @brief Sets the DMA source address for the DMA transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param srcAddr DMA source address. + */ +static inline void DMA_SetSourceAddress(DMA_Type *base, uint32_t channel, uint32_t srcAddr) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].SAR = srcAddr; +} + +/*! + * @brief Sets the DMA destination address for the DMA transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param destAddr DMA destination address. + */ +static inline void DMA_SetDestinationAddress(DMA_Type *base, uint32_t channel, uint32_t destAddr) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DAR = destAddr; +} + +/*! + * @brief Sets the DMA transfer size for the DMA transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param size The number of bytes to be transferred. + */ +static inline void DMA_SetTransferSize(DMA_Type *base, uint32_t channel, uint32_t size) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DSR_BCR = DMA_DSR_BCR_BCR(size); +} + +/*! + * @brief Sets the DMA modulo for the DMA transfer. + * + * This function defines a specific address range specified to be the value after (SAR + SSIZE)/(DAR + DSIZE) + * calculation is performed or the original register value. It provides the ability to implement a circular + * data queue easily. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param srcModulo source address modulo. + * @param destModulo destination address modulo. + */ +void DMA_SetModulo(DMA_Type *base, uint32_t channel, dma_modulo_t srcModulo, dma_modulo_t destModulo); + +/*! + * @brief Enables the DMA cycle steal for the DMA transfer. + * + * If the cycle steal feature is enabled (true), the DMA controller forces a single read/write transfer per request, + * or it continuously makes read/write transfers until the BCR decrements to 0. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param enable The command for enable (true) or disable (false). + */ +static inline void DMA_EnableCycleSteal(DMA_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DCR = (base->DMA[channel].DCR & (~DMA_DCR_CS_MASK)) | DMA_DCR_CS(enable); +} + +/*! + * @brief Enables the DMA auto align for the DMA transfer. + * + * If the auto align feature is enabled (true), the appropriate address register increments, + * regardless of DINC or SINC. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param enable The command for enable (true) or disable (false). + */ +static inline void DMA_EnableAutoAlign(DMA_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DCR = (base->DMA[channel].DCR & (~DMA_DCR_AA_MASK)) | DMA_DCR_AA(enable); +} + +/*! + * @brief Enables the DMA async request for the DMA transfer. + * + * If the async request feature is enabled (true), the DMA supports asynchronous DREQs + * while the MCU is in stop mode. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param enable The command for enable (true) or disable (false). + */ +static inline void DMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DCR = (base->DMA[channel].DCR & (~DMA_DCR_EADREQ_MASK)) | DMA_DCR_EADREQ(enable); +} + +/*! + * @brief Enables an interrupt for the DMA transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +static inline void DMA_EnableInterrupts(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DCR |= DMA_DCR_EINT(true); +} + +/*! + * @brief Disables an interrupt for the DMA transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +static inline void DMA_DisableInterrupts(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DCR &= ~DMA_DCR_EINT_MASK; +} + +/* @} */ +/*! + * @name DMA Channel Transfer Operation + * @{ + */ + +/*! + * @brief Enables the DMA hardware channel request. + * + * @param base DMA peripheral base address. + * @param channel The DMA channel number. + */ +static inline void DMA_EnableChannelRequest(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DCR |= DMA_DCR_ERQ_MASK; +} + +/*! + * @brief Disables the DMA hardware channel request. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +static inline void DMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DCR &= ~DMA_DCR_ERQ_MASK; +} + +/*! + * @brief Starts the DMA transfer with a software trigger. + * + * This function starts only one read/write iteration. + * + * @param base DMA peripheral base address. + * @param channel The DMA channel number. + */ +static inline void DMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->DMA[channel].DCR |= DMA_DCR_START_MASK; +} + +/* @} */ +/*! + * @name DMA Channel Status Operation + * @{ + */ + +/*! + * @brief Gets the remaining bytes of the current DMA transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @return The number of bytes which have not been transferred yet. + */ +static inline uint32_t DMA_GetRemainingBytes(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + return (base->DMA[channel].DSR_BCR & DMA_DSR_BCR_BCR_MASK) >> DMA_DSR_BCR_BCR_SHIFT; +} + +/*! + * @brief Gets the DMA channel status flags. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @return The mask of the channel status. Use the _dma_channel_status_flags + * type to decode the return 32 bit variables. + */ +static inline uint32_t DMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + return base->DMA[channel].DSR_BCR; +} + +/*! + * @brief Clears the DMA channel status flags. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param mask The mask of the channel status to be cleared. Use + * the defined _dma_channel_status_flags type. + */ +static inline void DMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + if (mask != 0U) + { + base->DMA[channel].DSR_BCR |= DMA_DSR_BCR_DONE(true); + } +} + +/* @} */ +/*! + * @name DMA Channel Transactional Operation + * @{ + */ + +/*! + * @brief Creates the DMA handle. + * + * This function is called first if using the transactional API for the DMA. This function + * initializes the internal state of the DMA handle. + * + * @param handle DMA handle pointer. The DMA handle stores callback function and + * parameters. + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +void DMA_CreateHandle(dma_handle_t *handle, DMA_Type *base, uint32_t channel); + +/*! + * @brief Sets the DMA callback function. + * + * This callback is called in the DMA IRQ handler. Use the callback to do something + * after the current transfer complete. + * + * @param handle DMA handle pointer. + * @param callback DMA callback function pointer. + * @param userData Parameter for callback function. If it is not needed, just set to NULL. + */ +void DMA_SetCallback(dma_handle_t *handle, dma_callback callback, void *userData); + +/*! + * @brief Prepares the DMA transfer configuration structure. + * + * This function prepares the transfer configuration structure according to the user input. + * + * @param config Pointer to the user configuration structure of type dma_transfer_config_t. + * @param srcAddr DMA transfer source address. + * @param srcWidth DMA transfer source address width (byte). + * @param destAddr DMA transfer destination address. + * @param destWidth DMA transfer destination address width (byte). + * @param transferBytes DMA transfer bytes to be transferred. + * @param type DMA transfer type. + */ +void DMA_PrepareTransfer(dma_transfer_config_t *config, + void *srcAddr, + uint32_t srcWidth, + void *destAddr, + uint32_t destWidth, + uint32_t transferBytes, + dma_transfer_type_t type); + +/*! + * @brief Submits the DMA transfer request. + * + * This function submits the DMA transfer request according to the transfer configuration structure. + * + * @param handle DMA handle pointer. + * @param config Pointer to DMA transfer configuration structure. + * @param options Additional configurations for transfer. Use + * the defined dma_transfer_options_t type. + * @retval kStatus_DMA_Success It indicates that the DMA submit transfer request succeeded. + * @retval kStatus_DMA_Busy It indicates that the DMA is busy. Submit transfer request is not allowed. + * @note This function can't process multi transfer request. + */ +status_t DMA_SubmitTransfer(dma_handle_t *handle, const dma_transfer_config_t *config, uint32_t options); + +/*! + * @brief DMA starts a transfer. + * + * This function enables the channel request. Call this function + * after submitting a transfer request. + * + * @param handle DMA handle pointer. + * @retval kStatus_DMA_Success It indicates that the DMA start transfer succeed. + * @retval kStatus_DMA_Busy It indicates that the DMA has started a transfer. + */ +static inline void DMA_StartTransfer(dma_handle_t *handle) +{ + assert(handle != NULL); + + handle->base->DMA[handle->channel].DCR |= DMA_DCR_ERQ_MASK; +} + +/*! + * @brief DMA stops a transfer. + * + * This function disables the channel request to stop a DMA transfer. + * The transfer can be resumed by calling the DMA_StartTransfer. + * + * @param handle DMA handle pointer. + */ +static inline void DMA_StopTransfer(dma_handle_t *handle) +{ + assert(handle != NULL); + + handle->base->DMA[handle->channel].DCR &= ~DMA_DCR_ERQ_MASK; +} + +/*! + * @brief DMA aborts a transfer. + * + * This function disables the channel request and clears all status bits. + * Submit another transfer after calling this API. + * + * @param handle DMA handle pointer. + */ +void DMA_AbortTransfer(dma_handle_t *handle); + +/*! + * @brief DMA IRQ handler for current transfer complete. + * + * This function clears the channel interrupt flag and calls + * the callback function if it is not NULL. + * + * @param handle DMA handle pointer. + */ +void DMA_HandleIRQ(dma_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* @}*/ + +#endif /* _FSL_DMA_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dmamux.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dmamux.c new file mode 100644 index 0000000000..a288b9f22f --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dmamux.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for DMAMUX. + * + * @param base DMAMUX peripheral base address. + */ +static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map DMAMUX instance number to base pointer. */ +static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS; + +/*! @brief Array to map DMAMUX instance number to clock name. */ +static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_DMAMUX_COUNT; instance++) + { + if (s_dmamuxBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_DMAMUX_COUNT); + + return instance; +} + +void DMAMUX_Init(DMAMUX_Type *base) +{ + CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); +} + +void DMAMUX_Deinit(DMAMUX_Type *base) +{ + CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dmamux.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dmamux.h new file mode 100644 index 0000000000..f4294d4dfa --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_dmamux.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_DMAMUX_H_ +#define _FSL_DMAMUX_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup dmamux + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief DMAMUX driver version 2.0.0. */ +#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name DMAMUX Initialize and De-initialize + * @{ + */ + +/*! + * @brief Initializes DMAMUX peripheral. + * + * This function ungate the DMAMUX clock. + * + * @param base DMAMUX peripheral base address. + * + */ +void DMAMUX_Init(DMAMUX_Type *base); + +/*! + * @brief Deinitializes DMAMUX peripheral. + * + * This function gate the DMAMUX clock. + * + * @param base DMAMUX peripheral base address. + */ +void DMAMUX_Deinit(DMAMUX_Type *base); + +/* @} */ +/*! + * @name DMAMUX Channel Operation + * @{ + */ + +/*! + * @brief Enable DMAMUX channel. + * + * This function enable DMAMUX channel to work. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK; +} + +/*! + * @brief Disable DMAMUX channel. + * + * This function disable DMAMUX channel. + * + * @note User must disable DMAMUX channel before configure it. + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] &= ~DMAMUX_CHCFG_ENBL_MASK; +} + +/*! + * @brief Configure DMAMUX channel source. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + * @param source Channel source which is used to trigger DMA transfer. + */ +static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint8_t source) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] = ((base->CHCFG[channel] & ~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(source)); +} + +#if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U +/*! + * @brief Enable DMAMUX period trigger. + * + * This function enable DMAMUX period trigger feature. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK; +} + +/*! + * @brief Disable DMAMUX period trigger. + * + * This function disable DMAMUX period trigger. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] &= ~DMAMUX_CHCFG_TRIG_MASK; +} +#endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */ + +/* @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* @} */ + +#endif /* _FSL_DMAMUX_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flash.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flash.c new file mode 100644 index 0000000000..2add4e9635 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flash.c @@ -0,0 +1,2610 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flash.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @name Misc utility defines + * @{ + */ +#ifndef ALIGN_DOWN +#define ALIGN_DOWN(x, a) ((x) & (uint32_t)(-((int32_t)(a)))) +#endif +#ifndef ALIGN_UP +#define ALIGN_UP(x, a) (-((int32_t)((uint32_t)(-((int32_t)(x))) & (uint32_t)(-((int32_t)(a)))))) +#endif + +#define BYTES_JOIN_TO_WORD_1_3(x, y) ((((uint32_t)(x)&0xFFU) << 24) | ((uint32_t)(y)&0xFFFFFFU)) +#define BYTES_JOIN_TO_WORD_2_2(x, y) ((((uint32_t)(x)&0xFFFFU) << 16) | ((uint32_t)(y)&0xFFFFU)) +#define BYTES_JOIN_TO_WORD_3_1(x, y) ((((uint32_t)(x)&0xFFFFFFU) << 8) | ((uint32_t)(y)&0xFFU)) +#define BYTES_JOIN_TO_WORD_1_1_2(x, y, z) \ + ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFU) << 16) | ((uint32_t)(z)&0xFFFFU)) +#define BYTES_JOIN_TO_WORD_1_2_1(x, y, z) \ + ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFFFU) << 8) | ((uint32_t)(z)&0xFFU)) +#define BYTES_JOIN_TO_WORD_2_1_1(x, y, z) \ + ((((uint32_t)(x)&0xFFFFU) << 16) | (((uint32_t)(y)&0xFFU) << 8) | ((uint32_t)(z)&0xFFU)) +#define BYTES_JOIN_TO_WORD_1_1_1_1(x, y, z, w) \ + ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFU) << 16) | (((uint32_t)(z)&0xFFU) << 8) | \ + ((uint32_t)(w)&0xFFU)) +/*@}*/ + +/*! @brief Data flash IFR map Field*/ +#if defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE +#define DFLASH_IFR_READRESOURCE_START_ADDRESS 0x8003F8U +#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */ +#define DFLASH_IFR_READRESOURCE_START_ADDRESS 0x8000F8U +#endif + +/*! + * @name Reserved FlexNVM size (For a variety of purposes) defines + * @{ + */ +#define FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED 0xFFFFFFFFU +#define FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED 0xFFFFU +/*@}*/ + +/*! + * @name Flash Program Once Field defines + * @{ + */ +#if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA +/* FTFA parts(eg. K80, KL80, L5K) support both 4-bytes and 8-bytes unit size */ +#define FLASH_PROGRAM_ONCE_MIN_ID_8BYTES \ + 0x10U /* Minimum Index indcating one of Progam Once Fields which is accessed in 8-byte records */ +#define FLASH_PROGRAM_ONCE_MAX_ID_8BYTES \ + 0x13U /* Maximum Index indcating one of Progam Once Fields which is accessed in 8-byte records */ +#define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 1 +#define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 1 +#elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE +/* FTFE parts(eg. K65, KE18) only support 8-bytes unit size */ +#define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 0 +#define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 1 +#elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL +/* FTFL parts(eg. K20) only support 4-bytes unit size */ +#define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 1 +#define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 0 +#endif +/*@}*/ + +/*! + * @name Flash security status defines + * @{ + */ +#define FLASH_SECURITY_STATE_KEYEN 0x80U +#define FLASH_SECURITY_STATE_UNSECURED 0x02U +#define FLASH_NOT_SECURE 0x01U +#define FLASH_SECURE_BACKDOOR_ENABLED 0x02U +#define FLASH_SECURE_BACKDOOR_DISABLED 0x04U +/*@}*/ + +/*! + * @name Flash controller command numbers + * @{ + */ +#define FTFx_VERIFY_BLOCK 0x00U /*!< RD1BLK*/ +#define FTFx_VERIFY_SECTION 0x01U /*!< RD1SEC*/ +#define FTFx_PROGRAM_CHECK 0x02U /*!< PGMCHK*/ +#define FTFx_READ_RESOURCE 0x03U /*!< RDRSRC*/ +#define FTFx_PROGRAM_LONGWORD 0x06U /*!< PGM4*/ +#define FTFx_PROGRAM_PHRASE 0x07U /*!< PGM8*/ +#define FTFx_ERASE_BLOCK 0x08U /*!< ERSBLK*/ +#define FTFx_ERASE_SECTOR 0x09U /*!< ERSSCR*/ +#define FTFx_PROGRAM_SECTION 0x0BU /*!< PGMSEC*/ +#define FTFx_VERIFY_ALL_BLOCK 0x40U /*!< RD1ALL*/ +#define FTFx_READ_ONCE 0x41U /*!< RDONCE or RDINDEX*/ +#define FTFx_PROGRAM_ONCE 0x43U /*!< PGMONCE or PGMINDEX*/ +#define FTFx_ERASE_ALL_BLOCK 0x44U /*!< ERSALL*/ +#define FTFx_SECURITY_BY_PASS 0x45U /*!< VFYKEY*/ +#define FTFx_SWAP_CONTROL 0x46U /*!< SWAP*/ +#define FTFx_ERASE_ALL_BLOCK_UNSECURE 0x49U /*!< ERSALLU*/ +#define FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT 0x4AU /*!< RD1XA*/ +#define FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT 0x4BU /*!< ERSXA*/ +#define FTFx_PROGRAM_PARTITION 0x80U /*!< PGMPART)*/ +#define FTFx_SET_FLEXRAM_FUNCTION 0x81U /*!< SETRAM*/ + /*@}*/ + +/*! + * @name Common flash register info defines + * @{ + */ +#if defined(FTFA) +#define FTFx FTFA +#define FTFx_BASE FTFA_BASE +#define FTFx_FSTAT_CCIF_MASK FTFA_FSTAT_CCIF_MASK +#define FTFx_FSTAT_RDCOLERR_MASK FTFA_FSTAT_RDCOLERR_MASK +#define FTFx_FSTAT_ACCERR_MASK FTFA_FSTAT_ACCERR_MASK +#define FTFx_FSTAT_FPVIOL_MASK FTFA_FSTAT_FPVIOL_MASK +#define FTFx_FSTAT_MGSTAT0_MASK FTFA_FSTAT_MGSTAT0_MASK +#define FTFx_FSEC_SEC_MASK FTFA_FSEC_SEC_MASK +#define FTFx_FSEC_KEYEN_MASK FTFA_FSEC_KEYEN_MASK +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM +#define FTFx_FCNFG_RAMRDY_MASK FTFA_FCNFG_RAMRDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM +#define FTFx_FCNFG_EEERDY_MASK FTFA_FCNFG_EEERDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ +#elif defined(FTFE) +#define FTFx FTFE +#define FTFx_BASE FTFE_BASE +#define FTFx_FSTAT_CCIF_MASK FTFE_FSTAT_CCIF_MASK +#define FTFx_FSTAT_RDCOLERR_MASK FTFE_FSTAT_RDCOLERR_MASK +#define FTFx_FSTAT_ACCERR_MASK FTFE_FSTAT_ACCERR_MASK +#define FTFx_FSTAT_FPVIOL_MASK FTFE_FSTAT_FPVIOL_MASK +#define FTFx_FSTAT_MGSTAT0_MASK FTFE_FSTAT_MGSTAT0_MASK +#define FTFx_FSEC_SEC_MASK FTFE_FSEC_SEC_MASK +#define FTFx_FSEC_KEYEN_MASK FTFE_FSEC_KEYEN_MASK +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM +#define FTFx_FCNFG_RAMRDY_MASK FTFE_FCNFG_RAMRDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM +#define FTFx_FCNFG_EEERDY_MASK FTFE_FCNFG_EEERDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ +#elif defined(FTFL) +#define FTFx FTFL +#define FTFx_BASE FTFL_BASE +#define FTFx_FSTAT_CCIF_MASK FTFL_FSTAT_CCIF_MASK +#define FTFx_FSTAT_RDCOLERR_MASK FTFL_FSTAT_RDCOLERR_MASK +#define FTFx_FSTAT_ACCERR_MASK FTFL_FSTAT_ACCERR_MASK +#define FTFx_FSTAT_FPVIOL_MASK FTFL_FSTAT_FPVIOL_MASK +#define FTFx_FSTAT_MGSTAT0_MASK FTFL_FSTAT_MGSTAT0_MASK +#define FTFx_FSEC_SEC_MASK FTFL_FSEC_SEC_MASK +#define FTFx_FSEC_KEYEN_MASK FTFL_FSEC_KEYEN_MASK +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM +#define FTFx_FCNFG_RAMRDY_MASK FTFL_FCNFG_RAMRDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ +#if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM +#define FTFx_FCNFG_EEERDY_MASK FTFL_FCNFG_EEERDY_MASK +#endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ +#else +#error "Unknown flash controller" +#endif +/*@}*/ + +/*! + * @brief Enumeration for access segment property. + */ +enum _flash_access_segment_property +{ + kFLASH_accessSegmentBase = 256UL, +}; + +/*! + * @brief Enumeration for acceleration ram property. + */ +enum _flash_acceleration_ram_property +{ + kFLASH_accelerationRamSize = 0x400U +}; + +/*! + * @brief Enumeration for flash config area. + */ +enum _flash_config_area_range +{ + kFLASH_configAreaStart = 0x400U, + kFLASH_configAreaEnd = 0x40FU +}; + +/*! @brief program Flash block base address*/ +#define PFLASH_BLOCK_BASE 0x00U + +/*! @brief Total flash region count*/ +#define FSL_FEATURE_FTFx_REGION_COUNT (32U) + +/*! + * @name Flash register access type defines + * @{ + */ +#if FLASH_DRIVER_IS_FLASH_RESIDENT +#define FTFx_REG_ACCESS_TYPE volatile uint8_t * +#define FTFx_REG32_ACCESS_TYPE volatile uint32_t * +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + /*@}*/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! @brief Copy flash_run_command() to RAM*/ +static void copy_flash_run_command(uint8_t *flashRunCommand); +/*! @brief Copy flash_cache_clear_command() to RAM*/ +static void copy_flash_cache_clear_command(uint8_t *flashCacheClearCommand); +/*! @brief Check whether flash execute-in-ram functions are ready*/ +static status_t flash_check_execute_in_ram_function_info(flash_config_t *config); +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +/*! @brief Internal function Flash command sequence. Called by driver APIs only*/ +static status_t flash_command_sequence(flash_config_t *config); + +/*! @brief Perform the cache clear to the flash*/ +void flash_cache_clear(flash_config_t *config); + +/*! @brief Validates the range and alignment of the given address range.*/ +static status_t flash_check_range(flash_config_t *config, + uint32_t startAddress, + uint32_t lengthInBytes, + uint32_t alignmentBaseline); +/*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/ +static status_t flash_get_matched_operation_info(flash_config_t *config, + uint32_t address, + flash_operation_config_t *info); +/*! @brief Validates the given user key for flash erase APIs.*/ +static status_t flash_check_user_key(uint32_t key); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +/*! @brief Updates FlexNVM memory partition status according to data flash 0 IFR.*/ +static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *config); +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD +/*! @brief Validates the range of the given resource address.*/ +static status_t flash_check_resource_range(uint32_t start, + uint32_t lengthInBytes, + uint32_t alignmentBaseline, + flash_read_resource_option_t option); +#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD +/*! @brief Validates the gived swap control option.*/ +static status_t flash_check_swap_control_option(flash_swap_control_option_t option); +#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP +/*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/ +static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address); +#endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD +/*! @brief Validates the gived flexram function option.*/ +static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option); +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Access to FTFx->FCCOB */ +#if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA +volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFA->FCCOB3; +#elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE +volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFE->FCCOB3; +#elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL +volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFL->FCCOB3; +#else +#error "Unknown flash controller" +#endif + +/*! @brief Access to FTFx->FPROT */ +#if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA +volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFA->FPROT3; +#elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE +volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFE->FPROT3; +#elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL +volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFL->FPROT3; +#else +#error "Unknown flash controller" +#endif + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! @brief A function pointer used to point to relocated flash_run_command() */ +static void (*callFlashRunCommand)(FTFx_REG_ACCESS_TYPE ftfx_fstat); +/*! @brief A function pointer used to point to relocated flash_cache_clear_command() */ +static void (*callFlashCacheClearCommand)(FTFx_REG32_ACCESS_TYPE ftfx_reg); +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +#if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED) +/*! @brief A static buffer used to hold flash_run_command() */ +static uint8_t s_flashRunCommand[kFLASH_executeInRamFunctionMaxSize]; +/*! @brief A static buffer used to hold flash_cache_clear_command() */ +static uint8_t s_flashCacheClearCommand[kFLASH_executeInRamFunctionMaxSize]; +/*! @brief Flash execute-in-ram function information */ +static flash_execute_in_ram_function_config_t s_flashExecuteInRamFunctionInfo; +#endif + +/*! + * @brief Table of pflash sizes. + * + * The index into this table is the value of the SIM_FCFG1.PFSIZE bitfield. + * + * The values in this table have been right shifted 10 bits so that they will all fit within + * an 16-bit integer. To get the actual flash density, you must left shift the looked up value + * by 10 bits. + * + * Elements of this table have a value of 0 in cases where the PFSIZE bitfield value is + * reserved. + * + * Code to use the table: + * @code + * uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT; + * flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; + * @endcode + */ +const uint16_t kPFlashDensities[] = { + 8, /* 0x0 - 8192, 8KB */ + 16, /* 0x1 - 16384, 16KB */ + 24, /* 0x2 - 24576, 24KB */ + 32, /* 0x3 - 32768, 32KB */ + 48, /* 0x4 - 49152, 48KB */ + 64, /* 0x5 - 65536, 64KB */ + 96, /* 0x6 - 98304, 96KB */ + 128, /* 0x7 - 131072, 128KB */ + 192, /* 0x8 - 196608, 192KB */ + 256, /* 0x9 - 262144, 256KB */ + 384, /* 0xa - 393216, 384KB */ + 512, /* 0xb - 524288, 512KB */ + 768, /* 0xc - 786432, 768KB */ + 1024, /* 0xd - 1048576, 1MB */ + 1536, /* 0xe - 1572864, 1.5MB */ + /* 2048, 0xf - 2097152, 2MB */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t FLASH_Init(flash_config_t *config) +{ + uint32_t flashDensity; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* calculate the flash density from SIM_FCFG1.PFSIZE */ + uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT; + /* PFSIZE=0xf means that on customer parts the IFR was not correctly programmed. + * We just use the pre-defined flash size in feature file here to support pre-production parts */ + if (pfsize == 0xf) + { + flashDensity = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE; + } + else + { + flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; + } + + /* fill out a few of the structure members */ + config->PFlashBlockBase = PFLASH_BLOCK_BASE; + config->PFlashTotalSize = flashDensity; + config->PFlashBlockCount = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; + config->PFlashSectorSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE; + +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL + config->PFlashAccessSegmentSize = kFLASH_accessSegmentBase << FTFx->FACSS; + config->PFlashAccessSegmentCount = FTFx->FACSN; +#else + config->PFlashAccessSegmentSize = 0; + config->PFlashAccessSegmentCount = 0; +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + + config->PFlashCallback = NULL; + +/* copy required flash commands to RAM */ +#if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED) + if (kStatus_FLASH_Success != flash_check_execute_in_ram_function_info(config)) + { + s_flashExecuteInRamFunctionInfo.activeFunctionCount = 0; + s_flashExecuteInRamFunctionInfo.flashRunCommand = s_flashRunCommand; + s_flashExecuteInRamFunctionInfo.flashCacheClearCommand = s_flashCacheClearCommand; + config->flashExecuteInRamFunctionInfo = &s_flashExecuteInRamFunctionInfo.activeFunctionCount; + FLASH_PrepareExecuteInRamFunctions(config); + } +#endif + + config->FlexRAMBlockBase = FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS; + config->FlexRAMTotalSize = FSL_FEATURE_FLASH_FLEX_RAM_SIZE; + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + { + status_t returnCode; + config->DFlashBlockBase = FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS; + returnCode = flash_update_flexnvm_memory_partition_status(config); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + } +#endif + + return kStatus_FLASH_Success; +} + +status_t FLASH_SetCallback(flash_config_t *config, flash_callback_t callback) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + config->PFlashCallback = callback; + + return kStatus_FLASH_Success; +} + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +status_t FLASH_PrepareExecuteInRamFunctions(flash_config_t *config) +{ + flash_execute_in_ram_function_config_t *flashExecuteInRamFunctionInfo; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo; + + copy_flash_run_command(flashExecuteInRamFunctionInfo->flashRunCommand); + copy_flash_cache_clear_command(flashExecuteInRamFunctionInfo->flashCacheClearCommand); + flashExecuteInRamFunctionInfo->activeFunctionCount = kFLASH_executeInRamFunctionTotalNum; + + return kStatus_FLASH_Success; +} +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +status_t FLASH_EraseAll(flash_config_t *config, uint32_t key) +{ + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* preparing passing parameter to erase all flash blocks */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_BLOCK, 0xFFFFFFU); + + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + /* Data flash IFR will be erased by erase all command, so we need to + * update FlexNVM memory partition status synchronously */ + if (returnCode == kStatus_FLASH_Success) + { + returnCode = flash_update_flexnvm_memory_partition_status(config); + } +#endif + + return returnCode; +} + +status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key) +{ + uint32_t sectorSize; + flash_operation_config_t flashInfo; + uint32_t endAddress; /* storing end address */ + uint32_t numberOfSectors; /* number of sectors calculated by endAddress */ + status_t returnCode; + + flash_get_matched_operation_info(config, start, &flashInfo); + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectorCmdAddressAligment); + if (returnCode) + { + return returnCode; + } + + start = flashInfo.convertedAddress; + sectorSize = flashInfo.activeSectorSize; + + /* calculating Flash end address */ + endAddress = start + lengthInBytes - 1; + + /* re-calculate the endAddress and align it to the start of the next sector + * which will be used in the comparison below */ + if (endAddress % sectorSize) + { + numberOfSectors = endAddress / sectorSize + 1; + endAddress = numberOfSectors * sectorSize - 1; + } + + /* the start address will increment to the next sector address + * until it reaches the endAdddress */ + while (start <= endAddress) + { + /* preparing passing parameter to erase a flash block */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_SECTOR, start); + + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + /* calling flash callback function if it is available */ + if (config->PFlashCallback) + { + config->PFlashCallback(); + } + + /* checking the success of command execution */ + if (kStatus_FLASH_Success != returnCode) + { + break; + } + else + { + /* Increment to the next sector */ + start += sectorSize; + } + } + + flash_cache_clear(config); + + return (returnCode); +} + +#if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD +status_t FLASH_EraseAllUnsecure(flash_config_t *config, uint32_t key) +{ + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Prepare passing parameter to erase all flash blocks (unsecure). */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_BLOCK_UNSECURE, 0xFFFFFFU); + + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + /* Data flash IFR will be erased by erase all unsecure command, so we need to + * update FlexNVM memory partition status synchronously */ + if (returnCode == kStatus_FLASH_Success) + { + returnCode = flash_update_flexnvm_memory_partition_status(config); + } +#endif + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */ + +status_t FLASH_EraseAllExecuteOnlySegments(flash_config_t *config, uint32_t key) +{ + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* preparing passing parameter to erase all execute-only segments + * 1st element for the FCCOB register */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT, 0xFFFFFFU); + + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + + return returnCode; +} + +status_t FLASH_Program(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes) +{ + status_t returnCode; + flash_operation_config_t flashInfo; + + if (src == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flash_get_matched_operation_info(config, start, &flashInfo); + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.blockWriteUnitSize); + if (returnCode) + { + return returnCode; + } + + start = flashInfo.convertedAddress; + + while (lengthInBytes > 0) + { + /* preparing passing parameter to program the flash block */ + kFCCOBx[1] = *src++; + if (4 == flashInfo.blockWriteUnitSize) + { + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_LONGWORD, start); + } + else if (8 == flashInfo.blockWriteUnitSize) + { + kFCCOBx[2] = *src++; + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_PHRASE, start); + } + else + { + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + /* calling flash callback function if it is available */ + if (config->PFlashCallback) + { + config->PFlashCallback(); + } + + /* checking for the success of command execution */ + if (kStatus_FLASH_Success != returnCode) + { + break; + } + else + { + /* update start address for next iteration */ + start += flashInfo.blockWriteUnitSize; + + /* update lengthInBytes for next iteration */ + lengthInBytes -= flashInfo.blockWriteUnitSize; + } + } + + flash_cache_clear(config); + + return (returnCode); +} + +status_t FLASH_ProgramOnce(flash_config_t *config, uint32_t index, uint32_t *src, uint32_t lengthInBytes) +{ + status_t returnCode; + + if ((config == NULL) || (src == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + /* pass paramters to FTFx */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_PROGRAM_ONCE, index, 0xFFFFU); + + kFCCOBx[1] = *src; + +/* Note: Have to seperate the first index from the rest if it equals 0 + * to avoid a pointless comparison of unsigned int to 0 compiler warning */ +#if FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT +#if FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT + if (((index == FLASH_PROGRAM_ONCE_MIN_ID_8BYTES) || + /* Range check */ + ((index >= FLASH_PROGRAM_ONCE_MIN_ID_8BYTES + 1) && (index <= FLASH_PROGRAM_ONCE_MAX_ID_8BYTES))) && + (lengthInBytes == 8)) +#endif /* FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT */ + { + kFCCOBx[2] = *(src + 1); + } +#endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */ + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + + return returnCode; +} + +#if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD +status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes) +{ + status_t returnCode; + uint32_t sectorSize; + flash_operation_config_t flashInfo; +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD + bool needSwitchFlexRamMode = false; +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + + if (src == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flash_get_matched_operation_info(config, start, &flashInfo); + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectionCmdAddressAligment); + if (returnCode) + { + return returnCode; + } + + start = flashInfo.convertedAddress; + sectorSize = flashInfo.activeSectorSize; + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD + /* Switch function of FlexRAM if needed */ + if (!(FTFx->FCNFG & FTFx_FCNFG_RAMRDY_MASK)) + { + needSwitchFlexRamMode = true; + + returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableAsRam); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_SetFlexramAsRamError; + } + } +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + + while (lengthInBytes > 0) + { + /* Make sure the write operation doesn't span two sectors */ + uint32_t endAddressOfCurrentSector = ALIGN_UP(start, sectorSize); + uint32_t lengthTobeProgrammedOfCurrentSector; + uint32_t currentOffset = 0; + + if (endAddressOfCurrentSector == start) + { + endAddressOfCurrentSector += sectorSize; + } + + if (lengthInBytes + start > endAddressOfCurrentSector) + { + lengthTobeProgrammedOfCurrentSector = endAddressOfCurrentSector - start; + } + else + { + lengthTobeProgrammedOfCurrentSector = lengthInBytes; + } + + /* Program Current Sector */ + while (lengthTobeProgrammedOfCurrentSector > 0) + { + /* Make sure the program size doesn't exceeds Acceleration RAM size */ + uint32_t programSizeOfCurrentPass; + uint32_t numberOfPhases; + + if (lengthTobeProgrammedOfCurrentSector > kFLASH_accelerationRamSize) + { + programSizeOfCurrentPass = kFLASH_accelerationRamSize; + } + else + { + programSizeOfCurrentPass = lengthTobeProgrammedOfCurrentSector; + } + + /* Copy data to FlexRAM */ + memcpy((void *)FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS, src + currentOffset / 4, programSizeOfCurrentPass); + /* Set start address of the data to be programmed */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_SECTION, start + currentOffset); + /* Set program size in terms of FEATURE_FLASH_SECTION_CMD_ADDRESS_ALIGMENT */ + numberOfPhases = programSizeOfCurrentPass / flashInfo.sectionCmdAddressAligment; + + kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_2(numberOfPhases, 0xFFFFU); + + /* Peform command sequence */ + returnCode = flash_command_sequence(config); + + /* calling flash callback function if it is available */ + if (config->PFlashCallback) + { + config->PFlashCallback(); + } + + if (returnCode != kStatus_FLASH_Success) + { + flash_cache_clear(config); + return returnCode; + } + + lengthTobeProgrammedOfCurrentSector -= programSizeOfCurrentPass; + currentOffset += programSizeOfCurrentPass; + } + + src += currentOffset / 4; + start += currentOffset; + lengthInBytes -= currentOffset; + } + + flash_cache_clear(config); + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD + /* Restore function of FlexRAM if needed. */ + if (needSwitchFlexRamMode) + { + returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableForEeprom); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_RecoverFlexramAsEepromError; + } + } +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */ + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromWrite(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes) +{ + status_t returnCode; + bool needSwitchFlexRamMode = false; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Validates the range of the given address */ + if ((start < config->FlexRAMBlockBase) || + ((start + lengthInBytes) > (config->FlexRAMBlockBase + config->EEpromTotalSize))) + { + return kStatus_FLASH_AddressError; + } + + returnCode = kStatus_FLASH_Success; + + /* Switch function of FlexRAM if needed */ + if (!(FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK)) + { + needSwitchFlexRamMode = true; + + returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableForEeprom); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_SetFlexramAsEepromError; + } + } + + /* Write data to FlexRAM when it is used as EEPROM emulator */ + while (lengthInBytes > 0) + { + if ((!(start & 0x3U)) && (lengthInBytes >= 4)) + { + *(uint32_t *)start = *(uint32_t *)src; + start += 4; + src += 4; + lengthInBytes -= 4; + } + else if ((!(start & 0x1U)) && (lengthInBytes >= 2)) + { + *(uint16_t *)start = *(uint16_t *)src; + start += 2; + src += 2; + lengthInBytes -= 2; + } + else + { + *(uint8_t *)start = *src; + start += 1; + src += 1; + lengthInBytes -= 1; + } + /* Wait till EEERDY bit is set */ + while (!(FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK)) + { + } + + /* Check for protection violation error */ + if (FTFx->FSTAT & FTFx_FSTAT_FPVIOL_MASK) + { + return kStatus_FLASH_ProtectionViolation; + } + } + + /* Switch function of FlexRAM if needed */ + if (needSwitchFlexRamMode) + { + returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableAsRam); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_RecoverFlexramAsRamError; + } + } + + return returnCode; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD +status_t FLASH_ReadResource( + flash_config_t *config, uint32_t start, uint32_t *dst, uint32_t lengthInBytes, flash_read_resource_option_t option) +{ + status_t returnCode; + flash_operation_config_t flashInfo; + + if ((config == NULL) || (dst == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + flash_get_matched_operation_info(config, start, &flashInfo); + + /* Check the supplied address range. */ + returnCode = flash_check_resource_range(start, lengthInBytes, flashInfo.resourceCmdAddressAligment, option); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + + while (lengthInBytes > 0) + { + /* preparing passing parameter */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_READ_RESOURCE, start); + if (flashInfo.resourceCmdAddressAligment == 4) + { + kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); + } + else if (flashInfo.resourceCmdAddressAligment == 8) + { + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); + } + else + { + } + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + if (kStatus_FLASH_Success != returnCode) + { + break; + } + + /* fetch data */ + *dst++ = kFCCOBx[1]; + if (flashInfo.resourceCmdAddressAligment == 8) + { + *dst++ = kFCCOBx[2]; + } + /* update start address for next iteration */ + start += flashInfo.resourceCmdAddressAligment; + /* update lengthInBytes for next iteration */ + lengthInBytes -= flashInfo.resourceCmdAddressAligment; + } + + return (returnCode); +} +#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ + +status_t FLASH_ReadOnce(flash_config_t *config, uint32_t index, uint32_t *dst, uint32_t lengthInBytes) +{ + status_t returnCode; + + if ((config == NULL) || (dst == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + /* pass paramters to FTFx */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_READ_ONCE, index, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + if (kStatus_FLASH_Success == returnCode) + { + *dst = kFCCOBx[1]; +/* Note: Have to seperate the first index from the rest if it equals 0 + * to avoid a pointless comparison of unsigned int to 0 compiler warning */ +#if FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT +#if FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT + if (((index == FLASH_PROGRAM_ONCE_MIN_ID_8BYTES) || + /* Range check */ + ((index >= FLASH_PROGRAM_ONCE_MIN_ID_8BYTES + 1) && (index <= FLASH_PROGRAM_ONCE_MAX_ID_8BYTES))) && + (lengthInBytes == 8)) +#endif /* FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT */ + { + *(dst + 1) = kFCCOBx[2]; + } +#endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */ + } + + return returnCode; +} + +status_t FLASH_GetSecurityState(flash_config_t *config, flash_security_state_t *state) +{ + /* store data read from flash register */ + uint8_t registerValue; + + if ((config == NULL) || (state == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Get flash security register value */ + registerValue = FTFx->FSEC; + + /* check the status of the flash security bits in the security register */ + if (FLASH_SECURITY_STATE_UNSECURED == (registerValue & FTFx_FSEC_SEC_MASK)) + { + /* Flash in unsecured state */ + *state = kFLASH_securityStateNotSecure; + } + else + { + /* Flash in secured state + * check for backdoor key security enable bit */ + if (FLASH_SECURITY_STATE_KEYEN == (registerValue & FTFx_FSEC_KEYEN_MASK)) + { + /* Backdoor key security enabled */ + *state = kFLASH_securityStateBackdoorEnabled; + } + else + { + /* Backdoor key security disabled */ + *state = kFLASH_securityStateBackdoorDisabled; + } + } + + return (kStatus_FLASH_Success); +} + +status_t FLASH_SecurityBypass(flash_config_t *config, const uint8_t *backdoorKey) +{ + uint8_t registerValue; /* registerValue */ + status_t returnCode; /* return code variable */ + + if ((config == NULL) || (backdoorKey == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + /* set the default return code as kStatus_Success */ + returnCode = kStatus_FLASH_Success; + + /* Get flash security register value */ + registerValue = FTFx->FSEC; + + /* Check to see if flash is in secure state (any state other than 0x2) + * If not, then skip this since flash is not secure */ + if (0x02 != (registerValue & 0x03)) + { + /* preparing passing parameter to erase a flash block */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_SECURITY_BY_PASS, 0xFFFFFFU); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_1_1(backdoorKey[0], backdoorKey[1], backdoorKey[2], backdoorKey[3]); + kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_1_1_1(backdoorKey[4], backdoorKey[5], backdoorKey[6], backdoorKey[7]); + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + } + + return (returnCode); +} + +status_t FLASH_VerifyEraseAll(flash_config_t *config, flash_margin_value_t margin) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* preparing passing parameter to verify all block command */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_VERIFY_ALL_BLOCK, margin, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + return flash_command_sequence(config); +} + +status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, flash_margin_value_t margin) +{ + /* Check arguments. */ + uint32_t blockSize; + flash_operation_config_t flashInfo; + uint32_t nextBlockStartAddress; + uint32_t remainingBytes; + status_t returnCode; + + flash_get_matched_operation_info(config, start, &flashInfo); + + returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectionCmdAddressAligment); + if (returnCode) + { + return returnCode; + } + + flash_get_matched_operation_info(config, start, &flashInfo); + start = flashInfo.convertedAddress; + blockSize = flashInfo.activeBlockSize; + + nextBlockStartAddress = ALIGN_UP(start, blockSize); + if (nextBlockStartAddress == start) + { + nextBlockStartAddress += blockSize; + } + + remainingBytes = lengthInBytes; + + while (remainingBytes) + { + uint32_t numberOfPhrases; + uint32_t verifyLength = nextBlockStartAddress - start; + if (verifyLength > remainingBytes) + { + verifyLength = remainingBytes; + } + + numberOfPhrases = verifyLength / flashInfo.sectionCmdAddressAligment; + + /* Fill in verify section command parameters. */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_VERIFY_SECTION, start); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_1_1(numberOfPhrases, margin, 0xFFU); + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + if (returnCode) + { + return returnCode; + } + + remainingBytes -= verifyLength; + start += verifyLength; + nextBlockStartAddress += blockSize; + } + + return kStatus_FLASH_Success; +} + +status_t FLASH_VerifyProgram(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + const uint32_t *expectedData, + flash_margin_value_t margin, + uint32_t *failedAddress, + uint32_t *failedData) +{ + status_t returnCode; + flash_operation_config_t flashInfo; + + if (expectedData == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flash_get_matched_operation_info(config, start, &flashInfo); + + returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.checkCmdAddressAligment); + if (returnCode) + { + return returnCode; + } + + start = flashInfo.convertedAddress; + + while (lengthInBytes) + { + /* preparing passing parameter to program check the flash block */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_CHECK, start); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(margin, 0xFFFFFFU); + kFCCOBx[2] = *expectedData; + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + /* checking for the success of command execution */ + if (kStatus_FLASH_Success != returnCode) + { + if (failedAddress) + { + *failedAddress = start; + } + if (failedData) + { + *failedData = 0; + } + break; + } + + lengthInBytes -= flashInfo.checkCmdAddressAligment; + expectedData += flashInfo.checkCmdAddressAligment / sizeof(*expectedData); + start += flashInfo.checkCmdAddressAligment; + } + + return (returnCode); +} + +status_t FLASH_VerifyEraseAllExecuteOnlySegments(flash_config_t *config, flash_margin_value_t margin) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* preparing passing parameter to verify erase all execute-only segments command */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT, margin, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + return flash_command_sequence(config); +} + +status_t FLASH_IsProtected(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + flash_protection_state_t *protection_state) +{ + uint32_t endAddress; /* end address for protection check */ + uint32_t protectionRegionSize; /* size of flash protection region */ + uint32_t regionCheckedCounter; /* increments each time the flash address was checked for + * protection status */ + uint32_t regionCounter; /* incrementing variable used to increment through the flash + * protection regions */ + uint32_t protectStatusCounter; /* increments each time a flash region was detected as protected */ + + uint8_t flashRegionProtectStatus[FSL_FEATURE_FTFx_REGION_COUNT]; /* array of the protection status for each + * protection region */ + uint32_t flashRegionAddress[FSL_FEATURE_FTFx_REGION_COUNT + 1]; /* array of the start addresses for each flash + * protection region. Note this is REGION_COUNT+1 + * due to requiring the next start address after + * the end of flash for loop-check purposes below */ + status_t returnCode; + + if (protection_state == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE); + if (returnCode) + { + return returnCode; + } + + /* calculating Flash end address */ + endAddress = start + lengthInBytes; + + /* Calculate the size of the flash protection region + * If the flash density is > 32KB, then protection region is 1/32 of total flash density + * Else if flash density is < 32KB, then flash protection region is set to 1KB */ + if (config->PFlashTotalSize > 32 * 1024) + { + protectionRegionSize = (config->PFlashTotalSize) / FSL_FEATURE_FTFx_REGION_COUNT; + } + else + { + protectionRegionSize = 1024; + } + + /* populate the flashRegionAddress array with the start address of each flash region */ + regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ + + /* populate up to 33rd element of array, this is the next address after end of flash array */ + while (regionCounter <= FSL_FEATURE_FTFx_REGION_COUNT) + { + flashRegionAddress[regionCounter] = config->PFlashBlockBase + protectionRegionSize * regionCounter; + regionCounter++; + } + + /* populate flashRegionProtectStatus array with status information + * Protection status for each region is stored in the FPROT[3:0] registers + * Each bit represents one region of flash + * 4 registers * 8-bits-per-register = 32-bits (32-regions) + * The convention is: + * FPROT3[bit 0] is the first protection region (start of flash memory) + * FPROT0[bit 7] is the last protection region (end of flash memory) + * regionCounter is used to determine which FPROT[3:0] register to check for protection status + * Note: FPROT=1 means NOT protected, FPROT=0 means protected */ + regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ + while (regionCounter < FSL_FEATURE_FTFx_REGION_COUNT) + { + if (regionCounter < 8) + { + flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT3) >> regionCounter) & (0x01u); + } + else if ((regionCounter >= 8) && (regionCounter < 16)) + { + flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT2) >> (regionCounter - 8)) & (0x01u); + } + else if ((regionCounter >= 16) && (regionCounter < 24)) + { + flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT1) >> (regionCounter - 16)) & (0x01u); + } + else + { + flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT0) >> (regionCounter - 24)) & (0x01u); + } + regionCounter++; + } + + /* loop through the flash regions and check + * desired flash address range for protection status + * loop stops when it is detected that start has exceeded the endAddress */ + regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ + regionCheckedCounter = 0; + protectStatusCounter = 0; /* make sure protectStatusCounter is initialized to 0 first */ + while (start < endAddress) + { + /* check to see if the address falls within this protection region + * Note that if the entire flash is to be checked, the last protection + * region checked would consist of the last protection start address and + * the start address following the end of flash */ + if ((start >= flashRegionAddress[regionCounter]) && (start < flashRegionAddress[regionCounter + 1])) + { + /* increment regionCheckedCounter to indicate this region was checked */ + regionCheckedCounter++; + + /* check the protection status of this region + * Note: FPROT=1 means NOT protected, FPROT=0 means protected */ + if (!flashRegionProtectStatus[regionCounter]) + { + /* increment protectStatusCounter to indicate this region is protected */ + protectStatusCounter++; + } + start += protectionRegionSize; /* increment to an address within the next region */ + } + regionCounter++; /* increment regionCounter to check for the next flash protection region */ + } + + /* if protectStatusCounter == 0, then no region of the desired flash region is protected */ + if (protectStatusCounter == 0) + { + *protection_state = kFLASH_protectionStateUnprotected; + } + /* if protectStatusCounter == regionCheckedCounter, then each region checked was protected */ + else if (protectStatusCounter == regionCheckedCounter) + { + *protection_state = kFLASH_protectionStateProtected; + } + /* if protectStatusCounter != regionCheckedCounter, then protection status is mixed + * In other words, some regions are protected while others are unprotected */ + else + { + *protection_state = kFLASH_protectionStateMixed; + } + + return (returnCode); +} + +status_t FLASH_IsExecuteOnly(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + flash_execute_only_access_state_t *access_state) +{ + status_t returnCode; + + if (access_state == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Check the supplied address range. */ + returnCode = flash_check_range(config, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE); + if (returnCode) + { + return returnCode; + } + +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL + { + uint32_t executeOnlySegmentCounter = 0; + + /* calculating end address */ + uint32_t endAddress = start + lengthInBytes; + + /* Aligning start address and end address */ + uint32_t alignedStartAddress = ALIGN_DOWN(start, config->PFlashAccessSegmentSize); + uint32_t alignedEndAddress = ALIGN_UP(endAddress, config->PFlashAccessSegmentSize); + + uint32_t segmentIndex = 0; + uint32_t maxSupportedExecuteOnlySegmentCount = + (alignedEndAddress - alignedStartAddress) / config->PFlashAccessSegmentSize; + + while (start < endAddress) + { + uint32_t xacc; + + segmentIndex = start / config->PFlashAccessSegmentSize; + + if (segmentIndex < 32) + { + xacc = *(const volatile uint32_t *)&FTFx->XACCL3; + } + else if (segmentIndex < config->PFlashAccessSegmentCount) + { + xacc = *(const volatile uint32_t *)&FTFx->XACCH3; + segmentIndex -= 32; + } + else + { + break; + } + + /* Determine if this address range is in a execute-only protection flash segment. */ + if ((~xacc) & (1u << segmentIndex)) + { + executeOnlySegmentCounter++; + } + + start += config->PFlashAccessSegmentSize; + } + + if (executeOnlySegmentCounter < 1u) + { + *access_state = kFLASH_accessStateUnLimited; + } + else if (executeOnlySegmentCounter < maxSupportedExecuteOnlySegmentCount) + { + *access_state = kFLASH_accessStateMixed; + } + else + { + *access_state = kFLASH_accessStateExecuteOnly; + } + } +#else + *access_state = kFLASH_accessStateUnLimited; +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + + return (returnCode); +} + +status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value) +{ + if ((config == NULL) || (value == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + switch (whichProperty) + { + case kFLASH_propertyPflashSectorSize: + *value = config->PFlashSectorSize; + break; + + case kFLASH_propertyPflashTotalSize: + *value = config->PFlashTotalSize; + break; + + case kFLASH_propertyPflashBlockSize: + *value = config->PFlashTotalSize / FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; + break; + + case kFLASH_propertyPflashBlockCount: + *value = config->PFlashBlockCount; + break; + + case kFLASH_propertyPflashBlockBaseAddr: + *value = config->PFlashBlockBase; + break; + + case kFLASH_propertyPflashFacSupport: +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) + *value = FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL; +#else + *value = 0; +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + break; + + case kFLASH_propertyPflashAccessSegmentSize: + *value = config->PFlashAccessSegmentSize; + break; + + case kFLASH_propertyPflashAccessSegmentCount: + *value = config->PFlashAccessSegmentCount; + break; + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + case kFLASH_propertyDflashSectorSize: + *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; + break; + case kFLASH_propertyDflashTotalSize: + *value = config->DFlashTotalSize; + break; + case kFLASH_propertyDflashBlockSize: + *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE; + break; + case kFLASH_propertyDflashBlockCount: + *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; + break; + case kFLASH_propertyDflashBlockBaseAddr: + *value = config->DFlashBlockBase; + break; + case kFLASH_propertyEepromTotalSize: + *value = config->EEpromTotalSize; + break; +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + + default: /* catch inputs that are not recognized */ + return kStatus_FLASH_UnknownProperty; + } + + return kStatus_FLASH_Success; +} + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD +status_t FLASH_SetFlexramFunction(flash_config_t *config, flash_flexram_function_option_t option) +{ + status_t status; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + status = flasn_check_flexram_function_option_range(option); + if (status != kStatus_FLASH_Success) + { + return status; + } + + /* preparing passing parameter to verify all block command */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_SET_FLEXRAM_FUNCTION, option, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + return flash_command_sequence(config); +} +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD +status_t FLASH_SwapControl(flash_config_t *config, + uint32_t address, + flash_swap_control_option_t option, + flash_swap_state_config_t *returnInfo) +{ + status_t returnCode; + + if ((config == NULL) || (returnInfo == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + if (address & (FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT - 1)) + { + return kStatus_FLASH_AlignmentError; + } + + /* Make sure address provided is in the lower half of Program flash but not in the Flash Configuration Field */ + if ((address >= (config->PFlashTotalSize / 2)) || + ((address >= kFLASH_configAreaStart) && (address <= kFLASH_configAreaEnd))) + { + return kStatus_FLASH_SwapIndicatorAddressError; + } + + /* Check the option. */ + returnCode = flash_check_swap_control_option(option); + if (returnCode) + { + return returnCode; + } + + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_SWAP_CONTROL, address); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); + + returnCode = flash_command_sequence(config); + + returnInfo->flashSwapState = (flash_swap_state_t)FTFx->FCCOB5; + returnInfo->currentSwapBlockStatus = (flash_swap_block_status_t)FTFx->FCCOB6; + returnInfo->nextSwapBlockStatus = (flash_swap_block_status_t)FTFx->FCCOB7; + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP +status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_function_option_t option) +{ + flash_swap_state_config_t returnInfo; + status_t returnCode; + + memset(&returnInfo, 0xFFU, sizeof(returnInfo)); + + do + { + returnCode = FLASH_SwapControl(config, address, kFLASH_swapControlOptionReportStatus, &returnInfo); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + + if (kFLASH_swapFunctionOptionDisable == option) + { + if (returnInfo.flashSwapState == kFLASH_swapStateDisabled) + { + return kStatus_FLASH_Success; + } + else if (returnInfo.flashSwapState == kFLASH_swapStateUninitialized) + { + /* The swap system changed to the DISABLED state with Program flash block 0 + * located at relative flash address 0x0_0000 */ + returnCode = FLASH_SwapControl(config, address, kFLASH_swapControlOptionDisableSystem, &returnInfo); + } + else + { + /* Swap disable should be requested only when swap system is in the uninitialized state */ + return kStatus_FLASH_SwapSystemNotInUninitialized; + } + } + else + { + /* When first swap: the initial swap state is Uninitialized, flash swap inidicator address is unset, + * the swap procedure should be Uninitialized -> Update-Erased -> Complete. + * After the first swap has been completed, the flash swap inidicator address cannot be modified + * unless EraseAllBlocks command is issued, the swap procedure is changed to Update -> Update-Erased -> + * Complete. */ + switch (returnInfo.flashSwapState) + { + case kFLASH_swapStateUninitialized: + /* If current swap mode is Uninitialized, Initialize Swap to Initialized/READY state. */ + returnCode = + FLASH_SwapControl(config, address, kFLASH_swapControlOptionIntializeSystem, &returnInfo); + break; + case kFLASH_swapStateReady: + /* Validate whether the address provided to the swap system is matched to + * swap indicator address in the IFR */ + returnCode = flash_validate_swap_indicator_address(config, address); + if (returnCode == kStatus_FLASH_Success) + { + /* If current swap mode is Initialized/Ready, Initialize Swap to UPDATE state. */ + returnCode = + FLASH_SwapControl(config, address, kFLASH_swapControlOptionSetInUpdateState, &returnInfo); + } + break; + case kFLASH_swapStateUpdate: + /* If current swap mode is Update, Erase indicator sector in non active block + * to proceed swap system to update-erased state */ + returnCode = FLASH_Erase(config, address + (config->PFlashTotalSize >> 1), + FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT, kFLASH_apiEraseKey); + break; + case kFLASH_swapStateUpdateErased: + /* If current swap mode is Update or Update-Erased, progress Swap to COMPLETE State */ + returnCode = + FLASH_SwapControl(config, address, kFLASH_swapControlOptionSetInCompleteState, &returnInfo); + break; + case kFLASH_swapStateComplete: + break; + case kFLASH_swapStateDisabled: + /* When swap system is in disabled state, We need to clear swap system back to uninitialized + * by issuing EraseAllBlocks command */ + returnCode = kStatus_FLASH_SwapSystemNotInUninitialized; + break; + default: + returnCode = kStatus_FLASH_InvalidArgument; + break; + } + } + if (returnCode != kStatus_FLASH_Success) + { + break; + } + } while (!((kFLASH_swapStateComplete == returnInfo.flashSwapState) && (kFLASH_swapFunctionOptionEnable == option))); + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ + +#if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD +status_t FLASH_ProgramPartition(flash_config_t *config, + flash_partition_flexram_load_option_t option, + uint32_t eepromDataSizeCode, + uint32_t flexnvmPartitionCode) +{ + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* eepromDataSizeCode[7:6], flexnvmPartitionCode[7:4] should be all 1'b0 + * or it will cause access error. */ + /* eepromDataSizeCode &= 0x3FU; */ + /* flexnvmPartitionCode &= 0x0FU; */ + + /* preparing passing parameter to program the flash block */ + kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_2_1(FTFx_PROGRAM_PARTITION, 0xFFFFU, option); + kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_2(eepromDataSizeCode, flexnvmPartitionCode, 0xFFFFU); + + /* calling flash command sequence function to execute the command */ + returnCode = flash_command_sequence(config); + + flash_cache_clear(config); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + /* Data flash IFR will be updated by program partition command during reset sequence, + * so we just set reserved values for partitioned FlexNVM size here */ + config->EEpromTotalSize = FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED; + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif + + return (returnCode); +} +#endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD */ + +status_t FLASH_PflashSetProtection(flash_config_t *config, uint32_t protectStatus) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + *kFPROT = protectStatus; + + if (protectStatus != *kFPROT) + { + return kStatus_FLASH_CommandFailure; + } + + return kStatus_FLASH_Success; +} + +status_t FLASH_PflashGetProtection(flash_config_t *config, uint32_t *protectStatus) +{ + if ((config == NULL) || (protectStatus == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + *protectStatus = *kFPROT; + + return kStatus_FLASH_Success; +} + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_DflashSetProtection(flash_config_t *config, uint8_t protectStatus) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + if ((config->DFlashTotalSize == 0) || (config->DFlashTotalSize == FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED)) + { + return kStatus_FLASH_CommandNotSupported; + } + + FTFx->FDPROT = protectStatus; + + if (FTFx->FDPROT != protectStatus) + { + return kStatus_FLASH_CommandFailure; + } + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_DflashGetProtection(flash_config_t *config, uint8_t *protectStatus) +{ + if ((config == NULL) || (protectStatus == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + if ((config->DFlashTotalSize == 0) || (config->DFlashTotalSize == FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED)) + { + return kStatus_FLASH_CommandNotSupported; + } + + *protectStatus = FTFx->FDPROT; + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromSetProtection(flash_config_t *config, uint8_t protectStatus) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + if ((config->EEpromTotalSize == 0) || (config->EEpromTotalSize == FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED)) + { + return kStatus_FLASH_CommandNotSupported; + } + + FTFx->FEPROT = protectStatus; + + if (FTFx->FEPROT != protectStatus) + { + return kStatus_FLASH_CommandFailure; + } + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromGetProtection(flash_config_t *config, uint8_t *protectStatus) +{ + if ((config == NULL) || (protectStatus == NULL)) + { + return kStatus_FLASH_InvalidArgument; + } + + if ((config->EEpromTotalSize == 0) || (config->EEpromTotalSize == FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED)) + { + return kStatus_FLASH_CommandNotSupported; + } + + *protectStatus = FTFx->FEPROT; + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! + * @brief Run flash command + * + * This function should be copied to RAM for execution to make sure that code works + * properly even flash cache is disabled. + * It is for flash-resident bootloader only, not technically required for ROM or + * flashloader (RAM-resident bootloader). + */ +void flash_run_command(FTFx_REG_ACCESS_TYPE ftfx_fstat) +{ + /* clear CCIF bit */ + *ftfx_fstat = FTFx_FSTAT_CCIF_MASK; + + /* Check CCIF bit of the flash status register, wait till it is set. + * IP team indicates that this loop will always complete. */ + while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK)) + { + } +} + +/*! + * @brief Be used for determining the size of flash_run_command() + * + * This function must be defined that lexically follows flash_run_command(), + * so we can determine the size of flash_run_command() at runtime and not worry + * about toolchain or code generation differences. + */ +void flash_run_command_end(void) +{ +} + +/*! + * @brief Copy flash_run_command() to RAM + * + * This function copys the memory between flash_run_command() and flash_run_command_end() + * into the buffer which is also means that copying flash_run_command() to RAM. + */ +static void copy_flash_run_command(uint8_t *flashRunCommand) +{ + /* Calculate the valid length of flash_run_command() memory. + * Set max size(64 bytes) as default function size, in case some compiler allocates + * flash_run_command_end ahead of flash_run_command. */ + uint32_t funcLength = kFLASH_executeInRamFunctionMaxSize; + uint32_t flash_run_command_start_addr = (uint32_t)flash_run_command & (~1U); + uint32_t flash_run_command_end_addr = (uint32_t)flash_run_command_end & (~1U); + if (flash_run_command_end_addr > flash_run_command_start_addr) + { + funcLength = flash_run_command_end_addr - flash_run_command_start_addr; + + assert(funcLength <= kFLASH_executeInRamFunctionMaxSize); + + /* In case some compiler allocates other function in the middle of flash_run_command + * and flash_run_command_end. */ + if (funcLength > kFLASH_executeInRamFunctionMaxSize) + { + funcLength = kFLASH_executeInRamFunctionMaxSize; + } + } + + /* Since the value of ARM function pointer is always odd, but the real start address + * of function memory should be even, that's why -1 and +1 operation exist. */ + memcpy((void *)flashRunCommand, (void *)flash_run_command_start_addr, funcLength); + callFlashRunCommand = (void (*)(FTFx_REG_ACCESS_TYPE ftfx_fstat))((uint32_t)flashRunCommand + 1); +} +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +/*! + * @brief Flash Command Sequence + * + * This function is used to perform the command write sequence to the flash. + * + * @param driver Pointer to storage for the driver runtime state. + * @return An error code or kStatus_FLASH_Success + */ +static status_t flash_command_sequence(flash_config_t *config) +{ + uint8_t registerValue; + +#if FLASH_DRIVER_IS_FLASH_RESIDENT + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ + FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; + + status_t returnCode = flash_check_execute_in_ram_function_info(config); + if (kStatus_FLASH_Success != returnCode) + { + return returnCode; + } + + /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using + * pre-processed MICRO sentences or operating global variable in flash_run_comamnd() + * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */ + callFlashRunCommand((FTFx_REG_ACCESS_TYPE)(&FTFx->FSTAT)); +#else + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ + FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; + + /* clear CCIF bit */ + FTFx->FSTAT = FTFx_FSTAT_CCIF_MASK; + + /* Check CCIF bit of the flash status register, wait till it is set. + * IP team indicates that this loop will always complete. */ + while (!(FTFx->FSTAT & FTFx_FSTAT_CCIF_MASK)) + { + } +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + + /* Check error bits */ + /* Get flash status register value */ + registerValue = FTFx->FSTAT; + + /* checking access error */ + if (registerValue & FTFx_FSTAT_ACCERR_MASK) + { + return kStatus_FLASH_AccessError; + } + /* checking protection error */ + else if (registerValue & FTFx_FSTAT_FPVIOL_MASK) + { + return kStatus_FLASH_ProtectionViolation; + } + /* checking MGSTAT0 non-correctable error */ + else if (registerValue & FTFx_FSTAT_MGSTAT0_MASK) + { + return kStatus_FLASH_CommandFailure; + } + else + { + return kStatus_FLASH_Success; + } +} + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! + * @brief Run flash cache clear command + * + * This function should be copied to RAM for execution to make sure that code works + * properly even flash cache is disabled. + * It is for flash-resident bootloader only, not technically required for ROM or + * flashloader (RAM-resident bootloader). + */ +void flash_cache_clear_command(FTFx_REG32_ACCESS_TYPE ftfx_reg) +{ +#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS + *ftfx_reg |= MCM_PLACR_CFCC_MASK; +#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS +#if defined(FMC_PFB01CR_CINV_WAY_MASK) + *ftfx_reg = (*ftfx_reg & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0); +#else + *ftfx_reg = (*ftfx_reg & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0); +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS + *ftfx_reg |= MSCM_OCMDR_OCMC1(2); + *ftfx_reg |= MSCM_OCMDR_OCMC1(1); +#else +/* #error "Unknown flash cache controller" */ +#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ + /* Memory barriers for good measure. + * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ + __ISB(); + __DSB(); +} + +/*! + * @brief Be used for determining the size of flash_cache_clear_command() + * + * This function must be defined that lexically follows flash_cache_clear_command(), + * so we can determine the size of flash_cache_clear_command() at runtime and not worry + * about toolchain or code generation differences. + */ +void flash_cache_clear_command_end(void) +{ +} + +/*! + * @brief Copy flash_cache_clear_command() to RAM + * + * This function copys the memory between flash_cache_clear_command() and flash_cache_clear_command_end() + * into the buffer which is also means that copying flash_cache_clear_command() to RAM. + */ +static void copy_flash_cache_clear_command(uint8_t *flashCacheClearCommand) +{ + /* Calculate the valid length of flash_cache_clear_command() memory. + * Set max size(64 bytes) as default function size, in case some compiler allocates + * flash_cache_clear_command_end ahead of flash_cache_clear_command. */ + uint32_t funcLength = kFLASH_executeInRamFunctionMaxSize; + uint32_t flash_cache_clear_command_start_addr = (uint32_t)flash_cache_clear_command & (~1U); + uint32_t flash_cache_clear_command_end_addr = (uint32_t)flash_cache_clear_command_end & (~1U); + if (flash_cache_clear_command_end_addr > flash_cache_clear_command_start_addr) + { + funcLength = flash_cache_clear_command_end_addr - flash_cache_clear_command_start_addr; + + assert(funcLength <= kFLASH_executeInRamFunctionMaxSize); + + /* In case some compiler allocates other function in the middle of flash_cache_clear_command + * and flash_cache_clear_command_end. */ + if (funcLength > kFLASH_executeInRamFunctionMaxSize) + { + funcLength = kFLASH_executeInRamFunctionMaxSize; + } + } + + /* Since the value of ARM function pointer is always odd, but the real start address + * of function memory should be even, that's why -1 and +1 operation exist. */ + memcpy((void *)flashCacheClearCommand, (void *)flash_cache_clear_command_start_addr, funcLength); + callFlashCacheClearCommand = (void (*)(FTFx_REG32_ACCESS_TYPE ftfx_reg))((uint32_t)flashCacheClearCommand + 1); +} +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +/*! + * @brief Flash Cache Clear + * + * This function is used to perform the cache clear to the flash. + */ +#if (defined(__GNUC__)) +/* #pragma GCC push_options */ +/* #pragma GCC optimize("O0") */ +void __attribute__((optimize("O0"))) flash_cache_clear(flash_config_t *config) +#else +#if (defined(__ICCARM__)) +#pragma optimize = none +#endif +#if (defined(__CC_ARM)) +#pragma push +#pragma O0 +#endif +void flash_cache_clear(flash_config_t *config) +#endif +{ +#if FLASH_DRIVER_IS_FLASH_RESIDENT + status_t returnCode = flash_check_execute_in_ram_function_info(config); + if (kStatus_FLASH_Success != returnCode) + { + return; + } + +/* We pass the ftfx register address as a parameter to flash_cache_clear_comamnd() instead of using + * pre-processed MACROs or a global variable in flash_cache_clear_comamnd() + * to make sure that flash_cache_clear_command() will be compiled into position-independent code (PIC). */ +#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS +#if defined(MCM) + callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM->PLACR); +#endif +#if defined(MCM0) + callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM0->PLACR); +#endif +#if defined(MCM1) + callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM1->PLACR); +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS +#if defined(FMC_PFB01CR_CINV_WAY_MASK) + callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR); +#else + callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR); +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS + callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[0]); +#else + /* #error "Unknown flash cache controller" */ + /* meaningless code, just a workaround to solve warning*/ + callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)0); +#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ + +#else + +#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS +#if defined(MCM) + MCM->PLACR |= MCM_PLACR_CFCC_MASK; +#endif +#if defined(MCM0) + MCM0->PLACR |= MCM_PLACR_CFCC_MASK; +#endif +#if defined(MCM1) + MCM1->PLACR |= MCM_PLACR_CFCC_MASK; +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS +#if defined(FMC_PFB01CR_CINV_WAY_MASK) + FMC->PFB01CR = (FMC->PFB01CR & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0); +#else + FMC->PFB0CR = (FMC->PFB0CR & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0); +#endif +#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS + MSCM->OCMDR[0] |= MSCM_OCMDR_OCMC1(2); + MSCM->OCMDR[0] |= MSCM_OCMDR_OCMC1(1); +#else +/* #error "Unknown flash cache controller" */ +#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ +} +#if (defined(__CC_ARM)) +#pragma pop +#endif +#if (defined(__GNUC__)) +/* #pragma GCC pop_options */ +#endif + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! @brief Check whether flash execute-in-ram functions are ready */ +static status_t flash_check_execute_in_ram_function_info(flash_config_t *config) +{ + flash_execute_in_ram_function_config_t *flashExecuteInRamFunctionInfo; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo; + + if ((config->flashExecuteInRamFunctionInfo) && + (kFLASH_executeInRamFunctionTotalNum == flashExecuteInRamFunctionInfo->activeFunctionCount)) + { + return kStatus_FLASH_Success; + } + + return kStatus_FLASH_ExecuteInRamFunctionNotReady; +} +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + +/*! @brief Validates the range and alignment of the given address range.*/ +static status_t flash_check_range(flash_config_t *config, + uint32_t startAddress, + uint32_t lengthInBytes, + uint32_t alignmentBaseline) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Verify the start and length are alignmentBaseline aligned. */ + if ((startAddress & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1))) + { + return kStatus_FLASH_AlignmentError; + } + +/* check for valid range of the target addresses */ +#if !FLASH_SSD_IS_FLEXNVM_ENABLED + if ((startAddress < config->PFlashBlockBase) || + ((startAddress + lengthInBytes) > (config->PFlashBlockBase + config->PFlashTotalSize))) +#else + if (!(((startAddress >= config->PFlashBlockBase) && + ((startAddress + lengthInBytes) <= (config->PFlashBlockBase + config->PFlashTotalSize))) || + ((startAddress >= config->DFlashBlockBase) && + ((startAddress + lengthInBytes) <= (config->DFlashBlockBase + config->DFlashTotalSize))))) +#endif + { + return kStatus_FLASH_AddressError; + } + + return kStatus_FLASH_Success; +} + +/*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/ +static status_t flash_get_matched_operation_info(flash_config_t *config, + uint32_t address, + flash_operation_config_t *info) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Clean up info Structure*/ + memset(info, 0, sizeof(flash_operation_config_t)); + +#if FLASH_SSD_IS_FLEXNVM_ENABLED + if ((address >= config->DFlashBlockBase) && (address <= (config->DFlashBlockBase + config->DFlashTotalSize))) + { + info->convertedAddress = address - config->DFlashBlockBase + 0x800000U; + info->activeSectorSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; + info->activeBlockSize = config->DFlashTotalSize / FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; + + info->blockWriteUnitSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE; + info->sectorCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT; + info->sectionCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT; + info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT; + info->checkCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT; + } + else +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + { + info->convertedAddress = address; + info->activeSectorSize = config->PFlashSectorSize; + info->activeBlockSize = config->PFlashTotalSize / config->PFlashBlockCount; + + info->blockWriteUnitSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE; + info->sectorCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT; + info->sectionCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT; + info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT; + info->checkCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT; + } + + return kStatus_FLASH_Success; +} + +/*! @brief Validates the given user key for flash erase APIs.*/ +static status_t flash_check_user_key(uint32_t key) +{ + /* Validate the user key */ + if (key != kFLASH_apiEraseKey) + { + return kStatus_FLASH_EraseKeyError; + } + + return kStatus_FLASH_Success; +} + +#if FLASH_SSD_IS_FLEXNVM_ENABLED +/*! @brief Updates FlexNVM memory partition status according to data flash 0 IFR.*/ +static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *config) +{ + struct + { + uint32_t reserved0; + uint8_t FlexNVMPartitionCode; + uint8_t EEPROMDataSetSize; + uint16_t reserved1; + } dataIFRReadOut; + status_t returnCode; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Get FlexNVM memory partition info from data flash IFR */ + returnCode = FLASH_ReadResource(config, DFLASH_IFR_READRESOURCE_START_ADDRESS, (uint32_t *)&dataIFRReadOut, + sizeof(dataIFRReadOut), kFLASH_resourceOptionFlashIfr); + if (returnCode != kStatus_FLASH_Success) + { + return kStatus_FLASH_PartitionStatusUpdateFailure; + } + + /* Fill out partitioned EEPROM size */ + dataIFRReadOut.EEPROMDataSetSize &= 0x0FU; + switch (dataIFRReadOut.EEPROMDataSetSize) + { + case 0x00U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000; + break; + case 0x01U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001; + break; + case 0x02U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010; + break; + case 0x03U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011; + break; + case 0x04U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100; + break; + case 0x05U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101; + break; + case 0x06U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110; + break; + case 0x07U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111; + break; + case 0x08U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000; + break; + case 0x09U: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001; + break; + case 0x0AU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010; + break; + case 0x0BU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011; + break; + case 0x0CU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100; + break; + case 0x0DU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101; + break; + case 0x0EU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110; + break; + case 0x0FU: + config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111; + break; + default: + config->EEpromTotalSize = FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED; + break; + } + + /* Fill out partitioned DFlash size */ + dataIFRReadOut.FlexNVMPartitionCode &= 0x0FU; + switch (dataIFRReadOut.FlexNVMPartitionCode) + { + case 0x00U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 */ + break; + case 0x01U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 */ + break; + case 0x02U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 */ + break; + case 0x03U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 */ + break; + case 0x04U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 */ + break; + case 0x05U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 */ + break; + case 0x06U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 */ + break; + case 0x07U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 */ + break; + case 0x08U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 */ + break; + case 0x09U: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 */ + break; + case 0x0AU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 */ + break; + case 0x0BU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 */ + break; + case 0x0CU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 */ + break; + case 0x0DU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 */ + break; + case 0x0EU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 */ + break; + case 0x0FU: +#if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 != 0xFFFFFFFF) + config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111; +#else + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; +#endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 */ + break; + default: + config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED; + break; + } + + return kStatus_FLASH_Success; +} +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD +/*! @brief Validates the range of the given resource address.*/ +static status_t flash_check_resource_range(uint32_t start, + uint32_t lengthInBytes, + uint32_t alignmentBaseline, + flash_read_resource_option_t option) +{ + status_t status; + uint32_t maxReadbleAddress; + + if ((start & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1))) + { + return kStatus_FLASH_AlignmentError; + } + + status = kStatus_FLASH_Success; + + maxReadbleAddress = start + lengthInBytes - 1; + if (option == kFLASH_resourceOptionVersionId) + { + if ((start != kFLASH_resourceRangeVersionIdStart) || + ((start + lengthInBytes - 1) != kFLASH_resourceRangeVersionIdEnd)) + { + status = kStatus_FLASH_InvalidArgument; + } + } + else if (option == kFLASH_resourceOptionFlashIfr) + { + if (maxReadbleAddress < kFLASH_resourceRangePflashIfrSizeInBytes) + { + } +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP + else if ((start >= kFLASH_resourceRangePflashSwapIfrStart) && + (maxReadbleAddress <= kFLASH_resourceRangePflashSwapIfrEnd)) + { + } +#endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ + else if ((start >= kFLASH_resourceRangeDflashIfrStart) && + (maxReadbleAddress <= kFLASH_resourceRangeDflashIfrEnd)) + { + } + else + { + status = kStatus_FLASH_InvalidArgument; + } + } + else + { + status = kStatus_FLASH_InvalidArgument; + } + + return status; +} +#endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD +/*! @brief Validates the gived swap control option.*/ +static status_t flash_check_swap_control_option(flash_swap_control_option_t option) +{ + if ((option == kFLASH_swapControlOptionIntializeSystem) || (option == kFLASH_swapControlOptionSetInUpdateState) || + (option == kFLASH_swapControlOptionSetInCompleteState) || (option == kFLASH_swapControlOptionReportStatus) || + (option == kFLASH_swapControlOptionDisableSystem)) + { + return kStatus_FLASH_Success; + } + + return kStatus_FLASH_InvalidArgument; +} +#endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ + +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP +/*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/ +static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address) +{ + flash_swap_ifr_field_config_t flashSwapIfrField; + uint32_t swapIndicatorAddress; + + status_t returnCode; + returnCode = FLASH_ReadResource(config, kFLASH_resourceRangePflashSwapIfrStart, (uint32_t *)&flashSwapIfrField, + sizeof(flash_swap_ifr_field_config_t), kFLASH_resourceOptionFlashIfr); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + + /* The high 2 byte value of Swap Indicator Address is stored in Program Flash Swap IFR Field, + * the low 4 bit value of Swap Indicator Address is always 4'b0000 */ + swapIndicatorAddress = + (uint32_t)flashSwapIfrField.swapIndicatorAddress * FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT; + if (address != swapIndicatorAddress) + { + return kStatus_FLASH_SwapIndicatorAddressError; + } + + return returnCode; +} +#endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ + +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD +/*! @brief Validates the gived flexram function option.*/ +static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option) +{ + if ((option != kFLASH_flexramFunctionOptionAvailableAsRam) && + (option != kFLASH_flexramFunctionOptionAvailableForEeprom)) + { + return kStatus_FLASH_InvalidArgument; + } + + return kStatus_FLASH_Success; +} +#endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flash.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flash.h new file mode 100644 index 0000000000..63463e03cb --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flash.h @@ -0,0 +1,1177 @@ +/* + * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLASH_H_ +#define _FSL_FLASH_H_ + +#if (defined(BL_TARGET_FLASH) || defined(BL_TARGET_ROM) || defined(BL_TARGET_RAM)) +#include +#include +#include "fsl_device_registers.h" +#include "bootloader_common.h" +#else +#include "fsl_common.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @addtogroup flash_driver + * @{ + */ + +/*! + * @name Flash version + * @{ + */ +/*! @brief Construct the version number for drivers. */ +#if !defined(MAKE_VERSION) +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) +#endif + +/*! @brief FLASH driver version for SDK*/ +#define FSL_FLASH_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */ + +/*! @brief FLASH driver version for ROM*/ +enum _flash_driver_version_constants +{ + kFLASH_driverVersionName = 'F', /*!< Flash driver version name.*/ + kFLASH_driverVersionMajor = 2, /*!< Major flash driver version.*/ + kFLASH_driverVersionMinor = 1, /*!< Minor flash driver version.*/ + kFLASH_driverVersionBugfix = 0 /*!< Bugfix for flash driver version.*/ +}; +/*@}*/ + +/*! + * @name Flash configuration + * @{ + */ +/*! @brief Whether to support FlexNVM in flash driver */ +#if !defined(FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT) +#define FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT 1 /*!< Enable FlexNVM support by default. */ +#endif + +/*! @brief Whether the FlexNVM is enabled in flash driver */ +#define FLASH_SSD_IS_FLEXNVM_ENABLED (FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT && FSL_FEATURE_FLASH_HAS_FLEX_NVM) + +/*! @brief Flash driver location. */ +#if !defined(FLASH_DRIVER_IS_FLASH_RESIDENT) +#if (!defined(BL_TARGET_ROM) && !defined(BL_TARGET_RAM)) +#define FLASH_DRIVER_IS_FLASH_RESIDENT 1 /*!< Used for flash resident application. */ +#else +#define FLASH_DRIVER_IS_FLASH_RESIDENT 0 /*!< Used for non-flash resident application. */ +#endif +#endif + +/*! @brief Flash Driver Export option */ +#if !defined(FLASH_DRIVER_IS_EXPORTED) +#if (defined(BL_TARGET_ROM) || defined(BL_TARGET_FLASH)) +#define FLASH_DRIVER_IS_EXPORTED 1 /*!< Used for ROM bootloader. */ +#else +#define FLASH_DRIVER_IS_EXPORTED 0 /*!< Used for SDK application. */ +#endif +#endif +/*@}*/ + +/*! + * @name Flash status + * @{ + */ +/*! @brief Flash driver status group. */ +#if defined(kStatusGroup_FlashDriver) +#define kStatusGroupGeneric kStatusGroup_Generic +#define kStatusGroupFlashDriver kStatusGroup_FlashDriver +#elif defined(kStatusGroup_FLASH) +#define kStatusGroupGeneric kStatusGroup_Generic +#define kStatusGroupFlashDriver kStatusGroup_FLASH +#else +#define kStatusGroupGeneric 0 +#define kStatusGroupFlashDriver 1 +#endif + +/*! @brief Construct a status code value from a group and code number. */ +#if !defined(MAKE_STATUS) +#define MAKE_STATUS(group, code) ((((group)*100) + (code))) +#endif + +/*! + * @brief Flash driver status codes. + */ +enum _flash_status +{ + kStatus_FLASH_Success = MAKE_STATUS(kStatusGroupGeneric, 0), /*!< Api is executed successfully*/ + kStatus_FLASH_InvalidArgument = MAKE_STATUS(kStatusGroupGeneric, 4), /*!< Invalid argument*/ + kStatus_FLASH_SizeError = MAKE_STATUS(kStatusGroupFlashDriver, 0), /*!< Error size*/ + kStatus_FLASH_AlignmentError = + MAKE_STATUS(kStatusGroupFlashDriver, 1), /*!< Parameter is not aligned with specified baseline*/ + kStatus_FLASH_AddressError = MAKE_STATUS(kStatusGroupFlashDriver, 2), /*!< Address is out of range */ + kStatus_FLASH_AccessError = + MAKE_STATUS(kStatusGroupFlashDriver, 3), /*!< Invalid instruction codes and out-of bounds addresses */ + kStatus_FLASH_ProtectionViolation = MAKE_STATUS( + kStatusGroupFlashDriver, 4), /*!< The program/erase operation is requested to execute on protected areas */ + kStatus_FLASH_CommandFailure = + MAKE_STATUS(kStatusGroupFlashDriver, 5), /*!< Run-time error during command execution. */ + kStatus_FLASH_UnknownProperty = MAKE_STATUS(kStatusGroupFlashDriver, 6), /*!< Unknown property.*/ + kStatus_FLASH_EraseKeyError = MAKE_STATUS(kStatusGroupFlashDriver, 7), /*!< Api erase key is invalid.*/ + kStatus_FLASH_RegionExecuteOnly = MAKE_STATUS(kStatusGroupFlashDriver, 8), /*!< Current region is execute only.*/ + kStatus_FLASH_ExecuteInRamFunctionNotReady = + MAKE_STATUS(kStatusGroupFlashDriver, 9), /*!< Execute-in-ram function is not available.*/ + kStatus_FLASH_PartitionStatusUpdateFailure = + MAKE_STATUS(kStatusGroupFlashDriver, 10), /*!< Failed to update partition status.*/ + kStatus_FLASH_SetFlexramAsEepromError = + MAKE_STATUS(kStatusGroupFlashDriver, 11), /*!< Failed to set flexram as eeprom.*/ + kStatus_FLASH_RecoverFlexramAsRamError = + MAKE_STATUS(kStatusGroupFlashDriver, 12), /*!< Failed to recover flexram as ram.*/ + kStatus_FLASH_SetFlexramAsRamError = MAKE_STATUS(kStatusGroupFlashDriver, 13), /*!< Failed to set flexram as ram.*/ + kStatus_FLASH_RecoverFlexramAsEepromError = + MAKE_STATUS(kStatusGroupFlashDriver, 14), /*!< Failed to recover flexram as eeprom.*/ + kStatus_FLASH_CommandNotSupported = MAKE_STATUS(kStatusGroupFlashDriver, 15), /*!< Flash api is not supported.*/ + kStatus_FLASH_SwapSystemNotInUninitialized = + MAKE_STATUS(kStatusGroupFlashDriver, 16), /*!< Swap system is not in uninitialzed state.*/ + kStatus_FLASH_SwapIndicatorAddressError = + MAKE_STATUS(kStatusGroupFlashDriver, 17), /*!< Swap indicator address is invalid.*/ +}; +/*@}*/ + +/*! + * @name Flash API key + * @{ + */ +/*! @brief Construct the four char code for flash driver API key. */ +#if !defined(FOUR_CHAR_CODE) +#define FOUR_CHAR_CODE(a, b, c, d) (((d) << 24) | ((c) << 16) | ((b) << 8) | ((a))) +#endif + +/*! + * @brief Enumeration for flash driver API keys. + * + * @note The resulting value is built with a byte order such that the string + * being readable in expected order when viewed in a hex editor, if the value + * is treated as a 32-bit little endian value. + */ +enum _flash_driver_api_keys +{ + kFLASH_apiEraseKey = FOUR_CHAR_CODE('k', 'f', 'e', 'k') /*!< Key value used to validate all flash erase APIs.*/ +}; +/*@}*/ + +/*! + * @brief Enumeration for supported flash margin levels. + */ +typedef enum _flash_margin_value +{ + kFLASH_marginValueNormal, /*!< Use the 'normal' read level for 1s.*/ + kFLASH_marginValueUser, /*!< Apply the 'User' margin to the normal read-1 level.*/ + kFLASH_marginValueFactory, /*!< Apply the 'Factory' margin to the normal read-1 level.*/ + kFLASH_marginValueInvalid /*!< Not real margin level, Used to determine the range of valid margin level. */ +} flash_margin_value_t; + +/*! + * @brief Enumeration for the three possible flash security states. + */ +typedef enum _flash_security_state +{ + kFLASH_securityStateNotSecure, /*!< Flash is not secure.*/ + kFLASH_securityStateBackdoorEnabled, /*!< Flash backdoor is enabled.*/ + kFLASH_securityStateBackdoorDisabled /*!< Flash backdoor is disabled.*/ +} flash_security_state_t; + +/*! + * @brief Enumeration for the three possible flash protection levels. + */ +typedef enum _flash_protection_state +{ + kFLASH_protectionStateUnprotected, /*!< Flash region is not protected.*/ + kFLASH_protectionStateProtected, /*!< Flash region is protected.*/ + kFLASH_protectionStateMixed /*!< Flash is mixed with protected and unprotected region.*/ +} flash_protection_state_t; + +/*! + * @brief Enumeration for the three possible flash execute access levels. + */ +typedef enum _flash_execute_only_access_state +{ + kFLASH_accessStateUnLimited, /*!< Flash region is unLimited.*/ + kFLASH_accessStateExecuteOnly, /*!< Flash region is execute only.*/ + kFLASH_accessStateMixed /*!< Flash is mixed with unLimited and execute only region.*/ +} flash_execute_only_access_state_t; + +/*! + * @brief Enumeration for various flash properties. + */ +typedef enum _flash_property_tag +{ + kFLASH_propertyPflashSectorSize = 0x00U, /*!< Pflash sector size property.*/ + kFLASH_propertyPflashTotalSize = 0x01U, /*!< Pflash total size property.*/ + kFLASH_propertyPflashBlockSize = 0x02U, /*!< Pflash block size property.*/ + kFLASH_propertyPflashBlockCount = 0x03U, /*!< Pflash block count property.*/ + kFLASH_propertyPflashBlockBaseAddr = 0x04U, /*!< Pflash block base address property.*/ + kFLASH_propertyPflashFacSupport = 0x05U, /*!< Pflash fac support property.*/ + kFLASH_propertyPflashAccessSegmentSize = 0x06U, /*!< Pflash access segment size property.*/ + kFLASH_propertyPflashAccessSegmentCount = 0x07U, /*!< Pflash access segment count property.*/ + kFLASH_propertyFlexRamBlockBaseAddr = 0x08U, /*!< FlexRam block base address property.*/ + kFLASH_propertyFlexRamTotalSize = 0x09U, /*!< FlexRam total size property.*/ + kFLASH_propertyDflashSectorSize = 0x10U, /*!< Dflash sector size property.*/ + kFLASH_propertyDflashTotalSize = 0x11U, /*!< Dflash total size property.*/ + kFLASH_propertyDflashBlockSize = 0x12U, /*!< Dflash block count property.*/ + kFLASH_propertyDflashBlockCount = 0x13U, /*!< Dflash block base address property.*/ + kFLASH_propertyDflashBlockBaseAddr = 0x14U, /*!< Eeprom total size property.*/ + kFLASH_propertyEepromTotalSize = 0x15U +} flash_property_tag_t; + +/*! + * @brief Constants for execute-in-ram flash function. + */ +enum _flash_execute_in_ram_function_constants +{ + kFLASH_executeInRamFunctionMaxSize = 64U, /*!< Max size of execute-in-ram function.*/ + kFLASH_executeInRamFunctionTotalNum = 2U /*!< Total number of execute-in-ram functions.*/ +}; + +/*! + * @brief Flash execute-in-ram function information. + */ +typedef struct _flash_execute_in_ram_function_config +{ + uint32_t activeFunctionCount; /*!< Number of available execute-in-ram functions.*/ + uint8_t *flashRunCommand; /*!< execute-in-ram function: flash_run_command.*/ + uint8_t *flashCacheClearCommand; /*!< execute-in-ram function: flash_cache_clear_command.*/ +} flash_execute_in_ram_function_config_t; + +/*! + * @brief Enumeration for the two possible options of flash read resource command. + */ +typedef enum _flash_read_resource_option +{ + kFLASH_resourceOptionFlashIfr = + 0x00U, /*!< Select code for Program flash 0 IFR, Program flash swap 0 IFR, Data flash 0 IFR */ + kFLASH_resourceOptionVersionId = 0x01U /*!< Select code for Version ID*/ +} flash_read_resource_option_t; + +/*! + * @brief Enumeration for the range of special-purpose flash resource + */ +enum _flash_read_resource_range +{ +#if (FSL_FEATURE_FLASH_IS_FTFE == 1) + kFLASH_resourceRangePflashIfrSizeInBytes = 1024U, /*!< Pflash IFR size in byte.*/ + kFLASH_resourceRangeVersionIdSizeInBytes = 8U, /*!< Version ID IFR size in byte.*/ + kFLASH_resourceRangeVersionIdStart = 0x08U, /*!< Version ID IFR start address.*/ + kFLASH_resourceRangeVersionIdEnd = 0x0FU, /*!< Version ID IFR end address.*/ +#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */ + kFLASH_resourceRangePflashIfrSizeInBytes = 256U, /*!< Pflash IFR size in byte.*/ + kFLASH_resourceRangeVersionIdSizeInBytes = 8U, /*!< Version ID IFR size in byte.*/ + kFLASH_resourceRangeVersionIdStart = 0x00U, /*!< Version ID IFR start address.*/ + kFLASH_resourceRangeVersionIdEnd = 0x07U, /*!< Version ID IFR end address.*/ +#endif + kFLASH_resourceRangePflashSwapIfrStart = 0x40000U, /*!< Pflash swap IFR start address.*/ + kFLASH_resourceRangePflashSwapIfrEnd = 0x403FFU, /*!< Pflash swap IFR end address.*/ + kFLASH_resourceRangeDflashIfrStart = 0x800000U, /*!< Dflash IFR start address.*/ + kFLASH_resourceRangeDflashIfrEnd = 0x8003FFU, /*!< Dflash IFR end address.*/ +}; + +/*! + * @brief Enumeration for the two possilbe options of set flexram function command. + */ +typedef enum _flash_flexram_function_option +{ + kFLASH_flexramFunctionOptionAvailableAsRam = 0xFFU, /*!< Option used to make FlexRAM available as RAM */ + kFLASH_flexramFunctionOptionAvailableForEeprom = 0x00U /*!< Option used to make FlexRAM available for EEPROM */ +} flash_flexram_function_option_t; + +/*! + * @brief Enumeration for the possible options of Swap function + */ +typedef enum _flash_swap_function_option +{ + kFLASH_swapFunctionOptionEnable = 0x00U, /*!< Option used to enable Swap function */ + kFLASH_swapFunctionOptionDisable = 0x01U /*!< Option used to Disable Swap function */ +} flash_swap_function_option_t; + +/*! + * @brief Enumeration for the possible options of Swap Control commands + */ +typedef enum _flash_swap_control_option +{ + kFLASH_swapControlOptionIntializeSystem = 0x01U, /*!< Option used to Intialize Swap System */ + kFLASH_swapControlOptionSetInUpdateState = 0x02U, /*!< Option used to Set Swap in Update State */ + kFLASH_swapControlOptionSetInCompleteState = 0x04U, /*!< Option used to Set Swap in Complete State */ + kFLASH_swapControlOptionReportStatus = 0x08U, /*!< Option used to Report Swap Status */ + kFLASH_swapControlOptionDisableSystem = 0x10U /*!< Option used to Disable Swap Status */ +} flash_swap_control_option_t; + +/*! + * @brief Enumeration for the possible flash swap status. + */ +typedef enum _flash_swap_state +{ + kFLASH_swapStateUninitialized = 0x00U, /*!< Flash swap system is in uninitialized state.*/ + kFLASH_swapStateReady = 0x01U, /*!< Flash swap system is in ready state.*/ + kFLASH_swapStateUpdate = 0x02U, /*!< Flash swap system is in update state.*/ + kFLASH_swapStateUpdateErased = 0x03U, /*!< Flash swap system is in updateErased state.*/ + kFLASH_swapStateComplete = 0x04U, /*!< Flash swap system is in complete state.*/ + kFLASH_swapStateDisabled = 0x05U /*!< Flash swap system is in disabled state.*/ +} flash_swap_state_t; + +/*! + * @breif Enumeration for the possible flash swap block status + */ +typedef enum _flash_swap_block_status +{ + kFLASH_swapBlockStatusLowerHalfProgramBlocksAtZero = + 0x00U, /*!< Swap block status is that lower half program block at zero.*/ + kFLASH_swapBlockStatusUpperHalfProgramBlocksAtZero = + 0x01U, /*!< Swap block status is that upper half program block at zero.*/ +} flash_swap_block_status_t; + +/*! + * @brief Flash Swap information. + */ +typedef struct _flash_swap_state_config +{ + flash_swap_state_t flashSwapState; /*!< Current swap system status.*/ + flash_swap_block_status_t currentSwapBlockStatus; /*!< Current swap block status.*/ + flash_swap_block_status_t nextSwapBlockStatus; /*!< Next swap block status.*/ +} flash_swap_state_config_t; + +/*! + * @brief Flash Swap IFR fileds. + */ +typedef struct _flash_swap_ifr_field_config +{ + uint16_t swapIndicatorAddress; /*!< Swap indicator address field.*/ + uint16_t swapEnableWord; /*!< Swap enable word field.*/ + uint8_t reserved0[6]; /*!< Reserved field.*/ + uint16_t swapDisableWord; /*!< Swap disable word field.*/ + uint8_t reserved1[4]; /*!< Reserved field.*/ +} flash_swap_ifr_field_config_t; + +/*! + * @brief Enumeration for FlexRAM load during reset option. + */ +typedef enum _flash_partition_flexram_load_option +{ + kFLASH_partitionFlexramLoadOptionLoadedWithValidEepromData = + 0x00U, /*!< FlexRAM is loaded with valid EEPROM data during reset sequence.*/ + kFLASH_partitionFlexramLoadOptionNotLoaded = 0x01U /*!< FlexRAM is not loaded during reset sequence.*/ +} flash_partition_flexram_load_option_t; + +/*! @brief callback type used for pflash block*/ +typedef void (*flash_callback_t)(void); + +/*! + * @brief Active flash information for current operation. + */ +typedef struct _flash_operation_config +{ + uint32_t convertedAddress; /*!< Converted address for current flash type.*/ + uint32_t activeSectorSize; /*!< Sector size of current flash type.*/ + uint32_t activeBlockSize; /*!< Block size of current flash type.*/ + uint32_t blockWriteUnitSize; /*!< write unit size.*/ + uint32_t sectorCmdAddressAligment; /*!< Erase sector command address alignment.*/ + uint32_t sectionCmdAddressAligment; /*!< Program/Verify section command address alignment.*/ + uint32_t resourceCmdAddressAligment; /*!< Read resource command address alignment.*/ + uint32_t checkCmdAddressAligment; /*!< Program check command address alignment.*/ +} flash_operation_config_t; + +/*! @brief Flash driver state information. + * + * An instance of this structure is allocated by the user of the flash driver and + * passed into each of the driver APIs. + */ +typedef struct _flash_config +{ + uint32_t PFlashBlockBase; /*!< Base address of the first PFlash block */ + uint32_t PFlashTotalSize; /*!< Size of all combined PFlash block. */ + uint32_t PFlashBlockCount; /*!< Number of PFlash blocks. */ + uint32_t PFlashSectorSize; /*!< Size in bytes of a sector of PFlash. */ + flash_callback_t PFlashCallback; /*!< Callback function for flash API. */ + uint32_t PFlashAccessSegmentSize; /*!< Size in bytes of a access segment of PFlash. */ + uint32_t PFlashAccessSegmentCount; /*!< Number of PFlash access segments. */ + uint32_t *flashExecuteInRamFunctionInfo; /*!< Info struct of flash execute-in-ram function. */ + uint32_t FlexRAMBlockBase; /*!< For FlexNVM device, this is the base address of FlexRAM + For non-FlexNVM device, this is the base address of acceleration RAM memory */ + uint32_t FlexRAMTotalSize; /*!< For FlexNVM device, this is the size of FlexRAM + For non-FlexNVM device, this is the size of acceleration RAM memory */ + uint32_t DFlashBlockBase; /*!< For FlexNVM device, this is the base address of D-Flash memory (FlexNVM memory); + For non-FlexNVM device, this field is unused */ + uint32_t DFlashTotalSize; /*!< For FlexNVM device, this is total size of the FlexNVM memory; + For non-FlexNVM device, this field is unused */ + uint32_t EEpromTotalSize; /*!< For FlexNVM device, this is the size in byte of EEPROM area which was partitioned + from FlexRAM; + For non-FlexNVM device, this field is unused */ +} flash_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Initializes global flash properties structure members + * + * This function checks and initializes Flash module for the other Flash APIs. + * + * @param config Pointer to storage for the driver runtime state. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_PartitionStatusUpdateFailure Failed to update partition status. + */ +status_t FLASH_Init(flash_config_t *config); + +/*! + * @brief Set the desired flash callback function + * + * @param config Pointer to storage for the driver runtime state. + * @param callback callback function to be stored in driver + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + */ +status_t FLASH_SetCallback(flash_config_t *config, flash_callback_t callback); + +/*! + * @brief Prepare flash execute-in-ram functions + * + * @param config Pointer to storage for the driver runtime state. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + */ +#if FLASH_DRIVER_IS_FLASH_RESIDENT +status_t FLASH_PrepareExecuteInRamFunctions(flash_config_t *config); +#endif + +/*@}*/ + +/*! + * @name Erasing + * @{ + */ + +/*! + * @brief Erases entire flash + * + * @param config Pointer to storage for the driver runtime state. + * @param key value used to validate all flash erase APIs. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_EraseKeyError Api erase key is invalid. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + * @retval #kStatus_FLASH_PartitionStatusUpdateFailure Failed to update partition status + */ +status_t FLASH_EraseAll(flash_config_t *config, uint32_t key); + +/*! + * @brief Erases flash sectors encompassed by parameters passed into function + * + * This function erases the appropriate number of flash sectors based on the + * desired start address and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be erased. + * The start address does not need to be sector aligned but must be word-aligned. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be erased. Must be word aligned. + * @param key value used to validate all flash erase APIs. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_AddressError Address is out of range. + * @retval #kStatus_FLASH_EraseKeyError Api erase key is invalid. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key); + +/*! + * @brief Erases entire flash, including protected sectors. + * + * @param config Pointer to storage for the driver runtime state. + * @param key value used to validate all flash erase APIs. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_EraseKeyError Api erase key is invalid. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + * @retval #kStatus_FLASH_PartitionStatusUpdateFailure Failed to update partition status + */ +#if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD +status_t FLASH_EraseAllUnsecure(flash_config_t *config, uint32_t key); +#endif + +/*! + * @brief Erases all program flash execute-only segments defined by the FXACC registers. + * + * @param config Pointer to storage for the driver runtime state. + * @param key value used to validate all flash erase APIs. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_EraseKeyError Api erase key is invalid. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_EraseAllExecuteOnlySegments(flash_config_t *config, uint32_t key); + +/*@}*/ + +/*! + * @name Programming + * @{ + */ + +/*! + * @brief Programs flash with data at locations passed in through parameters + * + * This function programs the flash memory with desired data for a given + * flash area as determined by the start address and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be programmed. Must be + * word-aligned. + * @param src Pointer to the source buffer of data that is to be programmed + * into the flash. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be programmed. Must be word-aligned. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_AddressError Address is out of range. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_Program(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes); + +/*! + * @brief Programs Program Once Field through parameters + * + * This function programs the Program Once Field with desired data for a given + * flash area as determined by the index and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param index The index indicating which area of Program Once Field to be programmed. + * @param src Pointer to the source buffer of data that is to be programmed + * into the Program Once Field. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be programmed. Must be word-aligned. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_ProgramOnce(flash_config_t *config, uint32_t index, uint32_t *src, uint32_t lengthInBytes); + +/*! + * @brief Programs flash with data at locations passed in through parameters via Program Section command + * + * This function programs the flash memory with desired data for a given + * flash area as determined by the start address and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be programmed. Must be + * word-aligned. + * @param src Pointer to the source buffer of data that is to be programmed + * into the flash. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be programmed. Must be word-aligned. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_AddressError Address is out of range. + * @retval #kStatus_FLASH_SetFlexramAsRamError Failed to set flexram as ram + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + * @retval #kStatus_FLASH_RecoverFlexramAsEepromError Failed to recover flexram as eeprom + */ +#if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD +status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes); +#endif + +/*! + * @brief Programs EEPROM with data at locations passed in through parameters + * + * This function programs the Emulated EEPROM with desired data for a given + * flash area as determined by the start address and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be programmed. Must be + * word-aligned. + * @param src Pointer to the source buffer of data that is to be programmed + * into the flash. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be programmed. Must be word-aligned. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AddressError Address is out of range. + * @retval #kStatus_FLASH_SetFlexramAsEepromError Failed to set flexram as eeprom. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_RecoverFlexramAsRamError Failed to recover flexram as ram + */ +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromWrite(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes); +#endif + +/*@}*/ + +/*! + * @name Reading + * @{ + */ + +/*! + * @brief Read resource with data at locations passed in through parameters + * + * This function reads the flash memory with desired location for a given + * flash area as determined by the start address and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be programmed. Must be + * word-aligned. + * @param dst Pointer to the destination buffer of data that is used to store + * data to be read. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be read. Must be word-aligned. + * @param option The resource option which indicates which area should be read back. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD +status_t FLASH_ReadResource( + flash_config_t *config, uint32_t start, uint32_t *dst, uint32_t lengthInBytes, flash_read_resource_option_t option); +#endif + +/*! + * @brief Read Program Once Field through parameters + * + * This function reads the read once feild with given index and length + * + * @param config Pointer to storage for the driver runtime state. + * @param index The index indicating the area of program once field to be read. + * @param dst Pointer to the destination buffer of data that is used to store + * data to be read. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be programmed. Must be word-aligned. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_ReadOnce(flash_config_t *config, uint32_t index, uint32_t *dst, uint32_t lengthInBytes); + +/*@}*/ + +/*! + * @name Security + * @{ + */ + +/*! + * @brief Returns the security state via the pointer passed into the function + * + * This function retrieves the current Flash security status, including the + * security enabling state and the backdoor key enabling state. + * + * @param config Pointer to storage for the driver runtime state. + * @param state Pointer to the value returned for the current security status code: + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + */ +status_t FLASH_GetSecurityState(flash_config_t *config, flash_security_state_t *state); + +/*! + * @brief Allows user to bypass security with a backdoor key + * + * If the MCU is in secured state, this function will unsecure the MCU by + * comparing the provided backdoor key with ones in the Flash Configuration + * Field. + * + * @param config Pointer to storage for the driver runtime state. + * @param backdoorKey Pointer to the user buffer containing the backdoor key. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_SecurityBypass(flash_config_t *config, const uint8_t *backdoorKey); + +/*@}*/ + +/*! + * @name Verification + * @{ + */ + +/*! + * @brief Verifies erasure of entire flash at specified margin level + * + * This function will check to see if the flash have been erased to the + * specified read margin level. + * + * @param config Pointer to storage for the driver runtime state. + * @param margin Read margin choice + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_VerifyEraseAll(flash_config_t *config, flash_margin_value_t margin); + +/*! + * @brief Verifies erasure of desired flash area at specified margin level + * + * This function will check the appropriate number of flash sectors based on + * the desired start address and length to see if the flash have been erased + * to the specified read margin level. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be verified. + * The start address does not need to be sector aligned but must be word-aligned. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be verified. Must be word-aligned. + * @param margin Read margin choice + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_AddressError Address is out of range. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, flash_margin_value_t margin); + +/*! + * @brief Verifies programming of desired flash area at specified margin level + * + * This function verifies the data programed in the flash memory using the + * Flash Program Check Command and compares it with expected data for a given + * flash area as determined by the start address and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be verified. Must be word-aligned. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be verified. Must be word-aligned. + * @param expectedData Pointer to the expected data that is to be + * verified against. + * @param margin Read margin choice + * @param failedAddress Pointer to returned failing address. + * @param failedData Pointer to returned failing data. Some derivitives do + * not included failed data as part of the FCCOBx registers. In this + * case, zeros are returned upon failure. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_AddressError Address is out of range. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_VerifyProgram(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + const uint32_t *expectedData, + flash_margin_value_t margin, + uint32_t *failedAddress, + uint32_t *failedData); + +/*! + * @brief Verifies if the program flash executeonly segments have been erased to + * the specified read margin level + * + * @param config Pointer to storage for the driver runtime state. + * @param margin Read margin choice + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_VerifyEraseAllExecuteOnlySegments(flash_config_t *config, flash_margin_value_t margin); + +/*@}*/ + +/*! + * @name Protection + * @{ + */ + +/*! + * @brief Returns the protection state of desired flash area via the pointer passed into the function + * + * This function retrieves the current Flash protect status for a given + * flash area as determined by the start address and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be checked. Must be word-aligned. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be checked. Must be word-aligned. + * @param protection_state Pointer to the value returned for the current + * protection status code for the desired flash area. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_AddressError Address is out of range. + */ +status_t FLASH_IsProtected(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + flash_protection_state_t *protection_state); + +/*! + * @brief Returns the access state of desired flash area via the pointer passed into the function + * + * This function retrieves the current Flash access status for a given + * flash area as determined by the start address and length. + * + * @param config Pointer to storage for the driver runtime state. + * @param start The start address of the desired flash memory to be checked. Must be word-aligned. + * @param lengthInBytes The length, given in bytes (not words or long-words) + * to be checked. Must be word-aligned. + * @param access_state Pointer to the value returned for the current + * access status code for the desired flash area. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_AddressError Address is out of range. + */ +status_t FLASH_IsExecuteOnly(flash_config_t *config, + uint32_t start, + uint32_t lengthInBytes, + flash_execute_only_access_state_t *access_state); + +/*@}*/ + +/*! + * @name Properties + * @{ + */ + +/*! + * @brief Returns the desired flash property. + * + * @param config Pointer to storage for the driver runtime state. + * @param whichProperty The desired property from the list of properties in + * enum flash_property_tag_t + * @param value Pointer to the value returned for the desired flash property + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_UnknownProperty unknown property tag + */ +status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value); + +/*@}*/ + +/*! + * @name FlexRAM + * @{ + */ + +/*! + * @brief Set FlexRAM Function command + * + * @param config Pointer to storage for the driver runtime state. + * @param option The option used to set work mode of FlexRAM + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +#if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD +status_t FLASH_SetFlexramFunction(flash_config_t *config, flash_flexram_function_option_t option); +#endif + +/*@}*/ + +/*! + * @name Swap + * @{ + */ + +/*! + * @brief Configure Swap function or Check the swap state of Flash Module + * + * @param config Pointer to storage for the driver runtime state. + * @param address Address used to configure the flash swap function + * @param option The possible option used to configure Flash Swap function or check the flash swap status + * @param returnInfo Pointer to the data which is used to return the information of flash swap. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_SwapIndicatorAddressError Swap indicator address is invalid + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +#if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD +status_t FLASH_SwapControl(flash_config_t *config, + uint32_t address, + flash_swap_control_option_t option, + flash_swap_state_config_t *returnInfo); +#endif + +/*! + * @brief Swap the lower half flash with the higher half flaock + * + * @param config Pointer to storage for the driver runtime state. + * @param address Address used to configure the flash swap function + * @param option The possible option used to configure Flash Swap function or check the flash swap status + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_AlignmentError Parameter is not aligned with specified baseline. + * @retval #kStatus_FLASH_SwapIndicatorAddressError Swap indicator address is invalid + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + * @retval #kStatus_FLASH_SwapSystemNotInUninitialized Swap system is not in uninitialzed state + */ +#if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP +status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_function_option_t option); +#endif + +/*! + * @name FlexNVM + * @{ + */ + +/*! + * @brief Prepares the FlexNVM block for use as data flash, EEPROM backup, or a combination of both and initializes the + * FlexRAM. + * + * @param config Pointer to storage for the driver runtime state. + * @param option The option used to set FlexRAM load behavior during reset. + * @param eepromDataSizeCode Determines the amount of FlexRAM used in each of the available EEPROM subsystems. + * @param flexnvmPartitionCode Specifies how to split the FlexNVM block between data flash memory and EEPROM backup + * memory supporting EEPROM functions. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_ExecuteInRamFunctionNotReady Execute-in-ram function is not available. + * @retval #kStatus_FLASH_AccessError Invalid instruction codes and out-of bounds addresses. + * @retval #kStatus_FLASH_ProtectionViolation The program/erase operation is requested to execute on protected areas. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +#if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD +status_t FLASH_ProgramPartition(flash_config_t *config, + flash_partition_flexram_load_option_t option, + uint32_t eepromDataSizeCode, + uint32_t flexnvmPartitionCode); +#endif + +/*@}*/ + +/*! +* @name Flash Protection Utilities +* @{ +*/ + +/*! + * @brief Set PFLASH Protection to the intended protection status. + * + * @param config Pointer to storage for the driver runtime state. + * @param protectStatus The expected protect status user wants to set to PFlash protection register. Each bit is + * corresponding to protection of 1/32 of the total PFlash. The least significant bit is corresponding to the lowest + * address area of P-Flash. The most significant bit is corresponding to the highest address area of PFlash. There are + * two possible cases as shown below: + * 0: this area is protected. + * 1: this area is unprotected. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +status_t FLASH_PflashSetProtection(flash_config_t *config, uint32_t protectStatus); + +/*! + * @brief Get PFLASH Protection Status. + * + * @param config Pointer to storage for the driver runtime state. + * @param protectStatus Protect status returned by PFlash IP. Each bit is corresponding to protection of 1/32 of the + * total PFlash. The least significant bit is corresponding to the lowest address area of PFlash. The most significant + * bit is corresponding to the highest address area of PFlash. Thee are two possible cases as below: + * 0: this area is protected. + * 1: this area is unprotected. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + */ +status_t FLASH_PflashGetProtection(flash_config_t *config, uint32_t *protectStatus); + +/*! + * @brief Set DFLASH Protection to the intended protection status. + * + * @param config Pointer to storage for the driver runtime state. + * @param protectStatus The expected protect status user wants to set to DFlash protection register. Each bit is + * corresponding to protection of 1/8 of the total DFlash. The least significant bit is corresponding to the lowest + * address area of DFlash. The most significant bit is corresponding to the highest address area of DFlash. There are + * two possible cases as shown below: + * 0: this area is protected. + * 1: this area is unprotected. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_CommandNotSupported Flash api is not supported + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_DflashSetProtection(flash_config_t *config, uint8_t protectStatus); +#endif + +/*! + * @brief Get DFLASH Protection Status. + * + * @param config Pointer to storage for the driver runtime state. + * @param protectStatus DFlash Protect status returned by PFlash IP. Each bit is corresponding to protection of 1/8 of + * the total DFlash. The least significant bit is corresponding to the lowest address area of DFlash. The most + * significant bit is corresponding to the highest address area of DFlash and so on. There are two possible cases as + * below: + * 0: this area is protected. + * 1: this area is unprotected. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_CommandNotSupported Flash api is not supported + */ +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_DflashGetProtection(flash_config_t *config, uint8_t *protectStatus); +#endif + +/*! + * @brief Set EEPROM Protection to the intended protection status. + * + * @param config Pointer to storage for the driver runtime state. + * @param protectStatus The expected protect status user wants to set to EEPROM protection register. Each bit is + * corresponding to protection of 1/8 of the total EEPROM. The least significant bit is corresponding to the lowest + * address area of EEPROM. The most significant bit is corresponding to the highest address area of EEPROM, and so on. + * There are two possible cases as shown below: + * 0: this area is protected. + * 1: this area is unprotected. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_CommandNotSupported Flash api is not supported + * @retval #kStatus_FLASH_CommandFailure Run-time error during command execution. + */ +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromSetProtection(flash_config_t *config, uint8_t protectStatus); +#endif + +/*! + * @brief Get DFLASH Protection Status. + * + * @param config Pointer to storage for the driver runtime state. + * @param protectStatus DFlash Protect status returned by PFlash IP. Each bit is corresponding to protection of 1/8 of + * the total EEPROM. The least significant bit is corresponding to the lowest address area of EEPROM. The most + * significant bit is corresponding to the highest address area of EEPROM. There are two possible cases as below: + * 0: this area is protected. + * 1: this area is unprotected. + * + * @retval #kStatus_FLASH_Success Api was executed successfully. + * @retval #kStatus_FLASH_InvalidArgument Invalid argument is provided. + * @retval #kStatus_FLASH_CommandNotSupported Flash api is not supported. + */ +#if FLASH_SSD_IS_FLEXNVM_ENABLED +status_t FLASH_EepromGetProtection(flash_config_t *config, uint8_t *protectStatus); +#endif + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_FLASH_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio.c new file mode 100644 index 0000000000..ea15f00a4e --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*< @brief user configurable flexio handle count. */ +#define FLEXIO_HANDLE_COUNT 2 + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*< @brief pointer to array of FLEXIO handle. */ +static void *s_flexioHandle[FLEXIO_HANDLE_COUNT]; + +/*< @brief pointer to array of FLEXIO IP types. */ +static void *s_flexioType[FLEXIO_HANDLE_COUNT]; + +/*< @brief pointer to array of FLEXIO Isr. */ +static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT]; + +/******************************************************************************* + * Codes + ******************************************************************************/ + +void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig) +{ + uint32_t ctrlReg = 0; + + CLOCK_EnableClock(kCLOCK_Flexio0); + + FLEXIO_Reset(base); + + ctrlReg = base->CTRL; + ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + ctrlReg |= (FLEXIO_CTRL_DOZEN(userConfig->enableInDoze) | FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | + FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio)); + + base->CTRL = ctrlReg; +} + +void FLEXIO_Deinit(FLEXIO_Type *base) +{ + FLEXIO_Enable(base, false); + CLOCK_DisableClock(kCLOCK_Flexio0); +} + +void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig) +{ + assert(userConfig); + + userConfig->enableFlexio = true; + userConfig->enableInDoze = false; + userConfig->enableInDebug = true; + userConfig->enableFastAccess = false; +} + +void FLEXIO_Reset(FLEXIO_Type *base) +{ + /*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/ + base->CTRL |= FLEXIO_CTRL_SWRST_MASK; + base->CTRL = 0; +} + +uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index) +{ + assert(index < FLEXIO_SHIFTBUF_COUNT); + + uint32_t address = 0; + + switch (type) + { + case kFLEXIO_ShifterBuffer: + address = (uint32_t) & (base->SHIFTBUF[index]); + break; + + case kFLEXIO_ShifterBufferBitSwapped: + address = (uint32_t) & (base->SHIFTBUFBIS[index]); + break; + + case kFLEXIO_ShifterBufferByteSwapped: + address = (uint32_t) & (base->SHIFTBUFBYS[index]); + break; + + case kFLEXIO_ShifterBufferBitByteSwapped: + address = (uint32_t) & (base->SHIFTBUFBBS[index]); + break; + +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP + case kFLEXIO_ShifterBufferNibbleByteSwapped: + address = (uint32_t) & (base->SHIFTBUFNBS[index]); + break; + +#endif +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP + case kFLEXIO_ShifterBufferHalfWordSwapped: + address = (uint32_t) & (base->SHIFTBUFHWS[index]); + break; + +#endif +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP + case kFLEXIO_ShifterBufferNibbleSwapped: + address = (uint32_t) & (base->SHIFTBUFNIS[index]); + break; + +#endif + default: + break; + } + return address; +} + +void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig) +{ + base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource) +#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH + | FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth) +#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */ + | FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) | + FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart); + + base->SHIFTCTL[index] = + FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) | + FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) | + FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode); +} + +void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig) +{ + base->TIMCFG[index] = + FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) | + FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) | + FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) | + FLEXIO_TIMCFG_TSTART(timerConfig->timerStart); + + base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare); + + base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) | + FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) | + FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) | + FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) | + FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode); +} + +status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr) +{ + assert(base); + assert(handle); + assert(isr); + + uint8_t index = 0; + + /* Find the an empty handle pointer to store the handle. */ + for (index = 0; index < FLEXIO_HANDLE_COUNT; index++) + { + if (s_flexioHandle[index] == NULL) + { + /* Register FLEXIO simulated driver base, handle and isr. */ + s_flexioType[index] = base; + s_flexioHandle[index] = handle; + s_flexioIsr[index] = isr; + break; + } + } + + if (index == FLEXIO_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + else + { + return kStatus_Success; + } +} + +status_t FLEXIO_UnregisterHandleIRQ(void *base) +{ + assert(base); + + uint8_t index = 0; + + /* Find the index from base address mappings. */ + for (index = 0; index < FLEXIO_HANDLE_COUNT; index++) + { + if (s_flexioType[index] == base) + { + /* Unregister FLEXIO simulated driver handle and isr. */ + s_flexioType[index] = NULL; + s_flexioHandle[index] = NULL; + s_flexioIsr[index] = NULL; + break; + } + } + + if (index == FLEXIO_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + else + { + return kStatus_Success; + } +} + +void FLEXIO_CommonIRQHandler(void) +{ + uint8_t index; + + for (index = 0; index < FLEXIO_HANDLE_COUNT; index++) + { + if (s_flexioHandle[index]) + { + s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]); + } + } +} + +void FLEXIO_DriverIRQHandler(void) +{ + FLEXIO_CommonIRQHandler(); +} + +void FLEXIO0_DriverIRQHandler(void) +{ + FLEXIO_CommonIRQHandler(); +} + +void UART2_FLEXIO_DriverIRQHandler(void) +{ + FLEXIO_CommonIRQHandler(); +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio.h new file mode 100644 index 0000000000..24fdfa6447 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio.h @@ -0,0 +1,707 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_H_ +#define _FSL_FLEXIO_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup flexio_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO driver version 2.0.0. */ +#define FSL_FLEXIO_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @brief Calculate FlexIO timer trigger.*/ +#define FLEXIO_TIMER_TRIGGER_SEL_PININPUT(x) ((uint32_t)(x) << 1U) +#define FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(x) (((uint32_t)(x) << 2U) | 0x1U) +#define FLEXIO_TIMER_TRIGGER_SEL_TIMn(x) (((uint32_t)(x) << 2U) | 0x3U) + +/*! @brief Define time of timer trigger polarity.*/ +typedef enum _flexio_timer_trigger_polarity +{ + kFLEXIO_TimerTriggerPolarityActiveHigh = 0x0U, /*!< Active high. */ + kFLEXIO_TimerTriggerPolarityActiveLow = 0x1U, /*!< Active low. */ +} flexio_timer_trigger_polarity_t; + +/*! @brief Define type of timer trigger source.*/ +typedef enum _flexio_timer_trigger_source +{ + kFLEXIO_TimerTriggerSourceExternal = 0x0U, /*!< External trigger selected. */ + kFLEXIO_TimerTriggerSourceInternal = 0x1U, /*!< Internal trigger selected. */ +} flexio_timer_trigger_source_t; + +/*! @brief Define type of timer/shifter pin configuration.*/ +typedef enum _flexio_pin_config +{ + kFLEXIO_PinConfigOutputDisabled = 0x0U, /*!< Pin output disabled. */ + kFLEXIO_PinConfigOpenDrainOrBidirection = 0x1U, /*!< Pin open drain or bidirectional output enable. */ + kFLEXIO_PinConfigBidirectionOutputData = 0x2U, /*!< Pin bidirectional output data. */ + kFLEXIO_PinConfigOutput = 0x3U, /*!< Pin output. */ +} flexio_pin_config_t; + +/*! @brief Definition of pin polarity.*/ +typedef enum _flexio_pin_polarity +{ + kFLEXIO_PinActiveHigh = 0x0U, /*!< Active high. */ + kFLEXIO_PinActiveLow = 0x1U, /*!< Active low. */ +} flexio_pin_polarity_t; + +/*! @brief Define type of timer work mode.*/ +typedef enum _flexio_timer_mode +{ + kFLEXIO_TimerModeDisabled = 0x0U, /*!< Timer Disabled. */ + kFLEXIO_TimerModeDual8BitBaudBit = 0x1U, /*!< Dual 8-bit counters baud/bit mode. */ + kFLEXIO_TimerModeDual8BitPWM = 0x2U, /*!< Dual 8-bit counters PWM mode. */ + kFLEXIO_TimerModeSingle16Bit = 0x3U, /*!< Single 16-bit counter mode. */ +} flexio_timer_mode_t; + +/*! @brief Define type of timer initial output or timer reset condition.*/ +typedef enum _flexio_timer_output +{ + kFLEXIO_TimerOutputOneNotAffectedByReset = 0x0U, /*!< Logic one when enabled and is not affected by timer + reset. */ + kFLEXIO_TimerOutputZeroNotAffectedByReset = 0x1U, /*!< Logic zero when enabled and is not affected by timer + reset. */ + kFLEXIO_TimerOutputOneAffectedByReset = 0x2U, /*!< Logic one when enabled and on timer reset. */ + kFLEXIO_TimerOutputZeroAffectedByReset = 0x3U, /*!< Logic zero when enabled and on timer reset. */ +} flexio_timer_output_t; + +/*! @brief Define type of timer decrement.*/ +typedef enum _flexio_timer_decrement_source +{ + kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput = 0x0U, /*!< Decrement counter on FlexIO clock, Shift clock + equals Timer output. */ + kFLEXIO_TimerDecSrcOnTriggerInputShiftTimerOutput = 0x1U, /*!< Decrement counter on Trigger input (both edges), + Shift clock equals Timer output. */ + kFLEXIO_TimerDecSrcOnPinInputShiftPinInput = 0x2U, /*!< Decrement counter on Pin input (both edges), + Shift clock equals Pin input. */ + kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput = 0x3U, /*!< Decrement counter on Trigger input (both edges), + Shift clock equals Trigger input. */ +} flexio_timer_decrement_source_t; + +/*! @brief Define type of timer reset condition.*/ +typedef enum _flexio_timer_reset_condition +{ + kFLEXIO_TimerResetNever = 0x0U, /*!< Timer never reset. */ + kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput = 0x2U, /*!< Timer reset on Timer Pin equal to Timer Output. */ + kFLEXIO_TimerResetOnTimerTriggerEqualToTimerOutput = 0x3U, /*!< Timer reset on Timer Trigger equal to + Timer Output. */ + kFLEXIO_TimerResetOnTimerPinRisingEdge = 0x4U, /*!< Timer reset on Timer Pin rising edge. */ + kFLEXIO_TimerResetOnTimerTriggerRisingEdge = 0x6U, /*!< Timer reset on Trigger rising edge. */ + kFLEXIO_TimerResetOnTimerTriggerBothEdge = 0x7U, /*!< Timer reset on Trigger rising or falling edge. */ +} flexio_timer_reset_condition_t; + +/*! @brief Define type of timer disable condition.*/ +typedef enum _flexio_timer_disable_condition +{ + kFLEXIO_TimerDisableNever = 0x0U, /*!< Timer never disabled. */ + kFLEXIO_TimerDisableOnPreTimerDisable = 0x1U, /*!< Timer disabled on Timer N-1 disable. */ + kFLEXIO_TimerDisableOnTimerCompare = 0x2U, /*!< Timer disabled on Timer compare. */ + kFLEXIO_TimerDisableOnTimerCompareTriggerLow = 0x3U, /*!< Timer disabled on Timer compare and Trigger Low. */ + kFLEXIO_TimerDisableOnPinBothEdge = 0x4U, /*!< Timer disabled on Pin rising or falling edge. */ + kFLEXIO_TimerDisableOnPinBothEdgeTriggerHigh = 0x5U, /*!< Timer disabled on Pin rising or falling edge provided + Trigger is high. */ + kFLEXIO_TimerDisableOnTriggerFallingEdge = 0x6U, /*!< Timer disabled on Trigger falling edge. */ +} flexio_timer_disable_condition_t; + +/*! @brief Define type of timer enable condition.*/ +typedef enum _flexio_timer_enable_condition +{ + kFLEXIO_TimerEnabledAlways = 0x0U, /*!< Timer always enabled. */ + kFLEXIO_TimerEnableOnPrevTimerEnable = 0x1U, /*!< Timer enabled on Timer N-1 enable. */ + kFLEXIO_TimerEnableOnTriggerHigh = 0x2U, /*!< Timer enabled on Trigger high. */ + kFLEXIO_TimerEnableOnTriggerHighPinHigh = 0x3U, /*!< Timer enabled on Trigger high and Pin high. */ + kFLEXIO_TimerEnableOnPinRisingEdge = 0x4U, /*!< Timer enabled on Pin rising edge. */ + kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh = 0x5U, /*!< Timer enabled on Pin rising edge and Trigger high. */ + kFLEXIO_TimerEnableOnTriggerRisingEdge = 0x6U, /*!< Timer enabled on Trigger rising edge. */ + kFLEXIO_TimerEnableOnTriggerBothEdge = 0x7U, /*!< Timer enabled on Trigger rising or falling edge. */ +} flexio_timer_enable_condition_t; + +/*! @brief Define type of timer stop bit generate condition.*/ +typedef enum _flexio_timer_stop_bit_condition +{ + kFLEXIO_TimerStopBitDisabled = 0x0U, /*!< Stop bit disabled. */ + kFLEXIO_TimerStopBitEnableOnTimerCompare = 0x1U, /*!< Stop bit is enabled on timer compare. */ + kFLEXIO_TimerStopBitEnableOnTimerDisable = 0x2U, /*!< Stop bit is enabled on timer disable. */ + kFLEXIO_TimerStopBitEnableOnTimerCompareDisable = 0x3U, /*!< Stop bit is enabled on timer compare and timer + disable. */ +} flexio_timer_stop_bit_condition_t; + +/*! @brief Define type of timer start bit generate condition.*/ +typedef enum _flexio_timer_start_bit_condition +{ + kFLEXIO_TimerStartBitDisabled = 0x0U, /*!< Start bit disabled. */ + kFLEXIO_TimerStartBitEnabled = 0x1U, /*!< Start bit enabled. */ +} flexio_timer_start_bit_condition_t; + +/*! @brief Define type of timer polarity for shifter control. */ +typedef enum _flexio_shifter_timer_polarity +{ + kFLEXIO_ShifterTimerPolarityOnPositive = 0x0U, /* Shift on positive edge of shift clock. */ + kFLEXIO_ShifterTimerPolarityOnNegitive = 0x1U, /* Shift on negative edge of shift clock. */ +} flexio_shifter_timer_polarity_t; + +/*! @brief Define type of shifter working mode.*/ +typedef enum _flexio_shifter_mode +{ + kFLEXIO_ShifterDisabled = 0x0U, /*!< Shifter is disabled. */ + kFLEXIO_ShifterModeReceive = 0x1U, /*!< Receive mode. */ + kFLEXIO_ShifterModeTransmit = 0x2U, /*!< Transmit mode. */ + kFLEXIO_ShifterModeMatchStore = 0x4U, /*!< Match store mode. */ + kFLEXIO_ShifterModeMatchContinuous = 0x5U, /*!< Match continuous mode. */ +#if FSL_FEATURE_FLEXIO_HAS_STATE_MODE + kFLEXIO_ShifterModeState = 0x6U, /*!< SHIFTBUF contents are used for storing + programmable state attributes. */ +#endif /* FSL_FEATURE_FLEXIO_HAS_STATE_MODE */ +#if FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE + kFLEXIO_ShifterModeLogic = 0x7U, /*!< SHIFTBUF contents are used for implementing + programmable logic look up table. */ +#endif /* FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE */ +} flexio_shifter_mode_t; + +/*! @brief Define type of shifter input source.*/ +typedef enum _flexio_shifter_input_source +{ + kFLEXIO_ShifterInputFromPin = 0x0U, /*!< Shifter input from pin. */ + kFLEXIO_ShifterInputFromNextShifterOutput = 0x1U, /*!< Shifter input from Shifter N+1. */ +} flexio_shifter_input_source_t; + +/*! @brief Define of STOP bit configuration.*/ +typedef enum _flexio_shifter_stop_bit +{ + kFLEXIO_ShifterStopBitDisable = 0x0U, /*!< Disable shifter stop bit. */ + kFLEXIO_ShifterStopBitLow = 0x2U, /*!< Set shifter stop bit to logic low level. */ + kFLEXIO_ShifterStopBitHigh = 0x3U, /*!< Set shifter stop bit to logic high level. */ +} flexio_shifter_stop_bit_t; + +/*! @brief Define type of START bit configuration.*/ +typedef enum _flexio_shifter_start_bit +{ + kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable = 0x0U, /*!< Disable shifter start bit, transmitter loads + data on enable. */ + kFLEXIO_ShifterStartBitDisabledLoadDataOnShift = 0x1U, /*!< Disable shifter start bit, transmitter loads + data on first shift. */ + kFLEXIO_ShifterStartBitLow = 0x2U, /*!< Set shifter start bit to logic low level. */ + kFLEXIO_ShifterStartBitHigh = 0x3U, /*!< Set shifter start bit to logic high level. */ +} flexio_shifter_start_bit_t; + +/*! @brief Define FlexIO shifter buffer type*/ +typedef enum _flexio_shifter_buffer_type +{ + kFLEXIO_ShifterBuffer = 0x0U, /*!< Shifter Buffer N Register. */ + kFLEXIO_ShifterBufferBitSwapped = 0x1U, /*!< Shifter Buffer N Bit Byte Swapped Register. */ + kFLEXIO_ShifterBufferByteSwapped = 0x2U, /*!< Shifter Buffer N Byte Swapped Register. */ + kFLEXIO_ShifterBufferBitByteSwapped = 0x3U, /*!< Shifter Buffer N Bit Swapped Register. */ +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP + kFLEXIO_ShifterBufferNibbleByteSwapped = 0x4U, /*!< Shifter Buffer N Nibble Byte Swapped Register. */ +#endif /*FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP*/ +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP + kFLEXIO_ShifterBufferHalfWordSwapped = 0x5U, /*!< Shifter Buffer N Half Word Swapped Register. */ +#endif +#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP + kFLEXIO_ShifterBufferNibbleSwapped = 0x6U, /*!< Shifter Buffer N Nibble Swapped Register. */ +#endif +} flexio_shifter_buffer_type_t; + +/*! @brief Define FlexIO user configuration structure. */ +typedef struct _flexio_config_ +{ + bool enableFlexio; /*!< Enable/disable FlexIO module */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode */ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode */ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires + the FlexIO clock to be at least twice the frequency of the bus clock. */ +} flexio_config_t; + +/*! @brief Define FlexIO timer configuration structure. */ +typedef struct _flexio_timer_config +{ + /* Trigger. */ + uint32_t triggerSelect; /*!< The internal trigger selection number using MACROs. */ + flexio_timer_trigger_polarity_t triggerPolarity; /*!< Trigger Polarity. */ + flexio_timer_trigger_source_t triggerSource; /*!< Trigger Source, internal (see 'trgsel') or external. */ + /* Pin. */ + flexio_pin_config_t pinConfig; /*!< Timer Pin Configuration. */ + uint32_t pinSelect; /*!< Timer Pin number Select. */ + flexio_pin_polarity_t pinPolarity; /*!< Timer Pin Polarity. */ + /* Timer. */ + flexio_timer_mode_t timerMode; /*!< Timer work Mode. */ + flexio_timer_output_t timerOutput; /*!< Configures the initial state of the Timer Output and + whether it is affected by the Timer reset. */ + flexio_timer_decrement_source_t timerDecrement; /*!< Configures the source of the Timer decrement and the + source of the Shift clock. */ + flexio_timer_reset_condition_t timerReset; /*!< Configures the condition that causes the timer counter + (and optionally the timer output) to be reset. */ + flexio_timer_disable_condition_t timerDisable; /*!< Configures the condition that causes the Timer to be + disabled and stop decrementing. */ + flexio_timer_enable_condition_t timerEnable; /*!< Configures the condition that causes the Timer to be + enabled and start decrementing. */ + flexio_timer_stop_bit_condition_t timerStop; /*!< Timer STOP Bit generation. */ + flexio_timer_start_bit_condition_t timerStart; /*!< Timer STRAT Bit generation. */ + uint32_t timerCompare; /*!< Value for Timer Compare N Register. */ +} flexio_timer_config_t; + +/*! @brief Define FlexIO shifter configuration structure. */ +typedef struct _flexio_shifter_config +{ + /* Timer. */ + uint32_t timerSelect; /*!< Selects which Timer is used for controlling the + logic/shift register and generating the Shift clock. */ + flexio_shifter_timer_polarity_t timerPolarity; /*!< Timer Polarity. */ + /* Pin. */ + flexio_pin_config_t pinConfig; /*!< Shifter Pin Configuration. */ + uint32_t pinSelect; /*!< Shifter Pin number Select. */ + flexio_pin_polarity_t pinPolarity; /*!< Shifter Pin Polarity. */ + /* Shifter. */ + flexio_shifter_mode_t shifterMode; /*!< Configures the mode of the Shifter. */ +#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH + uint32_t parallelWidth; /*!< Configures the parallel width when using parallel mode.*/ +#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */ + flexio_shifter_input_source_t inputSource; /*!< Selects the input source for the shifter. */ + flexio_shifter_stop_bit_t shifterStop; /*!< Shifter STOP bit. */ + flexio_shifter_start_bit_t shifterStart; /*!< Shifter START bit. */ +} flexio_shifter_config_t; + +/*! @brief typedef for FlexIO simulated driver interrupt handler.*/ +typedef void (*flexio_isr_t)(void *base, void *handle); + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name FlexIO Initialization and De-initialization + * @{ + */ + +/*! + * @brief Gets the default configuration to configure FlexIO module. The configuration + * can used directly for calling FLEXIO_Configure(). + * + * Example: + @code + flexio_config_t config; + FLEXIO_GetDefaultConfig(&config); + @endcode + * + * @param userConfig pointer to flexio_config_t structure +*/ +void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig); + +/*! + * @brief Configures the FlexIO with FlexIO configuration. The configuration structure + * can be filled by the user, or be set with default values by FLEXIO_GetDefaultConfig(). + * + * Example + @code + flexio_config_t config = { + .enableFlexio = true, + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false + }; + FLEXIO_Configure(base, &config); + @endcode + * + * @param base FlexIO peripheral base address + * @param userConfig pointer to flexio_config_t structure +*/ +void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig); + +/*! + * @brief Gates the FlexIO clock. Call this API to stop the FlexIO clock. + * + * @note After calling this API, call the FLEXO_Init to use the FlexIO module. + * + * @param base FlexIO peripheral base address +*/ +void FLEXIO_Deinit(FLEXIO_Type *base); + +/* @} */ + +/*! + * @name FlexIO Basic Operation + * @{ + */ + +/*! + * @brief Resets the FlexIO module. + * + * @param base FlexIO peripheral base address +*/ +void FLEXIO_Reset(FLEXIO_Type *base); + +/*! + * @brief Enables the FlexIO module operation. + * + * @param base FlexIO peripheral base address + * @param enable true to enable, false to disable. +*/ +static inline void FLEXIO_Enable(FLEXIO_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS +/*! + * @brief Reads the input data on each of the FlexIO pins. + * + * @param base FlexIO peripheral base address + * @return FlexIO pin input data +*/ +static inline uint32_t FLEXIO_ReadPinInput(FLEXIO_Type *base) +{ + return base->PIN; +} +#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/ + +#if defined(FSL_FEATURE_FLEXIO_HAS_STATE_MODE) && FSL_FEATURE_FLEXIO_HAS_STATE_MODE +/*! + * @brief Gets the current state pointer for state mode use. + * + * @param base FlexIO peripheral base address + * @return current state pointer +*/ +static inline uint8_t FLEXIO_GetShifterState(FLEXIO_Type *base) +{ + return ((base->SHIFTSTATE) & FLEXIO_SHIFTSTATE_STATE_MASK); +} +#endif /*FSL_FEATURE_FLEXIO_HAS_STATE_MODE*/ + +/*! + * @brief Configures the shifter with shifter configuration. The configuration structure + * covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper + * mode, select which timer controls the shifter to shift, whether to generate start bit/stop + * bit, and the polarity of start bit and stop bit. + * + * Example + @code + flexio_shifter_config_t config = { + .timerSelect = 0, + .timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive, + .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection, + .pinPolarity = kFLEXIO_PinActiveLow, + .shifterMode = kFLEXIO_ShifterModeTransmit, + .inputSource = kFLEXIO_ShifterInputFromPin, + .shifterStop = kFLEXIO_ShifterStopBitHigh, + .shifterStart = kFLEXIO_ShifterStartBitLow + }; + FLEXIO_SetShifterConfig(base, &config); + @endcode + * + * @param base FlexIO peripheral base address + * @param index shifter index + * @param shifterConfig pointer to flexio_shifter_config_t structure +*/ +void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig); +/*! + * @brief Configures the timer with the timer configuration. The configuration structure + * covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper + * mode, select trigger source for timer and the timer pin output and the timing for timer. + * + * Example + @code + flexio_timer_config_t config = { + .triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0), + .triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow, + .triggerSource = kFLEXIO_TimerTriggerSourceInternal, + .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection, + .pinSelect = 0, + .pinPolarity = kFLEXIO_PinActiveHigh, + .timerMode = kFLEXIO_TimerModeDual8BitBaudBit, + .timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset, + .timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput, + .timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput, + .timerDisable = kFLEXIO_TimerDisableOnTimerCompare, + .timerEnable = kFLEXIO_TimerEnableOnTriggerHigh, + .timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable, + .timerStart = kFLEXIO_TimerStartBitEnabled + }; + FLEXIO_SetTimerConfig(base, &config); + @endcode + * + * @param base FlexIO peripheral base address + * @param index timer index + * @param timerConfig pointer to flexio_timer_config_t structure +*/ +void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig); + +/* @} */ + +/*! + * @name FlexIO Interrupt Operation + * @{ + */ + +/*! + * @brief Enables the shifter status interrupt. The interrupt generates when the corresponding SSF is set. + * + * @param base FlexIO peripheral base address + * @param mask the shifter status mask which could be calculated by (1 << shifter index) + * @note for multiple shifter status interrupt enable, for example, two shifter status enable, could calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_EnableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTSIEN |= mask; +} + +/*! + * @brief Disables the shifter status interrupt. The interrupt won't generate when the corresponding SSF is set. + * + * @param base FlexIO peripheral base address + * @param mask the shifter status mask which could be calculated by (1 << shifter index) + * @note for multiple shifter status interrupt enable, for example, two shifter status enable, could calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_DisableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTSIEN &= ~mask; +} + +/*! + * @brief Enables the shifter error interrupt. The interrupt generates when the corresponding SEF is set. + * + * @param base FlexIO peripheral base address + * @param mask the shifter error mask which could be calculated by (1 << shifter index) + * @note for multiple shifter error interrupt enable, for example, two shifter error enable, could calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_EnableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTEIEN |= mask; +} + +/*! + * @brief Disables the shifter error interrupt. The interrupt won't generate when the corresponding SEF is set. + * + * @param base FlexIO peripheral base address + * @param mask the shifter error mask which could be calculated by (1 << shifter index) + * @note for multiple shifter error interrupt enable, for example, two shifter error enable, could calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_DisableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTEIEN &= ~mask; +} + +/*! + * @brief Enables the timer status interrupt. The interrupt generates when the corresponding SSF is set. + * + * @param base FlexIO peripheral base address + * @param mask the timer status mask which could be calculated by (1 << timer index) + * @note for multiple timer status interrupt enable, for example, two timer status enable, could calculate + * the mask by using ((1 << timer index0) | (1 << timer index1)) +*/ +static inline void FLEXIO_EnableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->TIMIEN |= mask; +} + +/*! + * @brief Disables the timer status interrupt. The interrupt won't generate when the corresponding SSF is set. + * + * @param base FlexIO peripheral base address + * @param mask the timer status mask which could be calculated by (1 << timer index) + * @note for multiple timer status interrupt enable, for example, two timer status enable, could calculate + * the mask by using ((1 << timer index0) | (1 << timer index1)) +*/ +static inline void FLEXIO_DisableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask) +{ + base->TIMIEN &= ~mask; +} + +/* @} */ + +/*! + * @name FlexIO Status Operation + * @{ + */ + +/*! + * @brief Gets the shifter status flags. + * + * @param base FlexIO peripheral base address + * @return shifter status flags +*/ +static inline uint32_t FLEXIO_GetShifterStatusFlags(FLEXIO_Type *base) +{ + return ((base->SHIFTSTAT) & FLEXIO_SHIFTSTAT_SSF_MASK); +} + +/*! + * @brief Clears the shifter status flags. + * + * @param base FlexIO peripheral base address + * @param mask the shifter status mask which could be calculated by (1 << shifter index) + * @note for clearing multiple shifter status flags, for example, two shifter status flags, could calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_ClearShifterStatusFlags(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTSTAT = mask; +} + +/*! + * @brief Gets the shifter error flags. + * + * @param base FlexIO peripheral base address + * @return shifter error flags +*/ +static inline uint32_t FLEXIO_GetShifterErrorFlags(FLEXIO_Type *base) +{ + return ((base->SHIFTERR) & FLEXIO_SHIFTERR_SEF_MASK); +} + +/*! + * @brief Clears the shifter error flags. + * + * @param base FlexIO peripheral base address + * @param mask the shifter error mask which could be calculated by (1 << shifter index) + * @note for clearing multiple shifter error flags, for example, two shifter error flags, could calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) +*/ +static inline void FLEXIO_ClearShifterErrorFlags(FLEXIO_Type *base, uint32_t mask) +{ + base->SHIFTERR = mask; +} + +/*! + * @brief Gets the timer status flags. + * + * @param base FlexIO peripheral base address + * @return timer status flags +*/ +static inline uint32_t FLEXIO_GetTimerStatusFlags(FLEXIO_Type *base) +{ + return ((base->TIMSTAT) & FLEXIO_TIMSTAT_TSF_MASK); +} + +/*! + * @brief Clears the timer status flags. + * + * @param base FlexIO peripheral base address + * @param mask the timer status mask which could be calculated by (1 << timer index) + * @note for clearing multiple timer status flags, for example, two timer status flags, could calculate + * the mask by using ((1 << timer index0) | (1 << timer index1)) +*/ +static inline void FLEXIO_ClearTimerStatusFlags(FLEXIO_Type *base, uint32_t mask) +{ + base->TIMSTAT = mask; +} + +/* @} */ + +/*! + * @name FlexIO DMA Operation + * @{ + */ + +/*! + * @brief Enables/disables the shifter status DMA. The DMA request generates when the corresponding SSF is set. + * + * @note For multiple shifter status DMA enables, for example, calculate + * the mask by using ((1 << shifter index0) | (1 << shifter index1)) + * + * @param base FlexIO peripheral base address + * @param mask the shifter status mask which could be calculated by (1 << shifter index) + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_EnableShifterStatusDMA(FLEXIO_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->SHIFTSDEN |= mask; + } + else + { + base->SHIFTSDEN &= ~mask; + } +} + +/*! + * @brief Gets the shifter buffer address for the DMA transfer usage. + * + * @param base FlexIO peripheral base address + * @param type shifter type of flexio_shifter_buffer_type_t + * @param index shifter index + * @return corresponding shifter buffer index +*/ +uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index); + +/*! + * @brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral. + * + * @param base pointer to FlexIO simulated peripheral type. + * @param handle pointer to handler for FlexIO simulated peripheral. + * @param isr FlexIO simulated peripheral interrupt handler. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. +*/ +status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr); + +/*! + * @brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral. + * + * @param base pointer to FlexIO simulated peripheral type. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. +*/ +status_t FLEXIO_UnregisterHandleIRQ(void *base); +/* @} */ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /*_FSL_FLEXIO_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2c_master.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2c_master.c new file mode 100644 index 0000000000..0d7f20fc9e --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2c_master.c @@ -0,0 +1,732 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_i2c_master.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief FLEXIO I2C transfer state */ +enum _flexio_i2c_master_transfer_states +{ + kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */ + kFLEXIO_I2C_CheckAddress = 0x1U, /*!< 7-bit address check state */ + kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */ + kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/ + kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/ + kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/ +}; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Set up master transfer, send slave address and decide the initial + * transfer state. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state + * @param transfer pointer to flexio_i2c_master_transfer_t structure + */ +static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer); + +/*! + * @brief Master run transfer state machine to perform a byte of transfer. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state + * @param statusFlags flexio i2c hardware status + * @retval kStatus_Success Successfully run state machine + * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer + */ +static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + uint32_t statusFlags); + +/*! + * @brief Complete transfer, disable interrupt and call callback. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state + * @param status flexio transfer status + */ +static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + status_t status); + +/******************************************************************************* + * Codes + ******************************************************************************/ + +static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer) +{ + bool needRestart; + uint32_t byteCount; + + /* Init the handle member. */ + handle->transfer.slaveAddress = xfer->slaveAddress; + handle->transfer.direction = xfer->direction; + handle->transfer.subaddress = xfer->subaddress; + handle->transfer.subaddressSize = xfer->subaddressSize; + handle->transfer.data = xfer->data; + handle->transfer.dataSize = xfer->dataSize; + handle->transfer.flags = xfer->flags; + handle->transferSize = xfer->dataSize; + + /* Initial state, i2c check address state. */ + handle->state = kFLEXIO_I2C_CheckAddress; + + /* Clear all status before transfer. */ + FLEXIO_I2C_MasterClearStatusFlags(base, kFLEXIO_I2C_ReceiveNakFlag); + + /* Calculate whether need to send re-start. */ + needRestart = (handle->transfer.subaddressSize != 0) && (handle->transfer.direction == kFLEXIO_I2C_Read); + + /* Calculate total byte count in a frame. */ + byteCount = 1; + + if (!needRestart) + { + byteCount += handle->transfer.dataSize; + } + + if (handle->transfer.subaddressSize != 0) + { + byteCount += handle->transfer.subaddressSize; + /* Next state, send command byte. */ + handle->state = kFLEXIO_I2C_SendCommand; + } + + /* Configure data count. */ + if (FLEXIO_I2C_MasterSetTransferCount(base, byteCount) != kStatus_Success) + { + return kStatus_InvalidArgument; + } + + while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))) + { + } + + /* Send address byte first. */ + if (needRestart) + { + FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write); + } + else + { + FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction); + } + + return kStatus_Success; +} + +static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + uint32_t statusFlags) +{ + if (statusFlags & kFLEXIO_I2C_ReceiveNakFlag) + { + /* Clear receive nak flag. */ + FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); + + if ((!((handle->state == kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) && + (!(((handle->state == kFLEXIO_I2C_ReceiveData) || (handle->state == kFLEXIO_I2C_ReceiveDataBegin)) && + (handle->transfer.dataSize == 1U)))) + { + FLEXIO_I2C_MasterReadByte(base); + + FLEXIO_I2C_MasterAbortStop(base); + + handle->state = kFLEXIO_I2C_Idle; + + return kStatus_FLEXIO_I2C_Nak; + } + } + + if (handle->state == kFLEXIO_I2C_CheckAddress) + { + if (handle->transfer.direction == kFLEXIO_I2C_Write) + { + /* Next state, send data. */ + handle->state = kFLEXIO_I2C_SendData; + } + else + { + /* Next state, receive data begin. */ + handle->state = kFLEXIO_I2C_ReceiveDataBegin; + } + } + + if ((statusFlags & kFLEXIO_I2C_RxFullFlag) && (handle->state != kFLEXIO_I2C_ReceiveData)) + { + FLEXIO_I2C_MasterReadByte(base); + } + + switch (handle->state) + { + case kFLEXIO_I2C_SendCommand: + if (statusFlags & kFLEXIO_I2C_TxEmptyFlag) + { + if (handle->transfer.subaddressSize > 0) + { + handle->transfer.subaddressSize--; + FLEXIO_I2C_MasterWriteByte( + base, ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize))); + + if (handle->transfer.subaddressSize == 0) + { + /* Load re-start in advance. */ + if (handle->transfer.direction == kFLEXIO_I2C_Read) + { + while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))) + { + } + FLEXIO_I2C_MasterRepeatedStart(base); + } + } + } + else + { + if (handle->transfer.direction == kFLEXIO_I2C_Write) + { + /* Next state, send data. */ + handle->state = kFLEXIO_I2C_SendData; + + /* Send first byte of data. */ + if (handle->transfer.dataSize > 0) + { + FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data); + + handle->transfer.data++; + handle->transfer.dataSize--; + } + } + else + { + FLEXIO_I2C_MasterSetTransferCount(base, (handle->transfer.dataSize + 1)); + FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read); + + /* Next state, receive data begin. */ + handle->state = kFLEXIO_I2C_ReceiveDataBegin; + } + } + } + break; + + /* Send command byte. */ + case kFLEXIO_I2C_SendData: + if (statusFlags & kFLEXIO_I2C_TxEmptyFlag) + { + /* Send one byte of data. */ + if (handle->transfer.dataSize > 0) + { + FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data); + + handle->transfer.data++; + handle->transfer.dataSize--; + } + else + { + FLEXIO_I2C_MasterStop(base); + handle->state = kFLEXIO_I2C_Idle; + } + } + break; + + case kFLEXIO_I2C_ReceiveDataBegin: + if (statusFlags & kFLEXIO_I2C_TxEmptyFlag) + { + /* Read one byte of data. */ + FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); + + /* Send nak at the last receive byte. */ + if (handle->transfer.dataSize == 1) + { + FLEXIO_I2C_MasterEnableAck(base, false); + while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))) + { + } + FLEXIO_I2C_MasterStop(base); + } + else + { + FLEXIO_I2C_MasterEnableAck(base, true); + } + } + else + { + handle->state = kFLEXIO_I2C_ReceiveData; + } + break; + + case kFLEXIO_I2C_ReceiveData: + if (statusFlags & kFLEXIO_I2C_RxFullFlag) + { + *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base); + handle->transfer.data++; + /* Receive one byte of data. */ + if (handle->transfer.dataSize--) + { + if (handle->transfer.dataSize != 0) + { + FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); + } + else + { + FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_RxFullInterruptEnable); + handle->state = kFLEXIO_I2C_Idle; + } + + /* Send nak at the last receive byte. */ + if (handle->transfer.dataSize == 1) + { + FLEXIO_I2C_MasterEnableAck(base, false); + while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])))) + { + } + FLEXIO_I2C_MasterStop(base); + } + } + } + break; + + default: + break; + } + + return kStatus_Success; +} + +static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + status_t status) +{ + FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable); + + if (handle->completionCallback) + { + handle->completionCallback(base, handle, status, handle->userData); + } +} + +void FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz) +{ + assert(base && masterConfig); + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + uint32_t controlVal = 0; + + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + + /* Ungate flexio clock. */ + CLOCK_EnableClock(kCLOCK_Flexio0); + + FLEXIO_Reset(base->flexioBase); + + /* Do hardware configuration. */ + /* 1. Configure the shifter 0 for tx. */ + shifterConfig.timerSelect = base->timerIndex[1]; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection; + shifterConfig.pinSelect = base->SDAPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveLow; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); + + /* 2. Configure the shifter 1 for rx. */ + shifterConfig.timerSelect = base->timerIndex[1]; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->SDAPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); + + /*3. Configure the timer 0 for generating bit clock. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection; + timerConfig.pinSelect = base->SCLPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1. */ + timerConfig.timerCompare = (srcClock_Hz / masterConfig->baudRate_Bps) / 2 - 1; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); + + /* 4. Configure the timer 1 for controlling shifters. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->SCLPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */ + timerConfig.timerCompare = 8 * 2 - 1; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); + + /* Configure FLEXIO I2C Master. */ + controlVal = base->flexioBase->CTRL; + controlVal &= + ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + controlVal |= + (FLEXIO_CTRL_DOZEN(masterConfig->enableInDoze) | FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | + FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster)); + + base->flexioBase->CTRL = controlVal; +} + +void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base) +{ + FLEXIO_Deinit(base->flexioBase); +} + +void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig) +{ + assert(masterConfig); + + masterConfig->enableMaster = true; + masterConfig->enableInDoze = false; + masterConfig->enableInDebug = true; + masterConfig->enableFastAccess = false; + + /* Default baud rate at 100kbps. */ + masterConfig->baudRate_Bps = 100000U; +} + +uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base) +{ + uint32_t status = 0; + + status = + ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]); + status |= + (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) + << 1U); + status |= + (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) + << 2U); + + return status; +} + +void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2C_TxEmptyFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]); + } + + if (mask & kFLEXIO_I2C_RxFullFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } + + if (mask & kFLEXIO_I2C_ReceiveNakFlag) + { + FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_I2C_RxFullInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_I2C_RxFullInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + uint16_t timerDiv = 0; + uint16_t timerCmp = 0; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/ + timerDiv = srcClock_Hz / baudRate_Bps; + timerDiv = timerDiv / 2 - 1U; + + timerCmp = flexioBase->TIMCMP[base->timerIndex[0]]; + timerCmp &= 0xFF00; + timerCmp |= timerDiv; + + flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp; +} + +status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count) +{ + if (count > 14U) + { + return kStatus_InvalidArgument; + } + + uint16_t timerCmp = 0; + uint32_t timerConfig = 0; + FLEXIO_Type *flexioBase = base->flexioBase; + + timerCmp = flexioBase->TIMCMP[base->timerIndex[0]]; + timerCmp &= 0x00FFU; + timerCmp |= (count * 18 + 1U) << 8U; + flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp; + timerConfig = flexioBase->TIMCFG[base->timerIndex[0]]; + timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK; + timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare); + flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig; + + return kStatus_Success; +} + +void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction) +{ + uint32_t data; + + data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U); + + FLEXIO_I2C_MasterWriteByte(base, data); +} + +void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base) +{ + /* Prepare for RESTART condition, no stop.*/ + FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); +} + +void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base) +{ + /* Prepare normal stop. */ + FLEXIO_I2C_MasterSetTransferCount(base, 0x0U); + FLEXIO_I2C_MasterWriteByte(base, 0x0U); +} + +void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base) +{ + uint32_t tmpConfig; + + /* Prepare abort stop. */ + tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]]; + tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK; + tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge); + base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig; +} + +void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable) +{ + uint32_t tmpConfig = 0; + + tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]]; + tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK; + if (enable) + { + tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow); + } + else + { + tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh); + } + base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig; +} + +status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize) +{ + assert(txBuff); + assert(txSize); + + uint32_t status; + + while (txSize--) + { + FLEXIO_I2C_MasterWriteByte(base, *txBuff++); + + /* Wait until data transfer complete. */ + while (!((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & kFLEXIO_I2C_RxFullFlag)) + { + } + + if (status & kFLEXIO_I2C_ReceiveNakFlag) + { + FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); + return kStatus_FLEXIO_I2C_Nak; + } + } + return kStatus_Success; +} + +void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize) +{ + assert(rxBuff); + assert(rxSize); + + while (rxSize--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag)) + { + } + + *rxBuff++ = FLEXIO_I2C_MasterReadByte(base); + } +} + +status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Register callback and userData. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[0]); + + /* Save the context in global variables to support the double weak mechanism. */ + return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ); +} + +status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + if (handle->state != kFLEXIO_I2C_Idle) + { + return kStatus_FLEXIO_I2C_Busy; + } + else + { + /* Set up transfer machine. */ + FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer); + + /* Enable both tx empty and rxfull interrupt. */ + FLEXIO_I2C_MasterEnableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable); + + return kStatus_Success; + } +} + +void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle) +{ + assert(handle); + + /* Disable interrupts. */ + FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable); + + /* Reset to idle state. */ + handle->state = kFLEXIO_I2C_Idle; +} + +status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count) +{ + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->transferSize - handle->transfer.dataSize; + + return kStatus_Success; +} + +void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle) +{ + FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType; + flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle; + uint32_t statusFlags; + status_t result; + + statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base); + + result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags); + + if (handle->state == kFLEXIO_I2C_Idle) + { + FLEXIO_I2C_MasterTransferComplete(base, handle, result); + } +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2c_master.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2c_master.h new file mode 100644 index 0000000000..1ebea372a6 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2c_master.h @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_I2C_MASTER_H_ +#define _FSL_FLEXIO_I2C_MASTER_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_i2c_master + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO I2C master driver version 2.1.0. */ +#define FSL_FLEXIO_I2C_MASTER_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief FlexIO I2C transfer status*/ +enum _flexio_i2c_status +{ + kStatus_FLEXIO_I2C_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 0), /*!< I2C is busy doing transfer. */ + kStatus_FLEXIO_I2C_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 1), /*!< I2C is busy doing transfer. */ + kStatus_FLEXIO_I2C_Nak = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 2), /*!< NAK received during transfer. */ +}; + +/*! @brief Define FlexIO I2C master interrupt mask. */ +enum _flexio_i2c_master_interrupt +{ + kFLEXIO_I2C_TxEmptyInterruptEnable = 0x1U, /*!< Tx buffer empty interrupt enable. */ + kFLEXIO_I2C_RxFullInterruptEnable = 0x2U, /*!< Rx buffer full interrupt enable. */ +}; + +/*! @brief Define FlexIO I2C master status mask. */ +enum _flexio_i2c_master_status_flags +{ + kFLEXIO_I2C_TxEmptyFlag = 0x1U, /*!< Tx shifter empty flag. */ + kFLEXIO_I2C_RxFullFlag = 0x2U, /*!< Rx shifter full/Transfer complete flag. */ + kFLEXIO_I2C_ReceiveNakFlag = 0x4U, /*!< Receive NAK flag. */ +}; + +/*! @brief Direction of master transfer.*/ +typedef enum _flexio_i2c_direction +{ + kFLEXIO_I2C_Write = 0x0U, /*!< Master send to slave. */ + kFLEXIO_I2C_Read = 0x1U, /*!< Master receive from slave. */ +} flexio_i2c_direction_t; + +/*! @brief Define FlexIO I2C master access structure typedef. */ +typedef struct _flexio_i2c_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */ + uint8_t SDAPinIndex; /*!< Pin select for I2C SDA. */ + uint8_t SCLPinIndex; /*!< Pin select for I2C SCL. */ + uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO I2C. */ + uint8_t timerIndex[2]; /*!< Timer index used in FlexIO I2C. */ +} FLEXIO_I2C_Type; + +/*! @brief Define FlexIO I2C master user configuration structure. */ +typedef struct _flexio_i2c_master_config +{ + bool enableMaster; /*!< Enables the FLEXIO I2C peripheral at initialization time. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires + the FlexIO clock to be at least twice the frequency of the bus clock. */ + uint32_t baudRate_Bps; /*!< Baud rate in Bps. */ +} flexio_i2c_master_config_t; + +/*! @brief Define FlexIO I2C master transfer structure. */ +typedef struct _flexio_i2c_master_transfer +{ + uint32_t flags; /*!< Transfer flag which controls the transfer, reserved for flexio i2c. */ + uint8_t slaveAddress; /*!< 7-bit slave address. */ + flexio_i2c_direction_t direction; /*!< Transfer direction, read or write. */ + uint32_t subaddress; /*!< Sub address. Transferred MSB first. */ + uint8_t subaddressSize; /*!< Size of command buffer. */ + uint8_t volatile *data; /*!< Transfer buffer. */ + volatile size_t dataSize; /*!< Transfer size. */ +} flexio_i2c_master_transfer_t; + +/*! @brief FlexIO I2C master handle typedef. */ +typedef struct _flexio_i2c_master_handle flexio_i2c_master_handle_t; + +/*! @brief FlexIO I2C master transfer callback typedef. */ +typedef void (*flexio_i2c_master_transfer_callback_t)(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + status_t status, + void *userData); + +/*! @brief Define FlexIO I2C master handle structure. */ +struct _flexio_i2c_master_handle +{ + flexio_i2c_master_transfer_t transfer; /*!< FlexIO I2C master transfer copy. */ + size_t transferSize; /*!< Total bytes to be transferred. */ + uint8_t state; /*!< Transfer state maintained during transfer. */ + flexio_i2c_master_transfer_callback_t completionCallback; /*!< Callback function called at transfer event. */ + /*!< Callback function called at transfer event. */ + void *userData; /*!< Callback parameter passed to callback function. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C + * hardware configuration. + * + * Example + @code + FLEXIO_I2C_Type base = { + .flexioBase = FLEXIO, + .SDAPinIndex = 0, + .SCLPinIndex = 1, + .shifterIndex = {0,1}, + .timerIndex = {0,1} + }; + flexio_i2c_master_config_t config = { + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false, + .baudRate_Bps = 100000 + }; + FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz); + @endcode + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param masterConfig pointer to flexio_i2c_master_config_t structure. + * @param srcClock_Hz FlexIO source clock in Hz. +*/ +void FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz); + +/*! + * @brief De-initializes the FlexIO I2C master peripheral. Calling this API gates the FlexIO clock, + * so the FlexIO I2C master module can't work unless call FLEXIO_I2C_MasterInit. + * + * @param base pointer to FLEXIO_I2C_Type structure. + */ +void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO module. The configuration + * can be used directly for calling FLEXIO_I2C_MasterInit(). + * + * Example: + @code + flexio_i2c_master_config_t config; + FLEXIO_I2C_MasterGetDefaultConfig(&config); + @endcode + * @param masterConfig pointer to flexio_i2c_master_config_t structure. +*/ +void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig); + +/*! + * @brief Enables/disables the FlexIO module operation. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param enable pass true to enable module, false to disable module. +*/ +static inline void FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the FlexIO I2C master status flags. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @return status flag, use status flag to AND #_flexio_i2c_master_status_flags could get the related status. +*/ + +uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base); + +/*! + * @brief Clears the FlexIO I2C master status flags. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param mask status flag. + * The parameter could be any combination of the following values: + * @arg kFLEXIO_I2C_RxFullFlag + * @arg kFLEXIO_I2C_ReceiveNakFlag +*/ + +void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask); + +/*@}*/ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the FlexIO i2c master interrupt requests. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param mask interrupt source. + * Currently only one interrupt request source: + * @arg kFLEXIO_I2C_TransferCompleteInterruptEnable + */ +void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask); + +/*! + * @brief Disables the FlexIO I2C master interrupt requests. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param mask interrupt source. + */ +void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask); + +/*@}*/ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Sets the FlexIO I2C master transfer baudrate. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param baudRate_Bps the baud rate value in HZ + * @param srcClock_Hz source clock in HZ + */ +void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Sends START + 7-bit address to the bus. + * + * @note This is API should be called when transfer configuration is ready to send a START signal + * and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address + * is put into the data register but not address transfer finished on the bus. Ensure that + * the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API. + * @param base pointer to FLEXIO_I2C_Type structure. + * @param address 7-bit address. + * @param direction transfer direction. + * This parameter is one of the values in flexio_i2c_direction_t: + * @arg kFLEXIO_I2C_Write: Transmit + * @arg kFLEXIO_I2C_Read: Receive + */ + +void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction); + +/*! + * @brief Sends the stop signal on the bus. + * + * @param base pointer to FLEXIO_I2C_Type structure. + */ +void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base); + +/*! + * @brief Sends the repeated start signal on the bus. + * + * @param base pointer to FLEXIO_I2C_Type structure. + */ +void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base); + +/*! + * @brief Sends the stop signal when transfer is still on-going. + * + * @param base pointer to FLEXIO_I2C_Type structure. + */ +void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base); + +/*! + * @brief Configures the sent ACK/NAK for the following byte. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param enable true to configure send ACK, false configure to send NAK. + */ +void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable); + +/*! + * @brief Sets the number of bytes to be transferred from a start signal to a stop signal. + * + * @note Call this API before a transfer begins because the timer generates a number of clocks according + * to the number of bytes that need to be transferred. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param count number of bytes need to be transferred from a start signal to a re-start/stop signal + * @retval kStatus_Success Successfully configured the count. + * @retval kStatus_InvalidArgument Input argument is invalid. +*/ +status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count); + +/*! + * @brief Writes one byte of data to the I2C bus. + * + * @note This is a non-blocking API, which returns directly after the data is put into the + * data register but not data transfer finished on the bus. Ensure that + * the TxEmptyFlag is asserted before calling this API. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param data a byte of data. + */ +static inline void FLEXIO_I2C_MasterWriteByte(FLEXIO_I2C_Type *base, uint32_t data) +{ + base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data; +} + +/*! + * @brief Reads one byte of data from the I2C bus. + * + * @note This is a non-blocking API, which returns directly after the data is read from the + * data register. Ensure that the data is ready in the register. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @return data byte read. + */ +static inline uint8_t FLEXIO_I2C_MasterReadByte(FLEXIO_I2C_Type *base) +{ + return base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]]; +} + +/*! + * @brief Sends a buffer of data in bytes. + * + * @note This function blocks via polling until all bytes have been sent. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param txBuff The data bytes to send. + * @param txSize The number of data bytes to send. + * @retval kStatus_Success Successfully write data. + * @retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data. + */ +status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize); + +/*! + * @brief Receives a buffer of bytes. + * + * @note This function blocks via polling until all bytes have been received. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param rxBuff The buffer to store the received bytes. + * @param rxSize The number of data bytes to be received. + */ +void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize); + +/*! + * @brief Performs a master polling transfer on the I2C bus. + * + * @note The API does not return until the transfer succeeds or fails due + * to receiving NAK. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state. + * @param xfer pointer to flexio_i2c_master_transfer_t structure. + * @return status of status_t. + */ +status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer); +/*@}*/ + +/*Transactional APIs*/ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the I2C handle which is used in transactional functions. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param handle pointer to flexio_i2c_master_handle_t structure to store the transfer state. + * @param callback pointer to user callback function. + * @param userData user param passed to the callback function. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range. + */ +status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_callback_t callback, + void *userData); + +/*! + * @brief Performs a master interrupt non-blocking transfer on the I2C bus. + * + * @note The API returns immediately after the transfer initiates. + * Call FLEXIO_I2C_MasterGetTransferCount to poll the transfer status to check whether + * the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer + * is finished. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state + * @param xfer pointer to flexio_i2c_master_transfer_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_FLEXIO_I2C_Busy FLEXIO I2C is not idle, is running another transfer. + */ +status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base, + flexio_i2c_master_handle_t *handle, + flexio_i2c_master_transfer_t *xfer); + +/*! + * @brief Gets the master transfer status during a interrupt non-blocking transfer. + * + * @param base pointer to FLEXIO_I2C_Type structure. + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count); + +/*! + * @brief Aborts an interrupt non-blocking transfer early. + * + * @note This API can be called at any time when an interrupt non-blocking transfer initiates + * to abort the transfer early. + * + * @param base pointer to FLEXIO_I2C_Type structure + * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state + */ +void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle); + +/*! + * @brief Master interrupt handler. + * + * @param i2cType pointer to FLEXIO_I2C_Type structure + * @param i2cHandle pointer to flexio_i2c_master_transfer_t structure + */ +void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /*_FSL_FLEXIO_I2C_MASTER_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s.c new file mode 100644 index 0000000000..3bace5b7bf --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s.c @@ -0,0 +1,637 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_i2s.h" + +/******************************************************************************* +* Definitations +******************************************************************************/ +enum _sai_transfer_state +{ + kFLEXIO_I2S_Busy = 0x0U, /*!< FLEXIO_I2S is busy */ + kFLEXIO_I2S_Idle, /*!< Transfer is done. */ +}; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Receive a piece of data in non-blocking way. + * + * @param base FLEXIO I2S base pointer + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be read. + * @param size Bytes to be read. + */ +static void FLEXIO_I2S_ReadNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size); + +/*! + * @brief sends a piece of data in non-blocking way. + * + * @param base FLEXIO I2S base pointer + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be written. + * @param size Bytes to be written. + */ +static void FLEXIO_I2S_WriteNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size); +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +static void FLEXIO_I2S_WriteNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size) +{ + uint32_t i = 0; + uint8_t j = 0; + uint8_t bytesPerWord = bitWidth / 8U; + uint32_t data = 0; + uint32_t temp = 0; + + for (i = 0; i < size / bytesPerWord; i++) + { + for (j = 0; j < bytesPerWord; j++) + { + temp = (uint32_t)(*txData); + data |= (temp << (8U * j)); + txData++; + } + base->flexioBase->SHIFTBUFBIS[base->txShifterIndex] = (data << (32U - bitWidth)); + data = 0; + } +} + +static void FLEXIO_I2S_ReadNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size) +{ + uint32_t i = 0; + uint8_t j = 0; + uint8_t bytesPerWord = bitWidth / 8U; + uint32_t data = 0; + + for (i = 0; i < size / bytesPerWord; i++) + { + data = base->flexioBase->SHIFTBUFBIS[base->rxShifterIndex]; + for (j = 0; j < bytesPerWord; j++) + { + *rxData = (data >> (8U * j)) & 0xFF; + rxData++; + } + } +} + +void FLEXIO_I2S_Init(FLEXIO_I2S_Type *base, const flexio_i2s_config_t *config) +{ + assert(base && config); + + flexio_shifter_config_t shifterConfig = {0}; + flexio_timer_config_t timerConfig = {0}; + + /* Ungate flexio clock. */ + CLOCK_EnableClock(kCLOCK_Flexio0); + + FLEXIO_Reset(base->flexioBase); + + /* Set shifter for I2S Tx data */ + shifterConfig.timerSelect = base->bclkTimerIndex; + shifterConfig.pinSelect = base->txPinIndex; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + if (config->masterSlave == kFLEXIO_I2S_Master) + { + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; + } + else + { + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->txShifterIndex, &shifterConfig); + + /* Set shifter for I2S Rx Data */ + shifterConfig.timerSelect = base->bclkTimerIndex; + shifterConfig.pinSelect = base->rxPinIndex; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + + FLEXIO_SetShifterConfig(base->flexioBase, base->rxShifterIndex, &shifterConfig); + + /* Set Timer to I2S frame sync */ + if (config->masterSlave == kFLEXIO_I2S_Master) + { + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->bclkTimerIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutput; + timerConfig.pinSelect = base->fsPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableNever; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + } + else + { + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->bclkPinIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->fsPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + } + FLEXIO_SetTimerConfig(base->flexioBase, base->fsTimerIndex, &timerConfig); + + /* Set Timer to I2S bit clock */ + if (config->masterSlave == kFLEXIO_I2S_Master) + { + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->txShifterIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinSelect = base->bclkPinIndex; + timerConfig.pinConfig = kFLEXIO_PinConfigOutput; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableNever; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + } + else + { + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->fsTimerIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinSelect = base->bclkPinIndex; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompareTriggerLow; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + } + FLEXIO_SetTimerConfig(base->flexioBase, base->bclkTimerIndex, &timerConfig); + + /* If enable flexio I2S */ + if (config->enableI2S) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +void FLEXIO_I2S_GetDefaultConfig(flexio_i2s_config_t *config) +{ + config->masterSlave = kFLEXIO_I2S_Master; + config->enableI2S = true; +} + +void FLEXIO_I2S_Deinit(FLEXIO_I2S_Type *base) +{ + /* Disable FLEXIO I2S module. */ + FLEXIO_I2S_Enable(base, false); + + /* Gate flexio clock. */ + CLOCK_DisableClock(kCLOCK_Flexio0); +} + +void FLEXIO_I2S_EnableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2S_TxDataRegEmptyInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->txShifterIndex); + } + if (mask & kFLEXIO_I2S_RxDataRegFullInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->rxShifterIndex); + } +} + +uint32_t FLEXIO_I2S_GetStatusFlags(FLEXIO_I2S_Type *base) +{ + uint32_t status = 0; + status = ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->txShifterIndex)) >> base->txShifterIndex); + status |= + (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->rxShifterIndex)) >> (base->rxShifterIndex)) + << 1U); + return status; +} + +void FLEXIO_I2S_DisableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_I2S_TxDataRegEmptyInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->txShifterIndex); + } + if (mask & kFLEXIO_I2S_RxDataRegFullInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->rxShifterIndex); + } +} + +void FLEXIO_I2S_MasterSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format, uint32_t srcClock_Hz) +{ + uint32_t timDiv = srcClock_Hz / (format->sampleRate_Hz * 32U * 2U); + uint32_t bclkDiv = 0; + + /* Set Frame sync timer cmp */ + base->flexioBase->TIMCMP[base->fsTimerIndex] = FLEXIO_TIMCMP_CMP(32U * timDiv - 1U); + + /* Set bit clock timer cmp */ + bclkDiv = ((timDiv / 2U - 1U) | (63U << 8U)); + base->flexioBase->TIMCMP[base->bclkTimerIndex] = FLEXIO_TIMCMP_CMP(bclkDiv); +} + +void FLEXIO_I2S_SlaveSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format) +{ + /* Set Frame sync timer cmp */ + base->flexioBase->TIMCMP[base->fsTimerIndex] = FLEXIO_TIMCMP_CMP(format->bitWidth * 4U - 3U); + + /* Set bit clock timer cmp */ + base->flexioBase->TIMCMP[base->bclkTimerIndex] = FLEXIO_TIMCMP_CMP(format->bitWidth * 2U - 1U); +} + +void FLEXIO_I2S_WriteBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size) +{ + uint32_t i = 0; + uint8_t bytesPerWord = bitWidth / 8U; + + for (i = 0; i < size / bytesPerWord; i++) + { + /* Wait until it can write data */ + while ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) == 0) + { + } + + FLEXIO_I2S_WriteNonBlocking(base, bitWidth, txData, bytesPerWord); + txData += bytesPerWord; + } + + /* Wait until the last data is sent */ + while ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) == 0) + { + } +} + +void FLEXIO_I2S_ReadBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size) +{ + uint32_t i = 0; + uint8_t bytesPerWord = bitWidth / 8U; + + for (i = 0; i < size / bytesPerWord; i++) + { + /* Wait until data is received */ + while (!(FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->rxShifterIndex))) + { + } + + FLEXIO_I2S_ReadNonBlocking(base, bitWidth, rxData, bytesPerWord); + rxData += bytesPerWord; + } +} + +void FLEXIO_I2S_TransferTxCreateHandle(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Store callback and user data. */ + handle->callback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2S_TransferTxHandleIRQ); + + /* Set the TX/RX state. */ + handle->state = kFLEXIO_I2S_Idle; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[0]); +} + +void FLEXIO_I2S_TransferRxCreateHandle(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Store callback and user data. */ + handle->callback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2S_TransferRxHandleIRQ); + + /* Set the TX/RX state. */ + handle->state = kFLEXIO_I2S_Idle; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[0]); +} + +void FLEXIO_I2S_TransferSetFormat(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_format_t *format, + uint32_t srcClock_Hz) +{ + assert(handle && format); + + /* Set the bitWidth to handle */ + handle->bitWidth = format->bitWidth; + + /* Set sample rate */ + if (srcClock_Hz != 0) + { + /* It is master */ + FLEXIO_I2S_MasterSetFormat(base, format, srcClock_Hz); + } + else + { + FLEXIO_I2S_SlaveSetFormat(base, format); + } +} + +status_t FLEXIO_I2S_TransferSendNonBlocking(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_transfer_t *xfer) +{ + assert(handle); + + /* Check if the queue is full */ + if (handle->queue[handle->queueUser].data) + { + return kStatus_FLEXIO_I2S_QueueFull; + } + if ((xfer->dataSize == 0) || (xfer->data == NULL)) + { + return kStatus_InvalidArgument; + } + + /* Add into queue */ + handle->queue[handle->queueUser].data = xfer->data; + handle->queue[handle->queueUser].dataSize = xfer->dataSize; + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + + /* Set the state to busy */ + handle->state = kFLEXIO_I2S_Busy; + + FLEXIO_I2S_EnableInterrupts(base, kFLEXIO_I2S_TxDataRegEmptyInterruptEnable); + + /* Enable Tx transfer */ + FLEXIO_I2S_Enable(base, true); + + return kStatus_Success; +} + +status_t FLEXIO_I2S_TransferReceiveNonBlocking(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_transfer_t *xfer) +{ + assert(handle); + + /* Check if the queue is full */ + if (handle->queue[handle->queueUser].data) + { + return kStatus_FLEXIO_I2S_QueueFull; + } + + if ((xfer->dataSize == 0) || (xfer->data == NULL)) + { + return kStatus_InvalidArgument; + } + + /* Add into queue */ + handle->queue[handle->queueUser].data = xfer->data; + handle->queue[handle->queueUser].dataSize = xfer->dataSize; + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + + /* Set state to busy */ + handle->state = kFLEXIO_I2S_Busy; + + /* Enable interrupt */ + FLEXIO_I2S_EnableInterrupts(base, kFLEXIO_I2S_RxDataRegFullInterruptEnable); + + /* Enable Rx transfer */ + FLEXIO_I2S_Enable(base, true); + + return kStatus_Success; +} + +void FLEXIO_I2S_TransferAbortSend(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle) +{ + assert(handle); + + /* Stop Tx transfer and disable interrupt */ + FLEXIO_I2S_Enable(base, false); + + FLEXIO_I2S_DisableInterrupts(base, kFLEXIO_I2S_TxDataRegEmptyInterruptEnable); + handle->state = kFLEXIO_I2S_Idle; + + /* Clear the queue */ + memset(handle->queue, 0, sizeof(flexio_i2s_transfer_t) * FLEXIO_I2S_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +void FLEXIO_I2S_TransferAbortReceive(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle) +{ + assert(handle); + + /* Stop Tx transfer and disable interrupt */ + FLEXIO_I2S_Enable(base, false); + + FLEXIO_I2S_DisableInterrupts(base, kFLEXIO_I2S_RxDataRegFullInterruptEnable); + handle->state = kFLEXIO_I2S_Idle; + + /* Clear the queue */ + memset(handle->queue, 0, sizeof(flexio_i2s_transfer_t) * FLEXIO_I2S_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +status_t FLEXIO_I2S_TransferGetSendCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kFLEXIO_I2S_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - handle->queue[handle->queueDriver].dataSize); + } + + return status; +} + +status_t FLEXIO_I2S_TransferGetReceiveCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kFLEXIO_I2S_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - handle->queue[handle->queueDriver].dataSize); + } + + return status; +} + +void FLEXIO_I2S_TransferTxHandleIRQ(void *i2sBase, void *i2sHandle) +{ + assert(i2sHandle); + + flexio_i2s_handle_t *handle = (flexio_i2s_handle_t *)i2sHandle; + FLEXIO_I2S_Type *base = (FLEXIO_I2S_Type *)i2sBase; + uint8_t *buffer = handle->queue[handle->queueDriver].data; + uint8_t dataSize = handle->bitWidth / 8U; + + /* Handle error */ + if (FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->txShifterIndex)) + { + FLEXIO_ClearShifterErrorFlags(base->flexioBase, (1U << base->txShifterIndex)); + } + /* Handle transfer */ + if ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_TxDataRegEmptyFlag) != 0) + { + FLEXIO_I2S_WriteNonBlocking(base, handle->bitWidth, buffer, dataSize); + + /* Update internal counter */ + handle->queue[handle->queueDriver].dataSize -= dataSize; + handle->queue[handle->queueDriver].data += dataSize; + } + + /* If finished a blcok, call the callback function */ + if (handle->queue[handle->queueDriver].dataSize == 0U) + { + memset(&handle->queue[handle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); + handle->queueDriver = (handle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_Success, handle->userData); + } + } + + /* If all data finished, just stop the transfer */ + if (handle->queue[handle->queueDriver].data == NULL) + { + FLEXIO_I2S_TransferAbortSend(base, handle); + } +} + +void FLEXIO_I2S_TransferRxHandleIRQ(void *i2sBase, void *i2sHandle) +{ + assert(i2sHandle); + + flexio_i2s_handle_t *handle = (flexio_i2s_handle_t *)i2sHandle; + FLEXIO_I2S_Type *base = (FLEXIO_I2S_Type *)i2sBase; + uint8_t *buffer = handle->queue[handle->queueDriver].data; + uint8_t dataSize = handle->bitWidth / 8U; + + /* Handle transfer */ + if ((FLEXIO_I2S_GetStatusFlags(base) & kFLEXIO_I2S_RxDataRegFullFlag) != 0) + { + FLEXIO_I2S_ReadNonBlocking(base, handle->bitWidth, buffer, dataSize); + + /* Update internal state */ + handle->queue[handle->queueDriver].dataSize -= dataSize; + handle->queue[handle->queueDriver].data += dataSize; + } + + /* If finished a blcok, call the callback function */ + if (handle->queue[handle->queueDriver].dataSize == 0U) + { + memset(&handle->queue[handle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); + handle->queueDriver = (handle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_Success, handle->userData); + } + } + + /* If all data finished, just stop the transfer */ + if (handle->queue[handle->queueDriver].data == NULL) + { + FLEXIO_I2S_TransferAbortReceive(base, handle); + } +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s.h new file mode 100644 index 0000000000..ff17ea70be --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s.h @@ -0,0 +1,570 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_I2S_H_ +#define _FSL_FLEXIO_I2S_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_i2s + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO I2S driver version 2.1.0. */ +#define FSL_FLEXIO_I2S_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief FlexIO I2S transfer status */ +enum _flexio_i2s_status +{ + kStatus_FLEXIO_I2S_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 0), /*!< FlexIO I2S is in idle state */ + kStatus_FLEXIO_I2S_TxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 1), /*!< FlexIO I2S Tx is busy */ + kStatus_FLEXIO_I2S_RxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 2), /*!< FlexIO I2S Tx is busy */ + kStatus_FLEXIO_I2S_Error = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 3), /*!< FlexIO I2S error occurred */ + kStatus_FLEXIO_I2S_QueueFull = MAKE_STATUS(kStatusGroup_FLEXIO_I2S, 4), /*!< FlexIO I2S transfer queue is full. */ +}; + +/*! @brief Define FlexIO I2S access structure typedef */ +typedef struct _flexio_i2s_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO base pointer */ + uint8_t txPinIndex; /*!< Tx data pin index in FlexIO pins */ + uint8_t rxPinIndex; /*!< Rx data pin index */ + uint8_t bclkPinIndex; /*!< Bit clock pin index */ + uint8_t fsPinIndex; /*!< Frame sync pin index */ + uint8_t txShifterIndex; /*!< Tx data shifter index */ + uint8_t rxShifterIndex; /*!< Rx data shifter index */ + uint8_t bclkTimerIndex; /*!< Bit clock timer index */ + uint8_t fsTimerIndex; /*!< Frame sync timer index */ +} FLEXIO_I2S_Type; + +/*! @brief Master or slave mode */ +typedef enum _flexio_i2s_master_slave +{ + kFLEXIO_I2S_Master = 0x0U, /*!< Master mode */ + kFLEXIO_I2S_Slave = 0x1U /*!< Slave mode */ +} flexio_i2s_master_slave_t; + +/*! @brief Define FlexIO FlexIO I2S interrupt mask. */ +enum _flexio_i2s_interrupt_enable +{ + kFLEXIO_I2S_TxDataRegEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */ + kFLEXIO_I2S_RxDataRegFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */ +}; + +/*! @brief Define FlexIO FlexIO I2S status mask. */ +enum _flexio_i2s_status_flags +{ + kFLEXIO_I2S_TxDataRegEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */ + kFLEXIO_I2S_RxDataRegFullFlag = 0x2U, /*!< Receive buffer full flag. */ +}; + +/*! @brief FlexIO I2S configure structure */ +typedef struct _flexio_i2s_config +{ + bool enableI2S; /*!< Enable FlexIO I2S */ + flexio_i2s_master_slave_t masterSlave; /*!< Master or slave */ +} flexio_i2s_config_t; + +/*! @brief FlexIO I2S audio format, FlexIO I2S only support the same format in Tx and Rx */ +typedef struct _flexio_i2s_format +{ + uint8_t bitWidth; /*!< Bit width of audio data, always 8/16/24/32 bits */ + uint32_t sampleRate_Hz; /*!< Sample rate of the audio data */ +} flexio_i2s_format_t; + +/*!@brief FlexIO I2S transfer queue size, user can refine it according to use case. */ +#define FLEXIO_I2S_XFER_QUEUE_SIZE (4) + +/*! @brief Audio sample rate */ +typedef enum _flexio_i2s_sample_rate +{ + kFLEXIO_I2S_SampleRate8KHz = 8000U, /*!< Sample rate 8000Hz */ + kFLEXIO_I2S_SampleRate11025Hz = 11025U, /*!< Sample rate 11025Hz */ + kFLEXIO_I2S_SampleRate12KHz = 12000U, /*!< Sample rate 12000Hz */ + kFLEXIO_I2S_SampleRate16KHz = 16000U, /*!< Sample rate 16000Hz */ + kFLEXIO_I2S_SampleRate22050Hz = 22050U, /*!< Sample rate 22050Hz */ + kFLEXIO_I2S_SampleRate24KHz = 24000U, /*!< Sample rate 24000Hz */ + kFLEXIO_I2S_SampleRate32KHz = 32000U, /*!< Sample rate 32000Hz */ + kFLEXIO_I2S_SampleRate44100Hz = 44100U, /*!< Sample rate 44100Hz */ + kFLEXIO_I2S_SampleRate48KHz = 48000U, /*!< Sample rate 48000Hz */ + kFLEXIO_I2S_SampleRate96KHz = 96000U /*!< Sample rate 96000Hz */ +} flexio_i2s_sample_rate_t; + +/*! @brief Audio word width */ +typedef enum _flexio_i2s_word_width +{ + kFLEXIO_I2S_WordWidth8bits = 8U, /*!< Audio data width 8 bits */ + kFLEXIO_I2S_WordWidth16bits = 16U, /*!< Audio data width 16 bits */ + kFLEXIO_I2S_WordWidth24bits = 24U, /*!< Audio data width 24 bits */ + kFLEXIO_I2S_WordWidth32bits = 32U /*!< Audio data width 32 bits */ +} flexio_i2s_word_width_t; + +/*! @brief Define FlexIO I2S transfer structure. */ +typedef struct _flexio_i2s_transfer +{ + uint8_t *data; /*!< Data buffer start pointer */ + size_t dataSize; /*!< Bytes to be transferred. */ +} flexio_i2s_transfer_t; + +typedef struct _flexio_i2s_handle flexio_i2s_handle_t; + +/*! @brief FlexIO I2S xfer callback prototype */ +typedef void (*flexio_i2s_callback_t)(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + status_t status, + void *userData); + +/*! @brief Define FlexIO I2S handle structure. */ +struct _flexio_i2s_handle +{ + uint32_t state; /*!< Internal state */ + flexio_i2s_callback_t callback; /*!< Callback function called at transfer event*/ + void *userData; /*!< Callback parameter passed to callback function*/ + uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32bits */ + flexio_i2s_transfer_t queue[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */ + size_t transferSize[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ + volatile uint8_t queueUser; /*!< Index for user to queue transfer */ + volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the FlexIO I2S. + * + * This API configures FlexIO pins and shifter to I2S and configure FlexIO I2S with configuration structure. + * The configuration structure can be filled by the user, or be set with default values by + * FLEXIO_I2S_GetDefaultConfig(). + * + * @note This API should be called at the beginning of the application to use + * the FlexIO I2S driver, or any access to the FlexIO I2S module could cause hard fault + * because clock is not enabled. + * + * @param base FlexIO I2S base pointer + * @param config FlexIO I2S configure structure. +*/ +void FLEXIO_I2S_Init(FLEXIO_I2S_Type *base, const flexio_i2s_config_t *config); + +/*! + * @brief Sets the FlexIO I2S configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in FLEXIO_I2S_Init(). + * User may use the initialized structure unchanged in FLEXIO_I2S_Init(), or modify + * some fields of the structure before calling FLEXIO_I2S_Init(). + * + * @param config pointer to master configuration structure + */ +void FLEXIO_I2S_GetDefaultConfig(flexio_i2s_config_t *config); + +/*! + * @brief De-initializes the FlexIO I2S. + * + * Calling this API gates the FlexIO i2s clock. After calling this API, call the FLEXO_I2S_Init to use the + * FlexIO I2S module. + * + * @param base FlexIO I2S base pointer +*/ +void FLEXIO_I2S_Deinit(FLEXIO_I2S_Type *base); + +/*! + * @brief Enables/disables the FlexIO I2S module operation. + * + * @param base pointer to FLEXIO_I2S_Type + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_I2S_Enable(FLEXIO_I2S_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the FlexIO I2S status flags. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @return Status flag, which are ORed by the enumerators in the _flexio_i2s_status_flags. +*/ +uint32_t FLEXIO_I2S_GetStatusFlags(FLEXIO_I2S_Type *base); + +/*! @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the FlexIO I2S interrupt. + * + * This function enables the FlexIO UART interrupt. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @param mask interrupt source + */ +void FLEXIO_I2S_EnableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask); + +/*! + * @brief Disables the FlexIO I2S interrupt. + * + * This function enables the FlexIO UART interrupt. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @param mask interrupt source + */ +void FLEXIO_I2S_DisableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask); + +/*! @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO I2S Tx DMA requests. + * + * @param base FlexIO I2S base pointer + * @param enable True means enable DMA, false means disable DMA. + */ +static inline void FLEXIO_I2S_TxEnableDMA(FLEXIO_I2S_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->txShifterIndex, enable); +} + +/*! + * @brief Enables/disables the FlexIO I2S Rx DMA requests. + * + * @param base FlexIO I2S base pointer + * @param enable True means enable DMA, false means disable DMA. + */ +static inline void FLEXIO_I2S_RxEnableDMA(FLEXIO_I2S_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->rxShifterIndex, enable); +} + +/*! + * @brief Gets the FlexIO I2S send data register address. + * + * This function returns the I2S data register address, mainly used by DMA/eDMA. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @return FlexIO i2s send data register address. + */ +static inline uint32_t FLEXIO_I2S_TxGetDataRegisterAddress(FLEXIO_I2S_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->txShifterIndex); +} + +/*! + * @brief Gets the FlexIO I2S receive data register address. + * + * This function returns the I2S data register address, mainly used by DMA/eDMA. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @return FlexIO i2s receive data register address. + */ +static inline uint32_t FLEXIO_I2S_RxGetDataRegisterAddress(FLEXIO_I2S_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->rxShifterIndex); +} + +/*! @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Configures the FlexIO I2S audio format in master mode. + * + * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @param format Pointer to FlexIO I2S audio data format structure. + * @param srcClock_Hz I2S master clock source frequency in Hz. +*/ +void FLEXIO_I2S_MasterSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format, uint32_t srcClock_Hz); + +/*! + * @brief Configures the FlexIO I2S audio format in slave mode. + * + * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @param format Pointer to FlexIO I2S audio data format structure. +*/ +void FLEXIO_I2S_SlaveSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format); + +/*! + * @brief Sends a piece of data using a blocking method. + * + * @note This function blocks via polling until data is ready to be sent. + * + * @param base FlexIO I2S base pointer. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param txData Pointer to the data to be written. + * @param size Bytes to be written. + */ +void FLEXIO_I2S_WriteBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size); + +/*! + * @brief Writes a data into data register. + * + * @param base FlexIO I2S base pointer. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param data Data to be written. + */ +static inline void FLEXIO_I2S_WriteData(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint32_t data) +{ + base->flexioBase->SHIFTBUFBIS[base->txShifterIndex] = (data << (32U - bitWidth)); +} + +/*! + * @brief Receives a piece of data using a blocking method. + * + * @note This function blocks via polling until data is ready to be sent. + * + * @param base FlexIO I2S base pointer + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param rxData Pointer to the data to be read. + * @param size Bytes to be read. + */ +void FLEXIO_I2S_ReadBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size); + +/*! + * @brief Reads a data from the data register. + * + * @param base FlexIO I2S base pointer + * @return Data read from data register. + */ +static inline uint32_t FLEXIO_I2S_ReadData(FLEXIO_I2S_Type *base) +{ + return base->flexioBase->SHIFTBUFBIS[base->rxShifterIndex]; +} + +/*! @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the FlexIO I2S handle. + * + * This function initializes the FlexIO I2S handle which can be used for other + * FlexIO I2S transactional APIs. Call this API once to get the + * initialized handle. + * + * @param base pointer to FLEXIO_I2S_Type structure + * @param handle pointer to flexio_i2s_handle_t structure to store the transfer state. + * @param callback FlexIO I2S callback function, which is called while finished a block. + * @param userData User parameter for the FlexIO I2S callback. + */ +void FLEXIO_I2S_TransferTxCreateHandle(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_callback_t callback, + void *userData); + +/*! + * @brief Configures the FlexIO I2S audio format. + * + * Audio format can be changed in run-time of FlexIO i2s. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base pointer to FLEXIO_I2S_Type structure. + * @param handle FlexIO I2S handle pointer. + * @param format Pointer to audio data format structure. + * @param srcClock_Hz FlexIO I2S bit clock source frequency in Hz. This parameter should be 0 while in slave mode. +*/ +void FLEXIO_I2S_TransferSetFormat(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_format_t *format, + uint32_t srcClock_Hz); + +/*! + * @brief Initializes the FlexIO I2S receive handle. + * + * This function initializes the FlexIO I2S handle which can be used for other + * FlexIO I2S transactional APIs. Usually, user only need to call this API once to get the + * initialized handle. + * + * @param base pointer to FLEXIO_I2S_Type structure. + * @param handle pointer to flexio_i2s_handle_t structure to store the transfer state. + * @param callback FlexIO I2S callback function, which is called while finished a block. + * @param userData User parameter for the FlexIO I2S callback. + */ +void FLEXIO_I2S_TransferRxCreateHandle(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_callback_t callback, + void *userData); + +/*! + * @brief Performs an interrupt non-blocking send transfer on FlexIO I2S. + * + * @note Calling the API returns immediately after transfer initiates. + * Call FLEXIO_I2S_GetRemainingBytes to poll the transfer status and check whether + * the transfer is finished. If the return status is 0, the transfer is finished. + * + * @param base pointer to FLEXIO_I2S_Type structure. + * @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state + * @param xfer pointer to flexio_i2s_transfer_t structure + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_FLEXIO_I2S_TxBusy Previous transmission still not finished, data not all written to TX register yet. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t FLEXIO_I2S_TransferSendNonBlocking(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_transfer_t *xfer); + +/*! + * @brief Performs an interrupt non-blocking receive transfer on FlexIO I2S. + * + * @note The API returns immediately after transfer initiates. + * Call FLEXIO_I2S_GetRemainingBytes to poll the transfer status to check whether + * the transfer is finished. If the return status is 0, the transfer is finished. + * + * @param base pointer to FLEXIO_I2S_Type structure. + * @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state + * @param xfer pointer to flexio_i2s_transfer_t structure + * @retval kStatus_Success Successfully start the data receive. + * @retval kStatus_FLEXIO_I2S_RxBusy Previous receive still not finished. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t FLEXIO_I2S_TransferReceiveNonBlocking(FLEXIO_I2S_Type *base, + flexio_i2s_handle_t *handle, + flexio_i2s_transfer_t *xfer); + +/*! + * @brief Aborts the current send. + * + * @note This API can be called at any time when interrupt non-blocking transfer initiates + * to abort the transfer in a early time. + * + * @param base pointer to FLEXIO_I2S_Type structure. + * @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state + */ +void FLEXIO_I2S_TransferAbortSend(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle); + +/*! + * @brief Aborts the current receive. + * + * @note This API can be called at any time when interrupt non-blocking transfer initiates + * to abort the transfer in a early time. + * + * @param base pointer to FLEXIO_I2S_Type structure. + * @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state + */ +void FLEXIO_I2S_TransferAbortReceive(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle); + +/*! + * @brief Gets the remaining bytes to be sent. + * + * @param base pointer to FLEXIO_I2S_Type structure. + * @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state + * @param count Bytes sent. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t FLEXIO_I2S_TransferGetSendCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count); + +/*! + * @brief Gets the remaining bytes to be received. + * + * @param base pointer to FLEXIO_I2S_Type structure. + * @param handle pointer to flexio_i2s_handle_t structure which stores the transfer state + * @return count Bytes received. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t FLEXIO_I2S_TransferGetReceiveCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count); + +/*! + * @brief Tx interrupt handler. + * + * @param i2sBase pointer to FLEXIO_I2S_Type structure. + * @param i2sHandle pointer to flexio_i2s_handle_t structure + */ +void FLEXIO_I2S_TransferTxHandleIRQ(void *i2sBase, void *i2sHandle); + +/*! + * @brief Rx interrupt handler. + * + * @param i2sBase pointer to FLEXIO_I2S_Type structure. + * @param i2sHandle pointer to flexio_i2s_handle_t structure + */ +void FLEXIO_I2S_TransferRxHandleIRQ(void *i2sBase, void *i2sHandle); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ + +/*! @} */ + +#endif /* _FSL_FLEXIO_I2S_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s_dma.c new file mode 100644 index 0000000000..07a1178691 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s_dma.c @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_i2s_dma.h" + +/******************************************************************************* + * Definitations + ******************************************************************************/ + +/*handle; + + /* If finished a blcok, call the callback function */ + memset(&flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); + flexio_i2sHandle->queueDriver = (flexio_i2sHandle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + if (flexio_i2sHandle->callback) + { + (flexio_i2sHandle->callback)(privHandle->base, flexio_i2sHandle, kStatus_Success, flexio_i2sHandle->userData); + } + + /* If all data finished, just stop the transfer */ + if (flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver].data == NULL) + { + FLEXIO_I2S_TransferAbortSendDMA(privHandle->base, flexio_i2sHandle); + } +} + +static void FLEXIO_I2S_RxDMACallback(dma_handle_t *handle, void *userData) +{ + flexio_i2s_dma_private_handle_t *privHandle = (flexio_i2s_dma_private_handle_t *)userData; + flexio_i2s_dma_handle_t *flexio_i2sHandle = privHandle->handle; + + /* If finished a blcok, call the callback function */ + memset(&flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); + flexio_i2sHandle->queueDriver = (flexio_i2sHandle->queueDriver + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + if (flexio_i2sHandle->callback) + { + (flexio_i2sHandle->callback)(privHandle->base, flexio_i2sHandle, kStatus_Success, flexio_i2sHandle->userData); + } + + /* If all data finished, just stop the transfer */ + if (flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver].data == NULL) + { + FLEXIO_I2S_TransferAbortReceiveDMA(privHandle->base, flexio_i2sHandle); + } +} + +void FLEXIO_I2S_TransferTxCreateHandleDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_dma_callback_t callback, + void *userData, + dma_handle_t *dmaHandle) +{ + assert(handle && dmaHandle); + + /* Set flexio_i2s base to handle */ + handle->dmaHandle = dmaHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set FLEXIO I2S state to idle */ + handle->state = kFLEXIO_I2S_Idle; + + s_dmaPrivateHandle[0].base = base; + s_dmaPrivateHandle[0].handle = handle; + + /* Install callback for Tx dma channel */ + DMA_SetCallback(dmaHandle, FLEXIO_I2S_TxDMACallback, &s_dmaPrivateHandle[0]); +} + +void FLEXIO_I2S_TransferRxCreateHandleDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_dma_callback_t callback, + void *userData, + dma_handle_t *dmaHandle) +{ + assert(handle && dmaHandle); + + /* Set flexio_i2s base to handle */ + handle->dmaHandle = dmaHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set FLEXIO I2S state to idle */ + handle->state = kFLEXIO_I2S_Idle; + + s_dmaPrivateHandle[1].base = base; + s_dmaPrivateHandle[1].handle = handle; + + /* Install callback for Tx dma channel */ + DMA_SetCallback(dmaHandle, FLEXIO_I2S_RxDMACallback, &s_dmaPrivateHandle[1]); +} + +void FLEXIO_I2S_TransferSetFormatDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_format_t *format, + uint32_t srcClock_Hz) +{ + assert(handle && format); + + /* Configure the audio format to FLEXIO I2S registers */ + if (srcClock_Hz != 0) + { + /* It is master */ + FLEXIO_I2S_MasterSetFormat(base, format, srcClock_Hz); + } + else + { + FLEXIO_I2S_SlaveSetFormat(base, format); + } + + /* Get the tranfer size from format, this should be used in DMA configuration */ + handle->bytesPerFrame = format->bitWidth / 8U; +} + +status_t FLEXIO_I2S_TransferSendDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, flexio_i2s_transfer_t *xfer) +{ + assert(handle && xfer); + + dma_transfer_config_t config = {0}; + uint32_t destAddr = FLEXIO_I2S_TxGetDataRegisterAddress(base) + (4U - handle->bytesPerFrame); + + /* Check if input parameter invalid */ + if ((xfer->data == NULL) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + if (handle->queue[handle->queueUser].data) + { + return kStatus_FLEXIO_I2S_QueueFull; + } + + /* Change the state of handle */ + handle->state = kFLEXIO_I2S_Busy; + + /* Update the queue state */ + handle->queue[handle->queueUser].data = xfer->data; + handle->queue[handle->queueUser].dataSize = xfer->dataSize; + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + + DMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame, + xfer->dataSize, kDMA_MemoryToPeripheral); + + /* Configure DMA channel */ + DMA_SubmitTransfer(handle->dmaHandle, &config, true); + + /* Start DMA transfer */ + DMA_StartTransfer(handle->dmaHandle); + + /* Enable DMA enable bit */ + FLEXIO_I2S_TxEnableDMA(base, true); + + /* Enable FLEXIO I2S Tx clock */ + FLEXIO_I2S_Enable(base, true); + + return kStatus_Success; +} + +status_t FLEXIO_I2S_TransferReceiveDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_transfer_t *xfer) +{ + assert(handle && xfer); + + dma_transfer_config_t config = {0}; + uint32_t srcAddr = FLEXIO_I2S_RxGetDataRegisterAddress(base) - (4U - handle->bytesPerFrame); + + /* Check if input parameter invalid */ + if ((xfer->data == NULL) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + if (handle->queue[handle->queueUser].data) + { + return kStatus_FLEXIO_I2S_QueueFull; + } + + /* Change the state of handle */ + handle->state = kFLEXIO_I2S_Busy; + + /* Update queue state */ + handle->queue[handle->queueUser].data = xfer->data; + handle->queue[handle->queueUser].dataSize = xfer->dataSize; + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % FLEXIO_I2S_XFER_QUEUE_SIZE; + + /* Prepare dma configure */ + DMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame, + xfer->dataSize, kDMA_PeripheralToMemory); + + DMA_SubmitTransfer(handle->dmaHandle, &config, true); + + /* Start DMA transfer */ + DMA_StartTransfer(handle->dmaHandle); + + /* Enable DMA enable bit */ + FLEXIO_I2S_RxEnableDMA(base, true); + + /* Enable FLEXIO I2S Rx clock */ + FLEXIO_I2S_Enable(base, true); + + return kStatus_Success; +} + +void FLEXIO_I2S_TransferAbortSendDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + DMA_AbortTransfer(handle->dmaHandle); + + /* Disable DMA enable bit */ + FLEXIO_I2S_TxEnableDMA(base, false); + + /* Set the handle state */ + handle->state = kFLEXIO_I2S_Idle; +} + +void FLEXIO_I2S_TransferAbortReceiveDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + DMA_AbortTransfer(handle->dmaHandle); + + /* Disable DMA enable bit */ + FLEXIO_I2S_RxEnableDMA(base, false); + + /* Set the handle state */ + handle->state = kFLEXIO_I2S_Idle; +} + +status_t FLEXIO_I2S_TransferGetSendCountDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kFLEXIO_I2S_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = handle->transferSize[handle->queueDriver] - + DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel); + } + + return status; +} + +status_t FLEXIO_I2S_TransferGetReceiveCountDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kFLEXIO_I2S_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = handle->transferSize[handle->queueDriver] - + DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel); + } + + return status; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s_dma.h new file mode 100644 index 0000000000..a8e52c184f --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2s_dma.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_I2S_DMA_H_ +#define _FSL_FLEXIO_I2S_DMA_H_ + +#include "fsl_flexio_i2s.h" +#include "fsl_dma.h" + +/*! + * @addtogroup flexio_dma_i2s + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +typedef struct _flexio_i2s_dma_handle flexio_i2s_dma_handle_t; + +/*! @brief FlexIO I2S DMA transfer callback function for finish and error */ +typedef void (*flexio_i2s_dma_callback_t)(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief FlexIO I2S DMA transfer handle, users should not touch the content of the handle.*/ +struct _flexio_i2s_dma_handle +{ + dma_handle_t *dmaHandle; /*!< DMA handler for FlexIO I2S send */ + uint8_t bytesPerFrame; /*!< Bytes in a frame */ + uint32_t state; /*!< Internal state for FlexIO I2S DMA transfer */ + flexio_i2s_dma_callback_t callback; /*!< Callback for users while transfer finish or error occurred */ + void *userData; /*!< User callback parameter */ + flexio_i2s_transfer_t queue[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer. */ + size_t transferSize[FLEXIO_I2S_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ + volatile uint8_t queueUser; /*!< Index for user to queue transfer. */ + volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name DMA Transactional + * @{ + */ + +/*! + * @brief Initializes the FlexIO I2S DMA handle. + * + * This function initializes the FlexIO I2S master DMA handle which can be used for other FlexIO I2S master + * transactional APIs. + * Usually, for a specified FlexIO I2S instance, user need only call this API once to get the initialized handle. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param callback FlexIO I2S DMA callback function called while finished a block. + * @param userData User parameter for callback. + * @param dmaHandle DMA handle for FlexIO I2S. This handle shall be a static value allocated by users. + */ +void FLEXIO_I2S_TransferTxCreateHandleDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_dma_callback_t callback, + void *userData, + dma_handle_t *dmaHandle); + +/*! + * @brief Initializes the FlexIO I2S Rx DMA handle. + * + * This function initializes the FlexIO I2S slave DMA handle which can be used for other FlexIO I2S master transactional + * APIs. + * Usually, for a specified FlexIO I2S instance, user need only call this API once to get the initialized handle. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param callback FlexIO I2S DMA callback function called while finished a block. + * @param userData User parameter for callback. + * @param dmaHandle DMA handle for FlexIO I2S. This handle shall be a static value allocated by users. + */ +void FLEXIO_I2S_TransferRxCreateHandleDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_dma_callback_t callback, + void *userData, + dma_handle_t *dmaHandle); + +/*! + * @brief Configures the FlexIO I2S Tx audio format. + * + * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data + * format to be transferred. This function also sets DMA parameter according to format. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer + * @param format Pointer to FlexIO I2S audio data format structure. + * @param srcClock_Hz FlexIO I2S clock source frequency in Hz. It should be 0 while in slave mode. + * @retval kStatus_Success Audio format set successfully. + * @retval kStatus_InvalidArgument The input arguments is invalid. +*/ +void FLEXIO_I2S_TransferSetFormatDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_format_t *format, + uint32_t srcClock_Hz); + +/*! + * @brief Performs a non-blocking FlexIO I2S transfer using DMA. + * + * @note This interface returns immediately after transfer initiates. Call + * FLEXIO_I2S_GetTransferStatus to poll the transfer status and check whether FLEXIO I2S transfer finished. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param xfer Pointer to DMA transfer structure. + * @retval kStatus_Success Start a FlexIO I2S DMA send successfully. + * @retval kStatus_InvalidArgument The input arguments is invalid. + * @retval kStatus_TxBusy FlexIO I2S is busy sending data. + */ +status_t FLEXIO_I2S_TransferSendDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking FlexIO I2S receive using DMA. + * + * @note This interface returns immediately after transfer initiates. Call + * FLEXIO_I2S_GetReceiveRemainingBytes to poll the transfer status to check whether the FlexIO I2S transfer is finished. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param xfer Pointer to DMA transfer structure. + * @retval kStatus_Success Start a FlexIO I2S DMA receive successfully. + * @retval kStatus_InvalidArgument The input arguments is invalid. + * @retval kStatus_RxBusy FlexIO I2S is busy receiving data. + */ +status_t FLEXIO_I2S_TransferReceiveDMA(FLEXIO_I2S_Type *base, + flexio_i2s_dma_handle_t *handle, + flexio_i2s_transfer_t *xfer); + +/*! + * @brief Aborts a FlexIO I2S transfer using DMA. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + */ +void FLEXIO_I2S_TransferAbortSendDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle); + +/*! + * @brief Aborts a FlexIO I2S receive using DMA. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + */ +void FLEXIO_I2S_TransferAbortReceiveDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle); + +/*! + * @brief Gets the remaining bytes to be sent. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param count Bytes sent. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t FLEXIO_I2S_TransferGetSendCountDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, size_t *count); + +/*! + * @brief Gets the remaining bytes to be received. + * + * @param base FlexIO I2S peripheral base address. + * @param handle FlexIO I2S DMA handle pointer. + * @param count Bytes received. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t FLEXIO_I2S_TransferGetReceiveCountDMA(FLEXIO_I2S_Type *base, flexio_i2s_dma_handle_t *handle, size_t *count); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi.c new file mode 100644 index 0000000000..65c987a6ff --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi.c @@ -0,0 +1,935 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_spi.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief FLEXIO SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */ +enum _flexio_spi_transfer_states +{ + kFLEXIO_SPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver's queue. */ + kFLEXIO_SPI_Busy, /*!< Transmiter/Receive's queue is not finished. */ +}; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Send a piece of data for SPI. + * + * This function computes the number of data to be written into D register or Tx FIFO, + * and write the data into it. At the same time, this function updates the values in + * master handle structure. + * + * @param base pointer to FLEXIO_SPI_Type structure + * @param handle Pointer to SPI master handle structure. + */ +static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle); + +/*! + * @brief Receive a piece of data for SPI master. + * + * This function computes the number of data to receive from D register or Rx FIFO, + * and write the data to destination address. At the same time, this function updates + * the values in master handle structure. + * + * @param base pointer to FLEXIO_SPI_Type structure + * @param handle Pointer to SPI master handle structure. + */ +static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Codes + ******************************************************************************/ + +static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) +{ + uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; + + if (handle->txData != NULL) + { + /* Transmit data and update tx size/buff. */ + if (handle->bytePerFrame == 1U) + { + tmpData = *(handle->txData); + handle->txData++; + } + else + { + tmpData = (uint32_t)(handle->txData[0]) << 8U; + tmpData += handle->txData[1]; + handle->txData += 2U; + } + } + else + { + tmpData = FLEXIO_SPI_DUMMYDATA; + } + + handle->txRemainingBytes -= handle->bytePerFrame; + + FLEXIO_SPI_WriteData(base, handle->direction, tmpData); + + if (!handle->txRemainingBytes) + { + FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable); + } +} + +static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) +{ + uint16_t tmpData; + + tmpData = FLEXIO_SPI_ReadData(base, handle->direction); + + if (handle->rxData != NULL) + { + if (handle->bytePerFrame == 1U) + { + *handle->rxData = tmpData; + handle->rxData++; + } + else + { + *((uint16_t *)(handle->rxData)) = tmpData; + handle->rxData += 2U; + } + } + handle->rxRemainingBytes -= handle->bytePerFrame; +} + +void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz) +{ + assert(base); + assert(masterConfig); + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + uint32_t ctrlReg = 0; + uint16_t timerDiv = 0; + uint16_t timerCmp = 0; + + /* Clear the shifterConfig & timerConfig struct. */ + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + + /* Ungate flexio clock. */ + CLOCK_EnableClock(kCLOCK_Flexio0); + + /* Configure FLEXIO SPI Master */ + ctrlReg = base->flexioBase->CTRL; + ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + ctrlReg |= (FLEXIO_CTRL_DOZEN(masterConfig->enableInDoze) | FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | + FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster)); + + base->flexioBase->CTRL = ctrlReg; + + /* Do hardware configuration. */ + /* 1. Configure the shifter 0 for tx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; + shifterConfig.pinSelect = base->SDOPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + } + else + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); + + /* 2. Configure the shifter 1 for rx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->SDIPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + } + else + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); + + /*3. Configure the timer 0 for SCK. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutput; + timerConfig.pinSelect = base->SCKPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + timerDiv = srcClock_Hz / masterConfig->baudRate_Bps; + timerDiv = timerDiv / 2 - 1; + + timerCmp = ((uint32_t)(masterConfig->dataMode * 2 - 1U)) << 8U; + timerCmp |= timerDiv; + + timerConfig.timerCompare = timerCmp; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); + + /* 4. Configure the timer 1 for CSn. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->timerIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutput; + timerConfig.pinSelect = base->CSnPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + + timerConfig.timerCompare = 0xFFFFU; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); +} + +void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base) +{ + /* Disable FLEXIO SPI module. */ + FLEXIO_SPI_Enable(base, false); + + /* Gate flexio clock. */ + CLOCK_DisableClock(kCLOCK_Flexio0); +} + +void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig) +{ + assert(masterConfig); + + masterConfig->enableMaster = true; + masterConfig->enableInDoze = false; + masterConfig->enableInDebug = true; + masterConfig->enableFastAccess = false; + /* Default baud rate 500kbps. */ + masterConfig->baudRate_Bps = 500000U; + /* Default CPHA = 0. */ + masterConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge; + /* Default bit count at 8. */ + masterConfig->dataMode = kFLEXIO_SPI_8BitMode; +} + +void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig) +{ + assert(base && slaveConfig); + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + uint32_t ctrlReg = 0; + + /* Clear the shifterConfig & timerConfig struct. */ + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + + /* Ungate flexio clock. */ + CLOCK_EnableClock(kCLOCK_Flexio0); + + /* Configure FLEXIO SPI Slave */ + ctrlReg = base->flexioBase->CTRL; + ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + ctrlReg |= (FLEXIO_CTRL_DOZEN(slaveConfig->enableInDoze) | FLEXIO_CTRL_DBGE(slaveConfig->enableInDebug) | + FLEXIO_CTRL_FASTACC(slaveConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(slaveConfig->enableSlave)); + + base->flexioBase->CTRL = ctrlReg; + + /* Do hardware configuration. */ + /* 1. Configure the shifter 0 for tx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; + shifterConfig.pinSelect = base->SDOPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + } + else + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); + + /* 2. Configure the shifter 1 for rx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->SDIPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; + if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + } + else + { + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + } + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); + + /*3. Configure the timer 0 for shift clock. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->CSnPinIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->SCKPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; + timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge; + timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; + if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) + { + /* The configuration kFLEXIO_TimerDisableOnTimerCompare only support continuous + PCS access, change to kFLEXIO_TimerDisableNever to enable discontinuous PCS access. */ + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; + } + else + { + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + } + + timerConfig.timerCompare = slaveConfig->dataMode * 2 - 1U; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); +} + +void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base) +{ + FLEXIO_SPI_MasterDeinit(base); +} + +void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig) +{ + assert(slaveConfig); + + slaveConfig->enableSlave = true; + slaveConfig->enableInDoze = false; + slaveConfig->enableInDebug = true; + slaveConfig->enableFastAccess = false; + /* Default CPHA = 0. */ + slaveConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge; + /* Default bit count at 8. */ + slaveConfig->dataMode = kFLEXIO_SPI_8BitMode; +} + +void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_SPI_TxEmptyInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[0]); + } + if (mask & kFLEXIO_SPI_RxFullInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[1]); + } +} + +void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_SPI_TxEmptyInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[0]); + } + if (mask & kFLEXIO_SPI_RxFullInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1 << base->shifterIndex[1]); + } +} + +void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable) +{ + if (mask & kFLEXIO_SPI_TxDmaEnable) + { + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1U << base->shifterIndex[0], enable); + } + + if (mask & kFLEXIO_SPI_RxDmaEnable) + { + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1U << base->shifterIndex[1], enable); + } +} + +uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base) +{ + uint32_t shifterStatus = FLEXIO_GetShifterStatusFlags(base->flexioBase); + uint32_t status = 0; + + status = ((shifterStatus & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]); + status |= (((shifterStatus & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) << 1U); + + return status; +} + +void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_SPI_TxBufferEmptyFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_SPI_RxBufferFullFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz) +{ + uint16_t timerDiv = 0; + uint16_t timerCmp = 0; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/ + timerDiv = srcClockHz / baudRate_Bps; + timerDiv = timerDiv / 2 - 1U; + + timerCmp = flexioBase->TIMCMP[base->timerIndex[0]]; + timerCmp &= 0xFF00U; + timerCmp |= timerDiv; + + flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp; +} + +void FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction, + const uint8_t *buffer, + size_t size) +{ + assert(buffer); + assert(size); + + while (size--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_TxBufferEmptyFlag)) + { + } + FLEXIO_SPI_WriteData(base, direction, *buffer++); + } +} + +void FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction, + uint8_t *buffer, + size_t size) +{ + assert(buffer); + assert(size); + + while (size--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_RxBufferFullFlag)) + { + } + *buffer++ = FLEXIO_SPI_ReadData(base, direction); + } +} + +void FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer) +{ + flexio_spi_shift_direction_t direction; + uint8_t bytesPerFrame; + uint32_t dataMode = 0; + uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]]; + uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; + + timerCmp &= 0x00FFU; + /* Configure the values in handle. */ + switch (xfer->flags) + { + case kFLEXIO_SPI_8bitMsb: + dataMode = (8 * 2 - 1U) << 8U; + bytesPerFrame = 1; + direction = kFLEXIO_SPI_MsbFirst; + break; + + case kFLEXIO_SPI_8bitLsb: + dataMode = (8 * 2 - 1U) << 8U; + bytesPerFrame = 1; + direction = kFLEXIO_SPI_LsbFirst; + break; + + case kFLEXIO_SPI_16bitMsb: + dataMode = (16 * 2 - 1U) << 8U; + bytesPerFrame = 2; + direction = kFLEXIO_SPI_MsbFirst; + break; + + case kFLEXIO_SPI_16bitLsb: + dataMode = (16 * 2 - 1U) << 8U; + bytesPerFrame = 2; + direction = kFLEXIO_SPI_LsbFirst; + break; + + default: + dataMode = (8 * 2 - 1U) << 8U; + bytesPerFrame = 1; + direction = kFLEXIO_SPI_MsbFirst; + assert(true); + break; + } + + dataMode |= timerCmp; + + /* Configure transfer size. */ + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + while (xfer->dataSize) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_TxBufferEmptyFlag)) + { + } + if (xfer->txData != NULL) + { + /* Transmit data and update tx size/buff. */ + if (bytesPerFrame == 1U) + { + tmpData = *(xfer->txData); + xfer->txData++; + } + else + { + tmpData = (uint32_t)(xfer->txData[0]) << 8U; + tmpData += xfer->txData[1]; + xfer->txData += 2U; + } + } + else + { + tmpData = FLEXIO_SPI_DUMMYDATA; + } + + xfer->dataSize -= bytesPerFrame; + + FLEXIO_SPI_WriteData(base, direction, tmpData); + + while (!(FLEXIO_SPI_GetStatusFlags(base) & kFLEXIO_SPI_RxBufferFullFlag)) + { + } + tmpData = FLEXIO_SPI_ReadData(base, direction); + + if (xfer->rxData != NULL) + { + if (bytesPerFrame == 1U) + { + *xfer->rxData = tmpData; + xfer->rxData++; + } + else + { + *((uint16_t *)(xfer->rxData)) = tmpData; + xfer->rxData += 2U; + } + } + } +} + +status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + flexio_spi_master_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Register callback and userData. */ + handle->callback = callback; + handle->userData = userData; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[0]); + + /* Save the context in global variables to support the double weak mechanism. */ + return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_MasterTransferHandleIRQ); +} + +status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + uint32_t dataMode = 0; + uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]]; + uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; + + timerCmp &= 0x00FFU; + + /* Check if SPI is busy. */ + if (handle->state == kFLEXIO_SPI_Busy) + { + return kStatus_FLEXIO_SPI_Busy; + } + + /* Check if the argument is legal. */ + if ((xfer->txData == NULL) && (xfer->rxData == NULL)) + { + return kStatus_InvalidArgument; + } + + /* Configure the values in handle */ + switch (xfer->flags) + { + case kFLEXIO_SPI_8bitMsb: + dataMode = (8 * 2 - 1U) << 8U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_8bitLsb: + dataMode = (8 * 2 - 1U) << 8U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_LsbFirst; + break; + case kFLEXIO_SPI_16bitMsb: + dataMode = (16 * 2 - 1U) << 8U; + handle->bytePerFrame = 2U; + handle->direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_16bitLsb: + dataMode = (16 * 2 - 1U) << 8U; + handle->bytePerFrame = 2U; + handle->direction = kFLEXIO_SPI_LsbFirst; + break; + default: + dataMode = (8 * 2 - 1U) << 8U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_MsbFirst; + assert(true); + break; + } + + dataMode |= timerCmp; + + /* Configure transfer size. */ + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + handle->state = kFLEXIO_SPI_Busy; + handle->txData = xfer->txData; + handle->rxData = xfer->rxData; + handle->rxRemainingBytes = xfer->dataSize; + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + /* Send first byte of data to trigger the rx interrupt. */ + if (handle->txData != NULL) + { + /* Transmit data and update tx size/buff. */ + if (handle->bytePerFrame == 1U) + { + tmpData = *(handle->txData); + handle->txData++; + } + else + { + tmpData = (uint32_t)(handle->txData[0]) << 8U; + tmpData += handle->txData[1]; + handle->txData += 2U; + } + } + else + { + tmpData = FLEXIO_SPI_DUMMYDATA; + } + + handle->txRemainingBytes = xfer->dataSize - handle->bytePerFrame; + + FLEXIO_SPI_WriteData(base, handle->direction, tmpData); + + /* Enable transmit and receive interrupt to handle rx. */ + FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable); + + return kStatus_Success; +} + +status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Return remaing bytes in different cases. */ + if (handle->rxData) + { + *count = handle->transferSize - handle->rxRemainingBytes; + } + else + { + *count = handle->transferSize - handle->txRemainingBytes; + } + + return kStatus_Success; +} + +void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) +{ + assert(handle); + + FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable); + FLEXIO_SPI_DisableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable); + + /* Transfer finished, set the state to idle. */ + handle->state = kFLEXIO_SPI_Idle; + + /* Clear the internal state. */ + handle->rxRemainingBytes = 0; + handle->txRemainingBytes = 0; +} + +void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle) +{ + assert(spiHandle); + + flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle; + FLEXIO_SPI_Type *base; + uint32_t status; + + if (handle->state == kFLEXIO_SPI_Idle) + { + return; + } + + base = (FLEXIO_SPI_Type *)spiType; + status = FLEXIO_SPI_GetStatusFlags(base); + + /* Handle rx. */ + if ((status & kFLEXIO_SPI_RxBufferFullFlag) && (handle->rxRemainingBytes)) + { + FLEXIO_SPI_TransferReceiveTransaction(base, handle); + } + + /* Handle tx. */ + if ((status & kFLEXIO_SPI_TxBufferEmptyFlag) && (handle->txRemainingBytes)) + { + FLEXIO_SPI_TransferSendTransaction(base, handle); + } + + /* All the transfer finished. */ + if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U)) + { + FLEXIO_SPI_MasterTransferAbort(base, handle); + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData); + } + } +} + +status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + flexio_spi_slave_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Register callback and userData. */ + handle->callback = callback; + handle->userData = userData; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[0]); + + /* Save the context in global variables to support the double weak mechanism. */ + return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_SlaveTransferHandleIRQ); +} + +status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + uint32_t dataMode = 0; + + /* Check if SPI is busy. */ + if (handle->state == kFLEXIO_SPI_Busy) + { + return kStatus_FLEXIO_SPI_Busy; + } + + /* Check if the argument is legal. */ + if ((xfer->txData == NULL) && (xfer->rxData == NULL)) + { + return kStatus_InvalidArgument; + } + + /* Configure the values in handle */ + switch (xfer->flags) + { + case kFLEXIO_SPI_8bitMsb: + dataMode = 8 * 2 - 1U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_8bitLsb: + dataMode = 8 * 2 - 1U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_LsbFirst; + break; + case kFLEXIO_SPI_16bitMsb: + dataMode = 16 * 2 - 1U; + handle->bytePerFrame = 2U; + handle->direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_16bitLsb: + dataMode = 16 * 2 - 1U; + handle->bytePerFrame = 2U; + handle->direction = kFLEXIO_SPI_LsbFirst; + break; + default: + dataMode = 8 * 2 - 1U; + handle->bytePerFrame = 1U; + handle->direction = kFLEXIO_SPI_MsbFirst; + assert(true); + break; + } + + /* Configure transfer size. */ + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + handle->state = kFLEXIO_SPI_Busy; + handle->txData = xfer->txData; + handle->rxData = xfer->rxData; + handle->txRemainingBytes = xfer->dataSize; + handle->rxRemainingBytes = xfer->dataSize; + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + /* Enable transmit and receive interrupt to handle tx and rx. */ + FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_TxEmptyInterruptEnable); + FLEXIO_SPI_EnableInterrupts(base, kFLEXIO_SPI_RxFullInterruptEnable); + + return kStatus_Success; +} + +void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle) +{ + assert(spiHandle); + + flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle; + FLEXIO_SPI_Type *base; + uint32_t status; + + if (handle->state == kFLEXIO_SPI_Idle) + { + return; + } + + base = (FLEXIO_SPI_Type *)spiType; + status = FLEXIO_SPI_GetStatusFlags(base); + + /* Handle tx. */ + if ((status & kFLEXIO_SPI_TxBufferEmptyFlag) && (handle->txRemainingBytes)) + { + FLEXIO_SPI_TransferSendTransaction(base, handle); + } + + /* Handle rx. */ + if ((status & kFLEXIO_SPI_RxBufferFullFlag) && (handle->rxRemainingBytes)) + { + FLEXIO_SPI_TransferReceiveTransaction(base, handle); + } + + /* All the transfer finished. */ + if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U)) + { + FLEXIO_SPI_SlaveTransferAbort(base, handle); + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData); + } + } +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi.h new file mode 100644 index 0000000000..34c7fba02b --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi.h @@ -0,0 +1,708 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLEXIO_SPI_H_ +#define _FSL_FLEXIO_SPI_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_spi + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO SPI driver version 2.1.0. */ +#define FSL_FLEXIO_SPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief FlexIO SPI dummy transfer data, the data is sent while txData is NULL. */ +#define FLEXIO_SPI_DUMMYDATA (0xFFFFU) + +/*! @brief Error codes for the FlexIO SPI driver. */ +enum _flexio_spi_status +{ + kStatus_FLEXIO_SPI_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 1), /*!< FlexIO SPI is busy. */ + kStatus_FLEXIO_SPI_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 2), /*!< SPI is idle */ + kStatus_FLEXIO_SPI_Error = MAKE_STATUS(kStatusGroup_FLEXIO_SPI, 3), /*!< FlexIO SPI error. */ +}; + +/*! @brief FlexIO SPI clock phase configuration. */ +typedef enum _flexio_spi_clock_phase +{ + kFLEXIO_SPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SPSCK occurs at the middle of the first + * cycle of a data transfer. */ + kFLEXIO_SPI_ClockPhaseSecondEdge = 0x1U, /*!< First edge on SPSCK occurs at the start of the + * first cycle of a data transfer. */ +} flexio_spi_clock_phase_t; + +/*! @brief FlexIO SPI data shifter direction options. */ +typedef enum _flexio_spi_shift_direction +{ + kFLEXIO_SPI_MsbFirst = 0, /*!< Data transfers start with most significant bit. */ + kFLEXIO_SPI_LsbFirst = 1, /*!< Data transfers start with least significant bit. */ +} flexio_spi_shift_direction_t; + +/*! @brief FlexIO SPI data length mode options. */ +typedef enum _flexio_spi_data_bitcount_mode +{ + kFLEXIO_SPI_8BitMode = 0x08U, /*!< 8-bit data transmission mode. */ + kFLEXIO_SPI_16BitMode = 0x10U, /*!< 16-bit data transmission mode. */ +} flexio_spi_data_bitcount_mode_t; + +/*! @brief Define FlexIO SPI interrupt mask. */ +enum _flexio_spi_interrupt_enable +{ + kFLEXIO_SPI_TxEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */ + kFLEXIO_SPI_RxFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */ +}; + +/*! @brief Define FlexIO SPI status mask. */ +enum _flexio_spi_status_flags +{ + kFLEXIO_SPI_TxBufferEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */ + kFLEXIO_SPI_RxBufferFullFlag = 0x2U, /*!< Receive buffer full flag. */ +}; + +/*! @brief Define FlexIO SPI DMA mask. */ +enum _flexio_spi_dma_enable +{ + kFLEXIO_SPI_TxDmaEnable = 0x1U, /*!< Tx DMA request source */ + kFLEXIO_SPI_RxDmaEnable = 0x2U, /*!< Rx DMA request source */ + kFLEXIO_SPI_DmaAllEnable = 0x3U, /*!< All DMA request source*/ +}; + +/*! @brief Define FlexIO SPI transfer flags. */ +enum _flexio_spi_transfer_flags +{ + kFLEXIO_SPI_8bitMsb = 0x1U, /*!< FlexIO SPI 8-bit MSB first */ + kFLEXIO_SPI_8bitLsb = 0x2U, /*!< FlexIO SPI 8-bit LSB first */ + kFLEXIO_SPI_16bitMsb = 0x9U, /*!< FlexIO SPI 16-bit MSB first */ + kFLEXIO_SPI_16bitLsb = 0xaU, /*!< FlexIO SPI 16-bit LSB first */ +}; + +/*! @brief Define FlexIO SPI access structure typedef. */ +typedef struct _flexio_spi_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */ + uint8_t SDOPinIndex; /*!< Pin select for data output. */ + uint8_t SDIPinIndex; /*!< Pin select for data input. */ + uint8_t SCKPinIndex; /*!< Pin select for clock. */ + uint8_t CSnPinIndex; /*!< Pin select for enable. */ + uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO SPI. */ + uint8_t timerIndex[2]; /*!< Timer index used in FlexIO SPI. */ +} FLEXIO_SPI_Type; + +/*! @brief Define FlexIO SPI master configuration structure. */ +typedef struct _flexio_spi_master_config +{ + bool enableMaster; /*!< Enable/disable FlexIO SPI master after configuration. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, + fast access requires the FlexIO clock to be at least + twice the frequency of the bus clock. */ + uint32_t baudRate_Bps; /*!< Baud rate in Bps. */ + flexio_spi_clock_phase_t phase; /*!< Clock phase. */ + flexio_spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode. */ +} flexio_spi_master_config_t; + +/*! @brief Define FlexIO SPI slave configuration structure. */ +typedef struct _flexio_spi_slave_config +{ + bool enableSlave; /*!< Enable/disable FlexIO SPI slave after configuration. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, + fast access requires the FlexIO clock to be at least + twice the frequency of the bus clock. */ + flexio_spi_clock_phase_t phase; /*!< Clock phase. */ + flexio_spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode. */ +} flexio_spi_slave_config_t; + +/*! @brief Define FlexIO SPI transfer structure. */ +typedef struct _flexio_spi_transfer +{ + uint8_t *txData; /*!< Send buffer. */ + uint8_t *rxData; /*!< Receive buffer. */ + size_t dataSize; /*!< Transfer bytes. */ + uint8_t flags; /*!< FlexIO SPI control flag, MSB first or LSB first. */ +} flexio_spi_transfer_t; + +/*! @brief typedef for flexio_spi_master_handle_t in advance. */ +typedef struct _flexio_spi_master_handle flexio_spi_master_handle_t; + +/*! @brief Slave handle is the same with master handle. */ +typedef flexio_spi_master_handle_t flexio_spi_slave_handle_t; + +/*! @brief FlexIO SPI master callback for finished transmit */ +typedef void (*flexio_spi_master_transfer_callback_t)(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + status_t status, + void *userData); + +/*! @brief FlexIO SPI slave callback for finished transmit */ +typedef void (*flexio_spi_slave_transfer_callback_t)(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + status_t status, + void *userData); + +/*! @brief Define FlexIO SPI handle structure. */ +struct _flexio_spi_master_handle +{ + uint8_t *txData; /*!< Transfer buffer. */ + uint8_t *rxData; /*!< Receive buffer. */ + size_t transferSize; /*!< Total bytes to be transferred. */ + volatile size_t txRemainingBytes; /*!< Send data remaining in bytes. */ + volatile size_t rxRemainingBytes; /*!< Receive data remaining in bytes. */ + volatile uint32_t state; /*!< FlexIO SPI internal state. */ + uint8_t bytePerFrame; /*!< SPI mode, 2bytes or 1byte in a frame */ + flexio_spi_shift_direction_t direction; /*!< Shift direction. */ + flexio_spi_master_transfer_callback_t callback; /*!< FlexIO SPI callback. */ + void *userData; /*!< Callback parameter. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name FlexIO SPI Configuration + * @{ + */ + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module and configures the FlexIO SPI master hardware, + * and configures the FlexIO SPI with FlexIO SPI master configuration. The + * configuration structure can be filled by the user, or be set with default values + * by the FLEXIO_SPI_MasterGetDefaultConfig(). + * + * @note FlexIO SPI master only support CPOL = 0, which means clock inactive low. + * + * Example + @code + FLEXIO_SPI_Type spiDev = { + .flexioBase = FLEXIO, + .SDOPinIndex = 0, + .SDIPinIndex = 1, + .SCKPinIndex = 2, + .CSnPinIndex = 3, + .shifterIndex = {0,1}, + .timerIndex = {0,1} + }; + flexio_spi_master_config_t config = { + .enableMaster = true, + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false, + .baudRate_Bps = 500000, + .phase = kFLEXIO_SPI_ClockPhaseFirstEdge, + .direction = kFLEXIO_SPI_MsbFirst, + .dataMode = kFLEXIO_SPI_8BitMode + }; + FLEXIO_SPI_MasterInit(&spiDev, &config, srcClock_Hz); + @endcode + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param masterConfig Pointer to the flexio_spi_master_config_t structure. + * @param srcClock_Hz FlexIO source clock in Hz. +*/ +void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz); + +/*! + * @brief Gates the FlexIO clock. + * + * @param base Pointer to the FLEXIO_SPI_Type. +*/ +void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO SPI master. The configuration + * can be used directly by calling the FLEXIO_SPI_MasterConfigure(). + * Example: + @code + flexio_spi_master_config_t masterConfig; + FLEXIO_SPI_MasterGetDefaultConfig(&masterConfig); + @endcode + * @param masterConfig Pointer to the flexio_spi_master_config_t structure. +*/ +void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig); + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI slave hardware + * configuration, and configures the FlexIO SPI with FlexIO SPI slave configuration. The + * configuration structure can be filled by the user, or be set with default values + * by the FLEXIO_SPI_SlaveGetDefaultConfig(). + * + * @note Only one timer is needed in the FlexIO SPI slave. As a result, the second timer index is ignored. + * FlexIO SPI slave only support CPOL = 0, which means clock inactive low. + * Example + @code + FLEXIO_SPI_Type spiDev = { + .flexioBase = FLEXIO, + .SDOPinIndex = 0, + .SDIPinIndex = 1, + .SCKPinIndex = 2, + .CSnPinIndex = 3, + .shifterIndex = {0,1}, + .timerIndex = {0} + }; + flexio_spi_slave_config_t config = { + .enableSlave = true, + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false, + .phase = kFLEXIO_SPI_ClockPhaseFirstEdge, + .direction = kFLEXIO_SPI_MsbFirst, + .dataMode = kFLEXIO_SPI_8BitMode + }; + FLEXIO_SPI_SlaveInit(&spiDev, &config); + @endcode + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param slaveConfig Pointer to the flexio_spi_slave_config_t structure. +*/ +void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig); + +/*! + * @brief Gates the FlexIO clock. + * + * @param base Pointer to the FLEXIO_SPI_Type. +*/ +void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO SPI slave. The configuration + * can be used directly for calling the FLEXIO_SPI_SlaveConfigure(). + * Example: + @code + flexio_spi_slave_config_t slaveConfig; + FLEXIO_SPI_SlaveGetDefaultConfig(&slaveConfig); + @endcode + * @param slaveConfig Pointer to the flexio_spi_slave_config_t structure. +*/ +void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig); + +/*@}*/ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets FlexIO SPI status flags. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @return status flag; Use the status flag to AND the following flag mask and get the status. + * @arg kFLEXIO_SPI_TxEmptyFlag + * @arg kFLEXIO_SPI_RxEmptyFlag +*/ + +uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base); + +/*! + * @brief Clears FlexIO SPI status flags. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param mask status flag + * The parameter can be any combination of the following values: + * @arg kFLEXIO_SPI_TxEmptyFlag + * @arg kFLEXIO_SPI_RxEmptyFlag +*/ + +void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask); + +/*@}*/ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the FlexIO SPI interrupt. + * + * This function enables the FlexIO SPI interrupt. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param mask interrupt source. The parameter can be any combination of the following values: + * @arg kFLEXIO_SPI_RxFullInterruptEnable + * @arg kFLEXIO_SPI_TxEmptyInterruptEnable + */ +void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask); + +/*! + * @brief Disables the FlexIO SPI interrupt. + * + * This function disables the FlexIO SPI interrupt. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param mask interrupt source The parameter can be any combination of the following values: + * @arg kFLEXIO_SPI_RxFullInterruptEnable + * @arg kFLEXIO_SPI_TxEmptyInterruptEnable + */ +void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask); + +/*@}*/ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO SPI transmit DMA. This function enables/disables the FlexIO SPI Tx DMA, + * which means that asserting the kFLEXIO_SPI_TxEmptyFlag does/doesn't trigger the DMA request. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param mask SPI DMA source. + * @param enable True means enable DMA, false means disable DMA. + */ +void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable); + +/*! + * @brief Gets the FlexIO SPI transmit data register address for MSB first transfer. + * + * This function returns the SPI data register address, which is mainly used by DMA/eDMA. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @return FlexIO SPI transmit data register address. + */ +static inline uint32_t FLEXIO_SPI_GetTxDataRegisterAddress(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction) +{ + if (direction == kFLEXIO_SPI_MsbFirst) + { + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, + base->shifterIndex[0]) + + 3U; + } + else + { + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBuffer, base->shifterIndex[0]); + } +} + +/*! + * @brief Gets the FlexIO SPI receive data register address for the MSB first transfer. + * + * This function returns the SPI data register address, which is mainly used by DMA/eDMA. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @return FlexIO SPI receive data register address. + */ +static inline uint32_t FLEXIO_SPI_GetRxDataRegisterAddress(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction) +{ + if (direction == kFLEXIO_SPI_MsbFirst) + { + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferBitSwapped, base->shifterIndex[1]); + } + else + { + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferByteSwapped, + base->shifterIndex[1]); + } +} + +/*@}*/ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO SPI module operation. + * + * @param base Pointer to the FLEXIO_SPI_Type. + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_SPI_Enable(FLEXIO_SPI_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/*! + * @brief Sets baud rate for the FlexIO SPI transfer, which is only used for the master. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param baudRate_Bps Baud Rate needed in Hz. + * @param srcClockHz SPI source clock frequency in Hz. + */ +void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz); + +/*! + * @brief Writes one byte of data, which is sent using the MSB method. + * + * @note This is a non-blocking API, which returns directly after the data is put into the + * data register but the data transfer is not finished on the bus. Ensure that + * the TxEmptyFlag is asserted before calling this API. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @param data 8 bit/16 bit data. + */ +static inline void FLEXIO_SPI_WriteData(FLEXIO_SPI_Type *base, flexio_spi_shift_direction_t direction, uint16_t data) +{ + if (direction == kFLEXIO_SPI_MsbFirst) + { + base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data; + } + else + { + base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = data; + } +} + +/*! + * @brief Reads 8 bit/16 bit data. + * + * @note This is a non-blocking API, which returns directly after the data is read from the + * data register. Ensure that the RxFullFlag is asserted before calling this API. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @return 8 bit/16 bit data received. + */ +static inline uint16_t FLEXIO_SPI_ReadData(FLEXIO_SPI_Type *base, flexio_spi_shift_direction_t direction) +{ + if (direction == kFLEXIO_SPI_MsbFirst) + { + return base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]]; + } + else + { + return base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; + } +} + +/*! + * @brief Sends a buffer of data bytes. + * + * @note This function blocks using the polling method until all bytes have been sent. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @param buffer The data bytes to send. + * @param size The number of data bytes to send. + */ +void FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction, + const uint8_t *buffer, + size_t size); + +/*! + * @brief Receives a buffer of bytes. + * + * @note This function blocks using the polling method until all bytes have been received. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param direction Shift direction of MSB first or LSB first. + * @param buffer The buffer to store the received bytes. + * @param size The number of data bytes to be received. + * @param direction Shift direction of MSB first or LSB first. + */ +void FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base, + flexio_spi_shift_direction_t direction, + uint8_t *buffer, + size_t size); + +/*! + * @brief Receives a buffer of bytes. + * + * @note This function blocks via polling until all bytes have been received. + * + * @param base pointer to FLEXIO_SPI_Type structure + * @param xfer FlexIO SPI transfer structure, see #flexio_spi_transfer_t. + */ +void FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer); + +/*Transactional APIs*/ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the FlexIO SPI Master handle, which is used in transactional functions. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + * @param callback The callback function. + * @param userData The parameter of the callback function. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. + */ +status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + flexio_spi_master_transfer_callback_t callback, + void *userData); + +/*! + * @brief Master transfer data using IRQ. + * + * This function sends data using IRQ. This is a non-blocking function, which returns + * right away. When all data is sent out/received, the callback function is called. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + * @param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_FLEXIO_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base, + flexio_spi_master_handle_t *handle, + flexio_spi_transfer_t *xfer); + +/*! + * @brief Aborts the master data transfer, which used IRQ. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + */ +void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle); + +/*! + * @brief Gets the data transfer status which used IRQ. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count); + +/*! + * @brief FlexIO SPI master IRQ handler function. + * + * @param spiType Pointer to the FLEXIO_SPI_Type structure. + * @param spiHandle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. + */ +void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle); + +/*! + * @brief Initializes the FlexIO SPI Slave handle, which is used in transactional functions. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + * @param callback The callback function. + * @param userData The parameter of the callback function. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. + */ +status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + flexio_spi_slave_transfer_callback_t callback, + void *userData); + +/*! + * @brief Slave transfer data using IRQ. + * + * This function sends data using IRQ. This is a non-blocking function, which returns + * right away. When all data is sent out/received, the callback function is called. + * @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_FLEXIO_SPI_Busy SPI is not idle; it is running another transfer. + */ +status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + flexio_spi_transfer_t *xfer); + +/*! + * @brief Aborts the slave data transfer which used IRQ, share same API with master. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + */ +static inline void FLEXIO_SPI_SlaveTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_slave_handle_t *handle) +{ + FLEXIO_SPI_MasterTransferAbort(base, handle); +} +/*! + * @brief Gets the data transfer status which used IRQ, share same API with master. + * + * @param base Pointer to the FLEXIO_SPI_Type structure. + * @param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +static inline status_t FLEXIO_SPI_SlaveTransferGetCount(FLEXIO_SPI_Type *base, + flexio_spi_slave_handle_t *handle, + size_t *count) +{ + return FLEXIO_SPI_MasterTransferGetCount(base, handle, count); +} + +/*! + * @brief FlexIO SPI slave IRQ handler function. + * + * @param spiType Pointer to the FLEXIO_SPI_Type structure. + * @param spiHandle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. + */ +void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /*_FSL_FLEXIO_SPI_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi_dma.c new file mode 100644 index 0000000000..845aa41a70 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi_dma.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_spi_dma.h" + +/******************************************************************************* + * Definitons + ******************************************************************************/ + +/*base, kFLEXIO_SPI_TxDmaEnable, false); + + /* Disable interrupt. */ + DMA_DisableInterrupts(handle->base, handle->channel); + + /* change the state. */ + spiPrivateHandle->handle->txInProgress = false; + + /* All finished, call the callback. */ + if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false)) + { + if (spiPrivateHandle->handle->callback) + { + (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success, + spiPrivateHandle->handle->userData); + } + } +} + +static void FLEXIO_SPI_RxDMACallback(dma_handle_t *handle, void *param) +{ + flexio_spi_master_dma_private_handle_t *spiPrivateHandle = (flexio_spi_master_dma_private_handle_t *)param; + + /* Disable Rx DMA. */ + FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, kFLEXIO_SPI_RxDmaEnable, false); + + /* Disable interrupt. */ + DMA_DisableInterrupts(handle->base, handle->channel); + + /* change the state. */ + spiPrivateHandle->handle->rxInProgress = false; + + /* All finished, call the callback. */ + if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false)) + { + if (spiPrivateHandle->handle->callback) + { + (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success, + spiPrivateHandle->handle->userData); + } + } +} + +static void FLEXIO_SPI_DMAConfig(FLEXIO_SPI_Type *base, + flexio_spi_master_dma_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + dma_transfer_config_t xferConfig; + flexio_spi_shift_direction_t direction; + uint8_t bytesPerFrame; + + /* Configure the values in handle. */ + switch (xfer->flags) + { + case kFLEXIO_SPI_8bitMsb: + bytesPerFrame = 1; + direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_8bitLsb: + bytesPerFrame = 1; + direction = kFLEXIO_SPI_LsbFirst; + break; + case kFLEXIO_SPI_16bitMsb: + bytesPerFrame = 2; + direction = kFLEXIO_SPI_MsbFirst; + break; + case kFLEXIO_SPI_16bitLsb: + bytesPerFrame = 2; + direction = kFLEXIO_SPI_LsbFirst; + break; + default: + bytesPerFrame = 1; + direction = kFLEXIO_SPI_MsbFirst; + assert(true); + break; + } + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + /* Configure tx transfer DMA. */ + xferConfig.destAddr = FLEXIO_SPI_GetTxDataRegisterAddress(base, direction); + xferConfig.enableDestIncrement = false; + if (bytesPerFrame == 1U) + { + xferConfig.srcSize = kDMA_Transfersize8bits; + xferConfig.destSize = kDMA_Transfersize8bits; + } + else + { + if (direction == kFLEXIO_SPI_MsbFirst) + { + xferConfig.destAddr -= 1U; + } + xferConfig.srcSize = kDMA_Transfersize16bits; + xferConfig.destSize = kDMA_Transfersize16bits; + } + + /* Configure DMA channel. */ + if (xfer->txData) + { + xferConfig.enableSrcIncrement = true; + xferConfig.srcAddr = (uint32_t)(xfer->txData); + } + else + { + /* Disable the source increasement and source set to dummyData. */ + xferConfig.enableSrcIncrement = false; + xferConfig.srcAddr = (uint32_t)(&s_dummyData); + } + + xferConfig.transferSize = xfer->dataSize; + + if (handle->txHandle) + { + DMA_SubmitTransfer(handle->txHandle, &xferConfig, kDMA_EnableInterrupt); + } + + /* Configure tx transfer DMA. */ + if (xfer->rxData) + { + xferConfig.srcAddr = FLEXIO_SPI_GetRxDataRegisterAddress(base, direction); + xferConfig.enableSrcIncrement = false; + xferConfig.destAddr = (uint32_t)(xfer->rxData); + xferConfig.enableDestIncrement = true; + DMA_SubmitTransfer(handle->rxHandle, &xferConfig, kDMA_EnableInterrupt); + handle->rxInProgress = true; + FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_RxDmaEnable, true); + DMA_StartTransfer(handle->rxHandle); + } + + /* Always start Tx transfer. */ + if (handle->txHandle) + { + handle->txInProgress = true; + FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_TxDmaEnable, true); + DMA_StartTransfer(handle->txHandle); + } +} + +status_t FLEXIO_SPI_MasterTransferCreateHandleDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_dma_handle_t *handle, + flexio_spi_master_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle) +{ + assert(handle); + + uint8_t index = 0; + + /* Find the an empty handle pointer to store the handle. */ + for (index = 0; index < FLEXIO_SPI_HANDLE_COUNT; index++) + { + if (s_dmaPrivateHandle[index].base == NULL) + { + s_dmaPrivateHandle[index].base = base; + s_dmaPrivateHandle[index].handle = handle; + break; + } + } + + if (index == FLEXIO_SPI_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + + /* Set spi base to handle. */ + handle->txHandle = txHandle; + handle->rxHandle = rxHandle; + + /* Register callback and userData. */ + handle->callback = callback; + handle->userData = userData; + + /* Set SPI state to idle. */ + handle->txInProgress = false; + handle->rxInProgress = false; + + /* Install callback for Tx/Rx dma channel. */ + if (handle->txHandle) + { + DMA_SetCallback(handle->txHandle, FLEXIO_SPI_TxDMACallback, &s_dmaPrivateHandle[index]); + } + if (handle->rxHandle) + { + DMA_SetCallback(handle->rxHandle, FLEXIO_SPI_RxDMACallback, &s_dmaPrivateHandle[index]); + } + + return kStatus_Success; +} + +status_t FLEXIO_SPI_MasterTransferDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_dma_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + uint32_t dataMode = 0; + uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]]; + + timerCmp &= 0x00FFU; + + /* Check if the device is busy. */ + if ((handle->txInProgress) || (handle->rxInProgress)) + { + return kStatus_FLEXIO_SPI_Busy; + } + + /* Check if input parameter invalid. */ + if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + /* configure data mode. */ + if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb)) + { + dataMode = (8 * 2 - 1U) << 8U; + } + else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb)) + { + dataMode = (16 * 2 - 1U) << 8U; + } + else + { + dataMode = 8 * 2 - 1U; + } + + dataMode |= timerCmp; + + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + FLEXIO_SPI_DMAConfig(base, handle, xfer); + + return kStatus_Success; +} + +status_t FLEXIO_SPI_MasterTransferGetCountDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_dma_handle_t *handle, + size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + if (handle->rxInProgress) + { + *count = (handle->transferSize - DMA_GetRemainingBytes(handle->rxHandle->base, handle->rxHandle->channel)); + } + else + { + *count = (handle->transferSize - DMA_GetRemainingBytes(handle->txHandle->base, handle->txHandle->channel)); + } + + return kStatus_Success; +} + +void FLEXIO_SPI_MasterTransferAbortDMA(FLEXIO_SPI_Type *base, flexio_spi_master_dma_handle_t *handle) +{ + assert(handle); + + /* Disable dma. */ + DMA_AbortTransfer(handle->txHandle); + DMA_AbortTransfer(handle->rxHandle); + + /* Disable DMA enable bit. */ + FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_DmaAllEnable, false); + + /* Set the handle state. */ + handle->txInProgress = false; + handle->rxInProgress = false; +} + +status_t FLEXIO_SPI_SlaveTransferDMA(FLEXIO_SPI_Type *base, + flexio_spi_slave_dma_handle_t *handle, + flexio_spi_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + uint32_t dataMode = 0; + + /* Check if the device is busy. */ + if ((handle->txInProgress) || (handle->rxInProgress)) + { + return kStatus_FLEXIO_SPI_Busy; + } + + /* Check if input parameter invalid. */ + if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + /* configure data mode. */ + if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb)) + { + dataMode = 8 * 2 - 1U; + } + else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb)) + { + dataMode = 16 * 2 - 1U; + } + else + { + dataMode = 8 * 2 - 1U; + } + + base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; + + FLEXIO_SPI_DMAConfig(base, handle, xfer); + + return kStatus_Success; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi_dma.h new file mode 100644 index 0000000000..7ebce1e41e --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_spi_dma.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_SPI_DMA_H_ +#define _FSL_FLEXIO_SPI_DMA_H_ + +#include "fsl_flexio_spi.h" +#include "fsl_dma.h" + +/*! + * @addtogroup flexio_dma_spi + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief typedef for flexio_spi_master_dma_handle_t in advance. */ +typedef struct _flexio_spi_master_dma_handle flexio_spi_master_dma_handle_t; + +/*! @brief Slave handle is the same with master handle. */ +typedef flexio_spi_master_dma_handle_t flexio_spi_slave_dma_handle_t; + +/*! @brief FlexIO SPI master callback for finished transmit */ +typedef void (*flexio_spi_master_dma_transfer_callback_t)(FLEXIO_SPI_Type *base, + flexio_spi_master_dma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief FlexIO SPI slave callback for finished transmit */ +typedef void (*flexio_spi_slave_dma_transfer_callback_t)(FLEXIO_SPI_Type *base, + flexio_spi_slave_dma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief FlexIO SPI DMA transfer handle, users should not touch the content of the handle.*/ +struct _flexio_spi_master_dma_handle +{ + size_t transferSize; /*!< Total bytes to be transferred. */ + bool txInProgress; /*!< Send transfer in progress */ + bool rxInProgress; /*!< Receive transfer in progress */ + dma_handle_t *txHandle; /*!< DMA handler for SPI send */ + dma_handle_t *rxHandle; /*!< DMA handler for SPI receive */ + flexio_spi_master_dma_transfer_callback_t callback; /*!< Callback for SPI DMA transfer */ + void *userData; /*!< User Data for SPI DMA callback */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name DMA Transactional + * @{ + */ + +/*! + * @brief Initializes the FLEXO SPI master DMA handle. + * + * This function initializes the FLEXO SPI master DMA handle which can be used for other FLEXO SPI master transactional + * APIs. + * Usually, for a specified FLEXO SPI instance, user need only call this API once to get the initialized handle. + * + * @param base pointer to FLEXIO_SPI_Type structure. + * @param handle pointer to flexio_spi_master_dma_handle_t structure to store the transfer state. + * @param callback SPI callback, NULL means no callback. + * @param userData callback function parameter. + * @param txHandle User requested DMA handle for FlexIO SPI RX DMA transfer. + * @param rxHandle User requested DMA handle for FlexIO SPI TX DMA transfer. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO SPI DMA type/handle table out of range. + */ +status_t FLEXIO_SPI_MasterTransferCreateHandleDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_dma_handle_t *handle, + flexio_spi_master_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle); + +/*! + * @brief Performs a non-blocking FlexIO SPI transfer using DMA. + * + * @note This interface returned immediately after transfer initiates, users could call + * FLEXIO_SPI_MasterGetTransferCountDMA to poll the transfer status to check + * whether FlexIO SPI transfer finished. + * + * @param base pointer to FLEXIO_SPI_Type structure. + * @param handle pointer to flexio_spi_master_dma_handle_t structure to store the transfer state. + * @param xfer Pointer to FlexIO SPI transfer structure. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer. + */ +status_t FLEXIO_SPI_MasterTransferDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_dma_handle_t *handle, + flexio_spi_transfer_t *xfer); + +/*! + * @brief Aborts a FlexIO SPI transfer using DMA. + * + * @param base pointer to FLEXIO_SPI_Type structure. + * @param handle FlexIO SPI DMA handle pointer. + */ +void FLEXIO_SPI_MasterTransferAbortDMA(FLEXIO_SPI_Type *base, flexio_spi_master_dma_handle_t *handle); + +/*! + * @brief Gets the remaining bytes for FlexIO SPI DMA transfer. + * + * @param base pointer to FLEXIO_SPI_Type structure. + * @param handle FlexIO SPI DMA handle pointer. + * @param count Number of bytes transferred so far by the non-blocking transaction. + */ +status_t FLEXIO_SPI_MasterTransferGetCountDMA(FLEXIO_SPI_Type *base, + flexio_spi_master_dma_handle_t *handle, + size_t *count); + +/*! + * @brief Initializes the FlexIO SPI slave DMA handle. + * + * This function initializes the FlexIO SPI slave DMA handle. + * + * @param base pointer to FLEXIO_SPI_Type structure. + * @param handle pointer to flexio_spi_slave_dma_handle_t structure to store the transfer state. + * @param callback SPI callback, NULL means no callback. + * @param userData callback function parameter. + * @param txHandle User requested DMA handle for FlexIO SPI TX DMA transfer. + * @param rxHandle User requested DMA handle for FlexIO SPI RX DMA transfer. + */ +static inline void FLEXIO_SPI_SlaveTransferCreateHandleDMA(FLEXIO_SPI_Type *base, + flexio_spi_slave_dma_handle_t *handle, + flexio_spi_slave_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle) +{ + FLEXIO_SPI_MasterTransferCreateHandleDMA(base, handle, callback, userData, txHandle, rxHandle); +} + +/*! + * @brief Performs a non-blocking FlexIO SPI transfer using DMA. + * + * @note This interface returned immediately after transfer initiates, users could call + * FLEXIO_SPI_SlaveGetTransferCountDMA to poll the transfer status to + * check whether FlexIO SPI transfer finished. + * + * @param base pointer to FLEXIO_SPI_Type structure. + * @param handle pointer to flexio_spi_slave_dma_handle_t structure to store the transfer state. + * @param xfer Pointer to FlexIO SPI transfer structure. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer. + */ +status_t FLEXIO_SPI_SlaveTransferDMA(FLEXIO_SPI_Type *base, + flexio_spi_slave_dma_handle_t *handle, + flexio_spi_transfer_t *xfer); + +/*! + * @brief Aborts a FlexIO SPI transfer using DMA. + * + * @param base pointer to FLEXIO_SPI_Type structure. + * @param handle pointer to flexio_spi_slave_dma_handle_t structure to store the transfer state. + */ +static inline void FLEXIO_SPI_SlaveTransferAbortDMA(FLEXIO_SPI_Type *base, flexio_spi_slave_dma_handle_t *handle) +{ + FLEXIO_SPI_MasterTransferAbortDMA(base, handle); +} + +/*! + * @brief Gets the remaining bytes to be transferred for FlexIO SPI DMA. + * + * @param base pointer to FLEXIO_SPI_Type structure. + * @param handle FlexIO SPI DMA handle pointer. + * @param count Number of bytes transferred so far by the non-blocking transaction. + */ +static inline status_t FLEXIO_SPI_SlaveTransferGetCountDMA(FLEXIO_SPI_Type *base, + flexio_spi_slave_dma_handle_t *handle, + size_t *count) +{ + return FLEXIO_SPI_MasterTransferGetCountDMA(base, handle, count); +} + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart.c new file mode 100644 index 0000000000..92349ea5a5 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart.c @@ -0,0 +1,690 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_uart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*rxRingBufferTail > handle->rxRingBufferHead) + { + size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); + } + else + { + size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); + } + + return size; +} + +static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle) +{ + bool full; + + if (FLEXIO_UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) + { + full = true; + } + else + { + full = false; + } + + return full; +} + +void FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz) +{ + assert(base && userConfig); + + flexio_shifter_config_t shifterConfig; + flexio_timer_config_t timerConfig; + uint32_t ctrlReg = 0; + uint16_t timerDiv = 0; + uint16_t timerCmp = 0; + + /* Clear the shifterConfig & timerConfig struct. */ + memset(&shifterConfig, 0, sizeof(shifterConfig)); + memset(&timerConfig, 0, sizeof(timerConfig)); + + /* Ungate flexio clock. */ + CLOCK_EnableClock(kCLOCK_Flexio0); + + /* Reset FLEXIO before configuration. */ + FLEXIO_Reset(base->flexioBase); + + /* Configure FLEXIO UART */ + ctrlReg = base->flexioBase->CTRL; + ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); + ctrlReg |= (FLEXIO_CTRL_DOZEN(userConfig->enableInDoze) | FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | + FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(userConfig->enableUart)); + + base->flexioBase->CTRL = ctrlReg; + + /* Do hardware configuration. */ + /* 1. Configure the shifter 0 for tx. */ + shifterConfig.timerSelect = base->timerIndex[0]; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; + shifterConfig.pinSelect = base->TxPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); + + /*2. Configure the timer 0 for tx. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->TxPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetNever; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + timerDiv = srcClock_Hz / userConfig->baudRate_Bps; + timerDiv = timerDiv / 2 - 1; + + timerCmp = ((uint32_t)(userConfig->bitCountPerChar * 2 - 1)) << 8U; + timerCmp |= timerDiv; + + timerConfig.timerCompare = timerCmp; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); + + /* 3. Configure the shifter 1 for rx. */ + shifterConfig.timerSelect = base->timerIndex[1]; + shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; + shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + shifterConfig.pinSelect = base->RxPinIndex; + shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; + shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; + shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; + shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; + shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; + + FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); + + /* 4. Configure the timer 1 for rx. */ + timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->RxPinIndex); + timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; + timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal; + timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; + timerConfig.pinSelect = base->RxPinIndex; + timerConfig.pinPolarity = kFLEXIO_PinActiveLow; + timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; + timerConfig.timerOutput = kFLEXIO_TimerOutputOneAffectedByReset; + timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; + timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinRisingEdge; + timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; + timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge; + timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; + timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; + + timerConfig.timerCompare = timerCmp; + + FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); +} + +void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base) +{ + /* Disable FLEXIO UART module. */ + FLEXIO_UART_Enable(base, false); + + /* Gate flexio clock. */ + CLOCK_DisableClock(kCLOCK_Flexio0); +} + +void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig) +{ + assert(userConfig); + + userConfig->enableUart = true; + userConfig->enableInDoze = false; + userConfig->enableInDebug = true; + userConfig->enableFastAccess = false; + /* Default baud rate 115200. */ + userConfig->baudRate_Bps = 115200U; + /* Default bit count at 8. */ + userConfig->bitCountPerChar = kFLEXIO_UART_8BitsPerChar; +} + +void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable) + { + FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable) + { + FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base) +{ + uint32_t status = 0; + status = + ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]); + status |= + (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) + << 1U); + status |= + (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) + << 2U); + return status; +} + +void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask) +{ + if (mask & kFLEXIO_UART_TxDataRegEmptyFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]); + } + if (mask & kFLEXIO_UART_RxDataRegFullFlag) + { + FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } + if (mask & kFLEXIO_UART_RxOverRunFlag) + { + FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); + } +} + +void FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize) +{ + assert(txData); + assert(txSize); + + while (txSize--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))) + { + } + + base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *txData++; + } +} + +void FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize) +{ + assert(rxData); + assert(rxSize); + + while (rxSize--) + { + /* Wait until data transfer complete. */ + while (!(FLEXIO_UART_GetStatusFlags(base) & kFLEXIO_UART_RxDataRegFullFlag)) + { + } + + *rxData++ = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; + } +} + +status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + IRQn_Type flexio_irqs[] = FLEXIO_IRQS; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set the TX/RX state. */ + handle->rxState = kFLEXIO_UART_RxIdle; + handle->txState = kFLEXIO_UART_TxIdle; + + /* Set the callback and user data. */ + handle->callback = callback; + handle->userData = userData; + + /* Enable interrupt in NVIC. */ + EnableIRQ(flexio_irqs[0]); + + /* Save the context in global variables to support the double weak mechanism. */ + return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_UART_TransferHandleIRQ); +} + +void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize) +{ + assert(handle); + + /* Setup the ringbuffer address */ + if (ringBuffer) + { + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; + + /* Enable the interrupt to accept the data when user need the ring buffer. */ + FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } +} + +void FLEXIO_UART_TransferStopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) +{ + assert(handle); + + if (handle->rxState == kFLEXIO_UART_RxIdle) + { + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + + handle->rxRingBuffer = NULL; + handle->rxRingBufferSize = 0U; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; +} + +status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_t *xfer) +{ + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* Return error if current TX busy. */ + if (kFLEXIO_UART_TxBusy == handle->txState) + { + status = kStatus_FLEXIO_UART_TxBusy; + } + else + { + handle->txData = xfer->data; + handle->txDataSize = xfer->dataSize; + handle->txState = kFLEXIO_UART_TxBusy; + + /* Enable transmiter interrupt. */ + FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); + + status = kStatus_Success; + } + + return status; +} + +void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) +{ + /* Disable the transmitter and disable the interrupt. */ + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); + + handle->txDataSize = 0; + handle->txState = kFLEXIO_UART_TxIdle; +} + +status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_Success; + } + + *count = handle->txSize - handle->txDataSize; + + return kStatus_Success; +} + +status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_t *xfer, + size_t *receivedBytes) +{ + uint32_t i; + status_t status; + /* How many bytes to copy from ring buffer to user memory. */ + size_t bytesToCopy = 0U; + /* How many bytes to receive. */ + size_t bytesToReceive; + /* How many bytes currently have received. */ + size_t bytesCurrentReceived; + uint32_t regPrimask = 0U; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* How to get data: + 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize + to uart handle, enable interrupt to store received data to xfer->data. When + all data received, trigger callback. + 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. + If there are enough data in ring buffer, copy them to xfer->data and return. + If there are not enough data in ring buffer, copy all of them to xfer->data, + save the xfer->data remained empty space to uart handle, receive data + to this empty space and trigger callback when finished. */ + + if (kFLEXIO_UART_RxBusy == handle->rxState) + { + status = kStatus_FLEXIO_UART_RxBusy; + } + else + { + bytesToReceive = xfer->dataSize; + bytesCurrentReceived = 0U; + + /* If RX ring buffer is used. */ + if (handle->rxRingBuffer) + { + /* Disable IRQ, protect ring buffer. */ + regPrimask = __get_PRIMASK(); + __disable_irq(); + + /* How many bytes in RX ring buffer currently. */ + bytesToCopy = FLEXIO_UART_TransferGetRxRingBufferLength(handle); + + if (bytesToCopy) + { + bytesToCopy = MIN(bytesToReceive, bytesToCopy); + + bytesToReceive -= bytesToCopy; + + /* Copy data from ring buffer to user memory. */ + for (i = 0U; i < bytesToCopy; i++) + { + xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; + + /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + } + + /* If ring buffer does not have enough data, still need to read more data. */ + if (bytesToReceive) + { + /* No data in ring buffer, save the request to UART handle. */ + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxState = kFLEXIO_UART_RxBusy; + } + + /* Recover PRIMASK, enable IRQ if previously enabled. */ + __set_PRIMASK(regPrimask); + } + /* Ring buffer not used. */ + else + { + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxState = kFLEXIO_UART_RxBusy; + + /* Enable RX interrupt. */ + FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + + /* Return the how many bytes have read. */ + if (receivedBytes) + { + *receivedBytes = bytesCurrentReceived; + } + + status = kStatus_Success; + } + + return status; +} + +void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) +{ + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ + if (!handle->rxRingBuffer) + { + /* Disable RX interrupt. */ + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + + handle->rxDataSize = 0U; + handle->rxState = kFLEXIO_UART_RxIdle; +} + +status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_Success; + } + + *count = handle->rxSize - handle->rxDataSize; + + return kStatus_Success; +} + +void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle) +{ + uint8_t count = 1; + FLEXIO_UART_Type *base = (FLEXIO_UART_Type *)uartType; + flexio_uart_handle_t *handle = (flexio_uart_handle_t *)uartHandle; + + /* Read the status back. */ + uint8_t status = FLEXIO_UART_GetStatusFlags(base); + + /* If RX overrun. */ + if (kFLEXIO_UART_RxOverRunFlag & status) + { + /* Clear Overrun flag. */ + FLEXIO_UART_ClearStatusFlags(base, kFLEXIO_UART_RxOverRunFlag); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_FLEXIO_UART_RxHardwareOverrun, handle->userData); + } + } + + /* Receive data register full */ + if ((kFLEXIO_UART_RxDataRegFullFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[1]))) + { + /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ + if (handle->rxDataSize) + { + /* Using non block API to read the data from the registers. */ + FLEXIO_UART_ReadByte(base, handle->rxData); + handle->rxDataSize--; + handle->rxData++; + count--; + + /* If all the data required for upper layer is ready, trigger callback. */ + if (!handle->rxDataSize) + { + handle->rxState = kFLEXIO_UART_RxIdle; + + if (handle->callback) + { + handle->callback(base, handle, kStatus_FLEXIO_UART_RxIdle, handle->userData); + } + } + } + + if (handle->rxRingBuffer) + { + if (count) + { + /* If RX ring buffer is full, trigger callback to notify over run. */ + if (FLEXIO_UART_TransferIsRxRingBufferFull(handle)) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_FLEXIO_UART_RxRingBufferOverrun, handle->userData); + } + } + + /* If ring buffer is still full after callback function, the oldest data is overrided. */ + if (FLEXIO_UART_TransferIsRxRingBufferFull(handle)) + { + /* Increase handle->rxRingBufferTail to make room for new data. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + + /* Read data. */ + handle->rxRingBuffer[handle->rxRingBufferHead] = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; + + /* Increase handle->rxRingBufferHead. */ + if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferHead = 0U; + } + else + { + handle->rxRingBufferHead++; + } + } + } + /* If no receive requst pending, stop RX interrupt. */ + else if (!handle->rxDataSize) + { + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); + } + else + { + } + } + + /* Send data register empty and the interrupt is enabled. */ + if ((kFLEXIO_UART_TxDataRegEmptyFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[0]))) + { + if (handle->txDataSize) + { + /* Using non block API to write the data to the registers. */ + FLEXIO_UART_WriteByte(base, handle->txData); + handle->txData++; + handle->txDataSize--; + count--; + + /* If all the data are written to data register, TX finished. */ + if (!handle->txDataSize) + { + handle->txState = kFLEXIO_UART_TxIdle; + + /* Disable TX register empty interrupt. */ + FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_FLEXIO_UART_TxIdle, handle->userData); + } + } + } + } +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart.h new file mode 100644 index 0000000000..9ffe6a8a62 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart.h @@ -0,0 +1,586 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLEXIO_UART_H_ +#define _FSL_FLEXIO_UART_H_ + +#include "fsl_common.h" +#include "fsl_flexio.h" + +/*! + * @addtogroup flexio_uart + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexIO UART driver version 2.1.0. */ +#define FSL_FLEXIO_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief Error codes for the UART driver. */ +enum _flexio_uart_status +{ + kStatus_FLEXIO_UART_TxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 0), /*!< Transmitter is busy. */ + kStatus_FLEXIO_UART_RxBusy = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 1), /*!< Receiver is busy. */ + kStatus_FLEXIO_UART_TxIdle = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 2), /*!< UART transmitter is idle. */ + kStatus_FLEXIO_UART_RxIdle = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 3), /*!< UART receiver is idle. */ + kStatus_FLEXIO_UART_ERROR = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 4), /*!< ERROR happens on UART. */ + kStatus_FLEXIO_UART_RxRingBufferOverrun = + MAKE_STATUS(kStatusGroup_FLEXIO_UART, 5), /*!< UART RX software ring buffer overrun. */ + kStatus_FLEXIO_UART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_FLEXIO_UART, 6) /*!< UART RX receiver overrun. */ +}; + +/*! @brief FlexIO UART bit count per char. */ +typedef enum _flexio_uart_bit_count_per_char +{ + kFLEXIO_UART_7BitsPerChar = 7U, /*!< 7-bit data characters */ + kFLEXIO_UART_8BitsPerChar = 8U, /*!< 8-bit data characters */ + kFLEXIO_UART_9BitsPerChar = 9U, /*!< 9-bit data characters */ +} flexio_uart_bit_count_per_char_t; + +/*! @brief Define FlexIO UART interrupt mask. */ +enum _flexio_uart_interrupt_enable +{ + kFLEXIO_UART_TxDataRegEmptyInterruptEnable = 0x1U, /*!< Transmit buffer empty interrupt enable. */ + kFLEXIO_UART_RxDataRegFullInterruptEnable = 0x2U, /*!< Receive buffer full interrupt enable. */ +}; + +/*! @brief Define FlexIO UART status mask. */ +enum _flexio_uart_status_flags +{ + kFLEXIO_UART_TxDataRegEmptyFlag = 0x1U, /*!< Transmit buffer empty flag. */ + kFLEXIO_UART_RxDataRegFullFlag = 0x2U, /*!< Receive buffer full flag. */ + kFLEXIO_UART_RxOverRunFlag = 0x4U, /*!< Receive buffer over run flag. */ +}; + +/*! @brief Define FlexIO UART access structure typedef. */ +typedef struct _flexio_uart_type +{ + FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */ + uint8_t TxPinIndex; /*!< Pin select for UART_Tx. */ + uint8_t RxPinIndex; /*!< Pin select for UART_Rx. */ + uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO UART. */ + uint8_t timerIndex[2]; /*!< Timer index used in FlexIO UART. */ +} FLEXIO_UART_Type; + +/*! @brief Define FlexIO UART user configuration structure. */ +typedef struct _flexio_uart_config +{ + bool enableUart; /*!< Enable/disable FlexIO UART TX & RX. */ + bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode*/ + bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode*/ + bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, + fast access requires the FlexIO clock to be at least + twice the frequency of the bus clock. */ + uint32_t baudRate_Bps; /*!< Baud rate in Bps. */ + flexio_uart_bit_count_per_char_t bitCountPerChar; /*!< number of bits, 7/8/9 -bit */ +} flexio_uart_config_t; + +/*! @brief Define FlexIO UART transfer structure. */ +typedef struct _flexio_uart_transfer +{ + uint8_t *data; /*!< Transfer buffer*/ + size_t dataSize; /*!< Transfer size*/ +} flexio_uart_transfer_t; + +/* Forward declaration of the handle typedef. */ +typedef struct _flexio_uart_handle flexio_uart_handle_t; + +/*! @brief FlexIO UART transfer callback function. */ +typedef void (*flexio_uart_transfer_callback_t)(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + status_t status, + void *userData); + +/*! @brief Define FLEXIO UART handle structure*/ +struct _flexio_uart_handle +{ + uint8_t *volatile txData; /*!< Address of remaining data to send. */ + volatile size_t txDataSize; /*!< Size of the remaining data to send. */ + uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ + volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ + size_t txSize; /*!< Total bytes to be sent. */ + size_t rxSize; /*!< Total bytes to be received. */ + + uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ + size_t rxRingBufferSize; /*!< Size of the ring buffer. */ + volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ + volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ + + flexio_uart_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< UART callback function parameter.*/ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the FlexIO clock, resets the FlexIO module, configures FlexIO UART + * hardware, and configures the FlexIO UART with FlexIO UART configuration. + * The configuration structure can be filled by the user, or be set with + * default values by FLEXIO_UART_GetDefaultConfig(). + * + * Example + @code + FLEXIO_UART_Type base = { + .flexioBase = FLEXIO, + .TxPinIndex = 0, + .RxPinIndex = 1, + .shifterIndex = {0,1}, + .timerIndex = {0,1} + }; + flexio_uart_config_t config = { + .enableInDoze = false, + .enableInDebug = true, + .enableFastAccess = false, + .baudRate_Bps = 115200U, + .bitCountPerChar = 8 + }; + FLEXIO_UART_Init(base, &config, srcClock_Hz); + @endcode + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param userConfig Pointer to the flexio_uart_config_t structure. + * @param srcClock_Hz FlexIO source clock in Hz. +*/ +void FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz); + +/*! + * @brief Disables the FlexIO UART and gates the FlexIO clock. + * + * @note After calling this API, call the FLEXO_UART_Init to use the FlexIO UART module. + * + * @param base pointer to FLEXIO_UART_Type structure +*/ +void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base); + +/*! + * @brief Gets the default configuration to configure the FlexIO UART. The configuration + * can be used directly for calling the FLEXIO_UART_Init(). + * Example: + @code + flexio_uart_config_t config; + FLEXIO_UART_GetDefaultConfig(&userConfig); + @endcode + * @param userConfig Pointer to the flexio_uart_config_t structure. +*/ +void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig); + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the FlexIO UART status flags. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @return FlexIO UART status flags. +*/ + +uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base); + +/*! + * @brief Gets the FlexIO UART status flags. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param mask Status flag. + * The parameter can be any combination of the following values: + * @arg kFLEXIO_UART_TxDataRegEmptyFlag + * @arg kFLEXIO_UART_RxEmptyFlag + * @arg kFLEXIO_UART_RxOverRunFlag +*/ + +void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the FlexIO UART interrupt. + * + * This function enables the FlexIO UART interrupt. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param mask Interrupt source. + */ +void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask); + +/*! + * @brief Disables the FlexIO UART interrupt. + * + * This function disables the FlexIO UART interrupt. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param mask Interrupt source. + */ +void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Gets the FlexIO UARt transmit data register address. + * + * This function returns the UART data register address, which is mainly used by DMA/eDMA. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @return FlexIO UART transmit data register address. + */ +static inline uint32_t FLEXIO_UART_GetTxDataRegisterAddress(FLEXIO_UART_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBuffer, base->shifterIndex[0]); +} + +/*! + * @brief Gets the FlexIO UART receive data register address. + * + * This function returns the UART data register address, which is mainly used by DMA/eDMA. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @return FlexIO UART receive data register address. + */ +static inline uint32_t FLEXIO_UART_GetRxDataRegisterAddress(FLEXIO_UART_Type *base) +{ + return FLEXIO_GetShifterBufferAddress(base->flexioBase, kFLEXIO_ShifterBufferByteSwapped, base->shifterIndex[1]); +} + +/*! + * @brief Enables/disables the FlexIO UART transmit DMA. + * This function enables/disables the FlexIO UART Tx DMA, + * which means asserting the kFLEXIO_UART_TxDataRegEmptyFlag does/doesn't trigger the DMA request. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param enable True to enable, false to disable. + */ +static inline void FLEXIO_UART_EnableTxDMA(FLEXIO_UART_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->shifterIndex[0], enable); +} + +/*! + * @brief Enables/disables the FlexIO UART receive DMA. + * This function enables/disables the FlexIO UART Rx DMA, + * which means asserting kFLEXIO_UART_RxDataRegFullFlag does/doesn't trigger the DMA request. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param enable True to enable, false to disable. + */ +static inline void FLEXIO_UART_EnableRxDMA(FLEXIO_UART_Type *base, bool enable) +{ + FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1 << base->shifterIndex[1], enable); +} + +/* @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Enables/disables the FlexIO UART module operation. + * + * @param base Pointer to the FLEXIO_UART_Type. + * @param enable True to enable, false to disable. +*/ +static inline void FLEXIO_UART_Enable(FLEXIO_UART_Type *base, bool enable) +{ + if (enable) + { + base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; + } + else + { + base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; + } +} + +/*! + * @brief Writes one byte of data. + * + * @note This is a non-blocking API, which returns directly after the data is put into the + * data register. Ensure that the TxEmptyFlag is asserted before calling + * this API. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param buffer The data bytes to send. + */ +static inline void FLEXIO_UART_WriteByte(FLEXIO_UART_Type *base, const uint8_t *buffer) +{ + base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *buffer; +} + +/*! + * @brief Reads one byte of data. + * + * @note This is a non-blocking API, which returns directly after the data is read from the + * data register. Ensure that the RxFullFlag is asserted before calling this API. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param buffer The buffer to store the received bytes. + */ +static inline void FLEXIO_UART_ReadByte(FLEXIO_UART_Type *base, uint8_t *buffer) +{ + *buffer = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; +} + +/*! + * @brief Sends a buffer of data bytes. + * + * @note This function blocks using the polling method until all bytes have been sent. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param txData The data bytes to send. + * @param txSize The number of data bytes to send. + */ +void FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize); + +/*! + * @brief Receives a buffer of bytes. + * + * @note This function blocks using the polling method until all bytes have been received. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param rxData The buffer to store the received bytes. + * @param rxSize The number of data bytes to be received. + */ +void FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the UART handle. + * + * This function initializes the FlexIO UART handle, which can be used for other FlexIO + * UART transactional APIs. Call this API once to get the + * initialized handle. + * + * The UART driver supports the "background" receiving, which means that user can set up + * a RX ring buffer optionally. Data received is stored into the ring buffer even when + * the user doesn't call the FLEXIO_UART_TransferReceiveNonBlocking() API. If there is already data + * received in the ring buffer, user can get the received data from the ring buffer + * directly. The ring buffer is disabled if passing NULL as @p ringBuffer. + * + * @param base to FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param callback The callback function. + * @param userData The parameter of the callback function. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. + */ +status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_callback_t callback, + void *userData); + +/*! + * @brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific UART handle. + * + * When the RX ring buffer is used, data received is stored into the ring buffer even when + * the user doesn't call the UART_ReceiveNonBlocking() API. If there are already data received + * in the ring buffer, user can get the received data from the ring buffer directly. + * + * @note When using the RX ring buffer, one byte is reserved for internal use. In other + * words, if @p ringBufferSize is 32, only 31 bytes are used for saving data. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. + * @param ringBufferSize Size of the ring buffer. + */ +void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize); + +/*! + * @brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + */ +void FLEXIO_UART_StopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle); + +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function sends data using an interrupt method. This is a non-blocking function, + * which returns directly without waiting for all data to be written to the TX register. When + * all data are written to TX register in ISR, the FlexIO UART driver calls the callback + * function and passes the @ref kStatus_FLEXIO_UART_TxIdle as status parameter. + * + * @note The kStatus_FLEXIO_UART_TxIdle is passed to the upper layer when all data is written + * to the TX register. However, it does not ensure that all data is sent out. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param xfer FlexIO UART transfer structure. See #flexio_uart_transfer_t. + * @retval kStatus_Success Successfully starts the data transmission. + * @retval kStatus_UART_TxBusy Previous transmission still not finished, data not written to the TX register. + */ +status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_t *xfer); + +/*! + * @brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt-driven data sending. Get the remainBytes to know + * how many bytes are still not sent out. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + */ +void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle); + +/*! + * @brief Gets the number of remaining bytes not sent. + * + * This function gets the number of remaining bytes not sent driven by interrupt. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param count Number of bytes sent so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count); + +/*! + * @brief Receives a buffer of data using the interrupt method. + * + * This function receives data using the interrupt method. This is a non-blocking function, + * which returns without waiting for all data to be received. + * If the RX ring buffer is used and not empty, the data in ring buffer is copied and + * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in ring buffer is not enough to read, the receive + * request is saved by the UART driver. When new data arrives, the receive request + * is serviced first. When all data is received, the UART driver notifies the upper layer + * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle. + * For example, if the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer, + * the 5 bytes are copied to xfer->data. This function returns with the + * parameter @p receivedBytes set to 5. For the last 5 bytes, newly arrived data is + * saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to xfer->data. When all data is received, the upper layer is notified. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param xfer UART transfer structure. See #flexio_uart_transfer_t. + * @param receivedBytes Bytes received from the ring buffer directly. + * @retval kStatus_Success Successfully queue the transfer into the transmit queue. + * @retval kStatus_FLEXIO_UART_RxBusy Previous receive request is not finished. + */ +status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base, + flexio_uart_handle_t *handle, + flexio_uart_transfer_t *xfer, + size_t *receivedBytes); + +/*! + * @brief Aborts the receive data which was using IRQ. + * + * This function aborts the receive data which was using IRQ. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + */ +void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle); + +/*! + * @brief Gets the number of remaining bytes not received. + * + * This function gets the number of remaining bytes not received driven by interrupt. + * + * @param base Pointer to the FLEXIO_UART_Type structure. + * @param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. + * @param count Number of bytes received so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count); + +/*! + * @brief FlexIO UART IRQ handler function. + * + * This function processes the FlexIO UART transmit and receives the IRQ request. + * + * @param uartType Pointer to the FLEXIO_UART_Type structure. + * @param uartHandle Pointer to the flexio_uart_handle_t structure to store the transfer state. + */ +void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /*_FSL_FLEXIO_UART_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart_dma.c new file mode 100644 index 0000000000..10a06fa593 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart_dma.c @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flexio_uart_dma.h" +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*base, false); + + /* Disable interrupt. */ + DMA_DisableInterrupts(handle->base, handle->channel); + + uartPrivateHandle->handle->txState = kFLEXIO_UART_TxIdle; + + if (uartPrivateHandle->handle->callback) + { + uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, + kStatus_FLEXIO_UART_TxIdle, uartPrivateHandle->handle->userData); + } +} + +static void FLEXIO_UART_TransferReceiveDMACallback(dma_handle_t *handle, void *param) +{ + flexio_uart_dma_private_handle_t *uartPrivateHandle = (flexio_uart_dma_private_handle_t *)param; + + /* Disable UART RX DMA. */ + FLEXIO_UART_EnableRxDMA(uartPrivateHandle->base, false); + + /* Disable interrupt. */ + DMA_DisableInterrupts(handle->base, handle->channel); + + uartPrivateHandle->handle->rxState = kFLEXIO_UART_RxIdle; + + if (uartPrivateHandle->handle->callback) + { + uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, + kStatus_FLEXIO_UART_RxIdle, uartPrivateHandle->handle->userData); + } +} + +status_t FLEXIO_UART_TransferCreateHandleDMA(FLEXIO_UART_Type *base, + flexio_uart_dma_handle_t *handle, + flexio_uart_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txDmaHandle, + dma_handle_t *rxDmaHandle) +{ + assert(handle); + + dma_transfer_config_t dmaXferConfig; + uint8_t index = 0; + + /* Find the an empty handle pointer to store the handle. */ + for (index = 0; index < FLEXIO_UART_HANDLE_COUNT; index++) + { + if (s_dmaPrivateHandle[index].base == NULL) + { + s_dmaPrivateHandle[index].base = base; + s_dmaPrivateHandle[index].handle = handle; + break; + } + } + + if (index == FLEXIO_UART_HANDLE_COUNT) + { + return kStatus_OutOfRange; + } + + memset(handle, 0, sizeof(*handle)); + + handle->rxState = kFLEXIO_UART_RxIdle; + handle->txState = kFLEXIO_UART_TxIdle; + + handle->callback = callback; + handle->userData = userData; + + handle->rxDmaHandle = rxDmaHandle; + handle->txDmaHandle = txDmaHandle; + + /* Set DMA channel configuration. */ + memset(&dmaXferConfig, 0, sizeof(dmaXferConfig)); + dmaXferConfig.srcSize = kDMA_Transfersize8bits; + dmaXferConfig.destSize = kDMA_Transfersize8bits; + + /* Configure TX. */ + if (txDmaHandle) + { + DMA_SetCallback(txDmaHandle, FLEXIO_UART_TransferSendDMACallback, &s_dmaPrivateHandle[index]); + + DMA_ResetChannel(txDmaHandle->base, txDmaHandle->channel); + + dmaXferConfig.destAddr = FLEXIO_UART_GetTxDataRegisterAddress(base); + dmaXferConfig.enableSrcIncrement = true; + dmaXferConfig.enableDestIncrement = false; + DMA_SetTransferConfig(txDmaHandle->base, txDmaHandle->channel, &dmaXferConfig); + } + + /* Configure RX. */ + if (rxDmaHandle) + { + DMA_SetCallback(rxDmaHandle, FLEXIO_UART_TransferReceiveDMACallback, &s_dmaPrivateHandle[index]); + + DMA_ResetChannel(rxDmaHandle->base, rxDmaHandle->channel); + + dmaXferConfig.destAddr = 0U; + dmaXferConfig.srcAddr = FLEXIO_UART_GetRxDataRegisterAddress(base); + dmaXferConfig.enableSrcIncrement = false; + dmaXferConfig.enableDestIncrement = true; + DMA_SetTransferConfig(rxDmaHandle->base, rxDmaHandle->channel, &dmaXferConfig); + } + + return kStatus_Success; +} + +status_t FLEXIO_UART_TransferSendDMA(FLEXIO_UART_Type *base, + flexio_uart_dma_handle_t *handle, + flexio_uart_transfer_t *xfer) +{ + assert(handle->txDmaHandle); + + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* If previous TX not finished. */ + if (kFLEXIO_UART_TxBusy == handle->txState) + { + status = kStatus_FLEXIO_UART_TxBusy; + } + else + { + handle->txState = kFLEXIO_UART_TxBusy; + + /* Set transfer data address and data size. */ + DMA_SetSourceAddress(handle->txDmaHandle->base, handle->txDmaHandle->channel, (uint32_t)xfer->data); + DMA_SetTransferSize(handle->txDmaHandle->base, handle->txDmaHandle->channel, xfer->dataSize); + + /* Enable FLEXIO UART TX DMA. */ + FLEXIO_UART_EnableTxDMA(base, true); + + /* Enable DMA transfer complete interrupt and start transfer. */ + DMA_EnableInterrupts(handle->txDmaHandle->base, handle->txDmaHandle->channel); + DMA_EnableChannelRequest(handle->txDmaHandle->base, handle->txDmaHandle->channel); + + status = kStatus_Success; + } + + return status; +} + +status_t FLEXIO_UART_TransferReceiveDMA(FLEXIO_UART_Type *base, + flexio_uart_dma_handle_t *handle, + flexio_uart_transfer_t *xfer) +{ + assert(handle->rxDmaHandle); + + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* If previous RX not finished. */ + if (kFLEXIO_UART_RxBusy == handle->rxState) + { + status = kStatus_FLEXIO_UART_RxBusy; + } + else + { + handle->rxState = kFLEXIO_UART_RxBusy; + + /* Set transfer data address and data size. */ + DMA_SetDestinationAddress(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, (uint32_t)xfer->data); + DMA_SetTransferSize(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, xfer->dataSize); + + /* Enable FLEXIO UART RX DMA. */ + FLEXIO_UART_EnableRxDMA(base, true); + + /* Enable DMA transfer complete interrupt and start transfer. */ + DMA_EnableInterrupts(handle->rxDmaHandle->base, handle->rxDmaHandle->channel); + DMA_EnableChannelRequest(handle->rxDmaHandle->base, handle->rxDmaHandle->channel); + + status = kStatus_Success; + } + + return status; +} + +void FLEXIO_UART_TransferAbortSendDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle) +{ + assert(handle->txDmaHandle); + + /* Disable FLEXIO UART TX DMA. */ + FLEXIO_UART_EnableTxDMA(base, false); + + /* Stop transfer. */ + DMA_StopTransfer(handle->txDmaHandle); + + /* Write DMA->DSR[DONE] to abort transfer and clear status. */ + DMA_ClearChannelStatusFlags(handle->txDmaHandle->base, handle->txDmaHandle->channel, kDMA_TransactionsDoneFlag); + + handle->txState = kFLEXIO_UART_TxIdle; +} + +void FLEXIO_UART_TransferAbortReceiveDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle) +{ + assert(handle->rxDmaHandle); + + /* Disable FLEXIO UART RX DMA. */ + FLEXIO_UART_EnableRxDMA(base, false); + + /* Stop transfer. */ + DMA_StopTransfer(handle->rxDmaHandle); + + /* Write DMA->DSR[DONE] to abort transfer and clear status. */ + DMA_ClearChannelStatusFlags(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, kDMA_TransactionsDoneFlag); + + handle->rxState = kFLEXIO_UART_RxIdle; +} + +status_t FLEXIO_UART_TransferGetSendCountDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle, size_t *count) +{ + assert(handle->txDmaHandle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + if (kFLEXIO_UART_TxBusy == handle->txState) + { + *count = (handle->txSize - DMA_GetRemainingBytes(handle->txDmaHandle->base, handle->txDmaHandle->channel)); + } + else + { + *count = handle->txSize; + } + + return kStatus_Success; +} + +status_t FLEXIO_UART_TransferGetReceiveCountDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle, size_t *count) +{ + assert(handle->rxDmaHandle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + if (kFLEXIO_UART_RxBusy == handle->rxState) + { + *count = (handle->rxSize - DMA_GetRemainingBytes(handle->rxDmaHandle->base, handle->rxDmaHandle->channel)); + } + else + { + *count = handle->rxSize; + } + + return kStatus_Success; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart_dma.h new file mode 100644 index 0000000000..e1defb6d05 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart_dma.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FLEXIO_UART_DMA_H_ +#define _FSL_FLEXIO_UART_DMA_H_ + +#include "fsl_flexio_uart.h" +#include "fsl_dmamux.h" +#include "fsl_dma.h" + +/*! + * @addtogroup flexio_dma_uart + * @{ + */ + +/*! @file*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Forward declaration of the handle typedef. */ +typedef struct _flexio_uart_dma_handle flexio_uart_dma_handle_t; + +/*! @brief UART transfer callback function. */ +typedef void (*flexio_uart_dma_transfer_callback_t)(FLEXIO_UART_Type *base, + flexio_uart_dma_handle_t *handle, + status_t status, + void *userData); + +/*! +* @brief UART DMA handle +*/ +struct _flexio_uart_dma_handle +{ + flexio_uart_dma_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< UART callback function parameter.*/ + + size_t txSize; /*!< Total bytes to be sent. */ + size_t rxSize; /*!< Total bytes to be received. */ + + dma_handle_t *txDmaHandle; /*!< The DMA TX channel used. */ + dma_handle_t *rxDmaHandle; /*!< The DMA RX channel used. */ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA transactional + * @{ + */ + +/*! + * @brief Initializes the FLEXIO_UART handle which is used in transactional functions + * + * @param base Pointer to FLEXIO_UART_Type structure. + * @param handle Pointer to flexio_uart_dma_handle_t structure. + * @param callback FlexIO UART callback, NULL means no callback. + * @param userData User callback function data. + * @param txDmaHandle User requested DMA handle for TX DMA transfer. + * @param rxDmaHandle User requested DMA handle for RX DMA transfer. + * @retval kStatus_Success Successfully create the handle. + * @retval kStatus_OutOfRange The FlexIO UART DMA type/handle table out of range. + */ +status_t FLEXIO_UART_TransferCreateHandleDMA(FLEXIO_UART_Type *base, + flexio_uart_dma_handle_t *handle, + flexio_uart_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txDmaHandle, + dma_handle_t *rxDmaHandle); + +/*! + * @brief Sends data using DMA. + * + * This function send data using DMA, this is non-blocking function, which return + * right away. When all data have been sent out, the send callback function is called. + * + * @param base Pointer to FLEXIO_UART_Type structure + * @param handle Pointer to flexio_uart_dma_handle_t structure + * @param xfer FLEXIO_UART DMA transfer structure, refer to #flexio_uart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_FLEXIO_UART_TxBusy Previous transfer on going. + */ +status_t FLEXIO_UART_TransferSendDMA(FLEXIO_UART_Type *base, + flexio_uart_dma_handle_t *handle, + flexio_uart_transfer_t *xfer); + +/*! + * @brief Receives data using DMA. + * + * This function receives data using DMA. This is non-blocking function, which returns + * right away. When all data have been received, the receive callback function is called. + * + * @param base Pointer to FLEXIO_UART_Type structure + * @param handle Pointer to flexio_uart_dma_handle_t structure + * @param xfer FLEXIO_UART DMA transfer sturcture, refer to #flexio_uart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_FLEXIO_UART_RxBusy Previous transfer on going. + */ +status_t FLEXIO_UART_TransferReceiveDMA(FLEXIO_UART_Type *base, + flexio_uart_dma_handle_t *handle, + flexio_uart_transfer_t *xfer); + +/*! + * @brief Aborts the sent data which using DMA. + * + * This function aborts the sent data which using DMA. + * + * @param base Pointer to FLEXIO_UART_Type structure + * @param handle Pointer to flexio_uart_dma_handle_t structure + */ +void FLEXIO_UART_TransferAbortSendDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle); + +/*! + * @brief Aborts the receive data which using DMA. + * + * This function aborts the receive data which using DMA. + * + * @param base Pointer to FLEXIO_UART_Type structure + * @param handle Pointer to flexio_uart_dma_handle_t structure + */ +void FLEXIO_UART_TransferAbortReceiveDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle); + +/*! + * @brief Gets the number of bytes still not sent out. + * + * This function gets the number of bytes still not sent out. + * + * @param base Pointer to FLEXIO_UART_Type structure + * @param handle Pointer to flexio_uart_dma_handle_t structure + * @param count Number of bytes sent so far by the non-blocking transaction. + */ +status_t FLEXIO_UART_TransferGetSendCountDMA(FLEXIO_UART_Type *base, flexio_uart_dma_handle_t *handle, size_t *count); + +/*! + * @brief Gets the number of bytes still not received. + * + * This function gets the number of bytes still not received. + * + * @param base Pointer to FLEXIO_UART_Type structure + * @param handle Pointer to flexio_uart_dma_handle_t structure + * @param count Number of bytes received so far by the non-blocking transaction. + */ +status_t FLEXIO_UART_TransferGetReceiveCountDMA(FLEXIO_UART_Type *base, + flexio_uart_dma_handle_t *handle, + size_t *count); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_UART_DMA_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_gpio.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_gpio.c new file mode 100644 index 0000000000..8fc068f2d6 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_gpio.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_gpio.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ +static PORT_Type *const s_portBases[] = PORT_BASE_PTRS; +static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS; + +/******************************************************************************* +* Prototypes +******************************************************************************/ + +/*! +* @brief Gets the GPIO instance according to the GPIO base +* +* @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.) +* @retval GPIO instance +*/ +static uint32_t GPIO_GetInstance(GPIO_Type *base); + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t GPIO_GetInstance(GPIO_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_GPIO_COUNT; instance++) + { + if (s_gpioBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_GPIO_COUNT); + + return instance; +} + +void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config) +{ + assert(config); + + if (config->pinDirection == kGPIO_DigitalInput) + { + base->PDDR &= ~(1U << pin); + } + else + { + GPIO_WritePinOutput(base, pin, config->outputLogic); + base->PDDR |= (1U << pin); + } +} + +uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base) +{ + uint8_t instance; + PORT_Type *portBase; + instance = GPIO_GetInstance(base); + portBase = s_portBases[instance]; + return portBase->ISFR; +} + +void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask) +{ + uint8_t instance; + PORT_Type *portBase; + instance = GPIO_GetInstance(base); + portBase = s_portBases[instance]; + portBase->ISFR = mask; +} + +#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT + +/******************************************************************************* + * Variables + ******************************************************************************/ +static FGPIO_Type *const s_fgpioBases[] = FGPIO_BASE_PTRS; + +/******************************************************************************* +* Prototypes +******************************************************************************/ +/*! +* @brief Gets the FGPIO instance according to the GPIO base +* +* @param base FGPIO peripheral base pointer(PTA, PTB, PTC, etc.) +* @retval FGPIO instance +*/ +static uint32_t FGPIO_GetInstance(FGPIO_Type *base); + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t FGPIO_GetInstance(FGPIO_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_FGPIO_COUNT; instance++) + { + if (s_fgpioBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_FGPIO_COUNT); + + return instance; +} + +void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config) +{ + assert(config); + + if (config->pinDirection == kGPIO_DigitalInput) + { + base->PDDR &= ~(1U << pin); + } + else + { + FGPIO_WritePinOutput(base, pin, config->outputLogic); + base->PDDR |= (1U << pin); + } +} + +uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base) +{ + uint8_t instance; + instance = FGPIO_GetInstance(base); + PORT_Type *portBase; + portBase = s_portBases[instance]; + return portBase->ISFR; +} + +void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask) +{ + uint8_t instance; + instance = FGPIO_GetInstance(base); + PORT_Type *portBase; + portBase = s_portBases[instance]; + portBase->ISFR = mask; +} + +#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_gpio.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_gpio.h new file mode 100644 index 0000000000..6eaaaa0874 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_gpio.h @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_GPIO_H_ +#define _FSL_GPIO_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup gpio + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief GPIO driver version 2.1.0. */ +#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief GPIO direction definition*/ +typedef enum _gpio_pin_direction +{ + kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/ + kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/ +} gpio_pin_direction_t; + +/*! + * @brief The GPIO pin configuration structure. + * + * Every pin can only be configured as either output pin or input pin at a time. + * If configured as a input pin, then leave the outputConfig unused + * Note : In some cases, the corresponding port property should be configured in advance + * with the PORT_SetPinConfig() + */ +typedef struct _gpio_pin_config +{ + gpio_pin_direction_t pinDirection; /*!< gpio direction, input or output */ + /* Output configurations, please ignore if configured as a input one */ + uint8_t outputLogic; /*!< Set default output logic, no use in input */ +} gpio_pin_config_t; + +/*! @} */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @addtogroup gpio_driver + * @{ + */ + +/*! @name GPIO Configuration */ +/*@{*/ + +/*! + * @brief Initializes a GPIO pin used by the board. + * + * To initialize the GPIO, define a pin configuration, either input or output, in the user file. + * Then, call the GPIO_PinInit() function. + * + * This is an example to define an input pin or output pin configuration: + * @code + * // Define a digital input pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalInput, + * 0, + * } + * //Define a digital output pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalOutput, + * 0, + * } + * @endcode + * + * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param pin GPIO port pin number + * @param config GPIO pin configuration pointer + */ +void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config); + +/*@}*/ + +/*! @name GPIO Output Operations */ +/*@{*/ + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0. + * + * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param pin GPIO pin's number + * @param output GPIO pin output logic level. + * - 0: corresponding pin output low logic level. + * - 1: corresponding pin output high logic level. + */ +static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output) +{ + if (output == 0U) + { + base->PCOR = 1 << pin; + } + else + { + base->PSOR = 1 << pin; + } +} + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 1. + * + * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pins' numbers macro + */ +static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask) +{ + base->PSOR = mask; +} + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 0. + * + * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pins' numbers macro + */ +static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask) +{ + base->PCOR = mask; +} + +/*! + * @brief Reverses current output logic of the multiple GPIO pins. + * + * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pins' numbers macro + */ +static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask) +{ + base->PTOR = mask; +} +/*@}*/ + +/*! @name GPIO Input Operations */ +/*@{*/ + +/*! + * @brief Reads the current input value of the whole GPIO port. + * + * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param pin GPIO pin's number + * @retval GPIO port input value + * - 0: corresponding pin input low logic level. + * - 1: corresponding pin input high logic level. + */ +static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin) +{ + return (((base->PDIR) >> pin) & 0x01U); +} +/*@}*/ + +/*! @name GPIO Interrupt */ +/*@{*/ + +/*! + * @brief Reads whole GPIO port interrupt status flag. + * + * If a pin is configured to generate the DMA request, the corresponding flag + * is cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic one is written to that flag. + * If configured for a level sensitive interrupt that remains asserted, the flag + * is set again immediately. + * + * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @retval Current GPIO port interrupt status flag, for example, 0x00010001 means the + * pin 0 and 17 have the interrupt. + */ +uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base); + +/*! + * @brief Clears multiple GPIO pins' interrupt status flag. + * + * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pins' numbers macro + */ +void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask); + +/*@}*/ +/*! @} */ + +/*! + * @addtogroup fgpio_driver + * @{ + */ + +/* + * Introduce the FGPIO feature. + * + * The FGPIO features are only support on some of Kinetis chips. The FGPIO registers are aliased to the IOPORT + * interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and will therefore + * complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO. + */ + +#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT + +/*! @name FGPIO Configuration */ +/*@{*/ + +/*! + * @brief Initializes a FGPIO pin used by the board. + * + * To initialize the FGPIO driver, define a pin configuration, either input or output, in the user file. + * Then, call the FGPIO_PinInit() function. + * + * This is an example to define an input pin or output pin configuration: + * @code + * // Define a digital input pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalInput, + * 0, + * } + * //Define a digital output pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalOutput, + * 0, + * } + * @endcode + * + * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param pin FGPIO port pin number + * @param config FGPIO pin configuration pointer + */ +void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config); + +/*@}*/ + +/*! @name FGPIO Output Operations */ +/*@{*/ + +/*! + * @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0. + * + * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param pin FGPIO pin's number + * @param output FGPIOpin output logic level. + * - 0: corresponding pin output low logic level. + * - 1: corresponding pin output high logic level. + */ +static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t output) +{ + if (output == 0U) + { + base->PCOR = 1 << pin; + } + else + { + base->PSOR = 1 << pin; + } +} + +/*! + * @brief Sets the output level of the multiple FGPIO pins to the logic 1. + * + * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param mask FGPIO pins' numbers macro + */ +static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask) +{ + base->PSOR = mask; +} + +/*! + * @brief Sets the output level of the multiple FGPIO pins to the logic 0. + * + * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param mask FGPIO pins' numbers macro + */ +static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask) +{ + base->PCOR = mask; +} + +/*! + * @brief Reverses current output logic of the multiple FGPIO pins. + * + * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param mask FGPIO pins' numbers macro + */ +static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask) +{ + base->PTOR = mask; +} +/*@}*/ + +/*! @name FGPIO Input Operations */ +/*@{*/ + +/*! + * @brief Reads the current input value of the whole FGPIO port. + * + * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param pin FGPIO pin's number + * @retval FGPIO port input value + * - 0: corresponding pin input low logic level. + * - 1: corresponding pin input high logic level. + */ +static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin) +{ + return (((base->PDIR) >> pin) & 0x01U); +} +/*@}*/ + +/*! @name FGPIO Interrupt */ +/*@{*/ + +/*! + * @brief Reads the whole FGPIO port interrupt status flag. + * + * If a pin is configured to generate the DMA request, the corresponding flag + * is cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic one is written to that flag. + * If configured for a level sensitive interrupt that remains asserted, the flag + * is set again immediately. + * + * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @retval Current FGPIO port interrupt status flags, for example, 0x00010001 means the + * pin 0 and 17 have the interrupt. + */ +uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base); + +/*! + * @brief Clears the multiple FGPIO pins' interrupt status flag. + * + * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param mask FGPIO pins' numbers macro + */ +void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask); + +/*@}*/ + +#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ + +#endif /* _FSL_GPIO_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c.c new file mode 100644 index 0000000000..e77a383239 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c.c @@ -0,0 +1,1536 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_i2c.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief i2c transfer state. */ +enum _i2c_transfer_states +{ + kIdleState = 0x0U, /*!< I2C bus idle. */ + kCheckAddressState = 0x1U, /*!< 7-bit address check state. */ + kSendCommandState = 0x2U, /*!< Send command byte phase. */ + kSendDataState = 0x3U, /*!< Send data transfer phase. */ + kReceiveDataBeginState = 0x4U, /*!< Receive data transfer phase begin. */ + kReceiveDataState = 0x5U, /*!< Receive data transfer phase. */ +}; + +/*! @brief Common sets of flags used by the driver. */ +enum _i2c_flag_constants +{ +/*! All flags which are cleared by the driver upon starting a transfer. */ +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag, + kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StartStopDetectInterruptEnable, +#elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag, + kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StopDetectInterruptEnable, +#else + kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag, + kIrqFlags = kI2C_GlobalInterruptEnable, +#endif + +}; + +/*! @brief Typedef for interrupt handler. */ +typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for I2C module. + * + * @param base I2C peripheral base address. + */ +uint32_t I2C_GetInstance(I2C_Type *base); + +/*! + * @brief Set up master transfer, send slave address and decide the initial + * transfer state. + * + * @param base I2C peripheral base address. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. + * @param xfer pointer to i2c_master_transfer_t structure. + */ +static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer); + +/*! + * @brief Check and clear status operation. + * + * @param base I2C peripheral base address. + * @param status current i2c hardware status. + * @retval kStatus_Success No error found. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStatus_I2C_Nak Received Nak error. + */ +static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status); + +/*! + * @brief Master run transfer state machine to perform a byte of transfer. + * + * @param base I2C peripheral base address. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state + * @param isDone input param to get whether the thing is done, true is done + * @retval kStatus_Success No error found. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStatus_I2C_Nak Received Nak error. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + */ +static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone); + +/*! + * @brief I2C common interrupt handler. + * + * @param base I2C peripheral base address. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state + */ +static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to i2c handles for each instance. */ +static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL}; + +/*! @brief SCL clock divider used to calculate baudrate. */ +const uint16_t s_i2cDividerTable[] = {20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, + 48, 56, 68, 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, + 112, 128, 144, 160, 192, 240, 160, 192, 224, 256, 288, 320, 384, + 480, 320, 384, 448, 512, 576, 640, 768, 960, 640, 768, 896, 1024, + 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840}; + +/*! @brief Pointers to i2c bases for each instance. */ +static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS; + +/*! @brief Pointers to i2c IRQ number for each instance. */ +const IRQn_Type s_i2cIrqs[] = I2C_IRQS; + +/*! @brief Pointers to i2c clocks for each instance. */ +const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS; + +/*! @brief Pointer to master IRQ handler for each instance. */ +static i2c_isr_t s_i2cMasterIsr; + +/*! @brief Pointer to slave IRQ handler for each instance. */ +static i2c_isr_t s_i2cSlaveIsr; + +/******************************************************************************* + * Codes + ******************************************************************************/ + +uint32_t I2C_GetInstance(I2C_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_I2C_COUNT; instance++) + { + if (s_i2cBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_I2C_COUNT); + + return instance; +} + +static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer) +{ + status_t result = kStatus_Success; + i2c_direction_t direction = xfer->direction; + uint16_t timeout = UINT16_MAX; + + /* Initialize the handle transfer information. */ + handle->transfer = *xfer; + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + /* Initial transfer state. */ + if (handle->transfer.subaddressSize > 0) + { + handle->state = kSendCommandState; + if (xfer->direction == kI2C_Read) + { + direction = kI2C_Write; + } + } + else + { + handle->state = kCheckAddressState; + } + + /* Wait until the data register is ready for transmit. */ + while ((!(base->S & kI2C_TransferCompleteFlag)) && (--timeout)) + { + } + + /* Failed to start the transfer. */ + if (timeout == 0) + { + return kStatus_I2C_Timeout; + } + + /* Clear all status before transfer. */ + I2C_MasterClearStatusFlags(base, kClearFlags); + + /* If repeated start is requested, send repeated start. */ + if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag) + { + result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction); + } + else /* For normal transfer, send start. */ + { + result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction); + } + + return result; +} + +static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status) +{ + status_t result = kStatus_Success; + + /* Check arbitration lost. */ + if (status & kI2C_ArbitrationLostFlag) + { + /* Clear arbitration lost flag. */ + base->S = kI2C_ArbitrationLostFlag; + result = kStatus_I2C_ArbitrationLost; + } + /* Check NAK */ + else if (status & kI2C_ReceiveNakFlag) + { + result = kStatus_I2C_Nak; + } + else + { + } + + return result; +} + +static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone) +{ + status_t result = kStatus_Success; + uint32_t statusFlags = base->S; + *isDone = false; + volatile uint8_t dummy = 0; + bool ignoreNak = ((handle->state == kSendDataState) && (handle->transfer.dataSize == 0U)) || + ((handle->state == kReceiveDataState) && (handle->transfer.dataSize == 1U)); + + /* Add this to avoid build warning. */ + dummy++; + + /* Check & clear error flags. */ + result = I2C_CheckAndClearError(base, statusFlags); + + /* Ignore Nak when it's appeared for last byte. */ + if ((result == kStatus_I2C_Nak) && ignoreNak) + { + result = kStatus_Success; + } + + if (result) + { + return result; + } + + /* Handle Check address state to check the slave address is Acked in slave + probe application. */ + if (handle->state == kCheckAddressState) + { + if (statusFlags & kI2C_ReceiveNakFlag) + { + return kStatus_I2C_Nak; + } + else + { + if (handle->transfer.direction == kI2C_Write) + { + /* Next state, send data. */ + handle->state = kSendDataState; + } + else + { + /* Next state, receive data begin. */ + handle->state = kReceiveDataBeginState; + } + } + } + + /* Run state machine. */ + switch (handle->state) + { + /* Send I2C command. */ + case kSendCommandState: + if (handle->transfer.subaddressSize) + { + handle->transfer.subaddressSize--; + base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)); + } + else + { + if (handle->transfer.direction == kI2C_Write) + { + /* Next state, send data. */ + handle->state = kSendDataState; + + /* Send first byte of data. */ + if (handle->transfer.dataSize > 0) + { + base->D = *handle->transfer.data; + handle->transfer.data++; + handle->transfer.dataSize--; + } + } + else + { + /* Send repeated start and slave address. */ + result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read); + + /* Next state, receive data begin. */ + handle->state = kReceiveDataBeginState; + } + } + break; + + /* Send I2C data. */ + case kSendDataState: + /* Send one byte of data. */ + if (handle->transfer.dataSize > 0) + { + base->D = *handle->transfer.data; + handle->transfer.data++; + handle->transfer.dataSize--; + } + else + { + *isDone = true; + } + break; + + /* Start I2C data receive. */ + case kReceiveDataBeginState: + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Send nak at the last receive byte. */ + if (handle->transfer.dataSize == 1) + { + base->C1 |= I2C_C1_TXAK_MASK; + } + + /* Read dummy to release the bus. */ + dummy = base->D; + + /* Next state, receive data. */ + handle->state = kReceiveDataState; + break; + + /* Receive I2C data. */ + case kReceiveDataState: + /* Receive one byte of data. */ + if (handle->transfer.dataSize--) + { + if (handle->transfer.dataSize == 0) + { + *isDone = true; + + /* Send stop if kI2C_TransferNoStop is not asserted. */ + if (!(handle->transfer.flags & kI2C_TransferNoStopFlag)) + { + result = I2C_MasterStop(base); + } + } + + /* Send NAK at the last receive byte. */ + if (handle->transfer.dataSize == 1) + { + base->C1 |= I2C_C1_TXAK_MASK; + } + + /* Read the data byte into the transfer buffer. */ + *handle->transfer.data = base->D; + handle->transfer.data++; + } + break; + + default: + break; + } + + return result; +} + +static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle) +{ + /* Check if master interrupt. */ + if ((base->S & kI2C_ArbitrationLostFlag) || (base->C1 & I2C_C1_MST_MASK)) + { + s_i2cMasterIsr(base, handle); + } + else + { + s_i2cSlaveIsr(base, handle); + } +} + +void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz) +{ + assert(masterConfig && srcClock_Hz); + + /* Temporary register for filter read. */ + uint8_t fltReg; +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + uint8_t c2Reg; +#endif + + /* Enable I2C clock. */ + CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); + + /* Disable I2C prior to configuring it. */ + base->C1 &= ~(I2C_C1_IICEN_MASK); + + /* Clear all flags. */ + I2C_MasterClearStatusFlags(base, kClearFlags); + + /* Configure baud rate. */ + I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz); + +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + /* Configure high drive feature. */ + c2Reg = base->C2; + c2Reg &= ~(I2C_C2_HDRS_MASK); + c2Reg |= I2C_C2_HDRS(masterConfig->enableHighDrive); + base->C2 = c2Reg; +#endif + + /* Read out the FLT register. */ + fltReg = base->FLT; + +#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF + /* Configure the stop / hold enable. */ + fltReg &= ~(I2C_FLT_SHEN_MASK); + fltReg |= I2C_FLT_SHEN(masterConfig->enableStopHold); +#endif + + /* Configure the glitch filter value. */ + fltReg &= ~(I2C_FLT_FLT_MASK); + fltReg |= I2C_FLT_FLT(masterConfig->glitchFilterWidth); + + /* Write the register value back to the filter register. */ + base->FLT = fltReg; + + /* Enable the I2C peripheral based on the configuration. */ + base->C1 = I2C_C1_IICEN(masterConfig->enableMaster); +} + +void I2C_MasterDeinit(I2C_Type *base) +{ + /* Disable I2C module. */ + I2C_Enable(base, false); + + /* Disable I2C clock. */ + CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); +} + +void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig) +{ + assert(masterConfig); + + /* Default baud rate at 100kbps. */ + masterConfig->baudRate_Bps = 100000U; + +/* Default pin high drive is disabled. */ +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + masterConfig->enableHighDrive = false; +#endif + +/* Default stop hold enable is disabled. */ +#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF + masterConfig->enableStopHold = false; +#endif + + /* Default glitch filter value is no filter. */ + masterConfig->glitchFilterWidth = 0U; + + /* Enable the I2C peripheral. */ + masterConfig->enableMaster = true; +} + +void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask) +{ + if (mask & kI2C_GlobalInterruptEnable) + { + base->C1 |= I2C_C1_IICIE_MASK; + } + +#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + if (mask & kI2C_StopDetectInterruptEnable) + { + base->FLT |= I2C_FLT_STOPIE_MASK; + } +#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + if (mask & kI2C_StartStopDetectInterruptEnable) + { + base->FLT |= I2C_FLT_SSIE_MASK; + } +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ +} + +void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask) +{ + if (mask & kI2C_GlobalInterruptEnable) + { + base->C1 &= ~I2C_C1_IICIE_MASK; + } + +#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + if (mask & kI2C_StopDetectInterruptEnable) + { + base->FLT &= ~I2C_FLT_STOPIE_MASK; + } +#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + if (mask & kI2C_StartStopDetectInterruptEnable) + { + base->FLT &= ~I2C_FLT_SSIE_MASK; + } +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ +} + +void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + uint32_t multiplier; + uint32_t computedRate; + uint32_t absError; + uint32_t bestError = UINT32_MAX; + uint32_t bestMult = 0u; + uint32_t bestIcr = 0u; + uint8_t mult; + uint8_t i; + + /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register, + * and ranges from 0-2. It selects the multiplier factor for the divider. */ + for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult) + { + multiplier = 1u << mult; + + /* Scan table to find best match. */ + for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(uint16_t); ++i) + { + computedRate = srcClock_Hz / (multiplier * s_i2cDividerTable[i]); + absError = baudRate_Bps > computedRate ? (baudRate_Bps - computedRate) : (computedRate - baudRate_Bps); + + if (absError < bestError) + { + bestMult = mult; + bestIcr = i; + bestError = absError; + + /* If the error is 0, then we can stop searching because we won't find a better match. */ + if (absError == 0) + { + break; + } + } + } + } + + /* Set frequency register based on best settings. */ + base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr); +} + +status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction) +{ + status_t result = kStatus_Success; + uint32_t statusFlags = I2C_MasterGetStatusFlags(base); + + /* Return an error if the bus is already in use. */ + if (statusFlags & kI2C_BusBusyFlag) + { + result = kStatus_I2C_Busy; + } + else + { + /* Send the START signal. */ + base->C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK; + +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING + while (!(base->S2 & I2C_S2_EMPTY_MASK)) + { + } +#endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */ + + base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U)); + } + + return result; +} + +status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction) +{ + status_t result = kStatus_Success; + uint8_t savedMult; + uint32_t statusFlags = I2C_MasterGetStatusFlags(base); + uint8_t timeDelay = 6; + + /* Return an error if the bus is already in use, but not by us. */ + if ((statusFlags & kI2C_BusBusyFlag) && ((base->C1 & I2C_C1_MST_MASK) == 0)) + { + result = kStatus_I2C_Busy; + } + else + { + savedMult = base->F; + base->F = savedMult & (~I2C_F_MULT_MASK); + + /* We are already in a transfer, so send a repeated start. */ + base->C1 |= I2C_C1_RSTA_MASK; + + /* Restore the multiplier factor. */ + base->F = savedMult; + + /* Add some delay to wait the Re-Start signal. */ + while (timeDelay--) + { + __NOP(); + } + +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING + while (!(base->S2 & I2C_S2_EMPTY_MASK)) + { + } +#endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */ + + base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U)); + } + + return result; +} + +status_t I2C_MasterStop(I2C_Type *base) +{ + status_t result = kStatus_Success; + uint16_t timeout = UINT16_MAX; + + /* Issue the STOP command on the bus. */ + base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Wait until data transfer complete. */ + while ((base->S & kI2C_BusBusyFlag) && (--timeout)) + { + } + + if (timeout == 0) + { + result = kStatus_I2C_Timeout; + } + + return result; +} + +uint32_t I2C_MasterGetStatusFlags(I2C_Type *base) +{ + uint32_t statusFlags = base->S; + +#ifdef I2C_HAS_STOP_DETECT + /* Look up the STOPF bit from the filter register. */ + if (base->FLT & I2C_FLT_STOPF_MASK) + { + statusFlags |= kI2C_StopDetectFlag; + } +#endif + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Look up the STARTF bit from the filter register. */ + if (base->FLT & I2C_FLT_STARTF_MASK) + { + statusFlags |= kI2C_StartDetectFlag; + } +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ + + return statusFlags; +} + +status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize) +{ + status_t result = kStatus_Success; + uint8_t statusFlags = 0; + + /* Wait until the data register is ready for transmit. */ + while (!(base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Setup the I2C peripheral to transmit data. */ + base->C1 |= I2C_C1_TX_MASK; + + while (txSize--) + { + /* Send a byte of data. */ + base->D = *txBuff++; + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + statusFlags = base->S; + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check if arbitration lost or no acknowledgement (NAK), return failure status. */ + if (statusFlags & kI2C_ArbitrationLostFlag) + { + base->S = kI2C_ArbitrationLostFlag; + result = kStatus_I2C_ArbitrationLost; + } + + if (statusFlags & kI2C_ReceiveNakFlag) + { + base->S = kI2C_ReceiveNakFlag; + result = kStatus_I2C_Nak; + } + + if (result != kStatus_Success) + { + /* Breaking out of the send loop. */ + break; + } + } + + return result; +} + +status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) +{ + status_t result = kStatus_Success; + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + + /* Wait until the data register is ready for transmit. */ + while (!(base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Setup the I2C peripheral to receive data. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* If rxSize equals 1, configure to send NAK. */ + if (rxSize == 1) + { + /* Issue NACK on read. */ + base->C1 |= I2C_C1_TXAK_MASK; + } + + /* Do dummy read. */ + dummy = base->D; + + while ((rxSize--)) + { + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Single byte use case. */ + if (rxSize == 0) + { + /* Read the final byte. */ + result = I2C_MasterStop(base); + } + + if (rxSize == 1) + { + /* Issue NACK on read. */ + base->C1 |= I2C_C1_TXAK_MASK; + } + + /* Read from the data register. */ + *rxBuff++ = base->D; + } + + return result; +} + +status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer) +{ + assert(xfer); + + i2c_direction_t direction = xfer->direction; + status_t result = kStatus_Success; + + /* Clear all status before transfer. */ + I2C_MasterClearStatusFlags(base, kClearFlags); + + /* Wait until ready to complete. */ + while (!(base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Change to send write address when it's a read operation with command. */ + if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read)) + { + direction = kI2C_Write; + } + + /* If repeated start is requested, send repeated start. */ + if (xfer->flags & kI2C_TransferRepeatedStartFlag) + { + result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, direction); + } + else /* For normal transfer, send start. */ + { + result = I2C_MasterStart(base, xfer->slaveAddress, direction); + } + + /* Return if error. */ + if (result) + { + return result; + } + + /* Send subaddress. */ + if (xfer->subaddressSize) + { + do + { + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear interrupt pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + if (result == kStatus_I2C_Nak) + { + I2C_MasterStop(base); + } + + return result; + } + + xfer->subaddressSize--; + base->D = ((xfer->subaddress) >> (8 * xfer->subaddressSize)); + + } while ((xfer->subaddressSize > 0) && (result == kStatus_Success)); + + if (xfer->direction == kI2C_Read) + { + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + if (result == kStatus_I2C_Nak) + { + I2C_MasterStop(base); + } + + return result; + } + + /* Send repeated start and slave address. */ + result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read); + + /* Return if error. */ + if (result) + { + return result; + } + } + } + + /* Wait until address + command transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + /* Return if error. */ + if (result) + { + if (result == kStatus_I2C_Nak) + { + I2C_MasterStop(base); + } + + return result; + } + + /* Transmit data. */ + if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0)) + { + /* Send Data. */ + result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize); + + if (((result == kStatus_Success) && (!(xfer->flags & kI2C_TransferNoStopFlag))) || (result == kStatus_I2C_Nak)) + { + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send stop. */ + result = I2C_MasterStop(base); + } + } + + /* Receive Data. */ + if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0)) + { + result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize); + } + + return result; +} + +void I2C_MasterTransferCreateHandle(I2C_Type *base, + i2c_master_handle_t *handle, + i2c_master_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + uint32_t instance = I2C_GetInstance(base); + + /* Zero handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set callback and userData. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + s_i2cHandle[instance] = handle; + + /* Save master interrupt handler. */ + s_i2cMasterIsr = I2C_MasterTransferHandleIRQ; + + /* Enable NVIC interrupt. */ + EnableIRQ(s_i2cIrqs[instance]); +} + +status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + status_t result = kStatus_Success; + + /* Check if the I2C bus is idle - if not return busy status. */ + if (handle->state != kIdleState) + { + result = kStatus_I2C_Busy; + } + else + { + /* Start up the master transfer state machine. */ + result = I2C_InitTransferStateMachine(base, handle, xfer); + + if (result == kStatus_Success) + { + /* Enable the I2C interrupts. */ + I2C_EnableInterrupts(base, kI2C_GlobalInterruptEnable); + } + } + + return result; +} + +void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle) +{ + assert(handle); + + /* Disable interrupt. */ + I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable); + + /* Reset the state to idle. */ + handle->state = kIdleState; +} + +status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->transferSize - handle->transfer.dataSize; + + return kStatus_Success; +} + +void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle) +{ + assert(i2cHandle); + + i2c_master_handle_t *handle = (i2c_master_handle_t *)i2cHandle; + status_t result = kStatus_Success; + bool isDone; + + /* Clear the interrupt flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check transfer complete flag. */ + result = I2C_MasterTransferRunStateMachine(base, handle, &isDone); + + if (isDone || result) + { + /* Send stop command if transfer done or received Nak. */ + if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak)) + { + /* Ensure stop command is a need. */ + if ((base->C1 & I2C_C1_MST_MASK)) + { + if (I2C_MasterStop(base) != kStatus_Success) + { + result = kStatus_I2C_Timeout; + } + } + } + + /* Restore handle to idle state. */ + handle->state = kIdleState; + + /* Disable interrupt. */ + I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable); + + /* Call the callback function after the function has completed. */ + if (handle->completionCallback) + { + handle->completionCallback(base, handle, result, handle->userData); + } + } +} + +void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig) +{ + assert(slaveConfig); + + uint8_t tmpReg; + + CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); + + /* Configure addressing mode. */ + switch (slaveConfig->addressingMode) + { + case kI2C_Address7bit: + base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U; + break; + + case kI2C_RangeMatch: + assert(slaveConfig->slaveAddress < slaveConfig->upperAddress); + base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U; + base->RA = ((uint32_t)(slaveConfig->upperAddress)) << 1U; + base->C2 |= I2C_C2_RMEN_MASK; + break; + + default: + break; + } + + /* Configure low power wake up feature. */ + tmpReg = base->C1; + tmpReg &= ~I2C_C1_WUEN_MASK; + base->C1 = tmpReg | I2C_C1_WUEN(slaveConfig->enableWakeUp) | I2C_C1_IICEN(slaveConfig->enableSlave); + + /* Configure general call & baud rate control & high drive feature. */ + tmpReg = base->C2; + tmpReg &= ~(I2C_C2_SBRC_MASK | I2C_C2_GCAEN_MASK); + tmpReg |= I2C_C2_SBRC(slaveConfig->enableBaudRateCtl) | I2C_C2_GCAEN(slaveConfig->enableGeneralCall); +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + tmpReg &= ~I2C_C2_HDRS_MASK; + tmpReg |= I2C_C2_HDRS(slaveConfig->enableHighDrive); +#endif + base->C2 = tmpReg; +} + +void I2C_SlaveDeinit(I2C_Type *base) +{ + /* Disable I2C module. */ + I2C_Enable(base, false); + + /* Disable I2C clock. */ + CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); +} + +void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig) +{ + assert(slaveConfig); + + /* By default slave is addressed with 7-bit address. */ + slaveConfig->addressingMode = kI2C_Address7bit; + + /* General call mode is disabled by default. */ + slaveConfig->enableGeneralCall = false; + + /* Slave address match waking up MCU from low power mode is disabled. */ + slaveConfig->enableWakeUp = false; + +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + /* Default pin high drive is disabled. */ + slaveConfig->enableHighDrive = false; +#endif + + /* Independent slave mode baud rate at maximum frequency is disabled. */ + slaveConfig->enableBaudRateCtl = false; + + /* Enable the I2C peripheral. */ + slaveConfig->enableSlave = true; +} + +status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize) +{ + return I2C_MasterWriteBlocking(base, txBuff, txSize); +} + +void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) +{ + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Wait until the data register is ready for receive. */ + while (!(base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Setup the I2C peripheral to receive data. */ + base->C1 &= ~(I2C_C1_TX_MASK); + + while (rxSize--) + { + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Read from the data register. */ + *rxBuff++ = base->D; + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + } +} + +void I2C_SlaveTransferCreateHandle(I2C_Type *base, + i2c_slave_handle_t *handle, + i2c_slave_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + uint32_t instance = I2C_GetInstance(base); + + /* Zero handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set callback and userData. */ + handle->callback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + s_i2cHandle[instance] = handle; + + /* Save slave interrupt handler. */ + s_i2cSlaveIsr = I2C_SlaveTransferHandleIRQ; + + /* Enable NVIC interrupt. */ + EnableIRQ(s_i2cIrqs[instance]); +} + +status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask) +{ + assert(handle); + + /* Check if the I2C bus is idle - if not return busy status. */ + if (handle->isBusy) + { + return kStatus_I2C_Busy; + } + else + { + /* Disable LPI2C IRQ sources while we configure stuff. */ + I2C_DisableInterrupts(base, kIrqFlags); + + /* Clear transfer in handle. */ + memset(&handle->transfer, 0, sizeof(handle->transfer)); + + /* Record that we're busy. */ + handle->isBusy = true; + + /* Set up event mask. tx and rx are always enabled. */ + handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent; + + /* Clear all flags. */ + I2C_SlaveClearStatusFlags(base, kClearFlags); + + /* Enable I2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */ + I2C_EnableInterrupts(base, kIrqFlags); + } + + return kStatus_Success; +} + +void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle) +{ + assert(handle); + + if (handle->isBusy) + { + /* Disable interrupts. */ + I2C_DisableInterrupts(base, kIrqFlags); + + /* Reset transfer info. */ + memset(&handle->transfer, 0, sizeof(handle->transfer)); + + /* Reset the state to idle. */ + handle->isBusy = false; + } +} + +status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (!handle->isBusy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + /* For an active transfer, just return the count from the handle. */ + *count = handle->transfer.transferredCount; + + return kStatus_Success; +} + +void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) +{ + assert(i2cHandle); + + uint16_t status; + bool doTransmit = false; + i2c_slave_handle_t *handle = (i2c_slave_handle_t *)i2cHandle; + i2c_slave_transfer_t *xfer; + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + + status = I2C_SlaveGetStatusFlags(base); + xfer = &(handle->transfer); + +#ifdef I2C_HAS_STOP_DETECT + /* Check stop flag. */ + if (status & kI2C_StopDetectFlag) + { + I2C_MasterClearStatusFlags(base, kI2C_StopDetectFlag); + + /* Clear the interrupt flag. */ + base->S = kI2C_IntPendingFlag; + + /* Call slave callback if this is the STOP of the transfer. */ + if (handle->isBusy) + { + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_Success; + handle->isBusy = false; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + } + + return; + } +#endif /* I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Check start flag. */ + if (status & kI2C_StartDetectFlag) + { + I2C_MasterClearStatusFlags(base, kI2C_StartDetectFlag); + + /* Clear the interrupt flag. */ + base->S = kI2C_IntPendingFlag; + + xfer->event = kI2C_SlaveRepeatedStartEvent; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + + if (!(status & kI2C_AddressMatchFlag)) + { + return; + } + } +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ + + /* Clear the interrupt flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check NAK */ + if (status & kI2C_ReceiveNakFlag) + { + /* Set receive mode. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Read dummy. */ + dummy = base->D; + + if (handle->transfer.dataSize != 0) + { + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_I2C_Nak; + handle->isBusy = false; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + } + else + { +#ifndef I2C_HAS_STOP_DETECT + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_Success; + handle->isBusy = false; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } +#endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */ + } + } + /* Check address match. */ + else if (status & kI2C_AddressMatchFlag) + { + handle->isBusy = true; + xfer->event = kI2C_SlaveAddressMatchEvent; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + + /* Slave transmit, master reading from slave. */ + if (status & kI2C_TransferDirectionFlag) + { + /* Change direction to send data. */ + base->C1 |= I2C_C1_TX_MASK; + + /* If we're out of data, invoke callback to get more. */ + if ((!xfer->data) || (!xfer->dataSize)) + { + xfer->event = kI2C_SlaveTransmitEvent; + + if (handle->callback) + { + handle->callback(base, xfer, handle->userData); + } + + /* Clear the transferred count now that we have a new buffer. */ + xfer->transferredCount = 0; + } + + doTransmit = true; + } + else + { + /* Slave receive, master writing to slave. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* If we're out of data, invoke callback to get more. */ + if ((!xfer->data) || (!xfer->dataSize)) + { + xfer->event = kI2C_SlaveReceiveEvent; + + if (handle->callback) + { + handle->callback(base, xfer, handle->userData); + } + + /* Clear the transferred count now that we have a new buffer. */ + xfer->transferredCount = 0; + } + + /* Read dummy to release the bus. */ + dummy = base->D; + } + } + /* Check transfer complete flag. */ + else if (status & kI2C_TransferCompleteFlag) + { + /* Slave transmit, master reading from slave. */ + if (status & kI2C_TransferDirectionFlag) + { + doTransmit = true; + } + else + { + /* Slave receive, master writing to slave. */ + uint8_t data = base->D; + + if (handle->transfer.dataSize) + { + /* Receive data. */ + *handle->transfer.data++ = data; + handle->transfer.dataSize--; + xfer->transferredCount++; + if (!handle->transfer.dataSize) + { +#ifndef I2C_HAS_STOP_DETECT + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_Success; + handle->isBusy = false; + + /* Proceed receive complete event. */ + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } +#endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */ + } + } + } + } + else + { + /* Read dummy to release bus. */ + dummy = base->D; + } + + /* Send data if there is the need. */ + if (doTransmit) + { + if (handle->transfer.dataSize) + { + /* Send data. */ + base->D = *handle->transfer.data++; + handle->transfer.dataSize--; + xfer->transferredCount++; + } + else + { + /* Switch to receive mode. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Read dummy to release bus. */ + dummy = base->D; + +#ifndef I2C_HAS_STOP_DETECT + xfer->event = kI2C_SlaveCompletionEvent; + xfer->completionStatus = kStatus_Success; + handle->isBusy = false; + + /* Proceed txdone event. */ + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } +#endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */ + } + } +} + +void I2C0_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C0, s_i2cHandle[0]); +} + +#if (FSL_FEATURE_SOC_I2C_COUNT > 1) +void I2C1_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]); +} +#endif /* I2C COUNT > 1 */ + +#if (FSL_FEATURE_SOC_I2C_COUNT > 2) +void I2C2_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]); +} +#endif /* I2C COUNT > 2 */ +#if (FSL_FEATURE_SOC_I2C_COUNT > 3) +void I2C3_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C3, s_i2cHandle[3]); +} +#endif /* I2C COUNT > 3 */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c.h new file mode 100644 index 0000000000..41a9afbdd5 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c.h @@ -0,0 +1,781 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_I2C_H_ +#define _FSL_I2C_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup i2c_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief I2C driver version 2.0.0. */ +#define FSL_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +#if (defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT || \ + defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT) +#define I2C_HAS_STOP_DETECT +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT / FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +/*! @brief I2C status return codes. */ +enum _i2c_status +{ + kStatus_I2C_Busy = MAKE_STATUS(kStatusGroup_I2C, 0), /*!< I2C is busy with current transfer. */ + kStatus_I2C_Idle = MAKE_STATUS(kStatusGroup_I2C, 1), /*!< Bus is Idle. */ + kStatus_I2C_Nak = MAKE_STATUS(kStatusGroup_I2C, 2), /*!< NAK received during transfer. */ + kStatus_I2C_ArbitrationLost = MAKE_STATUS(kStatusGroup_I2C, 3), /*!< Arbitration lost during transfer. */ + kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_I2C, 4), /*!< Wait event timeout. */ +}; + +/*! + * @brief I2C peripheral flags + * + * The following status register flags can be cleared: + * - #kI2C_ArbitrationLostFlag + * - #kI2C_IntPendingFlag + * - #kI2C_StartDetectFlag + * - #kI2C_StopDetectFlag + * + * @note These enumerations are meant to be OR'd together to form a bit mask. + * + */ +enum _i2c_flags +{ + kI2C_ReceiveNakFlag = I2C_S_RXAK_MASK, /*!< I2C receive NAK flag. */ + kI2C_IntPendingFlag = I2C_S_IICIF_MASK, /*!< I2C interrupt pending flag. */ + kI2C_TransferDirectionFlag = I2C_S_SRW_MASK, /*!< I2C transfer direction flag. */ + kI2C_RangeAddressMatchFlag = I2C_S_RAM_MASK, /*!< I2C range address match flag. */ + kI2C_ArbitrationLostFlag = I2C_S_ARBL_MASK, /*!< I2C arbitration lost flag. */ + kI2C_BusBusyFlag = I2C_S_BUSY_MASK, /*!< I2C bus busy flag. */ + kI2C_AddressMatchFlag = I2C_S_IAAS_MASK, /*!< I2C address match flag. */ + kI2C_TransferCompleteFlag = I2C_S_TCF_MASK, /*!< I2C transfer complete flag. */ +#ifdef I2C_HAS_STOP_DETECT + kI2C_StopDetectFlag = I2C_FLT_STOPF_MASK << 8, /*!< I2C stop detect flag. */ +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT / FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2C_StartDetectFlag = I2C_FLT_STARTF_MASK << 8, /*!< I2C start detect flag. */ +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ +}; + +/*! @brief I2C feature interrupt source. */ +enum _i2c_interrupt_enable +{ + kI2C_GlobalInterruptEnable = I2C_C1_IICIE_MASK, /*!< I2C global interrupt. */ + +#if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + kI2C_StopDetectInterruptEnable = I2C_FLT_STOPIE_MASK, /*!< I2C stop detect interrupt. */ +#endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2C_StartStopDetectInterruptEnable = I2C_FLT_SSIE_MASK, /*!< I2C start&stop detect interrupt. */ +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ +}; + +/*! @brief Direction of master and slave transfers. */ +typedef enum _i2c_direction +{ + kI2C_Write = 0x0U, /*!< Master transmit to slave. */ + kI2C_Read = 0x1U, /*!< Master receive from slave. */ +} i2c_direction_t; + +/*! @brief Addressing mode. */ +typedef enum _i2c_slave_address_mode +{ + kI2C_Address7bit = 0x0U, /*!< 7-bit addressing mode. */ + kI2C_RangeMatch = 0X2U, /*!< Range address match addressing mode. */ +} i2c_slave_address_mode_t; + +/*! @brief I2C transfer control flag. */ +enum _i2c_master_transfer_flags +{ + kI2C_TransferDefaultFlag = 0x0U, /*!< Transfer starts with a start signal, stops with a stop signal. */ + kI2C_TransferNoStartFlag = 0x1U, /*!< Transfer starts without a start signal. */ + kI2C_TransferRepeatedStartFlag = 0x2U, /*!< Transfer starts with a repeated start signal. */ + kI2C_TransferNoStopFlag = 0x4U, /*!< Transfer ends without a stop signal. */ +}; + +/*! + * @brief Set of events sent to the callback for nonblocking slave transfers. + * + * These event enumerations are used for two related purposes. First, a bit mask created by OR'ing together + * events is passed to I2C_SlaveTransferNonBlocking() in order to specify which events to enable. + * Then, when the slave callback is invoked, it is passed the current event through its @a transfer + * parameter. + * + * @note These enumerations are meant to be OR'd together to form a bit mask of events. + */ +typedef enum _i2c_slave_transfer_event +{ + kI2C_SlaveAddressMatchEvent = 0x01U, /*!< Received the slave address after a start or repeated start. */ + kI2C_SlaveTransmitEvent = 0x02U, /*!< Callback is requested to provide data to transmit + (slave-transmitter role). */ + kI2C_SlaveReceiveEvent = 0x04U, /*!< Callback is requested to provide a buffer in which to place received + data (slave-receiver role). */ + kI2C_SlaveTransmitAckEvent = 0x08U, /*!< Callback needs to either transmit an ACK or NACK. */ +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2C_SlaveRepeatedStartEvent = 0x10U, /*!< A repeated start was detected. */ +#endif + kI2C_SlaveCompletionEvent = 0x20U, /*!< A stop was detected or finished transfer, completing the transfer. */ + + /*! Bit mask of all available events. */ + kI2C_SlaveAllEvents = kI2C_SlaveAddressMatchEvent | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + kI2C_SlaveRepeatedStartEvent | +#endif + kI2C_SlaveCompletionEvent, +} i2c_slave_transfer_event_t; + +/*! @brief I2C master user configuration. */ +typedef struct _i2c_master_config +{ + bool enableMaster; /*!< Enables the I2C peripheral at initialization time. */ +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */ +#endif +#if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF + bool enableStopHold; /*!< Controls the stop hold enable. */ +#endif + uint32_t baudRate_Bps; /*!< Baud rate configuration of I2C peripheral. */ + uint8_t glitchFilterWidth; /*!< Controls the width of the glitch. */ +} i2c_master_config_t; + +/*! @brief I2C slave user configuration. */ +typedef struct _i2c_slave_config +{ + bool enableSlave; /*!< Enables the I2C peripheral at initialization time. */ + bool enableGeneralCall; /*!< Enable general call addressing mode. */ + bool enableWakeUp; /*!< Enables/disables waking up MCU from low power mode. */ +#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION + bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */ +#endif + bool enableBaudRateCtl; /*!< Enables/disables independent slave baud rate on SCL in very fast I2C modes. */ + uint16_t slaveAddress; /*!< Slave address configuration. */ + uint16_t upperAddress; /*!< Maximum boundary slave address used in range matching mode. */ + i2c_slave_address_mode_t addressingMode; /*!< Addressing mode configuration of i2c_slave_address_mode_config_t. */ +} i2c_slave_config_t; + +/*! @brief I2C master handle typedef. */ +typedef struct _i2c_master_handle i2c_master_handle_t; + +/*! @brief I2C master transfer callback typedef. */ +typedef void (*i2c_master_transfer_callback_t)(I2C_Type *base, + i2c_master_handle_t *handle, + status_t status, + void *userData); + +/*! @brief I2C slave handle typedef. */ +typedef struct _i2c_slave_handle i2c_slave_handle_t; + +/*! @brief I2C master transfer structure. */ +typedef struct _i2c_master_transfer +{ + uint32_t flags; /*!< Transfer flag which controls the transfer. */ + uint8_t slaveAddress; /*!< 7-bit slave address. */ + i2c_direction_t direction; /*!< Transfer direction, read or write. */ + uint32_t subaddress; /*!< Sub address. Transferred MSB first. */ + uint8_t subaddressSize; /*!< Size of command buffer. */ + uint8_t *volatile data; /*!< Transfer buffer. */ + volatile size_t dataSize; /*!< Transfer size. */ +} i2c_master_transfer_t; + +/*! @brief I2C master handle structure. */ +struct _i2c_master_handle +{ + i2c_master_transfer_t transfer; /*!< I2C master transfer copy. */ + size_t transferSize; /*!< Total bytes to be transferred. */ + uint8_t state; /*!< Transfer state maintained during transfer. */ + i2c_master_transfer_callback_t completionCallback; /*!< Callback function called when transfer finished. */ + void *userData; /*!< Callback parameter passed to callback function. */ +}; + +/*! @brief I2C slave transfer structure. */ +typedef struct _i2c_slave_transfer +{ + i2c_slave_transfer_event_t event; /*!< Reason the callback is being invoked. */ + uint8_t *volatile data; /*!< Transfer buffer. */ + volatile size_t dataSize; /*!< Transfer size. */ + status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for + #kI2C_SlaveCompletionEvent. */ + size_t transferredCount; /*!< Number of bytes actually transferred since start or last repeated start. */ +} i2c_slave_transfer_t; + +/*! @brief I2C slave transfer callback typedef. */ +typedef void (*i2c_slave_transfer_callback_t)(I2C_Type *base, i2c_slave_transfer_t *xfer, void *userData); + +/*! @brief I2C slave handle structure. */ +struct _i2c_slave_handle +{ + bool isBusy; /*!< Whether transfer is busy. */ + i2c_slave_transfer_t transfer; /*!< I2C slave transfer copy. */ + uint32_t eventMask; /*!< Mask of enabled events. */ + i2c_slave_transfer_callback_t callback; /*!< Callback function called at transfer event. */ + void *userData; /*!< Callback parameter passed to callback. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus. */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock + * and configure the I2C with master configuration. + * + * @note This API should be called at the beginning of the application to use + * the I2C driver, or any operation to the I2C module could cause hard fault + * because clock is not enabled. The configuration structure can be filled by user + * from scratch, or be set with default values by I2C_MasterGetDefaultConfig(). + * After calling this API, the master is ready to transfer. + * Example: + * @code + * i2c_master_config_t config = { + * .enableMaster = true, + * .enableStopHold = false, + * .highDrive = false, + * .baudRate_Bps = 100000, + * .glitchFilterWidth = 0 + * }; + * I2C_MasterInit(I2C0, &config, 12000000U); + * @endcode + * + * @param base I2C base pointer + * @param masterConfig pointer to master configuration structure + * @param srcClock_Hz I2C peripheral clock frequency in Hz + */ +void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz); + +/*! + * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock + * and initializes the I2C with slave configuration. + * + * @note This API should be called at the beginning of the application to use + * the I2C driver, or any operation to the I2C module can cause a hard fault + * because the clock is not enabled. The configuration structure can partly be set + * with default values by I2C_SlaveGetDefaultConfig(), or can be filled by the user. + * Example + * @code + * i2c_slave_config_t config = { + * .enableSlave = true, + * .enableGeneralCall = false, + * .addressingMode = kI2C_Address7bit, + * .slaveAddress = 0x1DU, + * .enableWakeUp = false, + * .enablehighDrive = false, + * .enableBaudRateCtl = false + * }; + * I2C_SlaveInit(I2C0, &config); + * @endcode + * + * @param base I2C base pointer + * @param slaveConfig pointer to slave configuration structure + */ +void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig); + +/*! + * @brief De-initializes the I2C master peripheral. Call this API to gate the I2C clock. + * The I2C master module can't work unless the I2C_MasterInit is called. + * @param base I2C base pointer + */ +void I2C_MasterDeinit(I2C_Type *base); + +/*! + * @brief De-initializes the I2C slave peripheral. Calling this API gates the I2C clock. + * The I2C slave module can't work unless the I2C_SlaveInit is called to enable the clock. + * @param base I2C base pointer + */ +void I2C_SlaveDeinit(I2C_Type *base); + +/*! + * @brief Sets the I2C master configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in the I2C_MasterConfigure(). + * Use the initialized structure unchanged in I2C_MasterConfigure(), or modify some fields of + * the structure before calling I2C_MasterConfigure(). + * Example: + * @code + * i2c_master_config_t config; + * I2C_MasterGetDefaultConfig(&config); + * @endcode + * @param masterConfig Pointer to the master configuration structure. +*/ +void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig); + +/*! + * @brief Sets the I2C slave configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in I2C_SlaveConfigure(). + * Modify fields of the structure before calling the I2C_SlaveConfigure(). + * Example: + * @code + * i2c_slave_config_t config; + * I2C_SlaveGetDefaultConfig(&config); + * @endcode + * @param slaveConfig Pointer to the slave configuration structure. + */ +void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig); + +/*! + * @brief Enables or disabless the I2C peripheral operation. + * + * @param base I2C base pointer + * @param enable pass true to enable module, false to disable module + */ +static inline void I2C_Enable(I2C_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= I2C_C1_IICEN_MASK; + } + else + { + base->C1 &= ~I2C_C1_IICEN_MASK; + } +} + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the I2C status flags. + * + * @param base I2C base pointer + * @return status flag, use status flag to AND #_i2c_flags could get the related status. + */ +uint32_t I2C_MasterGetStatusFlags(I2C_Type *base); + +/*! + * @brief Gets the I2C status flags. + * + * @param base I2C base pointer + * @return status flag, use status flag to AND #_i2c_flags could get the related status. + */ +static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base) +{ + return I2C_MasterGetStatusFlags(base); +} + +/*! + * @brief Clears the I2C status flag state. + * + * The following status register flags can be cleared: kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag + * + * @param base I2C base pointer + * @param statusMask The status flag mask, defined in type i2c_status_flag_t. + * The parameter could be any combination of the following values: + * @arg kI2C_StartDetectFlag (if available) + * @arg kI2C_StopDetectFlag (if available) + * @arg kI2C_ArbitrationLostFlag + * @arg kI2C_IntPendingFlagFlag + */ +static inline void I2C_MasterClearStatusFlags(I2C_Type *base, uint32_t statusMask) +{ +/* Must clear the STARTF / STOPF bits prior to clearing IICIF */ +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + if (statusMask & kI2C_StartDetectFlag) + { + /* Shift the odd-ball flags back into place. */ + base->FLT |= (uint8_t)(statusMask >> 8U); + } +#endif + +#ifdef I2C_HAS_STOP_DETECT + if (statusMask & kI2C_StopDetectFlag) + { + /* Shift the odd-ball flags back into place. */ + base->FLT |= (uint8_t)(statusMask >> 8U); + } +#endif + + base->S = (uint8_t)statusMask; +} + +/*! + * @brief Clears the I2C status flag state. + * + * The following status register flags can be cleared: kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag + * + * @param base I2C base pointer + * @param statusMask The status flag mask, defined in type i2c_status_flag_t. + * The parameter could be any combination of the following values: + * @arg kI2C_StartDetectFlag (if available) + * @arg kI2C_StopDetectFlag (if available) + * @arg kI2C_ArbitrationLostFlag + * @arg kI2C_IntPendingFlagFlag + */ +static inline void I2C_SlaveClearStatusFlags(I2C_Type *base, uint32_t statusMask) +{ + I2C_MasterClearStatusFlags(base, statusMask); +} + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables I2C interrupt requests. + * + * @param base I2C base pointer + * @param mask interrupt source + * The parameter can be combination of the following source if defined: + * @arg kI2C_GlobalInterruptEnable + * @arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable + * @arg kI2C_SdaTimeoutInterruptEnable + */ +void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask); + +/*! + * @brief Disables I2C interrupt requests. + * + * @param base I2C base pointer + * @param mask interrupt source + * The parameter can be combination of the following source if defined: + * @arg kI2C_GlobalInterruptEnable + * @arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable + * @arg kI2C_SdaTimeoutInterruptEnable + */ +void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask); + +/*! + * @name DMA Control + * @{ + */ +#if defined(FSL_FEATURE_I2C_HAS_DMA_SUPPORT) && FSL_FEATURE_I2C_HAS_DMA_SUPPORT +/*! + * @brief Enables/disables the I2C DMA interrupt. + * + * @param base I2C base pointer + * @param enable true to enable, false to disable +*/ +static inline void I2C_EnableDMA(I2C_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= I2C_C1_DMAEN_MASK; + } + else + { + base->C1 &= ~I2C_C1_DMAEN_MASK; + } +} + +#endif /* FSL_FEATURE_I2C_HAS_DMA_SUPPORT */ + +/*! + * @brief Gets the I2C tx/rx data register address. This API is used to provide a transfer address + * for I2C DMA transfer configuration. + * + * @param base I2C base pointer + * @return data register address + */ +static inline uint32_t I2C_GetDataRegAddr(I2C_Type *base) +{ + return (uint32_t)(&(base->D)); +} + +/* @} */ +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Sets the I2C master transfer baud rate. + * + * @param base I2C base pointer + * @param baudRate_Bps the baud rate value in bps + * @param srcClock_Hz Source clock + */ +void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Sends a START on the I2C bus. + * + * This function is used to initiate a new master mode transfer by sending the START signal. + * The slave address is sent following the I2C START signal. + * + * @param base I2C peripheral base pointer + * @param address 7-bit slave device address. + * @param direction Master transfer directions(transmit/receive). + * @retval kStatus_Success Successfully send the start signal. + * @retval kStatus_I2C_Busy Current bus is busy. + */ +status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); + +/*! + * @brief Sends a STOP signal on the I2C bus. + * + * @retval kStatus_Success Successfully send the stop signal. + * @retval kStatus_I2C_Timeout Send stop signal failed, timeout. + */ +status_t I2C_MasterStop(I2C_Type *base); + +/*! + * @brief Sends a REPEATED START on the I2C bus. + * + * @param base I2C peripheral base pointer + * @param address 7-bit slave device address. + * @param direction Master transfer directions(transmit/receive). + * @retval kStatus_Success Successfully send the start signal. + * @retval kStatus_I2C_Busy Current bus is busy but not occupied by current I2C master. + */ +status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); + +/*! + * @brief Performs a polling send transaction on the I2C bus without a STOP signal. + * + * @param base The I2C peripheral base pointer. + * @param txBuff The pointer to the data to be transferred. + * @param txSize The length in bytes of the data to be transferred. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. + */ +status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize); + +/*! + * @brief Performs a polling receive transaction on the I2C bus with a STOP signal. + * + * @note The I2C_MasterReadBlocking function stops the bus before reading the final byte. + * Without stopping the bus prior for the final read, the bus issues another read, resulting + * in garbage data being read into the data register. + * + * @param base I2C peripheral base pointer. + * @param rxBuff The pointer to the data to store the received data. + * @param rxSize The length in bytes of the data to be received. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_Timeout Send stop signal failed, timeout. + */ +status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize); + +/*! + * @brief Performs a polling send transaction on the I2C bus. + * + * @param base The I2C peripheral base pointer. + * @param txBuff The pointer to the data to be transferred. + * @param txSize The length in bytes of the data to be transferred. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. + */ +status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize); + +/*! + * @brief Performs a polling receive transaction on the I2C bus. + * + * @param base I2C peripheral base pointer. + * @param rxBuff The pointer to the data to store the received data. + * @param rxSize The length in bytes of the data to be received. + */ +void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize); + +/*! + * @brief Performs a master polling transfer on the I2C bus. + * + * @note The API does not return until the transfer succeeds or fails due + * to arbitration lost or receiving a NAK. + * + * @param base I2C peripheral base address. + * @param xfer Pointer to the transfer structure. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_Busy Previous transmission still not finished. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. + */ +status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the I2C handle which is used in transactional functions. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_master_handle_t structure to store the transfer state. + * @param callback pointer to user callback function. + * @param userData user paramater passed to the callback function. + */ +void I2C_MasterTransferCreateHandle(I2C_Type *base, + i2c_master_handle_t *handle, + i2c_master_transfer_callback_t callback, + void *userData); + +/*! + * @brief Performs a master interrupt non-blocking transfer on the I2C bus. + * + * @note Calling the API will return immediately after transfer initiates, user needs + * to call I2C_MasterGetTransferCount to poll the transfer status to check whether + * the transfer is finished, if the return status is not kStatus_I2C_Busy, the transfer + * is finished. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. + * @param xfer pointer to i2c_master_transfer_t structure. + * @retval kStatus_Success Sucessully start the data transmission. + * @retval kStatus_I2C_Busy Previous transmission still not finished. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + */ +status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer); + +/*! + * @brief Gets the master transfer status during a interrupt non-blocking transfer. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count); + +/*! + * @brief Aborts an interrupt non-blocking transfer early. + * + * @note This API can be called at any time when an interrupt non-blocking transfer initiates + * to abort the transfer early. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_master_handle_t structure which stores the transfer state + */ +void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle); + +/*! + * @brief Master interrupt handler. + * + * @param base I2C base pointer. + * @param i2cHandle pointer to i2c_master_handle_t structure. + */ +void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle); + +/*! + * @brief Initializes the I2C handle which is used in transactional functions. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_slave_handle_t structure to store the transfer state. + * @param callback pointer to user callback function. + * @param userData user parameter passed to the callback function. + */ +void I2C_SlaveTransferCreateHandle(I2C_Type *base, + i2c_slave_handle_t *handle, + i2c_slave_transfer_callback_t callback, + void *userData); + +/*! + * @brief Starts accepting slave transfers. + * + * Call this API after calling the I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing + * transactions driven by an I2C master. The slave monitors the I2C bus and passes events to the + * callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked + * from the interrupt context. + * + * The set of events received by the callback is customizable. To do so, set the @a eventMask parameter to + * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive. + * The #kI2C_SlaveTransmitEvent and #kLPI2C_SlaveReceiveEvent events are always enabled and do not need + * to be included in the mask. Alternatively, pass 0 to get a default set of only the transmit and + * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as + * a convenient way to enable all events. + * + * @param base The I2C peripheral base address. + * @param handle Pointer to #i2c_slave_handle_t structure which stores the transfer state. + * @param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify + * which events to send to the callback. Other accepted values are 0 to get a default set of + * only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events. + * + * @retval #kStatus_Success Slave transfers were successfully started. + * @retval #kStatus_I2C_Busy Slave transfers have already been started on this handle. + */ +status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask); + +/*! + * @brief Aborts the slave transfer. + * + * @note This API can be called at any time to stop slave for handling the bus events. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_slave_handle_t structure which stores the transfer state. + */ +void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle); + +/*! + * @brief Gets the slave transfer remaining bytes during a interrupt non-blocking transfer. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_slave_handle_t structure. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count); + +/*! + * @brief Slave interrupt handler. + * + * @param base I2C base pointer. + * @param i2cHandle pointer to i2c_slave_handle_t structure which stores the transfer state + */ +void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle); + +/* @} */ +#if defined(__cplusplus) +} +#endif /*_cplusplus. */ +/*@}*/ + +#endif /* _FSL_I2C_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c_dma.c new file mode 100644 index 0000000000..a5ee3e5745 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c_dma.c @@ -0,0 +1,523 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_i2c_dma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*base, false); + + /* Send stop if kI2C_TransferNoStop flag is not asserted. */ + if (!(i2cPrivateHandle->handle->transfer.flags & kI2C_TransferNoStopFlag)) + { + if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read) + { + /* Change to send NAK at the last byte. */ + i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK; + + /* Wait the last data to be received. */ + while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Send stop signal. */ + result = I2C_MasterStop(i2cPrivateHandle->base); + + /* Read the last data byte. */ + *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) = + i2cPrivateHandle->base->D; + } + else + { + /* Wait the last data to be sent. */ + while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Send stop signal. */ + result = I2C_MasterStop(i2cPrivateHandle->base); + } + } + + i2cPrivateHandle->handle->state = kIdleState; + + if (i2cPrivateHandle->handle->completionCallback) + { + i2cPrivateHandle->handle->completionCallback(i2cPrivateHandle->base, i2cPrivateHandle->handle, result, + i2cPrivateHandle->handle->userData); + } +} + +static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status) +{ + status_t result = kStatus_Success; + + /* Check arbitration lost. */ + if (status & kI2C_ArbitrationLostFlag) + { + /* Clear arbitration lost flag. */ + base->S = kI2C_ArbitrationLostFlag; + result = kStatus_I2C_ArbitrationLost; + } + /* Check NAK */ + else if (status & kI2C_ReceiveNakFlag) + { + result = kStatus_I2C_Nak; + } + else + { + } + + return result; +} + +static status_t I2C_InitTransferStateMachineDMA(I2C_Type *base, + i2c_master_dma_handle_t *handle, + i2c_master_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + /* Set up transfer first. */ + i2c_direction_t direction = xfer->direction; + status_t result = kStatus_Success; + uint16_t timeout = UINT16_MAX; + + if (handle->state != kIdleState) + { + return kStatus_I2C_Busy; + } + else + { + /* Init the handle member. */ + handle->transfer = *xfer; + + /* Save total transfer size. */ + handle->transferSize = xfer->dataSize; + + handle->state = kTransferDataState; + + /* Wait until ready to complete. */ + while ((!(base->S & kI2C_TransferCompleteFlag)) && (--timeout)) + { + } + + /* Failed to start the transfer. */ + if (timeout == 0) + { + return kStatus_I2C_Timeout; + } + + /* Clear all status before transfer. */ + I2C_MasterClearStatusFlags(base, kClearFlags); + + /* Change to send write address when it's a read operation with command. */ + if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read)) + { + direction = kI2C_Write; + } + + /* If repeated start is requested, send repeated start. */ + if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag) + { + result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction); + } + else /* For normal transfer, send start. */ + { + result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction); + } + + /* Send subaddress. */ + if (handle->transfer.subaddressSize) + { + do + { + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear interrupt pending flag. */ + base->S = kI2C_IntPendingFlag; + + handle->transfer.subaddressSize--; + base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)); + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + return result; + } + + } while ((handle->transfer.subaddressSize > 0) && (result == kStatus_Success)); + + if (handle->transfer.direction == kI2C_Read) + { + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send repeated start and slave address. */ + result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read); + } + } + + if (result) + { + return result; + } + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + } + + return result; +} + +static void I2C_MasterTransferDMAConfig(I2C_Type *base, i2c_master_dma_handle_t *handle) +{ + dma_transfer_config_t transfer_config; + dma_transfer_options_t transfer_options = kDMA_EnableInterrupt; + + if (handle->transfer.direction == kI2C_Read) + { + transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base); + transfer_config.destAddr = (uint32_t)(handle->transfer.data); + + /* Send stop if kI2C_TransferNoStop flag is not asserted. */ + if (!(handle->transfer.flags & kI2C_TransferNoStopFlag)) + { + transfer_config.transferSize = (handle->transfer.dataSize - 1); + } + else + { + transfer_config.transferSize = handle->transfer.dataSize; + } + + transfer_config.srcSize = kDMA_Transfersize8bits; + transfer_config.enableSrcIncrement = false; + transfer_config.destSize = kDMA_Transfersize8bits; + transfer_config.enableDestIncrement = true; + } + else + { + transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1); + transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base); + transfer_config.transferSize = (handle->transfer.dataSize - 1); + transfer_config.srcSize = kDMA_Transfersize8bits; + transfer_config.enableSrcIncrement = true; + transfer_config.destSize = kDMA_Transfersize8bits; + transfer_config.enableDestIncrement = false; + } + + DMA_SubmitTransfer(handle->dmaHandle, &transfer_config, transfer_options); + DMA_StartTransfer(handle->dmaHandle); +} + +void I2C_MasterTransferCreateHandleDMA(I2C_Type *base, + i2c_master_dma_handle_t *handle, + i2c_master_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *dmaHandle) +{ + assert(handle); + assert(dmaHandle); + + uint32_t instance = I2C_GetInstance(base); + + /* Zero handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set the user callback and userData. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Set the handle for DMA. */ + handle->dmaHandle = dmaHandle; + + s_dmaPrivateHandle[instance].base = base; + s_dmaPrivateHandle[instance].handle = handle; + + DMA_SetCallback(dmaHandle, (dma_callback)I2C_MasterTransferCallbackDMA, &s_dmaPrivateHandle[instance]); +} + +status_t I2C_MasterTransferDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, i2c_master_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + + status_t result; + uint8_t tmpReg; + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + + /* Disable dma transfer. */ + I2C_EnableDMA(base, false); + + /* Send address and command buffer(if there is), until senddata phase or receive data phase. */ + result = I2C_InitTransferStateMachineDMA(base, handle, xfer); + + if (result != kStatus_Success) + { + /* Send stop if received Nak. */ + if (result == kStatus_I2C_Nak) + { + if (I2C_MasterStop(base) != kStatus_Success) + { + result = kStatus_I2C_Timeout; + } + } + + /* Reset the state to idle state. */ + handle->state = kIdleState; + + return result; + } + + /* Configure dma transfer. */ + /* For i2c send, need to send 1 byte first to trigger the dma, for i2c read, + need to send stop before reading the last byte, so the dma transfer size should + be (xSize - 1). */ + if (handle->transfer.dataSize > 1) + { + I2C_MasterTransferDMAConfig(base, handle); + if (handle->transfer.direction == kI2C_Read) + { + /* Change direction for receive. */ + base->C1 &= ~I2C_C1_TX_MASK; + + /* Read dummy to release the bus. */ + dummy = base->D; + + /* Enabe dma transfer. */ + I2C_EnableDMA(base, true); + } + else + { + /* Enabe dma transfer. */ + I2C_EnableDMA(base, true); + + /* Send the first data. */ + base->D = *handle->transfer.data; + } + } + else /* If transfer size is 1, use polling method. */ + { + if (handle->transfer.direction == kI2C_Read) + { + tmpReg = base->C1; + + /* Change direction to Rx. */ + tmpReg &= ~I2C_C1_TX_MASK; + + /* Configure send NAK */ + tmpReg |= I2C_C1_TXAK_MASK; + + base->C1 = tmpReg; + + /* Read dummy to release the bus. */ + dummy = base->D; + } + else + { + base->D = *handle->transfer.data; + } + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send stop if kI2C_TransferNoStop flag is not asserted. */ + if (!(handle->transfer.flags & kI2C_TransferNoStopFlag)) + { + result = I2C_MasterStop(base); + } + + /* Read the last byte of data. */ + if (handle->transfer.direction == kI2C_Read) + { + *handle->transfer.data = base->D; + } + + /* Reset the state to idle. */ + handle->state = kIdleState; + } + + return result; +} + +status_t I2C_MasterTransferGetCountDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + if (kIdleState != handle->state) + { + *count = (handle->transferSize - DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel)); + } + else + { + *count = handle->transferSize; + } + + return kStatus_Success; +} + +void I2C_MasterTransferAbortDMA(I2C_Type *base, i2c_master_dma_handle_t *handle) +{ + DMA_AbortTransfer(handle->dmaHandle); + + /* Disable dma transfer. */ + I2C_EnableDMA(base, false); + + /* Reset the state to idle. */ + handle->state = kIdleState; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c_dma.h new file mode 100644 index 0000000000..321f79ec34 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_i2c_dma.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_I2C_DMA_H_ +#define _FSL_I2C_DMA_H_ + +#include "fsl_i2c.h" +#include "fsl_dmamux.h" +#include "fsl_dma.h" + +/*! + * @addtogroup i2c_dma_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief I2C master dma handle typedef. */ +typedef struct _i2c_master_dma_handle i2c_master_dma_handle_t; + +/*! @brief I2C master dma transfer callback typedef. */ +typedef void (*i2c_master_dma_transfer_callback_t)(I2C_Type *base, + i2c_master_dma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief I2C master dma transfer structure. */ +struct _i2c_master_dma_handle +{ + i2c_master_transfer_t transfer; /*!< I2C master transfer struct. */ + size_t transferSize; /*!< Total bytes to be transferred. */ + uint8_t state; /*!< I2C master transfer status. */ + dma_handle_t *dmaHandle; /*!< The DMA handler used. */ + i2c_master_dma_transfer_callback_t completionCallback; /*!< Callback function called after dma transfer finished. */ + void *userData; /*!< Callback parameter passed to callback function. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus. */ + +/*! + * @name I2C Block DMA Transfer Operation + * @{ + */ + +/*! + * @brief Init the I2C handle which is used in transcational functions + * + * @param base I2C peripheral base address + * @param handle pointer to i2c_master_dma_handle_t structure + * @param callback pointer to user callback function + * @param userData user param passed to the callback function + * @param dmaHandle DMA handle pointer + */ +void I2C_MasterTransferCreateHandleDMA(I2C_Type *base, + i2c_master_dma_handle_t *handle, + i2c_master_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *dmaHandle); + +/*! + * @brief Performs a master dma non-blocking transfer on the I2C bus + * + * @param base I2C peripheral base address + * @param handle pointer to i2c_master_dma_handle_t structure + * @param xfer pointer to transfer structure of i2c_master_transfer_t + * @retval kStatus_Success Sucessully complete the data transmission. + * @retval kStatus_I2C_Busy Previous transmission still not finished. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive Nak during transfer. + */ +status_t I2C_MasterTransferDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, i2c_master_transfer_t *xfer); + +/*! + * @brief Get master transfer status during a dma non-blocking transfer + * + * @param base I2C peripheral base address + * @param handle pointer to i2c_master_dma_handle_t structure + * @param count Number of bytes transferred so far by the non-blocking transaction. + */ +status_t I2C_MasterTransferGetCountDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, size_t *count); + +/*! + * @brief Abort a master dma non-blocking transfer in a early time + * + * @param base I2C peripheral base address + * @param handle pointer to i2c_master_dma_handle_t structure + */ +void I2C_MasterTransferAbortDMA(I2C_Type *base, i2c_master_dma_handle_t *handle); + +/* @} */ +#if defined(__cplusplus) +} +#endif /*_cplusplus. */ +/*@}*/ +#endif /*_FSL_I2C_DMA_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_llwu.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_llwu.c new file mode 100644 index 0000000000..c27b91e9f0 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_llwu.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_llwu.h" + +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) +void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + volatile uint32_t *regBase; + uint32_t regOffset; + uint32_t reg; + + switch (pinIndex >> 4U) + { + case 0U: + regBase = &base->PE1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 1U: + regBase = &base->PE2; + break; +#endif + default: + regBase = NULL; + break; + } +#else + volatile uint8_t *regBase; + uint8_t regOffset; + uint8_t reg; + switch (pinIndex >> 2U) + { + case 0U: + regBase = &base->PE1; + break; + case 1U: + regBase = &base->PE2; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 2U: + regBase = &base->PE3; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 12)) + case 3U: + regBase = &base->PE4; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 4U: + regBase = &base->PE5; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 20)) + case 5U: + regBase = &base->PE6; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 6U: + regBase = &base->PE7; + break; +#endif +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 28)) + case 7U: + regBase = &base->PE8; + break; +#endif + default: + regBase = NULL; + break; + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH == 32 */ + + if (regBase) + { + reg = *regBase; +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + regOffset = ((pinIndex & 0x0FU) << 1U); +#else + regOffset = ((pinIndex & 0x03U) << 1U); +#endif + reg &= ~(0x3U << regOffset); + reg |= ((uint32_t)pinMode << regOffset); + *regBase = reg; + } +} + +bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + return (bool)(base->PF & (1U << pinIndex)); +#else + volatile uint8_t *regBase; + + switch (pinIndex >> 3U) + { +#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) + case 0U: + regBase = &base->PF1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 1U: + regBase = &base->PF2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 2U: + regBase = &base->PF3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 3U: + regBase = &base->PF4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#else + case 0U: + regBase = &base->F1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 1U: + regBase = &base->F2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 2U: + regBase = &base->F3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 3U: + regBase = &base->F4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#endif /* FSL_FEATURE_LLWU_HAS_PF */ + default: + regBase = NULL; + break; + } + + if (regBase) + { + return (bool)(*regBase & (1U << pinIndex % 8)); + } + else + { + return false; + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} + +void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + base->PF = (1U << pinIndex); +#else + volatile uint8_t *regBase; + switch (pinIndex >> 3U) + { +#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) + case 0U: + regBase = &base->PF1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 1U: + regBase = &base->PF2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 2U: + regBase = &base->PF3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 3U: + regBase = &base->PF4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#else + case 0U: + regBase = &base->F1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8)) + case 1U: + regBase = &base->F2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) + case 2U: + regBase = &base->F3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24)) + case 3U: + regBase = &base->F4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#endif /* FSL_FEATURE_LLWU_HAS_PF */ + default: + regBase = NULL; + break; + } + if (regBase) + { + *regBase = (1U << pinIndex % 8U); + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER) +void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + uint32_t reg; + + reg = base->FILT; + reg &= ~((LLWU_FILT_FILTSEL1_MASK | LLWU_FILT_FILTE1_MASK) << (filterIndex * 8U - 1U)); + reg |= (((filterMode.pinIndex << LLWU_FILT_FILTSEL1_SHIFT) | (filterMode.filterMode << LLWU_FILT_FILTE1_SHIFT) + /* Clear the Filter Detect Flag */ + | LLWU_FILT_FILTF1_MASK) + << (filterIndex * 8U - 1U)); + base->FILT = reg; +#else + volatile uint8_t *regBase; + uint8_t reg; + + switch (filterIndex) + { + case 1: + regBase = &base->FILT1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1)) + case 2: + regBase = &base->FILT2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2)) + case 3: + regBase = &base->FILT3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3)) + case 4: + regBase = &base->FILT4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + default: + regBase = NULL; + break; + } + + if (regBase) + { + reg = *regBase; + reg &= ~(LLWU_FILT1_FILTSEL_MASK | LLWU_FILT1_FILTE_MASK); + reg |= ((uint32_t)filterMode.pinIndex << LLWU_FILT1_FILTSEL_SHIFT); + reg |= ((uint32_t)filterMode.filterMode << LLWU_FILT1_FILTE_SHIFT); + /* Clear the Filter Detect Flag */ + reg |= LLWU_FILT1_FILTF_MASK; + *regBase = reg; + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} + +bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + return (bool)(base->FILT & (1U << (filterIndex * 8U - 1))); +#else + bool status = false; + + switch (filterIndex) + { + case 1: + status = (base->FILT1 & LLWU_FILT1_FILTF_MASK); + break; +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1)) + case 2: + status = (base->FILT2 & LLWU_FILT2_FILTF_MASK); + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2)) + case 3: + status = (base->FILT3 & LLWU_FILT3_FILTF_MASK); + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3)) + case 4: + status = (base->FILT4 & LLWU_FILT4_FILTF_MASK); + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + default: + break; + } + + return status; +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} + +void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + uint32_t reg; + + reg = base->FILT; + switch (filterIndex) + { + case 1: + reg |= LLWU_FILT_FILTF1_MASK; + break; + case 2: + reg |= LLWU_FILT_FILTF2_MASK; + break; + case 3: + reg |= LLWU_FILT_FILTF3_MASK; + break; + case 4: + reg |= LLWU_FILT_FILTF4_MASK; + break; + default: + break; + } + base->FILT = reg; +#else + volatile uint8_t *regBase; + uint8_t reg; + + switch (filterIndex) + { + case 1: + regBase = &base->FILT1; + break; +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1)) + case 2: + regBase = &base->FILT2; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2)) + case 3: + regBase = &base->FILT3; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3)) + case 4: + regBase = &base->FILT4; + break; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + default: + regBase = NULL; + break; + } + + if (regBase) + { + reg = *regBase; + reg |= LLWU_FILT1_FILTF_MASK; + *regBase = reg; + } +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + +#if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE) +void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode) +{ + uint8_t reg; + + reg = base->RST; + reg &= ~(LLWU_RST_LLRSTE_MASK | LLWU_RST_RSTFILT_MASK); + reg |= + (((uint32_t)pinEnable << LLWU_RST_LLRSTE_SHIFT) | ((uint32_t)enableInLowLeakageMode << LLWU_RST_RSTFILT_SHIFT)); + base->RST = reg; +} +#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_llwu.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_llwu.h new file mode 100644 index 0000000000..7c11572e80 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_llwu.h @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LLWU_H_ +#define _FSL_LLWU_H_ + +#include "fsl_common.h" + +/*! @addtogroup llwu */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LLWU driver version 2.0.1. */ +#define FSL_LLWU_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief External input pin control modes + */ +typedef enum _llwu_external_pin_mode +{ + kLLWU_ExternalPinDisable = 0U, /*!< Pin disabled as wakeup input. */ + kLLWU_ExternalPinRisingEdge = 1U, /*!< Pin enabled with rising edge detection. */ + kLLWU_ExternalPinFallingEdge = 2U, /*!< Pin enabled with falling edge detection.*/ + kLLWU_ExternalPinAnyEdge = 3U /*!< Pin enabled with any change detection. */ +} llwu_external_pin_mode_t; + +/*! + * @brief Digital filter control modes + */ +typedef enum _llwu_pin_filter_mode +{ + kLLWU_PinFilterDisable = 0U, /*!< Filter disabled. */ + kLLWU_PinFilterRisingEdge = 1U, /*!< Filter positive edge detection.*/ + kLLWU_PinFilterFallingEdge = 2U, /*!< Filter negative edge detection.*/ + kLLWU_PinFilterAnyEdge = 3U /*!< Filter any edge detection. */ +} llwu_pin_filter_mode_t; + +#if (defined(FSL_FEATURE_LLWU_HAS_VERID) && FSL_FEATURE_LLWU_HAS_VERID) +/*! + * @brief IP version ID definition. + */ +typedef struct _llwu_version_id +{ + uint16_t feature; /*!< Feature Specification Number. */ + uint8_t minor; /*!< Minor version number. */ + uint8_t major; /*!< Major version number. */ +} llwu_version_id_t; +#endif /* FSL_FEATURE_LLWU_HAS_VERID */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PARAM) && FSL_FEATURE_LLWU_HAS_PARAM) +/*! + * @brief IP parameter definition. + */ +typedef struct _llwu_param +{ + uint8_t filters; /*!< Number of pin filter. */ + uint8_t dmas; /*!< Number of wakeup DMA. */ + uint8_t modules; /*!< Number of wakeup module. */ + uint8_t pins; /*!< Number of wake up pin. */ +} llwu_param_t; +#endif /* FSL_FEATURE_LLWU_HAS_PARAM */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER) +/*! + * @brief External input pin filter control structure + */ +typedef struct _llwu_external_pin_filter_mode +{ + uint32_t pinIndex; /*!< Pin number */ + llwu_pin_filter_mode_t filterMode; /*!< Filter mode */ +} llwu_external_pin_filter_mode_t; +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Low-Leakage Wakeup Unit Control APIs + * @{ + */ + +#if (defined(FSL_FEATURE_LLWU_HAS_VERID) && FSL_FEATURE_LLWU_HAS_VERID) +/*! + * @brief Gets the LLWU version ID. + * + * This function gets the LLWU version ID, including major version number, + * minor version number, and feature specification number. + * + * @param base LLWU peripheral base address. + * @param versionId Pointer to version ID structure. + */ +static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *versionId) +{ + *((uint32_t *)versionId) = base->VERID; +} +#endif /* FSL_FEATURE_LLWU_HAS_VERID */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PARAM) && FSL_FEATURE_LLWU_HAS_PARAM) +/*! + * @brief Gets the LLWU parameter. + * + * This function gets the LLWU parameter, including wakeup pin number, module + * number, DMA number, and pin filter number. + * + * @param base LLWU peripheral base address. + * @param param Pointer to LLWU param structure. + */ +static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param) +{ + *((uint32_t *)param) = base->PARAM; +} +#endif /* FSL_FEATURE_LLWU_HAS_PARAM */ + +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) +/*! + * @brief Sets the external input pin source mode. + * + * This function sets the external input pin source mode that is used + * as a wake up source. + * + * @param base LLWU peripheral base address. + * @param pinIndex pin index which to be enabled as external wakeup source, start from 1. + * @param pinMode pin configuration mode defined in llwu_external_pin_modes_t + */ +void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode); + +/*! + * @brief Gets the external wakeup source flag. + * + * This function checks the external pin flag to detect whether the MCU is + * woke up by the specific pin. + * + * @param base LLWU peripheral base address. + * @param pinIndex pin index, start from 1. + * @return true if the specific pin is wake up source. + */ +bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); + +/*! + * @brief Clears the external wakeup source flag. + * + * This function clears the external wakeup source flag for a specific pin. + * + * @param base LLWU peripheral base address. + * @param pinIndex pin index, start from 1. + */ +void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ + +#if (defined(FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE) && FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE) +/*! + * @brief Enables/disables the internal module source. + * + * This function enables/disables the internal module source mode that is used + * as a wake up source. + * + * @param base LLWU peripheral base address. + * @param moduleIndex module index which to be enabled as internal wakeup source, start from 1. + * @param enable enable or disable setting + */ +static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable) +{ + if (enable) + { + base->ME |= 1U << moduleIndex; + } + else + { + base->ME &= ~(1U << moduleIndex); + } +} + +/*! + * @brief Gets the external wakeup source flag. + * + * This function checks the external pin flag to detect whether the system is + * woke up by the specific pin. + * + * @param base LLWU peripheral base address. + * @param moduleIndex module index, start from 1. + * @return true if the specific pin is wake up source. + */ +static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t moduleIndex) +{ +#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) + return (bool)(base->MF & (1U << moduleIndex)); +#else +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) +#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) + return (bool)(base->MF5 & (1U << moduleIndex)); +#else + return (bool)(base->F5 & (1U << moduleIndex)); +#endif /* FSL_FEATURE_LLWU_HAS_PF */ +#else +#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) + return (bool)(base->PF3 & (1U << moduleIndex)); +#else + return (bool)(base->F3 & (1U << moduleIndex)); +#endif +#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +} +#endif /* FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE */ + +#if (defined(FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG) && FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG) +/*! + * @brief Enables/disables the internal module DMA wakeup source. + * + * This function enables/disables the internal DMA that is used as a wake up source. + * + * @param base LLWU peripheral base address. + * @param moduleIndex Internal module index which used as DMA request source, start from 1. + * @param enable Enable or disable DMA request source + */ +static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable) +{ + if (enable) + { + base->DE |= 1U << moduleIndex; + } + else + { + base->DE &= ~(1U << moduleIndex); + } +} +#endif /* FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG */ + +#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER) +/*! + * @brief Sets the pin filter configuration. + * + * This function sets the pin filter configuration. + * + * @param base LLWU peripheral base address. + * @param filterIndex pin filter index which used to enable/disable the digital filter, start from 1. + * @param filterMode filter mode configuration + */ +void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode); + +/*! + * @brief Gets the pin filter configuration. + * + * This function gets the pin filter flag. + * + * @param base LLWU peripheral base address. + * @param filterIndex pin filter index, start from 1. + * @return true if the flag is a source of existing a low-leakage power mode. + */ +bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); + +/*! + * @brief Clear the pin filter configuration. + * + * This function clear the pin filter flag. + * + * @param base LLWU peripheral base address. + * @param filterIndex pin filter index which to be clear the flag, start from 1. + */ +void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); + +#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ + +#if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE) +/*! + * @brief Sets the reset pin mode. + * + * This function sets how the reset pin is used as a low leakage mode exit source. + * + * @param pinEnable Enable reset pin filter + * @param pinFilterEnable Specify whether pin filter is enabled in Low-Leakage power mode. + */ +void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode); +#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ +#endif /* _FSL_LLWU_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lptmr.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lptmr.c new file mode 100644 index 0000000000..b3dcc89d55 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lptmr.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_lptmr.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address to be used to gate or ungate the module clock + * + * @param base LPTMR peripheral base address + * + * @return The LPTMR instance + */ +static uint32_t LPTMR_GetInstance(LPTMR_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to LPTMR bases for each instance. */ +static LPTMR_Type *const s_lptmrBases[] = LPTMR_BASE_PTRS; + +/*! @brief Pointers to LPTMR clocks for each instance. */ +static const clock_ip_name_t s_lptmrClocks[] = LPTMR_CLOCKS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t LPTMR_GetInstance(LPTMR_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_LPTMR_COUNT; instance++) + { + if (s_lptmrBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_LPTMR_COUNT); + + return instance; +} + +void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config) +{ + assert(config); + + /* Ungate the LPTMR clock*/ + CLOCK_EnableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); + + /* Configure the timers operation mode and input pin setup */ + base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) | + LPTMR_CSR_TPP(config->pinPolarity) | LPTMR_CSR_TPS(config->pinSelect)); + + /* Configure the prescale value and clock source */ + base->PSR = (LPTMR_PSR_PRESCALE(config->value) | LPTMR_PSR_PBYP(config->bypassPrescaler) | + LPTMR_PSR_PCS(config->prescalerClockSource)); +} + +void LPTMR_Deinit(LPTMR_Type *base) +{ + /* Disable the LPTMR and reset the internal logic */ + base->CSR &= ~LPTMR_CSR_TEN_MASK; + /* Gate the LPTMR clock*/ + CLOCK_DisableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); +} + +void LPTMR_GetDefaultConfig(lptmr_config_t *config) +{ + assert(config); + + /* Use time counter mode */ + config->timerMode = kLPTMR_TimerModeTimeCounter; + /* Use input 0 as source in pulse counter mode */ + config->pinSelect = kLPTMR_PinSelectInput_0; + /* Pulse input pin polarity is active-high */ + config->pinPolarity = kLPTMR_PinPolarityActiveHigh; + /* Counter resets whenever TCF flag is set */ + config->enableFreeRunning = false; + /* Bypass the prescaler */ + config->bypassPrescaler = true; + /* LPTMR clock source */ + config->prescalerClockSource = kLPTMR_PrescalerClock_1; + /* Divide the prescaler clock by 2 */ + config->value = kLPTMR_Prescale_Glitch_0; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lptmr.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lptmr.h new file mode 100644 index 0000000000..fd3cb1ed24 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lptmr.h @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LPTMR_H_ +#define _FSL_LPTMR_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lptmr_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_LPTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief LPTMR pin selection, used in pulse counter mode.*/ +typedef enum _lptmr_pin_select +{ + kLPTMR_PinSelectInput_0 = 0x0U, /*!< Pulse counter input 0 is selected */ + kLPTMR_PinSelectInput_1 = 0x1U, /*!< Pulse counter input 1 is selected */ + kLPTMR_PinSelectInput_2 = 0x2U, /*!< Pulse counter input 2 is selected */ + kLPTMR_PinSelectInput_3 = 0x3U /*!< Pulse counter input 3 is selected */ +} lptmr_pin_select_t; + +/*! @brief LPTMR pin polarity, used in pulse counter mode.*/ +typedef enum _lptmr_pin_polarity +{ + kLPTMR_PinPolarityActiveHigh = 0x0U, /*!< Pulse Counter input source is active-high */ + kLPTMR_PinPolarityActiveLow = 0x1U /*!< Pulse Counter input source is active-low */ +} lptmr_pin_polarity_t; + +/*! @brief LPTMR timer mode selection.*/ +typedef enum _lptmr_timer_mode +{ + kLPTMR_TimerModeTimeCounter = 0x0U, /*!< Time Counter mode */ + kLPTMR_TimerModePulseCounter = 0x1U /*!< Pulse Counter mode */ +} lptmr_timer_mode_t; + +/*! @brief LPTMR prescaler/glitch filter values*/ +typedef enum _lptmr_prescaler_glitch_value +{ + kLPTMR_Prescale_Glitch_0 = 0x0U, /*!< Prescaler divide 2, glitch filter does not support this setting */ + kLPTMR_Prescale_Glitch_1 = 0x1U, /*!< Prescaler divide 4, glitch filter 2 */ + kLPTMR_Prescale_Glitch_2 = 0x2U, /*!< Prescaler divide 8, glitch filter 4 */ + kLPTMR_Prescale_Glitch_3 = 0x3U, /*!< Prescaler divide 16, glitch filter 8 */ + kLPTMR_Prescale_Glitch_4 = 0x4U, /*!< Prescaler divide 32, glitch filter 16 */ + kLPTMR_Prescale_Glitch_5 = 0x5U, /*!< Prescaler divide 64, glitch filter 32 */ + kLPTMR_Prescale_Glitch_6 = 0x6U, /*!< Prescaler divide 128, glitch filter 64 */ + kLPTMR_Prescale_Glitch_7 = 0x7U, /*!< Prescaler divide 256, glitch filter 128 */ + kLPTMR_Prescale_Glitch_8 = 0x8U, /*!< Prescaler divide 512, glitch filter 256 */ + kLPTMR_Prescale_Glitch_9 = 0x9U, /*!< Prescaler divide 1024, glitch filter 512*/ + kLPTMR_Prescale_Glitch_10 = 0xAU, /*!< Prescaler divide 2048 glitch filter 1024 */ + kLPTMR_Prescale_Glitch_11 = 0xBU, /*!< Prescaler divide 4096, glitch filter 2048 */ + kLPTMR_Prescale_Glitch_12 = 0xCU, /*!< Prescaler divide 8192, glitch filter 4096 */ + kLPTMR_Prescale_Glitch_13 = 0xDU, /*!< Prescaler divide 16384, glitch filter 8192 */ + kLPTMR_Prescale_Glitch_14 = 0xEU, /*!< Prescaler divide 32768, glitch filter 16384 */ + kLPTMR_Prescale_Glitch_15 = 0xFU /*!< Prescaler divide 65536, glitch filter 32768 */ +} lptmr_prescaler_glitch_value_t; + +/*! + * @brief LPTMR prescaler/glitch filter clock select. + * @note Clock connections are SoC-specific + */ +typedef enum _lptmr_prescaler_clock_select +{ + kLPTMR_PrescalerClock_0 = 0x0U, /*!< Prescaler/glitch filter clock 0 selected. */ + kLPTMR_PrescalerClock_1 = 0x1U, /*!< Prescaler/glitch filter clock 1 selected. */ + kLPTMR_PrescalerClock_2 = 0x2U, /*!< Prescaler/glitch filter clock 2 selected. */ + kLPTMR_PrescalerClock_3 = 0x3U, /*!< Prescaler/glitch filter clock 3 selected. */ +} lptmr_prescaler_clock_select_t; + +/*! @brief List of LPTMR interrupts */ +typedef enum _lptmr_interrupt_enable +{ + kLPTMR_TimerInterruptEnable = LPTMR_CSR_TIE_MASK, /*!< Timer interrupt enable */ +} lptmr_interrupt_enable_t; + +/*! @brief List of LPTMR status flags */ +typedef enum _lptmr_status_flags +{ + kLPTMR_TimerCompareFlag = LPTMR_CSR_TCF_MASK, /*!< Timer compare flag */ +} lptmr_status_flags_t; + +/*! + * @brief LPTMR config structure + * + * This structure holds the configuration settings for the LPTMR peripheral. To initialize this + * structure to reasonable defaults, call the LPTMR_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The config struct can be made const so it resides in flash + */ +typedef struct _lptmr_config +{ + lptmr_timer_mode_t timerMode; /*!< Time counter mode or pulse counter mode */ + lptmr_pin_select_t pinSelect; /*!< LPTMR pulse input pin select; used only in pulse counter mode */ + lptmr_pin_polarity_t pinPolarity; /*!< LPTMR pulse input pin polarity; used only in pulse counter mode */ + bool enableFreeRunning; /*!< true: enable free running, counter is reset on overflow + false: counter is reset when the compare flag is set */ + bool bypassPrescaler; /*!< true: bypass prescaler; false: use clock from prescaler */ + lptmr_prescaler_clock_select_t prescalerClockSource; /*!< LPTMR clock source */ + lptmr_prescaler_glitch_value_t value; /*!< Prescaler or glitch filter value */ +} lptmr_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungate the LPTMR clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application using the LPTMR driver. + * + * @param base LPTMR peripheral base address + * @param config Pointer to user's LPTMR config structure. + */ +void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config); + +/*! + * @brief Gate the LPTMR clock + * + * @param base LPTMR peripheral base address + */ +void LPTMR_Deinit(LPTMR_Type *base); + +/*! + * @brief Fill in the LPTMR config struct with the default settings + * + * The default values are: + * @code + * config->timerMode = kLPTMR_TimerModeTimeCounter; + * config->pinSelect = kLPTMR_PinSelectInput_0; + * config->pinPolarity = kLPTMR_PinPolarityActiveHigh; + * config->enableFreeRunning = false; + * config->bypassPrescaler = true; + * config->prescalerClockSource = kLPTMR_PrescalerClock_1; + * config->value = kLPTMR_Prescale_Glitch_0; + * @endcode + * @param config Pointer to user's LPTMR config structure. + */ +void LPTMR_GetDefaultConfig(lptmr_config_t *config); + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected LPTMR interrupts. + * + * @param base LPTMR peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::lptmr_interrupt_enable_t + */ +static inline void LPTMR_EnableInterrupts(LPTMR_Type *base, uint32_t mask) +{ + base->CSR |= mask; +} + +/*! + * @brief Disables the selected LPTMR interrupts. + * + * @param base LPTMR peripheral base address + * @param mask The interrupts to disable. This is a logical OR of members of the + * enumeration ::lptmr_interrupt_enable_t + */ +static inline void LPTMR_DisableInterrupts(LPTMR_Type *base, uint32_t mask) +{ + base->CSR &= ~mask; +} + +/*! + * @brief Gets the enabled LPTMR interrupts. + * + * @param base LPTMR peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::lptmr_interrupt_enable_t + */ +static inline uint32_t LPTMR_GetEnabledInterrupts(LPTMR_Type *base) +{ + return (base->CSR & LPTMR_CSR_TIE_MASK); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the LPTMR status flags + * + * @param base LPTMR peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::lptmr_status_flags_t + */ +static inline uint32_t LPTMR_GetStatusFlags(LPTMR_Type *base) +{ + return (base->CSR & LPTMR_CSR_TCF_MASK); +} + +/*! + * @brief Clears the LPTMR status flags + * + * @param base LPTMR peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::lptmr_status_flags_t + */ +static inline void LPTMR_ClearStatusFlags(LPTMR_Type *base, uint32_t mask) +{ + base->CSR |= mask; +} + +/*! @}*/ + +/*! + * @name Read and Write the timer period + * @{ + */ + +/*! + * @brief Sets the timer period in units of count. + * + * Timers counts from 0 till it equals the count value set here. The count value is written to + * the CMR register. + * + * @note + * 1. The TCF flag is set with the CNR equals the count provided here and then increments. + * 2. User can call the utility macros provided in fsl_common.h to convert to ticks + * + * @param base LPTMR peripheral base address + * @param ticks Timer period in units of ticks + */ +static inline void LPTMR_SetTimerPeriod(LPTMR_Type *base, uint16_t ticks) +{ + base->CMR = ticks; +} + +/*! + * @brief Reads the current timer counting value. + * + * This function returns the real-time timer counting value, in a range from 0 to a + * timer period. + * + * @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec + * + * @param base LPTMR peripheral base address + * + * @return Current counter value in ticks + */ +static inline uint16_t LPTMR_GetCurrentTimerCount(LPTMR_Type *base) +{ + /* Must first write any value to the CNR. This will synchronize and register the current value + * of the CNR into a temporary register which can then be read + */ + base->CNR = 0U; + return (uint16_t)base->CNR; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the timer counting. + * + * After calling this function, the timer counts up to the CMR register value. + * Each time the timer reaches CMR value and then increments, it generates a + * trigger pulse and sets the timeout interrupt flag. An interrupt will also be + * triggered if the timer interrupt is enabled. + * + * @param base LPTMR peripheral base address + */ +static inline void LPTMR_StartTimer(LPTMR_Type *base) +{ + base->CSR |= LPTMR_CSR_TEN_MASK; +} + +/*! + * @brief Stops the timer counting. + * + * This function stops the timer counting and resets the timer's counter register + * + * @param base LPTMR peripheral base address + */ +static inline void LPTMR_StopTimer(LPTMR_Type *base) +{ + base->CSR &= ~LPTMR_CSR_TEN_MASK; +} + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LPTMR_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart.c new file mode 100644 index 0000000000..b1b015f6f4 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart.c @@ -0,0 +1,1103 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_lpuart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* LPUART transfer state. */ +enum _lpuart_transfer_states +{ + kLPUART_TxIdle, /*!< TX idle. */ + kLPUART_TxBusy, /*!< TX busy. */ + kLPUART_RxIdle, /*!< RX idle. */ + kLPUART_RxBusy /*!< RX busy. */ +}; + +/* Typedef for interrupt handler. */ +typedef void (*lpuart_isr_t)(LPUART_Type *base, lpuart_handle_t *handle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get the LPUART instance from peripheral base address. + * + * @param base LPUART peripheral base address. + * @return LPUART instance. + */ +uint32_t LPUART_GetInstance(LPUART_Type *base); + +/*! + * @brief Get the length of received data in RX ring buffer. + * + * @userData handle LPUART handle pointer. + * @return Length of received data in RX ring buffer. + */ +static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Check whether the RX ring buffer is full. + * + * @userData handle LPUART handle pointer. + * @retval true RX ring buffer is full. + * @retval false RX ring buffer is not full. + */ +static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Write to TX register using non-blocking method. + * + * This function writes data to the TX register directly, upper layer must make + * sure the TX register is empty or TX FIFO has empty room before calling this function. + * + * @note This function does not check whether all the data has been sent out to bus, + * so before disable TX, check kLPUART_TransmissionCompleteFlag to ensure the TX is + * finished. + * + * @param base LPUART peripheral base address. + * @param data Start addresss of the data to write. + * @param length Size of the buffer to be sent. + */ +static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length); + +/*! + * @brief Read RX register using non-blocking method. + * + * This function reads data from the TX register directly, upper layer must make + * sure the RX register is full or TX FIFO has data before calling this function. + * + * @param base LPUART peripheral base address. + * @param data Start addresss of the buffer to store the received data. + * @param length Size of the buffer. + */ +static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Array of LPUART handle. */ +static lpuart_handle_t *s_lpuartHandle[FSL_FEATURE_SOC_LPUART_COUNT]; +/* Array of LPUART peripheral base address. */ +static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS; +/* Array of LPUART IRQ number. */ +static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS; +/* Array of LPUART clock name. */ +static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS; +/* LPUART ISR for transactional APIs. */ +static lpuart_isr_t s_lpuartIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +uint32_t LPUART_GetInstance(LPUART_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_LPUART_COUNT; instance++) + { + if (s_lpuartBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_LPUART_COUNT); + + return instance; +} + +static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle) +{ + size_t size; + + if (handle->rxRingBufferTail > handle->rxRingBufferHead) + { + size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); + } + else + { + size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); + } + + return size; +} + +static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle) +{ + bool full; + + if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U)) + { + full = true; + } + else + { + full = false; + } + return full; +} + +static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length) +{ + size_t i; + + /* The Non Blocking write data API assume user have ensured there is enough space in + peripheral to write. */ + for (i = 0; i < length; i++) + { + base->DATA = data[i]; + } +} + +static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length) +{ + size_t i; + + /* The Non Blocking read data API assume user have ensured there is enough space in + peripheral to write. */ + for (i = 0; i < length; i++) + { + data[i] = base->DATA; + } +} + +void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz) +{ + assert(config); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark); + assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark); +#endif + uint32_t temp; + uint16_t sbr, sbrTemp; + uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; + + /* Enable lpuart clock */ + CLOCK_EnableClock(s_lpuartClock[LPUART_GetInstance(base)]); + + /* Disable LPUART TX RX before setting. */ + base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); + + /* This LPUART instantiation uses a slightly different baud rate calculation + * The idea is to use the best OSR (over-sampling rate) possible + * Note, OSR is typically hard-set to 16 in other LPUART instantiations + * loop to find the best OSR value possible, one that generates minimum baudDiff + * iterate through the rest of the supported values of OSR */ + + baudDiff = config->baudRate_Bps; + osr = 0; + sbr = 0; + for (osrTemp = 4; osrTemp <= 32; osrTemp++) + { + /* calculate the temporary sbr value */ + sbrTemp = (srcClock_Hz / (config->baudRate_Bps * osrTemp)); + /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ + if (sbrTemp == 0) + { + sbrTemp = 1; + } + /* Calculate the baud rate based on the temporary OSR and SBR values */ + calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp)); + + tempDiff = calculatedBaud - config->baudRate_Bps; + + /* Select the better value between srb and (sbr + 1) */ + if (tempDiff > (config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))))) + { + tempDiff = config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))); + sbrTemp++; + } + + if (tempDiff <= baudDiff) + { + baudDiff = tempDiff; + osr = osrTemp; /* update and store the best OSR value calculated */ + sbr = sbrTemp; /* update store the best SBR value calculated */ + } + } + + /* Check to see if actual baud rate is within 3% of desired baud rate + * based on the best calculate OSR value */ + if (baudDiff < ((config->baudRate_Bps / 100) * 3)) + { + temp = base->BAUD; + + /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. + * If so, then "BOTHEDGE" sampling must be turned on */ + if ((osr > 3) && (osr < 8)) + { + temp |= LPUART_BAUD_BOTHEDGE_MASK; + } + + /* program the osr value (bit value is one less than actual value) */ + temp &= ~LPUART_BAUD_OSR_MASK; + temp |= LPUART_BAUD_OSR(osr - 1); + + /* write the sbr value to the BAUD registers */ + temp &= ~LPUART_BAUD_SBR_MASK; + base->BAUD = temp | LPUART_BAUD_SBR(sbr); + } + + /* Set bit count and parity mode. */ + base->BAUD &= ~LPUART_BAUD_M10_MASK; + + temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK); + + if (kLPUART_ParityDisabled != config->parityMode) + { + temp |= (LPUART_CTRL_M_MASK | (uint8_t)config->parityMode); + } + + base->CTRL = temp; + +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + /* set stop bit per char */ + temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK; + base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount); +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Set tx/rx WATER watermark */ + base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16) | config->txFifoWatermark); + + /* Enable tx/rx FIFO */ + base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK); + + /* Flush FIFO */ + base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK); +#endif + + /* Clear all status flags */ + temp = (LPUART_STAT_LBKDIF_MASK | LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); + +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp |= LPUART_STAT_IDLE_MASK; +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); +#endif + + base->STAT |= temp; + + /* Enable TX/RX base on configure structure. */ + temp = base->CTRL; + if (config->enableTx) + { + temp |= LPUART_CTRL_TE_MASK; + } + + if (config->enableRx) + { + temp |= LPUART_CTRL_RE_MASK; + } + + base->CTRL = temp; +} +void LPUART_Deinit(LPUART_Type *base) +{ + uint32_t temp; + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Wait tx FIFO send out*/ + while (0 != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT)) + { + } +#endif + /* Wait last char shoft out */ + while (0 == (base->STAT & LPUART_STAT_TC_MASK)) + { + } + + /* Clear all status flags */ + temp = (LPUART_STAT_LBKDIF_MASK | LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); + +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp |= LPUART_STAT_IDLE_MASK; +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); +#endif + + base->STAT |= temp; + + /* Disable the module. */ + base->CTRL = 0; + + /* Disable lpuart clock */ + CLOCK_DisableClock(s_lpuartClock[LPUART_GetInstance(base)]); +} + +void LPUART_GetDefaultConfig(lpuart_config_t *config) +{ + assert(config); + config->baudRate_Bps = 115200U; + config->parityMode = kLPUART_ParityDisabled; +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + config->stopBitCount = kLPUART_OneStopBit; +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + config->txFifoWatermark = 0; + config->rxFifoWatermark = 0; +#endif + config->enableTx = false; + config->enableRx = false; +} + +void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + uint32_t temp, oldCtrl; + uint16_t sbr, sbrTemp; + uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; + + /* Store CTRL before disable Tx and Rx */ + oldCtrl = base->CTRL; + + /* Disable LPUART TX RX before setting. */ + base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); + + /* This LPUART instantiation uses a slightly different baud rate calculation + * The idea is to use the best OSR (over-sampling rate) possible + * Note, OSR is typically hard-set to 16 in other LPUART instantiations + * loop to find the best OSR value possible, one that generates minimum baudDiff + * iterate through the rest of the supported values of OSR */ + + baudDiff = baudRate_Bps; + osr = 0; + sbr = 0; + for (osrTemp = 4; osrTemp <= 32; osrTemp++) + { + /* calculate the temporary sbr value */ + sbrTemp = (srcClock_Hz / (baudRate_Bps * osrTemp)); + /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ + if (sbrTemp == 0) + { + sbrTemp = 1; + } + /* Calculate the baud rate based on the temporary OSR and SBR values */ + calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp)); + + tempDiff = calculatedBaud - baudRate_Bps; + + /* Select the better value between srb and (sbr + 1) */ + if (tempDiff > (baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))))) + { + tempDiff = baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))); + sbrTemp++; + } + + if (tempDiff <= baudDiff) + { + baudDiff = tempDiff; + osr = osrTemp; /* update and store the best OSR value calculated */ + sbr = sbrTemp; /* update store the best SBR value calculated */ + } + } + + /* Check to see if actual baud rate is within 3% of desired baud rate + * based on the best calculate OSR value */ + if (baudDiff < ((baudRate_Bps / 100) * 3)) + { + temp = base->BAUD; + + /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. + * If so, then "BOTHEDGE" sampling must be turned on */ + if ((osr > 3) && (osr < 8)) + { + temp |= LPUART_BAUD_BOTHEDGE_MASK; + } + + /* program the osr value (bit value is one less than actual value) */ + temp &= ~LPUART_BAUD_OSR_MASK; + temp |= LPUART_BAUD_OSR(osr - 1); + + /* write the sbr value to the BAUD registers */ + temp &= ~LPUART_BAUD_SBR_MASK; + base->BAUD = temp | LPUART_BAUD_SBR(sbr); + } + + /* Restore CTRL. */ + base->CTRL = oldCtrl; +} + +void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask) +{ + base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + base->FIFO |= ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); +#endif + mask &= 0xFFFFFF00U; + base->CTRL |= mask; +} + +void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask) +{ + base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + base->FIFO &= ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); +#endif + mask &= 0xFFFFFF00U; + base->CTRL &= ~mask; +} + +uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base) +{ + uint32_t temp; + temp = (base->BAUD & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)) >> 8; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp |= (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)) >> 8; +#endif + temp |= (base->CTRL & 0xFF0C000); + + return temp; +} + +uint32_t LPUART_GetStatusFlags(LPUART_Type *base) +{ + uint32_t temp; + temp = base->STAT; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp |= (base->FIFO & + (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >> + 16; +#endif + return temp; +} + +status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask) +{ + uint32_t temp; + status_t status; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp = (uint32_t)base->FIFO; + temp &= (uint32_t)(~(kLPUART_TxFifoOverflowFlag | kLPUART_RxFifoUnderflowFlag)); + temp |= mask & (kLPUART_TxFifoOverflowFlag | kLPUART_RxFifoUnderflowFlag); + base->FIFO = temp; +#endif + temp = (uint32_t)base->STAT; +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp &= (uint32_t)(~(kLPUART_LinBreakFlag)); + temp |= mask & kLPUART_LinBreakFlag; +#endif + temp &= (uint32_t)(~(kLPUART_RxActiveEdgeFlag | kLPUART_IdleLineFlag | kLPUART_RxOverrunFlag | + kLPUART_NoiseErrorFlag | kLPUART_FramingErrorFlag | kLPUART_ParityErrorFlag)); + temp |= mask & (kLPUART_RxActiveEdgeFlag | kLPUART_IdleLineFlag | kLPUART_RxOverrunFlag | kLPUART_NoiseErrorFlag | + kLPUART_FramingErrorFlag | kLPUART_ParityErrorFlag); +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp &= (uint32_t)(~(kLPUART_DataMatch2Flag | kLPUART_DataMatch2Flag)); + temp |= mask & (kLPUART_DataMatch2Flag | kLPUART_DataMatch2Flag); +#endif + base->STAT |= temp; + /* If some flags still pending. */ + if (mask & LPUART_GetStatusFlags(base)) + { + /* Some flags can only clear or set by the hardware itself, these flags are: kLPUART_TxDataRegEmptyFlag, + kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, kLPUART_RxActiveFlag, + kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, + kLPUART_TxFifoEmptyFlag, kLPUART_RxFifoEmptyFlag. */ + status = kStatus_LPUART_FlagCannotClearManually; /* flags can not clear manually */ + } + else + { + status = kStatus_Success; + } + + return status; +} + +void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length) +{ + /* This API can only ensure that the data is written into the data buffer but can't + ensure all data in the data buffer are sent into the transmit shift buffer. */ + while (length--) + { + while (!(base->STAT & LPUART_STAT_TDRE_MASK)) + { + } + base->DATA = *(data++); + } +} + +status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length) +{ + uint32_t statusFlag; + + while (length--) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + while (0 == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)) +#else + while (!(base->STAT & LPUART_STAT_RDRF_MASK)) +#endif + { + statusFlag = LPUART_GetStatusFlags(base); + + if (statusFlag & kLPUART_RxOverrunFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag); + return kStatus_LPUART_RxHardwareOverrun; + } + + if (statusFlag & kLPUART_NoiseErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_NoiseErrorFlag); + return kStatus_LPUART_NoiseError; + } + + if (statusFlag & kLPUART_FramingErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_FramingErrorFlag); + return kStatus_LPUART_FramingError; + } + + if (statusFlag & kLPUART_ParityErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_ParityErrorFlag); + return kStatus_LPUART_ParityError; + } + } + *(data++) = base->DATA; + } + + return kStatus_Success; +} + +void LPUART_TransferCreateHandle(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + uint32_t instance; + + /* Zero the handle. */ + memset(handle, 0, sizeof(lpuart_handle_t)); + + /* Set the TX/RX state. */ + handle->rxState = kLPUART_RxIdle; + handle->txState = kLPUART_TxIdle; + + /* Set the callback and user data. */ + handle->callback = callback; + handle->userData = userData; + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Note: + Take care of the RX FIFO, RX interrupt request only assert when received bytes + equal or more than RX water mark, there is potential issue if RX water + mark larger than 1. + For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and + 5 bytes are received. the last byte will be saved in FIFO but not trigger + RX interrupt because the water mark is 2. + */ + base->WATER &= (~LPUART_WATER_RXWATER_SHIFT); +#endif + + /* Get instance from peripheral base address. */ + instance = LPUART_GetInstance(base); + + /* Save the handle in global variables to support the double weak mechanism. */ + s_lpuartHandle[instance] = handle; + + s_lpuartIsr = LPUART_TransferHandleIRQ; + + /* Enable interrupt in NVIC. */ + EnableIRQ(s_lpuartIRQ[instance]); +} + +void LPUART_TransferStartRingBuffer(LPUART_Type *base, + lpuart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize) +{ + assert(handle); + + /* Setup the ring buffer address */ + if (ringBuffer) + { + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; + + /* Enable the interrupt to accept the data when user need the ring buffer. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } +} + +void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + if (handle->rxState == kLPUART_RxIdle) + { + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + + handle->rxRingBuffer = NULL; + handle->rxRingBufferSize = 0U; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; +} + +status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer) +{ + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* Return error if current TX busy. */ + if (kLPUART_TxBusy == handle->txState) + { + status = kStatus_LPUART_TxBusy; + } + else + { + handle->txData = xfer->data; + handle->txDataSize = xfer->dataSize; + handle->txDataSizeAll = xfer->dataSize; + handle->txState = kLPUART_TxBusy; + + /* Enable transmiter interrupt. */ + LPUART_EnableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable); + + status = kStatus_Success; + } + + return status; +} + +void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle) +{ + LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable); + + handle->txDataSize = 0; + handle->txState = kLPUART_TxIdle; +} + +status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) +{ + if (kLPUART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->txDataSizeAll - handle->txDataSize; + + return kStatus_Success; +} + +status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_t *xfer, + size_t *receivedBytes) +{ + uint32_t i; + status_t status; + /* How many bytes to copy from ring buffer to user memory. */ + size_t bytesToCopy = 0U; + /* How many bytes to receive. */ + size_t bytesToReceive; + /* How many bytes currently have received. */ + size_t bytesCurrentReceived; + uint32_t regPrimask = 0U; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* How to get data: + 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize + to lpuart handle, enable interrupt to store received data to xfer->data. When + all data received, trigger callback. + 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. + If there are enough data in ring buffer, copy them to xfer->data and return. + If there are not enough data in ring buffer, copy all of them to xfer->data, + save the xfer->data remained empty space to lpuart handle, receive data + to this empty space and trigger callback when finished. */ + + if (kLPUART_RxBusy == handle->rxState) + { + status = kStatus_LPUART_RxBusy; + } + else + { + bytesToReceive = xfer->dataSize; + bytesCurrentReceived = 0; + + /* If RX ring buffer is used. */ + if (handle->rxRingBuffer) + { + /* Disable IRQ, protect ring buffer. */ + regPrimask = DisableGlobalIRQ(); + + /* How many bytes in RX ring buffer currently. */ + bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle); + + if (bytesToCopy) + { + bytesToCopy = MIN(bytesToReceive, bytesToCopy); + + bytesToReceive -= bytesToCopy; + + /* Copy data from ring buffer to user memory. */ + for (i = 0U; i < bytesToCopy; i++) + { + xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; + + /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + } + + /* If ring buffer does not have enough data, still need to read more data. */ + if (bytesToReceive) + { + /* No data in ring buffer, save the request to LPUART handle. */ + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kLPUART_RxBusy; + } + /* Enable IRQ if previously enabled. */ + EnableGlobalIRQ(regPrimask); + + /* Call user callback since all data are received. */ + if (0 == bytesToReceive) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); + } + } + } + /* Ring buffer not used. */ + else + { + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kLPUART_RxBusy; + + /* Enable RX interrupt. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + + /* Return the how many bytes have read. */ + if (receivedBytes) + { + *receivedBytes = bytesCurrentReceived; + } + + status = kStatus_Success; + } + + return status; +} + +void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle) +{ + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ + if (!handle->rxRingBuffer) + { + /* Disable RX interrupt. */ + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + + handle->rxDataSize = 0U; + handle->rxState = kLPUART_RxIdle; +} + +status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) +{ + if (kLPUART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->rxDataSizeAll - handle->rxDataSize; + + return kStatus_Success; +} + +void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle) +{ + uint8_t count; + uint8_t tempCount; + volatile uint8_t dummy; + + assert(handle); + + /* If RX overrun. */ + if (LPUART_STAT_OR_MASK & base->STAT) + { + /* Read base->DATA, otherwise the RX does not work. */ + dummy = base->DATA; + /* Avoid optimization */ + dummy++; + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData); + } + } + + /* Receive data register full */ + if ((LPUART_STAT_RDRF_MASK & base->STAT) && (LPUART_CTRL_RIE_MASK & base->CTRL)) + { +/* Get the size that can be stored into buffer for this interrupt. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)); +#else + count = 1; +#endif + + /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ + while ((count) && (handle->rxDataSize)) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + tempCount = MIN(handle->rxDataSize, count); +#else + tempCount = 1; +#endif + + /* Using non block API to read the data from the registers. */ + LPUART_ReadNonBlocking(base, handle->rxData, tempCount); + handle->rxData += tempCount; + handle->rxDataSize -= tempCount; + count -= tempCount; + + /* If all the data required for upper layer is ready, trigger callback. */ + if (!handle->rxDataSize) + { + handle->rxState = kLPUART_RxIdle; + + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); + } + } + } + + /* If use RX ring buffer, receive data to ring buffer. */ + if (handle->rxRingBuffer) + { + while (count--) + { + /* If RX ring buffer is full, trigger callback to notify over run. */ + if (LPUART_TransferIsRxRingBufferFull(base, handle)) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData); + } + } + + /* If ring buffer is still full after callback function, the oldest data is overrided. */ + if (LPUART_TransferIsRxRingBufferFull(base, handle)) + { + /* Increase handle->rxRingBufferTail to make room for new data. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + + /* Read data. */ + handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; + + /* Increase handle->rxRingBufferHead. */ + if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferHead = 0U; + } + else + { + handle->rxRingBufferHead++; + } + } + } + /* If no receive requst pending, stop RX interrupt. */ + else if (!handle->rxDataSize) + { + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + else + { + } + } + + /* Send data register empty and the interrupt is enabled. */ + if ((base->STAT & LPUART_STAT_TDRE_MASK) && (base->CTRL & LPUART_CTRL_TIE_MASK)) + { +/* Get the bytes that available at this moment. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + count = FSL_FEATURE_LPUART_FIFO_SIZEn(base) - + ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT); +#else + count = 1; +#endif + + while ((count) && (handle->txDataSize)) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + tempCount = MIN(handle->txDataSize, count); +#else + tempCount = 1; +#endif + + /* Using non block API to write the data to the registers. */ + LPUART_WriteNonBlocking(base, handle->txData, tempCount); + handle->txData += tempCount; + handle->txDataSize -= tempCount; + count -= tempCount; + + /* If all the data are written to data register, notify user with the callback, then TX finished. */ + if (!handle->txDataSize) + { + handle->txState = kLPUART_TxIdle; + + /* Disable TX register empty interrupt. */ + base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData); + } + } + } + } +} + +void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle) +{ + /* TODO: To be implemented. */ +} + +#if defined(LPUART0) +void LPUART0_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +} +void LPUART0_RX_TX_DriverIRQHandler(void) +{ + LPUART0_DriverIRQHandler(); +} +#endif + +#if defined(LPUART1) +void LPUART1_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +} +void LPUART1_RX_TX_DriverIRQHandler(void) +{ + LPUART1_DriverIRQHandler(); +} +#endif + +#if defined(LPUART2) +void LPUART2_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +} +void LPUART2_RX_TX_DriverIRQHandler(void) +{ + LPUART2_DriverIRQHandler(); +} +#endif + +#if defined(LPUART3) +void LPUART3_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +} +void LPUART3_RX_TX_DriverIRQHandler(void) +{ + LPUART3_DriverIRQHandler(); +} +#endif + +#if defined(LPUART4) +void LPUART4_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +} +void LPUART4_RX_TX_DriverIRQHandler(void) +{ + LPUART4_DriverIRQHandler(); +} +#endif + +#if defined(LPUART5) +void LPUART5_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +} +void LPUART5_RX_TX_DriverIRQHandler(void) +{ + LPUART5_DriverIRQHandler(); +} +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart.h new file mode 100644 index 0000000000..a357400b56 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart.h @@ -0,0 +1,753 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LPUART_H_ +#define _FSL_LPUART_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lpuart_driver + * @{ + */ + +/*! @file*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LPUART driver version 2.1.0. */ +#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief Error codes for the LPUART driver. */ +enum _lpuart_status +{ + kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */ + kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */ + kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */ + kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */ + kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */ + kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */ + kStatus_LPUART_FlagCannotClearManually = + MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */ + kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */ + kStatus_LPUART_RxRingBufferOverrun = + MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */ + kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */ + kStatus_LPUART_NoiseError = MAKE_STATUS(kStatusGroup_LPUART, 10), /*!< LPUART noise error. */ + kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */ + kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */ +}; + +/*! @brief LPUART parity mode. */ +typedef enum _lpuart_parity_mode +{ + kLPUART_ParityDisabled = 0x0U, /*!< Parity disabled */ + kLPUART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */ + kLPUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */ +} lpuart_parity_mode_t; + +/*! @brief LPUART stop bit count. */ +typedef enum _lpuart_stop_bit_count +{ + kLPUART_OneStopBit = 0U, /*!< One stop bit */ + kLPUART_TwoStopBit = 1U, /*!< Two stop bits */ +} lpuart_stop_bit_count_t; + +/*! + * @brief LPUART interrupt configuration structure, default settings all disabled. + * + * This structure contains the settings for all LPUART interrupt configurations. + */ +enum _lpuart_interrupt_enable +{ +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + kLPUART_LinBreakInterruptEnable = (LPUART_BAUD_LBKDIE_MASK >> 8), /*!< LIN break detect. */ +#endif + kLPUART_RxActiveEdgeInterruptEnable = (LPUART_BAUD_RXEDGIE_MASK >> 8), /*!< Receive Active Edge. */ + kLPUART_TxDataRegEmptyInterruptEnable = (LPUART_CTRL_TIE_MASK), /*!< Transmit data register empty. */ + kLPUART_TransmissionCompleteInterruptEnable = (LPUART_CTRL_TCIE_MASK), /*!< Transmission complete. */ + kLPUART_RxDataRegFullInterruptEnable = (LPUART_CTRL_RIE_MASK), /*!< Receiver data register full. */ + kLPUART_IdleLineInterruptEnable = (LPUART_CTRL_ILIE_MASK), /*!< Idle line. */ + kLPUART_RxOverrunInterruptEnable = (LPUART_CTRL_ORIE_MASK), /*!< Receiver Overrun. */ + kLPUART_NoiseErrorInterruptEnable = (LPUART_CTRL_NEIE_MASK), /*!< Noise error flag. */ + kLPUART_FramingErrorInterruptEnable = (LPUART_CTRL_FEIE_MASK), /*!< Framing error flag. */ + kLPUART_ParityErrorInterruptEnable = (LPUART_CTRL_PEIE_MASK), /*!< Parity error flag. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + kLPUART_TxFifoOverflowInterruptEnable = (LPUART_FIFO_TXOFE_MASK >> 8), /*!< Transmit FIFO Overflow. */ + kLPUART_RxFifoUnderflowInterruptEnable = (LPUART_FIFO_RXUFE_MASK >> 8), /*!< Receive FIFO Underflow. */ +#endif +}; + +/*! + * @brief LPUART status flags. + * + * This provides constants for the LPUART status flags for use in the LPUART functions. + */ +enum _lpuart_flags +{ + kLPUART_TxDataRegEmptyFlag = + (LPUART_STAT_TDRE_MASK), /*!< Transmit data register empty flag, sets when transmit buffer is empty */ + kLPUART_TransmissionCompleteFlag = + (LPUART_STAT_TC_MASK), /*!< Transmission complete flag, sets when transmission activity complete */ + kLPUART_RxDataRegFullFlag = + (LPUART_STAT_RDRF_MASK), /*!< Receive data register full flag, sets when the receive data buffer is full */ + kLPUART_IdleLineFlag = (LPUART_STAT_IDLE_MASK), /*!< Idle line detect flag, sets when idle line detected */ + kLPUART_RxOverrunFlag = (LPUART_STAT_OR_MASK), /*!< Receive Overrun, sets when new data is received before data is + read from receive register */ + kLPUART_NoiseErrorFlag = (LPUART_STAT_NF_MASK), /*!< Receive takes 3 samples of each received bit. If any of these + samples differ, noise flag sets */ + kLPUART_FramingErrorFlag = + (LPUART_STAT_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected where stop bit expected */ + kLPUART_ParityErrorFlag = (LPUART_STAT_PF_MASK), /*!< If parity enabled, sets upon parity error detection */ +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + kLPUART_LinBreakFlag = (LPUART_STAT_LBKDIF_MASK), /*!< LIN break detect interrupt flag, sets when LIN break char + detected and LIN circuit enabled */ +#endif + kLPUART_RxActiveEdgeFlag = + (LPUART_STAT_RXEDGIF_MASK), /*!< Receive pin active edge interrupt flag, sets when active edge detected */ + kLPUART_RxActiveFlag = + (LPUART_STAT_RAF_MASK), /*!< Receiver Active Flag (RAF), sets at beginning of valid start bit */ +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + kLPUART_DataMatch1Flag = LPUART_STAT_MA1F_MASK, /*!< The next character to be read from LPUART_DATA matches MA1*/ + kLPUART_DataMatch2Flag = LPUART_STAT_MA2F_MASK, /*!< The next character to be read from LPUART_DATA matches MA2*/ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS + kLPUART_NoiseErrorInRxDataRegFlag = + (LPUART_DATA_NOISY_MASK >> 10), /*!< NOISY bit, sets if noise detected in current data word */ + kLPUART_ParityErrorInRxDataRegFlag = + (LPUART_DATA_PARITYE_MASK >> 10), /*!< PARITYE bit, sets if noise detected in current data word */ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + kLPUART_TxFifoEmptyFlag = (LPUART_FIFO_TXEMPT_MASK >> 16), /*!< TXEMPT bit, sets if transmit buffer is empty */ + kLPUART_RxFifoEmptyFlag = (LPUART_FIFO_RXEMPT_MASK >> 16), /*!< RXEMPT bit, sets if receive buffer is empty */ + kLPUART_TxFifoOverflowFlag = + (LPUART_FIFO_TXOF_MASK >> 16), /*!< TXOF bit, sets if transmit buffer overflow occurred */ + kLPUART_RxFifoUnderflowFlag = + (LPUART_FIFO_RXUF_MASK >> 16), /*!< RXUF bit, sets if receive buffer underflow occurred */ +#endif +}; + +/*! @brief LPUART configure structure. */ +typedef struct _lpuart_config +{ + uint32_t baudRate_Bps; /*!< LPUART baud rate */ + lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + uint8_t txFifoWatermark; /*!< TX FIFO watermark */ + uint8_t rxFifoWatermark; /*!< RX FIFO watermark */ +#endif + bool enableTx; /*!< Enable TX */ + bool enableRx; /*!< Enable RX */ +} lpuart_config_t; + +/*! @brief LPUART transfer structure. */ +typedef struct _lpuart_transfer +{ + uint8_t *data; /*!< The buffer of data to be transfer.*/ + size_t dataSize; /*!< The byte count to be transfer. */ +} lpuart_transfer_t; + +/* Forward declaration of the handle typedef. */ +typedef struct _lpuart_handle lpuart_handle_t; + +/*! @brief LPUART transfer callback function. */ +typedef void (*lpuart_transfer_callback_t)(LPUART_Type *base, lpuart_handle_t *handle, status_t status, void *userData); + +/*! @brief LPUART handle structure. */ +struct _lpuart_handle +{ + uint8_t *volatile txData; /*!< Address of remaining data to send. */ + volatile size_t txDataSize; /*!< Size of the remaining data to send. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ + volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + + uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ + size_t rxRingBufferSize; /*!< Size of the ring buffer. */ + volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ + volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ + + lpuart_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< LPUART callback function parameter.*/ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! +* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. +* +* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function +* to configure the configuration structure and get the default configuration. +* The example below shows how to use this API to configure the LPUART. +* @code +* lpuart_config_t lpuartConfig; +* lpuartConfig.baudRate_Bps = 115200U; +* lpuartConfig.parityMode = kLPUART_ParityDisabled; +* lpuartConfig.stopBitCount = kLPUART_OneStopBit; +* lpuartConfig.txFifoWatermark = 0; +* lpuartConfig.rxFifoWatermark = 1; +* LPUART_Init(LPUART1, &lpuartConfig, 20000000U); +* @endcode +* +* @param base LPUART peripheral base address. +* @param config Pointer to a user-defined configuration structure. +* @param srcClock_Hz LPUART clock source frequency in HZ. +*/ +void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Deinitializes a LPUART instance. + * + * This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock. + * + * @param base LPUART peripheral base address. + */ +void LPUART_Deinit(LPUART_Type *base); + +/*! + * @brief Gets the default configuration structure. + * + * This function initializes the LPUART configuration structure to a default value. The default + * values are: + * lpuartConfig->baudRate_Bps = 115200U; + * lpuartConfig->parityMode = kLPUART_ParityDisabled; + * lpuartConfig->stopBitCount = kLPUART_OneStopBit; + * lpuartConfig->txFifoWatermark = 0; + * lpuartConfig->rxFifoWatermark = 1; + * lpuartConfig->enableTx = false; + * lpuartConfig->enableRx = false; + * + * @param config Pointer to a configuration structure. + */ +void LPUART_GetDefaultConfig(lpuart_config_t *config); + +/*! + * @brief Sets the LPUART instance baudrate. + * + * This function configures the LPUART module baudrate. This function is used to update + * the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init. + * @code + * LPUART_SetBaudRate(LPUART1, 115200U, 20000000U); + * @endcode + * + * @param base LPUART peripheral base address. + * @param baudRate_Bps LPUART baudrate to be set. + * @param srcClock_Hz LPUART clock source frequency in HZ. + */ +void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets LPUART status flags. + * + * This function gets all LPUART status flags. The flags are returned as the logical + * OR value of the enumerators @ref _lpuart_flags. To check for a specific status, + * compare the return value with enumerators in the @ref _lpuart_flags. + * For example, to check whether the TX is empty: + * @code + * if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)) + * { + * ... + * } + * @endcode + * + * @param base LPUART peripheral base address. + * @return LPUART status flags which are ORed by the enumerators in the _lpuart_flags. + */ +uint32_t LPUART_GetStatusFlags(LPUART_Type *base); + +/*! + * @brief Clears status flags with a provided mask. + * + * This function clears LPUART status flags with a provided mask. Automatically cleared flags + * can't be cleared by this function. + * Flags that can only cleared or set by hardware are: + * kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, + * kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, + * kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag + * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. + * + * @param base LPUART peripheral base address. + * @param mask the status flags to be cleared. The user can use the enumerators in the + * _lpuart_status_flag_t to do the OR operation and get the mask. + * @return 0 succeed, others failed. + * @retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but + * it is cleared automatically by hardware. + * @retval kStatus_Success Status in the mask are cleared. + */ +status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables LPUART interrupts according to a provided mask. + * + * This function enables the LPUART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See the @ref _lpuart_interrupt_enable. + * This examples shows how to enable TX empty interrupt and RX full interrupt: + * @code + * LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); + * @endcode + * + * @param base LPUART peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable. + */ +void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask); + +/*! + * @brief Disables LPUART interrupts according to a provided mask. + * + * This function disables the LPUART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See @ref _lpuart_interrupt_enable. + * This example shows how to disable the TX empty interrupt and RX full interrupt: + * @code + * LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); + * @endcode + * + * @param base LPUART peripheral base address. + * @param mask The interrupts to disable. Logical OR of @ref _lpuart_interrupt_enable. + */ +void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask); + +/*! + * @brief Gets enabled LPUART interrupts. + * + * This function gets the enabled LPUART interrupts. The enabled interrupts are returned + * as the logical OR value of the enumerators @ref _lpuart_interrupt_enable. To check + * a specific interrupt enable status, compare the return value with enumerators + * in @ref _lpuart_interrupt_enable. + * For example, to check whether the TX empty interrupt is enabled: + * @code + * uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1); + * + * if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) + * { + * ... + * } + * @endcode + * + * @param base LPUART peripheral base address. + * @return LPUART interrupt flags which are logical OR of the enumerators in @ref _lpuart_interrupt_enable. + */ +uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base); + +#if defined(FSL_FEATURE_LPUART_HAS_DMA_ENABLE) && FSL_FEATURE_LPUART_HAS_DMA_ENABLE +/*! + * @brief Gets the LPUART data register address. + * + * This function returns the LPUART data register address, which is mainly used by the DMA/eDMA. + * + * @param base LPUART peripheral base address. + * @return LPUART data register addresses which are used both by the transmitter and receiver. + */ +static inline uint32_t LPUART_GetDataRegisterAddress(LPUART_Type *base) +{ + return (uint32_t) & (base->DATA); +} + +/*! + * @brief Enables or disables the LPUART transmitter DMA request. + * + * This function enables or disables the transmit data register empty flag, STAT[TDRE], to generate DMA requests. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableTxDMA(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->BAUD |= LPUART_BAUD_TDMAE_MASK; + base->CTRL |= LPUART_CTRL_TIE_MASK; + } + else + { + base->BAUD &= ~LPUART_BAUD_TDMAE_MASK; + base->CTRL &= ~LPUART_CTRL_TIE_MASK; + } +} + +/*! + * @brief Enables or disables the LPUART receiver DMA. + * + * This function enables or disables the receiver data register full flag, STAT[RDRF], to generate DMA requests. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableRxDMA(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->BAUD |= LPUART_BAUD_RDMAE_MASK; + base->CTRL |= LPUART_CTRL_RIE_MASK; + } + else + { + base->BAUD &= ~LPUART_BAUD_RDMAE_MASK; + base->CTRL &= ~LPUART_CTRL_RIE_MASK; + } +} + +/* @} */ +#endif /* FSL_FEATURE_LPUART_HAS_DMA_ENABLE */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Enables or disables the LPUART transmitter. + * + * This function enables or disables the LPUART transmitter. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableTx(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= LPUART_CTRL_TE_MASK; + } + else + { + base->CTRL &= ~LPUART_CTRL_TE_MASK; + } +} + +/*! + * @brief Enables or disables the LPUART receiver. + * + * This function enables or disables the LPUART receiver. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableRx(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= LPUART_CTRL_RE_MASK; + } + else + { + base->CTRL &= ~LPUART_CTRL_RE_MASK; + } +} + +/*! + * @brief Writes to the transmitter register. + * + * This function writes data to the transmitter register directly. The upper layer must + * ensure that the TX register is empty or that the TX FIFO has room before calling this function. + * + * @param base LPUART peripheral base address. + * @param data Data write to the TX register. + */ +static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data) +{ + base->DATA = data; +} + +/*! + * @brief Reads the RX register. + * + * This function reads data from the TX register directly. The upper layer must + * ensure that the RX register is full or that the TX FIFO has data before calling this function. + * + * @param base LPUART peripheral base address. + * @return Data read from data register. + */ +static inline uint8_t LPUART_ReadByte(LPUART_Type *base) +{ + return base->DATA; +} + +/*! + * @brief Writes to transmitter register using a blocking method. + * + * This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have + * room and then writes data to the transmitter buffer. + * + * @note This function does not check whether all data has been sent out to the bus. + * Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is + * finished. + * + * @param base LPUART peripheral base address. + * @param data Start address of the data to write. + * @param length Size of the data to write. + */ +void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length); + +/*! +* @brief Reads the RX data register using a blocking method. + * + * This function polls the RX register, waits for the RX register full or RX FIFO + * has data then reads data from the TX register. + * + * @param base LPUART peripheral base address. + * @param data Start address of the buffer to store the received data. + * @param length Size of the buffer. + * @retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data. + * @retval kStatus_LPUART_NoiseError Noise error happened while receiving data. + * @retval kStatus_LPUART_FramingError Framing error happened while receiving data. + * @retval kStatus_LPUART_ParityError Parity error happened while receiving data. + * @retval kStatus_Success Successfully received all data. + */ +status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the LPUART handle. + * + * This function initializes the LPUART handle, which can be used for other LPUART + * transactional APIs. Usually, for a specified LPUART instance, + * call this API once to get the initialized handle. + * + * The LPUART driver supports the "background" receiving, which means that user can set up + * an RX ring buffer optionally. Data received is stored into the ring buffer even when the + * user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * The ring buffer is disabled if passing NULL as @p ringBuffer. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +void LPUART_TransferCreateHandle(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_callback_t callback, + void *userData); +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function send data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data written to the transmitter register. When + * all data is written to the TX register in the ISR, the LPUART driver calls the callback + * function and passes the @ref kStatus_LPUART_TxIdle as status parameter. + * + * @note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written + * to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX, + * check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART transfer structure, refer to #lpuart_transfer_t. + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific UART handle. + * + * When the RX ring buffer is used, data received is stored into the ring buffer even when + * the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * + * @note When using RX ring buffer, one byte is reserved for internal use. In other + * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. + * @param ringBufferSize size of the ring buffer. + */ +void LPUART_TransferStartRingBuffer(LPUART_Type *base, + lpuart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize); + +/*! + * @brief Abort the background transfer and uninstall the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out + * how many bytes are still not sent out. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been written to LPUART TX register. + * + * This function gets the number of bytes that have been written to LPUART TX + * register by interrupt method. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count); + +/*! + * @brief Receives a buffer of data using the interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function + * which returns without waiting to ensure that all data are received. + * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and + * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in the ring buffer is not enough for read, the receive + * request is saved by the LPUART driver. When the new data arrives, the receive request + * is serviced first. When all data is received, the LPUART driver notifies the upper layer + * through a callback function and passes a status parameter @ref kStatus_UART_RxIdle. + * For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer. + * The 5 bytes are copied to xfer->data, which returns with the + * parameter @p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is + * saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to xfer->data. When all data is received, the upper layer is notified. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART transfer structure, refer to #uart_transfer_t. + * @param receivedBytes Bytes received from the ring buffer directly. + * @retval kStatus_Success Successfully queue the transfer into the transmit queue. + * @retval kStatus_LPUART_RxBusy Previous receive request is not finished. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_t *xfer, + size_t *receivedBytes); + +/*! + * @brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out + * how many bytes not received yet. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count); + +/*! + * @brief LPUART IRQ handle function. + * + * This function handles the LPUART transmit and receive IRQ request. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief LPUART Error IRQ handle function. + * + * This function handles the LPUART error IRQ request. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LPUART_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart_dma.c new file mode 100644 index 0000000000..f92e2ff204 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart_dma.c @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_lpuart_dma.h" +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*base, false); + + /* Disable interrupt. */ + DMA_DisableInterrupts(lpuartPrivateHandle->handle->txDmaHandle->base, + lpuartPrivateHandle->handle->txDmaHandle->channel); + + lpuartPrivateHandle->handle->txState = kLPUART_TxIdle; + + if (lpuartPrivateHandle->handle->callback) + { + lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle, + kStatus_LPUART_TxIdle, lpuartPrivateHandle->handle->userData); + } +} + +static void LPUART_TransferReceiveDMACallback(dma_handle_t *handle, void *param) +{ + lpuart_dma_private_handle_t *lpuartPrivateHandle = (lpuart_dma_private_handle_t *)param; + + /* Disable LPUART RX DMA. */ + LPUART_EnableRxDMA(lpuartPrivateHandle->base, false); + + /* Disable interrupt. */ + DMA_DisableInterrupts(lpuartPrivateHandle->handle->rxDmaHandle->base, + lpuartPrivateHandle->handle->rxDmaHandle->channel); + + lpuartPrivateHandle->handle->rxState = kLPUART_RxIdle; + + if (lpuartPrivateHandle->handle->callback) + { + lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle, + kStatus_LPUART_RxIdle, lpuartPrivateHandle->handle->userData); + } +} + +void LPUART_TransferCreateHandleDMA(LPUART_Type *base, + lpuart_dma_handle_t *handle, + lpuart_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txDmaHandle, + dma_handle_t *rxDmaHandle) +{ + assert(handle); + + uint32_t instance = LPUART_GetInstance(base); + + memset(handle, 0, sizeof(lpuart_dma_handle_t)); + + s_dmaPrivateHandle[instance].base = base; + s_dmaPrivateHandle[instance].handle = handle; + + handle->rxState = kLPUART_RxIdle; + handle->txState = kLPUART_TxIdle; + + handle->callback = callback; + handle->userData = userData; + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Note: + Take care of the RX FIFO, DMA request only assert when received bytes + equal or more than RX water mark, there is potential issue if RX water + mark larger than 1. + For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and + 5 bytes are received. the last byte will be saved in FIFO but not trigger + DMA transfer because the water mark is 2. + */ + if (rxDmaHandle) + { + base->WATER &= (~LPUART_WATER_RXWATER_MASK); + } +#endif + + handle->rxDmaHandle = rxDmaHandle; + handle->txDmaHandle = txDmaHandle; + + /* Configure TX. */ + if (txDmaHandle) + { + DMA_SetCallback(txDmaHandle, LPUART_TransferSendDMACallback, &s_dmaPrivateHandle[instance]); + } + + /* Configure RX. */ + if (rxDmaHandle) + { + DMA_SetCallback(rxDmaHandle, LPUART_TransferReceiveDMACallback, &s_dmaPrivateHandle[instance]); + } +} + +status_t LPUART_TransferSendDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, lpuart_transfer_t *xfer) +{ + assert(handle->txDmaHandle); + + status_t status; + dma_transfer_config_t xferConfig; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* If previous TX not finished. */ + if (kLPUART_TxBusy == handle->txState) + { + status = kStatus_LPUART_TxBusy; + } + else + { + handle->txState = kLPUART_TxBusy; + handle->txDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + DMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base), + sizeof(uint8_t), xfer->dataSize, kDMA_MemoryToPeripheral); + + /* Submit transfer. */ + DMA_SubmitTransfer(handle->txDmaHandle, &xferConfig, kDMA_EnableInterrupt); + DMA_StartTransfer(handle->txDmaHandle); + + /* Enable LPUART TX DMA. */ + LPUART_EnableTxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +status_t LPUART_TransferReceiveDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, lpuart_transfer_t *xfer) +{ + assert(handle->rxDmaHandle); + + status_t status; + dma_transfer_config_t xferConfig; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* If previous RX not finished. */ + if (kLPUART_RxBusy == handle->rxState) + { + status = kStatus_LPUART_RxBusy; + } + else + { + handle->rxState = kLPUART_RxBusy; + handle->rxDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + DMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data, + sizeof(uint8_t), xfer->dataSize, kDMA_PeripheralToMemory); + + /* Submit transfer. */ + DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig, kDMA_EnableInterrupt); + DMA_StartTransfer(handle->rxDmaHandle); + + /* Enable LPUART RX DMA. */ + LPUART_EnableRxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +void LPUART_TransferAbortSendDMA(LPUART_Type *base, lpuart_dma_handle_t *handle) +{ + assert(handle->txDmaHandle); + + /* Disable LPUART TX DMA. */ + LPUART_EnableTxDMA(base, false); + + /* Stop transfer. */ + DMA_AbortTransfer(handle->txDmaHandle); + + /* Write DMA->DSR[DONE] to abort transfer and clear status. */ + DMA_ClearChannelStatusFlags(handle->txDmaHandle->base, handle->txDmaHandle->channel, kDMA_TransactionsDoneFlag); + + handle->txState = kLPUART_TxIdle; +} + +void LPUART_TransferAbortReceiveDMA(LPUART_Type *base, lpuart_dma_handle_t *handle) +{ + assert(handle->rxDmaHandle); + + /* Disable LPUART RX DMA. */ + LPUART_EnableRxDMA(base, false); + + /* Stop transfer. */ + DMA_AbortTransfer(handle->rxDmaHandle); + + /* Write DMA->DSR[DONE] to abort transfer and clear status. */ + DMA_ClearChannelStatusFlags(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, kDMA_TransactionsDoneFlag); + + handle->rxState = kLPUART_RxIdle; +} + +status_t LPUART_TransferGetSendCountDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, uint32_t *count) +{ + assert(handle->txDmaHandle); + + if (kLPUART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->txDataSizeAll - DMA_GetRemainingBytes(handle->txDmaHandle->base, handle->txDmaHandle->channel); + + return kStatus_Success; +} + +status_t LPUART_TransferGetReceiveCountDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, uint32_t *count) +{ + assert(handle->rxDmaHandle); + + if (kLPUART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->rxDataSizeAll - DMA_GetRemainingBytes(handle->rxDmaHandle->base, handle->rxDmaHandle->channel); + + return kStatus_Success; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart_dma.h new file mode 100644 index 0000000000..c592d17ea3 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_lpuart_dma.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_LPUART_DMA_H_ +#define _FSL_LPUART_DMA_H_ + +#include "fsl_lpuart.h" +#include "fsl_dma.h" + +/*! + * @addtogroup lpuart_dma_driver + * @{ + */ + +/*! @file*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Forward declaration of the handle typedef. */ +typedef struct _lpuart_dma_handle lpuart_dma_handle_t; + +/*! @brief LPUART transfer callback function. */ +typedef void (*lpuart_dma_transfer_callback_t)(LPUART_Type *base, + lpuart_dma_handle_t *handle, + status_t status, + void *userData); + +/*! +* @brief LPUART DMA handle +*/ +struct _lpuart_dma_handle +{ + lpuart_dma_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< LPUART callback function parameter.*/ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + + dma_handle_t *txDmaHandle; /*!< The DMA TX channel used. */ + dma_handle_t *rxDmaHandle; /*!< The DMA RX channel used. */ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name EDMA transactional + * @{ + */ + +/*! + * @brief Initializes the LPUART handle which is used in transactional functions. + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_dma_handle_t structure. + * @param callback Callback function. + * @param userData User data. + * @param txDmaHandle User-requested DMA handle for TX DMA transfer. + * @param rxDmaHandle User-requested DMA handle for RX DMA transfer. + */ +void LPUART_TransferCreateHandleDMA(LPUART_Type *base, + lpuart_dma_handle_t *handle, + lpuart_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txDmaHandle, + dma_handle_t *rxDmaHandle); + +/*! + * @brief Sends data using DMA. + * + * This function sends data using DMA. This is a non-blocking function, which returns + * right away. When all data is sent, the send callback function is called. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART DMA transfer structure. See #lpuart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_LPUART_TxBusy Previous transfer on going. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferSendDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Receives data using DMA. + * + * This function receives data using DMA. This is a non-blocking function, which returns + * right away. When all data is received, the receive callback function is called. + * + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_dma_handle_t structure. + * @param xfer LPUART DMA transfer structure. See #lpuart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_LPUART_RxBusy Previous transfer on going. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferReceiveDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Aborts the sent data using DMA. + * + * This function aborts send data using DMA. + * + * @param base LPUART peripheral base address + * @param handle Pointer to lpuart_dma_handle_t structure + */ +void LPUART_TransferAbortSendDMA(LPUART_Type *base, lpuart_dma_handle_t *handle); + +/*! + * @brief Aborts the received data using DMA. + * + * This function aborts the received data using DMA. + * + * @param base LPUART peripheral base address + * @param handle Pointer to lpuart_dma_handle_t structure + */ +void LPUART_TransferAbortReceiveDMA(LPUART_Type *base, lpuart_dma_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been written to LPUART TX register. + * + * This function gets the number of bytes that have been written to LPUART TX + * register by DMA. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetSendCountDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, uint32_t *count); + +/*! + * @brief Get the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetReceiveCountDMA(LPUART_Type *base, lpuart_dma_handle_t *handle, uint32_t *count); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LPUART_DMA_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pit.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pit.c new file mode 100644 index 0000000000..1f2fdfe8b4 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pit.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_pit.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address to be used to gate or ungate the module clock + * + * @param base PIT peripheral base address + * + * @return The PIT instance + */ +static uint32_t PIT_GetInstance(PIT_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to PIT bases for each instance. */ +static PIT_Type *const s_pitBases[] = PIT_BASE_PTRS; + +/*! @brief Pointers to PIT clocks for each instance. */ +static const clock_ip_name_t s_pitClocks[] = PIT_CLOCKS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t PIT_GetInstance(PIT_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_PIT_COUNT; instance++) + { + if (s_pitBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_PIT_COUNT); + + return instance; +} + +void PIT_Init(PIT_Type *base, const pit_config_t *config) +{ + assert(config); + + /* Ungate the PIT clock*/ + CLOCK_EnableClock(s_pitClocks[PIT_GetInstance(base)]); + + /* Enable PIT timers */ + base->MCR &= ~PIT_MCR_MDIS_MASK; + + /* Config timer operation when in debug mode */ + if (config->enableRunInDebug) + { + base->MCR &= ~PIT_MCR_FRZ_MASK; + } + else + { + base->MCR |= PIT_MCR_FRZ_MASK; + } +} + +void PIT_Deinit(PIT_Type *base) +{ + /* Disable PIT timers */ + base->MCR |= PIT_MCR_MDIS_MASK; + + /* Gate the PIT clock*/ + CLOCK_DisableClock(s_pitClocks[PIT_GetInstance(base)]); +} + +#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER + +uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base) +{ + uint32_t valueH = 0U; + uint32_t valueL = 0U; + + /* LTMR64H should be read before LTMR64L */ + valueH = base->LTMR64H; + valueL = base->LTMR64L; + + return (((uint64_t)valueH << 32U) + (uint64_t)(valueL)); +} + +#endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pit.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pit.h new file mode 100644 index 0000000000..61606e7e8b --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pit.h @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_PIT_H_ +#define _FSL_PIT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup pit_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_PIT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! + * @brief List of PIT channels + * @note Actual number of available channels is SoC dependent + */ +typedef enum _pit_chnl +{ + kPIT_Chnl_0 = 0U, /*!< PIT channel number 0*/ + kPIT_Chnl_1, /*!< PIT channel number 1 */ + kPIT_Chnl_2, /*!< PIT channel number 2 */ + kPIT_Chnl_3, /*!< PIT channel number 3 */ +} pit_chnl_t; + +/*! @brief List of PIT interrupts */ +typedef enum _pit_interrupt_enable +{ + kPIT_TimerInterruptEnable = PIT_TCTRL_TIE_MASK, /*!< Timer interrupt enable*/ +} pit_interrupt_enable_t; + +/*! @brief List of PIT status flags */ +typedef enum _pit_status_flags +{ + kPIT_TimerFlag = PIT_TFLG_TIF_MASK, /*!< Timer flag */ +} pit_status_flags_t; + +/*! + * @brief PIT config structure + * + * This structure holds the configuration settings for the PIT peripheral. To initialize this + * structure to reasonable defaults, call the PIT_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The config struct can be made const so it resides in flash + */ +typedef struct _pit_config +{ + bool enableRunInDebug; /*!< true: Timers run in debug mode; false: Timers stop in debug mode */ +} pit_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the PIT clock, enables the PIT module and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application using the PIT driver. + * + * @param base PIT peripheral base address + * @param config Pointer to user's PIT config structure + */ +void PIT_Init(PIT_Type *base, const pit_config_t *config); + +/*! + * @brief Gate the PIT clock and disable the PIT module + * + * @param base PIT peripheral base address + */ +void PIT_Deinit(PIT_Type *base); + +/*! + * @brief Fill in the PIT config struct with the default settings + * + * The default values are: + * @code + * config->enableRunInDebug = false; + * @endcode + * @param config Pointer to user's PIT config structure. + */ +static inline void PIT_GetDefaultConfig(pit_config_t *config) +{ + assert(config); + + /* Timers are stopped in Debug mode */ + config->enableRunInDebug = false; +} + +#if defined(FSL_FEATURE_PIT_HAS_CHAIN_MODE) && FSL_FEATURE_PIT_HAS_CHAIN_MODE + +/*! + * @brief Enables or disables chaining a timer with the previous timer. + * + * When a timer has a chain mode enabled, it only counts after the previous + * timer has expired. If the timer n-1 has counted down to 0, counter n + * decrements the value by one. Each timer is 32-bits, this allows the developers + * to chain timers together and form a longer timer (64-bits and larger). The first timer + * (timer 0) cannot be chained to any other timer. + * + * @param base PIT peripheral base address + * @param channel Timer channel number which is chained with the previous timer + * @param enable Enable or disable chain. + * true: Current timer is chained with the previous timer. + * false: Timer doesn't chain with other timers. + */ +static inline void PIT_SetTimerChainMode(PIT_Type *base, pit_chnl_t channel, bool enable) +{ + if (enable) + { + base->CHANNEL[channel].TCTRL |= PIT_TCTRL_CHN_MASK; + } + else + { + base->CHANNEL[channel].TCTRL &= ~PIT_TCTRL_CHN_MASK; + } +} + +#endif /* FSL_FEATURE_PIT_HAS_CHAIN_MODE */ + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected PIT interrupts. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::pit_interrupt_enable_t + */ +static inline void PIT_EnableInterrupts(PIT_Type *base, pit_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].TCTRL |= mask; +} + +/*! + * @brief Disables the selected PIT interrupts. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * @param mask The interrupts to disable. This is a logical OR of members of the + * enumeration ::pit_interrupt_enable_t + */ +static inline void PIT_DisableInterrupts(PIT_Type *base, pit_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].TCTRL &= ~mask; +} + +/*! + * @brief Gets the enabled PIT interrupts. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::pit_interrupt_enable_t + */ +static inline uint32_t PIT_GetEnabledInterrupts(PIT_Type *base, pit_chnl_t channel) +{ + return (base->CHANNEL[channel].TCTRL & PIT_TCTRL_TIE_MASK); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the PIT status flags + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::pit_status_flags_t + */ +static inline uint32_t PIT_GetStatusFlags(PIT_Type *base, pit_chnl_t channel) +{ + return (base->CHANNEL[channel].TFLG & PIT_TFLG_TIF_MASK); +} + +/*! + * @brief Clears the PIT status flags. + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::pit_status_flags_t + */ +static inline void PIT_ClearStatusFlags(PIT_Type *base, pit_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].TFLG = mask; +} + +/*! @}*/ + +/*! + * @name Read and Write the timer period + * @{ + */ + +/*! + * @brief Sets the timer period in units of count. + * + * Timers begin counting from the value set by this function until it reaches 0, + * then it will generate an interrupt and load this regiter value again. + * Writing a new value to this register will not restart the timer; instead the value + * will be loaded after the timer expires. + * + * @note User can call the utility macros provided in fsl_common.h to convert to ticks + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * @param count Timer period in units of ticks + */ +static inline void PIT_SetTimerPeriod(PIT_Type *base, pit_chnl_t channel, uint32_t count) +{ + base->CHANNEL[channel].LDVAL = count; +} + +/*! + * @brief Reads the current timer counting value. + * + * This function returns the real-time timer counting value, in a range from 0 to a + * timer period. + * + * @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec + * + * @param base PIT peripheral base address + * @param channel Timer channel number + * + * @return Current timer counting value in ticks + */ +static inline uint32_t PIT_GetCurrentTimerCount(PIT_Type *base, pit_chnl_t channel) +{ + return base->CHANNEL[channel].CVAL; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the timer counting. + * + * After calling this function, timers load period value, count down to 0 and + * then load the respective start value again. Each time a timer reaches 0, + * it generates a trigger pulse and sets the timeout interrupt flag. + * + * @param base PIT peripheral base address + * @param channel Timer channel number. + */ +static inline void PIT_StartTimer(PIT_Type *base, pit_chnl_t channel) +{ + base->CHANNEL[channel].TCTRL |= PIT_TCTRL_TEN_MASK; +} + +/*! + * @brief Stops the timer counting. + * + * This function stops every timer counting. Timers reload their periods + * respectively after the next time they call the PIT_DRV_StartTimer. + * + * @param base PIT peripheral base address + * @param channel Timer channel number. + */ +static inline void PIT_StopTimer(PIT_Type *base, pit_chnl_t channel) +{ + base->CHANNEL[channel].TCTRL &= ~PIT_TCTRL_TEN_MASK; +} + +/*! @}*/ + +#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER + +/*! + * @brief Reads the current lifetime counter value. + * + * The lifetime timer is a 64-bit timer which chains timer 0 and timer 1 together. + * Timer 0 and 1 are chained by calling the PIT_SetTimerChainMode before using this timer. + * The period of lifetime timer is equal to the "period of timer 0 * period of timer 1". + * For the 64-bit value, the higher 32-bit has the value of timer 1, and the lower 32-bit + * has the value of timer 0. + * + * @param base PIT peripheral base address + * + * @return Current lifetime timer value + */ +uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base); + +#endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PIT_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pmc.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pmc.c new file mode 100644 index 0000000000..82d7b7ace1 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pmc.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_pmc.h" + +#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM) +void PMC_GetParam(PMC_Type *base, pmc_param_t *param) +{ + uint32_t reg = base->PARAM; + ; + param->vlpoEnable = (bool)(reg & PMC_PARAM_VLPOE_MASK); + param->hvdEnable = (bool)(reg & PMC_PARAM_HVDE_MASK); +} +#endif /* FSL_FEATURE_PMC_HAS_PARAM */ + +void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config) +{ + base->LVDSC1 = (0U | +#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) + ((uint32_t)config->voltSelect << PMC_LVDSC1_LVDV_SHIFT) | +#endif + ((uint32_t)config->enableInt << PMC_LVDSC1_LVDIE_SHIFT) | + ((uint32_t)config->enableReset << PMC_LVDSC1_LVDRE_SHIFT) + /* Clear the Low Voltage Detect Flag with previouse power detect setting */ + | PMC_LVDSC1_LVDACK_MASK); +} + +void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config) +{ + base->LVDSC2 = (0U | +#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) + ((uint32_t)config->voltSelect << PMC_LVDSC2_LVWV_SHIFT) | +#endif + ((uint32_t)config->enableInt << PMC_LVDSC2_LVWIE_SHIFT) + /* Clear the Low Voltage Warning Flag with previouse power detect setting */ + | PMC_LVDSC2_LVWACK_MASK); +} + +#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) +void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config) +{ + base->HVDSC1 = (((uint32_t)config->voltSelect << PMC_HVDSC1_HVDV_SHIFT) | + ((uint32_t)config->enableInt << PMC_HVDSC1_HVDIE_SHIFT) | + ((uint32_t)config->enableReset << PMC_HVDSC1_HVDRE_SHIFT) + /* Clear the High Voltage Detect Flag with previouse power detect setting */ + | PMC_HVDSC1_HVDACK_MASK); +} +#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ + +#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \ + (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \ + (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)) +void PMC_ConfigureBandgapBuffer(PMC_Type *base, const pmc_bandgap_buffer_config_t *config) +{ + base->REGSC = (0U +#if (defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) + | ((uint32_t)config->enable << PMC_REGSC_BGBE_SHIFT) +#endif /* FSL_FEATURE_PMC_HAS_BGBE */ +#if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) + | (((uint32_t)config->enableInLowPowerMode << PMC_REGSC_BGEN_SHIFT)) +#endif /* FSL_FEATURE_PMC_HAS_BGEN */ +#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) + | ((uint32_t)config->drive << PMC_REGSC_BGBDS_SHIFT) +#endif /* FSL_FEATURE_PMC_HAS_BGBDS */ + ); +} +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pmc.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pmc.h new file mode 100644 index 0000000000..c60c19c01e --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_pmc.h @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_PMC_H_ +#define _FSL_PMC_H_ + +#include "fsl_common.h" + +/*! @addtogroup pmc */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief PMC driver version */ +#define FSL_PMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +/*@}*/ + +#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) +/*! + * @brief Low-Voltage Detect Voltage Select + */ +typedef enum _pmc_low_volt_detect_volt_select +{ + kPMC_LowVoltDetectLowTrip = 0U, /*!< Low trip point selected (VLVD = VLVDL )*/ + kPMC_LowVoltDetectHighTrip = 1U /*!< High trip point selected (VLVD = VLVDH )*/ +} pmc_low_volt_detect_volt_select_t; +#endif + +#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) +/*! + * @brief Low-Voltage Warning Voltage Select + */ +typedef enum _pmc_low_volt_warning_volt_select +{ + kPMC_LowVoltWarningLowTrip = 0U, /*!< Low trip point selected (VLVW = VLVW1)*/ + kPMC_LowVoltWarningMid1Trip = 1U, /*!< Mid 1 trip point selected (VLVW = VLVW2)*/ + kPMC_LowVoltWarningMid2Trip = 2U, /*!< Mid 2 trip point selected (VLVW = VLVW3)*/ + kPMC_LowVoltWarningHighTrip = 3U /*!< High trip point selected (VLVW = VLVW4)*/ +} pmc_low_volt_warning_volt_select_t; +#endif + +#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) +/*! + * @brief High-Voltage Detect Voltage Select + */ +typedef enum _pmc_high_volt_detect_volt_select +{ + kPMC_HighVoltDetectLowTrip = 0U, /*!< Low trip point selected (VHVD = VHVDL )*/ + kPMC_HighVoltDetectHighTrip = 1U /*!< High trip point selected (VHVD = VHVDH )*/ +} pmc_high_volt_detect_volt_select_t; +#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ + +#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) +/*! + * @brief Bandgap Buffer Drive Select. + */ +typedef enum _pmc_bandgap_buffer_drive_select +{ + kPMC_BandgapBufferDriveLow = 0U, /*!< Low drive. */ + kPMC_BandgapBufferDriveHigh = 1U /*!< High drive. */ +} pmc_bandgap_buffer_drive_select_t; +#endif /* FSL_FEATURE_PMC_HAS_BGBDS */ + +#if (defined(FSL_FEATURE_PMC_HAS_VLPO) && FSL_FEATURE_PMC_HAS_VLPO) +/*! + * @brief VLPx Option + */ +typedef enum _pmc_vlp_freq_option +{ + kPMC_FreqRestrict = 0U, /*!< Frequency is restricted in VLPx mode. */ + kPMC_FreqUnrestrict = 1U /*!< Frequency is unrestricted in VLPx mode. */ +} pmc_vlp_freq_mode_t; +#endif /* FSL_FEATURE_PMC_HAS_VLPO */ + +#if (defined(FSL_FEATURE_PMC_HAS_VERID) && FSL_FEATURE_PMC_HAS_VERID) +/*! + @brief IP version ID definition. + */ +typedef struct _pmc_version_id +{ + uint16_t feature; /*!< Feature Specification Number. */ + uint8_t minor; /*!< Minor version number. */ + uint8_t major; /*!< Major version number. */ +} pmc_version_id_t; +#endif /* FSL_FEATURE_PMC_HAS_VERID */ + +#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM) +/*! @brief IP parameter definition. */ +typedef struct _pmc_param +{ + bool vlpoEnable; /*!< VLPO enable. */ + bool hvdEnable; /*!< HVD enable. */ +} pmc_param_t; +#endif /* FSL_FEATURE_PMC_HAS_PARAM */ + +/*! + * @brief Low-Voltage Detect Configuration Structure + */ +typedef struct _pmc_low_volt_detect_config +{ + bool enableInt; /*!< Enable interrupt when low voltage detect*/ + bool enableReset; /*!< Enable system reset when low voltage detect*/ +#if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) + pmc_low_volt_detect_volt_select_t voltSelect; /*!< Low voltage detect trip point voltage selection*/ +#endif +} pmc_low_volt_detect_config_t; + +/*! + * @brief Low-Voltage Warning Configuration Structure + */ +typedef struct _pmc_low_volt_warning_config +{ + bool enableInt; /*!< Enable interrupt when low voltage warning*/ +#if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) + pmc_low_volt_warning_volt_select_t voltSelect; /*!< Low voltage warning trip point voltage selection*/ +#endif +} pmc_low_volt_warning_config_t; + +#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) +/*! + * @brief High-Voltage Detect Configuration Structure + */ +typedef struct _pmc_high_volt_detect_config +{ + bool enableInt; /*!< Enable interrupt when high voltage detect*/ + bool enableReset; /*!< Enable system reset when high voltage detect*/ + pmc_high_volt_detect_volt_select_t voltSelect; /*!< High voltage detect trip point voltage selection*/ +} pmc_high_volt_detect_config_t; +#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ + +#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \ + (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \ + (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)) +/*! + * @brief Bandgap Buffer configuration. + */ +typedef struct _pmc_bandgap_buffer_config +{ +#if (defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) + bool enable; /*!< Enable bandgap buffer. */ +#endif +#if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) + bool enableInLowPowerMode; /*!< Enable bandgap buffer in low power mode. */ +#endif /* FSL_FEATURE_PMC_HAS_BGEN */ +#if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) + pmc_bandgap_buffer_drive_select_t drive; /*!< Bandgap buffer drive select. */ +#endif /* FSL_FEATURE_PMC_HAS_BGBDS */ +} pmc_bandgap_buffer_config_t; +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! @name Power Management Controller Control APIs*/ +/*@{*/ + +#if (defined(FSL_FEATURE_PMC_HAS_VERID) && FSL_FEATURE_PMC_HAS_VERID) +/*! + * @brief Gets the PMC version ID. + * + * This function gets the PMC version ID, including major version number, + * minor version number and feature specification number. + * + * @param base PMC peripheral base address. + * @param versionId Pointer to version ID structure. + */ +static inline void PMC_GetVersionId(PMC_Type *base, pmc_version_id_t *versionId) +{ + *((uint32_t *)versionId) = base->VERID; +} +#endif /* FSL_FEATURE_PMC_HAS_VERID */ + +#if (defined(FSL_FEATURE_PMC_HAS_PARAM) && FSL_FEATURE_PMC_HAS_PARAM) +/*! + * @brief Gets the PMC parameter. + * + * This function gets the PMC parameter, including VLPO enable and HVD enable. + * + * @param base PMC peripheral base address. + * @param param Pointer to PMC param structure. + */ +void PMC_GetParam(PMC_Type *base, pmc_param_t *param); +#endif + +/*! + * @brief Configure the low voltage detect setting. + * + * This function configures the low voltage detect setting, including the trip + * point voltage setting, enable interrupt or not, enable system reset or not. + * + * @param base PMC peripheral base address. + * @param config Low-Voltage detect configuration structure. + */ +void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config); + +/*! + * @brief Get Low-Voltage Detect Flag status + * + * This function reads the current LVDF status. If it returns 1, a low + * voltage event is detected. + * + * @param base PMC peripheral base address. + * @return Current low voltage detect flag + * - true: Low-Voltage detected + * - false: Low-Voltage not detected + */ +static inline bool PMC_GetLowVoltDetectFlag(PMC_Type *base) +{ + return (bool)(base->LVDSC1 & PMC_LVDSC1_LVDF_MASK); +} + +/*! + * @brief Acknowledge to clear the Low-Voltage Detect flag + * + * This function acknowledges the low voltage detection errors (write 1 to + * clear LVDF). + * + * @param base PMC peripheral base address. + */ +static inline void PMC_ClearLowVoltDetectFlag(PMC_Type *base) +{ + base->LVDSC1 |= PMC_LVDSC1_LVDACK_MASK; +} + +/*! + * @brief Configure the low voltage warning setting. + * + * This function configures the low voltage warning setting, including the trip + * point voltage setting and enable interrupt or not. + * + * @param base PMC peripheral base address. + * @param config Low-Voltage warning configuration structure. + */ +void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config); + +/*! + * @brief Get Low-Voltage Warning Flag status + * + * This function polls the current LVWF status. When 1 is returned, it + * indicates a low-voltage warning event. LVWF is set when V Supply transitions + * below the trip point or after reset and V Supply is already below the V LVW. + * + * @param base PMC peripheral base address. + * @return Current LVWF status + * - true: Low-Voltage Warning Flag is set. + * - false: the Low-Voltage Warning does not happen. + */ +static inline bool PMC_GetLowVoltWarningFlag(PMC_Type *base) +{ + return (bool)(base->LVDSC2 & PMC_LVDSC2_LVWF_MASK); +} + +/*! + * @brief Acknowledge to Low-Voltage Warning flag + * + * This function acknowledges the low voltage warning errors (write 1 to + * clear LVWF). + * + * @param base PMC peripheral base address. + */ +static inline void PMC_ClearLowVoltWarningFlag(PMC_Type *base) +{ + base->LVDSC2 |= PMC_LVDSC2_LVWACK_MASK; +} + +#if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) +/*! + * @brief Configure the high voltage detect setting. + * + * This function configures the high voltage detect setting, including the trip + * point voltage setting, enable interrupt or not, enable system reset or not. + * + * @param base PMC peripheral base address. + * @param config High-Voltage detect configuration structure. + */ +void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config); + +/*! + * @brief Get High-Voltage Detect Flag status + * + * This function reads the current HVDF status. If it returns 1, a low + * voltage event is detected. + * + * @param base PMC peripheral base address. + * @return Current high voltage detect flag + * - true: High-Voltage detected + * - false: High-Voltage not detected + */ +static inline bool PMC_GetHighVoltDetectFlag(PMC_Type *base) +{ + return (bool)(base->HVDSC1 & PMC_HVDSC1_HVDF_MASK); +} + +/*! + * @brief Acknowledge to clear the High-Voltage Detect flag + * + * This function acknowledges the high voltage detection errors (write 1 to + * clear HVDF). + * + * @param base PMC peripheral base address. + */ +static inline void PMC_ClearHighVoltDetectFlag(PMC_Type *base) +{ + base->HVDSC1 |= PMC_HVDSC1_HVDACK_MASK; +} +#endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ + +#if ((defined(FSL_FEATURE_PMC_HAS_BGBE) && FSL_FEATURE_PMC_HAS_BGBE) || \ + (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \ + (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)) +/*! + * @brief Configure the PMC bandgap + * + * This function configures the PMC bandgap, including the drive select and + * behavior in low power mode. + * + * @param base PMC peripheral base address. + * @param config Pointer to the configuration structure + */ +void PMC_ConfigureBandgapBuffer(PMC_Type *base, const pmc_bandgap_buffer_config_t *config); +#endif + +#if (defined(FSL_FEATURE_PMC_HAS_ACKISO) && FSL_FEATURE_PMC_HAS_ACKISO) +/*! + * @brief Gets the acknowledge Peripherals and I/O pads isolation flag. + * + * This function reads the Acknowledge Isolation setting that indicates + * whether certain peripherals and the I/O pads are in a latched state as + * a result of having been in the VLLS mode. + * + * @param base PMC peripheral base address. + * @param base Base address for current PMC instance. + * @return ACK isolation + * 0 - Peripherals and I/O pads are in a normal run state. + * 1 - Certain peripherals and I/O pads are in an isolated and + * latched state. + */ +static inline bool PMC_GetPeriphIOIsolationFlag(PMC_Type *base) +{ + return (bool)(base->REGSC & PMC_REGSC_ACKISO_MASK); +} + +/*! + * @brief Acknowledge to Peripherals and I/O pads isolation flag. + * + * This function clears the ACK Isolation flag. Writing one to this setting + * when it is set releases the I/O pads and certain peripherals to their normal + * run mode state. + * + * @param base PMC peripheral base address. + */ +static inline void PMC_ClearPeriphIOIsolationFlag(PMC_Type *base) +{ + base->REGSC |= PMC_REGSC_ACKISO_MASK; +} +#endif /* FSL_FEATURE_PMC_HAS_ACKISO */ + +#if (defined(FSL_FEATURE_PMC_HAS_REGONS) && FSL_FEATURE_PMC_HAS_REGONS) +/*! + * @brief Gets the Regulator regulation status. + * + * This function returns the regulator to a run regulation status. It provides + * the current status of the internal voltage regulator. + * + * @param base PMC peripheral base address. + * @param base Base address for current PMC instance. + * @return Regulation status + * 0 - Regulator is in a stop regulation or in transition to/from the regulation. + * 1 - Regulator is in a run regulation. + * + */ +static inline bool PMC_IsRegulatorInRunRegulation(PMC_Type *base) +{ + return (bool)(base->REGSC & PMC_REGSC_REGONS_MASK); +} +#endif /* FSL_FEATURE_PMC_HAS_REGONS */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* _FSL_PMC_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_port.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_port.h new file mode 100644 index 0000000000..790518ccd3 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_port.h @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_PORT_H_ +#define _FSL_PORT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup port_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! Version 2.0.1. */ +#define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! @brief Internal resistor pull feature selection */ +enum _port_pull +{ + kPORT_PullDisable = 0U, /*!< internal pull-up/down resistor is disabled. */ + kPORT_PullDown = 2U, /*!< internal pull-down resistor is enabled. */ + kPORT_PullUp = 3U, /*!< internal pull-up resistor is enabled. */ +}; + +/*! @brief Slew rate selection */ +enum _port_slew_rate +{ + kPORT_FastSlewRate = 0U, /*!< fast slew rate is configured. */ + kPORT_SlowSlewRate = 1U, /*!< slow slew rate is configured. */ +}; + +#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN +/*! @brief Internal resistor pull feature enable/disable */ +enum _port_open_drain_enable +{ + kPORT_OpenDrainDisable = 0U, /*!< internal pull-down resistor is disabled. */ + kPORT_OpenDrainEnable = 1U, /*!< internal pull-up resistor is enabled. */ +}; +#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ + +/*! @brief Passive filter feature enable/disable */ +enum _port_passive_filter_enable +{ + kPORT_PassiveFilterDisable = 0U, /*!< fast slew rate is configured. */ + kPORT_PassiveFilterEnable = 1U, /*!< slow slew rate is configured. */ +}; + +/*! @brief Configures the drive strength. */ +enum _port_drive_strength +{ + kPORT_LowDriveStrength = 0U, /*!< low drive strength is configured. */ + kPORT_HighDriveStrength = 1U, /*!< high drive strength is configured. */ +}; + +#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK +/*! @brief Unlock/lock the pin control register field[15:0] */ +enum _port_lock_register +{ + kPORT_UnlockRegister = 0U, /*!< Pin Control Register fields [15:0] are not locked. */ + kPORT_LockRegister = 1U, /*!< Pin Control Register fields [15:0] are locked. */ +}; +#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ + +/*! @brief Pin mux selection */ +typedef enum _port_mux +{ + kPORT_PinDisabledOrAnalog = 0U, /*!< corresponding pin is disabled, but is used as an analog pin. */ + kPORT_MuxAsGpio = 1U, /*!< corresponding pin is configured as GPIO. */ + kPORT_MuxAlt2 = 2U, /*!< chip-specific */ + kPORT_MuxAlt3 = 3U, /*!< chip-specific */ + kPORT_MuxAlt4 = 4U, /*!< chip-specific */ + kPORT_MuxAlt5 = 5U, /*!< chip-specific */ + kPORT_MuxAlt6 = 6U, /*!< chip-specific */ + kPORT_MuxAlt7 = 7U, /*!< chip-specific */ +} port_mux_t; + +/*! @brief Configures the interrupt generation condition. */ +typedef enum _port_interrupt +{ + kPORT_InterruptOrDMADisabled = 0x0U, /*!< Interrupt/DMA request is disabled. */ +#if defined(FSL_FEATURE_PORT_HAS_DMA_REQUEST) && FSL_FEATURE_PORT_HAS_DMA_REQUEST + kPORT_DMARisingEdge = 0x1U, /*!< DMA request on rising edge. */ + kPORT_DMAFallingEdge = 0x2U, /*!< DMA request on falling edge. */ + kPORT_DMAEitherEdge = 0x3U, /*!< DMA request on either edge. */ +#endif +#if defined(FSL_FEATURE_PORT_HAS_IRQC_FLAG) && FSL_FEATURE_PORT_HAS_IRQC_FLAG + kPORT_FlagRisingEdge = 0x05U, /*!< Flag sets on rising edge. */ + kPORT_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */ + kPORT_FlagEitherEdge = 0x07U, /*!< Flag sets on either edge. */ +#endif + kPORT_InterruptLogicZero = 0x8U, /*!< Interrupt when logic zero. */ + kPORT_InterruptRisingEdge = 0x9U, /*!< Interrupt on rising edge. */ + kPORT_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */ + kPORT_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */ + kPORT_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */ +#if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER + kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high trigger output. */ + kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low trigger output. */ +#endif +} port_interrupt_t; + +#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER +/*! @brief Digital filter clock source selection */ +typedef enum _port_digital_filter_clock_source +{ + kPORT_BusClock = 0U, /*!< Digital filters are clocked by the bus clock. */ + kPORT_LpoClock = 1U, /*!< Digital filters are clocked by the 1 kHz LPO clock. */ +} port_digital_filter_clock_source_t; + +/*! @brief PORT digital filter feature configuration definition */ +typedef struct _port_digital_filter_config +{ + uint32_t digitalFilterWidth; /*!< Set digital filter width */ + port_digital_filter_clock_source_t clockSource; /*!< Set digital filter clockSource */ +} port_digital_filter_config_t; +#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */ + +/*! @brief PORT pin config structure */ +typedef struct _port_pin_config +{ + uint16_t pullSelect : 2; /*!< no-pull/pull-down/pull-up select */ + uint16_t slewRate : 1; /*!< fast/slow slew rate Configure */ + uint16_t : 1; + uint16_t passiveFilterEnable : 1; /*!< passive filter enable/disable */ +#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN + uint16_t openDrainEnable : 1; /*!< open drain enable/disable */ +#else + uint16_t : 1; +#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ + uint16_t driveStrength : 1; /*!< fast/slow drive strength configure */ + uint16_t : 1; + uint16_t mux : 3; /*!< pin mux Configure */ + uint16_t : 4; +#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK + uint16_t lockRegister : 1; /*!< lock/unlock the pcr field[15:0] */ +#else + uint16_t : 1; +#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ +} port_pin_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! @name Configuration */ +/*@{*/ + +/*! + * @brief Sets the port PCR register. + * + * This is an example to define an input pin or output pin PCR configuration: + * @code + * // Define a digital input pin PCR configuration + * port_pin_config_t config = { + * kPORT_PullUp, + * kPORT_FastSlewRate, + * kPORT_PassiveFilterDisable, + * kPORT_OpenDrainDisable, + * kPORT_LowDriveStrength, + * kPORT_MuxAsGpio, + * kPORT_UnLockRegister, + * }; + * @endcode + * + * @param base PORT peripheral base pointer. + * @param pin PORT pin number. + * @param config PORT PCR register configure structure. + */ +static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config) +{ + assert(config); + uint32_t addr = (uint32_t)&base->PCR[pin]; + *(volatile uint16_t *)(addr) = *((const uint16_t *)config); +} + +/*! + * @brief Sets the port PCR register for multiple pins. + * + * This is an example to define input pins or output pins PCR configuration: + * @code + * // Define a digital input pin PCR configuration + * port_pin_config_t config = { + * kPORT_PullUp , + * kPORT_PullEnable, + * kPORT_FastSlewRate, + * kPORT_PassiveFilterDisable, + * kPORT_OpenDrainDisable, + * kPORT_LowDriveStrength, + * kPORT_MuxAsGpio, + * kPORT_UnlockRegister, + * }; + * @endcode + * + * @param base PORT peripheral base pointer. + * @param mask PORT pins' numbers macro. + * @param config PORT PCR register configure structure. + */ +static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config) +{ + assert(config); + + uint16_t pcrl = *((const uint16_t *)config); + + if (mask & 0xffffU) + { + base->GPCLR = ((mask & 0xffffU) << 16) | pcrl; + } + if (mask >> 16) + { + base->GPCHR = (mask & 0xffff0000U) | pcrl; + } +} + +/*! + * @brief Configures the pin muxing. + * + * @param base PORT peripheral base pointer. + * @param pin PORT pin number. + * @param mux pin muxing slot selection. + * - #kPORT_PinDisabledOrAnalog: Pin disabled or work in analog function. + * - #kPORT_MuxAsGpio : Set as GPIO. + * - #kPORT_MuxAlt2 : chip-specific. + * - #kPORT_MuxAlt3 : chip-specific. + * - #kPORT_MuxAlt4 : chip-specific. + * - #kPORT_MuxAlt5 : chip-specific. + * - #kPORT_MuxAlt6 : chip-specific. + * - #kPORT_MuxAlt7 : chip-specific. + * @Note : This function is NOT recommended to use together with the PORT_SetPinsConfig, because + * the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux will + * be reset to zero : kPORT_PinDisabledOrAnalog). + * This function is recommended to use in the case you just need to reset the pin mux + * + */ +static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux) +{ + base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(mux); +} + +#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER + +/*! + * @brief Enables the digital filter in one port, each bit of the 32-bit register represents one pin. + * + * @param base PORT peripheral base pointer. + * @param mask PORT pins' numbers macro. + */ +static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable) +{ + if (enable == true) + { + base->DFER |= mask; + } + else + { + base->DFER &= ~mask; + } +} + +/*! + * @brief Sets the digital filter in one port, each bit of the 32-bit register represents one pin. + * + * @param base PORT peripheral base pointer. + * @param config PORT digital filter configuration structure. + */ +static inline void PORT_SetDigitalFilterConfig(PORT_Type *base, const port_digital_filter_config_t *config) +{ + assert(config); + + base->DFCR = PORT_DFCR_CS(config->clockSource); + base->DFWR = PORT_DFWR_FILT(config->digitalFilterWidth); +} + +#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */ + +/*@}*/ + +/*! @name Interrupt */ +/*@{*/ + +/*! + * @brief Configures the port pin interrupt/DMA request. + * + * @param base PORT peripheral base pointer. + * @param pin PORT pin number. + * @param config PORT pin interrupt configuration. + * - #kPORT_InterruptOrDMADisabled: Interrupt/DMA request disabled. + * - #kPORT_DMARisingEdge : DMA request on rising edge(if the DMA requests exit). + * - #kPORT_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit). + * - #kPORT_DMAEitherEdge : DMA request on either edge(if the DMA requests exit). + * - #kPORT_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit). + * - #kPORT_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit). + * - #kPORT_FlagEitherEdge : Flag sets on either edge(if the Flag states exit). + * - #kPORT_InterruptLogicZero : Interrupt when logic zero. + * - #kPORT_InterruptRisingEdge : Interrupt on rising edge. + * - #kPORT_InterruptFallingEdge: Interrupt on falling edge. + * - #kPORT_InterruptEitherEdge : Interrupt on either edge. + * - #kPORT_InterruptLogicOne : Interrupt when logic one. + * - #kPORT_ActiveHighTriggerOutputEnable : Enable active high trigger output(if the trigger states exit). + * - #kPORT_ActiveLowTriggerOutputEnable : Enable active low trigger output(if the trigger states exit). + */ +static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config) +{ + base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_IRQC_MASK) | PORT_PCR_IRQC(config); +} + +/*! + * @brief Reads the whole port status flag. + * + * If a pin is configured to generate the DMA request, the corresponding flag + * is cleared automatically at the completion of the requested DMA transfer. + * Otherwise, the flag remains set until a logic one is written to that flag. + * If configured for a level sensitive interrupt that remains asserted, the flag + * is set again immediately. + * + * @param base PORT peripheral base pointer. + * @return Current port interrupt status flags, for example, 0x00010001 means the + * pin 0 and 17 have the interrupt. + */ +static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base) +{ + return base->ISFR; +} + +/*! + * @brief Clears the multiple pins' interrupt status flag. + * + * @param base PORT peripheral base pointer. + * @param mask PORT pins' numbers macro. + */ +static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask) +{ + base->ISFR = mask; +} + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PORT_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rcm.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rcm.c new file mode 100644 index 0000000000..538f6872a3 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rcm.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_rcm.h" + +void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config) +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) + uint32_t reg; + + reg = (((uint32_t)config->enableFilterInStop << RCM_RPC_RSTFLTSS_SHIFT) | (uint32_t)config->filterInRunWait); + if (config->filterInRunWait == kRCM_FilterBusClock) + { + reg |= ((uint32_t)config->busClockFilterCount << RCM_RPC_RSTFLTSEL_SHIFT); + } + base->RPC = reg; +#else + base->RPFC = ((uint8_t)(config->enableFilterInStop << RCM_RPFC_RSTFLTSS_SHIFT) | (uint8_t)config->filterInRunWait); + if (config->filterInRunWait == kRCM_FilterBusClock) + { + base->RPFW = config->busClockFilterCount; + } +#endif /* FSL_FEATURE_RCM_REG_WIDTH */ +} + +#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM) +void RCM_SetForceBootRomSource(RCM_Type *base, rcm_boot_rom_config_t config) +{ + uint32_t reg; + + reg = base->FM; + reg &= ~RCM_FM_FORCEROM_MASK; + reg |= ((uint32_t)config << RCM_FM_FORCEROM_SHIFT); + base->FM = reg; +} +#endif /* #if FSL_FEATURE_RCM_HAS_BOOTROM */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rcm.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rcm.h new file mode 100644 index 0000000000..81e25559ea --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rcm.h @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_RCM_H_ +#define _FSL_RCM_H_ + +#include "fsl_common.h" + +/*! @addtogroup rcm */ +/*! @{*/ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief RCM driver version 2.0.0. */ +#define FSL_RCM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! + * @brief System Reset Source Name definitions + */ +typedef enum _rcm_reset_source +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) +/* RCM register bit width is 32. */ +#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) + kRCM_SourceWakeup = RCM_SRS_WAKEUP_MASK, /*!< Low-leakage wakeup reset */ +#endif + kRCM_SourceLvd = RCM_SRS_LVD_MASK, /*!< low voltage detect reset */ +#if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) + kRCM_SourceLoc = RCM_SRS_LOC_MASK, /*!< Loss of clock reset */ +#endif /* FSL_FEATURE_RCM_HAS_LOC */ +#if (defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL) + kRCM_SourceLol = RCM_SRS_LOL_MASK, /*!< Loss of lock reset */ +#endif /* FSL_FEATURE_RCM_HAS_LOL */ + kRCM_SourceWdog = RCM_SRS_WDOG_MASK, /*!< Watchdog reset */ + kRCM_SourcePin = RCM_SRS_PIN_MASK, /*!< External pin reset */ + kRCM_SourcePor = RCM_SRS_POR_MASK, /*!< Power on reset */ +#if (defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG) + kRCM_SourceJtag = RCM_SRS_JTAG_MASK, /*!< JTAG generated reset */ +#endif /* FSL_FEATURE_RCM_HAS_JTAG */ + kRCM_SourceLockup = RCM_SRS_LOCKUP_MASK, /*!< Core lock up reset */ + kRCM_SourceSw = RCM_SRS_SW_MASK, /*!< Software reset */ +#if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) + kRCM_SourceMdmap = RCM_SRS_MDM_AP_MASK, /*!< MDM-AP system reset */ +#endif /* FSL_FEATURE_RCM_HAS_MDM_AP */ +#if (defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT) + kRCM_SourceEzpt = RCM_SRS_EZPT_MASK, /*!< EzPort reset */ +#endif /* FSL_FEATURE_RCM_HAS_EZPORT */ + kRCM_SourceSackerr = RCM_SRS_SACKERR_MASK, /*!< Parameter could get all reset flags */ + +#else /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ +/* RCM register bit width is 8. */ +#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) + kRCM_SourceWakeup = RCM_SRS0_WAKEUP_MASK, /*!< Low-leakage wakeup reset */ +#endif + kRCM_SourceLvd = RCM_SRS0_LVD_MASK, /*!< low voltage detect reset */ +#if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) + kRCM_SourceLoc = RCM_SRS0_LOC_MASK, /*!< Loss of clock reset */ +#endif /* FSL_FEATURE_RCM_HAS_LOC */ +#if (defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL) + kRCM_SourceLol = RCM_SRS0_LOL_MASK, /*!< Loss of lock reset */ +#endif /* FSL_FEATURE_RCM_HAS_LOL */ + kRCM_SourceWdog = RCM_SRS0_WDOG_MASK, /*!< Watchdog reset */ + kRCM_SourcePin = RCM_SRS0_PIN_MASK, /*!< External pin reset */ + kRCM_SourcePor = RCM_SRS0_POR_MASK, /*!< Power on reset */ +#if (defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG) + kRCM_SourceJtag = RCM_SRS1_JTAG_MASK << 8U, /*!< JTAG generated reset */ +#endif /* FSL_FEATURE_RCM_HAS_JTAG */ + kRCM_SourceLockup = RCM_SRS1_LOCKUP_MASK << 8U, /*!< Core lock up reset */ + kRCM_SourceSw = RCM_SRS1_SW_MASK, /*!< Software reset */ +#if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) + kRCM_SourceMdmap = RCM_SRS1_MDM_AP_MASK << 8U, /*!< MDM-AP system reset */ +#endif /* FSL_FEATURE_RCM_HAS_MDM_AP */ +#if (defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT) + kRCM_SourceEzpt = RCM_SRS1_EZPT_MASK << 8U, /*!< EzPort reset */ +#endif /* FSL_FEATURE_RCM_HAS_EZPORT */ + kRCM_SourceSackerr = RCM_SRS1_SACKERR_MASK << 8U, /*!< Parameter could get all reset flags */ +#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ + kRCM_SourceAll = 0xffffffffU, +} rcm_reset_source_t; + +/*! + * @brief Reset pin filter select in Run and Wait modes + */ +typedef enum _rcm_run_wait_filter_mode +{ + kRCM_FilterDisable = 0U, /*!< All filtering disabled */ + kRCM_FilterBusClock = 1U, /*!< Bus clock filter enabled */ + kRCM_FilterLpoClock = 2U /*!< LPO clock filter enabled */ +} rcm_run_wait_filter_mode_t; + +#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM) +/*! + * @brief Boot from ROM configuration. + */ +typedef enum _rcm_boot_rom_config +{ + kRCM_BootFlash = 0U, /*!< Boot from flash */ + kRCM_BootRomCfg0 = 1U, /*!< Boot from boot ROM due to BOOTCFG0 */ + kRCM_BootRomFopt = 2U, /*!< Boot from boot ROM due to FOPT[7] */ + kRCM_BootRomBoth = 3U /*!< Boot from boot ROM due to both BOOTCFG0 and FOPT[7] */ +} rcm_boot_rom_config_t; +#endif /* FSL_FEATURE_RCM_HAS_BOOTROM */ + +#if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE) +/*! + * @brief Max delay time from interrupt asserts to system reset. + */ +typedef enum _rcm_reset_delay +{ + kRCM_ResetDelay8Lpo = 0U, /*!< Delay 8 LPO cycles. */ + kRCM_ResetDelay32Lpo = 1U, /*!< Delay 32 LPO cycles. */ + kRCM_ResetDelay128Lpo = 2U, /*!< Delay 128 LPO cycles. */ + kRCM_ResetDelay512Lpo = 3U /*!< Delay 512 LPO cycles. */ +} rcm_reset_delay_t; + +/*! + * @brief System reset interrupt enable bit definitions. + */ +typedef enum _rcm_interrupt_enable +{ + kRCM_IntNone = 0U, /*!< No interrupt enabled. */ + kRCM_IntLossOfClk = RCM_SRIE_LOC_MASK, /*!< Loss of clock interrupt. */ + kRCM_IntLossOfLock = RCM_SRIE_LOL_MASK, /*!< Loss of lock interrupt. */ + kRCM_IntWatchDog = RCM_SRIE_WDOG_MASK, /*!< Watch dog interrupt. */ + kRCM_IntExternalPin = RCM_SRIE_PIN_MASK, /*!< External pin interrupt. */ + kRCM_IntGlobal = RCM_SRIE_GIE_MASK, /*!< Global interrupts. */ + kRCM_IntCoreLockup = RCM_SRIE_LOCKUP_MASK, /*!< Core lock up interrupt */ + kRCM_IntSoftware = RCM_SRIE_SW_MASK, /*!< software interrupt */ + kRCM_IntStopModeAckErr = RCM_SRIE_SACKERR_MASK, /*!< Stop mode ACK error interrupt. */ +#if (defined(FSL_FEATURE_RCM_HAS_CORE1) && FSL_FEATURE_RCM_HAS_CORE1) + kRCM_IntCore1 = RCM_SRIE_CORE1_MASK, /*!< Core 1 interrupt. */ +#endif + kRCM_IntAll = RCM_SRIE_LOC_MASK /*!< Enable all interrupts. */ + | + RCM_SRIE_LOL_MASK | RCM_SRIE_WDOG_MASK | RCM_SRIE_PIN_MASK | RCM_SRIE_GIE_MASK | + RCM_SRIE_LOCKUP_MASK | RCM_SRIE_SW_MASK | RCM_SRIE_SACKERR_MASK +#if (defined(FSL_FEATURE_RCM_HAS_CORE1) && FSL_FEATURE_RCM_HAS_CORE1) + | + RCM_SRIE_CORE1_MASK +#endif +} rcm_interrupt_enable_t; +#endif /* FSL_FEATURE_RCM_HAS_SRIE */ + +#if (defined(FSL_FEATURE_RCM_HAS_VERID) && FSL_FEATURE_RCM_HAS_VERID) +/*! + * @brief IP version ID definition. + */ +typedef struct _rcm_version_id +{ + uint16_t feature; /*!< Feature Specification Number. */ + uint8_t minor; /*!< Minor version number. */ + uint8_t major; /*!< Major version number. */ +} rcm_version_id_t; +#endif + +/*! + * @brief Reset pin filter configuration + */ +typedef struct _rcm_reset_pin_filter_config +{ + bool enableFilterInStop; /*!< Reset pin filter select in stop mode. */ + rcm_run_wait_filter_mode_t filterInRunWait; /*!< Reset pin filter in run/wait mode. */ + uint8_t busClockFilterCount; /*!< Reset pin bus clock filter width. */ +} rcm_reset_pin_filter_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! @name Reset Control Module APIs*/ +/*@{*/ + +#if (defined(FSL_FEATURE_RCM_HAS_VERID) && FSL_FEATURE_RCM_HAS_VERID) +/*! + * @brief Gets the RCM version ID. + * + * This function gets the RCM version ID including the major version number, + * the minor version number, and the feature specification number. + * + * @param base RCM peripheral base address. + * @param versionId Pointer to version ID structure. + */ +static inline void RCM_GetVersionId(RCM_Type *base, rcm_version_id_t *versionId) +{ + *((uint32_t *)versionId) = base->VERID; +} +#endif + +#if (defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM) +/*! + * @brief Gets the reset source implemented status. + * + * This function gets the RCM parameter that indicates whether the corresponding reset source is implemented. + * Use source masks defined in the rcm_reset_source_t to get the desired source status. + * + * Example: + @code + uint32_t status; + + // To test whether the MCU is reset using Watchdog. + status = RCM_GetResetSourceImplementedStatus(RCM) & (kRCM_SourceWdog | kRCM_SourcePin); + @endcode + * + * @param base RCM peripheral base address. + * @return All reset source implemented status bit map. + */ +static inline uint32_t RCM_GetResetSourceImplementedStatus(RCM_Type *base) +{ + return base->PARAM; +} +#endif /* FSL_FEATURE_RCM_HAS_PARAM */ + +/*! + * @brief Gets the reset source status which caused a previous reset. + * + * This function gets the current reset source status. Use source masks + * defined in the rcm_reset_source_t to get the desired source status. + * + * Example: + @code + uint32_t resetStatus; + + // To get all reset source statuses. + resetStatus = RCM_GetPreviousResetSources(RCM) & kRCM_SourceAll; + + // To test whether the MCU is reset using Watchdog. + resetStatus = RCM_GetPreviousResetSources(RCM) & kRCM_SourceWdog; + + // To test multiple reset sources. + resetStatus = RCM_GetPreviousResetSources(RCM) & (kRCM_SourceWdog | kRCM_SourcePin); + @endcode + * + * @param base RCM peripheral base address. + * @return All reset source status bit map. + */ +static inline uint32_t RCM_GetPreviousResetSources(RCM_Type *base) +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) + return base->SRS; +#else + return (uint32_t)((uint32_t)base->SRS0 | ((uint32_t)base->SRS1 << 8U)); +#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ +} + +#if (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) +/*! + * @brief Gets the sticky reset source status. + * + * This function gets the current reset source status that has not been cleared + * by software for some specific source. + * + * Example: + @code + uint32_t resetStatus; + + // To get all reset source statuses. + resetStatus = RCM_GetStickyResetSources(RCM) & kRCM_SourceAll; + + // To test whether the MCU is reset using Watchdog. + resetStatus = RCM_GetStickyResetSources(RCM) & kRCM_SourceWdog; + + // To test multiple reset sources. + resetStatus = RCM_GetStickyResetSources(RCM) & (kRCM_SourceWdog | kRCM_SourcePin); + @endcode + * + * @param base RCM peripheral base address. + * @return All reset source status bit map. + */ +static inline uint32_t RCM_GetStickyResetSources(RCM_Type *base) +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) + return base->SSRS; +#else + return (base->SSRS0 | ((uint32_t)base->SSRS1 << 8U)); +#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ +} + +/*! + * @brief Clears the sticky reset source status. + * + * This function clears the sticky system reset flags indicated by source masks. + * + * Example: + @code + // Clears multiple reset sources. + RCM_ClearStickyResetSources(kRCM_SourceWdog | kRCM_SourcePin); + @endcode + * + * @param base RCM peripheral base address. + * @param sourceMasks reset source status bit map + */ +static inline void RCM_ClearStickyResetSources(RCM_Type *base, uint32_t sourceMasks) +{ +#if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) + base->SSRS = sourceMasks; +#else + base->SSRS0 = (sourceMasks & 0xffU); + base->SSRS1 = ((sourceMasks >> 8U) & 0xffU); +#endif /* (FSL_FEATURE_RCM_REG_WIDTH == 32) */ +} +#endif /* FSL_FEATURE_RCM_HAS_SSRS */ + +/*! + * @brief Configures the reset pin filter. + * + * This function sets the reset pin filter including the filter source, filter + * width, and so on. + * + * @param base RCM peripheral base address. + * @param config Pointer to the configuration structure. + */ +void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config); + +#if (defined(FSL_FEATURE_RCM_HAS_EZPMS) && FSL_FEATURE_RCM_HAS_EZPMS) +/*! + * @brief Gets the EZP_MS_B pin assert status. + * + * This function gets the easy port mode status (EZP_MS_B) pin assert status. + * + * @param base RCM peripheral base address. + * @return status true - asserted, false - reasserted + */ +static inline bool RCM_GetEasyPortModePinStatus(RCM_Type *base) +{ + return (bool)(base->MR & RCM_MR_EZP_MS_MASK); +} +#endif /* FSL_FEATURE_RCM_HAS_EZPMS */ + +#if (defined(FSL_FEATURE_RCM_HAS_BOOTROM) && FSL_FEATURE_RCM_HAS_BOOTROM) +/*! + * @brief Gets the ROM boot source. + * + * This function gets the ROM boot source during the last chip reset. + * + * @param base RCM peripheral base address. + * @return The ROM boot source. + */ +static inline rcm_boot_rom_config_t RCM_GetBootRomSource(RCM_Type *base) +{ + return (rcm_boot_rom_config_t)((base->MR & RCM_MR_BOOTROM_MASK) >> RCM_MR_BOOTROM_SHIFT); +} + +/*! + * @brief Clears the ROM boot source flag. + * + * This function clears the ROM boot source flag. + * + * @param base Register base address of RCM + */ +static inline void RCM_ClearBootRomSource(RCM_Type *base) +{ + base->MR |= RCM_MR_BOOTROM_MASK; +} + +/*! + * @brief Forces the boot from ROM. + * + * This function forces booting from ROM during all subsequent system resets. + * + * @param base RCM peripheral base address. + * @param config Boot configuration. + */ +void RCM_SetForceBootRomSource(RCM_Type *base, rcm_boot_rom_config_t config); +#endif /* FSL_FEATURE_RCM_HAS_BOOTROM */ + +#if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE) +/*! + * @brief Sets the system reset interrupt configuration. + * + * For graceful shutdown, the RCM supports delaying the assertion of the system + * reset for a period of time when the reset interrupt is generated. This function + * can be used to enable the interrupt and the delay period. The interrupts + * are passed in as bit mask. See rcm_int_t for details. For example, to + * delay a reset for 512 LPO cycles after the WDOG timeout or loss-of-clock occurs, + * configure as follows: + * RCM_SetSystemResetInterruptConfig(kRCM_IntWatchDog | kRCM_IntLossOfClk, kRCM_ResetDelay512Lpo); + * + * @param base RCM peripheral base address. + * @param intMask Bit mask of the system reset interrupts to enable. See + * rcm_interrupt_enable_t for details. + * @param Delay Bit mask of the system reset interrupts to enable. + */ +static inline void RCM_SetSystemResetInterruptConfig(RCM_Type *base, uint32_t intMask, rcm_reset_delay_t delay) +{ + base->SRIE = (intMask | delay); +} +#endif /* FSL_FEATURE_RCM_HAS_SRIE */ +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* _FSL_RCM_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rtc.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rtc.c new file mode 100644 index 0000000000..898a544a46 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rtc.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_rtc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SECONDS_IN_A_DAY (86400U) +#define SECONDS_IN_A_HOUR (3600U) +#define SECONDS_IN_A_MINUTE (60U) +#define DAYS_IN_A_YEAR (365U) +#define YEAR_RANGE_START (1970U) +#define YEAR_RANGE_END (2099U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Checks whether the date and time passed in is valid + * + * @param datetime Pointer to structure where the date and time details are stored + * + * @return Returns false if the date & time details are out of range; true if in range + */ +static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime); + +/*! + * @brief Converts time data from datetime to seconds + * + * @param datetime Pointer to datetime structure where the date and time details are stored + * + * @return The result of the conversion in seconds + */ +static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime); + +/*! + * @brief Converts time data from seconds to a datetime structure + * + * @param seconds Seconds value that needs to be converted to datetime format + * @param datetime Pointer to the datetime structure where the result of the conversion is stored + */ +static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime); + +/******************************************************************************* + * Code + ******************************************************************************/ +static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime) +{ + /* Table of days in a month for a non leap year. First entry in the table is not used, + * valid months start from 1 + */ + uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + + /* Check year, month, hour, minute, seconds */ + if ((datetime->year < YEAR_RANGE_START) || (datetime->year > YEAR_RANGE_END) || (datetime->month > 12U) || + (datetime->month < 1U) || (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U)) + { + /* If not correct then error*/ + return false; + } + + /* Adjust the days in February for a leap year */ + if (!(datetime->year & 3U)) + { + daysPerMonth[2] = 29U; + } + + /* Check the validity of the day */ + if (datetime->day > daysPerMonth[datetime->month]) + { + return false; + } + + return true; +} + +static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime) +{ + /* Number of days from begin of the non Leap-year*/ + uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; + uint32_t seconds; + + /* Compute number of days from 1970 till given year*/ + seconds = (datetime->year - 1970U) * DAYS_IN_A_YEAR; + /* Add leap year days */ + seconds += ((datetime->year / 4) - (1970U / 4)); + /* Add number of days till given month*/ + seconds += monthDays[datetime->month]; + /* Add days in given month. We subtract the current day as it is + * represented in the hours, minutes and seconds field*/ + seconds += (datetime->day - 1); + /* For leap year if month less than or equal to Febraury, decrement day counter*/ + if ((!(datetime->year & 3U)) && (datetime->month <= 2U)) + { + seconds--; + } + + seconds = (seconds * SECONDS_IN_A_DAY) + (datetime->hour * SECONDS_IN_A_HOUR) + + (datetime->minute * SECONDS_IN_A_MINUTE) + datetime->second; + + return seconds; +} + +static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime) +{ + uint32_t x; + uint32_t secondsRemaining, days; + uint16_t daysInYear; + /* Table of days in a month for a non leap year. First entry in the table is not used, + * valid months start from 1 + */ + uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + + /* Start with the seconds value that is passed in to be converted to date time format */ + secondsRemaining = seconds; + + /* Calcuate the number of days, we add 1 for the current day which is represented in the + * hours and seconds field + */ + days = secondsRemaining / SECONDS_IN_A_DAY + 1; + + /* Update seconds left*/ + secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY; + + /* Calculate the datetime hour, minute and second fields */ + datetime->hour = secondsRemaining / SECONDS_IN_A_HOUR; + secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR; + datetime->minute = secondsRemaining / 60U; + datetime->second = secondsRemaining % SECONDS_IN_A_MINUTE; + + /* Calculate year */ + daysInYear = DAYS_IN_A_YEAR; + datetime->year = YEAR_RANGE_START; + while (days > daysInYear) + { + /* Decrease day count by a year and increment year by 1 */ + days -= daysInYear; + datetime->year++; + + /* Adjust the number of days for a leap year */ + if (datetime->year & 3U) + { + daysInYear = DAYS_IN_A_YEAR; + } + else + { + daysInYear = DAYS_IN_A_YEAR + 1; + } + } + + /* Adjust the days in February for a leap year */ + if (!(datetime->year & 3U)) + { + daysPerMonth[2] = 29U; + } + + for (x = 1U; x <= 12U; x++) + { + if (days <= daysPerMonth[x]) + { + datetime->month = x; + break; + } + else + { + days -= daysPerMonth[x]; + } + } + + datetime->day = days; +} + +void RTC_Init(RTC_Type *base, const rtc_config_t *config) +{ + assert(config); + + uint32_t reg; + + CLOCK_EnableClock(kCLOCK_Rtc0); + + /* Issue a software reset if timer is invalid */ + if (RTC_GetStatusFlags(RTC) & kRTC_TimeInvalidFlag) + { + RTC_Reset(RTC); + } + + reg = base->CR; + /* Setup the update mode and supervisor access mode */ + reg &= ~(RTC_CR_UM_MASK | RTC_CR_SUP_MASK); + reg |= RTC_CR_UM(config->updateMode) | RTC_CR_SUP(config->supervisorAccess); +#if defined(FSL_FEATURE_RTC_HAS_WAKEUP_PIN) && FSL_FEATURE_RTC_HAS_WAKEUP_PIN + /* Setup the wakeup pin select */ + reg &= ~(RTC_CR_WPS_MASK); + reg |= RTC_CR_WPS(config->wakeupSelect); +#endif /* FSL_FEATURE_RTC_HAS_WAKEUP_PIN */ + base->CR = reg; + + /* Configure the RTC time compensation register */ + base->TCR = (RTC_TCR_CIR(config->compensationInterval) | RTC_TCR_TCR(config->compensationTime)); +} + +void RTC_GetDefaultConfig(rtc_config_t *config) +{ + assert(config); + + /* Wakeup pin will assert if the RTC interrupt asserts or if the wakeup pin is turned on */ + config->wakeupSelect = false; + /* Registers cannot be written when locked */ + config->updateMode = false; + /* Non-supervisor mode write accesses are not supported and will generate a bus error */ + config->supervisorAccess = false; + /* Compensation interval used by the crystal compensation logic */ + config->compensationInterval = 0; + /* Compensation time used by the crystal compensation logic */ + config->compensationTime = 0; +} + +status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime) +{ + assert(datetime); + + /* Return error if the time provided is not valid */ + if (!(RTC_CheckDatetimeFormat(datetime))) + { + return kStatus_InvalidArgument; + } + + /* Set time in seconds */ + base->TSR = RTC_ConvertDatetimeToSeconds(datetime); + + return kStatus_Success; +} + +void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime) +{ + assert(datetime); + + uint32_t seconds = 0; + + seconds = base->TSR; + RTC_ConvertSecondsToDatetime(seconds, datetime); +} + +status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime) +{ + assert(alarmTime); + + uint32_t alarmSeconds = 0; + uint32_t currSeconds = 0; + + /* Return error if the alarm time provided is not valid */ + if (!(RTC_CheckDatetimeFormat(alarmTime))) + { + return kStatus_InvalidArgument; + } + + alarmSeconds = RTC_ConvertDatetimeToSeconds(alarmTime); + + /* Get the current time */ + currSeconds = base->TSR; + + /* Return error if the alarm time has passed */ + if (alarmSeconds < currSeconds) + { + return kStatus_Fail; + } + + /* Set alarm in seconds*/ + base->TAR = alarmSeconds; + + return kStatus_Success; +} + +void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime) +{ + assert(datetime); + + uint32_t alarmSeconds = 0; + + /* Get alarm in seconds */ + alarmSeconds = base->TAR; + + RTC_ConvertSecondsToDatetime(alarmSeconds, datetime); +} + +void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask) +{ + /* The alarm flag is cleared by writing to the TAR register */ + if (mask & kRTC_AlarmFlag) + { + base->TAR = 0U; + } + + /* The timer overflow flag is cleared by initializing the TSR register. + * The time counter should be disabled for this write to be successful + */ + if (mask & kRTC_TimeOverflowFlag) + { + base->TSR = 1U; + } + + /* The timer overflow flag is cleared by initializing the TSR register. + * The time counter should be disabled for this write to be successful + */ + if (mask & kRTC_TimeInvalidFlag) + { + base->TSR = 1U; + } +} + +#if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC) + +void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter) +{ + *counter = (((uint64_t)base->MCHR << 32) | ((uint64_t)base->MCLR)); +} + +void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter) +{ + /* Prepare to initialize the register with the new value written */ + base->MER &= ~RTC_MER_MCE_MASK; + + base->MCHR = (uint32_t)((counter) >> 32); + base->MCLR = (uint32_t)(counter); +} + +status_t RTC_IncrementMonotonicCounter(RTC_Type *base) +{ + if (base->SR & (RTC_SR_MOF_MASK | RTC_SR_TIF_MASK)) + { + return kStatus_Fail; + } + + /* Prepare to switch to increment mode */ + base->MER |= RTC_MER_MCE_MASK; + /* Write anything so the counter increments*/ + base->MCLR = 1U; + + return kStatus_Success; +} + +#endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rtc.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rtc.h new file mode 100644 index 0000000000..063d1d40c3 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_rtc.h @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_RTC_H_ +#define _FSL_RTC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup rtc_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_RTC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief List of RTC interrupts */ +typedef enum _rtc_interrupt_enable +{ + kRTC_TimeInvalidInterruptEnable = RTC_IER_TIIE_MASK, /*!< Time invalid interrupt.*/ + kRTC_TimeOverflowInterruptEnable = RTC_IER_TOIE_MASK, /*!< Time overflow interrupt.*/ + kRTC_AlarmInterruptEnable = RTC_IER_TAIE_MASK, /*!< Alarm interrupt.*/ + kRTC_SecondsInterruptEnable = RTC_IER_TSIE_MASK /*!< Seconds interrupt.*/ +} rtc_interrupt_enable_t; + +/*! @brief List of RTC flags */ +typedef enum _rtc_status_flags +{ + kRTC_TimeInvalidFlag = RTC_SR_TIF_MASK, /*!< Time invalid flag */ + kRTC_TimeOverflowFlag = RTC_SR_TOF_MASK, /*!< Time overflow flag */ + kRTC_AlarmFlag = RTC_SR_TAF_MASK /*!< Alarm flag*/ +} rtc_status_flags_t; + +/*! @brief List of RTC Oscillator capacitor load settings */ +typedef enum _rtc_osc_cap_load +{ + kRTC_Capacitor_2p = RTC_CR_SC2P_MASK, /*!< 2pF capacitor load */ + kRTC_Capacitor_4p = RTC_CR_SC4P_MASK, /*!< 4pF capacitor load */ + kRTC_Capacitor_8p = RTC_CR_SC8P_MASK, /*!< 8pF capacitor load */ + kRTC_Capacitor_16p = RTC_CR_SC16P_MASK /*!< 16pF capacitor load */ +} rtc_osc_cap_load_t; + +/*! @brief Structure is used to hold the date and time */ +typedef struct _rtc_datetime +{ + uint16_t year; /*!< Range from 1970 to 2099.*/ + uint8_t month; /*!< Range from 1 to 12.*/ + uint8_t day; /*!< Range from 1 to 31 (depending on month).*/ + uint8_t hour; /*!< Range from 0 to 23.*/ + uint8_t minute; /*!< Range from 0 to 59.*/ + uint8_t second; /*!< Range from 0 to 59.*/ +} rtc_datetime_t; + +/*! + * @brief RTC config structure + * + * This structure holds the configuration settings for the RTC peripheral. To initialize this + * structure to reasonable defaults, call the RTC_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The config struct can be made const so it resides in flash + */ +typedef struct _rtc_config +{ + bool wakeupSelect; /*!< true: Wakeup pin outputs the 32KHz clock; + false:Wakeup pin used to wakeup the chip */ + bool updateMode; /*!< true: Registers can be written even when locked under certain + conditions, false: No writes allowed when registers are locked */ + bool supervisorAccess; /*!< true: Non-supervisor accesses are allowed; + false: Non-supervisor accesses are not supported */ + uint32_t compensationInterval; /*!< Compensation interval that is written to the CIR field in RTC TCR Register */ + uint32_t compensationTime; /*!< Compensation time that is written to the TCR field in RTC TCR Register */ +} rtc_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the RTC clock and configures the peripheral for basic operation. + * + * This function will issue a software reset if the timer invalid flag is set. + * + * @note This API should be called at the beginning of the application using the RTC driver. + * + * @param base RTC peripheral base address + * @param config Pointer to user's RTC config structure. + */ +void RTC_Init(RTC_Type *base, const rtc_config_t *config); + +/*! + * @brief Stop the timer and gate the RTC clock + * + * @param base RTC peripheral base address + */ +static inline void RTC_Deinit(RTC_Type *base) +{ + /* Stop the RTC timer */ + base->SR &= ~RTC_SR_TCE_MASK; + + /* Gate the module clock */ + CLOCK_DisableClock(kCLOCK_Rtc0); +} + +/*! + * @brief Fill in the RTC config struct with the default settings + * + * The default values are: + * @code + * config->wakeupSelect = false; + * config->updateMode = false; + * config->supervisorAccess = false; + * config->compensationInterval = 0; + * config->compensationTime = 0; + * @endcode + * @param config Pointer to user's RTC config structure. + */ +void RTC_GetDefaultConfig(rtc_config_t *config); + +/*! @}*/ + +/*! + * @name Current Time & Alarm + * @{ + */ + +/*! + * @brief Sets the RTC date and time according to the given time structure. + * + * The RTC counter must be stopped prior to calling this function as writes to the RTC + * seconds register will fail if the RTC counter is running. + * + * @param base RTC peripheral base address + * @param datetime Pointer to structure where the date and time details to set are stored + * + * @return kStatus_Success: Success in setting the time and starting the RTC + * kStatus_InvalidArgument: Error because the datetime format is incorrect + */ +status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime); + +/*! + * @brief Gets the RTC time and stores it in the given time structure. + * + * @param base RTC peripheral base address + * @param datetime Pointer to structure where the date and time details are stored. + */ +void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime); + +/*! + * @brief Sets the RTC alarm time + * + * The function checks whether the specified alarm time is greater than the present + * time. If not, the function does not set the alarm and returns an error. + * + * @param base RTC peripheral base address + * @param alarmTime Pointer to structure where the alarm time is stored. + * + * @return kStatus_Success: success in setting the RTC alarm + * kStatus_InvalidArgument: Error because the alarm datetime format is incorrect + * kStatus_Fail: Error because the alarm time has already passed + */ +status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime); + +/*! + * @brief Returns the RTC alarm time. + * + * @param base RTC peripheral base address + * @param datetime Pointer to structure where the alarm date and time details are stored. + */ +void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime); + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected RTC interrupts. + * + * @param base RTC peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline void RTC_EnableInterrupts(RTC_Type *base, uint32_t mask) +{ + base->IER |= mask; +} + +/*! + * @brief Disables the selected RTC interrupts. + * + * @param base RTC peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline void RTC_DisableInterrupts(RTC_Type *base, uint32_t mask) +{ + base->IER &= ~mask; +} + +/*! + * @brief Gets the enabled RTC interrupts. + * + * @param base RTC peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline uint32_t RTC_GetEnabledInterrupts(RTC_Type *base) +{ + return (base->IER & (RTC_IER_TIIE_MASK | RTC_IER_TOIE_MASK | RTC_IER_TAIE_MASK | RTC_IER_TSIE_MASK)); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the RTC status flags + * + * @param base RTC peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::rtc_status_flags_t + */ +static inline uint32_t RTC_GetStatusFlags(RTC_Type *base) +{ + return (base->SR & (RTC_SR_TIF_MASK | RTC_SR_TOF_MASK | RTC_SR_TAF_MASK)); +} + +/*! + * @brief Clears the RTC status flags. + * + * @param base RTC peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::rtc_status_flags_t + */ +void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask); + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the RTC time counter. + * + * After calling this function, the timer counter increments once a second provided SR[TOF] or + * SR[TIF] are not set. + * + * @param base RTC peripheral base address + */ +static inline void RTC_StartTimer(RTC_Type *base) +{ + base->SR |= RTC_SR_TCE_MASK; +} + +/*! + * @brief Stops the RTC time counter. + * + * RTC's seconds register can be written to only when the timer is stopped. + * + * @param base RTC peripheral base address + */ +static inline void RTC_StopTimer(RTC_Type *base) +{ + base->SR &= ~RTC_SR_TCE_MASK; +} + +/*! @}*/ + +/*! + * @brief This function sets the specified capacitor configuration for the RTC oscillator. + * + * @param base RTC peripheral base address + * @param capLoad Oscillator loads to enable. This is a logical OR of members of the + * enumeration ::rtc_osc_cap_load_t + */ +static inline void RTC_SetOscCapLoad(RTC_Type *base, uint32_t capLoad) +{ + uint32_t reg = base->CR; + + reg &= ~(RTC_CR_SC2P_MASK | RTC_CR_SC4P_MASK | RTC_CR_SC8P_MASK | RTC_CR_SC16P_MASK); + reg |= capLoad; + + base->CR = reg; +} + +/*! + * @brief Performs a software reset on the RTC module. + * + * This resets all RTC registers except for the SWR bit and the RTC_WAR and RTC_RAR + * registers. The SWR bit is cleared by software explicitly clearing it. + * + * @param base RTC peripheral base address + */ +static inline void RTC_Reset(RTC_Type *base) +{ + base->CR |= RTC_CR_SWR_MASK; + base->CR &= ~RTC_CR_SWR_MASK; + + /* Set TSR register to 0x1 to avoid the timer invalid (TIF) bit being set in the SR register */ + base->TSR = 1U; +} + +#if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC) + +/*! + * @name Monotonic counter functions + * @{ + */ + +/*! + * @brief Reads the values of the Monotonic Counter High and Monotonic Counter Low and returns + * them as a single value. + * + * @param base RTC peripheral base address + * @param counter Pointer to variable where the value is stored. + */ +void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter); + +/*! + * @brief Writes values Monotonic Counter High and Monotonic Counter Low by decomposing + * the given single value. + * + * @param base RTC peripheral base address + * @param counter Counter value + */ +void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter); + +/*! + * @brief Increments the Monotonic Counter by one. + * + * Increments the Monotonic Counter (registers RTC_MCLR and RTC_MCHR accordingly) by setting + * the monotonic counter enable (MER[MCE]) and then writing to the RTC_MCLR register. A write to the + * monotonic counter low that causes it to overflow also increments the monotonic counter high. + * + * @param base RTC peripheral base address + * + * @return kStatus_Success: success + * kStatus_Fail: error occurred, either time invalid or monotonic overflow flag was found + */ +status_t RTC_IncrementMonotonicCounter(RTC_Type *base); + +/*! @}*/ + +#endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_RTC_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai.c new file mode 100644 index 0000000000..a45e9e6213 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai.c @@ -0,0 +1,1048 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sai.h" + +/******************************************************************************* + * Definitations + ******************************************************************************/ +enum _sai_transfer_state +{ + kSAI_Busy = 0x0U, /*!< SAI is busy */ + kSAI_Idle, /*!< Transfer is done. */ + kSAI_Error /*!< Transfer error occured. */ +}; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) + +/*! + * @brief Set the master clock divider. + * + * This API will compute the master clock divider according to master clock frequency and master + * clock source clock source frequency. + * + * @param base SAI base pointer. + * @param mclk_Hz Mater clock frequency in Hz. + * @param mclkSrcClock_Hz Master clock source frequency in Hz. + */ +static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz); +#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ + +/*! + * @brief Get the instance number for SAI. + * + * @param base SAI base pointer. + */ +uint32_t SAI_GetInstance(I2S_Type *base); + +/*! + * @brief sends a piece of data in non-blocking way. + * + * @param base SAI base pointer + * @param channel Data channel used. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be written. + * @param size Bytes to be written. + */ +static void SAI_WriteNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); + +/*! + * @brief Receive a piece of data in non-blocking way. + * + * @param base SAI base pointer + * @param channel Data channel used. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be read. + * @param size Bytes to be read. + */ +static void SAI_ReadNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); +/******************************************************************************* + * Variables + ******************************************************************************/ +/*!@brief SAI handle pointer */ +sai_handle_t *s_saiHandle[FSL_FEATURE_SOC_I2S_COUNT][2]; +/* Base pointer array */ +static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS; +/* IRQ number array */ +static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS; +static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS; +/* Clock name array */ +static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS; + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) +static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz) +{ + uint32_t freq = mclkSrcClock_Hz; + uint16_t fract, divide; + uint32_t remaind = 0; + uint32_t current_remainder = 0xFFFFFFFFU; + uint16_t current_fract = 0; + uint16_t current_divide = 0; + uint32_t mul_freq = 0; + uint32_t max_fract = 256; + + /*In order to prevent overflow */ + freq /= 100; + mclk_Hz /= 100; + + /* Compute the max fract number */ + max_fract = mclk_Hz * 4096 / freq + 1; + if (max_fract > 256) + { + max_fract = 256; + } + + /* Looking for the closet frequency */ + for (fract = 1; fract < max_fract; fract++) + { + mul_freq = freq * fract; + remaind = mul_freq % mclk_Hz; + divide = mul_freq / mclk_Hz; + + /* Find the exactly frequency */ + if (remaind == 0) + { + current_fract = fract; + current_divide = mul_freq / mclk_Hz; + break; + } + + /* Closer to next one, set the closest to next data */ + if (remaind > mclk_Hz / 2) + { + remaind = mclk_Hz - remaind; + divide += 1; + } + + /* Update the closest div and fract */ + if (remaind < current_remainder) + { + current_fract = fract; + current_divide = divide; + current_remainder = remaind; + } + } + + /* Fill the computed fract and divider to registers */ + base->MDR = I2S_MDR_DIVIDE(current_divide - 1) | I2S_MDR_FRACT(current_fract - 1); + + /* Waiting for the divider updated */ + while (base->MCR & I2S_MCR_DUF_MASK) + { + } +} +#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ + +uint32_t SAI_GetInstance(I2S_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_I2S_COUNT; instance++) + { + if (s_saiBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_I2S_COUNT); + + return instance; +} + +static void SAI_WriteNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) +{ + uint32_t i = 0; + uint8_t j = 0; + uint8_t bytesPerWord = bitWidth / 8U; + uint32_t data = 0; + uint32_t temp = 0; + + for (i = 0; i < size / bytesPerWord; i++) + { + for (j = 0; j < bytesPerWord; j++) + { + temp = (uint32_t)(*buffer); + data |= (temp << (8U * j)); + buffer++; + } + base->TDR[channel] = data; + data = 0; + } +} + +static void SAI_ReadNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) +{ + uint32_t i = 0; + uint8_t j = 0; + uint8_t bytesPerWord = bitWidth / 8U; + uint32_t data = 0; + + for (i = 0; i < size / bytesPerWord; i++) + { + data = base->RDR[channel]; + for (j = 0; j < bytesPerWord; j++) + { + *buffer = (data >> (8U * j)) & 0xFF; + buffer++; + } + } +} + +void SAI_TxInit(I2S_Type *base, const sai_config_t *config) +{ + uint32_t val = 0; + + /* Enable the SAI clock */ + CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); + +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + /* Configure Master clock output enable */ + base->MCR = I2S_MCR_MOE(config->mclkOutputEnable); + + /* Master clock source setting */ + val = (base->MCR & ~I2S_MCR_MICS_MASK); + base->MCR = (val | I2S_MCR_MICS(config->mclkSource)); +#endif /* FSL_FEATURE_SAI_HAS_MCR */ + + /* Configure audio protocol */ + switch (config->protocol) + { + case kSAI_BusLeftJustified: + base->TCR2 |= I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); + break; + + case kSAI_BusRightJustified: + base->TCR2 |= I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); + break; + + case kSAI_BusI2S: + base->TCR2 |= I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(1U) | I2S_TCR4_FRSZ(1U); + break; + + case kSAI_BusPCMA: + base->TCR2 &= ~I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); + break; + + case kSAI_BusPCMB: + base->TCR2 &= ~I2S_TCR2_BCP_MASK; + base->TCR3 &= ~I2S_TCR3_WDFL_MASK; + base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); + break; + + default: + break; + } + + /* Set master or slave */ + if (config->masterSlave == kSAI_Master) + { + base->TCR2 |= I2S_TCR2_BCD_MASK; + base->TCR4 |= I2S_TCR4_FSD_MASK; + + /* Bit clock source setting */ + val = base->TCR2 & (~I2S_TCR2_MSEL_MASK); + base->TCR2 = (val | I2S_TCR2_MSEL(config->bclkSource)); + } + else + { + base->TCR2 &= ~I2S_TCR2_BCD_MASK; + base->TCR4 &= ~I2S_TCR4_FSD_MASK; + } + + /* Set Sync mode */ + switch (config->syncMode) + { + case kSAI_ModeAsync: + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(0U)); + break; + case kSAI_ModeSync: + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(1U)); + /* If sync with Rx, should set Rx to async mode */ + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(0U)); + break; + case kSAI_ModeSyncWithOtherTx: + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(2U)); + break; + case kSAI_ModeSyncWithOtherRx: + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(3U)); + break; + default: + break; + } +} + +void SAI_RxInit(I2S_Type *base, const sai_config_t *config) +{ + uint32_t val = 0; + + /* Enable SAI clock first. */ + CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); + +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + /* Configure Master clock output enable */ + base->MCR = I2S_MCR_MOE(config->mclkOutputEnable); + + /* Master clock source setting */ + val = (base->MCR & ~I2S_MCR_MICS_MASK); + base->MCR = (val | I2S_MCR_MICS(config->mclkSource)); +#endif /* FSL_FEATURE_SAI_HAS_MCR */ + + /* Configure audio protocol */ + switch (config->protocol) + { + case kSAI_BusLeftJustified: + base->RCR2 |= I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); + break; + + case kSAI_BusRightJustified: + base->RCR2 |= I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); + break; + + case kSAI_BusI2S: + base->RCR2 |= I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(1U) | I2S_RCR4_FRSZ(1U); + break; + + case kSAI_BusPCMA: + base->RCR2 &= ~I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); + break; + + case kSAI_BusPCMB: + base->RCR2 &= ~I2S_RCR2_BCP_MASK; + base->RCR3 &= ~I2S_RCR3_WDFL_MASK; + base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); + break; + + default: + break; + } + + /* Set master or slave */ + if (config->masterSlave == kSAI_Master) + { + base->RCR2 |= I2S_RCR2_BCD_MASK; + base->RCR4 |= I2S_RCR4_FSD_MASK; + + /* Bit clock source setting */ + val = base->RCR2 & (~I2S_RCR2_MSEL_MASK); + base->RCR2 = (val | I2S_RCR2_MSEL(config->bclkSource)); + } + else + { + base->RCR2 &= ~I2S_RCR2_BCD_MASK; + base->RCR4 &= ~I2S_RCR4_FSD_MASK; + } + + /* Set Sync mode */ + switch (config->syncMode) + { + case kSAI_ModeAsync: + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(0U)); + break; + case kSAI_ModeSync: + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(1U)); + /* If sync with Tx, should set Tx to async mode */ + val = base->TCR2; + val &= ~I2S_TCR2_SYNC_MASK; + base->TCR2 = (val | I2S_TCR2_SYNC(0U)); + break; + case kSAI_ModeSyncWithOtherTx: + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(2U)); + break; + case kSAI_ModeSyncWithOtherRx: + val = base->RCR2; + val &= ~I2S_RCR2_SYNC_MASK; + base->RCR2 = (val | I2S_RCR2_SYNC(3U)); + break; + default: + break; + } +} + +void SAI_Deinit(I2S_Type *base) +{ + SAI_TxEnable(base, false); + SAI_RxEnable(base, false); + CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]); +} + +void SAI_TxGetDefaultConfig(sai_config_t *config) +{ + config->bclkSource = kSAI_BclkSourceMclkDiv; + config->masterSlave = kSAI_Master; + config->mclkSource = kSAI_MclkSourceSysclk; + config->protocol = kSAI_BusLeftJustified; + config->syncMode = kSAI_ModeAsync; +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + config->mclkOutputEnable = true; +#endif /* FSL_FEATURE_SAI_HAS_MCR */ +} + +void SAI_RxGetDefaultConfig(sai_config_t *config) +{ + config->bclkSource = kSAI_BclkSourceMclkDiv; + config->masterSlave = kSAI_Master; + config->mclkSource = kSAI_MclkSourceSysclk; + config->protocol = kSAI_BusLeftJustified; + config->syncMode = kSAI_ModeSync; +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + config->mclkOutputEnable = true; +#endif /* FSL_FEATURE_SAI_HAS_MCR */ +} + +void SAI_TxReset(I2S_Type *base) +{ + /* Set the software reset and FIFO reset to clear internal state */ + base->TCSR = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK; + + /* Clear software reset bit, this should be done by software */ + base->TCSR &= ~I2S_TCSR_SR_MASK; + + /* Reset all Tx register values */ + base->TCR2 = 0; + base->TCR3 = 0; + base->TCR4 = 0; + base->TCR5 = 0; + base->TMR = 0; +} + +void SAI_RxReset(I2S_Type *base) +{ + /* Set the software reset and FIFO reset to clear internal state */ + base->RCSR = I2S_RCSR_SR_MASK | I2S_RCSR_FR_MASK; + + /* Clear software reset bit, this should be done by software */ + base->RCSR &= ~I2S_RCSR_SR_MASK; + + /* Reset all Rx register values */ + base->RCR2 = 0; + base->RCR3 = 0; + base->RCR4 = 0; + base->RCR5 = 0; + base->RMR = 0; +} + +void SAI_TxEnable(I2S_Type *base, bool enable) +{ + if (enable) + { + /* If clock is sync with Rx, should enable RE bit. */ + if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) == 0x1U) + { + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK); + } + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK); + } + else + { + /* Should not close RE even sync with Rx */ + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~I2S_TCSR_TE_MASK)); + } +} + +void SAI_RxEnable(I2S_Type *base, bool enable) +{ + if (enable) + { + /* If clock is sync with Tx, should enable TE bit. */ + if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) == 0x1U) + { + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK); + } + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK); + } + else + { + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~I2S_RCSR_RE_MASK)); + } +} + +void SAI_TxSetFormat(I2S_Type *base, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + uint32_t bclk = format->sampleRate_Hz * 32U * 2U; + +/* Compute the mclk */ +#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) + /* Check if master clock divider enabled, then set master clock divider */ + if (base->MCR & I2S_MCR_MOE_MASK) + { + SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz); + } +#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ + + /* Set bclk if needed */ + if (base->TCR2 & I2S_TCR2_BCD_MASK) + { + base->TCR2 &= ~I2S_TCR2_DIV_MASK; + base->TCR2 |= I2S_TCR2_DIV((bclkSourceClockHz / bclk) / 2U - 1U); + } + + /* Set bitWidth */ + if (format->protocol == kSAI_BusRightJustified) + { + base->TCR5 = I2S_TCR5_WNW(31U) | I2S_TCR5_W0W(31U) | I2S_TCR5_FBT(31U); + } + else + { + base->TCR5 = I2S_TCR5_WNW(31U) | I2S_TCR5_W0W(31U) | I2S_TCR5_FBT(format->bitWidth - 1); + } + + /* Set mono or stereo */ + base->TMR = (uint32_t)format->stereo; + + /* Set data channel */ + base->TCR3 &= ~I2S_TCR3_TCE_MASK; + base->TCR3 |= I2S_TCR3_TCE(1U << format->channel); + +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Set watermark */ + base->TCR1 = format->watermark; +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +} + +void SAI_RxSetFormat(I2S_Type *base, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + uint32_t bclk = format->sampleRate_Hz * 32U * 2U; + +/* Compute the mclk */ +#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) + /* Check if master clock divider enabled */ + if (base->MCR & I2S_MCR_MOE_MASK) + { + SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz); + } +#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ + + /* Set bclk if needed */ + if (base->RCR2 & I2S_RCR2_BCD_MASK) + { + base->RCR2 &= ~I2S_RCR2_DIV_MASK; + base->RCR2 |= I2S_RCR2_DIV((bclkSourceClockHz / bclk) / 2U - 1U); + } + + /* Set bitWidth */ + if (format->protocol == kSAI_BusRightJustified) + { + base->RCR5 = I2S_RCR5_WNW(31U) | I2S_RCR5_W0W(31U) | I2S_RCR5_FBT(31U); + } + else + { + base->RCR5 = I2S_RCR5_WNW(31U) | I2S_RCR5_W0W(31U) | I2S_RCR5_FBT(format->bitWidth - 1); + } + + /* Set mono or stereo */ + base->RMR = (uint32_t)format->stereo; + + /* Set data channel */ + base->RCR3 &= ~I2S_RCR3_RCE_MASK; + base->RCR3 |= I2S_RCR3_RCE(1U << format->channel); + +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Set watermark */ + base->RCR1 = format->watermark; +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +} + +void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) +{ + uint32_t i = 0; + uint8_t bytesPerWord = bitWidth / 8U; + + for (i = 0; i < size; i++) + { + /* Wait until it can write data */ + while (!(base->TCSR & I2S_TCSR_FWF_MASK)) + { + } + + SAI_WriteNonBlocking(base, channel, bitWidth, buffer, bytesPerWord); + buffer += bytesPerWord; + } + + /* Wait until the last data is sent */ + while (!(base->TCSR & I2S_TCSR_FWF_MASK)) + { + } +} + +void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) +{ + uint32_t i = 0; + uint8_t bytesPerWord = bitWidth / 8U; + + for (i = 0; i < size; i++) + { + /* Wait until data is received */ + while (!(base->RCSR & I2S_RCSR_FWF_MASK)) + { + } + + SAI_ReadNonBlocking(base, channel, bitWidth, buffer, bytesPerWord); + buffer += bytesPerWord; + } +} + +void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData) +{ + assert(handle); + + s_saiHandle[SAI_GetInstance(base)][0] = handle; + + handle->callback = callback; + handle->userData = userData; + + /* Enable Tx irq */ + EnableIRQ(s_saiTxIRQ[SAI_GetInstance(base)]); +} + +void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData) +{ + assert(handle); + + s_saiHandle[SAI_GetInstance(base)][1] = handle; + + handle->callback = callback; + handle->userData = userData; + + /* Enable Rx irq */ + EnableIRQ(s_saiRxIRQ[SAI_GetInstance(base)]); +} + +status_t SAI_TransferTxSetFormat(I2S_Type *base, + sai_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + assert(handle); + + if ((mclkSourceClockHz < format->sampleRate_Hz) || (bclkSourceClockHz < format->sampleRate_Hz)) + { + return kStatus_InvalidArgument; + } + + /* Copy format to handle */ + handle->bitWidth = format->bitWidth; +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + handle->watermark = format->watermark; +#endif + handle->channel = format->channel; + + SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); + + return kStatus_Success; +} + +status_t SAI_TransferRxSetFormat(I2S_Type *base, + sai_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + assert(handle); + + if ((mclkSourceClockHz < format->sampleRate_Hz) || (bclkSourceClockHz < format->sampleRate_Hz)) + { + return kStatus_InvalidArgument; + } + + /* Copy format to handle */ + handle->bitWidth = format->bitWidth; +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + handle->watermark = format->watermark; +#endif + handle->channel = format->channel; + + SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); + + return kStatus_Success; +} + +status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer) +{ + assert(handle); + + /* Check if the queue is full */ + if (handle->saiQueue[handle->queueUser].data) + { + return kStatus_SAI_QueueFull; + } + + /* Add into queue */ + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->saiQueue[handle->queueUser].data = xfer->data; + handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE; + + /* Set the state to busy */ + handle->state = kSAI_Busy; + +/* Enable interrupt */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Use FIFO request interrupt and fifo error*/ + SAI_TxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable); +#else + SAI_TxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable); +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + /* Enable Tx transfer */ + SAI_TxEnable(base, true); + + return kStatus_Success; +} + +status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer) +{ + assert(handle); + + /* Check if the queue is full */ + if (handle->saiQueue[handle->queueUser].data) + { + return kStatus_SAI_QueueFull; + } + + /* Add into queue */ + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->saiQueue[handle->queueUser].data = xfer->data; + handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE; + + /* Set state to busy */ + handle->state = kSAI_Busy; + +/* Enable interrupt */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Use FIFO request interrupt and fifo error*/ + SAI_RxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable); +#else + SAI_RxEnableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable); +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + /* Enable Rx transfer */ + SAI_RxEnable(base, true); + + return kStatus_Success; +} + +status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSAI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - handle->saiQueue[handle->queueDriver].dataSize); + } + + return status; +} + +status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSAI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = (handle->transferSize[handle->queueDriver] - handle->saiQueue[handle->queueDriver].dataSize); + } + + return status; +} + +void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle) +{ + assert(handle); + + /* Stop Tx transfer and disable interrupt */ + SAI_TxEnable(base, false); +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Use FIFO request interrupt and fifo error */ + SAI_TxDisableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable); +#else + SAI_TxDisableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable); +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + handle->state = kSAI_Idle; + + /* Clear the queue */ + memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle) +{ + assert(handle); + + /* Stop Tx transfer and disable interrupt */ + SAI_RxEnable(base, false); +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + /* Use FIFO request interrupt and fifo error */ + SAI_RxDisableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable); +#else + SAI_RxDisableInterrupts(base, kSAI_FIFOErrorInterruptEnable | kSAI_FIFOWarningInterruptEnable); +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + handle->state = kSAI_Idle; + + /* Clear the queue */ + memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle) +{ + assert(handle); + + uint8_t *buffer = handle->saiQueue[handle->queueDriver].data; + uint8_t dataSize = handle->bitWidth / 8U; + + /* Handle Error */ + if (base->TCSR & I2S_TCSR_FEF_MASK) + { + /* Clear FIFO error flag to continue transfer */ + SAI_TxClearStatusFlags(base, kSAI_FIFOErrorFlag); + + /* Call the callback */ + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SAI_TxError, handle->userData); + } + } + +/* Handle transfer */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if (base->TCSR & I2S_TCSR_FRF_MASK) + { + /* Judge if the data need to transmit is less than space */ + uint8_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), + (size_t)((FSL_FEATURE_SAI_FIFO_COUNT - handle->watermark) * dataSize)); + + /* Copy the data from sai buffer to FIFO */ + SAI_WriteNonBlocking(base, handle->channel, handle->bitWidth, buffer, size); + + /* Update the internal counter */ + handle->saiQueue[handle->queueDriver].dataSize -= size; + handle->saiQueue[handle->queueDriver].data += size; + } +#else + if (base->TCSR & I2S_TCSR_FWF_MASK) + { + uint8_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize); + + SAI_WriteNonBlocking(base, handle->channel, handle->bitWidth, buffer, size); + + /* Update internal counter */ + handle->saiQueue[handle->queueDriver].dataSize -= size; + handle->saiQueue[handle->queueDriver].data += size; + } +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + /* If finished a blcok, call the callback function */ + if (handle->saiQueue[handle->queueDriver].dataSize == 0U) + { + memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t)); + handle->queueDriver = (handle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE; + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SAI_TxIdle, handle->userData); + } + } + + /* If all data finished, just stop the transfer */ + if (handle->saiQueue[handle->queueDriver].data == NULL) + { + SAI_TransferAbortSend(base, handle); + } +} + +void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle) +{ + assert(handle); + + uint8_t *buffer = handle->saiQueue[handle->queueDriver].data; + uint8_t dataSize = handle->bitWidth / 8U; + + /* Handle Error */ + if (base->RCSR & I2S_RCSR_FEF_MASK) + { + /* Clear FIFO error flag to continue transfer */ + SAI_RxClearStatusFlags(base, kSAI_FIFOErrorFlag); + + /* Call the callback */ + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SAI_RxError, handle->userData); + } + } + +/* Handle transfer */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if (base->RCSR & I2S_RCSR_FRF_MASK) + { + /* Judge if the data need to transmit is less than space */ + uint8_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), (handle->watermark * dataSize)); + + /* Copy the data from sai buffer to FIFO */ + SAI_ReadNonBlocking(base, handle->channel, handle->bitWidth, buffer, size); + + /* Update the internal counter */ + handle->saiQueue[handle->queueDriver].dataSize -= size; + handle->saiQueue[handle->queueDriver].data += size; + } +#else + if (base->RCSR & I2S_RCSR_FWF_MASK) + { + uint8_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize); + + SAI_ReadNonBlocking(base, handle->channel, handle->bitWidth, buffer, size); + + /* Update internal state */ + handle->saiQueue[handle->queueDriver].dataSize -= size; + handle->saiQueue[handle->queueDriver].data += size; + } +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + + /* If finished a blcok, call the callback function */ + if (handle->saiQueue[handle->queueDriver].dataSize == 0U) + { + memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t)); + handle->queueDriver = (handle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE; + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SAI_RxIdle, handle->userData); + } + } + + /* If all data finished, just stop the transfer */ + if (handle->saiQueue[handle->queueDriver].data == NULL) + { + SAI_TransferAbortReceive(base, handle); + } +} + +#if defined(I2S0) +#if defined(FSL_FEATURE_SAI_INT_SOURCE_NUM) && (FSL_FEATURE_SAI_INT_SOURCE_NUM == 1) +void I2S0_DriverIRQHandler(void) +{ + if ((s_saiHandle[0][1]) && ((I2S0->RCSR & kSAI_FIFOWarningFlag) || (I2S0->RCSR & kSAI_FIFOErrorFlag))) + { + SAI_TransferRxHandleIRQ(I2S0, s_saiHandle[0][1]); + } + if ((s_saiHandle[0][0]) && ((I2S0->TCSR & kSAI_FIFOWarningFlag) || (I2S0->TCSR & kSAI_FIFOErrorFlag))) + { + SAI_TransferTxHandleIRQ(I2S0, s_saiHandle[0][0]); + } +} +#else +void I2S0_Tx_DriverIRQHandler(void) +{ + assert(s_saiHandle[0][0]); + SAI_TransferTxHandleIRQ(I2S0, s_saiHandle[0][0]); +} + +void I2S0_Rx_DriverIRQHandler(void) +{ + assert(s_saiHandle[0][1]); + SAI_TransferRxHandleIRQ(I2S0, s_saiHandle[0][1]); +} +#endif /* FSL_FEATURE_SAI_INT_SOURCE_NUM */ +#endif /* I2S0*/ + +#if defined(I2S1) +void I2S1_Tx_DriverIRQHandler(void) +{ + assert(s_saiHandle[1][0]); + SAI_TransferTxHandleIRQ(I2S1, s_saiHandle[1][0]); +} + +void I2S1_Rx_DriverIRQHandler(void) +{ + assert(s_saiHandle[1][1]); + SAI_TransferRxHandleIRQ(I2S1, s_saiHandle[1][1]); +} +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai.h new file mode 100644 index 0000000000..72b6efd06b --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai.h @@ -0,0 +1,850 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SAI_H_ +#define _FSL_SAI_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup sai + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_SAI_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0 */ +/*@}*/ + +/*! @brief SAI return status*/ +enum _sai_status_t +{ + kStatus_SAI_TxBusy = MAKE_STATUS(kStatusGroup_SAI, 0), /*!< SAI Tx is busy. */ + kStatus_SAI_RxBusy = MAKE_STATUS(kStatusGroup_SAI, 1), /*!< SAI Rx is busy. */ + kStatus_SAI_TxError = MAKE_STATUS(kStatusGroup_SAI, 2), /*!< SAI Tx FIFO error. */ + kStatus_SAI_RxError = MAKE_STATUS(kStatusGroup_SAI, 3), /*!< SAI Rx FIFO error. */ + kStatus_SAI_QueueFull = MAKE_STATUS(kStatusGroup_SAI, 4), /*!< SAI transfer queue is full. */ + kStatus_SAI_TxIdle = MAKE_STATUS(kStatusGroup_SAI, 5), /*!< SAI Tx is idle */ + kStatus_SAI_RxIdle = MAKE_STATUS(kStatusGroup_SAI, 6) /*!< SAI Rx is idle */ +}; + +/*! @brief Define the SAI bus type */ +typedef enum _sai_protocol +{ + kSAI_BusLeftJustified = 0x0U, /*!< Uses left justified format.*/ + kSAI_BusRightJustified, /*!< Uses right justified format. */ + kSAI_BusI2S, /*!< Uses I2S format. */ + kSAI_BusPCMA, /*!< Uses I2S PCM A format.*/ + kSAI_BusPCMB /*!< Uses I2S PCM B format. */ +} sai_protocol_t; + +/*! @brief Master or slave mode */ +typedef enum _sai_master_slave +{ + kSAI_Master = 0x0U, /*!< Master mode */ + kSAI_Slave = 0x1U /*!< Slave mode */ +} sai_master_slave_t; + +/*! @brief Mono or stereo audio format */ +typedef enum _sai_mono_stereo +{ + kSAI_Stereo = 0x0U, /*!< Stereo sound. */ + kSAI_MonoLeft, /*!< Only left channel have sound. */ + kSAI_MonoRight /*!< Only Right channel have sound. */ +} sai_mono_stereo_t; + +/*! @brief Synchronous or asynchronous mode */ +typedef enum _sai_sync_mode +{ + kSAI_ModeAsync = 0x0U, /*!< Asynchronous mode */ + kSAI_ModeSync, /*!< Synchronous mode (with receiver or transmit) */ + kSAI_ModeSyncWithOtherTx, /*!< Synchronous with another SAI transmit */ + kSAI_ModeSyncWithOtherRx /*!< Synchronous with another SAI receiver */ +} sai_sync_mode_t; + +/*! @brief Mater clock source */ +typedef enum _sai_mclk_source +{ + kSAI_MclkSourceSysclk = 0x0U, /*!< Master clock from the system clock */ + kSAI_MclkSourceSelect1, /*!< Master clock from source 1 */ + kSAI_MclkSourceSelect2, /*!< Master clock from source 2 */ + kSAI_MclkSourceSelect3 /*!< Master clock from source 3 */ +} sai_mclk_source_t; + +/*! @brief Bit clock source */ +typedef enum _sai_bclk_source +{ + kSAI_BclkSourceBusclk = 0x0U, /*!< Bit clock using bus clock */ + kSAI_BclkSourceMclkDiv, /*!< Bit clock using master clock divider */ + kSAI_BclkSourceOtherSai0, /*!< Bit clock from other SAI device */ + kSAI_BclkSourceOtherSai1 /*!< Bit clock from other SAI device */ +} sai_bclk_source_t; + +/*! @brief The SAI interrupt enable flag */ +enum _sai_interrupt_enable_t +{ + kSAI_WordStartInterruptEnable = + I2S_TCSR_WSIE_MASK, /*!< Word start flag, means the first word in a frame detected */ + kSAI_SyncErrorInterruptEnable = I2S_TCSR_SEIE_MASK, /*!< Sync error flag, means the sync error is detected */ + kSAI_FIFOWarningInterruptEnable = I2S_TCSR_FWIE_MASK, /*!< FIFO warning flag, means the FIFO is empty */ + kSAI_FIFOErrorInterruptEnable = I2S_TCSR_FEIE_MASK, /*!< FIFO error flag */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + kSAI_FIFORequestInterruptEnable = I2S_TCSR_FRIE_MASK, /*!< FIFO request, means reached watermark */ +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +}; + +/*! @brief The DMA request sources */ +enum _sai_dma_enable_t +{ + kSAI_FIFOWarningDMAEnable = I2S_TCSR_FWDE_MASK, /*!< FIFO warning caused by the DMA request */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + kSAI_FIFORequestDMAEnable = I2S_TCSR_FRDE_MASK, /*!< FIFO request caused by the DMA request */ +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ +}; + +/*! @brief The SAI status flag */ +enum _sai_flags +{ + kSAI_WordStartFlag = I2S_TCSR_WSF_MASK, /*!< Word start flag, means the first word in a frame detected */ + kSAI_SyncErrorFlag = I2S_TCSR_SEF_MASK, /*!< Sync error flag, means the sync error is detected */ + kSAI_FIFOErrorFlag = I2S_TCSR_FEF_MASK, /*!< FIFO error flag */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + kSAI_FIFORequestFlag = I2S_TCSR_FRF_MASK, /*!< FIFO request flag. */ +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + kSAI_FIFOWarningFlag = I2S_TCSR_FWF_MASK, /*!< FIFO warning flag */ +}; + +/*! @brief The reset type */ +typedef enum _sai_reset_type +{ + kSAI_ResetTypeSoftware = I2S_TCSR_SR_MASK, /*!< Software reset, reset the logic state */ + kSAI_ResetTypeFIFO = I2S_TCSR_FR_MASK, /*!< FIFO reset, reset the FIFO read and write pointer */ + kSAI_ResetAll = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK /*!< All reset. */ +} sai_reset_type_t; + +#if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING +/*! + * @brief The SAI packing mode + * The mode includes 8 bit and 16 bit packing. + */ +typedef enum _sai_fifo_packing +{ + kSAI_FifoPackingDisabled = 0x0U, /*!< Packing disabled */ + kSAI_FifoPacking8bit = 0x2U, /*!< 8 bit packing enabled */ + kSAI_FifoPacking16bit = 0x3U /*!< 16bit packing enabled */ +} sai_fifo_packing_t; +#endif /* FSL_FEATURE_SAI_HAS_FIFO_PACKING */ + +/*! @brief SAI user configure structure */ +typedef struct _sai_config +{ + sai_protocol_t protocol; /*!< Audio bus protocol in SAI */ + sai_sync_mode_t syncMode; /*!< SAI sync mode, control Tx/Rx clock sync */ +#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) + bool mclkOutputEnable; /*!< Master clock output enable, true means master clock divider enabled */ +#endif /* FSL_FEATURE_SAI_HAS_MCR */ + sai_mclk_source_t mclkSource; /*!< Master Clock source */ + sai_bclk_source_t bclkSource; /*!< Bit Clock source */ + sai_master_slave_t masterSlave; /*!< Master or slave */ +} sai_config_t; + +/*!@brief SAI transfer queue size, user can refine it according to use case. */ +#define SAI_XFER_QUEUE_SIZE (4) + +/*! @brief Audio sample rate */ +typedef enum _sai_sample_rate +{ + kSAI_SampleRate8KHz = 8000U, /*!< Sample rate 8000Hz */ + kSAI_SampleRate11025Hz = 11025U, /*!< Sample rate 11025Hz */ + kSAI_SampleRate12KHz = 12000U, /*!< Sample rate 12000Hz */ + kSAI_SampleRate16KHz = 16000U, /*!< Sample rate 16000Hz */ + kSAI_SampleRate22050Hz = 22050U, /*!< Sample rate 22050Hz */ + kSAI_SampleRate24KHz = 24000U, /*!< Sample rate 24000Hz */ + kSAI_SampleRate32KHz = 32000U, /*!< Sample rate 32000Hz */ + kSAI_SampleRate44100Hz = 44100U, /*!< Sample rate 44100Hz */ + kSAI_SampleRate48KHz = 48000U, /*!< Sample rate 48000Hz */ + kSAI_SampleRate96KHz = 96000U /*!< Sample rate 96000Hz */ +} sai_sample_rate_t; + +/*! @brief Audio word width */ +typedef enum _sai_word_width +{ + kSAI_WordWidth8bits = 8U, /*!< Audio data width 8 bits */ + kSAI_WordWidth16bits = 16U, /*!< Audio data width 16 bits */ + kSAI_WordWidth24bits = 24U, /*!< Audio data width 24 bits */ + kSAI_WordWidth32bits = 32U /*!< Audio data width 32 bits */ +} sai_word_width_t; + +/*! @brief sai transfer format */ +typedef struct _sai_transfer_format +{ + uint32_t sampleRate_Hz; /*!< Sample rate of audio data */ + uint32_t bitWidth; /*!< Data length of audio data, usually 8/16/24/32bits */ + sai_mono_stereo_t stereo; /*!< Mono or stereo */ + uint32_t masterClockHz; /*!< Master clock frequency in Hz */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + uint8_t watermark; /*!< Watermark value */ +#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ + uint8_t channel; /*!< Data channel used in transfer.*/ + sai_protocol_t protocol; /*!< Which audio protocol used */ +} sai_transfer_format_t; + +/*! @brief SAI transfer structure */ +typedef struct _sai_transfer +{ + uint8_t *data; /*!< Data start address to transfer. */ + size_t dataSize; /*!< Transfer size. */ +} sai_transfer_t; + +typedef struct _sai_handle sai_handle_t; + +/*! @brief SAI transfer callback prototype */ +typedef void (*sai_transfer_callback_t)(I2S_Type *base, sai_handle_t *handle, status_t status, void *userData); + +/*! @brief SAI handle structure */ +struct _sai_handle +{ + uint32_t state; /*!< Transfer status */ + sai_transfer_callback_t callback; /*!< Callback function called at transfer event*/ + void *userData; /*!< Callback parameter passed to callback function*/ + uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32bits */ + uint8_t channel; /*!< Transfer channel */ + sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */ + size_t transferSize[SAI_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ + volatile uint8_t queueUser; /*!< Index for user to queue transfer */ + volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + uint8_t watermark; /*!< Watermark value */ +#endif +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the SAI Tx peripheral. + * + * Ungates the SAI clock, resets the module, and configures SAI Tx with a configuration structure. + * The configuration structure can be custom filled or set with default values by + * SAI_TxGetDefaultConfig(). + * + * @note This API should be called at the beginning of the application to use + * the SAI driver. Otherwise, accessing the SAIM module can cause a hard fault + * because the clock is not enabled. + * + * @param base SAI base pointer + * @param config SAI configure structure. +*/ +void SAI_TxInit(I2S_Type *base, const sai_config_t *config); + +/*! + * @brief Initializes the the SAI Rx peripheral. + * + * Ungates the SAI clock, resets the module, and configures the SAI Rx with a configuration structure. + * The configuration structure can be custom filled or set with default values by + * SAI_RxGetDefaultConfig(). + * + * @note This API should be called at the beginning of the application to use + * the SAI driver. Otherwise, accessing the SAI module can cause a hard fault + * because the clock is not enabled. + * + * @param base SAI base pointer + * @param config SAI configure structure. + */ +void SAI_RxInit(I2S_Type *base, const sai_config_t *config); + +/*! + * @brief Sets the SAI Tx configuration structure to default values. + * + * This API initializes the configuration structure for use in SAI_TxConfig(). + * The initialized structure can remain unchanged in SAI_TxConfig(), or it can be modified + * before calling SAI_TxConfig(). + * Example: + @code + sai_config_t config; + SAI_TxGetDefaultConfig(&config); + @endcode + * + * @param config pointer to master configuration structure + */ +void SAI_TxGetDefaultConfig(sai_config_t *config); + +/*! + * @brief Sets the SAI Rx configuration structure to default values. + * + * This API initializes the configuration structure for use in SAI_RxConfig(). + * The initialized structure can remain unchanged in SAI_RxConfig() or it can be modified + * before calling SAI_RxConfig(). + * Example: + @code + sai_config_t config; + SAI_RxGetDefaultConfig(&config); + @endcode + * + * @param config pointer to master configuration structure + */ +void SAI_RxGetDefaultConfig(sai_config_t *config); + +/*! + * @brief De-initializes the SAI peripheral. + * + * This API gates the SAI clock. The SAI module can't operate unless SAI_TxInit + * or SAI_RxInit is called to enable the clock. + * + * @param base SAI base pointer +*/ +void SAI_Deinit(I2S_Type *base); + +/*! + * @brief Resets the SAI Tx. + * + * This function enables the software reset and FIFO reset of SAI Tx. After reset, clear the reset bit. + * + * @param base SAI base pointer + */ +void SAI_TxReset(I2S_Type *base); + +/*! + * @brief Resets the SAI Rx. + * + * This function enables the software reset and FIFO reset of SAI Rx. After reset, clear the reset bit. + * + * @param base SAI base pointer + */ +void SAI_RxReset(I2S_Type *base); + +/*! + * @brief Enables/disables SAI Tx. + * + * @param base SAI base pointer + * @param enable True means enable SAI Tx, false means disable. + */ +void SAI_TxEnable(I2S_Type *base, bool enable); + +/*! + * @brief Enables/disables SAI Rx. + * + * @param base SAI base pointer + * @param enable True means enable SAI Rx, false means disable. + */ +void SAI_RxEnable(I2S_Type *base, bool enable); + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the SAI Tx status flag state. + * + * @param base SAI base pointer + * @return SAI Tx status flag value. Use the Status Mask to get the status value needed. + */ +static inline uint32_t SAI_TxGetStatusFlag(I2S_Type *base) +{ + return base->TCSR; +} + +/*! + * @brief Clears the SAI Tx status flag state. + * + * @param base SAI base pointer + * @param mask State mask. It can be a combination of the following source if defined: + * @arg kSAI_WordStartFlag + * @arg kSAI_SyncErrorFlag + * @arg kSAI_FIFOErrorFlag + */ +static inline void SAI_TxClearStatusFlags(I2S_Type *base, uint32_t mask) +{ + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask); +} + +/*! + * @brief Gets the SAI Tx status flag state. + * + * @param base SAI base pointer + * @return SAI Rx status flag value. Use the Status Mask to get the status value needed. + */ +static inline uint32_t SAI_RxGetStatusFlag(I2S_Type *base) +{ + return base->RCSR; +} + +/*! + * @brief Clears the SAI Rx status flag state. + * + * @param base SAI base pointer + * @param mask State mask. It can be a combination of the following source if defined: + * @arg kSAI_WordStartFlag + * @arg kSAI_SyncErrorFlag + * @arg kSAI_FIFOErrorFlag + */ +static inline void SAI_RxClearStatusFlags(I2S_Type *base, uint32_t mask) +{ + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask); +} + +/*! @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables SAI Tx interrupt requests. + * + * @param base SAI base pointer + * @param mask interrupt source + * The parameter can be a combination of the following source if defined: + * @arg kSAI_WordStartInterruptEnable + * @arg kSAI_SyncErrorInterruptEnable + * @arg kSAI_FIFOWarningInterruptEnable + * @arg kSAI_FIFORequestInterruptEnable + * @arg kSAI_FIFOErrorInterruptEnable + */ +static inline void SAI_TxEnableInterrupts(I2S_Type *base, uint32_t mask) +{ + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask); +} + +/*! + * @brief Enables SAI Rx interrupt requests. + * + * @param base SAI base pointer + * @param mask interrupt source + * The parameter can be a combination of the following source if defined: + * @arg kSAI_WordStartInterruptEnable + * @arg kSAI_SyncErrorInterruptEnable + * @arg kSAI_FIFOWarningInterruptEnable + * @arg kSAI_FIFORequestInterruptEnable + * @arg kSAI_FIFOErrorInterruptEnable + */ +static inline void SAI_RxEnableInterrupts(I2S_Type *base, uint32_t mask) +{ + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask); +} + +/*! + * @brief Disables SAI Tx interrupt requests. + * + * @param base SAI base pointer + * @param mask interrupt source + * The parameter can be a combination of the following source if defined: + * @arg kSAI_WordStartInterruptEnable + * @arg kSAI_SyncErrorInterruptEnable + * @arg kSAI_FIFOWarningInterruptEnable + * @arg kSAI_FIFORequestInterruptEnable + * @arg kSAI_FIFOErrorInterruptEnable + */ +static inline void SAI_TxDisableInterrupts(I2S_Type *base, uint32_t mask) +{ + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~mask)); +} + +/*! + * @brief Disables SAI Rx interrupt requests. + * + * @param base SAI base pointer + * @param mask interrupt source + * The parameter can be a combination of the following source if defined: + * @arg kSAI_WordStartInterruptEnable + * @arg kSAI_SyncErrorInterruptEnable + * @arg kSAI_FIFOWarningInterruptEnable + * @arg kSAI_FIFORequestInterruptEnable + * @arg kSAI_FIFOErrorInterruptEnable + */ +static inline void SAI_RxDisableInterrupts(I2S_Type *base, uint32_t mask) +{ + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~mask)); +} + +/*! @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables/disables SAI Tx DMA requests. + * @param base SAI base pointer + * @param mask DMA source + * The parameter can be combination of the following source if defined: + * @arg kSAI_FIFOWarningDMAEnable + * @arg kSAI_FIFORequestDMAEnable + * @param enable True means enable DMA, false means disable DMA. + */ +static inline void SAI_TxEnableDMA(I2S_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | mask); + } + else + { + base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~mask)); + } +} + +/*! + * @brief Enables/disables SAI Rx DMA requests. + * @param base SAI base pointer + * @param mask DMA source + * The parameter can be a combination of the following source if defined: + * @arg kSAI_FIFOWarningDMAEnable + * @arg kSAI_FIFORequestDMAEnable + * @param enable True means enable DMA, false means disable DMA. + */ +static inline void SAI_RxEnableDMA(I2S_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | mask); + } + else + { + base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~mask)); + } +} + +/*! + * @brief Gets the SAI Tx data register address. + * + * This API is used to provide a transfer address for SAI DMA transfer configuration. + * + * @param base SAI base pointer. + * @param channel Which data channel used. + * @return data register address. + */ +static inline uint32_t SAI_TxGetDataRegisterAddress(I2S_Type *base, uint32_t channel) +{ + return (uint32_t)(&(base->TDR)[channel]); +} + +/*! + * @brief Gets the SAI Rx data register address. + * + * This API is used to provide a transfer address for SAI DMA transfer configuration. + * + * @param base SAI base pointer. + * @param channel Which data channel used. + * @return data register address. + */ +static inline uint32_t SAI_RxGetDataRegisterAddress(I2S_Type *base, uint32_t channel) +{ + return (uint32_t)(&(base->RDR)[channel]); +} + +/*! @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Configures the SAI Tx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base SAI base pointer. + * @param format Pointer to SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master + * clock, this value should equals to masterClockHz in format. +*/ +void SAI_TxSetFormat(I2S_Type *base, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Configures the SAI Rx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base SAI base pointer. + * @param format Pointer to SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master + * clock, this value should equals to masterClockHz in format. +*/ +void SAI_RxSetFormat(I2S_Type *base, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Sends data using a blocking method. + * + * @note This function blocks by polling until data is ready to be sent. + * + * @param base SAI base pointer. + * @param channel Data channel used. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be written. + * @param size Bytes to be written. + */ +void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); + +/*! + * @brief Writes data into SAI FIFO. + * + * @param base SAI base pointer. + * @param channel Data channel used. + * @param data Data needs to be written. + */ +static inline void SAI_WriteData(I2S_Type *base, uint32_t channel, uint32_t data) +{ + base->TDR[channel] = data; +} + +/*! + * @brief Receives data using a blocking method. + * + * @note This function blocks by polling until data is ready to be sent. + * + * @param base SAI base pointer. + * @param channel Data channel used. + * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param buffer Pointer to the data to be read. + * @param size Bytes to be read. + */ +void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); + +/*! + * @brief Reads data from SAI FIFO. + * + * @param base SAI base pointer. + * @param channel Data channel used. + * @return Data in SAI FIFO. + */ +static inline uint32_t SAI_ReadData(I2S_Type *base, uint32_t channel) +{ + return base->RDR[channel]; +} + +/*! @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the SAI Tx handle. + * + * This function initializes the Tx handle for SAI Tx transactional APIs. Call + * this function one time to get the handle initialized. + * + * @param base SAI base pointer + * @param handle SAI handle pointer. + * @param callback pointer to user callback function + * @param userData user parameter passed to the callback function + */ +void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData); + +/*! + * @brief Initializes the SAI Rx handle. + * + * This function initializes the Rx handle for SAI Rx transactional APIs. Call + * this function one time to get the handle initialized. + * + * @param base SAI base pointer. + * @param handle SAI handle pointer. + * @param callback pointer to user callback function + * @param userData user parameter passed to the callback function + */ +void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData); + +/*! + * @brief Configures the SAI Tx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base SAI base pointer. + * @param handle SAI handle pointer. + * @param format Pointer to SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master + * clock, this value should equal to masterClockHz in format. + * @return Status of this function. Return value is one of status_t. +*/ +status_t SAI_TransferTxSetFormat(I2S_Type *base, + sai_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Configures the SAI Rx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. + * + * @param base SAI base pointer. + * @param handle SAI handle pointer. + * @param format Pointer to SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master + * clock, this value should equals to masterClockHz in format. + * @return Status of this function. Return value is one of status_t. +*/ +status_t SAI_TransferRxSetFormat(I2S_Type *base, + sai_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Performs an interrupt non-blocking send transfer on SAI. + * + * @note This API returns immediately after the transfer initiates. + * Call the SAI_TxGetTransferStatusIRQ to poll the transfer status and check whether + * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer + * is finished. + * + * @param base SAI base pointer + * @param handle pointer to sai_handle_t structure which stores the transfer state + * @param xfer pointer to sai_transfer_t structure + * @retval kStatus_Success Successfully started the data receive. + * @retval kStatus_SAI_TxBusy Previous receive still not finished. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer); + +/*! + * @brief Performs an interrupt non-blocking receive transfer on SAI. + * + * @note This API returns immediately after the transfer initiates. + * Call the SAI_RxGetTransferStatusIRQ to poll the transfer status and check whether + * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer + * is finished. + * + * @param base SAI base pointer + * @param handle pointer to sai_handle_t structure which stores the transfer state + * @param xfer pointer to sai_transfer_t structure + * @retval kStatus_Success Successfully started the data receive. + * @retval kStatus_SAI_RxBusy Previous receive still not finished. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer); + +/*! + * @brief Gets a set byte count. + * + * @param base SAI base pointer. + * @param handle pointer to sai_handle_t structure which stores the transfer state. + * @param count Bytes count sent. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count); + +/*! + * @brief Gets a received byte count. + * + * @param base SAI base pointer. + * @param handle pointer to sai_handle_t structure which stores the transfer state. + * @param count Bytes count received. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count); + +/*! + * @brief Aborts the current send. + * + * @note This API can be called any time when an interrupt non-blocking transfer initiates + * to abort the transfer early. + * + * @param base SAI base pointer. + * @param handle pointer to sai_handle_t structure which stores the transfer state. + */ +void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle); + +/*! + * @brief Aborts the the current IRQ receive. + * + * @note This API can be called any time when an interrupt non-blocking transfer initiates + * to abort the transfer early. + * + * @param base SAI base pointer + * @param handle pointer to sai_handle_t structure which stores the transfer state. + */ +void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle); + +/*! + * @brief Tx interrupt handler. + * + * @param base SAI base pointer. + * @param handle pointer to sai_handle_t structure. + */ +void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle); + +/*! + * @brief Tx interrupt handler. + * + * @param base SAI base pointer. + * @param handle pointer to sai_handle_t structure. + */ +void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ + +/*! @} */ + +#endif /* _FSL_SAI_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai_dma.c new file mode 100644 index 0000000000..a0ee6db183 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai_dma.c @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sai_dma.h" + +/******************************************************************************* +* Definitions +******************************************************************************/ +/*handle; + + /* Update queue counter */ + memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t)); + saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE; + + /* Call callback function */ + if (saiHandle->callback) + { + (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_TxIdle, saiHandle->userData); + } + + /* If all data finished, just stop the transfer */ + if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL) + { + SAI_TransferAbortSendDMA(privHandle->base, saiHandle); + } +} + +static void SAI_RxDMACallback(dma_handle_t *handle, void *userData) +{ + sai_dma_private_handle_t *privHandle = (sai_dma_private_handle_t *)userData; + sai_dma_handle_t *saiHandle = privHandle->handle; + + /* Update queue counter */ + memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t)); + saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE; + + /* Call callback function */ + if (saiHandle->callback) + { + (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_RxIdle, saiHandle->userData); + } + + /* If all data finished, just stop the transfer */ + if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL) + { + SAI_TransferAbortReceiveDMA(privHandle->base, saiHandle); + } +} + +void SAI_TransferTxCreateHandleDMA( + I2S_Type *base, sai_dma_handle_t *handle, sai_dma_callback_t callback, void *userData, dma_handle_t *dmaHandle) +{ + assert(handle && dmaHandle); + + uint32_t instance = SAI_GetInstance(base); + + /* Set sai base to handle */ + handle->dmaHandle = dmaHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set SAI state to idle */ + handle->state = kSAI_Idle; + + s_dmaPrivateHandle[instance][0].base = base; + s_dmaPrivateHandle[instance][0].handle = handle; + +/* Use FIFO error continue nstead of using interrupt to handle error */ +#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && (FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) + base->TCR4 |= I2S_TCR4_FCONT_MASK; +#endif + + /* Install callback for Tx dma channel */ + DMA_SetCallback(dmaHandle, SAI_TxDMACallback, &s_dmaPrivateHandle[instance][0]); +} + +void SAI_TransferRxCreateHandleDMA( + I2S_Type *base, sai_dma_handle_t *handle, sai_dma_callback_t callback, void *userData, dma_handle_t *dmaHandle) +{ + assert(handle && dmaHandle); + + uint32_t instance = SAI_GetInstance(base); + + /* Set sai base to handle */ + handle->dmaHandle = dmaHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set SAI state to idle */ + handle->state = kSAI_Idle; + + s_dmaPrivateHandle[instance][1].base = base; + s_dmaPrivateHandle[instance][1].handle = handle; + +/* Use FIFO error continue nstead of using interrupt to handle error */ +#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && (FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) + base->RCR4 |= I2S_RCR4_FCONT_MASK; +#endif + + /* Install callback for Tx dma channel */ + DMA_SetCallback(dmaHandle, SAI_RxDMACallback, &s_dmaPrivateHandle[instance][1]); +} + +void SAI_TransferTxSetFormatDMA(I2S_Type *base, + sai_dma_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + assert(handle && format); + + dma_transfer_config_t config = {0}; + + /* Configure the audio format to SAI registers */ + SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); + + /* Update the information in handle */ + handle->channel = format->channel; + + /* Configure the data format into DMA register */ + config.destAddr = SAI_TxGetDataRegisterAddress(base, format->channel); + config.enableDestIncrement = false; + config.enableSrcIncrement = true; + switch (format->bitWidth) + { + case 8: + config.srcSize = kDMA_Transfersize8bits; + config.destSize = kDMA_Transfersize8bits; + handle->bytesPerFrame = 1U; + break; + case 16: + config.srcSize = kDMA_Transfersize16bits; + config.destSize = kDMA_Transfersize16bits; + handle->bytesPerFrame = 2U; + break; + default: + config.srcSize = kDMA_Transfersize32bits; + config.destSize = kDMA_Transfersize32bits; + handle->bytesPerFrame = 4U; + break; + } + + /* Configure DMA channel */ + DMA_SubmitTransfer(handle->dmaHandle, &config, true); +} + +void SAI_TransferRxSetFormatDMA(I2S_Type *base, + sai_dma_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz) +{ + assert(handle && format); + + dma_transfer_config_t config = {0}; + + /* Configure the audio format to SAI registers */ + SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); + handle->channel = format->channel; + + /* Configure the data format into DMA register */ + config.srcAddr = SAI_RxGetDataRegisterAddress(base, format->channel); + config.enableDestIncrement = true; + config.enableSrcIncrement = false; + switch (format->bitWidth) + { + case 8: + config.srcSize = kDMA_Transfersize8bits; + config.destSize = kDMA_Transfersize8bits; + handle->bytesPerFrame = 1U; + break; + case 16: + config.srcSize = kDMA_Transfersize16bits; + config.destSize = kDMA_Transfersize16bits; + handle->bytesPerFrame = 2U; + break; + default: + config.srcSize = kDMA_Transfersize32bits; + config.destSize = kDMA_Transfersize32bits; + handle->bytesPerFrame = 4U; + break; + } + + /* Configure DMA channel */ + DMA_SubmitTransfer(handle->dmaHandle, &config, true); +} + +status_t SAI_TransferSendDMA(I2S_Type *base, sai_dma_handle_t *handle, sai_transfer_t *xfer) +{ + assert(handle && xfer); + + /* Check if input parameter invalid */ + if ((xfer->data == NULL) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + if (handle->saiQueue[handle->queueUser].data) + { + return kStatus_SAI_QueueFull; + } + + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->saiQueue[handle->queueUser].data = xfer->data; + handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE; + + /* Set the source address */ + DMA_SetSourceAddress(handle->dmaHandle->base, handle->dmaHandle->channel, (uint32_t)(xfer->data)); + + /* Set the transfer size */ + DMA_SetTransferSize(handle->dmaHandle->base, handle->dmaHandle->channel, xfer->dataSize); + + /* Change the state of handle */ + handle->state = kSAI_Busy; + + /* Start DMA transfer */ + DMA_StartTransfer(handle->dmaHandle); + +/* Enable DMA request and start SAI */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, true); +#else + SAI_TxEnableDMA(base, kSAI_FIFOWarningDMAEnable, true); +#endif + SAI_TxEnable(base, true); + + return kStatus_Success; +} + +status_t SAI_TransferReceiveDMA(I2S_Type *base, sai_dma_handle_t *handle, sai_transfer_t *xfer) +{ + assert(handle && xfer); + + /* Check if input parameter invalid */ + if ((xfer->data == NULL) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + if (handle->saiQueue[handle->queueUser].data) + { + return kStatus_SAI_QueueFull; + } + + /* Add into queue */ + handle->transferSize[handle->queueUser] = xfer->dataSize; + handle->saiQueue[handle->queueUser].data = xfer->data; + handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; + handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE; + + /* Set the source address */ + DMA_SetDestinationAddress(handle->dmaHandle->base, handle->dmaHandle->channel, (uint32_t)(xfer->data)); + + /* Set the transfer size */ + DMA_SetTransferSize(handle->dmaHandle->base, handle->dmaHandle->channel, xfer->dataSize); + + /* Change the state of handle */ + handle->state = kSAI_Busy; + + /* Start DMA transfer */ + DMA_StartTransfer(handle->dmaHandle); + +/* Enable DMA request and start SAI */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, true); +#else + SAI_RxEnableDMA(base, kSAI_FIFOWarningDMAEnable, true); +#endif + SAI_RxEnable(base, true); + + return kStatus_Success; +} + +void SAI_TransferAbortSendDMA(I2S_Type *base, sai_dma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + DMA_AbortTransfer(handle->dmaHandle); + +/* Disable DMA enable bit */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); +#else + SAI_TxEnableDMA(base, kSAI_FIFOWarningDMAEnable, false); +#endif + + /* Set the handle state */ + handle->state = kSAI_Idle; + + /* Clear the queue */ + memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +void SAI_TransferAbortReceiveDMA(I2S_Type *base, sai_dma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + DMA_AbortTransfer(handle->dmaHandle); + +/* Disable DMA enable bit */ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); +#else + SAI_RxEnableDMA(base, kSAI_FIFOWarningDMAEnable, false); +#endif + /* Set the handle state */ + handle->state = kSAI_Idle; + + /* Clear the queue */ + memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE); + handle->queueDriver = 0; + handle->queueUser = 0; +} + +status_t SAI_TransferGetSendCountDMA(I2S_Type *base, sai_dma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSAI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = handle->transferSize[handle->queueDriver] - + DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel); + } + + return status; +} + +status_t SAI_TransferGetReceiveCountDMA(I2S_Type *base, sai_dma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSAI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + *count = handle->transferSize[handle->queueDriver] - + DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel); + } + + return status; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai_dma.h new file mode 100644 index 0000000000..9606afcfdf --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sai_dma.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SAI_DMA_H_ +#define _FSL_SAI_DMA_H_ + +#include "fsl_sai.h" +#include "fsl_dma.h" + +/*! + * @addtogroup sai_dma + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +typedef struct _sai_dma_handle sai_dma_handle_t; + +/*! @brief Define SAI DMA callback */ +typedef void (*sai_dma_callback_t)(I2S_Type *base, sai_dma_handle_t *handle, status_t status, void *userData); + +/*! @brief SAI DMA transfer handle, users should not touch the content of the handle.*/ +struct _sai_dma_handle +{ + dma_handle_t *dmaHandle; /*!< DMA handler for SAI send */ + uint8_t bytesPerFrame; /*!< Bytes in a frame */ + uint8_t channel; /*!< Which Data channel SAI use */ + uint32_t state; /*!< SAI DMA transfer internal state */ + sai_dma_callback_t callback; /*!< Callback for users while transfer finish or error occured */ + void *userData; /*!< User callback parameter */ + sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer. */ + size_t transferSize[SAI_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ + volatile uint8_t queueUser; /*!< Index for user to queue transfer. */ + volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name DMA Transactional + * @{ + */ + +/*! + * @brief Initializes the SAI master DMA handle. + * + * This function initializes the SAI master DMA handle, which can be used for other SAI master transactional APIs. + * Usually, for a specified SAI instance, call this API once to get the initialized handle. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + * @param base SAI peripheral base address. + * @param callback Pointer to user callback function. + * @param userData User parameter passed to the callback function. + * @param dmaHandle DMA handle pointer, this handle shall be static allocated by users. + */ +void SAI_TransferTxCreateHandleDMA( + I2S_Type *base, sai_dma_handle_t *handle, sai_dma_callback_t callback, void *userData, dma_handle_t *dmaHandle); + +/*! + * @brief Initializes the SAI slave DMA handle. + * + * This function initializes the SAI slave DMA handle, which can be used for other SAI master transactional APIs. + * Usually, for a specified SAI instance, call this API once to get the initialized handle. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + * @param base SAI peripheral base address. + * @param callback Pointer to user callback function. + * @param userData User parameter passed to the callback function. + * @param dmaHandle DMA handle pointer, this handle shall be static allocated by users. + */ +void SAI_TransferRxCreateHandleDMA( + I2S_Type *base, sai_dma_handle_t *handle, sai_dma_callback_t callback, void *userData, dma_handle_t *dmaHandle); + +/*! + * @brief Configures the SAI Tx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. This function also sets the eDMA parameter according to the format. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + * @param format Pointer to SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master. + * clock, this value should equals to masterClockHz in format. + * @retval kStatus_Success Audio format set successfully. + * @retval kStatus_InvalidArgument The input arguments is invalid. +*/ +void SAI_TransferTxSetFormatDMA(I2S_Type *base, + sai_dma_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Configures the SAI Rx audio format. + * + * The audio format can be changed at run-time. This function configures the sample rate and audio data + * format to be transferred. This function also sets EDMA parameter according to format. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + * @param format Pointer to SAI audio data format structure. + * @param mclkSourceClockHz SAI master clock source frequency in Hz. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master. + * clock, this value should equals to masterClockHz in format. + * @retval kStatus_Success Audio format set successfully. + * @retval kStatus_InvalidArgument The input arguments is invalid. +*/ +void SAI_TransferRxSetFormatDMA(I2S_Type *base, + sai_dma_handle_t *handle, + sai_transfer_format_t *format, + uint32_t mclkSourceClockHz, + uint32_t bclkSourceClockHz); + +/*! + * @brief Performs a non-blocking SAI transfer using DMA. + * + * @note This interface returns immediately after the transfer initiates. Call + * the SAI_GetTransferStatus to poll the transfer status to check whether the SAI transfer finished. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + * @param xfer Pointer to DMA transfer structure. + * @retval kStatus_Success Successfully start the data receive. + * @retval kStatus_SAI_TxBusy Previous receive still not finished. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t SAI_TransferSendDMA(I2S_Type *base, sai_dma_handle_t *handle, sai_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking SAI transfer using DMA. + * + * @note This interface returns immediately after transfer initiates. Call + * SAI_GetTransferStatus to poll the transfer status to check whether the SAI transfer is finished. + * + * @param base SAI base pointer + * @param handle SAI DMA handle pointer. + * @param xfer Pointer to DMA transfer structure. + * @retval kStatus_Success Successfully start the data receive. + * @retval kStatus_SAI_RxBusy Previous receive still not finished. + * @retval kStatus_InvalidArgument The input parameter is invalid. + */ +status_t SAI_TransferReceiveDMA(I2S_Type *base, sai_dma_handle_t *handle, sai_transfer_t *xfer); + +/*! + * @brief Aborts a SAI transfer using DMA. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + */ +void SAI_TransferAbortSendDMA(I2S_Type *base, sai_dma_handle_t *handle); + +/*! + * @brief Aborts a SAI transfer using DMA. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + */ +void SAI_TransferAbortReceiveDMA(I2S_Type *base, sai_dma_handle_t *handle); + +/*! + * @brief Gets byte count sent by SAI. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + * @param count Bytes count sent by SAI. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t SAI_TransferGetSendCountDMA(I2S_Type *base, sai_dma_handle_t *handle, size_t *count); + +/*! + * @brief Gets byte count received by SAI. + * + * @param base SAI base pointer. + * @param handle SAI DMA handle pointer. + * @param count Bytes count received by SAI. + * @retval kStatus_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t SAI_TransferGetReceiveCountDMA(I2S_Type *base, sai_dma_handle_t *handle, size_t *count); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sim.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sim.c new file mode 100644 index 0000000000..3a4b801b7b --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sim.c @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_sim.h" + +/******************************************************************************* + * Codes + ******************************************************************************/ +#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) +void SIM_SetUsbVoltRegulatorEnableMode(uint32_t mask) +{ + SIM->SOPT1CFG |= (SIM_SOPT1CFG_URWE_MASK | SIM_SOPT1CFG_UVSWE_MASK | SIM_SOPT1CFG_USSWE_MASK); + + SIM->SOPT1 = (SIM->SOPT1 & ~kSIM_UsbVoltRegEnableInAllModes) | mask; +} +#endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */ + +void SIM_GetUniqueId(sim_uid_t *uid) +{ +#if defined(SIM_UIDH) + uid->H = SIM->UIDH; +#endif + uid->MH = SIM->UIDMH; + uid->ML = SIM->UIDML; + uid->L = SIM->UIDL; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sim.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sim.h new file mode 100644 index 0000000000..a3b6918884 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_sim.h @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _FSL_SIM_H_ +#define _FSL_SIM_H_ + +#include "fsl_common.h" + +/*! @addtogroup sim */ +/*! @{*/ + +/*! @file */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_SIM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Driver version 2.0.0 */ +/*@}*/ + +#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) +/*!@brief USB voltage regulator enable setting. */ +enum _sim_usb_volt_reg_enable_mode +{ + kSIM_UsbVoltRegEnable = SIM_SOPT1_USBREGEN_MASK, /*!< Enable voltage regulator. */ + kSIM_UsbVoltRegEnableInLowPower = SIM_SOPT1_USBVSTBY_MASK, /*!< Enable voltage regulator in VLPR/VLPW modes. */ + kSIM_UsbVoltRegEnableInStop = SIM_SOPT1_USBSSTBY_MASK, /*!< Enable voltage regulator in STOP/VLPS/LLS/VLLS modes. */ + kSIM_UsbVoltRegEnableInAllModes = SIM_SOPT1_USBREGEN_MASK | SIM_SOPT1_USBSSTBY_MASK | + SIM_SOPT1_USBVSTBY_MASK /*!< Enable voltage regulator in all power modes. */ +}; +#endif /* (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) */ + +/*!@brief Unique ID. */ +typedef struct _sim_uid +{ +#if defined(SIM_UIDH) + uint32_t H; /*!< UIDH. */ +#endif + uint32_t MH; /*!< UIDMH. */ + uint32_t ML; /*!< UIDML. */ + uint32_t L; /*!< UIDL. */ +} sim_uid_t; + +/*!@brief Flash enable mode. */ +enum _sim_flash_mode +{ + kSIM_FlashDisableInWait = SIM_FCFG1_FLASHDOZE_MASK, /*!< Disable flash in wait mode. */ + kSIM_FlashDisable = SIM_FCFG1_FLASHDIS_MASK /*!< Disable flash in normal mode. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +#if (defined(FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) && FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR) +/*! + * @brief Sets the USB voltage regulator setting. + * + * This function configures whether the USB voltage regulator is enabled in + * normal RUN mode, STOP/VLPS/LLS/VLLS modes and VLPR/VLPW modes. The configurations + * are passed in as mask value of \ref _sim_usb_volt_reg_enable_mode. For example, enable + * USB voltage regulator in RUN/VLPR/VLPW modes and disable in STOP/VLPS/LLS/VLLS mode, + * please use: + * + * SIM_SetUsbVoltRegulatorEnableMode(kSIM_UsbVoltRegEnable | kSIM_UsbVoltRegEnableInLowPower); + * + * @param mask USB voltage regulator enable setting. + */ +void SIM_SetUsbVoltRegulatorEnableMode(uint32_t mask); +#endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */ + +/*! + * @brief Get the unique identification register value. + * + * @param uid Pointer to the structure to save the UID value. + */ +void SIM_GetUniqueId(sim_uid_t *uid); + +/*! + * @brief Set the flash enable mode. + * + * @param mode The mode to set, see \ref _sim_flash_mode for mode details. + */ +static inline void SIM_SetFlashMode(uint8_t mode) +{ + SIM->FCFG1 = mode; +} + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* _FSL_SIM_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_slcd.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_slcd.c new file mode 100644 index 0000000000..7876f143fd --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_slcd.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_slcd.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define SLCD_WAVEFORM_CONFIG_NUM 16 + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get the SLCD instance from peripheral base address. + * + * @param base SLCD peripheral base address. + * @return SLCD instance. + */ +static uint32_t SLCD_GetInstance(LCD_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to slcd clocks for each instance. */ +const clock_ip_name_t s_slcdClock[FSL_FEATURE_SOC_SLCD_COUNT] = SLCD_CLOCKS; + +/*! @brief Pointers to slcd bases for each instance. */ +static LCD_Type *const s_slcdBases[] = LCD_BASE_PTRS; + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t SLCD_GetInstance(LCD_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_SLCD_COUNT; instance++) + { + if (s_slcdBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_SLCD_COUNT); + + return instance; +} + +void SLCD_Init(LCD_Type *base, slcd_config_t *configure) +{ + assert(configure); + assert(configure->clkConfig); + + uint32_t gcrReg = 0; + bool intEnabled = false; + uint32_t regNum = 0; + uint32_t instance = SLCD_GetInstance(base); + + /* Un-gate the SLCD clock. */ + CLOCK_EnableClock(s_slcdClock[instance]); + + /* Configure general setting: power supply. */ + gcrReg = LCD_GCR_RVEN(configure->powerSupply & 0x1U) | LCD_GCR_CPSEL((configure->powerSupply >> 1U) & 0x1U) | + LCD_GCR_VSUPPLY((configure->powerSupply >> 2U) & 0x1U) | LCD_GCR_LADJ(configure->loadAdjust); + /* Configure general setting: clock source. */ + gcrReg |= LCD_GCR_SOURCE((configure->clkConfig->clkSource) & 0x1U) | + LCD_GCR_LCLK(configure->clkConfig->clkPrescaler) | LCD_GCR_ALTDIV(configure->clkConfig->altClkDivider); + /* Configure the duty and set the work for low power wait and stop mode. */ + gcrReg |= LCD_GCR_DUTY(configure->dutyCycle) | LCD_GCR_LCDSTP(configure->lowPowerBehavior & 0x1U); +#if FSL_FEATURE_SLCD_HAS_LCD_WAIT + gcrReg |= LCD_GCR_LCDWAIT((configure->lowPowerBehavior >> 1U) & 0x1U); +#endif +#if FSL_FEATURE_SLCD_HAS_LCD_DOZE_ENABLE + gcrReg |= LCD_GCR_LCDDOZE((configure->lowPowerBehavior >> 1U) & 0x1U); +#endif +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + /* Configure for frame frequency interrupt. */ + gcrReg |= LCD_GCR_LCDIEN(configure->frameFreqIntEnable); +#endif /* FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT */ +#if FSL_FEATURE_SLCD_HAS_MULTI_ALTERNATE_CLOCK_SOURCE + /* Select the alternate clock for alternate clock source. */ + gcrReg |= LCD_GCR_ALTSOURCE(((configure->clkConfig->clkSource) >> 1U) & 0x1U); +#endif /* FSL_FEATURE_SLCD_HAS_MULTI_ALTERNATE_CLOCK_SOURCE */ +#if FSL_FEATURE_SLCD_HAS_FAST_FRAME_RATE + /* Configure the for fast frame rate. */ + gcrReg |= LCD_GCR_FFR(configure->clkConfig->fastFrameRateEnable ? 1U : 0U); +#endif /* FSL_FEATURE_SLCD_HAS_FAST_FRAME_RATE */ + + if (configure->powerSupply & 0x1U) + { + gcrReg |= LCD_GCR_RVTRIM(configure->voltageTrim); + } + base->GCR = gcrReg; + + /* Set display mode. */ + base->AR = LCD_AR_ALT(configure->displayMode & 0x1U) | LCD_AR_BLANK((configure->displayMode >> 1U) & 0x1U); + + /* Configure the front plane and back plane pin setting. */ + base->BPEN[0] = configure->backPlaneLowPin; + base->BPEN[1] = configure->backPlaneHighPin; + base->PEN[0] = configure->slcdLowPinEnabled; + base->PEN[1] = configure->slcdHighPinEnabled; + + /* Set the fault frame detection. */ + base->FDCR = 0; + if (configure->faultConfig) + { + /* If fault configure structure is not NULL, the fault detection is enabled. */ + base->FDCR = LCD_FDCR_FDPRS(configure->faultConfig->faultPrescaler) | + LCD_FDCR_FDSWW(configure->faultConfig->width) | + LCD_FDCR_FDBPEN(configure->faultConfig->faultDetectBackPlaneEnable ? 1U : 0U) | + LCD_FDCR_FDPINID(configure->faultConfig->faultDetectPinIndex) | LCD_FDCR_FDEN_MASK; + if (configure->faultConfig->faultDetectIntEnable) + { + base->GCR |= LCD_GCR_FDCIEN_MASK; + intEnabled = true; + } + } + + /* Initialize the Waveform. */ + for (regNum = 0; regNum < SLCD_WAVEFORM_CONFIG_NUM; regNum++) + { + base->WF[regNum] = 0; + } + +/* Enable the NVIC. */ +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + if (configure->frameFreqIntEnable) + { + intEnabled = true; + } +#endif /* FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT */ + if (intEnabled) + { + EnableIRQ(LCD_IRQn); + } +} + +void SLCD_Deinit(LCD_Type *base) +{ + uint32_t instance = SLCD_GetInstance(base); + + /* Stop SLCD display. */ + SLCD_StopDisplay(base); + + /* Gate the SLCD clock. */ + CLOCK_DisableClock(s_slcdClock[instance]); + + /* Disable NVIC. */ + DisableIRQ(LCD_IRQn); +} + +void SLCD_GetDefaultConfig(slcd_config_t *configure) +{ + assert(configure); + + /* Get Default parameters for the configuration structure. */ + /* SLCD in normal mode. */ + configure->displayMode = kSLCD_NormalMode; + /* Power supply default: use charge pump to generate VLL1 and VLL2, VLL3 connected to VDD internally. */ + configure->powerSupply = kSLCD_InternalVll3UseChargePump; + configure->voltageTrim = kSLCD_RegulatedVolatgeTrim00; + /* Work in low power mode. */ + configure->lowPowerBehavior = kSLCD_EnabledInWaitStop; +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + /* No interrupt source is enabled. */ + configure->frameFreqIntEnable = false; +#endif /* FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT */ + /* Fault detection is disabled. */ + configure->faultConfig = NULL; +} + +void SLCD_StartBlinkMode(LCD_Type *base, slcd_blink_mode_t mode, slcd_blink_rate_t rate) +{ + base->AR &= ~(LCD_AR_BMODE_MASK | LCD_AR_BRATE_MASK); + /* Set blink mode and blink rate. */ + base->AR |= LCD_AR_BMODE(mode) | LCD_AR_BRATE(rate); + + /* Enable Blink mode. */ + base->AR |= LCD_AR_BLINK_MASK; +} + +void SLCD_EnableInterrupts(LCD_Type *base, uint32_t mask) +{ + uint32_t gcReg = base->GCR; + + gcReg |= LCD_GCR_FDCIEN(mask & 0x1U); +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + gcReg |= LCD_GCR_LCDEN((mask >> 1U) & 0x1U); +#endif /* FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT */ + + base->GCR = gcReg; +} + +void SLCD_DisableInterrupts(LCD_Type *base, uint32_t mask) +{ + uint32_t gcrReg = base->GCR; + + /*!< SLCD fault detection complete interrupt source. */ + if (mask & kSLCD_FaultDetectCompleteInterrupt) + { + gcrReg &= ~LCD_GCR_FDCIEN_MASK; + } +/*!< SLCD frame frequency interrupt source. */ +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + if (mask & kSLCD_FrameFreqInterrupt) + { + gcrReg &= ~LCD_GCR_LCDIEN_MASK; + } +#endif /* FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT */ + + base->GCR = gcrReg; +} + +void SLCD_ClearInterruptStatus(LCD_Type *base, uint32_t mask) +{ + /*!< SLCD fault detection complete interrupt source. */ + if (mask & kSLCD_FaultDetectCompleteInterrupt) + { + base->FDSR |= LCD_FDSR_FDCF_MASK; + } +/*!< SLCD frame frequency interrupt source. */ +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + if (mask & kSLCD_FrameFreqInterrupt) + { + base->AR |= LCD_AR_LCDIF_MASK; + } +#endif /* FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT */ +} + +uint32_t SLCD_GetInterruptStatus(LCD_Type *base) +{ + uint32_t status = 0; + + /* Get the frame detect complete interrupt status. */ + status = ((base->FDSR & LCD_FDSR_FDCF_MASK) >> LCD_FDSR_FDCF_SHIFT); + +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + /* Get the frame frequency interrupt status. */ + status |= ((base->AR & LCD_AR_LCDIF_MASK) >> (LCD_AR_LCDIF_SHIFT - 1)); +#endif /* FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT */ + + return status; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_slcd.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_slcd.h new file mode 100644 index 0000000000..58f387d9b4 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_slcd.h @@ -0,0 +1,586 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SLCD_H_ +#define _FSL_SLCD_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup slcd + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief SLCD driver version 2.0.0. */ +#define FSL_SLCD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @brief SLCD power supply option. */ +typedef enum _slcd_power_supply_option +{ + kSLCD_InternalVll3UseChargePump = + 2U, /*!< VLL3 connected to VDD internally, charge pump is used to generate VLL1 and VLL2. */ + kSLCD_ExternalVll3UseResistorBiasNetwork = + 4U, /*!< VLL3 is driven externally and resistor bias network is used to generate VLL1 and VLL2. */ + kSLCD_ExteranlVll3UseChargePump = + 6U, /*!< VLL3 is driven externally and charge pump is used to generate VLL1 and VLL2. */ + kSLCD_InternalVll1UseChargePump = + 7U /*!< VIREG is connected to VLL1 internally and charge pump is used to generate VLL2 and VLL3. */ +} slcd_power_supply_option_t; + +/*! @brief SLCD regulated voltage trim parameter, be used to meet the desired contrast. */ +typedef enum _slcd_regulated_voltage_trim +{ + kSLCD_RegulatedVolatgeTrim00 = 0U, /*!< Increase the voltage to 0.91 V. */ + kSLCD_RegulatedVolatgeTrim01, /*!< Increase the voltage to 1.01 V. */ + kSLCD_RegulatedVolatgeTrim02, /*!< Increase the voltage to 0.96 V. */ + kSLCD_RegulatedVolatgeTrim03, /*!< Increase the voltage to 1.06 V. */ + kSLCD_RegulatedVolatgeTrim04, /*!< Increase the voltage to 0.93 V. */ + kSLCD_RegulatedVolatgeTrim05, /*!< Increase the voltage to 1.02 V. */ + kSLCD_RegulatedVolatgeTrim06, /*!< Increase the voltage to 0.98 V. */ + kSLCD_RegulatedVolatgeTrim07, /*!< Increase the voltage to 1.08 V. */ + kSLCD_RegulatedVolatgeTrim08, /*!< Increase the voltage to 0.92 V. */ + kSLCD_RegulatedVolatgeTrim09, /*!< Increase the voltage to 1.02 V. */ + kSLCD_RegulatedVolatgeTrim10, /*!< Increase the voltage to 0.97 V. */ + kSLCD_RegulatedVolatgeTrim11, /*!< Increase the voltage to 1.07 V. */ + kSLCD_RegulatedVolatgeTrim12, /*!< Increase the voltage to 0.94 V. */ + kSLCD_RegulatedVolatgeTrim13, /*!< Increase the voltage to 1.05 V. */ + kSLCD_RegulatedVolatgeTrim14, /*!< Increase the voltage to 0.99 V. */ + kSLCD_RegulatedVolatgeTrim15 /*!< Increase the voltage to 1.09 V. */ +} slcd_regulated_voltage_trim_t; + +/*! @brief SLCD load adjust to handle different LCD glass capacitance or + * configure the LCD charge pump clock source. + * Adjust the LCD glass capacitance if resistor bias network is enabled: + * kSLCD_LowLoadOrFastestClkSrc - Low load (LCD glass capacitance 2000pF or lower. + * LCD or GPIO function can be used on VLL1,VLL2,Vcap1 and Vcap2 pins) + * kSLCD_LowLoadOrIntermediateClkSrc - low load (LCD glass capacitance 2000pF or lower. + * LCD or GPIO function can be used on VLL1,VLL2,Vcap1 and Vcap2 pins) + * kSLCD_HighLoadOrIntermediateClkSrc - high load (LCD glass capacitance 8000pF or lower. + * LCD or GPIO function can be used on Vcap1 and Vcap2 pins) + * kSLCD_HighLoadOrSlowestClkSrc - high load (LCD glass capacitance 8000pF or lower + * LCD or GPIO function can be used on Vcap1 and Vcap2 pins) + * Adjust clock for charge pump if charge pump is enabled: + * kSLCD_LowLoadOrFastestClkSrc - Fasten clock source (LCD glass capacitance + * 8000pF or 4000pF or lower if Fast Frame Rate is set) + * kSLCD_LowLoadOrIntermediateClkSrc - Intermediate clock source (LCD glass + * capacitance 4000pF or 2000pF or lower if Fast Frame Rate is set) + * kSLCD_HighLoadOrIntermediateClkSrc - Intermediate clock source (LCD glass + * capacitance 2000pF or 1000pF or lower if Fast Frame Rate is set) + * kSLCD_HighLoadOrSlowestClkSrc - slowest clock source (LCD glass capacitance + * 1000pF or 500pF or lower if Fast Frame Rate is set) + */ +typedef enum _slcd_load_adjust +{ + kSLCD_LowLoadOrFastestClkSrc = 0U, /*!< Adjust in low load or selects fastest clock. */ + kSLCD_LowLoadOrIntermediateClkSrc, /*!< Adjust in low load or selects intermediate clock. */ + kSLCD_HighLoadOrIntermediateClkSrc, /*!< Adjust in high load or selects intermediate clock. */ + kSLCD_HighLoadOrSlowestClkSrc /*!< Adjust in high load or selects slowest clock. */ +} slcd_load_adjust_t; + +/*! @brief SLCD clock source. */ +typedef enum _slcd_clock_src +{ + kSLCD_DefaultClk = 0U, /*!< Select default clock ERCLK32K. */ + kSLCD_AlternateClk1 = 1U, /*!< Select alternate clock source 1 : MCGIRCLK. */ +#if FSL_FEATURE_SLCD_HAS_MULTI_ALTERNATE_CLOCK_SOURCE + kSLCD_AlternateClk2 = 3U /*!< Select alternate clock source 2 : OSCERCLK. */ +#endif /* FSL_FEATURE_SLCD_HAS_MULTI_ALTERNATE_CLOCK_SOURCE */ +} slcd_clock_src_t; + +/*! @brief SLCD alternate clock divider. */ +typedef enum _slcd_alt_clock_div +{ + kSLCD_AltClkDivFactor1 = 0U, /*!< No divide for alternate clock. */ + kSLCD_AltClkDivFactor64, /*!< Divide alternate clock with factor 64. */ + kSLCD_AltClkDivFactor256, /*!< Divide alternate clock with factor 256. */ + kSLCD_AltClkDivFactor512 /*!< Divide alternate clock with factor 512. */ +} slcd_alt_clock_div_t; + +/*! @brief SLCD clock prescaler to generate frame frequency. */ +typedef enum _slcd_clock_prescaler +{ + kSLCD_ClkPrescaler00 = 0U, /*!< Prescaler 0. */ + kSLCD_ClkPrescaler01, /*!< Prescaler 1. */ + kSLCD_ClkPrescaler02, /*!< Prescaler 2. */ + kSLCD_ClkPrescaler03, /*!< Prescaler 3. */ + kSLCD_ClkPrescaler04, /*!< Prescaler 4. */ + kSLCD_ClkPrescaler05, /*!< Prescaler 5. */ + kSLCD_ClkPrescaler06, /*!< Prescaler 6. */ + kSLCD_ClkPrescaler07 /*!< Prescaler 7. */ +} slcd_clock_prescaler_t; + +/*! @brief SLCD duty cycle. */ +typedef enum _slcd_duty_cycle +{ + kSLCD_1Div1DutyCycle = 0U, /*!< LCD use 1 BP 1/1 duty cycle. */ + kSLCD_1Div2DutyCycle, /*!< LCD use 2 BP 1/2 duty cycle. */ + kSLCD_1Div3DutyCycle, /*!< LCD use 3 BP 1/3 duty cycle. */ + kSLCD_1Div4DutyCycle, /*!< LCD use 4 BP 1/4 duty cycle. */ + kSLCD_1Div5DutyCycle, /*!< LCD use 5 BP 1/5 duty cycle. */ + kSLCD_1Div6DutyCycle, /*!< LCD use 6 BP 1/6 duty cycle. */ + kSLCD_1Div7DutyCycle, /*!< LCD use 7 BP 1/7 duty cycle. */ + kSLCD_1Div8DutyCycle /*!< LCD use 8 BP 1/8 duty cycle. */ +} slcd_duty_cycle_t; + +/*! @brief SLCD segment phase type. */ +typedef enum _slcd_phase_type +{ + kSLCD_NoPhaseActivate = 0x00U, /*!< LCD wareform no phase activates. */ + kSLCD_PhaseAActivate = 0x01U, /*!< LCD waveform phase A activates. */ + kSLCD_PhaseBActivate = 0x02U, /*!< LCD waveform phase B activates. */ + kSLCD_PhaseCActivate = 0x04U, /*!< LCD waveform phase C activates. */ + kSLCD_PhaseDActivate = 0x08U, /*!< LCD waveform phase D activates. */ + kSLCD_PhaseEActivate = 0x10U, /*!< LCD waveform phase E activates. */ + kSLCD_PhaseFActivate = 0x20U, /*!< LCD waveform phase F activates. */ + kSLCD_PhaseGActivate = 0x40U, /*!< LCD waveform phase G activates. */ + kSLCD_PhaseHActivate = 0x80U /*!< LCD waveform phase H activates. */ +} slcd_phase_type_t; + +/*! @brief SLCD segment phase bit index. */ +typedef enum _slcd_phase_index +{ + kSLCD_PhaseAIndex = 0x0U, /*!< LCD phase A bit index. */ + kSLCD_PhaseBIndex = 0x1U, /*!< LCD phase B bit index. */ + kSLCD_PhaseCIndex = 0x2U, /*!< LCD phase C bit index. */ + kSLCD_PhaseDIndex = 0x3U, /*!< LCD phase D bit index. */ + kSLCD_PhaseEIndex = 0x4U, /*!< LCD phase E bit index. */ + kSLCD_PhaseFIndex = 0x5U, /*!< LCD phase F bit index. */ + kSLCD_PhaseGIndex = 0x6U, /*!< LCD phase G bit index. */ + kSLCD_PhaseHIndex = 0x7U /*!< LCD phase H bit index. */ +} slcd_phase_index_t; + +/*! @brief SLCD display mode. */ +typedef enum _slcd_display_mode +{ + kSLCD_NormalMode = 0U, /*!< LCD Normal display mode. */ + kSLCD_AlternateMode, /*!< LCD Alternate display mode. For four back planes or less. */ + kSLCD_BlankMode /*!< LCD Blank display mode. */ +} slcd_display_mode_t; + +/*! @brief SLCD blink mode. */ +typedef enum _slcd_blink_mode +{ + kSLCD_BlankDisplayBlink = 0U, /*!< Display blank during the blink period. */ + kSLCD_AltDisplayBlink /*!< Display alternate display during the blink period if duty cycle is lower than 5. */ +} slcd_blink_mode_t; + +/*! @brief SLCD blink rate. */ +typedef enum _slcd_blink_rate +{ + kSLCD_BlinkRate00 = 0U, /*!< SLCD blink rate is LCD clock/((2^12)). */ + kSLCD_BlinkRate01, /*!< SLCD blink rate is LCD clock/((2^13)). */ + kSLCD_BlinkRate02, /*!< SLCD blink rate is LCD clock/((2^14)). */ + kSLCD_BlinkRate03, /*!< SLCD blink rate is LCD clock/((2^15)). */ + kSLCD_BlinkRate04, /*!< SLCD blink rate is LCD clock/((2^16)). */ + kSLCD_BlinkRate05, /*!< SLCD blink rate is LCD clock/((2^17)). */ + kSLCD_BlinkRate06, /*!< SLCD blink rate is LCD clock/((2^18)). */ + kSLCD_BlinkRate07 /*!< SLCD blink rate is LCD clock/((2^19)). */ +} slcd_blink_rate_t; + +/*! @brief SLCD fault detect clock prescaler. */ +typedef enum _slcd_fault_detect_clock_prescaler +{ + kSLCD_FaultSampleFreqDivider1 = 0U, /*!< Fault detect sample clock frequency is 1/1 bus clock. */ + kSLCD_FaultSampleFreqDivider2, /*!< Fault detect sample clock frequency is 1/2 bus clock. */ + kSLCD_FaultSampleFreqDivider4, /*!< Fault detect sample clock frequency is 1/4 bus clock. */ + kSLCD_FaultSampleFreqDivider8, /*!< Fault detect sample clock frequency is 1/8 bus clock. */ + kSLCD_FaultSampleFreqDivider16, /*!< Fault detect sample clock frequency is 1/16 bus clock. */ + kSLCD_FaultSampleFreqDivider32, /*!< Fault detect sample clock frequency is 1/32 bus clock. */ + kSLCD_FaultSampleFreqDivider64, /*!< Fault detect sample clock frequency is 1/64 bus clock. */ + kSLCD_FaultSampleFreqDivider128 /*!< Fault detect sample clock frequency is 1/128 bus clock. */ +} slcd_fault_detect_clock_prescaler_t; + +/*! @brief SLCD fault detect sample window width. */ +typedef enum _slcd_fault_detect_sample_window_width +{ + kSLCD_FaultDetectWindowWidth4SampleClk = 0U, /*!< Sample window width is 4 sample clock cycles. */ + kSLCD_FaultDetectWindowWidth8SampleClk, /*!< Sample window width is 8 sample clock cycles. */ + kSLCD_FaultDetectWindowWidth16SampleClk, /*!< Sample window width is 16 sample clock cycles. */ + kSLCD_FaultDetectWindowWidth32SampleClk, /*!< Sample window width is 32 sample clock cycles. */ + kSLCD_FaultDetectWindowWidth64SampleClk, /*!< Sample window width is 64 sample clock cycles. */ + kSLCD_FaultDetectWindowWidth128SampleClk, /*!< Sample window width is 128 sample clock cycles. */ + kSLCD_FaultDetectWindowWidth256SampleClk, /*!< Sample window width is 256 sample clock cycles. */ + kSLCD_FaultDetectWindowWidth512SampleClk /*!< Sample window width is 512 sample clock cycles. */ +} slcd_fault_detect_sample_window_width_t; + +/*! @brief SLCD interrupt source. */ +typedef enum _slcd_interrupt_enable +{ + kSLCD_FaultDetectCompleteInterrupt = 1U, /*!< SLCD fault detection complete interrupt source. */ +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + kSLCD_FrameFreqInterrupt = 2U /*!< SLCD frame frequency interrupt source. Not available in all low-power modes. */ +#endif /* FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT */ +} slcd_interrupt_enable_t; + +/*! @brief SLCD behavior in low power mode. */ +typedef enum _slcd_lowpower_behavior +{ + kSLCD_EnabledInWaitStop = 0, /*!< SLCD works in wait and stop mode. */ + kSLCD_EnabledInWaitOnly, /*!< SLCD works in wait mode and is disabled in stop mode. */ + kSLCD_EnabledInStopOnly, /*!< SLCD works in stop mode and is disabled in wait mode. */ + kSLCD_DisabledInWaitStop /*!< SLCD is disabled in stop mode and wait mode. */ +} slcd_lowpower_behavior; + +/*! @brief SLCD fault frame detection configure structure. */ +typedef struct _slcd_fault_detect_config +{ + bool faultDetectIntEnable; /*!< Fault frame detection interrupt enable flag.*/ + bool faultDetectBackPlaneEnable; /*!< True means the pin id fault detected is back plane otherwise front plane. */ + uint8_t faultDetectPinIndex; /*!< Fault detected pin id from 0 to 63. */ + slcd_fault_detect_clock_prescaler_t faultPrescaler; /*!< Fault detect clock prescaler. */ + slcd_fault_detect_sample_window_width_t width; /*!< Fault detect sample window width. */ +} slcd_fault_detect_config_t; + +/*! @brief SLCD clock configure structure. */ +typedef struct _slcd_clock_config +{ + slcd_clock_src_t clkSource; /*!< Clock source. "slcd_clock_src_t" is recommended to be used. + The SLCD is optimized to operate using a 32.768kHz clock input. */ + slcd_alt_clock_div_t + altClkDivider; /*!< The divider to divide the alternate clock used for alternate clock source. */ + slcd_clock_prescaler_t clkPrescaler; /*!< Clock prescaler. */ +#if FSL_FEATURE_SLCD_HAS_FAST_FRAME_RATE + bool fastFrameRateEnable; /*!< Fast frame rate enable flag. */ +#endif /* FSL_FEATURE_SLCD_HAS_FAST_FRAME_RATE */ +} slcd_clock_config_t; + +/*! @brief SLCD configure structure. */ +typedef struct _slcd_config +{ + slcd_power_supply_option_t powerSupply; /*!< Power supply option. */ + slcd_regulated_voltage_trim_t voltageTrim; /*!< Regulated voltage trim used for the internal regulator VIREG to + adjust to facilitate contrast control. */ + slcd_clock_config_t *clkConfig; /*!< Clock configure. */ + slcd_display_mode_t displayMode; /*!< SLCD display mode. */ + slcd_load_adjust_t loadAdjust; /*!< Load adjust to handle glass capacitance. */ + slcd_duty_cycle_t dutyCycle; /*!< Duty cycle. */ + slcd_lowpower_behavior lowPowerBehavior; /*!< SLCD behavior in low power mode. */ +#if FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT + bool frameFreqIntEnable; /*!< Frame frequency interrupt enable flag.*/ +#endif /* FSL_FEATURE_SLCD_HAS_FAST_FRAME_RATE */ + uint32_t slcdLowPinEnabled; /*!< Setting enabled SLCD pin 0 ~ pin 31. Setting bit n to 1 means enable pin n. */ + uint32_t + slcdHighPinEnabled; /*!< Setting enabled SLCD pin 32 ~ pin 63. Setting bit n to 1 means enable pin (n + 32). */ + uint32_t backPlaneLowPin; /*!< Setting back plane pin 0 ~ pin 31. Setting bit n to 1 means setting pin n as back + plane. It should never have the same bit setting as the frontPlane Pin. */ + uint32_t backPlaneHighPin; /*!< Setting back plane pin 32 ~ pin 63. Setting bit n to 1 means setting pin (n + 32) as + back plane. It should never have the same bit setting as the frontPlane Pin. */ + slcd_fault_detect_config_t *faultConfig; /*!< Fault frame detection configure. If not requirement, set to NULL. */ +} slcd_config_t; +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the SLCD, ungates the module clock, initializes the power + * setting, enables all used plane pins, and sets with interrupt and work mode + * with configuration. + * + * @param base SLCD peripheral base address. + * @param configure SLCD configuration pointer. + * For the configuration structure, many parameters have the default setting + * and the SLCD_Getdefaultconfig() is provided to get them. Use it + * verified for their applications. + * The others have no default settings such as "clkConfig" and must be provided + * by the application before calling the SLCD_Init() API. + */ +void SLCD_Init(LCD_Type *base, slcd_config_t *configure); + +/*! + * @brief Deinitializes the SLCD module, gates the module clock, disables an interrupt, + * and displays the SLCD. + * + * @param base SLCD peripheral base address. + */ +void SLCD_Deinit(LCD_Type *base); + +/*! + * @brief Gets the SLCD default configuration structure. The + * purpose of this API is to get default parameters of the configuration structure + * for the SLCD_Init(). Use these initialized parameters unchanged in SLCD_Init(), + * or modify some fields of the structure before the calling SLCD_Init(). + * All default parameters of the configure structure are listed: + * @code + config.displayMode = kSLCD_NormalMode; // SLCD normal mode + config.powerSupply = kSLCD_InternalVll3UseChargePump; // Use charge pump internal VLL3 + config.voltageTrim = kSLCD_RegulatedVolatgeTrim00; + config.lowPowerBehavior = kSLCD_EnabledInWaitStop; // Work on low power mode + config.interruptSrc = 0; // No interrupt source is enabled + config.faultConfig = NULL; // Fault detection is disabled + config.frameFreqIntEnable = false; + @endcode + * @param configure The SLCD configuration structure pointer. + */ +void SLCD_GetDefaultConfig(slcd_config_t *configure); + +/* @}*/ + +/*! + * @name Plane Setting and Display Control + * @{ + */ + +/*! + * @brief Enables the SLCD controller, starts generate, and displays the front plane and back plane waveform. + * + * @param base SLCD peripheral base address. + */ +static inline void SLCD_StartDisplay(LCD_Type *base) +{ + base->GCR |= LCD_GCR_LCDEN_MASK; +} + +/*! + * @brief Stops the SLCD controller. There is no waveform generator and all enabled pins + * only output a low value. + * + * @param base SLCD peripheral base address. + */ +static inline void SLCD_StopDisplay(LCD_Type *base) +{ + base->GCR &= ~LCD_GCR_LCDEN_MASK; +} + +/*! + * @brief Starts the SLCD blink mode. + * + * @param base SLCD peripheral base address. + * @param mode SLCD blink mode. + * @param rate SLCD blink rate. + */ +void SLCD_StartBlinkMode(LCD_Type *base, slcd_blink_mode_t mode, slcd_blink_rate_t rate); + +/*! + * @brief Stops the SLCD blink mode. + * + * @param base SLCD peripheral base address. + */ +static inline void SLCD_StopBlinkMode(LCD_Type *base) +{ + base->AR &= ~LCD_AR_BLINK_MASK; +} + +/*! + * @brief Sets the SLCD back plane pin phase. + * + * This function sets the SLCD back plane pin phase. "kSLCD_PhaseXActivate" setting + * means the phase X is active for the back plane pin. "kSLCD_NoPhaseActivate" setting + * means there is no phase active for the back plane pin. + * register value. + * For example, set the back plane pin 20 for phase A: + * @code + * SLCD_SetBackPlanePhase(LCD, 20, kSLCD_PhaseAActivate); + * @endcode + * + * @param base SLCD peripheral base address. + * @param pinIndx SLCD back plane pin index. Range from 0 to 63. + * @param phase The phase activates for the back plane pin. + */ +static inline void SLCD_SetBackPlanePhase(LCD_Type *base, uint32_t pinIndx, slcd_phase_type_t phase) +{ + base->WF8B[pinIndx] = phase; +} + +/*! + * @brief Sets the SLCD front plane segment operation for a front plane pin. + * + * This function sets the SLCD front plane segment on or off operation. + * Each bit turns on or off the segments associated with the front plane pin in + * the following pattern: HGFEDCBA (most significant bit controls segment H and + * least significant bit controls segment A). + * For example, turn on the front plane pin 20 for phase B and phase C: + * @code + * SLCD_SetFrontPlaneSegments(LCD, 20, (kSLCD_PhaseBActivate | kSLCD_PhaseCActivate)); + * @endcode + * + * @param base SLCD peripheral base address. + * @param pinIndx SLCD back plane pin index. Range from 0 to 63. + * @param operation The operation for the segment on the front plane pin. + * This is a logical OR of the enumeration :: slcd_phase_type_t. + */ +static inline void SLCD_SetFrontPlaneSegments(LCD_Type *base, uint32_t pinIndx, uint8_t operation) +{ + base->WF8B[pinIndx] = operation; +} + +/*! + * @brief Sets one SLCD front plane pin for one phase. + * + * This function can be used to set one phase on or off for the front plane pin. + * It can be call many times to set the plane pin for different phase indexes. + * For example, turn on the front plane pin 20 for phase B and phase C: + * @code + * SLCD_SetFrontPlaneOnePhase(LCD, 20, kSLCD_PhaseBIndex, true); + * SLCD_SetFrontPlaneOnePhase(LCD, 20, kSLCD_PhaseCIndex, true); + * @endcode + * + * @param base SLCD peripheral base address. + * @param pinIndx SLCD back plane pin index. Range from 0 to 63. + * @param phaseIndx The phase bit index @ref slcd_phase_index_t. + * @param enable True to turn on the segment for phaseIndx phase + * false to turn off the segment for phaseIndx phase. + */ +static inline void SLCD_SetFrontPlaneOnePhase(LCD_Type *base, + uint32_t pinIndx, + slcd_phase_index_t phaseIndx, + bool enable) +{ + uint8_t reg = base->WF8B[pinIndx]; + + if (enable) + { + base->WF8B[pinIndx] = (reg | (1U << phaseIndx)); + } + else + { + base->WF8B[pinIndx] = (reg & ~(1U << phaseIndx)); + } +} + +#if FSL_FEATURE_SLCD_HAS_PAD_SAFE +/*! + * @brief Enables/disables the SLCD pad safe state. + * + * Forces the safe state on the LCD pad controls. All LCD front plane + * and backplane functions are disabled. + * + * @param base SLCD peripheral base address. + * @param enable True enable, false disable. + */ +static inline void SLCD_EnablePadSafeState(LCD_Type *base, bool enable) +{ + if (enable) + { /* Enable. */ + base->GCR |= LCD_GCR_PADSAFE_MASK; + } + else + { /* Disable. */ + base->GCR &= ~LCD_GCR_PADSAFE_MASK; + } +} +#endif /* FSL_FEATURE_SLCD_HAS_PAD_SAFE */ + +/*! + * @brief Gets the SLCD fault detect counter. + * + * This function gets the number of samples inside the + * fault detection sample window. + * + * @param base SLCD peripheral base address. + * @return The fault detect counter. The maximum return value is 255. + * If the maximum 255 returns, the overflow may happen. + * Reconfigure the fault detect sample window and fault detect clock prescaler + * for proper sampling. + */ +static inline uint32_t SLCD_GetFaultDetectCounter(LCD_Type *base) +{ + return base->FDSR & LCD_FDSR_FDCNT_MASK; +} + +/* @} */ + +/*! + * @name Interrupts. + * @{ + */ + +/*! + * @brief Enables the SLCD interrupt. + * For example, to enable fault detect complete interrupt and frame frequency interrupt, + * for FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT enabled case, do the following. + * @code + * SLCD_EnableInterrupts(LCD,kSLCD_FaultDetectCompleteInterrupt | kSLCD_FrameFreqInterrupt); + * @endcode + * + * @param base SLCD peripheral base address. + * @param mask SLCD interrupts to enable. This is a logical OR of the + * enumeration :: slcd_interrupt_enable_t. + */ +void SLCD_EnableInterrupts(LCD_Type *base, uint32_t mask); + +/*! + * @brief Disables the SLCD interrupt. + * For example, to disable fault detect complete interrupt and frame frequency interrupt, + * for FSL_FEATURE_SLCD_HAS_FRAME_FREQUENCY_INTERRUPT enabled case, do the following. + * @code + * SLCD_DisableInterrupts(LCD,kSLCD_FaultDetectCompleteInterrupt | kSLCD_FrameFreqInterrupt); + * @endcode + * + * @param base SLCD peripheral base address. + * @param mask SLCD interrupts to disable. This is a logical OR of the + * enumeration :: slcd_interrupt_enable_t. + */ +void SLCD_DisableInterrupts(LCD_Type *base, uint32_t mask); + +/*! + * @brief Gets the SLCD interrupt status flag. + * + * @param base SLCD peripheral base address. + * @return The event status of the interrupt source. This is the logical OR of members + * of the enumeration :: slcd_interrupt_enable_t. + */ +uint32_t SLCD_GetInterruptStatus(LCD_Type *base); + +/*! + * @brief Clears the SLCD interrupt events status flag. + * + * @param base SLCD peripheral base address. + * @param mask SLCD interrupt source to be cleared. + * This is the logical OR of members of the enumeration :: slcd_interrupt_enable_t. + */ +void SLCD_ClearInterruptStatus(LCD_Type *base, uint32_t mask); + +/* @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* _FSL_SLCD_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_smc.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_smc.c new file mode 100644 index 0000000000..0018cf7dce --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_smc.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_smc.h" + +#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +void SMC_GetParam(SMC_Type *base, smc_param_t *param) +{ + uint32_t reg = base->PARAM; + param->hsrunEnable = (bool)(reg & SMC_PARAM_EHSRUN_MASK); + param->llsEnable = (bool)(reg & SMC_PARAM_ELLS_MASK); + param->lls2Enable = (bool)(reg & SMC_PARAM_ELLS2_MASK); + param->vlls0Enable = (bool)(reg & SMC_PARAM_EVLLS0_MASK); +} +#endif /* FSL_FEATURE_SMC_HAS_PARAM */ + +status_t SMC_SetPowerModeRun(SMC_Type *base) +{ + uint8_t reg; + + reg = base->PMCTRL; + /* configure Normal RUN mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_RunNormal << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} + +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) +status_t SMC_SetPowerModeHsrun(SMC_Type *base) +{ + uint8_t reg; + + reg = base->PMCTRL; + /* configure High Speed RUN mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + +status_t SMC_SetPowerModeWait(SMC_Type *base) +{ + /* configure Normal Wait mode */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __WFI(); + + return kStatus_Success; +} + +status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) +{ + uint8_t reg; + +#if (defined(FSL_FEATURE_SMC_HAS_PSTOPO) && FSL_FEATURE_SMC_HAS_PSTOPO) + /* configure the Partial Stop mode in Noraml Stop mode */ + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + base->STOPCTRL = reg; +#endif + + /* configure Normal Stop mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + + /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __WFI(); + + /* check whether the power mode enter Stop mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} + +status_t SMC_SetPowerModeVlpr(SMC_Type *base +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + , + bool wakeupMode +#endif + ) +{ + uint8_t reg; + + reg = base->PMCTRL; +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + /* configure whether the system remains in VLP mode on an interrupt */ + if (wakeupMode) + { + /* exits to RUN mode on an interrupt */ + reg |= SMC_PMCTRL_LPWUI_MASK; + } + else + { + /* remains in VLP mode on an interrupt */ + reg &= ~SMC_PMCTRL_LPWUI_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPWUI */ + + /* configure VLPR mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} + +status_t SMC_SetPowerModeVlpw(SMC_Type *base) +{ + /* Power mode transaction to VLPW can only happen in VLPR mode */ + if (kSMC_PowerStateVlpr != SMC_GetPowerModeState(base)) + { + return kStatus_Fail; + } + + /* configure VLPW mode */ + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __WFI(); + + return kStatus_Success; +} + +status_t SMC_SetPowerModeVlps(SMC_Type *base) +{ + uint8_t reg; + + /* configure VLPS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __WFI(); + + /* check whether the power mode enter VLPS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} + +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +status_t SMC_SetPowerModeLls(SMC_Type *base +#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ + (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)) + , + const smc_power_mode_lls_config_t *config +#endif + ) +{ + uint8_t reg; + + /* configure to LLS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopLls << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + +/* configure LLS sub-mode*/ +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); + base->STOPCTRL = reg; +#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ + +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + if (config->enableLpoClock) + { + base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK; + } + else + { + base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPOPO */ + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __WFI(); + + /* check whether the power mode enter LLS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) +status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) +{ + uint8_t reg; + +#if (defined(FSL_FEATURE_SMC_HAS_PORPO) && FSL_FEATURE_SMC_HAS_PORPO) +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \ + (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \ + (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + if (config->subMode == kSMC_StopSub0) +#endif + { + /* configure whether the Por Detect work in Vlls0 mode */ + if (config->enablePorDetectInVlls0) + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL &= ~SMC_VLLSCTRL_PORPO_MASK; +#else + base->STOPCTRL &= ~SMC_STOPCTRL_PORPO_MASK; +#endif + } + else + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL |= SMC_VLLSCTRL_PORPO_MASK; +#else + base->STOPCTRL |= SMC_STOPCTRL_PORPO_MASK; +#endif + } + } +#endif /* FSL_FEATURE_SMC_HAS_PORPO */ + +#if (defined(FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) && FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) + else if (config->subMode == kSMC_StopSub2) + { + /* configure whether the Por Detect work in Vlls0 mode */ + if (config->enableRam2InVlls2) + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; +#else + base->STOPCTRL |= SMC_STOPCTRL_RAM2PO_MASK; +#endif + } + else + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL &= ~SMC_VLLSCTRL_RAM2PO_MASK; +#else + base->STOPCTRL &= ~SMC_STOPCTRL_RAM2PO_MASK; +#endif + } + } + else + { + } +#endif /* FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION */ + + /* configure to VLLS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopVlls << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + +/* configure the VLLS sub-mode */ +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + reg = base->VLLSCTRL; + reg &= ~SMC_VLLSCTRL_VLLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_VLLSCTRL_VLLSM_SHIFT); + base->VLLSCTRL = reg; +#else +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); + base->STOPCTRL = reg; +#else + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_VLLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); + base->STOPCTRL = reg; +#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ +#endif + +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + if (config->enableLpoClock) + { + base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK; + } + else + { + base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPOPO */ + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __WFI(); + + /* check whether the power mode enter LLS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} +#endif /* FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_smc.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_smc.h new file mode 100644 index 0000000000..5149f87e34 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_smc.h @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SMC_H_ +#define _FSL_SMC_H_ + +#include "fsl_common.h" + +/*! @addtogroup smc */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief SMC driver version 2.0.1. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief Power Modes Protection + */ +typedef enum _smc_power_mode_protection +{ +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) + kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-Low-Leakage Stop Mode. */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) + kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-Leakage Stop Mode. */ +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-Power Mode. */ +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) + kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High Speed Run mode. */ +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + kSMC_AllowPowerModeAll = (0U +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) + | + SMC_PMPROT_AVLLS_MASK +#endif +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) + | + SMC_PMPROT_ALLS_MASK +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + | + SMC_PMPROT_AVLP_MASK +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) + | + kSMC_AllowPowerModeHsrun +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + ) /*!< Allow all power mode. */ +} smc_power_mode_protection_t; + +/*! + * @brief Power Modes in PMSTAT + */ +typedef enum _smc_power_state +{ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ + kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ + kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ + kSMC_PowerStateVlps = 0x01U << 4U, /*!< 0001_0000 - Current power mode is VLPS */ +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) + kSMC_PowerStateLls = 0x01U << 5U, /*!< 0010_0000 - Current power mode is LLS */ +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) + kSMC_PowerStateVlls = 0x01U << 6U, /*!< 0100_0000 - Current power mode is VLLS */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) + kSMC_PowerStateHsrun = 0x01U << 7U /*!< 1000_0000 - Current power mode is HSRUN */ +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +} smc_power_state_t; + +/*! + * @brief Run mode definition + */ +typedef enum _smc_run_mode +{ + kSMC_RunNormal = 0U, /*!< normal RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-Low-Power RUN mode. */ +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) + kSMC_Hsrun = 3U /*!< High Speed Run mode (HSRUN). */ +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +} smc_run_mode_t; + +/*! + * @brief Stop mode definition + */ +typedef enum _smc_stop_mode +{ + kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-Low-Power STOP mode. */ +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) + kSMC_StopLls = 3U, /*!< Low-Leakage Stop mode. */ +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) + kSMC_StopVlls = 4U /*!< Very-Low-Leakage Stop mode. */ +#endif +} smc_stop_mode_t; + +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \ + (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \ + (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) +/*! + * @brief VLLS/LLS stop sub mode definition + */ +typedef enum _smc_stop_submode +{ + kSMC_StopSub0 = 0U, /*!< Stop submode 0, for VLLS0/LLS0. */ + kSMC_StopSub1 = 1U, /*!< Stop submode 1, for VLLS1/LLS1. */ + kSMC_StopSub2 = 2U, /*!< Stop submode 2, for VLLS2/LLS2. */ + kSMC_StopSub3 = 3U /*!< Stop submode 3, for VLLS3/LLS3. */ +} smc_stop_submode_t; +#endif + +/*! + * @brief Partial STOP option + */ +typedef enum _smc_partial_stop_mode +{ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ + kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ +} smc_partial_stop_option_t; + +/*! + * @brief SMC configuration status + */ +enum _smc_status +{ + kStatus_SMC_StopAbort = MAKE_STATUS(kStatusGroup_POWER, 0) /*!< Entering Stop mode is abort*/ +}; + +#if (defined(FSL_FEATURE_SMC_HAS_VERID) && FSL_FEATURE_SMC_HAS_VERID) +/*! + * @brief IP version ID definition. + */ +typedef struct _smc_version_id +{ + uint16_t feature; /*!< Feature Specification Number. */ + uint8_t minor; /*!< Minor version number. */ + uint8_t major; /*!< Major version number. */ +} smc_version_id_t; +#endif /* FSL_FEATURE_SMC_HAS_VERID */ + +#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * @brief IP parameter definition. + */ +typedef struct _smc_param +{ + bool hsrunEnable; /*!< HSRUN mode enable. */ + bool llsEnable; /*!< LLS mode enable. */ + bool lls2Enable; /*!< LLS2 mode enable. */ + bool vlls0Enable; /*!< VLLS0 mode enable. */ +} smc_param_t; +#endif /* FSL_FEATURE_SMC_HAS_PARAM */ + +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ + (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) +/*! + * @brief SMC Low-Leakage Stop power mode config + */ +typedef struct _smc_power_mode_lls_config +{ +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + smc_stop_submode_t subMode; /*!< Low-leakage Stop sub-mode */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + bool enableLpoClock; /*!< Enable LPO clock in LLS mode */ +#endif +} smc_power_mode_lls_config_t; +#endif /* (FSL_FEATURE_SMC_HAS_LLS_SUBMODE || FSL_FEATURE_SMC_HAS_LPOPO) */ + +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) +/*! + * @brief SMC Very Low-Leakage Stop power mode config + */ +typedef struct _smc_power_mode_vlls_config +{ +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \ + (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \ + (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + smc_stop_submode_t subMode; /*!< Very Low-leakage Stop sub-mode */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_PORPO) && FSL_FEATURE_SMC_HAS_PORPO) + bool enablePorDetectInVlls0; /*!< Enable Power on reset detect in VLLS mode */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) && FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) + bool enableRam2InVlls2; /*!< Enable RAM2 power in VLLS2 */ +#endif +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + bool enableLpoClock; /*!< Enable LPO clock in VLLS mode */ +#endif +} smc_power_mode_vlls_config_t; +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! @name System mode controller APIs*/ +/*@{*/ + +#if (defined(FSL_FEATURE_SMC_HAS_VERID) && FSL_FEATURE_SMC_HAS_VERID) +/*! + * @brief Gets the SMC version ID. + * + * This function gets the SMC version ID, including major version number, + * minor version number and feature specification number. + * + * @param base SMC peripheral base address. + * @param versionId Pointer to version ID structure. + */ +static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) +{ + *((uint32_t *)versionId) = base->VERID; +} +#endif /* FSL_FEATURE_SMC_HAS_VERID */ + +#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * @brief Gets the SMC parameter. + * + * This function gets the SMC parameter, including the enabled power mdoes. + * + * @param base SMC peripheral base address. + * @param param Pointer to SMC param structure. + */ +void SMC_GetParam(SMC_Type *base, smc_param_t *param); +#endif + +/*! + * @brief Configures all power mode protection settings. + * + * This function configures the power mode protection settings for + * supported power modes in the specified chip family. The available power modes + * are defined in the smc_power_mode_protection_t. This should be done at an early + * system level initialization stage. See the reference manual for details. + * This register can only write once after the power reset. + * + * The allowed modes are passed as bit map, for example, to allow LLS and VLLS, + * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). + * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). + * + * @param base SMC peripheral base address. + * @param allowedModes Bitmap of the allowed power modes. + */ +static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedModes) +{ + base->PMPROT = allowedModes; +} + +/*! + * @brief Gets the current power mode status. + * + * This function returns the current power mode stat. Once application + * switches the power mode, it should always check the stat to check whether it + * runs into the specified mode or not. An application should check + * this mode before switching to a different mode. The system requires that + * only certain modes can switch to other specific modes. See the + * reference manual for details and the smc_power_state_t for information about + * the power stat. + * + * @param base SMC peripheral base address. + * @return Current power mode status. + */ +static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base) +{ + return (smc_power_state_t)base->PMSTAT; +} + +/*! + * @brief Configure the system to RUN power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeRun(SMC_Type *base); + +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) +/*! + * @brief Configure the system to HSRUN power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeHsrun(SMC_Type *base); +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + +/*! + * @brief Configure the system to WAIT power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeWait(SMC_Type *base); + +/*! + * @brief Configure the system to Stop power mode. + * + * @param base SMC peripheral base address. + * @param option Partial Stop mode option. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); + +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) +/*! + * @brief Configure the system to VLPR power mode. + * + * @param base SMC peripheral base address. + * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); +#else +/*! + * @brief Configure the system to VLPR power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlpr(SMC_Type *base); +#endif /* FSL_FEATURE_SMC_HAS_LPWUI */ + +/*! + * @brief Configure the system to VLPW power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlpw(SMC_Type *base); + +/*! + * @brief Configure the system to VLPS power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlps(SMC_Type *base); + +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ + (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)) +/*! + * @brief Configure the system to LLS power mode. + * + * @param base SMC peripheral base address. + * @param config The LLS power mode configuration structure + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); +#else +/*! + * @brief Configure the system to LLS power mode. + * + * @param base SMC peripheral base address. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeLls(SMC_Type *base); +#endif +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) +/*! + * @brief Configure the system to VLLS power mode. + * + * @param base SMC peripheral base address. + * @param config The VLLS power mode configuration structure. + * @return SMC configuration error code. + */ +status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config); +#endif /* FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_SMC_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi.c new file mode 100644 index 0000000000..b2dde5cb9b --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi.c @@ -0,0 +1,945 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_spi.h" + +/******************************************************************************* + * Definitons + ******************************************************************************/ +/*! @brief SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */ +enum _spi_transfer_states_t +{ + kSPI_Idle = 0x0, /*!< SPI is idle state */ + kSPI_Busy /*!< SPI is busy tranferring data. */ +}; + +/*! @brief Typedef for spi master interrupt handler. spi master and slave handle is the same. */ +typedef void (*spi_isr_t)(SPI_Type *base, spi_master_handle_t *spiHandle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get the instance for SPI module. + * + * @param base SPI base address + */ +uint32_t SPI_GetInstance(SPI_Type *base); + +/*! + * @brief Sends a buffer of data bytes in non-blocking way. + * + * @param base SPI base pointer + * @param buffer The data bytes to send + * @param size The number of data bytes to send + */ +static void SPI_WriteNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size); + +/*! + * @brief Receive a buffer of data bytes in non-blocking way. + * + * @param base SPI base pointer + * @param buffer The data bytes to send + * @param size The number of data bytes to send + */ +static void SPI_ReadNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size); + +/*! + * @brief Send a piece of data for SPI. + * + * This function computes the number of data to be written into D register or Tx FIFO, + * and write the data into it. At the same time, this function updates the values in + * master handle structure. + * + * @param handle Pointer to SPI master handle structure. + */ +static void SPI_SendTransfer(SPI_Type *base, spi_master_handle_t *handle); + +/*! + * @brief Receive a piece of data for SPI master. + * + * This function computes the number of data to receive from D register or Rx FIFO, + * and write the data to destination address. At the same time, this function updates + * the values in master handle structure. + * + * @param handle Pointer to SPI master handle structure. + */ +static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle); +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief SPI internal handle pointer array */ +static spi_master_handle_t *s_spiHandle[FSL_FEATURE_SOC_SPI_COUNT]; +/*! @brief Base pointer array */ +static SPI_Type *const s_spiBases[] = SPI_BASE_PTRS; +/*! @brief IRQ name array */ +static const IRQn_Type s_spiIRQ[] = SPI_IRQS; +/*! @brief Clock array name */ +static const clock_ip_name_t s_spiClock[] = SPI_CLOCKS; + +/*! @brief Pointer to master IRQ handler for each instance. */ +static spi_isr_t s_spiIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +uint32_t SPI_GetInstance(SPI_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_SPI_COUNT; instance++) + { + if (s_spiBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_SPI_COUNT); + + return instance; +} + +static void SPI_WriteNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size) +{ + uint32_t i = 0; + uint8_t bytesPerFrame = 1U; + +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + /* Check if 16 bits or 8 bits */ + bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; +#endif + + while (i < size) + { + if (buffer != NULL) + { +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + /*16 bit mode*/ + if (base->C2 & SPI_C2_SPIMODE_MASK) + { + base->DL = *buffer++; + base->DH = *buffer++; + } + /* 8 bit mode */ + else + { + base->DL = *buffer++; + } +#else + base->D = *buffer++; +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + } + /* Send dummy data */ + else + { + SPI_WriteData(base, SPI_DUMMYDATA); + } + i += bytesPerFrame; + } +} + +static void SPI_ReadNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size) +{ + uint32_t i = 0; + uint8_t bytesPerFrame = 1U; + +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + /* Check if 16 bits or 8 bits */ + bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; +#endif + + while (i < size) + { + if (buffer != NULL) + { +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + /*16 bit mode*/ + if (base->C2 & SPI_C2_SPIMODE_MASK) + { + *buffer++ = base->DL; + *buffer++ = base->DH; + } + /* 8 bit mode */ + else + { + *buffer++ = base->DL; + } +#else + *buffer++ = base->D; +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + } + else + { + SPI_ReadData(base); + } + i += bytesPerFrame; + } +} + +static void SPI_SendTransfer(SPI_Type *base, spi_master_handle_t *handle) +{ + uint8_t bytes = MIN((handle->watermark * 2U), handle->txRemainingBytes); + + /* Read S register and ensure SPTEF is 1, otherwise the write would be ignored. */ + if (handle->watermark == 1U) + { + if (bytes != 0U) + { + bytes = handle->bytePerFrame; + } + + /* Send data */ + if (base->C1 & SPI_C1_MSTR_MASK) + { + /* As a master, only write once */ + if (base->S & SPI_S_SPTEF_MASK) + { + SPI_WriteNonBlocking(base, handle->txData, bytes); + /* Update handle information */ + if (handle->txData) + { + handle->txData += bytes; + } + handle->txRemainingBytes -= bytes; + } + } + else + { + /* As a slave, send data until SPTEF cleared */ + while ((base->S & SPI_S_SPTEF_MASK) && (handle->txRemainingBytes > 0)) + { + SPI_WriteNonBlocking(base, handle->txData, bytes); + + /* Update handle information */ + if (handle->txData) + { + handle->txData += bytes; + } + handle->txRemainingBytes -= bytes; + } + } + } + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO) + /* If use FIFO */ + else + { + if (base->S & SPI_S_TNEAREF_MASK) + { + SPI_WriteNonBlocking(base, handle->txData, bytes); + + /* Update handle information */ + if (handle->txData) + { + handle->txData += bytes; + } + handle->txRemainingBytes -= bytes; + } + } +#endif +} + +static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle) +{ + uint8_t bytes = MIN((handle->watermark * 2U), handle->rxRemainingBytes); + uint8_t val = 1U; + + /* Read S register and ensure SPRF is 1, otherwise the write would be ignored. */ + if (handle->watermark == 1U) + { + val = base->S & SPI_S_SPRF_MASK; + if (bytes != 0U) + { + bytes = handle->bytePerFrame; + } + } + + if (val) + { + SPI_ReadNonBlocking(base, handle->rxData, bytes); + + /* Update information in handle */ + if (handle->rxData) + { + handle->rxData += bytes; + } + handle->rxRemainingBytes -= bytes; + } +} + +void SPI_MasterGetDefaultConfig(spi_master_config_t *config) +{ + config->enableMaster = true; + config->enableStopInWaitMode = false; + config->polarity = kSPI_ClockPolarityActiveHigh; + config->phase = kSPI_ClockPhaseFirstEdge; + config->direction = kSPI_MsbFirst; + +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + config->dataMode = kSPI_8BitMode; +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + config->txWatermark = kSPI_TxFifoOneHalfEmpty; + config->rxWatermark = kSPI_RxFifoOneHalfFull; +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + + config->pinMode = kSPI_PinModeNormal; + config->outputMode = kSPI_SlaveSelectAutomaticOutput; + config->baudRate_Bps = 500000U; +} + +void SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz) +{ + assert(config && srcClock_Hz); + + /* Open clock gate for SPI and open interrupt */ + CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]); + + /* Disable SPI before configuration */ + base->C1 &= ~SPI_C1_SPE_MASK; + + /* Configure clock polarity and phase, set SPI to master */ + base->C1 = SPI_C1_MSTR(1U) | SPI_C1_CPOL(config->polarity) | SPI_C1_CPHA(config->phase) | + SPI_C1_SSOE(config->outputMode & 1U) | SPI_C1_LSBFE(config->direction); + +/* Set data mode, and also pin mode and mode fault settings */ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + base->C2 = SPI_C2_MODFEN(config->outputMode >> 1U) | SPI_C2_BIDIROE(config->pinMode >> 1U) | + SPI_C2_SPISWAI(config->enableStopInWaitMode) | SPI_C2_SPC0(config->pinMode & 1U) | + SPI_C2_SPIMODE(config->dataMode); +#else + base->C2 = SPI_C2_MODFEN(config->outputMode >> 1U) | SPI_C2_BIDIROE(config->pinMode >> 1U) | + SPI_C2_SPISWAI(config->enableStopInWaitMode) | SPI_C2_SPC0(config->pinMode & 1U); +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + +/* Set watermark, FIFO is enabled */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0) + { + base->C3 = SPI_C3_TNEAREF_MARK(config->txWatermark) | SPI_C3_RNFULLF_MARK(config->rxWatermark) | + SPI_C3_INTCLR(0U) | SPI_C3_FIFOMODE(1U); + } +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + + /* Set baud rate */ + SPI_MasterSetBaudRate(base, config->baudRate_Bps, srcClock_Hz); + + /* Enable SPI */ + if (config->enableMaster) + { + base->C1 |= SPI_C1_SPE_MASK; + } +} + +void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config) +{ + config->enableSlave = true; + config->polarity = kSPI_ClockPolarityActiveHigh; + config->phase = kSPI_ClockPhaseFirstEdge; + config->direction = kSPI_MsbFirst; + config->enableStopInWaitMode = false; + +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + config->dataMode = kSPI_8BitMode; +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + config->txWatermark = kSPI_TxFifoOneHalfEmpty; + config->rxWatermark = kSPI_RxFifoOneHalfFull; +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ +} + +void SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config) +{ + assert(config); + + /* Open clock gate for SPI and open interrupt */ + CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]); + + /* Disable SPI before configuration */ + base->C1 &= ~SPI_C1_SPE_MASK; + + /* Configure master and clock polarity and phase */ + base->C1 = + SPI_C1_MSTR(0U) | SPI_C1_CPOL(config->polarity) | SPI_C1_CPHA(config->phase) | SPI_C1_LSBFE(config->direction); + +/* Configure data mode if needed */ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + base->C2 = SPI_C2_SPIMODE(config->dataMode) | SPI_C2_SPISWAI(config->enableStopInWaitMode); +#else + base->C2 = SPI_C2_SPISWAI(config->enableStopInWaitMode); +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + +/* Set watermark */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0U) + { + base->C3 = SPI_C3_TNEAREF_MARK(config->txWatermark) | SPI_C3_RNFULLF_MARK(config->rxWatermark) | + SPI_C3_INTCLR(0U) | SPI_C3_FIFOMODE(1U); + } +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + + /* Enable SPI */ + if (config->enableSlave) + { + base->C1 |= SPI_C1_SPE_MASK; + } +} + +void SPI_Deinit(SPI_Type *base) +{ + /* Disable SPI module before shutting down */ + base->C1 &= ~SPI_C1_SPE_MASK; + + /* Gate the clock */ + CLOCK_DisableClock(s_spiClock[SPI_GetInstance(base)]); +} + +uint32_t SPI_GetStatusFlags(SPI_Type *base) +{ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0) + { + return ((base->S) | (((uint32_t)base->CI) << 8U)); + } + else + { + return (base->S); + } +#else + return (base->S); +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ +} + +void SPI_EnableInterrupts(SPI_Type *base, uint32_t mask) +{ + /* Rx full interrupt */ + if (mask & kSPI_RxFullAndModfInterruptEnable) + { + base->C1 |= SPI_C1_SPIE_MASK; + } + + /* Tx empty interrupt */ + if (mask & kSPI_TxEmptyInterruptEnable) + { + base->C1 |= SPI_C1_SPTIE_MASK; + } + + /* Data match interrupt */ + if (mask & kSPI_MatchInterruptEnable) + { + base->C2 |= SPI_C2_SPMIE_MASK; + } + +/* FIFO related interrupts */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0) + { + /* Rx FIFO near full interrupt */ + if (mask & kSPI_RxFifoNearFullInterruptEnable) + { + base->C3 |= SPI_C3_RNFULLIEN_MASK; + } + + /* Tx FIFO near empty interrupt */ + if (mask & kSPI_TxFifoNearEmptyInterruptEnable) + { + base->C3 |= SPI_C3_TNEARIEN_MASK; + } + } +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ +} + +void SPI_DisableInterrupts(SPI_Type *base, uint32_t mask) +{ + /* Rx full interrupt */ + if (mask & kSPI_RxFullAndModfInterruptEnable) + { + base->C1 &= (~SPI_C1_SPIE_MASK); + } + + /* Tx empty interrupt */ + if (mask & kSPI_TxEmptyInterruptEnable) + { + base->C1 &= (~SPI_C1_SPTIE_MASK); + } + + /* Data match interrupt */ + if (mask & kSPI_MatchInterruptEnable) + { + base->C2 &= (~SPI_C2_SPMIE_MASK); + } + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0) + { + /* Rx FIFO near full interrupt */ + if (mask & kSPI_RxFifoNearFullInterruptEnable) + { + base->C3 &= ~SPI_C3_RNFULLIEN_MASK; + } + + /* Tx FIFO near empty interrupt */ + if (mask & kSPI_TxFifoNearEmptyInterruptEnable) + { + base->C3 &= ~SPI_C3_TNEARIEN_MASK; + } + } +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ +} + +void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + uint32_t prescaler; + uint32_t bestPrescaler; + uint32_t rateDivisor; + uint32_t bestDivisor; + uint32_t rateDivisorValue; + uint32_t realBaudrate; + uint32_t diff; + uint32_t min_diff; + uint32_t freq = baudRate_Bps; + + /* Find combination of prescaler and scaler resulting in baudrate closest to the requested value */ + min_diff = 0xFFFFFFFFU; + + /* Set the maximum divisor bit settings for each of the following divisors */ + bestPrescaler = 7U; + bestDivisor = 8U; + + /* In all for loops, if min_diff = 0, the exit for loop*/ + for (prescaler = 0; (prescaler <= 7) && min_diff; prescaler++) + { + /* Initialize to div-by-2 */ + rateDivisorValue = 2U; + + for (rateDivisor = 0; (rateDivisor <= 8U) && min_diff; rateDivisor++) + { + /* Calculate actual baud rate, note need to add 1 to prescaler */ + realBaudrate = ((srcClock_Hz) / ((prescaler + 1) * rateDivisorValue)); + + /* Calculate the baud rate difference based on the conditional statement ,that states that the + calculated baud rate must not exceed the desired baud rate */ + if (freq >= realBaudrate) + { + diff = freq - realBaudrate; + if (min_diff > diff) + { + /* A better match found */ + min_diff = diff; + bestPrescaler = prescaler; + bestDivisor = rateDivisor; + } + } + + /* Multiply by 2 for each iteration, possible divisor values: 2, 4, 8, 16, ... 512 */ + rateDivisorValue *= 2U; + } + } + + /* Write the best prescalar and baud rate scalar */ + base->BR = SPI_BR_SPR(bestDivisor) | SPI_BR_SPPR(bestPrescaler); +} + +void SPI_WriteBlocking(SPI_Type *base, uint8_t *buffer, size_t size) +{ + uint32_t i = 0; + uint8_t bytesPerFrame = 1U; + +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + /* Check if 16 bits or 8 bits */ + bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; +#endif + + while (i < size) + { + while ((base->S & SPI_S_SPTEF_MASK) == 0) + { + } + + /* Send a frame of data */ + SPI_WriteNonBlocking(base, buffer, bytesPerFrame); + + i += bytesPerFrame; + buffer += bytesPerFrame; + } +} + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO +void SPI_EnableFIFO(SPI_Type *base, bool enable) +{ + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0U) + { + if (enable) + { + base->C3 |= SPI_C3_FIFOMODE_MASK; + } + else + { + base->C3 &= ~SPI_C3_FIFOMODE_MASK; + } + } +} +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + +void SPI_WriteData(SPI_Type *base, uint16_t data) +{ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS) + base->DL = data & 0xFFU; + base->DH = (data >> 8U) & 0xFFU; +#else + base->D = data & 0xFFU; +#endif +} + +uint16_t SPI_ReadData(SPI_Type *base) +{ + uint16_t val = 0; +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS) + val = base->DL; + val |= (uint16_t)((uint16_t)(base->DH) << 8U); +#else + val = base->D; +#endif + return val; +} + +status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer) +{ + assert(xfer); + + uint8_t bytesPerFrame = 1U; + + /* Check if the argument is legal */ + if ((xfer->txData == NULL) && (xfer->rxData == NULL)) + { + return kStatus_InvalidArgument; + } + +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + /* Check if 16 bits or 8 bits */ + bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; +#endif + + /* Disable SPI and then enable it, this is used to clear S register */ + base->C1 &= ~SPI_C1_SPE_MASK; + base->C1 |= SPI_C1_SPE_MASK; + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + + /* Disable FIFO, as the FIFO may cause data loss if the data size is not integer + times of 2bytes. As SPI cannot set watermark to 0, only can set to 1/2 FIFO size or 3/4 FIFO + size. */ + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0) + { + base->C3 &= ~SPI_C3_FIFOMODE_MASK; + } + +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + + /* Begin the polling transfer until all data sent */ + while (xfer->dataSize > 0) + { + /* Data send */ + while ((base->S & SPI_S_SPTEF_MASK) == 0U) + { + } + SPI_WriteNonBlocking(base, xfer->txData, bytesPerFrame); + if (xfer->txData) + { + xfer->txData += bytesPerFrame; + } + + while ((base->S & SPI_S_SPRF_MASK) == 0U) + { + } + SPI_ReadNonBlocking(base, xfer->rxData, bytesPerFrame); + if (xfer->rxData) + { + xfer->rxData += bytesPerFrame; + } + + /* Decrease the number */ + xfer->dataSize -= bytesPerFrame; + } + + return kStatus_Success; +} + +void SPI_MasterTransferCreateHandle(SPI_Type *base, + spi_master_handle_t *handle, + spi_master_callback_t callback, + void *userData) +{ + assert(handle); + + uint8_t instance = SPI_GetInstance(base); + + /* Initialize the handle */ + s_spiHandle[instance] = handle; + handle->callback = callback; + handle->userData = userData; + s_spiIsr = SPI_MasterTransferHandleIRQ; + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + uint8_t txSize = 0U; + /* Get the number to be sent if there is FIFO */ + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0) + { + txSize = (base->C3 & SPI_C3_TNEAREF_MARK_MASK) >> SPI_C3_TNEAREF_MARK_SHIFT; + if (txSize == 0U) + { + handle->watermark = FSL_FEATURE_SPI_FIFO_SIZEn(base) * 3U / 4U; + } + else + { + handle->watermark = FSL_FEATURE_SPI_FIFO_SIZEn(base) / 2U; + } + } + /* If no FIFO, just set the watermark to 1 */ + else + { + handle->watermark = 1U; + } +#else + handle->watermark = 1U; +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + +/* Get the bytes per frame */ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS) + handle->bytePerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; +#else + handle->bytePerFrame = 1U; +#endif + + /* Enable SPI NVIC */ + EnableIRQ(s_spiIRQ[instance]); +} + +status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer) +{ + assert(handle && xfer); + + /* Check if SPI is busy */ + if (handle->state == kSPI_Busy) + { + return kStatus_SPI_Busy; + } + + /* Check if the input arguments valid */ + if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + /* Set the handle information */ + handle->txData = xfer->txData; + handle->rxData = xfer->rxData; + handle->transferSize = xfer->dataSize; + handle->txRemainingBytes = xfer->dataSize; + handle->rxRemainingBytes = xfer->dataSize; + + /* Set the SPI state to busy */ + handle->state = kSPI_Busy; + + /* Disable SPI and then enable it, this is used to clear S register*/ + base->C1 &= ~SPI_C1_SPE_MASK; + base->C1 |= SPI_C1_SPE_MASK; + +/* Enable Interrupt, only enable Rx interrupt, use rx interrupt to driver SPI transfer */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + if (handle->watermark > 1U) + { + /* Enable Rx near full interrupt */ + SPI_EnableInterrupts(base, kSPI_RxFifoNearFullInterruptEnable); + } + else + { + SPI_EnableInterrupts(base, kSPI_RxFullAndModfInterruptEnable); + } +#else + SPI_EnableInterrupts(base, kSPI_RxFullAndModfInterruptEnable); +#endif + + /* First send a piece of data to Tx Data or FIFO to start a SPI transfer */ + SPI_SendTransfer(base, handle); + + return kStatus_Success; +} + +status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kStatus_SPI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + /* Return remaing bytes in different cases */ + if (handle->rxData) + { + *count = handle->transferSize - handle->rxRemainingBytes; + } + else + { + *count = handle->transferSize - handle->txRemainingBytes; + } + } + + return status; +} + +void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle) +{ + assert(handle); + +/* Stop interrupts */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + if (handle->watermark > 1U) + { + SPI_DisableInterrupts(base, kSPI_RxFifoNearFullInterruptEnable | kSPI_RxFullAndModfInterruptEnable); + } + else + { + SPI_DisableInterrupts(base, kSPI_RxFullAndModfInterruptEnable); + } +#else + SPI_DisableInterrupts(base, kSPI_RxFullAndModfInterruptEnable); +#endif + + /* Transfer finished, set the state to Done*/ + handle->state = kSPI_Idle; + + /* Clear the internal state */ + handle->rxRemainingBytes = 0; + handle->txRemainingBytes = 0; +} + +void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle) +{ + assert(handle); + + /* If needs to receive data, do a receive */ + if (handle->rxRemainingBytes) + { + SPI_ReceiveTransfer(base, handle); + } + + /* We always need to send a data to make the SPI run */ + if (handle->txRemainingBytes) + { + SPI_SendTransfer(base, handle); + } + + /* All the transfer finished */ + if ((handle->txRemainingBytes == 0) && (handle->rxRemainingBytes == 0)) + { + /* Complete the transfer */ + SPI_MasterTransferAbort(base, handle); + + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SPI_Idle, handle->userData); + } + } +} + +void SPI_SlaveTransferCreateHandle(SPI_Type *base, + spi_slave_handle_t *handle, + spi_slave_callback_t callback, + void *userData) +{ + assert(handle); + + /* Slave create handle share same logic with master create handle, the only difference + is the Isr pointer. */ + SPI_MasterTransferCreateHandle(base, handle, callback, userData); + s_spiIsr = SPI_SlaveTransferHandleIRQ; +} + +void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle) +{ + assert(handle); + + /* Do data send first in case of data missing. */ + if (handle->txRemainingBytes) + { + SPI_SendTransfer(base, handle); + } + + /* If needs to receive data, do a receive */ + if (handle->rxRemainingBytes) + { + SPI_ReceiveTransfer(base, handle); + } + + /* All the transfer finished */ + if ((handle->txRemainingBytes == 0) && (handle->rxRemainingBytes == 0)) + { + /* Complete the transfer */ + SPI_SlaveTransferAbort(base, handle); + + if (handle->callback) + { + (handle->callback)(base, handle, kStatus_SPI_Idle, handle->userData); + } + } +} + +#if defined(SPI0) +void SPI0_DriverIRQHandler(void) +{ + assert(s_spiHandle[0]); + s_spiIsr(SPI0, s_spiHandle[0]); +} +#endif + +#if defined(SPI1) +void SPI1_DriverIRQHandler(void) +{ + assert(s_spiHandle[1]); + s_spiIsr(SPI1, s_spiHandle[1]); +} +#endif + +#if defined(SPI2) +void SPI2_DriverIRQHandler(void) +{ + assert(s_spiHandle[2]); + s_spiIsr(SPI0, s_spiHandle[2]); +} +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi.h new file mode 100644 index 0000000000..7e9162350d --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi.h @@ -0,0 +1,707 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SPI_H_ +#define _FSL_SPI_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup spi_driver + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief SPI driver version 2.0.1. */ +#define FSL_SPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +#ifndef SPI_DUMMYDATA +/*! @brief SPI dummy transfer data, the data is sent while txBuff is NULL. */ +#define SPI_DUMMYDATA (0xFFU) +#endif + +/*! @brief Return status for the SPI driver.*/ +enum _spi_status +{ + kStatus_SPI_Busy = MAKE_STATUS(kStatusGroup_SPI, 0), /*!< SPI bus is busy */ + kStatus_SPI_Idle = MAKE_STATUS(kStatusGroup_SPI, 1), /*!< SPI is idle */ + kStatus_SPI_Error = MAKE_STATUS(kStatusGroup_SPI, 2) /*!< SPI error */ +}; + +/*! @brief SPI clock polarity configuration.*/ +typedef enum _spi_clock_polarity +{ + kSPI_ClockPolarityActiveHigh = 0x0U, /*!< Active-high SPI clock (idles low). */ + kSPI_ClockPolarityActiveLow /*!< Active-low SPI clock (idles high). */ +} spi_clock_polarity_t; + +/*! @brief SPI clock phase configuration.*/ +typedef enum _spi_clock_phase +{ + kSPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SPSCK occurs at the middle of the first + * cycle of a data transfer. */ + kSPI_ClockPhaseSecondEdge /*!< First edge on SPSCK occurs at the start of the + * first cycle of a data transfer. */ +} spi_clock_phase_t; + +/*! @brief SPI data shifter direction options.*/ +typedef enum _spi_shift_direction +{ + kSPI_MsbFirst = 0x0U, /*!< Data transfers start with most significant bit. */ + kSPI_LsbFirst /*!< Data transfers start with least significant bit. */ +} spi_shift_direction_t; + +/*! @brief SPI slave select output mode options.*/ +typedef enum _spi_ss_output_mode +{ + kSPI_SlaveSelectAsGpio = 0x0U, /*!< Slave select pin configured as GPIO. */ + kSPI_SlaveSelectFaultInput = 0x2U, /*!< Slave select pin configured for fault detection. */ + kSPI_SlaveSelectAutomaticOutput = 0x3U /*!< Slave select pin configured for automatic SPI output. */ +} spi_ss_output_mode_t; + +/*! @brief SPI pin mode options.*/ +typedef enum _spi_pin_mode +{ + kSPI_PinModeNormal = 0x0U, /*!< Pins operate in normal, single-direction mode.*/ + kSPI_PinModeInput = 0x1U, /*!< Bidirectional mode. Master: MOSI pin is input; + * Slave: MISO pin is input. */ + kSPI_PinModeOutput = 0x3U /*!< Bidirectional mode. Master: MOSI pin is output; + * Slave: MISO pin is output. */ +} spi_pin_mode_t; + +/*! @brief SPI data length mode options.*/ +typedef enum _spi_data_bitcount_mode +{ + kSPI_8BitMode = 0x0U, /*!< 8-bit data transmission mode*/ + kSPI_16BitMode /*!< 16-bit data transmission mode*/ +} spi_data_bitcount_mode_t; + +/*! @brief SPI interrupt sources.*/ +enum _spi_interrupt_enable +{ + kSPI_RxFullAndModfInterruptEnable = 0x1U, /*!< Receive buffer full (SPRF) and mode fault (MODF) interrupt */ + kSPI_TxEmptyInterruptEnable = 0x2U, /*!< Transmit buffer empty interrupt */ + kSPI_MatchInterruptEnable = 0x4U, /*!< Match interrupt */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + kSPI_RxFifoNearFullInterruptEnable = 0x8U, /*!< Receive FIFO nearly full interrupt */ + kSPI_TxFifoNearEmptyInterruptEnable = 0x10U, /*!< Transmit FIFO nearly empty interrupt */ +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ +}; + +/*! @brief SPI status flags.*/ +enum _spi_flags +{ + kSPI_RxBufferFullFlag = SPI_S_SPRF_MASK, /*!< Read buffer full flag */ + kSPI_MatchFlag = SPI_S_SPMF_MASK, /*!< Match flag */ + kSPI_TxBufferEmptyFlag = SPI_S_SPTEF_MASK, /*!< Transmit buffer empty flag */ + kSPI_ModeFaultFlag = SPI_S_MODF_MASK, /*!< Mode fault flag */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + kSPI_RxFifoNearFullFlag = SPI_S_RNFULLF_MASK, /*!< Rx FIFO near full */ + kSPI_TxFifoNearEmptyFlag = SPI_S_TNEAREF_MASK, /*!< Tx FIFO near empty */ + kSPI_TxFifoFullFlag = SPI_S_TXFULLF_MASK, /*!< Tx FIFO full */ + kSPI_RxFifoEmptyFlag = SPI_S_RFIFOEF_MASK, /*!< Rx FIFO empty */ + kSPI_TxFifoError = SPI_CI_TXFERR_MASK << 8U, /*!< Tx FIFO error */ + kSPI_RxFifoError = SPI_CI_RXFERR_MASK << 8U, /*!< Rx FIFO error */ + kSPI_TxOverflow = SPI_CI_TXFOF_MASK << 8U, /*!< Tx FIFO Overflow */ + kSPI_RxOverflow = SPI_CI_RXFOF_MASK << 8U /*!< Rx FIFO Overflow */ +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ +}; + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO +/*! @brief SPI FIFO write-1-to-clear interrupt flags.*/ +typedef enum _spi_w1c_interrupt +{ + kSPI_RxFifoFullClearInterrupt = SPI_CI_SPRFCI_MASK, /*!< Receive FIFO full interrupt */ + kSPI_TxFifoEmptyClearInterrupt = SPI_CI_SPTEFCI_MASK, /*!< Transmit FIFO empty interrupt */ + kSPI_RxNearFullClearInterrupt = SPI_CI_RNFULLFCI_MASK, /*!< Receive FIFO nearly full interrupt */ + kSPI_TxNearEmptyClearInterrupt = SPI_CI_TNEAREFCI_MASK /*!< Transmit FIFO nearly empty interrupt */ +} spi_w1c_interrupt_t; + +/*! @brief SPI TX FIFO watermark settings.*/ +typedef enum _spi_txfifo_watermark +{ + kSPI_TxFifoOneFourthEmpty = 0, /*!< SPI tx watermark at 1/4 FIFO size */ + kSPI_TxFifoOneHalfEmpty = 1 /*!< SPI tx watermark at 1/2 FIFO size */ +} spi_txfifo_watermark_t; + +/*! @brief SPI RX FIFO watermark settings.*/ +typedef enum _spi_rxfifo_watermark +{ + kSPI_RxFifoThreeFourthsFull = 0, /*!< SPI rx watermark at 3/4 FIFO size */ + kSPI_RxFifoOneHalfFull = 1 /*!< SPI rx watermark at 1/2 FIFO size */ +} spi_rxfifo_watermark_t; +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + +#if defined(FSL_FEATURE_SPI_HAS_DMA_SUPPORT) && FSL_FEATURE_SPI_HAS_DMA_SUPPORT +/*! @brief SPI DMA source*/ +enum _spi_dma_enable_t +{ + kSPI_TxDmaEnable = SPI_C2_TXDMAE_MASK, /*!< Tx DMA request source */ + kSPI_RxDmaEnable = SPI_C2_RXDMAE_MASK, /*!< Rx DMA request source */ + kSPI_DmaAllEnable = (SPI_C2_TXDMAE_MASK | SPI_C2_RXDMAE_MASK) /*!< All DMA request source*/ +}; +#endif /* FSL_FEATURE_SPI_HAS_DMA_SUPPORT */ + +/*! @brief SPI master user configure structure.*/ +typedef struct _spi_master_config +{ + bool enableMaster; /*!< Enable SPI at initialization time */ + bool enableStopInWaitMode; /*!< SPI stop in wait mode */ + spi_clock_polarity_t polarity; /*!< Clock polarity */ + spi_clock_phase_t phase; /*!< Clock phase */ + spi_shift_direction_t direction; /*!< MSB or LSB */ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode */ +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + spi_txfifo_watermark_t txWatermark; /*!< Tx watermark settings */ + spi_rxfifo_watermark_t rxWatermark; /*!< Rx watermark settings */ +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + spi_ss_output_mode_t outputMode; /*!< SS pin setting */ + spi_pin_mode_t pinMode; /*!< SPI pin mode select */ + uint32_t baudRate_Bps; /*!< Baud Rate for SPI in Hz */ +} spi_master_config_t; + +/*! @brief SPI slave user configure structure.*/ +typedef struct _spi_slave_config +{ + bool enableSlave; /*!< Enable SPI at initialization time */ + bool enableStopInWaitMode; /*!< SPI stop in wait mode */ + spi_clock_polarity_t polarity; /*!< Clock polarity */ + spi_clock_phase_t phase; /*!< Clock phase */ + spi_shift_direction_t direction; /*!< MSB or LSB */ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode */ +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO + spi_txfifo_watermark_t txWatermark; /*!< Tx watermark settings */ + spi_rxfifo_watermark_t rxWatermark; /*!< Rx watermark settings */ +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ +} spi_slave_config_t; + +/*! @brief SPI transfer structure */ +typedef struct _spi_transfer +{ + uint8_t *txData; /*!< Send buffer */ + uint8_t *rxData; /*!< Receive buffer */ + size_t dataSize; /*!< Transfer bytes */ + uint32_t flags; /*!< SPI control flag, useless to SPI.*/ +} spi_transfer_t; + +typedef struct _spi_master_handle spi_master_handle_t; + +/*! @brief Slave handle is the same with master handle */ +typedef spi_master_handle_t spi_slave_handle_t; + +/*! @brief SPI master callback for finished transmit */ +typedef void (*spi_master_callback_t)(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData); + +/*! @brief SPI master callback for finished transmit */ +typedef void (*spi_slave_callback_t)(SPI_Type *base, spi_slave_handle_t *handle, status_t status, void *userData); + +/*! @brief SPI transfer handle structure */ +struct _spi_master_handle +{ + uint8_t *volatile txData; /*!< Transfer buffer */ + uint8_t *volatile rxData; /*!< Receive buffer */ + volatile size_t txRemainingBytes; /*!< Send data remaining in bytes */ + volatile size_t rxRemainingBytes; /*!< Receive data remaining in bytes */ + volatile uint32_t state; /*!< SPI internal state */ + size_t transferSize; /*!< Bytes to be transferred */ + uint8_t bytePerFrame; /*!< SPI mode, 2bytes or 1byte in a frame */ + uint8_t watermark; /*!< Watermark value for SPI transfer */ + spi_master_callback_t callback; /*!< SPI callback */ + void *userData; /*!< Callback parameter */ +}; + +#if defined(__cplusplus) +extern "C" { +#endif +/******************************************************************************* + * APIs + ******************************************************************************/ +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Sets the SPI master configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in SPI_MasterInit(). + * User may use the initialized structure unchanged in SPI_MasterInit(), or modify + * some fields of the structure before calling SPI_MasterInit(). After calling this API, + * the master is ready to transfer. + * Example: + @code + spi_master_config_t config; + SPI_MasterGetDefaultConfig(&config); + @endcode + * + * @param config pointer to master config structure + */ +void SPI_MasterGetDefaultConfig(spi_master_config_t *config); + +/*! + * @brief Initializes the SPI with master configuration. + * + * The configuration structure can be filled by user from scratch, or be set with default + * values by SPI_MasterGetDefaultConfig(). After calling this API, the slave is ready to transfer. + * Example + @code + spi_master_config_t config = { + .baudRate_Bps = 400000, + ... + }; + SPI_MasterInit(SPI0, &config); + @endcode + * + * @param base SPI base pointer + * @param config pointer to master configuration structure + * @param srcClock_Hz Source clock frequency. + */ +void SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Sets the SPI slave configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in SPI_SlaveInit(). + * Modify some fields of the structure before calling SPI_SlaveInit(). + * Example: + @code + spi_slave_config_t config; + SPI_SlaveGetDefaultConfig(&config); + @endcode + * + * @param config pointer to slave configuration structure + */ +void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config); + +/*! + * @brief Initializes the SPI with slave configuration. + * + * The configuration structure can be filled by user from scratch or be set with + * default values by SPI_SlaveGetDefaultConfig(). + * After calling this API, the slave is ready to transfer. + * Example + @code + spi_slave_config_t config = { + .polarity = kSPIClockPolarity_ActiveHigh; + .phase = kSPIClockPhase_FirstEdge; + .direction = kSPIMsbFirst; + ... + }; + SPI_MasterInit(SPI0, &config); + @endcode + * + * @param base SPI base pointer + * @param config pointer to master configuration structure + */ +void SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config); + +/*! + * @brief De-initializes the SPI. + * + * Calling this API resets the SPI module, gates the SPI clock. + * The SPI module can't work unless calling the SPI_MasterInit/SPI_SlaveInit to initialize module. + * + * @param base SPI base pointer + */ +void SPI_Deinit(SPI_Type *base); + +/*! + * @brief Enables or disables the SPI. + * + * @param base SPI base pointer + * @param enable pass true to enable module, false to disable module + */ +static inline void SPI_Enable(SPI_Type *base, bool enable) +{ + if (enable) + { + base->C1 |= SPI_C1_SPE_MASK; + } + else + { + base->C1 &= ~SPI_C1_SPE_MASK; + } +} + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the status flag. + * + * @param base SPI base pointer + * @return SPI Status, use status flag to AND #_spi_flags could get the related status. + */ +uint32_t SPI_GetStatusFlags(SPI_Type *base); + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO +/*! + * @brief Clear the interrupt if enable INCTLR. + * + * @param base SPI base pointer + * @param interrupt Interrupt need to be cleared + * The parameter could be any combination of the following values: + * @arg kSPIRxFifoFullClearInt + * @arg kSPITxFifoEmptyClearInt + * @arg kSPIRxNearFullClearInt + * @arg kSPITxNearEmptyClearInt + */ +static inline void SPI_ClearInterrupt(SPI_Type *base, uint32_t mask) +{ + base->CI |= mask; +} +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + +/*! @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the interrupt for the SPI. + * + * @param base SPI base pointer + * @param mask SPI interrupt source. The parameter can be any combination of the following values: + * @arg kSPI_RxFullAndModfInterruptEnable + * @arg kSPI_TxEmptyInterruptEnable + * @arg kSPI_MatchInterruptEnable + * @arg kSPI_RxFifoNearFullInterruptEnable + * @arg kSPI_TxFifoNearEmptyInterruptEnable + */ +void SPI_EnableInterrupts(SPI_Type *base, uint32_t mask); + +/*! + * @brief Disables the interrupt for the SPI. + * + * @param base SPI base pointer + * @param mask SPI interrupt source. The parameter can be any combination of the following values: + * @arg kSPI_RxFullAndModfInterruptEnable + * @arg kSPI_TxEmptyInterruptEnable + * @arg kSPI_MatchInterruptEnable + * @arg kSPI_RxFifoNearFullInterruptEnable + * @arg kSPI_TxFifoNearEmptyInterruptEnable + */ +void SPI_DisableInterrupts(SPI_Type *base, uint32_t mask); + +/*! @} */ + +/*! + * @name DMA Control + * @{ + */ + +#if defined(FSL_FEATURE_SPI_HAS_DMA_SUPPORT) && FSL_FEATURE_SPI_HAS_DMA_SUPPORT +/*! + * @brief Enables the DMA source for SPI. + * + * @param base SPI base pointer + * @param source SPI DMA source. + * @param enable True means enable DMA, false means disable DMA + */ +static inline void SPI_EnableDMA(SPI_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->C2 |= mask; + } + else + { + base->C2 &= ~mask; + } +} +#endif /* FSL_FEATURE_SPI_HAS_DMA_SUPPORT */ + +/*! + * @brief Gets the SPI tx/rx data register address. + * + * This API is used to provide a transfer address for the SPI DMA transfer configuration. + * + * @param base SPI base pointer + * @return data register address + */ +static inline uint32_t SPI_GetDataRegisterAddress(SPI_Type *base) +{ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + return (uint32_t)(&(base->DL)); +#else + return (uint32_t)(&(base->D)); +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ +} + +/*! @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Sets the baud rate for SPI transfer. This is only used in master. + * + * @param base SPI base pointer + * @param baudRate_Bps baud rate needed in Hz. + * @param srcClock_Hz SPI source clock frequency in Hz. + */ +void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Sets the match data for SPI. + * + * The match data is a hardware comparison value. When the value received in the SPI receive data + * buffer equals the hardware comparison value, the SPI Match Flag in the S register (S[SPMF]) sets. + * This can also generate an interrupt if the enable bit sets. + * + * @param base SPI base pointer + * @param matchData Match data. + */ +static inline void SPI_SetMatchData(SPI_Type *base, uint32_t matchData) +{ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS + base->ML = matchData & 0xFFU; + base->MH = (matchData >> 8U) & 0xFFU; +#else + base->M = matchData; +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ +} + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO +/*! + * @brief Enables or disables the FIFO if there is a FIFO. + * + * @param base SPI base pointer + * @param enable True means enable FIFO, false means disable FIFO. + */ +void SPI_EnableFIFO(SPI_Type *base, bool enable); +#endif + +/*! + * @brief Sends a buffer of data bytes using a blocking method. + * + * @note This function blocks via polling until all bytes have been sent. + * + * @param base SPI base pointer + * @param buffer The data bytes to send + * @param size The number of data bytes to send + */ +void SPI_WriteBlocking(SPI_Type *base, uint8_t *buffer, size_t size); + +/*! + * @brief Writes a data into the SPI data register. + * + * @param base SPI base pointer + * @param data needs to be write. + */ +void SPI_WriteData(SPI_Type *base, uint16_t data); + +/*! + * @brief Gets a data from the SPI data register. + * + * @param base SPI base pointer + * @return Data in the register. + */ +uint16_t SPI_ReadData(SPI_Type *base); + +/*! @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the SPI master handle. + * + * This function initializes the SPI master handle which can be used for other SPI master transactional APIs. Usually, + * for a specified SPI instance, call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +void SPI_MasterTransferCreateHandle(SPI_Type *base, + spi_master_handle_t *handle, + spi_master_callback_t callback, + void *userData); + +/*! + * @brief Transfers a block of data using a polling method. + * + * @param base SPI base pointer + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + */ +status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking SPI interrupt transfer. + * + * @note The API immediately returns after transfer initialization is finished. + * Call SPI_GetStatusIRQ() to get the transfer status. + * @note If using the SPI with FIFO for the interrupt transfer, the transfer size is the integer times of the watermark. + * Otherwise, + * the last data may be lost because it cannot generate an interrupt request. Users can also call the functional API to + * get the last + * received data. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer); + +/*! + * @brief Gets the bytes of the SPI interrupt transferred. + * + * @param base SPI peripheral base address. + * @param handle Pointer to SPI transfer handle, this should be a static variable. + * @param count Transferred bytes of SPI master. + * @retval kStatus_SPI_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count); + +/*! + * @brief Aborts an SPI transfer using interrupt. + * + * @param base SPI peripheral base address. + * @param handle Pointer to SPI transfer handle, this should be a static variable. + */ +void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle); + +/*! + * @brief Interrupts the handler for the SPI. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state. + */ +void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle); + +/*! + * @brief Initializes the SPI slave handle. + * + * This function initializes the SPI slave handle which can be used for other SPI slave transactional APIs. Usually, + * for a specified SPI instance, call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +void SPI_SlaveTransferCreateHandle(SPI_Type *base, + spi_slave_handle_t *handle, + spi_slave_callback_t callback, + void *userData); + +/*! + * @brief Performs a non-blocking SPI slave interrupt transfer. + * + * @note The API returns immediately after the transfer initialization is finished. + * Call SPI_GetStatusIRQ() to get the transfer status. + * @note If using the SPI with FIFO for the interrupt transfer, the transfer size is the integer times the watermark. + * Otherwise, + * the last data may be lost because it cannot generate an interrupt request. Call the functional API to get the last + * several + * receive data. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +static inline status_t SPI_SlaveTransferNonBlocking(SPI_Type *base, spi_slave_handle_t *handle, spi_transfer_t *xfer) +{ + return SPI_MasterTransferNonBlocking(base, handle, xfer); +} + +/*! + * @brief Gets the bytes of the SPI interrupt transferred. + * + * @param base SPI peripheral base address. + * @param handle Pointer to SPI transfer handle, this should be a static variable. + * @param count Transferred bytes of SPI slave. + * @retval kStatus_SPI_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +static inline status_t SPI_SlaveTransferGetCount(SPI_Type *base, spi_slave_handle_t *handle, size_t *count) +{ + return SPI_MasterTransferGetCount(base, handle, count); +} + +/*! + * @brief Aborts an SPI slave transfer using interrupt. + * + * @param base SPI peripheral base address. + * @param handle Pointer to SPI transfer handle, this should be a static variable. + */ +static inline void SPI_SlaveTransferAbort(SPI_Type *base, spi_slave_handle_t *handle) +{ + SPI_MasterTransferAbort(base, handle); +} + +/*! + * @brief Interrupts a handler for the SPI slave. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_slave_handle_t structure which stores the transfer state + */ +void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_SPI_H_*/ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi_dma.c new file mode 100644 index 0000000000..cdaddcc799 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi_dma.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_spi_dma.h" + +/******************************************************************************* + * Definitons + ******************************************************************************/ +/*handle; + SPI_Type *base = privHandle->base; + + /* Disable Tx dma */ + SPI_EnableDMA(base, kSPI_TxDmaEnable, false); + + /* Stop DMA tranfer */ + DMA_StopTransfer(spiHandle->txHandle); + + /* change the state */ + spiHandle->txInProgress = false; + + /* All finished, call the callback */ + if ((spiHandle->txInProgress == false) && (spiHandle->rxInProgress == false)) + { + spiHandle->state = kSPI_Idle; + if (spiHandle->callback) + { + (spiHandle->callback)(base, spiHandle, kStatus_Success, spiHandle->userData); + } + } +} + +static void SPI_RxDMACallback(dma_handle_t *handle, void *userData) +{ + spi_dma_private_handle_t *privHandle = (spi_dma_private_handle_t *)userData; + spi_dma_handle_t *spiHandle = privHandle->handle; + SPI_Type *base = privHandle->base; + + /* Disable Tx dma */ + SPI_EnableDMA(base, kSPI_RxDmaEnable, false); + + /* Stop DMA tranfer */ + DMA_StopTransfer(spiHandle->rxHandle); + + /* change the state */ + spiHandle->rxInProgress = false; + + /* All finished, call the callback */ + if ((spiHandle->txInProgress == false) && (spiHandle->rxInProgress == false)) + { + spiHandle->state = kSPI_Idle; + if (spiHandle->callback) + { + (spiHandle->callback)(base, spiHandle, kStatus_Success, spiHandle->userData); + } + } +} + +void SPI_MasterTransferCreateHandleDMA(SPI_Type *base, + spi_dma_handle_t *handle, + spi_dma_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle) +{ + assert(handle); + dma_transfer_config_t config = {0}; + uint32_t instance = SPI_GetInstance(base); + + /* Set spi base to handle */ + handle->txHandle = txHandle; + handle->rxHandle = rxHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set SPI state to idle */ + handle->state = kSPI_Idle; + + /* Set handle to global state */ + s_dmaPrivateHandle[instance].base = base; + s_dmaPrivateHandle[instance].handle = handle; + +/* Compute internal state */ +#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS) + handle->bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; +#else + handle->bytesPerFrame = 1U; +#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ + +#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO) + /* If using DMA, disable FIFO, as the FIFO may cause data loss if the data size is not integer + times of 2bytes. As SPI cannot set watermark to 0, only can set to 1/2 FIFO size or 3/4 FIFO + size. */ + if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0) + { + base->C3 &= ~SPI_C3_FIFOMODE_MASK; + } + +#endif /* FSL_FEATURE_SPI_HAS_FIFO */ + + /* Set the non-change attribute for Tx DMA transfer, to improve efficiency */ + config.destAddr = SPI_GetDataRegisterAddress(base); + config.enableDestIncrement = false; + config.enableSrcIncrement = true; + if (handle->bytesPerFrame == 1U) + { + config.srcSize = kDMA_Transfersize8bits; + config.destSize = kDMA_Transfersize8bits; + } + else + { + config.srcSize = kDMA_Transfersize16bits; + config.destSize = kDMA_Transfersize16bits; + } + + DMA_SubmitTransfer(handle->txHandle, &config, true); + + /* Set non-change attribute for Rx DMA */ + config.srcAddr = SPI_GetDataRegisterAddress(base); + config.destAddr = 0U; + config.enableDestIncrement = true; + config.enableSrcIncrement = false; + DMA_SubmitTransfer(handle->rxHandle, &config, true); + + /* Install callback for Tx dma channel */ + DMA_SetCallback(handle->txHandle, SPI_TxDMACallback, &s_dmaPrivateHandle[instance]); + DMA_SetCallback(handle->rxHandle, SPI_RxDMACallback, &s_dmaPrivateHandle[instance]); +} + +status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer) +{ + assert(handle && xfer); + + dma_transfer_config_t config = {0}; + + /* Check if the device is busy */ + if (handle->state == kSPI_Busy) + { + return kStatus_SPI_Busy; + } + + /* Check if input parameter invalid */ + if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) + { + return kStatus_InvalidArgument; + } + + /* Disable SPI and then enable it, this is used to clear S register*/ + SPI_Enable(base, false); + SPI_Enable(base, true); + + /* Configure tx transfer DMA */ + config.destAddr = SPI_GetDataRegisterAddress(base); + config.enableDestIncrement = false; + if (handle->bytesPerFrame == 1U) + { + config.srcSize = kDMA_Transfersize8bits; + config.destSize = kDMA_Transfersize8bits; + } + else + { + config.srcSize = kDMA_Transfersize16bits; + config.destSize = kDMA_Transfersize16bits; + } + config.transferSize = xfer->dataSize; + /* Configure DMA channel */ + if (xfer->txData) + { + config.enableSrcIncrement = true; + config.srcAddr = (uint32_t)(xfer->txData); + } + else + { + /* Disable the source increasement and source set to dummyData */ + config.enableSrcIncrement = false; + config.srcAddr = (uint32_t)(&s_dummyData); + } + DMA_SubmitTransfer(handle->txHandle, &config, true); + + /* Handle rx transfer */ + if (xfer->rxData) + { + /* Set the source address */ + DMA_SetDestinationAddress(handle->rxHandle->base, handle->rxHandle->channel, (uint32_t)(xfer->rxData)); + + /* Set the transfer size */ + DMA_SetTransferSize(handle->rxHandle->base, handle->rxHandle->channel, xfer->dataSize); + } + + /* Change the state of handle */ + handle->transferSize = xfer->dataSize; + handle->state = kSPI_Busy; + + /* Start Rx transfer if needed */ + if (xfer->rxData) + { + handle->rxInProgress = true; + SPI_EnableDMA(base, kSPI_RxDmaEnable, true); + DMA_StartTransfer(handle->rxHandle); + } + + /* Always start Tx transfer */ + handle->txInProgress = true; + SPI_EnableDMA(base, kSPI_TxDmaEnable, true); + DMA_StartTransfer(handle->txHandle); + + return kStatus_Success; +} + +status_t SPI_MasterTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count) +{ + assert(handle); + + status_t status = kStatus_Success; + + if (handle->state != kSPI_Busy) + { + status = kStatus_NoTransferInProgress; + } + else + { + if (handle->rxInProgress) + { + *count = handle->transferSize - DMA_GetRemainingBytes(handle->rxHandle->base, handle->rxHandle->channel); + } + else + { + *count = handle->transferSize - DMA_GetRemainingBytes(handle->txHandle->base, handle->txHandle->channel); + } + } + + return status; +} + +void SPI_MasterTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle) +{ + assert(handle); + + /* Disable dma */ + DMA_StopTransfer(handle->txHandle); + DMA_StopTransfer(handle->rxHandle); + + /* Disable DMA enable bit */ + SPI_EnableDMA(base, kSPI_DmaAllEnable, false); + + /* Set the handle state */ + handle->txInProgress = false; + handle->rxInProgress = false; + handle->state = kSPI_Idle; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi_dma.h new file mode 100644 index 0000000000..90c7c93fb6 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_spi_dma.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SPI_DMA_H_ +#define _FSL_SPI_DMA_H_ + +#include "fsl_spi.h" +#include "fsl_dma.h" + +/*! + * @addtogroup spi_dma_driver + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +typedef struct _spi_dma_handle spi_dma_handle_t; + +/*! @brief SPI DMA callback called at the end of transfer. */ +typedef void (*spi_dma_callback_t)(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData); + +/*! @brief SPI DMA transfer handle, users should not touch the content of the handle.*/ +struct _spi_dma_handle +{ + bool txInProgress; /*!< Send transfer finished */ + bool rxInProgress; /*!< Receive transfer finished */ + dma_handle_t *txHandle; /*!< DMA handler for SPI send */ + dma_handle_t *rxHandle; /*!< DMA handler for SPI receive */ + uint8_t bytesPerFrame; /*!< Bytes in a frame for SPI tranfer */ + spi_dma_callback_t callback; /*!< Callback for SPI DMA transfer */ + void *userData; /*!< User Data for SPI DMA callback */ + uint32_t state; /*!< Internal state of SPI DMA transfer */ + size_t transferSize; /*!< Bytes need to be transfer */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name DMA Transactional + * @{ + */ + +/*! + * @brief Initialize the SPI master DMA handle. + * + * This function initializes the SPI master DMA handle which can be used for other SPI master transactional APIs. + * Usually, for a specified SPI instance, user need only call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback User callback function called at the end of a transfer. + * @param userData User data for callback. + * @param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users. + * @param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users. + */ +void SPI_MasterTransferCreateHandleDMA(SPI_Type *base, + spi_dma_handle_t *handle, + spi_dma_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle); + +/*! + * @brief Perform a non-blocking SPI transfer using DMA. + * + * @note This interface returned immediately after transfer initiates, users should call + * SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + * @param xfer Pointer to dma transfer structure. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer); + +/*! + * @brief Abort a SPI transfer using DMA. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + */ +void SPI_MasterTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle); + +/*! + * @brief Get the transferred bytes for SPI slave DMA. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + * @param count Transferred bytes. + * @retval kStatus_SPI_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t SPI_MasterTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count); + +/*! + * @brief Initialize the SPI slave DMA handle. + * + * This function initializes the SPI slave DMA handle which can be used for other SPI master transactional APIs. + * Usually, for a specified SPI instance, user need only call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback User callback function called at the end of a transfer. + * @param userData User data for callback. + * @param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users. + * @param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users. + */ +static inline void SPI_SlaveTransferCreateHandleDMA(SPI_Type *base, + spi_dma_handle_t *handle, + spi_dma_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle) +{ + SPI_MasterTransferCreateHandleDMA(base, handle, callback, userData, txHandle, rxHandle); +} + +/*! + * @brief Perform a non-blocking SPI transfer using DMA. + * + * @note This interface returned immediately after transfer initiates, users should call + * SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + * @param xfer Pointer to dma transfer structure. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +static inline status_t SPI_SlaveTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer) +{ + return SPI_MasterTransferDMA(base, handle, xfer); +} + +/*! + * @brief Abort a SPI transfer using DMA. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + */ +static inline void SPI_SlaveTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle) +{ + SPI_MasterTransferAbortDMA(base, handle); +} + +/*! + * @brief Get the transferred bytes for SPI slave DMA. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + * @param count Transferred bytes. + * @retval kStatus_SPI_Success Succeed get the transfer count. + * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +static inline status_t SPI_SlaveTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count) +{ + return SPI_MasterTransferGetCountDMA(base, handle, count); +} + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_tpm.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_tpm.c new file mode 100644 index 0000000000..e3134a9755 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_tpm.c @@ -0,0 +1,725 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_tpm.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define TPM_COMBINE_SHIFT (8U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base TPM peripheral base address + * + * @return The TPM instance + */ +static uint32_t TPM_GetInstance(TPM_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to TPM bases for each instance. */ +static TPM_Type *const s_tpmBases[] = TPM_BASE_PTRS; + +/*! @brief Pointers to TPM clocks for each instance. */ +static const clock_ip_name_t s_tpmClocks[] = TPM_CLOCKS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t TPM_GetInstance(TPM_Type *base) +{ + uint32_t instance; + uint32_t tpmArrayCount = (sizeof(s_tpmBases) / sizeof(s_tpmBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < tpmArrayCount; instance++) + { + if (s_tpmBases[instance] == base) + { + break; + } + } + + assert(instance < tpmArrayCount); + + return instance; +} + +void TPM_Init(TPM_Type *base, const tpm_config_t *config) +{ + assert(config); + + /* Enable the module clock */ + CLOCK_EnableClock(s_tpmClocks[TPM_GetInstance(base)]); + +#if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL + /* TPM reset is available on certain SoC's */ + TPM_Reset(base); +#endif + + /* Set the clock prescale factor */ + base->SC = TPM_SC_PS(config->prescale); + + /* Setup the counter operation */ + base->CONF = TPM_CONF_DOZEEN(config->enableDoze) | TPM_CONF_GTBEEN(config->useGlobalTimeBase) | + TPM_CONF_CROT(config->enableReloadOnTrigger) | TPM_CONF_CSOT(config->enableStartOnTrigger) | + TPM_CONF_CSOO(config->enableStopOnOverflow) | +#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER + TPM_CONF_CPOT(config->enablePauseOnTrigger) | +#endif +#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION + TPM_CONF_TRGSRC(config->triggerSource) | +#endif + TPM_CONF_TRGSEL(config->triggerSelect); + if (config->enableDebugMode) + { + base->CONF |= TPM_CONF_DBGMODE_MASK; + } + else + { + base->CONF &= ~TPM_CONF_DBGMODE_MASK; + } +} + +void TPM_Deinit(TPM_Type *base) +{ + /* Stop the counter */ + base->SC &= ~TPM_SC_CMOD_MASK; + /* Gate the TPM clock */ + CLOCK_DisableClock(s_tpmClocks[TPM_GetInstance(base)]); +} + +void TPM_GetDefaultConfig(tpm_config_t *config) +{ + assert(config); + + /* TPM clock divide by 1 */ + config->prescale = kTPM_Prescale_Divide_1; + /* Use internal TPM counter as timebase */ + config->useGlobalTimeBase = false; + /* TPM counter continues in doze mode */ + config->enableDoze = false; + /* TPM counter pauses when in debug mode */ + config->enableDebugMode = false; + /* TPM counter will not be reloaded on input trigger */ + config->enableReloadOnTrigger = false; + /* TPM counter continues running after overflow */ + config->enableStopOnOverflow = false; + /* TPM counter starts immediately once it is enabled */ + config->enableStartOnTrigger = false; +#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER + config->enablePauseOnTrigger = false; +#endif + /* Choose trigger select 0 as input trigger for controlling counter operation */ + config->triggerSelect = kTPM_Trigger_Select_0; +#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION + /* Choose external trigger source to control counter operation */ + config->triggerSource = kTPM_TriggerSource_External; +#endif +} + +status_t TPM_SetupPwm(TPM_Type *base, + const tpm_chnl_pwm_signal_param_t *chnlParams, + uint8_t numOfChnls, + tpm_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz) +{ + assert(chnlParams); + assert(pwmFreq_Hz); + assert(numOfChnls); + assert(srcClock_Hz); + + uint32_t mod; + uint32_t tpmClock = (srcClock_Hz / (1U << (base->SC & TPM_SC_PS_MASK))); + uint16_t cnv; + uint8_t i; + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL + /* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/ + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; +#endif + + switch (mode) + { + case kTPM_EdgeAlignedPwm: +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + case kTPM_CombinedPwm: +#endif + base->SC &= ~TPM_SC_CPWMS_MASK; + mod = (tpmClock / pwmFreq_Hz) - 1; + break; + case kTPM_CenterAlignedPwm: + base->SC |= TPM_SC_CPWMS_MASK; + mod = tpmClock / (pwmFreq_Hz * 2); + break; + default: + return kStatus_Fail; + } + + /* Return an error in case we overflow the registers, probably would require changing + * clock source to get the desired frequency */ + if (mod > 65535U) + { + return kStatus_Fail; + } + /* Set the PWM period */ + base->MOD = mod; + + /* Setup each TPM channel */ + for (i = 0; i < numOfChnls; i++) + { + /* Return error if requested dutycycle is greater than the max allowed */ + if (chnlParams->dutyCyclePercent > 100) + { + return kStatus_Fail; + } +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + if (mode == kTPM_CombinedPwm) + { + uint16_t cnvFirstEdge; + + /* This check is added for combined mode as the channel number should be the pair number */ + if (chnlParams->chnlNumber >= (FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2)) + { + return kStatus_Fail; + } + + /* Return error if requested value is greater than the max allowed */ + if (chnlParams->firstEdgeDelayPercent > 100) + { + return kStatus_Fail; + } + /* Configure delay of the first edge */ + if (chnlParams->firstEdgeDelayPercent == 0) + { + /* No delay for the first edge */ + cnvFirstEdge = 0; + } + else + { + cnvFirstEdge = (mod * chnlParams->firstEdgeDelayPercent) / 100; + } + /* Configure dutycycle */ + if (chnlParams->dutyCyclePercent == 0) + { + /* Signal stays low */ + cnv = 0; + cnvFirstEdge = 0; + } + else + { + cnv = (mod * chnlParams->dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + } + + /* Set the combine bit for the channel pair */ + base->COMBINE |= (1U << (TPM_COMBINE_COMBINE0_SHIFT + (TPM_COMBINE_SHIFT * chnlParams->chnlNumber))); + + /* When switching mode, disable channel n first */ + base->CONTROLS[chnlParams->chnlNumber * 2].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlParams->chnlNumber * 2].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Set the requested PWM mode for channel n, PWM output requires mode select to be set to 2 */ + base->CONTROLS[chnlParams->chnlNumber * 2].CnSC |= + ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT)); + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlParams->chnlNumber * 2].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + /* Set the channel pair values */ + base->CONTROLS[chnlParams->chnlNumber * 2].CnV = cnvFirstEdge; + + /* When switching mode, disable channel n + 1 first */ + base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Set the requested PWM mode for channel n + 1, PWM output requires mode select to be set to 2 */ + base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC |= + ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT)); + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + /* Set the channel pair values */ + base->CONTROLS[(chnlParams->chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv; + } + else + { +#endif + if (chnlParams->dutyCyclePercent == 0) + { + /* Signal stays low */ + cnv = 0; + } + else + { + cnv = (mod * chnlParams->dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + } + + /* When switching mode, disable channel first */ + base->CONTROLS[chnlParams->chnlNumber].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlParams->chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Set the requested PWM mode, PWM output requires mode select to be set to 2 */ + base->CONTROLS[chnlParams->chnlNumber].CnSC |= + ((chnlParams->level << TPM_CnSC_ELSA_SHIFT) | (2U << TPM_CnSC_MSA_SHIFT)); + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlParams->chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + base->CONTROLS[chnlParams->chnlNumber].CnV = cnv; +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + } +#endif + + chnlParams++; + } + + return kStatus_Success; +} + +void TPM_UpdatePwmDutycycle(TPM_Type *base, + tpm_chnl_t chnlNumber, + tpm_pwm_mode_t currentPwmMode, + uint8_t dutyCyclePercent) +{ + assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); + + uint16_t cnv, mod; + + mod = base->MOD; +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + if (currentPwmMode == kTPM_CombinedPwm) + { + uint16_t cnvFirstEdge; + + /* This check is added for combined mode as the channel number should be the pair number */ + if (chnlNumber >= (FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2)) + { + return; + } + cnv = (mod * dutyCyclePercent) / 100; + cnvFirstEdge = base->CONTROLS[chnlNumber * 2].CnV; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + base->CONTROLS[(chnlNumber * 2) + 1].CnV = cnvFirstEdge + cnv; + } + else + { +#endif + cnv = (mod * dutyCyclePercent) / 100; + /* For 100% duty cycle */ + if (cnv >= mod) + { + cnv = mod + 1; + } + base->CONTROLS[chnlNumber].CnV = cnv; +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + } +#endif +} + +void TPM_UpdateChnlEdgeLevelSelect(TPM_Type *base, tpm_chnl_t chnlNumber, uint8_t level) +{ + assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); + + uint32_t reg = base->CONTROLS[chnlNumber].CnSC & ~(TPM_CnSC_CHF_MASK); + + /* When switching mode, disable channel first */ + base->CONTROLS[chnlNumber].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Clear the field and write the new level value */ + reg &= ~(TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + reg |= ((uint32_t)level << TPM_CnSC_ELSA_SHIFT) & (TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + base->CONTROLS[chnlNumber].CnSC = reg; + + /* Wait till mode change is acknowledged */ + reg &= (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + while (reg != (base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } +} + +void TPM_SetupInputCapture(TPM_Type *base, tpm_chnl_t chnlNumber, tpm_input_capture_edge_t captureMode) +{ + assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL + /* Clear quadrature Decoder mode for channel 0 or 1*/ + if ((chnlNumber == 0) || (chnlNumber == 1)) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } +#endif + +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + /* Clear the combine bit for chnlNumber */ + base->COMBINE &= ~(1U << TPM_COMBINE_SHIFT * (chnlNumber / 2)); +#endif + + /* When switching mode, disable channel first */ + base->CONTROLS[chnlNumber].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Set the requested input capture mode */ + base->CONTROLS[chnlNumber].CnSC |= captureMode; + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } +} + +void TPM_SetupOutputCompare(TPM_Type *base, + tpm_chnl_t chnlNumber, + tpm_output_compare_mode_t compareMode, + uint32_t compareValue) +{ + assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL + /* Clear quadrature Decoder mode for channel 0 or 1 */ + if ((chnlNumber == 0) || (chnlNumber == 1)) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } +#endif + + /* When switching mode, disable channel first */ + base->CONTROLS[chnlNumber].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Setup the channel output behaviour when a match occurs with the compare value */ + base->CONTROLS[chnlNumber].CnSC |= compareMode; + + /* Setup the compare value */ + base->CONTROLS[chnlNumber].CnV = compareValue; + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlNumber].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } +} + +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE +void TPM_SetupDualEdgeCapture(TPM_Type *base, + tpm_chnl_t chnlPairNumber, + const tpm_dual_edge_capture_param_t *edgeParam, + uint32_t filterValue) +{ + assert(edgeParam); + assert(chnlPairNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2); + + uint32_t reg; +/* Clear quadrature Decoder mode for channel 0 or 1*/ +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL + if (chnlPairNumber == 0) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } +#endif + + /* Unlock: When switching mode, disable channel first */ + base->CONTROLS[chnlPairNumber * 2].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlPairNumber * 2].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + base->CONTROLS[chnlPairNumber * 2 + 1].CnSC &= + ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[chnlPairNumber * 2 + 1].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Now, the registers for input mode can be operated. */ + if (edgeParam->enableSwap) + { + /* Set the combine and swap bits for the channel pair */ + base->COMBINE |= (TPM_COMBINE_COMBINE0_MASK | TPM_COMBINE_COMSWAP0_MASK) + << (TPM_COMBINE_SHIFT * chnlPairNumber); + + /* Input filter setup for channel n+1 input */ + reg = base->FILTER; + reg &= ~(TPM_FILTER_CH0FVAL_MASK << (TPM_FILTER_CH1FVAL_SHIFT * (chnlPairNumber + 1))); + reg |= (filterValue << (TPM_FILTER_CH1FVAL_SHIFT * (chnlPairNumber + 1))); + base->FILTER = reg; + } + else + { + reg = base->COMBINE; + /* Clear the swap bit for the channel pair */ + reg &= ~(TPM_COMBINE_COMSWAP0_MASK << (TPM_COMBINE_COMSWAP0_SHIFT * chnlPairNumber)); + + /* Set the combine bit for the channel pair */ + reg |= TPM_COMBINE_COMBINE0_MASK << (TPM_COMBINE_SHIFT * chnlPairNumber); + base->COMBINE = reg; + + /* Input filter setup for channel n input */ + reg = base->FILTER; + reg &= ~(TPM_FILTER_CH0FVAL_MASK << (TPM_FILTER_CH1FVAL_SHIFT * chnlPairNumber)); + reg |= (filterValue << (TPM_FILTER_CH1FVAL_SHIFT * chnlPairNumber)); + base->FILTER = reg; + } + + /* Setup the edge detection from channel n */ + base->CONTROLS[chnlPairNumber * 2].CnSC |= edgeParam->currChanEdgeMode; + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[chnlPairNumber * 2].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + + /* Setup the edge detection from channel n+1 */ + base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC |= edgeParam->nextChanEdgeMode; + + /* Wait till mode change is acknowledged */ + while (!(base->CONTROLS[(chnlPairNumber * 2) + 1].CnSC & + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } +} +#endif + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL +void TPM_SetupQuadDecode(TPM_Type *base, + const tpm_phase_params_t *phaseAParams, + const tpm_phase_params_t *phaseBParams, + tpm_quad_decode_mode_t quadMode) +{ + assert(phaseAParams); + assert(phaseBParams); + + base->CONTROLS[0].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[0].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + uint32_t reg; + + /* Set Phase A filter value */ + reg = base->FILTER; + reg &= ~(TPM_FILTER_CH0FVAL_MASK); + reg |= TPM_FILTER_CH0FVAL(phaseAParams->phaseFilterVal); + base->FILTER = reg; + +#if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL + /* Set Phase A polarity */ + if (phaseAParams->phasePolarity) + { + base->POL |= TPM_POL_POL0_MASK; + } + else + { + base->POL &= ~TPM_POL_POL0_MASK; + } +#endif + + base->CONTROLS[1].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); + + /* Wait till mode change to disable channel is acknowledged */ + while ((base->CONTROLS[1].CnSC & (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + { + } + /* Set Phase B filter value */ + reg = base->FILTER; + reg &= ~(TPM_FILTER_CH1FVAL_MASK); + reg |= TPM_FILTER_CH1FVAL(phaseBParams->phaseFilterVal); + base->FILTER = reg; +#if defined(FSL_FEATURE_TPM_HAS_POL) && FSL_FEATURE_TPM_HAS_POL + /* Set Phase B polarity */ + if (phaseBParams->phasePolarity) + { + base->POL |= TPM_POL_POL1_MASK; + } + else + { + base->POL &= ~TPM_POL_POL1_MASK; + } +#endif + + /* Set Quadrature mode */ + reg = base->QDCTRL; + reg &= ~(TPM_QDCTRL_QUADMODE_MASK); + reg |= TPM_QDCTRL_QUADMODE(quadMode); + base->QDCTRL = reg; + + /* Enable Quad decode */ + base->QDCTRL |= TPM_QDCTRL_QUADEN_MASK; +} + +#endif + +void TPM_EnableInterrupts(TPM_Type *base, uint32_t mask) +{ + uint32_t chnlInterrupts = (mask & 0xFF); + uint8_t chnlNumber = 0; + + /* Enable the timer overflow interrupt */ + if (mask & kTPM_TimeOverflowInterruptEnable) + { + base->SC |= TPM_SC_TOIE_MASK; + } + + /* Enable the channel interrupts */ + while (chnlInterrupts) + { + if (chnlInterrupts & 0x1) + { + base->CONTROLS[chnlNumber].CnSC |= TPM_CnSC_CHIE_MASK; + } + chnlNumber++; + chnlInterrupts = chnlInterrupts >> 1U; + } +} + +void TPM_DisableInterrupts(TPM_Type *base, uint32_t mask) +{ + uint32_t chnlInterrupts = (mask & 0xFF); + uint8_t chnlNumber = 0; + + /* Disable the timer overflow interrupt */ + if (mask & kTPM_TimeOverflowInterruptEnable) + { + base->SC &= ~TPM_SC_TOIE_MASK; + } + + /* Disable the channel interrupts */ + while (chnlInterrupts) + { + if (chnlInterrupts & 0x1) + { + base->CONTROLS[chnlNumber].CnSC &= ~TPM_CnSC_CHIE_MASK; + } + chnlNumber++; + chnlInterrupts = chnlInterrupts >> 1U; + } +} + +uint32_t TPM_GetEnabledInterrupts(TPM_Type *base) +{ + uint32_t enabledInterrupts = 0; + int8_t chnlCount = FSL_FEATURE_TPM_CHANNEL_COUNTn(base); + + /* The CHANNEL_COUNT macro returns -1 if it cannot match the TPM instance */ + assert(chnlCount != -1); + + /* Check if timer overflow interrupt is enabled */ + if (base->SC & TPM_SC_TOIE_MASK) + { + enabledInterrupts |= kTPM_TimeOverflowInterruptEnable; + } + + /* Check if the channel interrupts are enabled */ + while (chnlCount > 0) + { + chnlCount--; + if (base->CONTROLS[chnlCount].CnSC & TPM_CnSC_CHIE_MASK) + { + enabledInterrupts |= (1U << chnlCount); + } + } + + return enabledInterrupts; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_tpm.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_tpm.h new file mode 100644 index 0000000000..a15e44c1fb --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_tpm.h @@ -0,0 +1,590 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_TPM_H_ +#define _FSL_TPM_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup tpm + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_TPM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */ +/*@}*/ + +/*! + * @brief List of TPM channels. + * @note Actual number of available channels is SoC dependent + */ +typedef enum _tpm_chnl +{ + kTPM_Chnl_0 = 0U, /*!< TPM channel number 0*/ + kTPM_Chnl_1, /*!< TPM channel number 1 */ + kTPM_Chnl_2, /*!< TPM channel number 2 */ + kTPM_Chnl_3, /*!< TPM channel number 3 */ + kTPM_Chnl_4, /*!< TPM channel number 4 */ + kTPM_Chnl_5, /*!< TPM channel number 5 */ + kTPM_Chnl_6, /*!< TPM channel number 6 */ + kTPM_Chnl_7 /*!< TPM channel number 7 */ +} tpm_chnl_t; + +/*! @brief TPM PWM operation modes */ +typedef enum _tpm_pwm_mode +{ + kTPM_EdgeAlignedPwm = 0U, /*!< Edge aligned PWM */ + kTPM_CenterAlignedPwm, /*!< Center aligned PWM */ +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + kTPM_CombinedPwm /*!< Combined PWM */ +#endif +} tpm_pwm_mode_t; + +/*! @brief TPM PWM output pulse mode: high-true, low-true or no output */ +typedef enum _tpm_pwm_level_select +{ + kTPM_NoPwmSignal = 0U, /*!< No PWM output on pin */ + kTPM_LowTrue, /*!< Low true pulses */ + kTPM_HighTrue /*!< High true pulses */ +} tpm_pwm_level_select_t; + +/*! @brief Options to configure a TPM channel's PWM signal */ +typedef struct _tpm_chnl_pwm_signal_param +{ + tpm_chnl_t chnlNumber; /*!< TPM channel to configure. + In combined mode (available in some SoC's, this represents the + channel pair number */ + tpm_pwm_level_select_t level; /*!< PWM output active level select */ + uint8_t dutyCyclePercent; /*!< PWM pulse width, value should be between 0 to 100 + 0=inactive signal(0% duty cycle)... + 100=always active signal (100% duty cycle)*/ +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + uint8_t firstEdgeDelayPercent; /*!< Used only in combined PWM mode to generate asymmetrical PWM. + Specifies the delay to the first edge in a PWM period. + If unsure, leave as 0; Should be specified as + percentage of the PWM period */ +#endif +} tpm_chnl_pwm_signal_param_t; + +/*! + * @brief Trigger options available. + * + * This is used for both internal & external trigger sources (external option available in certain SoC's) + * + * @note The actual trigger options available is SoC-specific. + */ +typedef enum _tpm_trigger_select +{ + kTPM_Trigger_Select_0 = 0U, + kTPM_Trigger_Select_1, + kTPM_Trigger_Select_2, + kTPM_Trigger_Select_3, + kTPM_Trigger_Select_4, + kTPM_Trigger_Select_5, + kTPM_Trigger_Select_6, + kTPM_Trigger_Select_7, + kTPM_Trigger_Select_8, + kTPM_Trigger_Select_9, + kTPM_Trigger_Select_10, + kTPM_Trigger_Select_11, + kTPM_Trigger_Select_12, + kTPM_Trigger_Select_13, + kTPM_Trigger_Select_14, + kTPM_Trigger_Select_15 +} tpm_trigger_select_t; + +#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION +/*! + * @brief Trigger source options available + * + * @note This selection is available only on some SoC's. For SoC's without this selection, the only + * trigger source available is internal triger. + */ +typedef enum _tpm_trigger_source +{ + kTPM_TriggerSource_External = 0U, /*!< Use external trigger input */ + kTPM_TriggerSource_Internal /*!< Use internal trigger */ +} tpm_trigger_source_t; +#endif + +/*! @brief TPM output compare modes */ +typedef enum _tpm_output_compare_mode +{ + kTPM_NoOutputSignal = (1U << TPM_CnSC_MSA_SHIFT), /*!< No channel output when counter reaches CnV */ + kTPM_ToggleOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (1U << TPM_CnSC_ELSA_SHIFT)), /*!< Toggle output */ + kTPM_ClearOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (2U << TPM_CnSC_ELSA_SHIFT)), /*!< Clear output */ + kTPM_SetOnMatch = ((1U << TPM_CnSC_MSA_SHIFT) | (3U << TPM_CnSC_ELSA_SHIFT)), /*!< Set output */ + kTPM_HighPulseOutput = ((3U << TPM_CnSC_MSA_SHIFT) | (1U << TPM_CnSC_ELSA_SHIFT)), /*!< Pulse output high */ + kTPM_LowPulseOutput = ((3U << TPM_CnSC_MSA_SHIFT) | (2U << TPM_CnSC_ELSA_SHIFT)) /*!< Pulse output low */ +} tpm_output_compare_mode_t; + +/*! @brief TPM input capture edge */ +typedef enum _tpm_input_capture_edge +{ + kTPM_RisingEdge = (1U << TPM_CnSC_ELSA_SHIFT), /*!< Capture on rising edge only */ + kTPM_FallingEdge = (2U << TPM_CnSC_ELSA_SHIFT), /*!< Capture on falling edge only */ + kTPM_RiseAndFallEdge = (3U << TPM_CnSC_ELSA_SHIFT) /*!< Capture on rising or falling edge */ +} tpm_input_capture_edge_t; + +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE +/*! + * @brief TPM dual edge capture parameters + * + * @note This mode is available only on some SoC's. + */ +typedef struct _tpm_dual_edge_capture_param +{ + bool enableSwap; /*!< true: Use channel n+1 input, channel n input is ignored; + false: Use channel n input, channel n+1 input is ignored */ + tpm_input_capture_edge_t currChanEdgeMode; /*!< Input capture edge select for channel n */ + tpm_input_capture_edge_t nextChanEdgeMode; /*!< Input capture edge select for channel n+1 */ +} tpm_dual_edge_capture_param_t; +#endif + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL +/*! + * @brief TPM quadrature decode modes + * + * @note This mode is available only on some SoC's. + */ +typedef enum _tpm_quad_decode_mode +{ + kTPM_QuadPhaseEncode = 0U, /*!< Phase A and Phase B encoding mode */ + kTPM_QuadCountAndDir /*!< Count and direction encoding mode */ +} tpm_quad_decode_mode_t; + +/*! @brief TPM quadrature phase polarities */ +typedef enum _tpm_phase_polarity +{ + kTPM_QuadPhaseNormal = 0U, /*!< Phase input signal is not inverted */ + kTPM_QuadPhaseInvert /*!< Phase input signal is inverted */ +} tpm_phase_polarity_t; + +/*! @brief TPM quadrature decode phase parameters */ +typedef struct _tpm_phase_param +{ + uint32_t phaseFilterVal; /*!< Filter value, filter is disabled when the value is zero */ + tpm_phase_polarity_t phasePolarity; /*!< Phase polarity */ +} tpm_phase_params_t; +#endif + +/*! @brief TPM clock source selection*/ +typedef enum _tpm_clock_source +{ + kTPM_SystemClock = 1U, /*!< System clock */ + kTPM_ExternalClock /*!< External clock */ +} tpm_clock_source_t; + +/*! @brief TPM prescale value selection for the clock source*/ +typedef enum _tpm_clock_prescale +{ + kTPM_Prescale_Divide_1 = 0U, /*!< Divide by 1 */ + kTPM_Prescale_Divide_2, /*!< Divide by 2 */ + kTPM_Prescale_Divide_4, /*!< Divide by 4 */ + kTPM_Prescale_Divide_8, /*!< Divide by 8 */ + kTPM_Prescale_Divide_16, /*!< Divide by 16 */ + kTPM_Prescale_Divide_32, /*!< Divide by 32 */ + kTPM_Prescale_Divide_64, /*!< Divide by 64 */ + kTPM_Prescale_Divide_128 /*!< Divide by 128 */ +} tpm_clock_prescale_t; + +/*! + * @brief TPM config structure + * + * This structure holds the configuration settings for the TPM peripheral. To initialize this + * structure to reasonable defaults, call the TPM_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The config struct can be made const so it resides in flash + */ +typedef struct _tpm_config +{ + tpm_clock_prescale_t prescale; /*!< Select TPM clock prescale value */ + bool useGlobalTimeBase; /*!< true: Use of an external global time base is enabled; + false: disabled */ + tpm_trigger_select_t triggerSelect; /*!< Input trigger to use for controlling the counter operation */ +#if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION + tpm_trigger_source_t triggerSource; /*!< Decides if we use external or internal trigger. */ +#endif + bool enableDoze; /*!< true: TPM counter is paused in doze mode; + false: TPM counter continues in doze mode */ + bool enableDebugMode; /*!< true: TPM counter continues in debug mode; + false: TPM counter is paused in debug mode */ + bool enableReloadOnTrigger; /*!< true: TPM counter is reloaded on trigger; + false: TPM counter not reloaded */ + bool enableStopOnOverflow; /*!< true: TPM counter stops after overflow; + false: TPM counter continues running after overflow */ + bool enableStartOnTrigger; /*!< true: TPM counter only starts when a trigger is detected; + false: TPM counter starts immediately */ +#if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER + bool enablePauseOnTrigger; /*!< true: TPM counter will pause while trigger remains asserted; + false: TPM counter continues running */ +#endif +} tpm_config_t; + +/*! @brief List of TPM interrupts */ +typedef enum _tpm_interrupt_enable +{ + kTPM_Chnl0InterruptEnable = (1U << 0), /*!< Channel 0 interrupt.*/ + kTPM_Chnl1InterruptEnable = (1U << 1), /*!< Channel 1 interrupt.*/ + kTPM_Chnl2InterruptEnable = (1U << 2), /*!< Channel 2 interrupt.*/ + kTPM_Chnl3InterruptEnable = (1U << 3), /*!< Channel 3 interrupt.*/ + kTPM_Chnl4InterruptEnable = (1U << 4), /*!< Channel 4 interrupt.*/ + kTPM_Chnl5InterruptEnable = (1U << 5), /*!< Channel 5 interrupt.*/ + kTPM_Chnl6InterruptEnable = (1U << 6), /*!< Channel 6 interrupt.*/ + kTPM_Chnl7InterruptEnable = (1U << 7), /*!< Channel 7 interrupt.*/ + kTPM_TimeOverflowInterruptEnable = (1U << 8) /*!< Time overflow interrupt.*/ +} tpm_interrupt_enable_t; + +/*! @brief List of TPM flags */ +typedef enum _tpm_status_flags +{ + kTPM_Chnl0Flag = (1U << 0), /*!< Channel 0 flag */ + kTPM_Chnl1Flag = (1U << 1), /*!< Channel 1 flag */ + kTPM_Chnl2Flag = (1U << 2), /*!< Channel 2 flag */ + kTPM_Chnl3Flag = (1U << 3), /*!< Channel 3 flag */ + kTPM_Chnl4Flag = (1U << 4), /*!< Channel 4 flag */ + kTPM_Chnl5Flag = (1U << 5), /*!< Channel 5 flag */ + kTPM_Chnl6Flag = (1U << 6), /*!< Channel 6 flag */ + kTPM_Chnl7Flag = (1U << 7), /*!< Channel 7 flag */ + kTPM_TimeOverflowFlag = (1U << 8) /*!< Time overflow flag */ +} tpm_status_flags_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the TPM clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application using the TPM driver. + * + * @param base TPM peripheral base address + * @param config Pointer to user's TPM config structure. + */ +void TPM_Init(TPM_Type *base, const tpm_config_t *config); + +/*! + * @brief Stops the counter and gates the TPM clock + * + * @param base TPM peripheral base address + */ +void TPM_Deinit(TPM_Type *base); + +/*! + * @brief Fill in the TPM config struct with the default settings + * + * The default values are: + * @code + * config->prescale = kTPM_Prescale_Divide_1; + * config->useGlobalTimeBase = false; + * config->dozeEnable = false; + * config->dbgMode = false; + * config->enableReloadOnTrigger = false; + * config->enableStopOnOverflow = false; + * config->enableStartOnTrigger = false; + *#if FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER + * config->enablePauseOnTrigger = false; + *#endif + * config->triggerSelect = kTPM_Trigger_Select_0; + *#if FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION + * config->triggerSource = kTPM_TriggerSource_External; + *#endif + * @endcode + * @param config Pointer to user's TPM config structure. + */ +void TPM_GetDefaultConfig(tpm_config_t *config); + +/*! @}*/ + +/*! + * @name Channel mode operations + * @{ + */ + +/*! + * @brief Configures the PWM signal parameters + * + * User calls this function to configure the PWM signals period, mode, dutycycle and edge. Use this + * function to configure all the TPM channels that will be used to output a PWM signal + * + * @param base TPM peripheral base address + * @param chnlParams Array of PWM channel parameters to configure the channel(s) + * @param numOfChnls Number of channels to configure, this should be the size of the array passed in + * @param mode PWM operation mode, options available in enumeration ::tpm_pwm_mode_t + * @param pwmFreq_Hz PWM signal frequency in Hz + * @param srcClock_Hz TPM counter clock in Hz + * + * @return kStatus_Success if the PWM setup was successful, + * kStatus_Error on failure + */ +status_t TPM_SetupPwm(TPM_Type *base, + const tpm_chnl_pwm_signal_param_t *chnlParams, + uint8_t numOfChnls, + tpm_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz); + +/*! + * @brief Update the duty cycle of an active PWM signal + * + * @param base TPM peripheral base address + * @param chnlNumber The channel number. In combined mode, this represents + * the channel pair number + * @param currentPwmMode The current PWM mode set during PWM setup + * @param dutyCyclePercent New PWM pulse width, value should be between 0 to 100 + * 0=inactive signal(0% duty cycle)... + * 100=active signal (100% duty cycle) + */ +void TPM_UpdatePwmDutycycle(TPM_Type *base, + tpm_chnl_t chnlNumber, + tpm_pwm_mode_t currentPwmMode, + uint8_t dutyCyclePercent); + +/*! + * @brief Update the edge level selection for a channel + * + * @param base TPM peripheral base address + * @param chnlNumber The channel number + * @param level The level to be set to the ELSnB:ELSnA field; valid values are 00, 01, 10, 11. + * See the appropriate SoC reference manual for details about this field. + */ +void TPM_UpdateChnlEdgeLevelSelect(TPM_Type *base, tpm_chnl_t chnlNumber, uint8_t level); + +/*! + * @brief Enables capturing an input signal on the channel using the function parameters. + * + * When the edge specified in the captureMode argument occurs on the channel, the TPM counter is captured into + * the CnV register. The user has to read the CnV register separately to get this value. + * + * @param base TPM peripheral base address + * @param chnlNumber The channel number + * @param captureMode Specifies which edge to capture + */ +void TPM_SetupInputCapture(TPM_Type *base, tpm_chnl_t chnlNumber, tpm_input_capture_edge_t captureMode); + +/*! + * @brief Configures the TPM to generate timed pulses. + * + * When the TPM counter matches the value of compareVal argument (this is written into CnV reg), the channel + * output is changed based on what is specified in the compareMode argument. + * + * @param base TPM peripheral base address + * @param chnlNumber The channel number + * @param compareMode Action to take on the channel output when the compare condition is met + * @param compareValue Value to be programmed in the CnV register. + */ +void TPM_SetupOutputCompare(TPM_Type *base, + tpm_chnl_t chnlNumber, + tpm_output_compare_mode_t compareMode, + uint32_t compareValue); + +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE +/*! + * @brief Configures the dual edge capture mode of the TPM. + * + * This function allows to measure a pulse width of the signal on the input of channel of a + * channel pair. The filter function is disabled if the filterVal argument passed is zero. + * + * @param base TPM peripheral base address + * @param chnlPairNumber The TPM channel pair number; options are 0, 1, 2, 3 + * @param edgeParam Sets up the dual edge capture function + * @param filterValue Filter value, specify 0 to disable filter. + */ +void TPM_SetupDualEdgeCapture(TPM_Type *base, + tpm_chnl_t chnlPairNumber, + const tpm_dual_edge_capture_param_t *edgeParam, + uint32_t filterValue); +#endif + +#if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL +/*! + * @brief Configures the parameters and activates the quadrature decode mode. + * + * @param base TPM peripheral base address + * @param phaseAParams Phase A configuration parameters + * @param phaseBParams Phase B configuration parameters + * @param quadMode Selects encoding mode used in quadrature decoder mode + */ +void TPM_SetupQuadDecode(TPM_Type *base, + const tpm_phase_params_t *phaseAParams, + const tpm_phase_params_t *phaseBParams, + tpm_quad_decode_mode_t quadMode); +#endif + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected TPM interrupts. + * + * @param base TPM peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::tpm_interrupt_enable_t + */ +void TPM_EnableInterrupts(TPM_Type *base, uint32_t mask); + +/*! + * @brief Disables the selected TPM interrupts. + * + * @param base TPM peripheral base address + * @param mask The interrupts to disable. This is a logical OR of members of the + * enumeration ::tpm_interrupt_enable_t + */ +void TPM_DisableInterrupts(TPM_Type *base, uint32_t mask); + +/*! + * @brief Gets the enabled TPM interrupts. + * + * @param base TPM peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::tpm_interrupt_enable_t + */ +uint32_t TPM_GetEnabledInterrupts(TPM_Type *base); + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the TPM status flags + * + * @param base TPM peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::tpm_status_flags_t + */ +static inline uint32_t TPM_GetStatusFlags(TPM_Type *base) +{ + return base->STATUS; +} + +/*! + * @brief Clears the TPM status flags + * + * @param base TPM peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::tpm_status_flags_t + */ +static inline void TPM_ClearStatusFlags(TPM_Type *base, uint32_t mask) +{ + /* Clear the status flags */ + base->STATUS = mask; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the TPM counter. + * + * + * @param base TPM peripheral base address + * @param clockSource TPM clock source; once clock source is set the counter will start running + */ +static inline void TPM_StartTimer(TPM_Type *base, tpm_clock_source_t clockSource) +{ + uint32_t reg = base->SC; + + reg &= ~(TPM_SC_CMOD_MASK); + reg |= TPM_SC_CMOD(clockSource); + base->SC = reg; +} + +/*! + * @brief Stops the TPM counter. + * + * @param base TPM peripheral base address + */ +static inline void TPM_StopTimer(TPM_Type *base) +{ + /* Set clock source to none to disable counter */ + base->SC &= ~(TPM_SC_CMOD_MASK); + + /* Wait till this reads as zero acknowledging the counter is disabled */ + while (base->SC & TPM_SC_CMOD_MASK) + { + } +} + +/*! @}*/ + +#if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL +/*! + * @brief Performs a software reset on the TPM module. + * + * Reset all internal logic and registers, except the Global Register. Remains set until cleared by software.. + * + * @note TPM software reset is available on certain SoC's only + * + * @param base TPM peripheral base address + */ +static inline void TPM_Reset(TPM_Type *base) +{ + base->GLOBAL |= TPM_GLOBAL_RST_MASK; + base->GLOBAL &= ~TPM_GLOBAL_RST_MASK; +} +#endif + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_TPM_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart.c new file mode 100644 index 0000000000..b0b92399db --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart.c @@ -0,0 +1,1032 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_uart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* UART transfer state. */ +enum _uart_tansfer_states +{ + kUART_TxIdle, /* TX idle. */ + kUART_TxBusy, /* TX busy. */ + kUART_RxIdle, /* RX idle. */ + kUART_RxBusy /* RX busy. */ +}; + +/* Typedef for interrupt handler. */ +typedef void (*uart_isr_t)(UART_Type *base, uart_handle_t *handle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get the UART instance from peripheral base address. + * + * @param base UART peripheral base address. + * @return UART instance. + */ +uint32_t UART_GetInstance(UART_Type *base); + +/*! + * @brief Get the length of received data in RX ring buffer. + * + * @param handle UART handle pointer. + * @return Length of received data in RX ring buffer. + */ +static size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle); + +/*! + * @brief Check whether the RX ring buffer is full. + * + * @param handle UART handle pointer. + * @retval true RX ring buffer is full. + * @retval false RX ring buffer is not full. + */ +static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle); + +/*! + * @brief Read RX register using non-blocking method. + * + * This function reads data from the TX register directly, upper layer must make + * sure the RX register is full or TX FIFO has data before calling this function. + * + * @param base UART peripheral base address. + * @param data Start addresss of the buffer to store the received data. + * @param length Size of the buffer. + */ +static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length); + +/*! + * @brief Write to TX register using non-blocking method. + * + * This function writes data to the TX register directly, upper layer must make + * sure the TX register is empty or TX FIFO has empty room before calling this function. + * + * @note This function does not check whether all the data has been sent out to bus, + * so before disable TX, check kUART_TransmissionCompleteFlag to ensure the TX is + * finished. + * + * @param base UART peripheral base address. + * @param data Start addresss of the data to write. + * @param length Size of the buffer to be sent. + */ +static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Array of UART handle. */ +#if (defined(UART5)) +#define UART_HANDLE_ARRAY_SIZE 6 +#else /* UART5 */ +#if (defined(UART4)) +#define UART_HANDLE_ARRAY_SIZE 5 +#else /* UART4 */ +#if (defined(UART3)) +#define UART_HANDLE_ARRAY_SIZE 4 +#else /* UART3 */ +#if (defined(UART2)) +#define UART_HANDLE_ARRAY_SIZE 3 +#else /* UART2 */ +#if (defined(UART1)) +#define UART_HANDLE_ARRAY_SIZE 2 +#else /* UART1 */ +#if (defined(UART0)) +#define UART_HANDLE_ARRAY_SIZE 1 +#else /* UART0 */ +#error No UART instance. +#endif /* UART 0 */ +#endif /* UART 1 */ +#endif /* UART 2 */ +#endif /* UART 3 */ +#endif /* UART 4 */ +#endif /* UART 5 */ +static uart_handle_t *s_uartHandle[UART_HANDLE_ARRAY_SIZE]; +/* Array of UART peripheral base address. */ +static UART_Type *const s_uartBases[] = UART_BASE_PTRS; + +/* Array of UART IRQ number. */ +static const IRQn_Type s_uartIRQ[] = UART_RX_TX_IRQS; +/* Array of UART clock name. */ +static const clock_ip_name_t s_uartClock[] = UART_CLOCKS; + +/* UART ISR for transactional APIs. */ +static uart_isr_t s_uartIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ + +uint32_t UART_GetInstance(UART_Type *base) +{ + uint32_t instance; + uint32_t uartArrayCount = (sizeof(s_uartBases) / sizeof(s_uartBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < uartArrayCount; instance++) + { + if (s_uartBases[instance] == base) + { + break; + } + } + + assert(instance < uartArrayCount); + + return instance; +} + +static size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle) +{ + size_t size; + + if (handle->rxRingBufferTail > handle->rxRingBufferHead) + { + size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); + } + else + { + size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); + } + + return size; +} + +static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle) +{ + bool full; + + if (UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) + { + full = true; + } + else + { + full = false; + } + + return full; +} + +void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz) +{ + assert(config); +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->txFifoWatermark); + assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->rxFifoWatermark); +#endif + + uint16_t sbr; + uint8_t temp; + + /* Enable uart clock */ + CLOCK_EnableClock(s_uartClock[UART_GetInstance(base)]); + + /* Disable UART TX RX before setting. */ + base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); + + /* Calculate the baud rate modulo divisor, sbr*/ + sbr = srcClock_Hz / (config->baudRate_Bps * 16); + + /* Write the sbr value to the BDH and BDL registers*/ + base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); + base->BDL = (uint8_t)sbr; + +#if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT + /* Determine if a fractional divider is needed to fine tune closer to the + * desired baud, each value of brfa is in 1/32 increments, + * hence the multiply-by-32. */ + uint16_t brfa = (32 * srcClock_Hz / (config->baudRate_Bps * 16)) - 32 * sbr; + + /* Write the brfa value to the register*/ + base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); +#endif + + /* Set bit count and parity mode. */ + temp = base->C1 & ~(UART_C1_PE_MASK | UART_C1_PT_MASK | UART_C1_M_MASK); + + if (kUART_ParityDisabled != config->parityMode) + { + temp |= (UART_C1_M_MASK | (uint8_t)config->parityMode); + } + + base->C1 = temp; + +#if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT + /* Set stop bit per char */ + base->BDH = (base->BDH & ~UART_BDH_SBNS_MASK) | UART_BDH_SBNS((uint8_t)config->stopBitCount); +#endif + +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + /* Set tx/rx FIFO watermark */ + base->TWFIFO = config->txFifoWatermark; + base->RWFIFO = config->rxFifoWatermark; + + /* Enable tx/rx FIFO */ + base->PFIFO |= (UART_PFIFO_TXFE_MASK | UART_PFIFO_RXFE_MASK); + + /* Flush FIFO */ + base->CFIFO |= (UART_CFIFO_TXFLUSH_MASK | UART_CFIFO_RXFLUSH_MASK); +#endif + + /* Enable TX/RX base on configure structure. */ + temp = base->C2; + + if (config->enableTx) + { + temp |= UART_C2_TE_MASK; + } + + if (config->enableRx) + { + temp |= UART_C2_RE_MASK; + } + + base->C2 = temp; +} + +void UART_Deinit(UART_Type *base) +{ +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + /* Wait tx FIFO send out*/ + while (0 != base->TCFIFO) + { + } +#endif + /* Wait last char shoft out */ + while (0 == (base->S1 & UART_S1_TC_MASK)) + { + } + + /* Disable the module. */ + base->C2 = 0; + + /* Disable uart clock */ + CLOCK_DisableClock(s_uartClock[UART_GetInstance(base)]); +} + +void UART_GetDefaultConfig(uart_config_t *config) +{ + assert(config); + + config->baudRate_Bps = 115200U; + config->parityMode = kUART_ParityDisabled; +#if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT + config->stopBitCount = kUART_OneStopBit; +#endif +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + config->txFifoWatermark = 0; + config->rxFifoWatermark = 1; +#endif + config->enableTx = false; + config->enableRx = false; +} + +void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + uint16_t sbr; + uint8_t oldCtrl; + + /* Store C2 before disable Tx and Rx */ + oldCtrl = base->C2; + + /* Disable UART TX RX before setting. */ + base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); + + /* Calculate the baud rate modulo divisor, sbr*/ + sbr = srcClock_Hz / (baudRate_Bps * 16); + + /* Write the sbr value to the BDH and BDL registers*/ + base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); + base->BDL = (uint8_t)sbr; + +#if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT + /* Determine if a fractional divider is needed to fine tune closer to the + * desired baud, each value of brfa is in 1/32 increments, + * hence the multiply-by-32. */ + uint16_t brfa = (32 * srcClock_Hz / (baudRate_Bps * 16)) - 32 * sbr; + + /* Write the brfa value to the register*/ + base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); +#endif + + /* Restore C2. */ + base->C2 = oldCtrl; +} + +void UART_EnableInterrupts(UART_Type *base, uint32_t mask) +{ + /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) + */ + base->BDH |= (mask & 0xFF); + base->C2 |= ((mask >> 8) & 0xFF); + base->C3 |= ((mask >> 16) & 0xFF); + +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + base->CFIFO |= ((mask >> 24) & 0xFF); +#endif +} + +void UART_DisableInterrupts(UART_Type *base, uint32_t mask) +{ + /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) + */ + base->BDH &= ~(mask & 0xFF); + base->C2 &= ~((mask >> 8) & 0xFF); + base->C3 &= ~((mask >> 16) & 0xFF); + +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + base->CFIFO &= ~((mask >> 24) & 0xFF); +#endif +} + +uint32_t UART_GetEnabledInterrupts(UART_Type *base) +{ + uint32_t temp; + + temp = base->BDH | ((uint32_t)(base->C2) << 8) | ((uint32_t)(base->C3) << 16); + +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + temp |= ((uint32_t)(base->CFIFO) << 24); +#endif + + return temp; +} + +uint32_t UART_GetStatusFlags(UART_Type *base) +{ + uint32_t status_flag; + + status_flag = base->S1 | ((uint32_t)(base->S2) << 8); + +#if defined(FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS + status_flag |= ((uint32_t)(base->ED) << 16); +#endif + +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + status_flag |= ((uint32_t)(base->SFIFO) << 24); +#endif + + return status_flag; +} + +status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask) +{ + uint8_t reg = base->S2; + status_t status; + +#if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT + reg &= ~(UART_S2_RXEDGIF_MASK | UART_S2_LBKDIF_MASK); +#else + reg &= ~UART_S2_RXEDGIF_MASK; +#endif + + base->S2 = reg | (uint8_t)(mask >> 8); + +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + base->SFIFO = (uint8_t)(mask >> 24); +#endif + + if (mask & (kUART_IdleLineFlag | kUART_RxOverrunFlag | kUART_NoiseErrorFlag | kUART_FramingErrorFlag | + kUART_ParityErrorFlag)) + { + /* Read base->D to clear the flags. */ + (void)base->S1; + (void)base->D; + } + + /* If some flags still pending. */ + if (mask & UART_GetStatusFlags(base)) + { + /* Some flags can only clear or set by the hardware itself, these flags are: kUART_TxDataRegEmptyFlag, + kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, + kUART_ParityErrorInRxDataRegFlag, kUART_TxFifoEmptyFlag, kUART_RxFifoEmptyFlag. */ + status = kStatus_UART_FlagCannotClearManually; + } + else + { + status = kStatus_Success; + } + + return status; +} + +void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length) +{ + /* This API can only ensure that the data is written into the data buffer but can't + ensure all data in the data buffer are sent into the transmit shift buffer. */ + while (length--) + { + while (!(base->S1 & UART_S1_TDRE_MASK)) + { + } + base->D = *(data++); + } +} + +static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length) +{ + size_t i; + + /* The Non Blocking write data API assume user have ensured there is enough space in + peripheral to write. */ + for (i = 0; i < length; i++) + { + base->D = data[i]; + } +} + +status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length) +{ + uint32_t statusFlag; + + while (length--) + { +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + while (!base->RCFIFO) +#else + while (!(base->S1 & UART_S1_RDRF_MASK)) +#endif + { + statusFlag = UART_GetStatusFlags(base); + + if (statusFlag & kUART_RxOverrunFlag) + { + return kStatus_UART_RxHardwareOverrun; + } + + if (statusFlag & kUART_NoiseErrorFlag) + { + return kStatus_UART_NoiseError; + } + + if (statusFlag & kUART_FramingErrorFlag) + { + return kStatus_UART_FramingError; + } + + if (statusFlag & kUART_ParityErrorFlag) + { + return kStatus_UART_ParityError; + } + } + *(data++) = base->D; + } + + return kStatus_Success; +} + +static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length) +{ + size_t i; + + /* The Non Blocking read data API assume user have ensured there is enough space in + peripheral to write. */ + for (i = 0; i < length; i++) + { + data[i] = base->D; + } +} + +void UART_TransferCreateHandle(UART_Type *base, + uart_handle_t *handle, + uart_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + uint32_t instance; + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set the TX/RX state. */ + handle->rxState = kUART_RxIdle; + handle->txState = kUART_TxIdle; + + /* Set the callback and user data. */ + handle->callback = callback; + handle->userData = userData; + +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + /* Note: + Take care of the RX FIFO, RX interrupt request only assert when received bytes + equal or more than RX water mark, there is potential issue if RX water + mark larger than 1. + For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and + 5 bytes are received. the last byte will be saved in FIFO but not trigger + RX interrupt because the water mark is 2. + */ + base->RWFIFO = 1U; +#endif + + /* Get instance from peripheral base address. */ + instance = UART_GetInstance(base); + + /* Save the handle in global variables to support the double weak mechanism. */ + s_uartHandle[instance] = handle; + + s_uartIsr = UART_TransferHandleIRQ; + + /* Enable interrupt in NVIC. */ + EnableIRQ(s_uartIRQ[instance]); +} + +void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize) +{ + assert(handle); + + /* Setup the ringbuffer address */ + if (ringBuffer) + { + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; + + /* Enable the interrupt to accept the data when user need the ring buffer. */ + UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + } +} + +void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle) +{ + assert(handle); + + if (handle->rxState == kUART_RxIdle) + { + UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + } + + handle->rxRingBuffer = NULL; + handle->rxRingBufferSize = 0U; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; +} + +status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer) +{ + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* Return error if current TX busy. */ + if (kUART_TxBusy == handle->txState) + { + status = kStatus_UART_TxBusy; + } + else + { + handle->txData = xfer->data; + handle->txDataSize = xfer->dataSize; + handle->txDataSizeAll = xfer->dataSize; + handle->txState = kUART_TxBusy; + + /* Enable transmiter interrupt. */ + UART_EnableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable); + + status = kStatus_Success; + } + + return status; +} + +void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle) +{ + UART_DisableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable | kUART_TransmissionCompleteInterruptEnable); + + handle->txDataSize = 0; + handle->txState = kUART_TxIdle; +} + +status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) +{ + if (kUART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->txDataSizeAll - handle->txDataSize; + + return kStatus_Success; +} + +status_t UART_TransferReceiveNonBlocking(UART_Type *base, + uart_handle_t *handle, + uart_transfer_t *xfer, + size_t *receivedBytes) +{ + uint32_t i; + status_t status; + /* How many bytes to copy from ring buffer to user memory. */ + size_t bytesToCopy = 0U; + /* How many bytes to receive. */ + size_t bytesToReceive; + /* How many bytes currently have received. */ + size_t bytesCurrentReceived; + uint32_t regPrimask = 0U; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* How to get data: + 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize + to uart handle, enable interrupt to store received data to xfer->data. When + all data received, trigger callback. + 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. + If there are enough data in ring buffer, copy them to xfer->data and return. + If there are not enough data in ring buffer, copy all of them to xfer->data, + save the xfer->data remained empty space to uart handle, receive data + to this empty space and trigger callback when finished. */ + + if (kUART_RxBusy == handle->rxState) + { + status = kStatus_UART_RxBusy; + } + else + { + bytesToReceive = xfer->dataSize; + bytesCurrentReceived = 0U; + + /* If RX ring buffer is used. */ + if (handle->rxRingBuffer) + { + /* Disable IRQ, protect ring buffer. */ + regPrimask = DisableGlobalIRQ(); + + /* How many bytes in RX ring buffer currently. */ + bytesToCopy = UART_TransferGetRxRingBufferLength(handle); + + if (bytesToCopy) + { + bytesToCopy = MIN(bytesToReceive, bytesToCopy); + + bytesToReceive -= bytesToCopy; + + /* Copy data from ring buffer to user memory. */ + for (i = 0U; i < bytesToCopy; i++) + { + xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; + + /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + } + + /* If ring buffer does not have enough data, still need to read more data. */ + if (bytesToReceive) + { + /* No data in ring buffer, save the request to UART handle. */ + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kUART_RxBusy; + } + + /* Enable IRQ if previously enabled. */ + EnableGlobalIRQ(regPrimask); + + /* Call user callback since all data are received. */ + if (0 == bytesToReceive) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData); + } + } + } + /* Ring buffer not used. */ + else + { + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kUART_RxBusy; + + /* Enable RX interrupt. */ + UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + } + + /* Return the how many bytes have read. */ + if (receivedBytes) + { + *receivedBytes = bytesCurrentReceived; + } + + status = kStatus_Success; + } + + return status; +} + +void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle) +{ + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ + if (!handle->rxRingBuffer) + { + /* Disable RX interrupt. */ + UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + } + + handle->rxDataSize = 0U; + handle->rxState = kUART_RxIdle; +} + +status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) +{ + if (kUART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->rxDataSizeAll - handle->rxDataSize; + + return kStatus_Success; +} + +void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle) +{ + uint8_t count; + uint8_t tempCount; + + assert(handle); + + /* If RX overrun. */ + if (UART_S1_OR_MASK & base->S1) + { + /* Read base->D, otherwise the RX does not work. */ + (void)base->D; + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_UART_RxHardwareOverrun, handle->userData); + } + } + + /* Receive data register full */ + if ((UART_S1_RDRF_MASK & base->S1) && (UART_C2_RIE_MASK & base->C2)) + { +/* Get the size that can be stored into buffer for this interrupt. */ +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + count = base->RCFIFO; +#else + count = 1; +#endif + + /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ + while ((count) && (handle->rxDataSize)) + { +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + tempCount = MIN(handle->rxDataSize, count); +#else + tempCount = 1; +#endif + + /* Using non block API to read the data from the registers. */ + UART_ReadNonBlocking(base, handle->rxData, tempCount); + handle->rxData += tempCount; + handle->rxDataSize -= tempCount; + count -= tempCount; + + /* If all the data required for upper layer is ready, trigger callback. */ + if (!handle->rxDataSize) + { + handle->rxState = kUART_RxIdle; + + if (handle->callback) + { + handle->callback(base, handle, kStatus_UART_RxIdle, handle->userData); + } + } + } + + /* If use RX ring buffer, receive data to ring buffer. */ + if (handle->rxRingBuffer) + { + while (count--) + { + /* If RX ring buffer is full, trigger callback to notify over run. */ + if (UART_TransferIsRxRingBufferFull(handle)) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_UART_RxRingBufferOverrun, handle->userData); + } + } + + /* If ring buffer is still full after callback function, the oldest data is overrided. */ + if (UART_TransferIsRxRingBufferFull(handle)) + { + /* Increase handle->rxRingBufferTail to make room for new data. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + + /* Read data. */ + handle->rxRingBuffer[handle->rxRingBufferHead] = base->D; + + /* Increase handle->rxRingBufferHead. */ + if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferHead = 0U; + } + else + { + handle->rxRingBufferHead++; + } + } + } + /* If no receive requst pending, stop RX interrupt. */ + else if (!handle->rxDataSize) + { + UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + } + else + { + } + } + + /* Send data register empty and the interrupt is enabled. */ + if ((base->S1 & UART_S1_TDRE_MASK) && (base->C2 & UART_C2_TIE_MASK)) + { +/* Get the bytes that available at this moment. */ +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + count = FSL_FEATURE_UART_FIFO_SIZEn(base) - base->TCFIFO; +#else + count = 1; +#endif + + while ((count) && (handle->txDataSize)) + { +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + tempCount = MIN(handle->txDataSize, count); +#else + tempCount = 1; +#endif + + /* Using non block API to write the data to the registers. */ + UART_WriteNonBlocking(base, handle->txData, tempCount); + handle->txData += tempCount; + handle->txDataSize -= tempCount; + count -= tempCount; + + /* If all the data are written to data register, TX finished. */ + if (!handle->txDataSize) + { + handle->txState = kUART_TxIdle; + + /* Disable TX register empty interrupt. */ + base->C2 = (base->C2 & ~UART_C2_TIE_MASK); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_UART_TxIdle, handle->userData); + } + } + } + } +} + +void UART_TransferHandleErrorIRQ(UART_Type *base, uart_handle_t *handle) +{ + /* TODO: To be implemented. */ +} + +#if defined(UART0) +#if ((!(defined(FSL_FEATURE_SOC_LPSCI_COUNT))) || \ + ((defined(FSL_FEATURE_SOC_LPSCI_COUNT)) && (FSL_FEATURE_SOC_LPSCI_COUNT == 0))) +void UART0_DriverIRQHandler(void) +{ + s_uartIsr(UART0, s_uartHandle[0]); +} + +void UART0_RX_TX_DriverIRQHandler(void) +{ + UART0_DriverIRQHandler(); +} +#endif +#endif + +#if defined(UART1) +void UART1_DriverIRQHandler(void) +{ + s_uartIsr(UART1, s_uartHandle[1]); +} + +void UART1_RX_TX_DriverIRQHandler(void) +{ + UART1_DriverIRQHandler(); +} +#endif + +#if defined(UART2) +void UART2_DriverIRQHandler(void) +{ + s_uartIsr(UART2, s_uartHandle[2]); +} + +void UART2_RX_TX_DriverIRQHandler(void) +{ + UART2_DriverIRQHandler(); +} + +#endif + +#if defined(UART3) +void UART3_DriverIRQHandler(void) +{ + s_uartIsr(UART3, s_uartHandle[3]); +} + +void UART3_RX_TX_DriverIRQHandler(void) +{ + UART3_DriverIRQHandler(); +} +#endif + +#if defined(UART4) +void UART4_DriverIRQHandler(void) +{ + s_uartIsr(UART4, s_uartHandle[4]); +} + +void UART4_RX_TX_DriverIRQHandler(void) +{ + UART4_DriverIRQHandler(); +} +#endif + +#if defined(UART5) +void UART5_DriverIRQHandler(void) +{ + s_uartIsr(UART5, s_uartHandle[5]); +} + +void UART5_RX_TX_DriverIRQHandler(void) +{ + UART5_DriverIRQHandler(); +} +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart.h new file mode 100644 index 0000000000..3eec4e66b5 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart.h @@ -0,0 +1,757 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_UART_H_ +#define _FSL_UART_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup uart_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief UART driver version 2.1.0. */ +#define FSL_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! @brief Error codes for the UART driver. */ +enum _uart_status +{ + kStatus_UART_TxBusy = MAKE_STATUS(kStatusGroup_UART, 0), /*!< Transmitter is busy. */ + kStatus_UART_RxBusy = MAKE_STATUS(kStatusGroup_UART, 1), /*!< Receiver is busy. */ + kStatus_UART_TxIdle = MAKE_STATUS(kStatusGroup_UART, 2), /*!< UART transmitter is idle. */ + kStatus_UART_RxIdle = MAKE_STATUS(kStatusGroup_UART, 3), /*!< UART receiver is idle. */ + kStatus_UART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_UART, 4), /*!< TX FIFO watermark too large */ + kStatus_UART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_UART, 5), /*!< RX FIFO watermark too large */ + kStatus_UART_FlagCannotClearManually = + MAKE_STATUS(kStatusGroup_UART, 6), /*!< UART flag can't be manually cleared. */ + kStatus_UART_Error = MAKE_STATUS(kStatusGroup_UART, 7), /*!< Error happens on UART. */ + kStatus_UART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_UART, 8), /*!< UART RX software ring buffer overrun. */ + kStatus_UART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_UART, 9), /*!< UART RX receiver overrun. */ + kStatus_UART_NoiseError = MAKE_STATUS(kStatusGroup_UART, 10), /*!< UART noise error. */ + kStatus_UART_FramingError = MAKE_STATUS(kStatusGroup_UART, 11), /*!< UART framing error. */ + kStatus_UART_ParityError = MAKE_STATUS(kStatusGroup_UART, 12), /*!< UART parity error. */ +}; + +/*! @brief UART parity mode. */ +typedef enum _uart_parity_mode +{ + kUART_ParityDisabled = 0x0U, /*!< Parity disabled */ + kUART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */ + kUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */ +} uart_parity_mode_t; + +/*! @brief UART stop bit count. */ +typedef enum _uart_stop_bit_count +{ + kUART_OneStopBit = 0U, /*!< One stop bit */ + kUART_TwoStopBit = 1U, /*!< Two stop bits */ +} uart_stop_bit_count_t; + +/*! + * @brief UART interrupt configuration structure, default settings all disabled. + * + * This structure contains the settings for all of the UART interrupt configurations. + */ +enum _uart_interrupt_enable +{ +#if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT + kUART_LinBreakInterruptEnable = (UART_BDH_LBKDIE_MASK), /*!< LIN break detect interrupt. */ +#endif + kUART_RxActiveEdgeInterruptEnable = (UART_BDH_RXEDGIE_MASK), /*!< RX active edge interrupt. */ + kUART_TxDataRegEmptyInterruptEnable = (UART_C2_TIE_MASK << 8), /*!< Transmit data register empty interrupt. */ + kUART_TransmissionCompleteInterruptEnable = (UART_C2_TCIE_MASK << 8), /*!< Transmission complete interrupt. */ + kUART_RxDataRegFullInterruptEnable = (UART_C2_RIE_MASK << 8), /*!< Receiver data register full interrupt. */ + kUART_IdleLineInterruptEnable = (UART_C2_ILIE_MASK << 8), /*!< Idle line interrupt. */ + kUART_RxOverrunInterruptEnable = (UART_C3_ORIE_MASK << 16), /*!< Receiver overrun interrupt. */ + kUART_NoiseErrorInterruptEnable = (UART_C3_NEIE_MASK << 16), /*!< Noise error flag interrupt. */ + kUART_FramingErrorInterruptEnable = (UART_C3_FEIE_MASK << 16), /*!< Framing error flag interrupt. */ + kUART_ParityErrorInterruptEnable = (UART_C3_PEIE_MASK << 16), /*!< Parity error flag interrupt. */ +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + kUART_RxFifoOverflowInterruptEnable = (UART_CFIFO_TXOFE_MASK << 24), /*!< TX FIFO overflow interrupt. */ + kUART_TxFifoOverflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */ + kUART_RxFifoUnderflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */ +#endif +}; + +/*! + * @brief UART status flags. + * + * This provides constants for the UART status flags for use in the UART functions. + */ +enum _uart_flags +{ + kUART_TxDataRegEmptyFlag = (UART_S1_TDRE_MASK), /*!< TX data register empty flag. */ + kUART_TransmissionCompleteFlag = (UART_S1_TC_MASK), /*!< Transmission complete flag. */ + kUART_RxDataRegFullFlag = (UART_S1_RDRF_MASK), /*!< RX data register full flag. */ + kUART_IdleLineFlag = (UART_S1_IDLE_MASK), /*!< Idle line detect flag. */ + kUART_RxOverrunFlag = (UART_S1_OR_MASK), /*!< RX overrun flag. */ + kUART_NoiseErrorFlag = (UART_S1_NF_MASK), /*!< RX takes 3 samples of each received bit. + If any of these samples differ, noise flag sets */ + kUART_FramingErrorFlag = (UART_S1_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected + where stop bit expected */ + kUART_ParityErrorFlag = (UART_S1_PF_MASK), /*!< If parity enabled, sets upon parity error detection */ +#if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT + kUART_LinBreakFlag = + (UART_S2_LBKDIF_MASK << 8), /*!< LIN break detect interrupt flag, sets when + LIN break char detected and LIN circuit enabled */ +#endif + kUART_RxActiveEdgeFlag = (UART_S2_RXEDGIF_MASK << 8), /*!< RX pin active edge interrupt flag, + sets when active edge detected */ + kUART_RxActiveFlag = (UART_S2_RAF_MASK << 8), /*!< Receiver Active Flag (RAF), + sets at beginning of valid start bit */ +#if defined(FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS + kUART_NoiseErrorInRxDataRegFlag = (UART_ED_NOISY_MASK << 16), /*!< Noisy bit, sets if noise detected. */ + kUART_ParityErrorInRxDataRegFlag = (UART_ED_PARITYE_MASK << 16), /*!< Paritye bit, sets if parity error detected. */ +#endif +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + kUART_TxFifoEmptyFlag = (UART_SFIFO_TXEMPT_MASK << 24), /*!< TXEMPT bit, sets if TX buffer is empty */ + kUART_RxFifoEmptyFlag = (UART_SFIFO_RXEMPT_MASK << 24), /*!< RXEMPT bit, sets if RX buffer is empty */ + kUART_TxFifoOverflowFlag = (UART_SFIFO_TXOF_MASK << 24), /*!< TXOF bit, sets if TX buffer overflow occurred */ + kUART_RxFifoOverflowFlag = (UART_SFIFO_RXOF_MASK << 24), /*!< RXOF bit, sets if receive buffer overflow */ + kUART_RxFifoUnderflowFlag = (UART_SFIFO_RXUF_MASK << 24), /*!< RXUF bit, sets if receive buffer underflow */ +#endif +}; + +/*! @brief UART configuration structure. */ +typedef struct _uart_config +{ + uint32_t baudRate_Bps; /*!< UART baud rate */ + uart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ +#if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT + uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ +#endif +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + uint8_t txFifoWatermark; /*!< TX FIFO watermark */ + uint8_t rxFifoWatermark; /*!< RX FIFO watermark */ +#endif + bool enableTx; /*!< Enable TX */ + bool enableRx; /*!< Enable RX */ +} uart_config_t; + +/*! @brief UART transfer structure. */ +typedef struct _uart_transfer +{ + uint8_t *data; /*!< The buffer of data to be transfer.*/ + size_t dataSize; /*!< The byte count to be transfer. */ +} uart_transfer_t; + +/* Forward declaration of the handle typedef. */ +typedef struct _uart_handle uart_handle_t; + +/*! @brief UART transfer callback function. */ +typedef void (*uart_transfer_callback_t)(UART_Type *base, uart_handle_t *handle, status_t status, void *userData); + +/*! @brief UART handle structure. */ +struct _uart_handle +{ + uint8_t *volatile txData; /*!< Address of remaining data to send. */ + volatile size_t txDataSize; /*!< Size of the remaining data to send. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ + volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + + uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ + size_t rxRingBufferSize; /*!< Size of the ring buffer. */ + volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ + volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ + + uart_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< UART callback function parameter.*/ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes a UART instance with user configuration structure and peripheral clock. + * + * This function configures the UART module with the user-defined settings. The user can configure the configuration + * structure and also get the default configuration by using the UART_GetDefaultConfig() function. + * Example below shows how to use this API to configure UART. + * @code + * uart_config_t uartConfig; + * uartConfig.baudRate_Bps = 115200U; + * uartConfig.parityMode = kUART_ParityDisabled; + * uartConfig.stopBitCount = kUART_OneStopBit; + * uartConfig.txFifoWatermark = 0; + * uartConfig.rxFifoWatermark = 1; + * UART_Init(UART1, &uartConfig, 20000000U); + * @endcode + * + * @param base UART peripheral base address. + * @param config Pointer to user-defined configuration structure. + * @param srcClock_Hz UART clock source frequency in HZ. + */ +void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Deinitializes a UART instance. + * + * This function waits for TX complete, disables TX and RX, and disables the UART clock. + * + * @param base UART peripheral base address. + */ +void UART_Deinit(UART_Type *base); + +/*! + * @brief Gets the default configuration structure. + * + * This function initializes the UART configuration structure to a default value. The default + * values are: + * uartConfig->baudRate_Bps = 115200U; + * uartConfig->bitCountPerChar = kUART_8BitsPerChar; + * uartConfig->parityMode = kUART_ParityDisabled; + * uartConfig->stopBitCount = kUART_OneStopBit; + * uartConfig->txFifoWatermark = 0; + * uartConfig->rxFifoWatermark = 1; + * uartConfig->enableTx = false; + * uartConfig->enableRx = false; + * + * @param config Pointer to configuration structure. + */ +void UART_GetDefaultConfig(uart_config_t *config); + +/*! + * @brief Sets the UART instance baud rate. + * + * This function configures the UART module baud rate. This function is used to update + * the UART module baud rate after the UART module is initialized by the UART_Init. + * @code + * UART_SetBaudRate(UART1, 115200U, 20000000U); + * @endcode + * + * @param base UART peripheral base address. + * @param baudRate_Bps UART baudrate to be set. + * @param srcClock_Hz UART clock source freqency in HZ. + */ +void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Get UART status flags. + * + * This function get all UART status flags, the flags are returned as the logical + * OR value of the enumerators @ref _uart_flags. To check specific status, + * compare the return value with enumerators in @ref _uart_flags. + * For example, to check whether the TX is empty: + * @code + * if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(UART1)) + * { + * ... + * } + * @endcode + * + * @param base UART peripheral base address. + * @return UART status flags which are ORed by the enumerators in the _uart_flags. + */ +uint32_t UART_GetStatusFlags(UART_Type *base); + +/*! + * @brief Clears status flags with the provided mask. + * + * This function clears UART status flags with a provided mask. Automatically cleared flag + * can't be cleared by this function. + * Some flags can only be cleared or set by hardware itself. These flags are: + * kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, + * kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag, + * kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag + * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. + * + * @param base UART peripheral base address. + * @param mask The status flags to be cleared, it is logical OR value of @ref _uart_flags. + * @retval kStatus_UART_FlagCannotClearManually The flag can't be cleared by this function but + * it is cleared automatically by hardware. + * @retval kStatus_Success Status in the mask are cleared. + */ +status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables UART interrupts according to the provided mask. + * + * This function enables the UART interrupts according to the provided mask. The mask + * is a logical OR of enumeration members. See @ref _uart_interrupt_enable. + * For example, to enable TX empty interrupt and RX full interrupt: + * @code + * UART_EnableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); + * @endcode + * + * @param base UART peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable. + */ +void UART_EnableInterrupts(UART_Type *base, uint32_t mask); + +/*! + * @brief Disables the UART interrupts according to the provided mask. + * + * This function disables the UART interrupts according to the provided mask. The mask + * is a logical OR of enumeration members. See @ref _uart_interrupt_enable. + * For example, to disable TX empty interrupt and RX full interrupt: + * @code + * UART_DisableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); + * @endcode + * + * @param base UART peripheral base address. + * @param mask The interrupts to disable. Logical OR of @ref _uart_interrupt_enable. + */ +void UART_DisableInterrupts(UART_Type *base, uint32_t mask); + +/*! + * @brief Gets the enabled UART interrupts. + * + * This function gets the enabled UART interrupts. The enabled interrupts are returned + * as the logical OR value of the enumerators @ref _uart_interrupt_enable. To check + * specific interrupts enable status, compare the return value with enumerators + * in @ref _uart_interrupt_enable. + * For example, to check whether TX empty interrupt is enabled: + * @code + * uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1); + * + * if (kUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) + * { + * ... + * } + * @endcode + * + * @param base UART peripheral base address. + * @return UART interrupt flags which are logical OR of the enumerators in @ref _uart_interrupt_enable. + */ +uint32_t UART_GetEnabledInterrupts(UART_Type *base); + +/* @} */ + +#if defined(FSL_FEATURE_UART_HAS_DMA_SELECT) && FSL_FEATURE_UART_HAS_DMA_SELECT +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Gets the UART data register address. + * + * This function returns the UART data register address, which is mainly used by DMA/eDMA. + * + * @param base UART peripheral base address. + * @return UART data register address which are used both by transmitter and receiver. + */ +static inline uint32_t UART_GetDataRegisterAddress(UART_Type *base) +{ + return (uint32_t) & (base->D); +} + +/*! + * @brief Enables or disables the UART transmitter DMA request. + * + * This function enables or disables the transmit data register empty flag, S1[TDRE], to generate the DMA requests. + * + * @param base UART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void UART_EnableTxDMA(UART_Type *base, bool enable) +{ + if (enable) + { +#if (defined(FSL_FEATURE_UART_IS_SCI) && FSL_FEATURE_UART_IS_SCI) + base->C4 |= UART_C4_TDMAS_MASK; +#else + base->C5 |= UART_C5_TDMAS_MASK; +#endif + base->C2 |= UART_C2_TIE_MASK; + } + else + { +#if (defined(FSL_FEATURE_UART_IS_SCI) && FSL_FEATURE_UART_IS_SCI) + base->C4 &= ~UART_C4_TDMAS_MASK; +#else + base->C5 &= ~UART_C5_TDMAS_MASK; +#endif + base->C2 &= ~UART_C2_TIE_MASK; + } +} + +/*! + * @brief Enables or disables the UART receiver DMA. + * + * This function enables or disables the receiver data register full flag, S1[RDRF], to generate DMA requests. + * + * @param base UART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void UART_EnableRxDMA(UART_Type *base, bool enable) +{ + if (enable) + { +#if (defined(FSL_FEATURE_UART_IS_SCI) && FSL_FEATURE_UART_IS_SCI) + base->C4 |= UART_C4_RDMAS_MASK; +#else + base->C5 |= UART_C5_RDMAS_MASK; +#endif + base->C2 |= UART_C2_RIE_MASK; + } + else + { +#if (defined(FSL_FEATURE_UART_IS_SCI) && FSL_FEATURE_UART_IS_SCI) + base->C4 &= ~UART_C4_RDMAS_MASK; +#else + base->C5 &= ~UART_C5_RDMAS_MASK; +#endif + base->C2 &= ~UART_C2_RIE_MASK; + } +} + +/* @} */ +#endif /* FSL_FEATURE_UART_HAS_DMA_SELECT */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Enables or disables the UART transmitter. + * + * This function enables or disables the UART transmitter. + * + * @param base UART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void UART_EnableTx(UART_Type *base, bool enable) +{ + if (enable) + { + base->C2 |= UART_C2_TE_MASK; + } + else + { + base->C2 &= ~UART_C2_TE_MASK; + } +} + +/*! + * @brief Enables or disables the UART receiver. + * + * This function enables or disables the UART receiver. + * + * @param base UART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void UART_EnableRx(UART_Type *base, bool enable) +{ + if (enable) + { + base->C2 |= UART_C2_RE_MASK; + } + else + { + base->C2 &= ~UART_C2_RE_MASK; + } +} + +/*! + * @brief Writes to the TX register. + * + * This function writes data to the TX register directly. The upper layer must ensure + * that the TX register is empty or TX FIFO has empty room before calling this function. + * + * @param base UART peripheral base address. + * @param data The byte to write. + */ +static inline void UART_WriteByte(UART_Type *base, uint8_t data) +{ + base->D = data; +} + +/*! + * @brief Reads the RX register directly. + * + * This function reads data from the TX register directly. The upper layer must + * ensure that the RX register is full or that the TX FIFO has data before calling this function. + * + * @param base UART peripheral base address. + * @return The byte read from UART data register. + */ +static inline uint8_t UART_ReadByte(UART_Type *base) +{ + return base->D; +} + +/*! + * @brief Writes to the TX register using a blocking method. + * + * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO + * to have room and writes data to the TX buffer. + * + * @note This function does not check whether all the data has been sent out to the bus. + * Before disabling the TX, check kUART_TransmissionCompleteFlag to ensure that the TX is + * finished. + * + * @param base UART peripheral base address. + * @param data Start address of the data to write. + * @param length Size of the data to write. + */ +void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length); + +/*! + * @brief Read RX data register using a blocking method. + * + * This function polls the RX register, waits for the RX register to be full or for RX FIFO to + * have data and read data from the TX register. + * + * @param base UART peripheral base address. + * @param data Start address of the buffer to store the received data. + * @param length Size of the buffer. + * @retval kStatus_UART_RxHardwareOverrun Receiver overrun happened while receiving data. + * @retval kStatus_UART_NoiseError Noise error happened while receiving data. + * @retval kStatus_UART_FramingError Framing error happened while receiving data. + * @retval kStatus_UART_ParityError Parity error happened while receiving data. + * @retval kStatus_Success Successfully received all data. + */ +status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the UART handle. + * + * This function initializes the UART handle which can be used for other UART + * transactional APIs. Usually, for a specified UART instance, + * call this API once to get the initialized handle. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param callback The callback function. + * @param userData The parameter of the callback function. + */ +void UART_TransferCreateHandle(UART_Type *base, + uart_handle_t *handle, + uart_transfer_callback_t callback, + void *userData); + +/*! + * @brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific UART handle. + * + * When the RX ring buffer is used, data received are stored into the ring buffer even when the + * user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * + * @note When using the RX ring buffer, one byte is reserved for internal use. In other + * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer. + * @param ringBufferSize size of the ring buffer. + */ +void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize); + +/*! + * @brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + */ +void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle); + +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function sends data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data to be written to the TX register. When + * all data is written to the TX register in the ISR, the UART driver calls the callback + * function and passes the @ref kStatus_UART_TxIdle as status parameter. + * + * @note The kStatus_UART_TxIdle is passed to the upper layer when all data is written + * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX, + * check the kUART_TransmissionCompleteFlag to ensure that the TX is finished. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param xfer UART transfer structure. See #uart_transfer_t. + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_UART_TxBusy Previous transmission still not finished, data not all written to TX register yet. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer); + +/*! + * @brief Aborts the interrupt driven data transmit. + * + * This function aborts the interrupt driven data sending. The user can get the remainBytes to find out + * how many bytes are still not sent out. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + */ +void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been written to UART TX register. + * + * This function gets the number of bytes that have been written to UART TX + * register by interrupt method. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count); + +/*! + * @brief Receives a buffer of data using an interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function, which + * returns without waiting for all data to be received. + * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and + * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in the ring buffer is not enough to read, the receive + * request is saved by the UART driver. When the new data arrives, the receive request + * is serviced first. When all data is received, the UART driver notifies the upper layer + * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle. + * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer. + * The 5 bytes are copied to the xfer->data and this function returns with the + * parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is + * saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies the upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to the xfer->data. When all data is received, the upper layer is notified. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param xfer UART transfer structure, refer to #uart_transfer_t. + * @param receivedBytes Bytes received from the ring buffer directly. + * @retval kStatus_Success Successfully queue the transfer into transmit queue. + * @retval kStatus_UART_RxBusy Previous receive request is not finished. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t UART_TransferReceiveNonBlocking(UART_Type *base, + uart_handle_t *handle, + uart_transfer_t *xfer, + size_t *receivedBytes); + +/*! + * @brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know + * how many bytes not received yet. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + */ +void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count); + +/*! + * @brief UART IRQ handle function. + * + * This function handles the UART transmit and receive IRQ request. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + */ +void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle); + +/*! + * @brief UART Error IRQ handle function. + * + * This function handle the UART error IRQ request. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + */ +void UART_TransferHandleErrorIRQ(UART_Type *base, uart_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_UART_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart_dma.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart_dma.c new file mode 100644 index 0000000000..c4a2f000a1 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart_dma.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_uart_dma.h" +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Array of UART handle. */ +#if (defined(UART5)) +#define UART_HANDLE_ARRAY_SIZE 6 +#else /* UART5 */ +#if (defined(UART4)) +#define UART_HANDLE_ARRAY_SIZE 5 +#else /* UART4 */ +#if (defined(UART3)) +#define UART_HANDLE_ARRAY_SIZE 4 +#else /* UART3 */ +#if (defined(UART2)) +#define UART_HANDLE_ARRAY_SIZE 3 +#else /* UART2 */ +#if (defined(UART1)) +#define UART_HANDLE_ARRAY_SIZE 2 +#else /* UART1 */ +#if (defined(UART0)) +#define UART_HANDLE_ARRAY_SIZE 1 +#else /* UART0 */ +#error No UART instance. +#endif /* UART 0 */ +#endif /* UART 1 */ +#endif /* UART 2 */ +#endif /* UART 3 */ +#endif /* UART 4 */ +#endif /* UART 5 */ + +/*base, false); + + /* Disable interrupt. */ + DMA_DisableInterrupts(handle->base, handle->channel); + + uartPrivateHandle->handle->txState = kUART_TxIdle; + + if (uartPrivateHandle->handle->callback) + { + uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, kStatus_UART_TxIdle, + uartPrivateHandle->handle->userData); + } +} + +static void UART_TransferReceiveDMACallback(dma_handle_t *handle, void *param) +{ + uart_dma_private_handle_t *uartPrivateHandle = (uart_dma_private_handle_t *)param; + + /* Disable UART RX DMA. */ + UART_EnableRxDMA(uartPrivateHandle->base, false); + + /* Disable interrupt. */ + DMA_DisableInterrupts(handle->base, handle->channel); + + uartPrivateHandle->handle->rxState = kUART_RxIdle; + + if (uartPrivateHandle->handle->callback) + { + uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, kStatus_UART_RxIdle, + uartPrivateHandle->handle->userData); + } +} + +void UART_TransferCreateHandleDMA(UART_Type *base, + uart_dma_handle_t *handle, + uart_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txDmaHandle, + dma_handle_t *rxDmaHandle) +{ + assert(handle); + + uint32_t instance = UART_GetInstance(base); + + memset(handle, 0, sizeof(*handle)); + + s_dmaPrivateHandle[instance].base = base; + s_dmaPrivateHandle[instance].handle = handle; + + handle->rxState = kUART_RxIdle; + handle->txState = kUART_TxIdle; + + handle->callback = callback; + handle->userData = userData; + +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + /* Note: + Take care of the RX FIFO, DMA request only assert when received bytes + equal or more than RX water mark, there is potential issue if RX water + mark larger than 1. + For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and + 5 bytes are received. the last byte will be saved in FIFO but not trigger + DMA transfer because the water mark is 2. + */ + if (rxDmaHandle) + { + base->RWFIFO = 1U; + } +#endif + + handle->rxDmaHandle = rxDmaHandle; + handle->txDmaHandle = txDmaHandle; + + /* Configure TX. */ + if (txDmaHandle) + { + DMA_SetCallback(txDmaHandle, UART_TransferSendDMACallback, &s_dmaPrivateHandle[instance]); + } + + /* Configure RX. */ + if (rxDmaHandle) + { + DMA_SetCallback(rxDmaHandle, UART_TransferReceiveDMACallback, &s_dmaPrivateHandle[instance]); + } +} + +status_t UART_TransferSendDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer) +{ + assert(handle->txDmaHandle); + + dma_transfer_config_t xferConfig; + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* If previous TX not finished. */ + if (kUART_TxBusy == handle->txState) + { + status = kStatus_UART_TxBusy; + } + else + { + handle->txState = kUART_TxBusy; + handle->txDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + DMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)UART_GetDataRegisterAddress(base), + sizeof(uint8_t), xfer->dataSize, kDMA_MemoryToPeripheral); + + /* Submit transfer. */ + DMA_SubmitTransfer(handle->txDmaHandle, &xferConfig, kDMA_EnableInterrupt); + DMA_StartTransfer(handle->txDmaHandle); + + /* Enable UART TX DMA. */ + UART_EnableTxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +status_t UART_TransferReceiveDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer) +{ + assert(handle->rxDmaHandle); + + dma_transfer_config_t xferConfig; + status_t status; + + /* Return error if xfer invalid. */ + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* If previous RX not finished. */ + if (kUART_RxBusy == handle->rxState) + { + status = kStatus_UART_RxBusy; + } + else + { + handle->rxState = kUART_RxBusy; + handle->rxDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + DMA_PrepareTransfer(&xferConfig, (void *)UART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data, + sizeof(uint8_t), xfer->dataSize, kDMA_PeripheralToMemory); + + /* Submit transfer. */ + DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig, kDMA_EnableInterrupt); + DMA_StartTransfer(handle->rxDmaHandle); + + /* Enable UART RX DMA. */ + UART_EnableRxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +void UART_TransferAbortSendDMA(UART_Type *base, uart_dma_handle_t *handle) +{ + assert(handle->txDmaHandle); + + /* Disable UART TX DMA. */ + UART_EnableTxDMA(base, false); + + /* Stop transfer. */ + DMA_AbortTransfer(handle->txDmaHandle); + + /* Write DMA->DSR[DONE] to abort transfer and clear status. */ + DMA_ClearChannelStatusFlags(handle->txDmaHandle->base, handle->txDmaHandle->channel, kDMA_TransactionsDoneFlag); + + handle->txState = kUART_TxIdle; +} + +void UART_TransferAbortReceiveDMA(UART_Type *base, uart_dma_handle_t *handle) +{ + assert(handle->rxDmaHandle); + + /* Disable UART RX DMA. */ + UART_EnableRxDMA(base, false); + + /* Stop transfer. */ + DMA_AbortTransfer(handle->rxDmaHandle); + + /* Write DMA->DSR[DONE] to abort transfer and clear status. */ + DMA_ClearChannelStatusFlags(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, kDMA_TransactionsDoneFlag); + + handle->rxState = kUART_RxIdle; +} + +status_t UART_TransferGetSendCountDMA(UART_Type *base, uart_dma_handle_t *handle, uint32_t *count) +{ + assert(handle->txDmaHandle); + + if (kUART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->txDataSizeAll - DMA_GetRemainingBytes(handle->txDmaHandle->base, handle->txDmaHandle->channel); + + return kStatus_Success; +} + +status_t UART_TransferGetReceiveCountDMA(UART_Type *base, uart_dma_handle_t *handle, uint32_t *count) +{ + assert(handle->rxDmaHandle); + + if (kUART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + if (!count) + { + return kStatus_InvalidArgument; + } + + *count = handle->rxDataSizeAll - DMA_GetRemainingBytes(handle->rxDmaHandle->base, handle->rxDmaHandle->channel); + + return kStatus_Success; +} diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart_dma.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart_dma.h new file mode 100644 index 0000000000..cd26fa0f12 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_uart_dma.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_UART_DMA_H_ +#define _FSL_UART_DMA_H_ + +#include "fsl_uart.h" +#include "fsl_dmamux.h" +#include "fsl_dma.h" + +/*! + * @addtogroup uart_dma_driver + * @{ + */ + +/*! @file*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Forward declaration of the handle typedef. */ +typedef struct _uart_dma_handle uart_dma_handle_t; + +/*! @brief UART transfer callback function. */ +typedef void (*uart_dma_transfer_callback_t)(UART_Type *base, + uart_dma_handle_t *handle, + status_t status, + void *userData); + +/*! +* @brief UART DMA handle +*/ +struct _uart_dma_handle +{ + UART_Type *base; /*!< UART peripheral base address. */ + + uart_dma_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< UART callback function parameter.*/ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + + dma_handle_t *txDmaHandle; /*!< The DMA TX channel used. */ + dma_handle_t *rxDmaHandle; /*!< The DMA RX channel used. */ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name EDMA transactional + * @{ + */ + +/*! + * @brief Initializes the UART handle which is used in transactional functions and sets the callback. + * + * @param base UART peripheral base address. + * @param handle Pointer to uart_dma_handle_t structure. + * @param callback UART callback, NULL means no callback. + * @param userData User callback function data. + * @param rxDmaHandle User requested DMA handle for RX DMA transfer. + * @param txDmaHandle User requested DMA handle for TX DMA transfer. + */ +void UART_TransferCreateHandleDMA(UART_Type *base, + uart_dma_handle_t *handle, + uart_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txDmaHandle, + dma_handle_t *rxDmaHandle); + +/*! + * @brief Sends data using DMA. + * + * This function sends data using DMA. This is non-blocking function, which returns + * right away. When all data is sent, the send callback function is called. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param xfer UART DMA transfer structure. See #uart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_UART_TxBusy Previous transfer on going. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t UART_TransferSendDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer); + +/*! + * @brief Receives data using DMA. + * + * This function receives data using DMA. This is non-blocking function, which returns + * right away. When all data is received, the receive callback function is called. + * + * @param base UART peripheral base address. + * @param handle Pointer to uart_dma_handle_t structure. + * @param xfer UART DMA transfer structure. See #uart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_UART_RxBusy Previous transfer on going. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t UART_TransferReceiveDMA(UART_Type *base, uart_dma_handle_t *handle, uart_transfer_t *xfer); + +/*! + * @brief Aborts the send data using DMA. + * + * This function aborts the sent data using DMA. + * + * @param base UART peripheral base address. + * @param handle Pointer to uart_dma_handle_t structure. + */ +void UART_TransferAbortSendDMA(UART_Type *base, uart_dma_handle_t *handle); + +/*! + * @brief Aborts the received data using DMA. + * + * This function abort receive data which using DMA. + * + * @param base UART peripheral base address. + * @param handle Pointer to uart_dma_handle_t structure. + */ +void UART_TransferAbortReceiveDMA(UART_Type *base, uart_dma_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been written to UART TX register. + * + * This function gets the number of bytes that have been written to UART TX + * register by DMA. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t UART_TransferGetSendCountDMA(UART_Type *base, uart_dma_handle_t *handle, uint32_t *count); + +/*! + * @brief Get the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base UART peripheral base address. + * @param handle UART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t UART_TransferGetReceiveCountDMA(UART_Type *base, uart_dma_handle_t *handle, uint32_t *count); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_UART_DMA_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_vref.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_vref.c new file mode 100644 index 0000000000..0854ca0757 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_vref.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_vref.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Gets the instance from the base address + * + * @param base VREF peripheral base address + * + * @return The VREF instance + */ +static uint32_t VREF_GetInstance(VREF_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to VREF bases for each instance. */ +static VREF_Type *const s_vrefBases[] = VREF_BASE_PTRS; + +/*! @brief Pointers to VREF clocks for each instance. */ +static const clock_ip_name_t s_vrefClocks[] = VREF_CLOCKS; + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t VREF_GetInstance(VREF_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < FSL_FEATURE_SOC_VREF_COUNT; instance++) + { + if (s_vrefBases[instance] == base) + { + break; + } + } + + assert(instance < FSL_FEATURE_SOC_VREF_COUNT); + + return instance; +} + +void VREF_Init(VREF_Type *base, const vref_config_t *config) +{ + assert(config != NULL); + + uint8_t reg = 0U; + + /* Ungate clock for VREF */ + CLOCK_EnableClock(s_vrefClocks[VREF_GetInstance(base)]); + +/* Configure VREF to a known state */ +#if defined(FSL_FEATURE_VREF_HAS_CHOP_OSC) && FSL_FEATURE_VREF_HAS_CHOP_OSC + /* Set chop oscillator bit */ + base->TRM |= VREF_TRM_CHOPEN_MASK; +#endif /* FSL_FEATURE_VREF_HAS_CHOP_OSC */ + reg = base->SC; + /* Set buffer Mode selection and Regulator enable bit */ + reg |= VREF_SC_MODE_LV(config->bufferMode) | VREF_SC_REGEN(1U); +#if defined(FSL_FEATURE_VREF_HAS_COMPENSATION) && FSL_FEATURE_VREF_HAS_COMPENSATION + /* Set second order curvature compensation enable bit */ + reg |= VREF_SC_ICOMPEN(1U); +#endif /* FSL_FEATURE_VREF_HAS_COMPENSATION */ + /* Enable VREF module */ + reg |= VREF_SC_VREFEN(1U); + /* Update bit-field from value to Status and Control register */ + base->SC = reg; +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + reg = base->VREFL_TRM; + /* Clear old select external voltage reference and VREFL (0.4 V) reference buffer enable bits*/ + reg &= ~(VREF_VREFL_TRM_VREFL_EN_MASK | VREF_VREFL_TRM_VREFL_SEL_MASK); + /* Select external voltage reference and set VREFL (0.4 V) reference buffer enable */ + reg |= VREF_VREFL_TRM_VREFL_SEL(config->enableExternalVoltRef) | VREF_VREFL_TRM_VREFL_EN(config->enableLowRef); + base->VREFL_TRM = reg; +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + + /* Wait until internal voltage stable */ + while ((base->SC & VREF_SC_VREFST_MASK) == 0) + { + } +} + +void VREF_Deinit(VREF_Type *base) +{ + /* Gate clock for VREF */ + CLOCK_DisableClock(s_vrefClocks[VREF_GetInstance(base)]); +} + +void VREF_GetDefaultConfig(vref_config_t *config) +{ +/* Set High power buffer mode in */ +#if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE + config->bufferMode = kVREF_ModeHighPowerBuffer; +#else + config->bufferMode = kVREF_ModeTightRegulationBuffer; +#endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */ + +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + /* Select internal voltage reference */ + config->enableExternalVoltRef = false; + /* Set VREFL (0.4 V) reference buffer disable */ + config->enableLowRef = false; +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ +} + +void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue) +{ + uint8_t reg = 0U; + + /* Set TRIM bits value in voltage reference */ + reg = base->TRM; + reg = ((reg & ~VREF_TRM_TRIM_MASK) | VREF_TRM_TRIM(trimValue)); + base->TRM = reg; + /* Wait until internal voltage stable */ + while ((base->SC & VREF_SC_VREFST_MASK) == 0) + { + } +} + +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE +void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue) +{ + /* The values 111b and 110b are NOT valid/allowed */ + assert((trimValue != 0x7U) && (trimValue != 0x6U)); + + uint8_t reg = 0U; + + /* Set TRIM bits value in low voltage reference */ + reg = base->VREFL_TRM; + reg = ((reg & ~VREF_VREFL_TRM_VREFL_TRIM_MASK) | VREF_VREFL_TRM_VREFL_TRIM(trimValue)); + base->VREFL_TRM = reg; + /* Wait until internal voltage stable */ + while ((base->SC & VREF_SC_VREFST_MASK) == 0) + { + } +} +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_vref.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_vref.h new file mode 100644 index 0000000000..79378863bb --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_vref.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_VREF_H_ +#define _FSL_VREF_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup vref + * @{ + */ + +/*! @file */ + +/****************************************************************************** + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_VREF_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +/*@}*/ + +/* Those macros below defined to support SoC family which have VREFL (0.4V) reference */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE +#define SC VREFH_SC +#define VREF_SC_MODE_LV VREF_VREFH_SC_MODE_LV +#define VREF_SC_REGEN VREF_VREFH_SC_REGEN +#define VREF_SC_VREFEN VREF_VREFH_SC_VREFEN +#define VREF_SC_ICOMPEN VREF_VREFH_SC_ICOMPEN +#define VREF_SC_REGEN_MASK VREF_VREFH_SC_REGEN_MASK +#define VREF_SC_VREFST_MASK VREF_VREFH_SC_VREFST_MASK +#define VREF_SC_VREFEN_MASK VREF_VREFH_SC_VREFEN_MASK +#define VREF_SC_MODE_LV_MASK VREF_VREFH_SC_MODE_LV_MASK +#define VREF_SC_ICOMPEN_MASK VREF_VREFH_SC_ICOMPEN_MASK +#define TRM VREFH_TRM +#define VREF_TRM_TRIM VREF_VREFH_TRM_TRIM +#define VREF_TRM_CHOPEN_MASK VREF_VREFH_TRM_CHOPEN_MASK +#define VREF_TRM_TRIM_MASK VREF_VREFH_TRM_TRIM_MASK +#define VREF_TRM_CHOPEN_SHIFT VREF_VREFH_TRM_CHOPEN_SHIFT +#define VREF_TRM_TRIM_SHIFT VREF_VREFH_TRM_TRIM_SHIFT +#define VREF_SC_MODE_LV_SHIFT VREF_VREFH_SC_MODE_LV_SHIFT +#define VREF_SC_REGEN_SHIFT VREF_VREFH_SC_REGEN_SHIFT +#define VREF_SC_VREFST_SHIFT VREF_VREFH_SC_VREFST_SHIFT +#define VREF_SC_ICOMPEN_SHIFT VREF_VREFH_SC_ICOMPEN_SHIFT +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + +/*! + * @brief VREF modes. + */ +typedef enum _vref_buffer_mode +{ + kVREF_ModeBandgapOnly = 0U, /*!< Bandgap on only, for stabilization and startup */ +#if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE + kVREF_ModeHighPowerBuffer = 1U, /*!< High power buffer mode enabled */ + kVREF_ModeLowPowerBuffer = 2U /*!< Low power buffer mode enabled */ +#else + kVREF_ModeTightRegulationBuffer = 2U /*!< Tight regulation buffer enabled */ +#endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */ +} vref_buffer_mode_t; + +/*! + * @brief The description structure for the VREF module. + */ +typedef struct _vref_config +{ + vref_buffer_mode_t bufferMode; /*!< Buffer mode selection */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + bool enableLowRef; /*!< Set VREFL (0.4 V) reference buffer enable or disable */ + bool enableExternalVoltRef; /*!< Select external voltage reference or not (internal) */ +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ +} vref_config_t; + +/****************************************************************************** + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name VREF functional operation + * @{ + */ + +/*! + * @brief Enables the clock gate and configures the VREF module according to the configuration structure. + * + * This function must be called before calling all the other VREF driver functions, + * read/write registers, and configurations with user-defined settings. + * The example below shows how to set up vref_config_t parameters and + * how to call the VREF_Init function by passing in these parameters: + * Example: + * @code + * vref_config_t vrefConfig; + * vrefConfig.bufferMode = kVREF_ModeHighPowerBuffer; + * vrefConfig.enableExternalVoltRef = false; + * vrefConfig.enableLowRef = false; + * VREF_Init(VREF, &vrefConfig); + * @endcode + * + * @param base VREF peripheral address. + * @param config Pointer to the configuration structure. + */ +void VREF_Init(VREF_Type *base, const vref_config_t *config); + +/*! + * @brief Stops and disables the clock for the VREF module. + * + * This function should be called to shut down the module. + * Example: + * @code + * vref_config_t vrefUserConfig; + * VREF_Init(VREF); + * VREF_GetDefaultConfig(&vrefUserConfig); + * ... + * VREF_Deinit(VREF); + * @endcode + * + * @param base VREF peripheral address. + */ +void VREF_Deinit(VREF_Type *base); + +/*! + * @brief Initializes the VREF configuration structure. + * + * This function initializes the VREF configuration structure to a default value. + * Example: + * @code + * vrefConfig->bufferMode = kVREF_ModeHighPowerBuffer; + * vrefConfig->enableExternalVoltRef = false; + * vrefConfig->enableLowRef = false; + * @endcode + * + * @param config Pointer to the initialization structure. + */ +void VREF_GetDefaultConfig(vref_config_t *config); + +/*! + * @brief Sets a TRIM value for reference voltage. + * + * This function sets a TRIM value for reference voltage. + * Note that the TRIM value maximum is 0x3F. + * + * @param base VREF peripheral address. + * @param trimValue Value of the trim register to set the output reference voltage (maximum 0x3F (6-bit)). + */ +void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue); + +/*! + * @brief Reads the value of the TRIM meaning output voltage. + * + * This function gets the TRIM value from the TRM register. + * + * @param base VREF peripheral address. + * @return Six-bit value of trim setting. + */ +static inline uint8_t VREF_GetTrimVal(VREF_Type *base) +{ + return (base->TRM & VREF_TRM_TRIM_MASK); +} +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + +/*! + * @brief Sets the TRIM value for low voltage reference. + * + * This function sets the TRIM value for low reference voltage. + * NOTE: + * - The TRIM value maximum is 0x05U + * - The values 111b and 110b are not valid/allowed. + * + * @param base VREF peripheral address. + * @param trimValue Value of the trim register to set output low reference voltage (maximum 0x05U (3-bit)). + */ +void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue); + +/*! + * @brief Reads the value of the TRIM meaning output voltage. + * + * This function gets the TRIM value from the VREFL_TRM register. + * + * @param base VREF peripheral address. + * @return Three-bit value of the trim setting. + */ +static inline uint8_t VREF_GetLowReferenceTrimVal(VREF_Type *base) +{ + return (base->VREFL_TRM & VREF_VREFL_TRM_VREFL_TRIM_MASK); +} +#endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_VREF_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/peripheral_clock_defines.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/peripheral_clock_defines.h new file mode 100644 index 0000000000..93be44de1b --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/peripheral_clock_defines.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_PERIPHERAL_CLOCK_H_ +#define _FSL_PERIPHERAL_CLOCK_H_ + +#include "fsl_clock.h" + +/* Array for UART module clocks */ +#define UART_CLOCK_FREQS \ + { \ + kCLOCK_IpInvalid, kCLOCK_IpInvalid, UART2_CLK_SRC \ + } + +/* Array for LPUART module clocks */ +#define LPUART_CLOCK_FREQS \ + { \ + kCLOCK_McgIrc48MClk, kCLOCK_McgIrc48MClk \ + } + +/* Array for I2C module clocks */ +#define I2C_CLOCK_FREQS \ + { \ + I2C0_CLK_SRC, I2C1_CLK_SRC \ + } + +/* Array for DSPI module clocks */ +#define SPI_CLOCK_FREQS \ + { \ + SPI0_CLK_SRC, SPI1_CLK_SRC \ + } + +#endif /* _FSL_PERIPHERAL_CLOCK_H_ */ diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/pwmout_api.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/pwmout_api.c new file mode 100644 index 0000000000..a2a90e8b8b --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/pwmout_api.c @@ -0,0 +1,139 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" + +#if DEVICE_PWMOUT + +#include "cmsis.h" +#include "pinmap.h" +#include "fsl_tpm.h" +#include "PeripheralPins.h" + +static float pwm_clock_mhz; +/* Array of TPM peripheral base address. */ +static TPM_Type *const tpm_addrs[] = TPM_BASE_PTRS; + +void pwmout_init(pwmout_t* obj, PinName pin) { + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (PWMName)NC); + + obj->pwm_name = pwm; + + uint32_t pwm_base_clock; + + /* Set the TPM clock source to be IRC 48M */ + CLOCK_SetTpmClock(1U); + pwm_base_clock = CLOCK_GetFreq(kCLOCK_McgIrc48MClk); + float clkval = (float)pwm_base_clock / 1000000.0f; + uint32_t clkdiv = 0; + while (clkval > 1) { + clkdiv++; + clkval /= 2.0f; + if (clkdiv == 7) { + break; + } + } + + pwm_clock_mhz = clkval; + uint32_t channel = pwm & 0xF; + uint32_t instance = pwm >> TPM_SHIFT; + tpm_config_t tpmInfo; + + TPM_GetDefaultConfig(&tpmInfo); + tpmInfo.prescale = (tpm_clock_prescale_t)clkdiv; + /* Initialize TPM module */ + TPM_Init(tpm_addrs[instance], &tpmInfo); + + tpm_chnl_pwm_signal_param_t config = { + .chnlNumber = (tpm_chnl_t)channel, + .level = kTPM_HighTrue, + .dutyCyclePercent = 0, + }; + // default to 20ms: standard for servos, and fine for e.g. brightness control + TPM_SetupPwm(tpm_addrs[instance], &config, 1, kTPM_EdgeAlignedPwm, 50, pwm_base_clock); + + TPM_StartTimer(tpm_addrs[instance], kTPM_SystemClock); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + TPM_Deinit(tpm_addrs[obj->pwm_name >> TPM_SHIFT]); +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0f; + } else if (value > 1.0f) { + value = 1.0f; + } + + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + uint16_t mod = base->MOD & TPM_MOD_MOD_MASK; + uint32_t new_count = (uint32_t)((float)(mod) * value); + // Update of CnV register + base->CONTROLS[obj->pwm_name & 0xF].CnV = new_count; + base->CNT = 0; +} + +float pwmout_read(pwmout_t* obj) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & TPM_CnV_VAL_MASK; + uint16_t mod = base->MOD & TPM_MOD_MOD_MASK; + + if (mod == 0) + return 0.0; + float v = (float)(count) / (float)(mod); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + float dc = pwmout_read(obj); + + // Stop TPM clock to ensure instant update of MOD register + base->MOD = TPM_MOD_MOD((pwm_clock_mhz * (float)us) - 1); + pwmout_write(obj, dc); +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT]; + uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us); + + // Update of CnV register + base->CONTROLS[obj->pwm_name & 0xF].CnV = value; +} + +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/serial_api.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/serial_api.c new file mode 100644 index 0000000000..7e48db7986 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/serial_api.c @@ -0,0 +1,256 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "serial_api.h" + +#if DEVICE_SERIAL + +// math.h required for floating point operations for baud rate calculation +#include +#include "mbed_assert.h" + +#include + +#include "cmsis.h" +#include "pinmap.h" +#include "fsl_lpuart.h" +#include "peripheral_clock_defines.h" +#include "PeripheralPins.h" +#include "fsl_clock_config.h" + +static uint32_t serial_irq_ids[FSL_FEATURE_SOC_LPUART_COUNT] = {0}; +static uart_irq_handler irq_handler; +/* Array of UART peripheral base address. */ +static LPUART_Type *const uart_addrs[] = LPUART_BASE_PTRS; +/* Array of LPUART bus clock frequencies */ +static clock_name_t const uart_clocks[] = LPUART_CLOCK_FREQS; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX); + uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX); + obj->index = pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)obj->index != NC); + + // Need to initialize the clocks here as ticker init gets called before mbed_sdk_init + if (SystemCoreClock == DEFAULT_SYSTEM_CLOCK) + BOARD_BootClockRUN(); + + /* Set the LPUART clock source */ + if (obj->index == LPUART_0) { + CLOCK_SetLpuart0Clock(1U); + } else { + CLOCK_SetLpuart1Clock(1U); + } + + lpuart_config_t config; + LPUART_GetDefaultConfig(&config); + config.baudRate_Bps = 9600; + config.enableTx = false; + config.enableRx = false; + + LPUART_Init(uart_addrs[obj->index], &config, CLOCK_GetFreq(uart_clocks[obj->index])); + + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + if (tx != NC) { + LPUART_EnableTx(uart_addrs[obj->index], true); + pin_mode(tx, PullUp); + } + if (rx != NC) { + LPUART_EnableRx(uart_addrs[obj->index], true); + pin_mode(rx, PullUp); + } + + if (obj->index == STDIO_UART) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + LPUART_Deinit(uart_addrs[obj->index]); + serial_irq_ids[obj->index] = 0; +} + +void serial_baud(serial_t *obj, int baudrate) { + LPUART_SetBaudRate(uart_addrs[obj->index], (uint32_t)baudrate, CLOCK_GetFreq(uart_clocks[obj->index])); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + LPUART_Type *base = uart_addrs[obj->index]; + uint8_t temp; + /* Set bit count and parity mode. */ + temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK); + if (parity != ParityNone) + { + /* Enable Parity */ + temp |= (LPUART_CTRL_PE_MASK | LPUART_CTRL_M_MASK); + if (parity == ParityOdd) { + temp |= LPUART_CTRL_PT_MASK; + } else { + // Hardware does not support forced parity + MBED_ASSERT(0); + } + } + base->CTRL = temp; + +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + /* set stop bit per char */ + temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK; + base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)--stop_bits); +#endif +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t transmit_empty, uint32_t receive_full, uint32_t index) { + LPUART_Type *base = uart_addrs[index]; + + /* If RX overrun. */ + if (LPUART_STAT_OR_MASK & base->STAT) + { + /* Read base->D, otherwise the RX does not work. */ + (void)base->DATA; + LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag); + } + + if (serial_irq_ids[index] != 0) { + if (transmit_empty) + irq_handler(serial_irq_ids[index], TxIrq); + + if (receive_full) + irq_handler(serial_irq_ids[index], RxIrq); + } +} + +void uart0_irq() { + uint32_t status_flags = LPUART0->STAT; + uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 0); +} + +void uart1_irq() { + uint32_t status_flags = LPUART1->STAT; + uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 1); +} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type uart_irqs[] = LPUART_RX_TX_IRQS; + uint32_t vector = 0; + + switch (obj->index) { + case 0: + vector = (uint32_t)&uart0_irq; + break; + case 1: + vector = (uint32_t)&uart1_irq; + break; + default: + break; + } + + if (enable) { + switch (irq) { + case RxIrq: + LPUART_EnableInterrupts(uart_addrs[obj->index], kLPUART_RxDataRegFullInterruptEnable); + break; + case TxIrq: + LPUART_EnableInterrupts(uart_addrs[obj->index], kLPUART_TxDataRegEmptyInterruptEnable); + break; + default: + break; + } + NVIC_SetVector(uart_irqs[obj->index], vector); + NVIC_EnableIRQ(uart_irqs[obj->index]); + + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + switch (irq) { + case RxIrq: + LPUART_DisableInterrupts(uart_addrs[obj->index], kLPUART_RxDataRegFullInterruptEnable); + break; + case TxIrq: + LPUART_DisableInterrupts(uart_addrs[obj->index], kLPUART_TxDataRegEmptyInterruptEnable); + break; + default: + break; + } + switch (other_irq) { + case RxIrq: + all_disabled = ((LPUART_GetEnabledInterrupts(uart_addrs[obj->index]) & kLPUART_RxDataRegFullInterruptEnable) == 0); + break; + case TxIrq: + all_disabled = ((LPUART_GetEnabledInterrupts(uart_addrs[obj->index]) & kLPUART_TxDataRegEmptyInterruptEnable) == 0); + break; + default: + break; + } + if (all_disabled) + NVIC_DisableIRQ(uart_irqs[obj->index]); + } +} + +int serial_getc(serial_t *obj) { + uint8_t data; + + LPUART_ReadBlocking(uart_addrs[obj->index], &data, 1); + return data; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + LPUART_WriteByte(uart_addrs[obj->index], (uint8_t)c); +} + +int serial_readable(serial_t *obj) { + uint32_t status_flags = LPUART_GetStatusFlags(uart_addrs[obj->index]); + if (status_flags & kLPUART_RxOverrunFlag) + LPUART_ClearStatusFlags(uart_addrs[obj->index], kLPUART_RxOverrunFlag); + return (status_flags & kLPUART_RxDataRegFullFlag); +} + +int serial_writable(serial_t *obj) { + uint32_t status_flags = LPUART_GetStatusFlags(uart_addrs[obj->index]); + if (status_flags & kLPUART_RxOverrunFlag) + LPUART_ClearStatusFlags(uart_addrs[obj->index], kLPUART_RxOverrunFlag); + return (status_flags & kLPUART_TxDataRegEmptyFlag); +} + +void serial_clear(serial_t *obj) { +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + uart_addrs[obj->index]->CTRL |= LPUART_CTRL_SBK_MASK; +} + +void serial_break_clear(serial_t *obj) { + uart_addrs[obj->index]->CTRL &= ~LPUART_CTRL_SBK_MASK; +} + +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/spi_api.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/spi_api.c new file mode 100644 index 0000000000..19404ced60 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/spi_api.c @@ -0,0 +1,131 @@ +/* mbed Microcontroller Library + * Copyright (c) 2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "mbed_assert.h" + +#include "spi_api.h" + +#if DEVICE_SPI + +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "fsl_spi.h" +#include "peripheral_clock_defines.h" +#include "PeripheralPins.h" + +/* Array of SPI peripheral base address. */ +static SPI_Type *const spi_address[] = SPI_BASE_PTRS; +/* Array of SPI bus clock frequencies */ +static clock_name_t const spi_clocks[] = SPI_CLOCK_FREQS; + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + uint32_t spi_mosi = pinmap_peripheral(mosi, PinMap_SPI_MOSI); + uint32_t spi_miso = pinmap_peripheral(miso, PinMap_SPI_MISO); + uint32_t spi_sclk = pinmap_peripheral(sclk, PinMap_SPI_SCLK); + uint32_t spi_ssel = pinmap_peripheral(ssel, PinMap_SPI_SSEL); + uint32_t spi_data = pinmap_merge(spi_mosi, spi_miso); + uint32_t spi_cntl = pinmap_merge(spi_sclk, spi_ssel); + + obj->instance = pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->instance != NC); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) { + SPI_Deinit(spi_address[obj->instance]); +} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + + spi_master_config_t master_config; + spi_slave_config_t slave_config; + + if ((bits != 8) || (bits != 16)) { + error("Only 8bits and 16bits SPI supported"); + return; + } + + if (slave) { + /* Slave config */ + SPI_SlaveGetDefaultConfig(&slave_config); + slave_config.dataMode = (bits == 16) ? kSPI_16BitMode : kSPI_8BitMode; + slave_config.polarity = (mode & 0x2) ? kSPI_ClockPolarityActiveLow : kSPI_ClockPolarityActiveHigh; + slave_config.phase = (mode & 0x1) ? kSPI_ClockPhaseSecondEdge : kSPI_ClockPhaseFirstEdge; + + SPI_SlaveInit(spi_address[obj->instance], &slave_config); + } else { + /* Master config */ + SPI_MasterGetDefaultConfig(&master_config); + master_config.dataMode = (bits == 16) ? kSPI_16BitMode : kSPI_8BitMode; + master_config.polarity = (mode & 0x2) ? kSPI_ClockPolarityActiveLow : kSPI_ClockPolarityActiveHigh; + master_config.phase = (mode & 0x1) ? kSPI_ClockPhaseSecondEdge : kSPI_ClockPhaseFirstEdge; + master_config.direction = kSPI_MsbFirst; + + SPI_MasterInit(spi_address[obj->instance], &master_config, CLOCK_GetFreq(spi_clocks[obj->instance])); + } +} + +void spi_frequency(spi_t *obj, int hz) { + SPI_MasterSetBaudRate(spi_address[obj->instance], (uint32_t)hz, CLOCK_GetFreq(spi_clocks[obj->instance])); +} + +static inline int spi_readable(spi_t * obj) { + return (SPI_GetStatusFlags(spi_address[obj->instance]) & kSPI_RxBufferFullFlag); +} + +int spi_master_write(spi_t *obj, int value) { + spi_transfer_t xfer = {0}; + uint32_t rx_data; + SPI_Type *base = spi_address[obj->instance]; + + /* SPI master start transfer */ + xfer.txData = (uint8_t *)&value; + xfer.rxData = (uint8_t *)&rx_data; + xfer.dataSize = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; + SPI_MasterTransferBlocking(base, &xfer); + + return rx_data & 0xffff; +} + +int spi_slave_receive(spi_t *obj) { + return spi_readable(obj); +} + +int spi_slave_read(spi_t *obj) { + uint32_t rx_data; + + while (!spi_readable(obj)); + rx_data = SPI_ReadData(spi_address[obj->instance]); + + return rx_data & 0xffff; +} + +void spi_slave_write(spi_t *obj, int value) { + SPI_Type *base = spi_address[obj->instance]; + size_t size = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; + SPI_WriteBlocking(spi_address[obj->instance], (uint8_t *)&value, size); +} + +#endif diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/us_ticker.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/us_ticker.c new file mode 100644 index 0000000000..9acf9fe716 --- /dev/null +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/us_ticker.c @@ -0,0 +1,98 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "us_ticker_api.h" +#include "PeripheralNames.h" +#include "fsl_pit.h" +#include "fsl_lptmr.h" +#include "fsl_clock_config.h" + +static int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) { + return; + } + us_ticker_inited = 1; + + // Need to initialize the clocks here as ticker init gets called before mbed_sdk_init + if (SystemCoreClock == DEFAULT_SYSTEM_CLOCK) + BOARD_BootClockRUN(); + + //Timer uses PIT + //Common for ticker/timer + uint32_t busClock; + + // Structure to initialize PIT + pit_config_t pitConfig; + + PIT_GetDefaultConfig(&pitConfig); + PIT_Init(PIT, &pitConfig); + + busClock = CLOCK_GetFreq(kCLOCK_BusClk); + + PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, busClock / 1000000 - 1); + PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, 0xFFFFFFFF); + PIT_SetTimerChainMode(PIT, kPIT_Chnl_1, true); + PIT_StartTimer(PIT, kPIT_Chnl_0); + PIT_StartTimer(PIT, kPIT_Chnl_1); + + //Ticker uses LPTMR + lptmr_config_t lptmrConfig; + LPTMR_GetDefaultConfig(&lptmrConfig); + lptmrConfig.prescalerClockSource = kLPTMR_PrescalerClock_0; + LPTMR_Init(LPTMR0, &lptmrConfig); + + busClock = CLOCK_GetFreq(kCLOCK_McgInternalRefClk); + LPTMR_SetTimerPeriod(LPTMR0, busClock / 1000000 - 1); + /* Set interrupt handler */ + NVIC_SetVector(LPTMR0_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(LPTMR0_IRQn); +} + + +uint32_t us_ticker_read() { + if (!us_ticker_inited) { + us_ticker_init(); + } + + return ~(PIT_GetCurrentTimerCount(PIT, kPIT_Chnl_1)); +} + +void us_ticker_disable_interrupt(void) { + LPTMR_DisableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable); +} + +void us_ticker_clear_interrupt(void) { + LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag); +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + int delta = (int)(timestamp - us_ticker_read()); + if (delta <= 0) { + // This event was in the past. + // Set the interrupt as pending, but don't process it here. + // This prevents a recurive loop under heavy load + // which can lead to a stack overflow. + NVIC_SetPendingIRQ(LPTMR0_IRQn); + return; + } + + LPTMR_StopTimer(LPTMR0); + LPTMR_SetTimerPeriod(LPTMR0, (uint32_t)delta); + LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable); + LPTMR_StartTimer(LPTMR0); +}